diff --git a/.gitattributes b/.gitattributes index 3c59efe684..2462fa3c3b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,13 @@ *.png binary *.jpg binary *.paa binary + +# Change GitHub language categorization +addons/**/*.cpp linguist-language=SQF +addons/**/*.hpp linguist-language=SQF + +optionals/**/*.cpp linguist-language=SQF +optionals/**/*.hpp linguist-language=SQF + +# Do not count hemtt includes in language usage stats +include/* linguist-vendored diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 08c731127a..a2e6e53c4d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -34,11 +34,11 @@ We welcome anyone to contribute to this repository. Issues that we are actively ## Pull Request process -When contributing to this repository, please first discuss the change you wish to make via issue or [Slack](https://slackin.ace3mod.com/) with the [ACE3 project maintainers](https://ace3mod.com/team.html) before making a change. This may not be necessary if you are contributing for something which has an existing issue in our repository already. +When contributing to this repository, please first discuss the change you wish to make via issue or [Discord](https://acemod.org/discord) with the [ACE3 project maintainers](https://ace3.acemod.org/team.html) before making a change. This may not be necessary if you are contributing for something which has an existing issue in our repository already. -1. Please make a pull request (PR) as early as possible. This lets use help you in the proces of developing it. When opening a work in progress pull request, mark your PR with a `WIP:` prefix. +1. Please make a pull request (PR) as early as possible. This lets use help you in the proces of developing it. When opening a work in progress pull request, use GitHub's draft feature. This will mark the PR as a work in progress and will prevent it from being merged until you mark it as ready for review. 2. Describe what this pull request will do and how it solves this in the description of your PR. A clear intent and description of the way the issue is resolved will help us to review the PR more efficiently. -3. Please follow our [Development Guidelines](https://ace3mod.com/wiki/development/). +3. Please follow our [Development Guidelines](https://ace3.acemod.org/wiki/development/). ### Notes @@ -47,4 +47,4 @@ Please note that all contributors to this project are volunteers and do this in ## Assistance with contributing -If you require assistance with contributing, check out the #dev channel on our [Slack](https://slackin.ace3mod.com/). Additional documentation can be found on our [Development wiki](https://ace3mod.com/wiki/development/). +If you require assistance with contributing, check out the #dev channel on our [Discord](https://acemod.org/discord). Additional documentation can be found on our [Development wiki](https://ace3.acemod.org/wiki/development/). 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..08c14747e5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,52 @@ +--- +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` [e.g. 3.0.0 stable, commit hash] + + +**Description:** +A clear and concise description of what the bug is. + +**Steps to reproduce:** +_Follow [this flowchart](https://ace3.acemod.org/img/wiki/user/issue_flowchart.webp)!_ + +1. _Go to ..._ +2. _Click ..._ +3. _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/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..3ba13e0cec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..2bba1a5dd1 --- /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://ace3.acemod.org/wiki/user/how-to-make-a-feature-request.html). diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 69565c700e..5bdf51df2a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,9 @@ **When merged this pull request will:** -- Describe what this pull request will do -- Each change in a separate line -- Include documentation if applicable -- Respect the [Development Guidelines](https://ace3mod.com/wiki/development/) +- _Describe what this pull request will do_ +- _Each change in a separate line_ + +### IMPORTANT + +- If the contribution affects [the documentation](https://github.com/acemod/ACE3/tree/master/docs), please include your changes in this pull request so the documentation will appear on the [website](https://ace3.acemod.org/). +- [Development Guidelines](https://ace3.acemod.org/wiki/development/) are read, understood and applied. +- Title of this PR uses our standard template `Component - Add|Fix|Improve|Change|Make|Remove {changes}`. diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000000..778d34fd9f --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,48 @@ +branches: + - master + - release-drafter # for testing edits to this configuration + +name-template: 'Version $NEXT_PATCH_VERSION' +tag-template: 'v$NEXT_PATCH_VERSION' + +sort-by: title # sort alphabetically +sort-direction: ascending + +categories: + - title: '**ADDED:**' + labels: + - 'kind/feature' + - title: '**FIXED:**' + labels: + - 'kind/bug-fix' + - title: '**IMPROVED:**' + labels: + - 'kind/enhancement' + - 'kind/optimization' + - title: '**CHANGED:**' + labels: + - 'kind/cleanup' + - 'kind/change' + - title: '**SETTINGS:**' + labels: + - 'kind/setting' + - title: '**TRANSLATIONS:**' + labels: + - 'kind/translation' + +exclude-labels: + - 'ignore-changelog' + - 'dependencies' + +change-template: '- $TITLE (#$NUMBER)' +template: | + _Requires CBA version X.Y.Z or later and Arma 3 version X.Y or later._ + + ## Change Log Summary + + $CHANGES + +replacers: + # Category titles + - search: '/\#\# (\*\*(ADDED|FIXED|IMPROVED|CHANGED|SETTINGS|TRANSLATIONS):\*\*)/g' + replace: '$1' diff --git a/.github/stale.yml b/.github/stale.yml index a129b592ad..c9e0bf2f9e 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -14,6 +14,7 @@ exemptLabels: - status/cherrypick - status/merge on release - sticky + - help wanted # Label to use when marking an issue as stale staleLabel: status/stale diff --git a/.github/workflows/arma.yml b/.github/workflows/arma.yml new file mode 100644 index 0000000000..d0649a0ade --- /dev/null +++ b/.github/workflows/arma.yml @@ -0,0 +1,54 @@ +name: Arma + +on: + push: + branches: + - master + pull_request: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + - name: Validate SQF + run: python3 tools/sqf_validator.py + - name: Validate Config + run: python3 tools/config_style_checker.py + - name: Validate Stringtables + run: python3 tools/stringtable_validator.py + - name: Check Strings + run: python3 tools/check_strings.py + - name: Check for BOM + uses: arma-actions/bom-check@master + with: + path: 'addons' + - name: Validate function headers + run: python3 docs/tools/document_functions.py --debug + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + - name: Lint (sqflint) + uses: arma-actions/sqflint@master + continue-on-error: true # No failure due to many false-positives + + build: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + - name: Setup HEMTT + uses: arma-actions/hemtt@v1 + - name: Run HEMTT build + run: hemtt build + - name: Rename build folder + run: mv .hemttout/build .hemttout/@ace + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ace3-${{ github.sha }}-nobin + path: .hemttout/@* diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000000..cc6aba0a99 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,85 @@ +name: Documentation + +on: + push: + branches: + - master + workflow_dispatch: + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + update: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + - 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.DOCS_TOKEN }} + run: python3 tools/deploy.py + + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract Dependencies + run: python3 tools/extract_dependencies.py --markdown + - name: Document Functions + run: python3 docs/tools/document_functions.py + + - name: Build with Jekyll + uses: actions/jekyll-build-pages@v1 + with: + source: docs/ + destination: docs/_site/ + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: jekyll-site + path: docs/_site/ + retention-days: 1 + + deploy: + runs-on: ubuntu-latest + needs: [build] + + environment: + name: netlify + url: ${{ steps.deployment.outputs.deploy-url }} + + steps: + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: jekyll-site + path: _site/ + + - name: Deploy to Netlify + id: deployment + uses: nwtgck/actions-netlify@v2 + with: + publish-dir: _site/ + production-branch: master + production-deploy: true + deploy-message: ${{ github.event.head_commit.message }} + enable-pull-request-comment: false + enable-commit-comment: false + enable-commit-status: true + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + timeout-minutes: 1 diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml new file mode 100644 index 0000000000..9693d2df22 --- /dev/null +++ b/.github/workflows/extensions.yml @@ -0,0 +1,29 @@ +name: Extensions + +on: + pull_request: + paths: + - 'extensions/**' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest] + + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + - name: Build + shell: cmd + run: | + cd extensions + mkdir build + cd build + cmake .. && cmake --build . + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ace3_extensions-${{ matrix.os }}-debug + path: extensions/build diff --git a/.github/workflows/hemtt.yml b/.github/workflows/hemtt.yml new file mode 100644 index 0000000000..e606852285 --- /dev/null +++ b/.github/workflows/hemtt.yml @@ -0,0 +1,44 @@ +name: HEMTT + +on: + push: + branches: + - master + pull_request_target: + +jobs: + windows: + runs-on: windows-latest + steps: + - name: Install Arma 3 Tools + uses: arma-actions/arma3-tools@master + with: + toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} + - name: Checkout the source code + uses: actions/checkout@v4 + - name: Setup HEMTT + uses: arma-actions/hemtt@v1 + - name: Checkout pull request + uses: actions/checkout@v4 + if: ${{ github.event_name == 'pull_request_target' }} + with: + path: pullrequest + ref: 'refs/pull/${{ github.event.number }}/merge' + - name: Replace addons with pull request addons + if: ${{ github.event_name == 'pull_request_target' }} + run: | + rm -r addons\ + rm -r optionals\ + rm -r include\ + xcopy /e /h /q pullrequest\addons addons\ + xcopy /e /h /q pullrequest\optionals optionals\ + xcopy /e /h /q pullrequest\include include\ + - name: Run HEMTT build + run: hemtt build + - name: Rename build folder + run: mv .hemttout/build .hemttout/@ace + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ace3-${{ github.sha }} + path: .hemttout/@* diff --git a/.github/workflows/pboproject.yml b/.github/workflows/pboproject.yml new file mode 100644 index 0000000000..71e36eb12b --- /dev/null +++ b/.github/workflows/pboproject.yml @@ -0,0 +1,85 @@ +name: pboProject + +on: + push: + branches: + - master + pull_request_target: + +jobs: + pboproject: + runs-on: windows-2022 + steps: + - name: Install Arma 3 Tools + uses: arma-actions/arma3-tools@master + with: + toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} + - name: Install Mikero Tools + uses: arma-actions/mikero-tools@2023-01-04 + - name: Download game data + run: | + Invoke-WebRequest "$env:ARMA3_DATA_URL" -OutFile arma3.zip + Invoke-WebRequest "$env:RHSAFRF_URL" -OutFile rhsafrf.zip + Invoke-WebRequest "$env:RHSGREF_URL" -OutFile rhsgref.zip + Invoke-WebRequest "$env:RHSSAF_URL" -OutFile rhssaf.zip + Invoke-WebRequest "$env:RHSUSF_URL" -OutFile rhsusf.zip + $files = @("arma3.zip", "rhsafrf.zip", "rhsgref.zip", "rhssaf.zip", "rhsusf.zip") + ForEach ($file in $files) { + Expand-7ZipArchive -Path $file -DestinationPath . + Remove-Item $file + } + env: + ARMA3_DATA_URL: ${{ secrets.ARMA3_DATA_URL }} + RHSAFRF_URL: ${{ secrets.RHSAFRF_URL }} + RHSGREF_URL: ${{ secrets.RHSGREF_URL }} + RHSSAF_URL: ${{ secrets.RHSSAF_URL }} + RHSUSF_URL: ${{ secrets.RHSUSF_URL }} + - name: Checkout CBA A3 + uses: actions/checkout@v4 + with: + path: x\cba + ref: master + repository: CBATeam/CBA_A3.git + - name: Checkout ACE3 + uses: actions/checkout@v4 + with: + path: z\ace + persist-credentials: false + - name: Checkout pull request + uses: actions/checkout@v4 + if: ${{ github.event_name == 'pull_request_target' }} + with: + path: pullrequest + ref: 'refs/pull/${{ github.event.number }}/merge' + - name: Replace addons with pull request addons + if: ${{ github.event_name == 'pull_request_target' }} + run: | + rm -r z\ace\addons\ + rm -r z\ace\optionals\ + rm -r z\ace\tools\pDummies\ + xcopy /e /h /q pullrequest\addons z\ace\addons\ + xcopy /e /h /q pullrequest\optionals z\ace\optionals\ + xcopy /e /h /q pullrequest\tools\pDummies z\ace\tools\pDummies\ + - name: Setup build environment + run: | + subst P: . + pboproject -P + xcopy /e /h /q z\ace\tools\pDummies\gm gm\ + xcopy /e /h /q z\ace\tools\pDummies\vn vn\ + xcopy /e /h /q z\ace\tools\pDummies\WW2 WW2\ + xcopy /e /h /q z\ace\tools\pDummies\CUP CUP\ + - name: Build + run: py P:\z\ace\tools\make.py ci + env: + PYTHONUNBUFFERED: 1 + - name: Archive logs + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: logs + path: temp/*.log + - name: Archive @ace + uses: actions/upload-artifact@v4 + with: + name: '@ace3-${{ github.sha }}' + path: z\ace\release\@ace diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000000..2130398964 --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,16 @@ +name: Release Drafter + +on: + push: + branches: + - master + +jobs: + draft: + runs-on: ubuntu-latest + steps: + - name: Release Drafter + if: github.repository == 'acemod/ACE3' + uses: release-drafter/release-drafter@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github_changelog_generator b/.github_changelog_generator deleted file mode 100644 index 6d1d741bbd..0000000000 --- a/.github_changelog_generator +++ /dev/null @@ -1,20 +0,0 @@ -# No issues and PRs without labels -issues=false -pr-wo-labels=false - -# Issues are disabled, don't fetch them -max-issues=0 - -# Label filters -exclude-labels=by design,can't reproduce,duplicate,question,invalid,wontfix,ignore changelog - -# Tag is created before generating changelog for release candidates -unreleased=false - -# No section labels, we only want a list of merged PRs (label separation only works for Issues) -simple-list=true - -# Misc -author=false -compare-link=false -header-label=## Change Log Summary diff --git a/.gitignore b/.gitignore index 6a37c85d53..4ad0a5e1eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,14 @@ @* *.zip release/* +releases/* +extensions/vcproj32/* +extensions/vcproj64/* +.vscode/* +hemtt +hemtt.exe +.hemttout tools/temp -tools/armake.exe *.cache *.pbo texHeaders.bin @@ -11,3 +17,7 @@ texHeaders.bin *.biprivatekey Thumbs.db CHANGELOG.md +sqfvm.exe +ArmaScriptCompiler.exe +*.sqfc +!extras/**/*.zip diff --git a/.hemtt/hooks/post_build/01_move_readmes.rhai b/.hemtt/hooks/post_build/01_move_readmes.rhai new file mode 100644 index 0000000000..8f359ade51 --- /dev/null +++ b/.hemtt/hooks/post_build/01_move_readmes.rhai @@ -0,0 +1,4 @@ +let docs_readmes = ["README.zh-TW.md", "README_DE.md", "README_PL.md"]; +for readme in docs_readmes { + HEMTT_VFS.join("docs").join(readme).move(HEMTT_VFS.join(readme)); +} diff --git a/.hemtt/hooks/post_release/01_rename_zip.rhai b/.hemtt/hooks/post_release/01_rename_zip.rhai new file mode 100644 index 0000000000..c8200358f8 --- /dev/null +++ b/.hemtt/hooks/post_release/01_rename_zip.rhai @@ -0,0 +1,9 @@ +let releases = HEMTT_RFS.join("releases"); + +let src = releases.join(HEMTT.project().prefix() + "-" + HEMTT.project().version().to_string() + ".zip"); +let dst = releases.join(HEMTT.project().name().to_lower() + "_" + HEMTT.project().version().to_string_short() + ".zip"); + +print("Moving zip to " + dst); +if !src.move(dst) { + fatal("Failed to move " + src + " to " + dst); +} diff --git a/.hemtt/hooks/pre_build/01_set_version.rhai b/.hemtt/hooks/pre_build/01_set_version.rhai new file mode 100644 index 0000000000..e34fe201be --- /dev/null +++ b/.hemtt/hooks/pre_build/01_set_version.rhai @@ -0,0 +1,12 @@ +let modcpp = HEMTT_VFS.join("mod.cpp").open_file().read(); +modcpp.replace("0.0.0", HEMTT.project().version().to_string_short()); +HEMTT_VFS.join("mod.cpp").create_file().write(modcpp); +print("mod.cpp version set"); + +let docs_readmes = ["README.zh-TW.md", "README_DE.md", "README_PL.md"]; +for readme in docs_readmes { + let readmemd = HEMTT_VFS.join("docs").join(readme).open_file().read(); + readmemd.replace("0.0.0", HEMTT.project().version().to_string_short()); + HEMTT_VFS.join("docs").join(readme).create_file().write(readmemd); + print(readme + " version set"); +} diff --git a/.hemtt/project.toml b/.hemtt/project.toml new file mode 100644 index 0000000000..f5ed361e3e --- /dev/null +++ b/.hemtt/project.toml @@ -0,0 +1,67 @@ +name = "ACE3" +prefix = "ace" +author = "ACE-Team" +mainprefix = "z" + +[files] +include = [ + "*.dll", + "*.so", + "mod.cpp", + "README*.md", # Translated READMEs get moved to root in a hook (virtual file system) + "AUTHORS.txt", + "LICENSE", + "logo_ace3_ca.paa", + "meta.cpp", +] + +[version] +git_hash = 0 + +# Unused in HEMTT v1.11 or higher, kept for backwards compatibility +[asc] +enabled = true +exclude = [ + ".inc.sqf", + "/dev/", + "common/functions/fnc_dummy.sqf", + "zeus/functions/fnc_zeusAttributes.sqf", +] + +[hemtt.launch.default] +workshop = [ + "450814997", # CBA_A3 +] + +[hemtt.launch.spe] +workshop = [ + "450814997", # CBA_A3 +] +dlc = [ + "spe" +] + +[hemtt.launch.vn] +workshop = [ + "450814997", # CBA_A3's Workshop ID +] +dlc = [ + "S.O.G. Prairie Fire", +] + +[hemtt.launch.ws] +workshop = [ + "450814997", # CBA_A3's Workshop ID +] +dlc = [ + "Western Sahara", +] + +[hemtt.launch.rhs] +workshop = [ + "450814997", # CBA_A3's Workshop ID + "843425103", # RHS AFRF Workshop ID + "843577117", # RHS USAF Workshop ID + "843593391", # RHS GREF Workshop ID + "843632231", # RHS SAF Workshop ID +] diff --git a/AUTHORS.txt b/AUTHORS.txt index 2e8263b6f2..27dad9464e 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -6,82 +6,102 @@ # request, preferably including an email address. # CORE TEAM +BaerMitUmlaut +Brett Mayson bux578 commy2 +Dahlgren +Drofseh esteldunedain Felix Wiegand Garth "L-H" de Wet Giallustio Glowbal +Grim Janus +johnb43 jokoho482 Jonpas Kieran +kymckay +mharis001 +MikeMF +MiszczuZPolski NouberNou PabstMirror Ruthberg -SilentSpike +tcvm tpM +veteran29 ViperMaul VKing Walter Pearce # CONTRIBUTORS -[BIG]Bull +10Dozen a.k.a Dusin 11RDP-LoupVert 654wak654 -ACCtomeek +[BIG]Bull +ACCtomeek adam3adam Adanteh aeroson Aggr094 alef Aleksey EpMAK Yermakov +AleM Alganthe Andrea "AtixNeon" Verano Anthariel -Arcanum417 Anton Arcanum417 Arkhir +ARV187 aka Spark23 Asgar Serran -BaerMitUmlaut Bamse +Barman75 Bla1337 BlackPixxel BlackQwar Brakoviejo -Brandon (TCVM) Brisse Brostrom.A | Evul BullHorn +C0kkie chris579 classicarma Clon1998 Codingboy Coren Crusty -C0kkie +Cyruz143 +dabako +dgibso29 Dharma Bellamkonda Dimaslg diwako dixon13 +Drift_91 Drill -Dudakov aka [OMCB]Kaban -Drofseh Dslyecxi +Dudakov aka [OMCB]Kaban Eclipser +Elgin675 ElTyranos eRazeri evromalarkey F3 Project Falke75 +Fatal Ferenczi Ferenzi FFAAMOD Filip Basara fr89k +Fragment +Frank FreeZbe +Fyuran geraldbolso1899 Ghost Gianmarco Varriale (TeamNuke) @@ -96,11 +116,18 @@ havena Hawkins Head Hybrid V +Hypoxic +JasperRab +JDT john681611 +JoramD Karneck Kavinsky Keithen Kllrt +KokaKolaA3 +Krzyciu +LAxemann legman Legolasindar "Viper" licht-im-Norden87 @@ -110,34 +137,45 @@ Luigi "Luigium" Myrini Macusercom MarcBook meat -mharis001 Michail Nikolaev MikeMatrix +mjc4wilton +Mysteryjuju nic547 nikolauska nomisum OnkelDisMaster Orbis2358 oscarmolinadev +Panisher (Tushino Serious Games) PaxJaromeMalues -PiZZADOX <509thParachuteInfantry@gmail.com> Phyma +PiZZADOX <509thParachuteInfantry@gmail.com> pokertour Professor +Pterolatypus +QuantX QuickDagger rakowozz ramius86 Raspu86 +RcINS Riccardo Petricca Robert Boklahánics ruPaladin Rutger "RedBery" Meijering +sancron +Schwaggot +Seb +shukari simon84 Skengman2 +Smith Sniperwolf572 System98 SzwedzikPL Tachi +tbeswick96 Tessa Elieff Timi007 Toaster @@ -147,7 +185,11 @@ Tuupertunut Valentin Torikian voiper VyMajoris(W-Cephei) +Walthzer Winter +wizpig64 +YetheSamartaka xrufix Zakant zGuba +Zman6258 diff --git a/Arma3_workshop_addon.jpg b/Arma3_workshop_addon.jpg deleted file mode 100644 index ffc430d688..0000000000 Binary files a/Arma3_workshop_addon.jpg and /dev/null differ diff --git a/Makefile b/Makefile deleted file mode 100644 index 736994ecb4..0000000000 --- a/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -VERSION = $(shell cat "VERSION") -PREFIX = ace -BIN = @ace -ZIP = ace3 -FLAGS = -i include -w unquoted-string -w redefinition-wo-undef -VERSION_FILES = README.md docs/README_DE.md docs/README_PL.md mod.cpp - -MAJOR = $(word 1, $(subst ., ,$(VERSION))) -MINOR = $(word 2, $(subst ., ,$(VERSION))) -PATCH = $(word 3, $(subst ., ,$(VERSION))) -BUILD = $(word 4, $(subst ., ,$(VERSION))) -VERSION_S = $(MAJOR).$(MINOR).$(PATCH) -GIT_HASH = $(shell git log -1 --pretty=format:"%H" | head -c 8) - -ifeq ($(OS), Windows_NT) - ARMAKE = ./tools/armake.exe # Downloaded via make.ps (rename armake_wXY.exe otherwise) -else - ARMAKE = armake -endif - -$(BIN)/addons/$(PREFIX)_%.pbo: addons/% - @mkdir -p $(BIN)/addons - @echo " PBO $@" - @${ARMAKE} build ${FLAGS} -f -e "version=$(GIT_HASH)" $< $@ - -$(BIN)/optionals/$(PREFIX)_%.pbo: optionals/% - @mkdir -p $(BIN)/optionals - @echo " PBO $@" - @${ARMAKE} build ${FLAGS} -f -e "version=$(GIT_HASH)" $< $@ - -# Shortcut for building single addons (eg. "make .pbo") -%.pbo: - "$(MAKE)" $(MAKEFLAGS) $(patsubst %, $(BIN)/addons/$(PREFIX)_%, $@) - -all: $(patsubst addons/%, $(BIN)/addons/$(PREFIX)_%.pbo, $(wildcard addons/*)) \ - $(patsubst optionals/%, $(BIN)/optionals/$(PREFIX)_%.pbo, $(wildcard optionals/*)) - -filepatching: - "$(MAKE)" $(MAKEFLAGS) FLAGS="-w unquoted-string -p" - -$(BIN)/keys/%.biprivatekey: - @mkdir -p $(BIN)/keys - @echo " KEY $@" - @${ARMAKE} keygen -f $(patsubst $(BIN)/keys/%.biprivatekey, $(BIN)/keys/%, $@) - -$(BIN)/addons/$(PREFIX)_%.pbo.$(PREFIX)_$(VERSION)-$(GIT_HASH).bisign: $(BIN)/addons/$(PREFIX)_%.pbo $(BIN)/keys/$(PREFIX)_$(VERSION).biprivatekey - @echo " SIG $@" - @${ARMAKE} sign -f -s $@ $(BIN)/keys/$(PREFIX)_$(VERSION).biprivatekey $< - -$(BIN)/optionals/$(PREFIX)_%.pbo.$(PREFIX)_$(VERSION)-$(GIT_HASH).bisign: $(BIN)/optionals/$(PREFIX)_%.pbo $(BIN)/keys/$(PREFIX)_$(VERSION).biprivatekey - @echo " SIG $@" - @${ARMAKE} sign -f -s $@ $(BIN)/keys/$(PREFIX)_$(VERSION).biprivatekey $< - -signatures: $(patsubst addons/%, $(BIN)/addons/$(PREFIX)_%.pbo.$(PREFIX)_$(VERSION)-$(GIT_HASH).bisign, $(wildcard addons/*)) \ - $(patsubst optionals/%, $(BIN)/optionals/$(PREFIX)_%.pbo.$(PREFIX)_$(VERSION)-$(GIT_HASH).bisign, $(wildcard optionals/*)) - -extensions: $(wildcard extensions/*/*) - cd extensions/build && cmake .. && make - find ./extensions/build/ \( -name "*.so" -o -name "*.dll" \) -exec cp {} ./ \; - -extensions-win64: $(wildcard extensions/*/*) - cd extensions/build && CXX=$(eval $(which g++-w64-mingw-i686)) cmake .. && make - -version: - @echo " VER $(VERSION)" - $(shell sed -i -r -s 's/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/$(VERSION)/g' $(VERSION_FILES)) - $(shell sed -i -r -s 's/[0-9]+\.[0-9]+\.[0-9]+/$(VERSION_S)/g' $(VERSION_FILES)) - @echo -e "#define MAJOR $(MAJOR)\n#define MINOR $(MINOR)\n#define PATCHLVL $(PATCH)\n#define BUILD $(BUILD)" > "addons/main/script_version.hpp" - $(shell sed -i -r -s 's/ACE_VERSION_MAJOR [0-9]+/ACE_VERSION_MAJOR $(MAJOR)/g' extensions/CMakeLists.txt) - $(shell sed -i -r -s 's/ACE_VERSION_MINOR [0-9]+/ACE_VERSION_MINOR $(MINOR)/g' extensions/CMakeLists.txt) - $(shell sed -i -r -s 's/ACE_VERSION_REVISION [0-9]+/ACE_VERSION_REVISION $(PATCH)/g' extensions/CMakeLists.txt) - -commit: - @echo " GIT commit release preparation" - @git add -A - @git diff-index --quiet HEAD || git commit -am "Prepare release $(VERSION_S)" -q - -push: commit - @echo " GIT push release preparation" - @git push -q - -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) - @zip -qr $(ZIP)_$(VERSION_S).zip $(BIN) - -clean: - rm -rf $(BIN) $(ZIP)_*.zip - -.PHONY: all filepatching signatures extensions extensions-win64 version commit push release clean diff --git a/README.md b/README.md index 74e32e1fac..feb9194d65 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@

- + +

- ACE3 Version + ACE3 Version ACE3 Issues @@ -18,11 +19,8 @@ ACE3 License - - ACE3 Slack - - - ACE3 Build Status + + ACE3 Discord

@@ -76,10 +74,10 @@ The mod is **built modularly**, so almost any included PBO can be easily removed ## Getting started -ACE3 requires Arma 3 and the latest version of CBA A3. See the following pages for help and information on how to get started with ACE3: +ACE3 requires Arma 3 and the latest version of CBA A3. See the following pages for help and information on how to get started with ACE3: -- [Installation guide](https://ace3mod.com/wiki/user/installation-guide.html) -- [Information center](https://ace3mod.com/wiki/user/information-center.html) +- [Installation guide](https://ace3.acemod.org/wiki/user/installation-guide.html) +- [Information center](https://ace3.acemod.org/wiki/user/information-center.html) ## Contributing @@ -87,26 +85,24 @@ You can help out with the ongoing development by looking for potential bugs in o ### Contribution guidelines -To contribute something to ACE3, simply fork this repository and submit your pull requests for review by other collaborators. Remember to add yourself to the author array of any PBO you will be editing and the [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) file; including a valid email address. +To contribute something to ACE3, simply fork this repository and submit your pull requests for review by other collaborators. See [the pull request guidelines](https://ace3.acemod.org/wiki/development/merging-pull-requests.html) for further information on this process. ### Submitting issues and requesting features Please, use our [Issue Tracker](https://github.com/acemod/ACE3/issues) to report a bug, propose a feature, or suggest changes to the existing ones. See also: -- [How to report an issue](https://ace3mod.com/wiki/user/how-to-report-an-issue.html) -- [How to make a feature request](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) +- [How to report an issue](https://ace3.acemod.org/wiki/user/how-to-report-an-issue.html) +- [How to make a feature request](https://ace3.acemod.org/wiki/user/how-to-make-a-feature-request.html) ### Testing & building -To help us test the latest development changes, download our master branch ([directly](https://github.com/acemod/ACE3/archive/master.zip), or [with git](https://help.github.com/articles/fetching-a-remote/)), then assemble a test build: - -- [Setting up the development environment](https://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – step-by-step instructions on how to properly setup and build a version of ACE3 for testing purposes. +To help us test the latest development changes, download the [artifact](https://github.com/acemod/ACE3/actions/workflows/arma.yml) of the branch you'd like to test or subscribe to "Anrop ACE3 Master" on the workshop to test `master` branch. Alternatively [build your own version](https://ace3.acemod.org/wiki/development/setting-up-the-development-environment.html). ### Get in touch - - + + @@ -121,7 +117,7 @@ To help us test the latest development changes, download our master branch ([dir - +
SlackWe have a public Slack team that anyone can join. This is where all our developers and contributors hang out and where we make announcementsDiscordWe have a public Discord server that anyone can join. This is where all our developers and contributors hang out and where we make announcements
Bohemia Forum We have a dedicated thread on the Bohemia Forums for the ACE3 project
## License diff --git a/VERSION b/VERSION deleted file mode 100644 index d87a10b470..0000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.12.6.43 diff --git a/ace_artillerytables.dll b/ace_artillerytables.dll new file mode 100644 index 0000000000..2f5855c81a Binary files /dev/null and b/ace_artillerytables.dll differ diff --git a/ace_artillerytables_x64.dll b/ace_artillerytables_x64.dll new file mode 100644 index 0000000000..97a061c257 Binary files /dev/null and b/ace_artillerytables_x64.dll differ 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/ace_parse_imagepath.dll b/ace_parse_imagepath.dll deleted file mode 100644 index f252410bcd..0000000000 Binary files a/ace_parse_imagepath.dll and /dev/null differ diff --git a/ace_parse_imagepath_x64.dll b/ace_parse_imagepath_x64.dll deleted file mode 100644 index 8d154117c5..0000000000 Binary files a/ace_parse_imagepath_x64.dll and /dev/null differ diff --git a/addons/advanced_ballistics/ACE_Settings.hpp b/addons/advanced_ballistics/ACE_Settings.hpp index c25592eb5d..a34547249c 100644 --- a/addons/advanced_ballistics/ACE_Settings.hpp +++ b/addons/advanced_ballistics/ACE_Settings.hpp @@ -1,45 +1,20 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(DisplayName); - displayName = CSTRING(enabled_DisplayName); - description = CSTRING(enabled_Description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(muzzleVelocityVariationEnabled) { - category = CSTRING(DisplayName); - displayName = CSTRING(muzzleVelocityVariationEnabled_DisplayName); - description = CSTRING(muzzleVelocityVariationEnabled_Description); - typeName = "BOOL"; - value = 1; - }; + movedToSQF = 1; + }; class GVAR(ammoTemperatureEnabled) { - category = CSTRING(DisplayName); - displayName = CSTRING(ammoTemperatureEnabled_DisplayName); - description = CSTRING(ammoTemperatureEnabled_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(barrelLengthInfluenceEnabled) { - category = CSTRING(DisplayName); - displayName = CSTRING(barrelLengthInfluenceEnabled_DisplayName); - description = CSTRING(barrelLengthInfluenceEnabled_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(bulletTraceEnabled) { - category = CSTRING(DisplayName); - displayName = CSTRING(bulletTraceEnabled_DisplayName); - description = CSTRING(bulletTraceEnabled_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(simulationInterval) { - category = CSTRING(DisplayName); - displayName = CSTRING(simulationInterval_DisplayName); - description = CSTRING(simulationInterval_Description); - typeName = "SCALAR"; - value = 0.05; - sliderSettings[] = {0, 0.2, 0.05, 2}; + movedToSQF = 1; }; }; diff --git a/addons/advanced_ballistics/CfgEventHandlers.hpp b/addons/advanced_ballistics/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/advanced_ballistics/CfgEventHandlers.hpp +++ b/addons/advanced_ballistics/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/advanced_ballistics/README.md b/addons/advanced_ballistics/README.md index 122769b191..ebd377bab6 100644 --- a/addons/advanced_ballistics/README.md +++ b/addons/advanced_ballistics/README.md @@ -2,10 +2,3 @@ ace_advanced_ballistics =============== The Advanced Ballistics module introduces advanced external- and internal ballistics to the game. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/advanced_ballistics/RscTitles.hpp b/addons/advanced_ballistics/RscTitles.hpp index 6deaf0a058..759f341a0c 100644 --- a/addons/advanced_ballistics/RscTitles.hpp +++ b/addons/advanced_ballistics/RscTitles.hpp @@ -42,14 +42,14 @@ class RscTitles { x="SafeZoneX + 0.001"; y="SafeZoneY + 0.001"; w=0.2; - h=0.2*4/3; + h="0.2*4/3"; size=0.034; sizeEx=0.027; text=""; }; - class RscProtractorMarker : RscProtractorBase { + class RscProtractorMarker: RscProtractorBase { idc=132951; }; }; }; -}; \ No newline at end of file +}; diff --git a/addons/advanced_ballistics/XEH_postInit.sqf b/addons/advanced_ballistics/XEH_postInit.sqf index 1e0e6860da..9d0dd0ee4b 100644 --- a/addons/advanced_ballistics/XEH_postInit.sqf +++ b/addons/advanced_ballistics/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" - GVAR(currentbulletID) = -1; GVAR(Protractor) = false; @@ -11,7 +9,9 @@ GVAR(currentGrid) = 0; if (!hasInterface) exitWith {}; -["ace_settingsInitialized", { +#include "initKeybinds.inc.sqf" + +["CBA_settingsInitialized", { //If not enabled, dont't add PFEH if (!GVAR(enabled)) exitWith {}; @@ -19,13 +19,16 @@ if (!hasInterface) exitWith {}; [] call FUNC(initializeTerrainExtension); // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + + // Register Perframe Handler + [LINKFUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler; //Add warnings for missing compat PBOs (only if AB is on) { _x params ["_modPBO", "_compatPBO"]; - if ((isClass (configFile >> "CfgPatches" >> _modPBO)) && {!isClass (configFile >> "CfgPatches" >> _compatPBO)}) then { + if ([_modPBO] call EFUNC(common,isModLoaded) && {!([_compatPBO] call EFUNC(common,isModLoaded))}) then { WARNING_2("Weapon Mod [%1] missing ace compat pbo [%2] (from @ace\optionals)",_modPBO,_compatPBO); }; } forEach [ diff --git a/addons/advanced_ballistics/XEH_preInit.sqf b/addons/advanced_ballistics/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/advanced_ballistics/XEH_preInit.sqf +++ b/addons/advanced_ballistics/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; 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_calculateAmmoTemperatureVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf index 2ead82fa12..6bc5a82fa2 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * diff --git a/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf b/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf index b574698931..c8486d7040 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * diff --git a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf index e28ccd2523..5cf4a3af72 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg, MikeMatrix, joko // Jonas * diff --git a/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf b/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf index 184ee6970d..ccd7363f9b 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * diff --git a/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf b/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf index cf6dbb03b1..2ee8ce3e3a 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * diff --git a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf index d2f5cba98f..a2156349f6 100644 --- a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf +++ b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf @@ -1,5 +1,5 @@ #define DEBUG_MODE_FULL -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * @@ -68,7 +68,7 @@ for "_i" from 0 to (count _cfgWeapons)-1 do { private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _vanillaInitialSpeed] call FUNC(calculateBarrelLengthVelocityShift); private _abInitialSpeed = _vanillaInitialSpeed + _barrelVelocityShift; // -------------------------------------------------- - + if (_weapon find "_base" == -1 && _weapon find "_Base" == -1) then { #ifdef DEBUG_INIT_SPEEDS _data pushBack [-_forEachIndex, _abInitialSpeed, _magazine, _weapon]; diff --git a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf index 714aaa31ef..ceaef17bad 100644 --- a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf +++ b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 0c18ae539e..e9180cb1c4 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg, joko // Jonas * Handle the PFH for Bullets @@ -15,12 +15,11 @@ * Public: No */ +private _deleted = false; { _x params ["_bullet","_caliber","_bulletTraceVisible","_index"]; - if (!alive _bullet) then { - GVAR(allBullets) deleteAt (GVAR(allBullets) find _x); - } else { + if (alive _bullet) then { private _bulletVelocity = velocity _bullet; private _bulletPosition = getPosASL _bullet; @@ -29,11 +28,12 @@ }; _bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6", _index, _bulletVelocity, _bulletPosition, wind, ASLToATL(_bulletPosition) select 2, CBA_missionTime toFixed 6]))); + } else { + GVAR(allBullets) set [_forEachIndex, objNull]; + _deleted = true; }; - nil -} count +GVAR(allBullets); +} forEach GVAR(allBullets); -if (GVAR(allBullets) isEqualTo []) then { - [_this select 1] call CBA_fnc_removePerFrameHandler; - GVAR(BulletPFH) = nil; +if (_deleted) then { + GVAR(allBullets) = GVAR(allBullets) - [objNull]; }; diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index b1f9898b6d..ff2fe85ae4 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * @@ -17,9 +17,9 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; if (!alive _projectile) exitWith {}; if (underwater _unit) exitWith {}; @@ -27,25 +27,27 @@ private _abort = !local _unit; if (_abort) then { private _bulletVelocity = velocity _projectile; private _muzzleVelocity = vectorMagnitude _bulletVelocity; - + private _maxRange = uiNamespace getVariable format[QGVAR(maxRange_%1), _ammo]; if (isNil "_maxRange") then { private _airFriction = getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction"); - private _maxRange = if (_airFriction < 0) then { + private _vanillaInitialSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); + _maxRange = if (_airFriction < 0) then { private _maxTime = ((_vanillaInitialSpeed - BULLET_TRACE_MIN_VELOCITY) / (BULLET_TRACE_MIN_VELOCITY * -_airFriction * _vanillaInitialSpeed)) max getNumber(configFile >> "CfgAmmo" >> _ammo >> "tracerEndTime"); -ln(1 - _airFriction * _vanillaInitialSpeed * _maxTime) / _airFriction } else { _vanillaInitialSpeed * getNumber(configFile >> "CfgAmmo" >> _ammo >> "tracerEndTime") }; + _maxRange = _maxRange * 1.3; // Adding 30% more to range just to be safe uiNamespace setVariable [format[QGVAR(maxRange_%1), _ammo], _maxRange]; }; if (ACE_player distance _unit > _maxRange && {ACE_player distance ((getPosASL _unit) vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply _maxRange)) > _maxRange}) exitWith {}; - + private _ammoCount = (_unit ammo _muzzle) + 1; private _tracersEvery = getNumber(configFile >> "CfgMagazines" >> _magazine >> "tracersEvery"); private _lastRoundsTracer = getNumber(configFile >> "CfgMagazines" >> _magazine >> "lastRoundsTracer"); if (_ammoCount <= _lastRoundsTracer || {_tracersEvery > 0 && {(_ammoCount - _lastRoundsTracer) % _tracersEvery == 0}}) exitWith { _abort = false }; - + if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then { if (currentWeapon ACE_player == binocular ACE_player) exitWith { _abort = false }; if (currentWeapon ACE_player == primaryWeapon ACE_player && {count primaryWeaponItems ACE_player > 2}) then { @@ -89,7 +91,7 @@ if (GVAR(muzzleVelocityVariationEnabled)) then { private _seed = 0.5 * (_time + _ammoCount) * (_time + _ammoCount + 1) + _ammoCount; // Generate normally distributed random number (via Box–Muller transform) private _z = sqrt(-2.0 * ln(0.00000001 max (-_seed random 1))) * cos(_seed random 360); - + _muzzleVelocity = _muzzleVelocity * (_z * _muzzleVelocityVariationSD + 1); }; @@ -123,7 +125,3 @@ GVAR(currentbulletID) = (GVAR(currentbulletID) + 1) % 10000; "ace_advanced_ballistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", GVAR(currentbulletID), _ammoCount, _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _transonicStabilityCoef, getPosASL _projectile, _bulletVelocity, EGVAR(common,mapLatitude), EGVAR(weather,currentTemperature), EGVAR(common,mapAltitude), EGVAR(weather,currentHumidity), EGVAR(weather,currentOvercast), CBA_missionTime toFixed 6]; GVAR(allBullets) pushBack [_projectile, _caliber, _bulletTraceVisible, GVAR(currentbulletID)]; - -if (isNil QGVAR(BulletPFH)) then { - GVAR(BulletPFH) = [FUNC(handleFirePFH), GVAR(simulationInterval), []] call CBA_fnc_addPerFrameHandler; -}; diff --git a/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf b/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf index 83e11175d3..4bb5d080cd 100644 --- a/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf +++ b/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the advanced ballistics settings diff --git a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf index 5c634cadff..89e89b9f7e 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" +#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 @@ -19,10 +19,10 @@ if (!hasInterface) exitWith {}; if (!GVAR(enabled)) exitWith {}; private _initStartTime = diag_tickTime; -private _mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize"); +private _mapSize = worldSize; if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith { - INFO_1("Terrain already initialized [world: %1]", worldName); + INFO_1("Terrain already initialized [world: %1]",worldName); #ifdef DEBUG_MODE_FULL systemChat "AdvancedBallistics: Terrain already initialized"; #endif @@ -33,14 +33,14 @@ private _gridCells = _mapGrids * _mapGrids; GVAR(currentGrid) = 0; -INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldName); +INFO_2("Starting Terrain Extension [cells: %1] [world: %2]",_gridCells,worldName); [{ params ["_args","_idPFH"]; _args params ["_mapGrids", "_gridCells", "_initStartTime"]; if (GVAR(currentGrid) >= _gridCells) exitWith { - INFO_2("Finished terrain initialization in %1 seconds [world: %2]", (diag_tickTime - _initStartTime) toFixed 2, worldName); + INFO_2("Finished terrain initialization in %1 seconds [world: %2]",(diag_tickTime - _initStartTime) toFixed 2,worldName); #ifdef DEBUG_MODE_FULL systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2]; #endif @@ -53,7 +53,7 @@ INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldNa private _gridCenter = [_x + 25, _y + 25]; private _gridHeight = round(getTerrainHeightASL _gridCenter); private _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]); - private _gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0}; + private _gridSurfaceIsWater = parseNumber (surfaceIsWater _gridCenter); "ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater]; GVAR(currentGrid) = GVAR(currentGrid) + 1; if (GVAR(currentGrid) >= _gridCells) exitWith {}; diff --git a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf index 13b4692452..5190786924 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * @@ -40,10 +40,13 @@ if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); -if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then { +if !(_dragModel in [1, 2, 5, 6, 7, 8]) then { _dragModel = 1; }; private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); +if (_ballisticCoefficients isEqualTo []) then { + _ballisticCoefficients = [0.5]; +}; private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries"); private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere"); if (_atmosphereModel isEqualTo "") then { @@ -60,20 +63,20 @@ private _barrelLengthTable = getArray(_ammoConfig >> "ACE_barrelLengths"); //Handle subsonic ammo that would have a huge muzzle velocity shift (when ballistic configs not explicitly defined) private _typicalSpeed = getNumber (_ammoConfig >> "typicalSpeed"); if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then { - private _inheritedBarrelConfig = (!(_muzzleVelocityTable isEqualTo [])) && {(configProperties [_ammoConfig, "(configName _x) == 'ACE_muzzleVelocities'", false]) isEqualTo []}; - private _inheritedTempConfig = (!(_ammoTempMuzzleVelocityShifts isEqualTo [])) && {(configProperties [_ammoConfig, "(configName _x) == 'ACE_ammoTempMuzzleVelocityShifts'", false]) isEqualTo []}; + private _inheritedBarrelConfig = (_muzzleVelocityTable isNotEqualTo []) && {(configProperties [_ammoConfig, "(configName _x) == 'ACE_muzzleVelocities'", false]) isEqualTo []}; + private _inheritedTempConfig = (_ammoTempMuzzleVelocityShifts isNotEqualTo []) && {(configProperties [_ammoConfig, "(configName _x) == 'ACE_ammoTempMuzzleVelocityShifts'", false]) isEqualTo []}; TRACE_3("subsonic",_typicalSpeed,_inheritedBarrelConfig,_inheritedTempConfig); if (_inheritedBarrelConfig || _inheritedTempConfig) then { private _parentConfig = inheritsFrom _ammoConfig; private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed"); - WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig, _parentSpeed); + WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig,_parentSpeed); if (_parentSpeed <= 0) exitWith {//Handle weird or null parent _muzzleVelocityTable = []; _ammoTempMuzzleVelocityShifts = []; }; private _linearMuliplier = _typicalSpeed / _parentSpeed; if (_inheritedBarrelConfig) then { - if (!((configProperties [_parentConfig, "(configName _x) == 'ACE_muzzleVelocities'", false]) isEqualTo [])) then { + if ((configProperties [_parentConfig, "(configName _x) == 'ACE_muzzleVelocities'", false]) isNotEqualTo []) then { TRACE_2("Parent Has Defined Barrel MV",_linearMuliplier,_muzzleVelocityTable); { _muzzleVelocityTable set [_forEachIndex, (_x * _linearMuliplier)]; } forEach _muzzleVelocityTable; } else { @@ -82,7 +85,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then { }; }; if (_inheritedTempConfig) then { - if (!((configProperties [_parentConfig, "(configName _x) == 'ACE_ammoTempMuzzleVelocityShifts'", false]) isEqualTo [])) then { + if ((configProperties [_parentConfig, "(configName _x) == 'ACE_ammoTempMuzzleVelocityShifts'", false]) isNotEqualTo []) then { TRACE_2("Parent Has Defined Ammo Temp Shifts",_linearMuliplier,_muzzleVelocityTable); { _ammoTempMuzzleVelocityShifts set [_forEachIndex, (_x * _linearMuliplier)]; } forEach _ammoTempMuzzleVelocityShifts; } else { diff --git a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf index dbc9999824..c79aeaf2ea 100644 --- a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * @@ -21,7 +21,7 @@ private _weaponConfig = (configFile >> "CfgWeapons" >> _this); private _barrelTwist = 0 max getNumber(_weaponConfig >> "ACE_barrelTwist"); -private _twistDirection = [0, 1] select (_barrelTwist != 0); +private _twistDirection = parseNumber (_barrelTwist != 0); if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { _twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection"); if !(_twistDirection in [-1, 0, 1]) then { diff --git a/addons/advanced_ballistics/functions/script_component.hpp b/addons/advanced_ballistics/functions/script_component.hpp deleted file mode 100644 index 2c718bf9db..0000000000 --- a/addons/advanced_ballistics/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\advanced_ballistics\script_component.hpp" \ No newline at end of file diff --git a/addons/advanced_ballistics/initKeybinds.sqf b/addons/advanced_ballistics/initKeybinds.inc.sqf similarity index 100% rename from addons/advanced_ballistics/initKeybinds.sqf rename to addons/advanced_ballistics/initKeybinds.inc.sqf diff --git a/addons/advanced_ballistics/initSettings.inc.sqf b/addons/advanced_ballistics/initSettings.inc.sqf new file mode 100644 index 0000000000..957044f343 --- /dev/null +++ b/addons/advanced_ballistics/initSettings.inc.sqf @@ -0,0 +1,49 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_DisplayName), LSTRING(enabled_Description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(muzzleVelocityVariationEnabled), "CHECKBOX", + [LSTRING(muzzleVelocityVariationEnabled_DisplayName), LSTRING(muzzleVelocityVariationEnabled_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(ammoTemperatureEnabled), "CHECKBOX", + [LSTRING(ammoTemperatureEnabled_DisplayName), LSTRING(ammoTemperatureEnabled_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(barrelLengthInfluenceEnabled), "CHECKBOX", + [LSTRING(barrelLengthInfluenceEnabled_DisplayName), LSTRING(barrelLengthInfluenceEnabled_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(bulletTraceEnabled), "CHECKBOX", + [LSTRING(bulletTraceEnabled_DisplayName), LSTRING(bulletTraceEnabled_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(simulationInterval), "SLIDER", + [LSTRING(simulationInterval_DisplayName), LSTRING(simulationInterval_Description)], + _category, + [0, 0.2, 0.05, 2], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/advanced_ballistics/stringtable.xml b/addons/advanced_ballistics/stringtable.xml index 6d57aed254..b077f53b6a 100644 --- a/addons/advanced_ballistics/stringtable.xml +++ b/addons/advanced_ballistics/stringtable.xml @@ -4,9 +4,9 @@ Show Wind Info Pokaż inf. o wietrze - Mostra indicazioni del vento + Mostra indicazioni vento Показать информацию о ветре - Afficher les info sur le vent + Afficher les infos sur le vent Mostrar información del viento Windinformationen anzeigen Széladatok mutatása @@ -16,10 +16,11 @@ 바람의 정보를 표시 顯示風況 显示风况 + Rüzgar bilgilerini göster Show Protractor - Pokaż kątomierz + Pokaż protraktor Mostra il rapportatore Показать транспортир Afficher le rapporteur @@ -32,6 +33,7 @@ 각도기 표시 顯示量角器 显示量角器 + Açı Ölçeri Göster Advanced Ballistics @@ -44,10 +46,11 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata - アドバンスド バリスティックス + アドバンスド弾道計算 고급 탄도학 先進彈道系統 - 先进弹道系统 + 进阶弹道系统 + Gelişmiş Balistik Advanced Ballistics @@ -60,10 +63,11 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata - アドバンスド バリスティックス + アドバンスド弾道計算を有効化 고급 탄도학 先進彈道系統 - 先进弹道系统 + 进阶弹道系统 + Gelişmiş Balistik Enables advanced ballistics @@ -71,39 +75,48 @@ Activa la balística avanzada Aktiviert die erweiterte Ballistik Aktivuje pokročilou balistiku - Ativa balística avançada - Activer la balistique avancée + Ativa a balística avançada + Active la balistique avancée. Engedélyezi a fejlett ballisztikát Включает продвинутую баллистику Abilita Balistica Avanzata - アドバンスド バリスティックスを有効化します。 + アドバンスド弾道計算は高度な弾道計算処理を有効化します。 고급 탄도학을 적용합니다 啟用先進彈道系統 - 启用先进弹道系统 + 启用进阶弹道系统 + Gelişmiş balistiği etkinleştir Enable Muzzle Velocity Variation + Activar variación de velocidad inicial Variation der Mündungsgeschwindigkeit aktivieren - 銃口初速の変動を有効化する + 銃口初速の変動を有効化 Abilita Variazione Velocità Volata 총구속도 변화적용 啟用槍口初速變化 启用枪口初速变化 - Activer les variations de la vitesse initiale + Activer la variation de vitesse initiale Aktywuj wariację prędkości wylotowej Вкл. вариацию начальной скорости + Ativar Variação de Velocidade no Freio de boca + Povoluje variantu rychlosti ústí + Namlu Hızı Değişimini Etkinleştir Simulates slight variations in muzzle velocity between each shot + Simula variaciones ligeras de velocidad entre cada disparo Simuliert leichte Variationen der Mündungsgeschwindigkeit zwischen jedem Schuss. - 発射毎の銃口初速の変動をシミュレートします。 - Simula lievi variazioni della velocità della volata tra un colpo e l'altro + 各発射毎の銃口初速のわずかな変動をシミュレートします。 + Simula piccole variazioni della velocità alla volata tra ogni colpo. 각 사격 사이에 총구속도 변화를 시뮬레이션 합니다. 模擬每發子彈的槍口初速都略有不同 模拟每发子弹的枪口初速都略有不同 - Simule les légères variations + Simule de légères variations de vitesse initiale entre chaque tir. 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 + Simuluje malé odchylky v úsťové rychlosti mezi jednotlivými výstřely + Her atış arasında namlu çıkış hızındaki küçük değişiklikleri simüle eder Enable Ammo Temperature Simulation @@ -112,14 +125,15 @@ Simulation der Munitionstemperatur aktivieren Povolit simulaci teploty munice Ativar simulação de temperatura de munição - Active la simulation de la température + Activer la simulation de la température Lőszer-hő szimuláció engedélyezése Симуляция температуры для боеприпасов - Abilita simulazione della temperatura delle munizioni - 弾薬温度のシミュレーションを有効化する + Abilita simulazione temperatura munizioni + 弾薬温度シミュレーションを有効化 탄약 온도 구현 적용 啟用彈藥溫度模擬系統 启用弹药温度模拟系统 + Cephane Sıcaklık Simülasyonunu Etkinleştir Muzzle velocity varies with ammo temperature @@ -128,14 +142,15 @@ Munitionstemperatur hat Einfluss auf die Mündungsgeschwindigkeit Úsťová rychlost je závislá na teplotě munice A velocidade de saída varia com a temperatura da munição - La température de la munition influe sur la vélocité intiale + La vitesse initiale varie en fonction de la température des munitions. A kezdősebesség a lőszer hőmérsékletétől függően változó Начальная скорость пули зависит от температуры - La velocità dello sparo varia a seconda della temperatura delle munizioni + La velocità alla volata varia a seconda della temperatura delle munizioni. 弾薬の温度により銃口初速を変動させます。 탄약 온도에 비례해 총구 속도가 달라집니다 子彈初速將隨彈藥溫度而有所變化 子弹初速将随弹药温度而有所变化 + Mermi çıkış hızı cephane sıcaklığına göre değişir Enable Barrel Length Simulation @@ -147,11 +162,12 @@ Activer la simulation de la longueur de canon Csőhossz-szimuláció engedélyezése Симуляция длины ствола - Abilita simulazione della lunghezza della canna - 銃身長のシミュレーションを有効化する + Abilita simulazione lunghezza canna + 銃身長シミュレーションを有効化 총열 길이 구현 적용 啟用槍管長度模擬系統 启用枪管长度模拟系统 + Namlu Uzunluğu Simülasyonunu Etkinleştir Muzzle velocity varies with barrel length @@ -160,14 +176,15 @@ Lauflänge beeinflusst Mündungsgeschwindigkeit Úsťová rychlost je závislá na délce hlavně A velocidade de saída caria com o comprimento do cano - La longueur du canon influe sur la vélocité initale + La vitesse initiale varie en fonction de la longueur du canon. A kezdősebesség a cső hosszától függően változó Начальная скорость пули зависит от длины ствола - La velocità di sparo varia a seconda della lunghezza della canna + La velocità alla volata varia a seconda della lunghezza della canna. 銃身長により銃口初速を変動させます。 총구 속도가 총열에 비례해 달라집니다 子彈初速將隨槍管長度而有所變化 子弹初速将随枪管长度而有所变化 + Mermi çıkış hızı namlu uzunluğuna göre değişir Enable Bullet Trace Effect @@ -176,14 +193,15 @@ Geschossspureffekt aktivieren Povolit efekt trasírek Ativa efeito traçante de projétil - Activer l'effet balle traçante + Activer l'effet de balle traçante Nyomkövető-effekt engedélyezése Следы пуль - Abilita effetto dei Proiettili Traccianti - 弾丸の軌跡エフェクトを有効化する + Abilita effetto di traccia proiettile + 弾丸の軌跡エフェクトを有効化 예광탄 효과 적용 啟用曳光彈效果 - 启用曳光弹效果 + 启用子弹尾迹效果 + İzli Mermi Etkisini Etkinleştir Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics) @@ -192,14 +210,15 @@ Aktiviere Geschossspureffekt für hohe Kaliber (bei Benutzung von Optiken mit starker Vergrößerung) Aktivuje efekt trasírek z vysokokaliberních zbraní (viditelné pouze skrze výkonnou optiku) Ativa o efeito traçante de projétil para projéteis de alto calibre (somente visível quando observado por miras telescópicas) - Active une tracante pour les munitions de gros calibre (seulement visible en utilisant des optiques avancées) + Active un effet de balle traçante pour les munitions de gros calibre (seulement visible en utilisant une optique à fort grossissement). Engedélyezi a nagy kaliberű lövedékek nyomának vizuális követését (csak nagy teljesítményű optikán keresztül látható) Включает эффект следов пуль для больших калибров (видны только через мощную оптику) - Abilita effetto dei proiettili traccianti di alto calibro (visibile solo attraverso ottiche ad alto potenziale) + Abilita effetto di traccia lasciata da proiettili di alto calibro (visibile solo attraverso ottiche ad alto ingrandimento) 大口径弾の軌跡エフェクトを有効化します。 (高性能光学機器を介してのみ見ることができます) 대구경 탄환에 예광탄 효과를 적용합니다(오직 고성능 조준경 사용시에만 보입니다) 啟用曳光彈效果給大口徑子彈 (只有透過高倍率光學瞄鏡才能看到) - 启用曳光弹效果给大口径子弹 (只有透过高倍率光学瞄镜才能看到) + 给大口径子弹启用子弹尾迹效果(只有透过高倍率光学瞄镜才能看到) + Yüksek kalibreli mermilere mermi izleme efekti sağlar (yalnızca yüksek güçlü optiklerden bakıldığında görülebilir) Simulation Interval @@ -211,8 +230,8 @@ Intervalle de simulation Szimuláció intervalluma Интервал симуляции - Intervallo Simulazione - シミュレーションの間隔 + Intervallo di Simulazione + シミュレーション間隔 구현 간격 模擬間隔 模拟间隔 @@ -224,14 +243,14 @@ Definiert das Intervall zwischen den einzelnen Simulationsschritten Určuje interval mezi každým výpočtem Define o intervalo entre cada cálculo - Définit un intervalle de calcul entre deux simulations + Définit l'intervalle entre chacune des étapes de calcul. Meghatározza a számítási lépések közötti időintervallumot Определяет временной интервал между вычислениями - Definisce l'intervallo tra ogni step di calcolo - 各計算毎の間隔を定義します。 + Definisce l'intervallo tra ogni passo del calcolo + 各シミュレーション毎の間隔を定義します。 각 계산 단위의 간격을 정의합니다 定義每個模擬計算之間的時間間隔 - 定义每个模拟计算之间的时间间隔 + 定义每个计算步骤之间的间隔 Simulation Radius @@ -239,15 +258,16 @@ Radio de simulación Simulationsradius Rozsah simulace - Raio de simulação + Raio da simulação Rayon de simulation Szimuláció hatóköre Радиус симуляции Raggio Simulazione - シミュレーションの範囲 + シミュレーションの半径 구현 범위 模擬半徑 模拟半径 + Similasyon Yarıçapı Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles @@ -256,30 +276,32 @@ Gibt den Radius (in Metern) um den Spieler an, bei dem die erweiterte Ballistik auf Geschosse angewendet wird Určuje oblast kolem hráče (v metrech), kde je pokročilá balistika použita na projektil Define o raio ao redor do jogador (em metros) onde a balística avançada será aplicada aos projéteis - Définit le rayon autour du joueur (en mètres) d'application de la balistique avancée + Définit le rayon autour du joueur (en mètres), dans lequel la balistique avancée est appliquée aux projectiles. Meghatározza a játékos körüli hatókört (méterben), ahol a lövedékek fejlett ballisztikát használnak Определяет радиус вокруг игрока (в метрах), в котором продвинутая баллистика применяется к снарядам - Definisce il raggio attorno al giocatore (in metri) per cui la Balistica Avanzata è applicata ai proiettili - アドバンスド バリスティックスの適用半径範囲 (プレイヤー中心、メートル単位) を定義します。 + Definisce il raggio attorno al giocatore (in metri) entro il quale la Balistica Avanzata è applicata ai proiettili + アドバンスド弾道計算の適用半径範囲 (プレイヤー中心、メートル単位) を定義します。 플레이어 주위의 발사체를 고급 탄도학으로 정의하는 범위를 정합니다(미터) 以玩家的半徑距離(公尺)定義先進彈道系統啟用範圍 - 以玩家的半径距离(公尺)定义先进弹道系统启用范围 + 定义玩家周围的半径(米),在这个半径内,进阶弹道系统会被启用 + Mermilere gelişmiş balistik uygulandığı oyuncunun etrafındaki yarıçapı (metre cinsinden) tanımlar This module enables advanced ballistics simulation - meaning the trajectory of projectiles is influenced by variables like air temperature, atmospheric pressure, humidity, gravity, the type of ammunition and the weapon from which it was fired. Dieses Modul aktiviert die Erweiterte Ballisitk. Die Flugbahn eines Geschosses wird nun von Einflüssen wie z.B Temperatur, Luftdruck, Luftfeuchtigkeit, Schwerkraft, Geschossart sowie der Waffe aus dem es gefeuert wird, beeinflusst. Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki. Tento modul umožňuje aktivovat pokročilou balistiku, která vypočítává trajektorii kulky a bere do úvahy věci jako je teplota vzduchu, atmosférický tlak, vlhkost vzduchu, gravitaci, typ munice a zbraň, ze které je náboj vystřelen. To vše přispívá k velmi přesné balistice. - Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, força de Coriolis, a gravidade, o modelo da arma no qual o disparo é realizado e o tipo de munição. Tudo isso acrescenta-se a um balística muito precisa. - Ce module active la simulation de balistique avancée - les projectiles sont influencés par des variables comme le vent, la température, la pression atmosphérique, l'humidité, la gravité, le type de munition et l'arme avec laquelles ils sont tirés. + Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, a gravidade, a arma no qual o disparo é realizado e o tipo de munição. + Ce module permet une simulation balistique avancée ; c'est à dire que la trajectoire des projectiles est influencée par des facteurs tels que la température de l'air, la pression atmosphérique, l'humidité, la gravité, le type de munition et l'arme depuis laquelle elle est tirée. Ez a modul engedélyezi a fejlett ballisztikai szimulációt - a lövedékek röppályáját befolyásolni fogja a levegő hőmérséklete, légnyomás, páratartalom, gravitáció, a lövedék fajtája, valamint a fegyver, amiből kilőtték a lövedéket. Этот модуль включает симуляцию продвинутой баллистики - при этом на траекторию полета снаряда влияют различные параметры, такие как температура воздуха, атмосферное давление, влажность, гравитация, тип боеприпаса и оружия, из которого произвели выстрел. Este módulo permite la simulación balística avanzada - es decir, la trayectoria de los proyectiles está influenciada por variables como la temperatura del aire, la presión atmosférica, la humedad, la gravedad, el tipo de municiones y el arma desde el que fue disparada. - Questo modulo abilita la simulazione della Balistica Avanzata - cioè la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata - アドバンスド バリスティックスのシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 + Questo modulo abilita la simulazione della Balistica Avanzata - essa comporta che la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata. + アドバンスド弾道計算のシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다. 該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響 - 该模块实现先进的弹道仿真 - 这意味着子弹的轨迹是由空气温度、大气压力、湿度、重力、弹药类型以及射击的武器所影响 + 该模块实现增强的弹道模拟—子弹的轨迹由空气温度、大气压力、湿度、重力、弹药类型和射击的武器等变量所影响 + Bu modül gelişmiş balistik simülasyonunu etkinleştirir - yani mermilerin gidişatını hava sıcaklığı, atmosfer basıncı, nem, yerçekimi, mühimmat türü ve ateşlendiği silah gibi durumlar etkiler. diff --git a/addons/advanced_fatigue/CfgEventHandlers.hpp b/addons/advanced_fatigue/CfgEventHandlers.hpp index 0b5cb8edff..f6e2bb398c 100644 --- a/addons/advanced_fatigue/CfgEventHandlers.hpp +++ b/addons/advanced_fatigue/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/advanced_fatigue/README.md b/addons/advanced_fatigue/README.md index aec1cfd38b..46c4aab73f 100644 --- a/addons/advanced_fatigue/README.md +++ b/addons/advanced_fatigue/README.md @@ -2,9 +2,3 @@ ace_advanced_fatigue ========== An in depth stamina and fatigue simulation. - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [BaerMitUmlaut](https://github.com/BaerMitUmlaut) diff --git a/addons/advanced_fatigue/XEH_PREP.hpp b/addons/advanced_fatigue/XEH_PREP.hpp index c6250516f5..22bb99617a 100644 --- a/addons/advanced_fatigue/XEH_PREP.hpp +++ b/addons/advanced_fatigue/XEH_PREP.hpp @@ -2,9 +2,11 @@ PREP(addDutyFactor); PREP(createStaminaBar); PREP(getAnimDuty); PREP(getMetabolicCosts); +PREP(getWeaponInertia); PREP(handleEffects); PREP(handlePlayerChanged); PREP(handleStaminaBar); PREP(mainLoop); PREP(moduleSettings); PREP(removeDutyFactor); +PREP(renderDebugLines); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 78027fd3f5..519d218b8c 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -2,26 +2,33 @@ if (!hasInterface) exitWith {}; -[missionNamespace, "ACE_setCustomAimCoef", QUOTE(ADDON), { - private _unit = ACE_player; - private _fatigue = _unit getVariable [QGVAR(aimFatigue), 0]; +#ifdef DEBUG_MODE_FULL +call FUNC(renderDebugLines); +#endif - switch (stance _unit) do { - case ("CROUCH"): { - 1.0 + _fatigue ^ 2 * 0.1 - }; - case ("PRONE"): { - 1.0 + _fatigue ^ 2 * 2.0 - }; - default { - 1.5 + _fatigue ^ 2 * 3.0 - }; - }; -}] call EFUNC(common,arithmeticSetSource); +// recheck weapon inertia after weapon swap, change of attachments or switching unit +["weapon", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler; +["loadout", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler; +["unit", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; + ["baseline", { + private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0]; + switch (stance ACE_player) do { + case ("CROUCH"): { + (1.0 + _fatigue ^ 2 * 0.1) + }; + case ("PRONE"): { + (1.0 + _fatigue ^ 2 * 2.0) + }; + default { + (1.5 + _fatigue ^ 2 * 3.0) + }; + }; + }, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); + // - Post process effect ------------------------------------------------------ GVAR(ppeBlackout) = ppEffectCreate ["ColorCorrections", 4220]; GVAR(ppeBlackout) ppEffectEnable true; @@ -30,35 +37,34 @@ if (!hasInterface) exitWith {}; GVAR(ppeBlackout) ppEffectCommit 0.4; // - GVAR updating and initialization ----------------------------------------- - ["unit", FUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; + ["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["visibleMap", { params ["", "_visibleMap"]; // command visibleMap is updated one frame later - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player}); + (uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!_visibleMap && isNull objectParent ACE_player); }, true] call CBA_fnc_addPlayerEventHandler; ["vehicle", { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player}); + (uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!visibleMap && isNull objectParent ACE_player); }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 - linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; + linearConversion [0, 1, _this getVariable [QEGVAR(medical,pain), 0], 1, 1.1, true]; }] call FUNC(addDutyFactor); [QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33 - linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true]; + linearConversion [6, 0, _this getVariable [QEGVAR(medical,bloodVolume), 6], 1, 2, true]; }] call FUNC(addDutyFactor); }; - if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then { + if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { [QEGVAR(dragging,isCarrying), { [1, 3] select (_this getVariable [QEGVAR(dragging,isCarrying), false]); }] call FUNC(addDutyFactor); }; - if (["ACE_Weather"] call EFUNC(common,isModLoaded)) then { + // Weather has an off switch, Dragging & Medical don't. + if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then { [QEGVAR(weather,temperature), { // 35->1, 45->2 - linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true]; + linearConversion [35, 45, missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25], 1, 2, true]; }] call FUNC(addDutyFactor); }; diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 12f007ccf6..643b7b0be0 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -6,10 +6,12 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40); -GVAR(dutyList) = [[], []]; +GVAR(dutyList) = createHashMap; GVAR(setAnimExclusions) = []; +GVAR(inertia) = 0; +GVAR(inertiaCache) = createHashMap; ADDON = true; diff --git a/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf b/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf index e2f87f3080..061dcf102d 100644 --- a/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf +++ b/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Adds a duty factor. @@ -18,6 +18,4 @@ params [["_id", "", [""]], ["_factor", 1, [0, {}]]]; if (_id == "" || {_factor isEqualTo 1}) exitWith {}; -GVAR(dutyList) params ["_idList", "_factorList"]; -_idList pushBack _id; -_factorList pushBack _factor, +GVAR(dutyList) set [_id, _factor]; diff --git a/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf b/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf index 157f683018..2648cfd164 100644 --- a/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf +++ b/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Creates the stamina bar. diff --git a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf index 717161b890..50e052d5f8 100644 --- a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf +++ b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut - * Calculates the duty of the current animation. + * Calculates the duty ('postureWeight') of the current animation. * * Arguments: * 0: Unit @@ -37,13 +37,14 @@ if (_animType in ["idl", "mov", "adj"]) then { }; }; - if (currentWeapon _unit != handgunWeapon _unit) then { + if (currentWeapon _unit != "") then { if (_animName select [13, 3] == "ras") then { - // low ready jog - _duty = _duty * 1.2; if (_animName select [9, 3] == "tac") then { // high ready jog/walk - _duty = _duty * 1.5; + _duty = _duty * (1 + 0.8*GVAR(inertia)); + } else { + // low ready jog + _duty = _duty * (1 + 0.2*GVAR(inertia)); }; }; }; diff --git a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf index 0e0ce7de04..36048cee04 100644 --- a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf +++ b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf @@ -1,51 +1,74 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: BaerMitUmlaut - * Calculates the current metabolic costs for a unit. + * Author: BaerMitUmlaut, ulteq + * Calculates the current metabolic costs. * Calculation is done according to the Pandolf/Wojtowicz formulas. * * Arguments: - * 0: Unit - * 1: Speed + * 0: Duty of animation + * 1: Mass of unit + * 2: Terrain gradient + * 3: Terrain factor + * 4: Speed * * Return Value: * Metabolic cost * * Example: - * [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts + * [1, 840, 20, 1, 4] call ace_advanced_fatigue_fnc_getMetabolicCosts * * Public: No */ -params ["_unit", "_velocity"]; -private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor); +params ["_duty", "_gearMass", "_terrainGradient", "_terrainFactor", "_speed"]; -private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2)); -private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor); -private _duty = GVAR(animDuty); +// Metabolic cost for walking and running is different +if (_speed > 2) then { + // Running + #ifdef DEBUG_MODE_FULL + private _baseline = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 0.9 * (_speed ^ 2); + private _graded = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = abs ((_graded / _baseline) - 1); + hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9", + _fwdAngle toFixed 1, + _sideAngle toFixed 1, + _terrainFactor toFixed 2, + _terrainGradient toFixed 1, + _terrainImpact toFixed 2, + _speed toFixed 2, + _gearMass toFixed 1, + _duty toFixed 2, + round (_graded * BIOMECH_EFFICIENCY * _duty) + ]; + #endif -{ - if (_x isEqualType 0) then { - _duty = _duty * _x; - } else { - _duty = _duty * (_unit call _x); - }; -} forEach (GVAR(dutyList) select 1); - -if (GVAR(isSwimming)) then { - _terrainGradient = 0; -}; - -if (_velocity > 2) then { ( - 2.10 * SIM_BODYMASS + 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty } else { + // Walking + #ifdef DEBUG_MODE_FULL + private _baseline = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 1.15 * (_speed ^ 2); + private _graded = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = abs ((_graded / _baseline) - 1); + hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9", + _fwdAngle toFixed 1, + _sideAngle toFixed 1, + _terrainFactor toFixed 2, + _terrainGradient toFixed 1, + _terrainImpact toFixed 2, + _speed toFixed 2, + _gearMass toFixed 1, + _duty toFixed 2, + round (_graded * BIOMECH_EFFICIENCY * _duty) + ]; + #endif + ( 1.05 * SIM_BODYMASS - + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty }; diff --git a/addons/advanced_fatigue/functions/fnc_getWeaponInertia.sqf b/addons/advanced_fatigue/functions/fnc_getWeaponInertia.sqf new file mode 100644 index 0000000000..973121c13d --- /dev/null +++ b/addons/advanced_fatigue/functions/fnc_getWeaponInertia.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Calculates total weapon inertia, accounting for attachments. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Total inertia + * + * Example: + * [ACE_player] call ace_advanced_fatigue_fnc_getWeaponInertia + * + * Public: No + */ +params [["_unit", ACE_player, [objNull]]]; + +private _cache = GVAR(inertiaCache); +private _weapon = currentWeapon _unit; +private _weaponAndItems = [_weapon] + (_unit weaponAccessories _weapon); + +private _inertia = _cache get _weaponAndItems; +if (isNil "_inertia") then { + _inertia = 0; + private _cfgWeapons = configFile >> "CfgWeapons"; + { + // if item is "" or inertia property is undefined, just ignore it + private _itemInertia = getNumber (_cfgWeapons >> _x >> "inertia"); + if (isNil "_itemInertia") then { continue }; + + _inertia = _inertia + _itemInertia; + } forEach _weaponAndItems; + _cache set [_weaponAndItems, _inertia]; +}; + +GVAR(inertia) = _inertia; +_inertia diff --git a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf index fbbb685217..d948823354 100644 --- a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf @@ -1,43 +1,44 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, ulteq * Handles any audible, visual and physical effects of fatigue. * * Arguments: * 0: Unit * 1: Fatigue - * 2: Speed - * 3: Overexhausted + * 2: Overexhausted + * 3: Forward Angle + * 4: Side Angle * * Return Value: * None * * Example: - * [_player, 0.5, 3.3, true] call ace_advanced_fatigue_fnc_handleEffects + * [_player, 0.5, 3.3, true, 0, 0] call ace_advanced_fatigue_fnc_handleEffects * * Public: No */ -params ["_unit", "_fatigue", "_speed", "_overexhausted"]; -#ifdef DEBUG_MODE_FULL - systemChat str _fatigue; - systemChat str vectorMagnitude velocity _unit; -#endif +params ["_unit", "_fatigue", "_overexhausted", "_fwdAngle", "_sideAngle"]; // - Audible effects ---------------------------------------------------------- GVAR(lastBreath) = GVAR(lastBreath) + 1; + if (_fatigue > 0.4 && {GVAR(lastBreath) > (_fatigue * -10 + 9)} && {!underwater _unit}) then { + if (!isGameFocused) exitWith {}; + switch (true) do { case (_fatigue < 0.6): { - playSound (QGVAR(breathLow) + str(floor random 6)); + playSound (QGVAR(breathLow) + str (floor random 6)); }; case (_fatigue < 0.85): { - playSound (QGVAR(breathMid) + str(floor random 6)); + playSound (QGVAR(breathMid) + str (floor random 6)); }; default { - playSound (QGVAR(breathMax) + str(floor random 6)); + playSound (QGVAR(breathMax) + str (floor random 6)); }; }; + GVAR(lastBreath) = 0; }; @@ -61,31 +62,35 @@ if (GVAR(isSwimming)) exitWith { if (GVAR(setAnimExclusions) isEqualTo []) then { _unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true]; }; - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + + if (isSprintAllowed _unit && _fatigue > 0.7) then { // small checks like these are faster without lazy eval [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.7}) then { + if (!isSprintAllowed _unit && _fatigue < 0.7) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; }; -if ((getAnimSpeedCoef _unit) != 1) then { - if (GVAR(setAnimExclusions) isEqualTo []) then { - TRACE_1("reset",getAnimSpeedCoef _unit); - _unit setAnimSpeedCoef 1; - }; + +// If other components are setting setAnimSpeedCoef, do not change animSpeedCoef +if (getAnimSpeedCoef _unit != 1 && {GVAR(setAnimExclusions) isEqualTo []}) then { + TRACE_1("reset",getAnimSpeedCoef _unit); + _unit setAnimSpeedCoef 1; }; -if (_overexhausted) then { +if (!isForcedWalk _unit && _fatigue >= 1) then { // small checks like these are faster without lazy eval [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if (isForcedWalk _unit && {_fatigue < 0.7}) then { + if (isForcedWalk _unit && _fatigue < 0.7) then { [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); } else { - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + // Forward angle is the slope of the terrain, side angle simulates the unevenness/roughness of the terrain + if (isSprintAllowed _unit && {_fatigue > 0.7 || abs _fwdAngle > 20 || abs _sideAngle > 20}) then { [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.6}) then { + if (!isSprintAllowed _unit && _fatigue < 0.6 && abs _fwdAngle < 20 && abs _sideAngle < 20) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; @@ -93,6 +98,3 @@ if (_overexhausted) then { }; _unit setVariable [QGVAR(aimFatigue), _fatigue]; - -private _aimCoef = [missionNamespace, "ACE_setCustomAimCoef", "max"] call EFUNC(common,arithmeticGetResult); -_unit setCustomAimCoef _aimCoef; diff --git a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf index 0cea426eef..82c9c90a56 100644 --- a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf +++ b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: BaerMitUmlaut - * Handles switching units (once on init and afterwards via Zeus). + * Author: BaerMitUmlaut, ulteq + * Handles switching units (once on init and afterwards via Zeus). Also handles CBA setting change for performance factor. * * Arguments: * 0: New Unit @@ -15,20 +15,24 @@ * * Public: No */ + params ["_newUnit", "_oldUnit"]; + TRACE_2("unit changed",_newUnit,_oldUnit); -if !(isNull _oldUnit) then { +if (!isNull _oldUnit) then { + TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); + _oldUnit enableStamina true; _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); _oldUnit setVariable [QGVAR(ae1Reserve), GVAR(ae1Reserve)]; _oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)]; _oldUnit setVariable [QGVAR(anReserve), GVAR(anReserve)]; _oldUnit setVariable [QGVAR(anFatigue), GVAR(anFatigue)]; _oldUnit setVariable [QGVAR(muscleDamage), GVAR(muscleDamage)]; + _oldUnit setVariable [QGVAR(respiratoryRate), GVAR(respiratoryRate)]; }; _newUnit enableStamina false; @@ -38,6 +42,7 @@ if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { private _animHandler = _newUnit addEventHandler ["AnimChanged", { GVAR(animDuty) = _this call FUNC(getAnimDuty); }]; + TRACE_1("add new",_animHandler); _newUnit setVariable [QGVAR(animHandler), _animHandler]; }; @@ -47,18 +52,27 @@ GVAR(ae2Reserve) = _newUnit getVariable [QGVAR(ae2Reserve), AE2_MAXRESERVE] GVAR(anReserve) = _newUnit getVariable [QGVAR(anReserve), AN_MAXRESERVE]; GVAR(anFatigue) = _newUnit getVariable [QGVAR(anFatigue), 0]; GVAR(muscleDamage) = _newUnit getVariable [QGVAR(muscleDamage), 0]; +GVAR(respiratoryRate) = _newUnit getVariable [QGVAR(respiratoryRate), 0]; // Clean variables for respawning units { _newUnit setVariable [_x, nil]; -} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage)]; +} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage), QGVAR(respiratoryRate)]; GVAR(VO2Max) = 35 + 20 * (_newUnit getVariable [QGVAR(performanceFactor), GVAR(performanceFactor)]); -GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * 0.23 * JOULES_PER_ML_O2 / 60; +GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * BIOMECH_EFFICIENCY * JOULES_PER_ML_O2 / 60; GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower); -GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362; -GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362; +GVAR(ae1PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE1_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362; +GVAR(ae2PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE2_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362; +GVAR(aePathwayPower) = GVAR(ae1PathwayPower) + GVAR(ae2PathwayPower); +GVAR(anPathwayPower) = GVAR(peakPower) - GVAR(aePathwayPower); + +GVAR(aeWattsPerATP) = GVAR(ae1PathwayPower) / AE1_ATP_RELEASE_RATE; +GVAR(anWattsPerATP) = GVAR(anPathwayPower) / AN_ATP_RELEASE_RATE; + +GVAR(respiratoryBufferDivisor) = (RESPIRATORY_BUFFER - 1) / RESPIRATORY_BUFFER; +GVAR(maxPowerFatigueRatio) = 0.057 / GVAR(peakPower); GVAR(ppeBlackoutLast) = 100; GVAR(lastBreath) = 0; diff --git a/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf b/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf index 73ba6179a9..8def1439b7 100644 --- a/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles visual changes of the stamina bar. @@ -25,10 +25,14 @@ _posAndSize set [2, _stamina * GVAR(staminaBarWidth)]; _staminaBarContainer ctrlSetPosition _posAndSize; // - Opacity ------------------------------------------------------------------ -if (_stamina >= 0.8) then { - _staminaBarContainer ctrlSetFade (0.9 + 0.1 * (_stamina - 0.8) / 0.2); +if (GVAR(fadeStaminaBar)) then { + if (_stamina >= 0.8) then { + _staminaBarContainer ctrlSetFade (0.9 + 0.1 * (_stamina - 0.8) / 0.2); + } else { + _staminaBarContainer ctrlSetFade (0.9 * _stamina / 0.8); + }; } else { - _staminaBarContainer ctrlSetFade (0.9 * _stamina / 0.8); + _staminaBarContainer ctrlSetFade 0; }; // - Color -------------------------------------------------------------------- diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index 1d3b215b54..a07abae794 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, ulteq * Main looping function that updates fatigue values. * * Arguments: @@ -14,68 +14,134 @@ * * Public: No */ -if (!alive ACE_player) exitWith { // Dead people don't breath, Will also handle null (Map intros) - [FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + +// Dead people don't breathe, will also handle null (map intros) +if (!alive ACE_player) exitWith { + [LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 1; _staminaBarContainer ctrlCommit 1; }; +private _velocity = velocity ACE_player; +private _normal = surfaceNormal (getPosWorld ACE_player); +private _movementVector = vectorNormalized _velocity; +private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); +private _fwdAngle = asin (_movementVector select 2); +private _sideAngle = asin (_sideVector select 2); + private _currentWork = REE; -private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6; +private _currentSpeed = (vectorMagnitude _velocity) min 6; // fix #4481. Diving to the ground is recorded as PRONE stance with running speed velocity. Cap maximum speed to fix. if (GVAR(isProne)) then { _currentSpeed = _currentSpeed min 1.5; }; -if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { - _currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts); +// Get the current duty +private _duty = GVAR(animDuty); + +{ + if (_x isEqualType 0) then { + _duty = _duty * _x; + } else { + _duty = _duty * (ACE_player call _x); + }; +} forEach (values GVAR(dutyList)); + +private _terrainGradient = abs _fwdAngle; +private _terrainFactor = 1; +private _gearMass = 0 max (((ACE_player getVariable [QEGVAR(movement,totalLoad), loadAbs ACE_player]) / 22.046 - UNDERWEAR_WEIGHT) * GVAR(loadFactor)); + +if (isNull objectParent ACE_player && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { + if (!GVAR(isSwimming)) then { + // If the unit is going downhill, it's much less demanding + if (_fwdAngle < 0) then { + _terrainGradient = 0.15 * _terrainGradient; + }; + + // Used to simulate the unevenness/roughness of the terrain + if ((getPosATL ACE_player) select 2 < 0.01) then { + private _sideGradient = abs (_sideAngle / 45) min 1; + + _terrainFactor = 1 + _sideGradient ^ 4; + }; + }; + + _currentWork = [_duty, _gearMass, _terrainGradient * GVAR(terrainGradientFactor), _terrainFactor, _currentSpeed] call FUNC(getMetabolicCosts); _currentWork = _currentWork max REE; }; +// Oxygen calculation +private _oxygen = if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { // Defer to medical + (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100 +} else { + 1 - 0.131 * GVAR(respiratoryRate) ^ 2 // Default AF oxygen saturation +}; // Calculate muscle damage increase -// Note: Muscle damage recovery is ignored as it takes multiple days -GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004; -private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage)); +GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * MUSCLE_TEAR_RATE; + +// Calculate muscle damage recovery +GVAR(muscleDamage) = 0 max (GVAR(muscleDamage) - MUSCLE_RECOVERY * GVAR(recoveryFactor)) min 1; +private _muscleIntegrity = 1 - GVAR(muscleDamage); +private _muscleFactor = sqrt _muscleIntegrity; // Calculate available power -private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; -private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; +private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleFactor; +private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleFactor; +private _aePathwayPowerFatigued = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued; +private _anPathwayPowerFatigued = GVAR(anPathwayPower) * sqrt (GVAR(anReserve) / AN_MAXRESERVE) * _oxygen * _muscleIntegrity; // Calculate how much power is consumed from each reserve private _ae1Power = _currentWork min _ae1PathwayPowerFatigued; -private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued; -private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0; +private _ae2Power = (_currentWork - _ae1Power) min _ae2PathwayPowerFatigued; +private _anPower = 0 max (_currentWork - _ae1Power - _ae2Power); // Remove ATP from reserves for current work -GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP; -GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP; -GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; -// Increase anearobic fatigue -GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; +GVAR(ae1Reserve) = 0 max (GVAR(ae1Reserve) - _ae1Power / GVAR(aeWattsPerATP)); +GVAR(ae2Reserve) = 0 max (GVAR(ae2Reserve) - _ae2Power / GVAR(aeWattsPerATP)); +GVAR(anReserve) = 0 max (GVAR(anReserve) - _anPower / GVAR(anWattsPerATP)); + +// Acidosis accumulation +GVAR(anFatigue) = GVAR(anFatigue) + _anPower * GVAR(maxPowerFatigueRatio) * 1.1; // Aerobic ATP reserve recovery -GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; -GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; +GVAR(ae1Reserve) = (GVAR(ae1Reserve) + _oxygen * GVAR(recoveryFactor) * AE1_ATP_RECOVERY * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower)) min AE1_MAXRESERVE; +GVAR(ae2Reserve) = (GVAR(ae2Reserve) + _oxygen * GVAR(recoveryFactor) * AE2_ATP_RECOVERY * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower)) min AE2_MAXRESERVE; -// Anaerobic ATP reserver and fatigue recovery -GVAR(anReserve) = ((GVAR(anReserve) - + (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min AN_MAXRESERVE) max 0; +private _aeSurplus = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power; -GVAR(anFatigue) = ((GVAR(anFatigue) - - (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min 1) max 0; +// Anaerobic ATP reserve recovery +GVAR(anReserve) = 0 max (GVAR(anReserve) + _aeSurplus / GVAR(VO2MaxPower) * AN_ATP_RECOVERY * GVAR(recoveryFactor) * (GVAR(anFatigue) max linearConversion [AN_MAXRESERVE, 0, GVAR(anReserve), 0, 0.75, true]) ^ 2) min AN_MAXRESERVE; // max linearConversion ensures that if GVAR(anFatigue) is very low, it will still regenerate reserves +// Acidosis recovery +GVAR(anFatigue) = 0 max (GVAR(anFatigue) - _aeSurplus * GVAR(maxPowerFatigueRatio) * GVAR(recoveryFactor) * GVAR(anFatigue) ^ 2) min 1; -private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; -private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE; -private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage); +// Respiratory rate decrease +GVAR(respiratoryRate) = GVAR(respiratoryRate) * GVAR(respiratoryBufferDivisor); -[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); +// Respiratory rate increase +private _aePowerRatio = (GVAR(aePathwayPower) / _aePathwayPowerFatigued) min 2; +private _respiratorySampleDivisor = 1 / (RESPIRATORY_BUFFER * 4.72 * GVAR(VO2Max)); +GVAR(respiratoryRate) = (GVAR(respiratoryRate) + _currentWork * _respiratorySampleDivisor * _aePowerRatio) min 1; + +// Calculate a pseudo-perceived fatigue, which is used for effects +GVAR(aeReservePercentage) = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; +GVAR(anReservePercentage) = GVAR(anReserve) / AN_MAXRESERVE; +private _perceivedFatigue = 1 - (GVAR(anReservePercentage) min GVAR(aeReservePercentage)); + +#ifdef DEBUG_MODE_FULL +systemChat format ["---- muscleDamage: %1 ----", GVAR(muscleDamage) toFixed 8]; +systemChat format ["---- ae2: %1 - an: %2 ----", (GVAR(ae2Reserve) / AE2_MAXRESERVE) toFixed 2, (GVAR(anReserve) / AN_MAXRESERVE) toFixed 2]; +systemChat format ["---- anFatigue: %1 - perceivedFatigue: %2 ----", GVAR(anFatigue) toFixed 2, _perceivedFatigue toFixed 2]; +systemChat format ["---- velocity %1 - respiratoryRate: %2 ----", (vectorMagnitude _velocity) toFixed 2, GVAR(respiratoryRate) toFixed 2]; +// systemChat format ["---- aePower: %1 ----", _aePathwayPowerFatigued toFixed 1]; +#endif + +[ACE_player, _perceivedFatigue, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects); if (GVAR(enableStaminaBar)) then { [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); }; -[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; +[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf b/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf index ab2742fb75..dfe5b19666 100644 --- a/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf +++ b/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Initializes the module settings. diff --git a/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf b/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf index aacba72dd8..a47f6e69c1 100644 --- a/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf +++ b/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Removes a duty factor. @@ -16,10 +16,4 @@ */ params [["_id", "", [""]]]; -GVAR(dutyList) params ["_idList", "_factorList"]; -private _index = _idList find _id; - -if (_index != -1) then { - _idList deleteAt _index; - _factorList deleteAt _index; -}; +GVAR(dutyList) deleteAt _id; diff --git a/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf b/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf new file mode 100644 index 0000000000..3826637b9e --- /dev/null +++ b/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: ulteq + * Draw lines for debugging. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_advanced_fatigue_fnc_renderDebugLines + * + * Public: No + */ + +addMissionEventHandler ["Draw3D", { + private _normal = surfaceNormal (getPosWorld ACE_player); + private _beg = (getPosWorld ACE_player) vectorAdd (_normal vectorMultiply 0.5); + private _end = _beg vectorAdd (_normal vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 1, 0, 1]]; + + private _side = vectorNormalized (_normal vectorCrossProduct [0, 0, 1]); + private _end = _beg vectorAdd (_side vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 0, 1, 1]]; + + private _up = vectorNormalized (_normal vectorCrossProduct _side); + private _end = _beg vectorAdd (_up vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [1, 0, 0, 1]]; + + private _movementVector = vectorNormalized (velocity ACE_player); + private _end = _beg vectorAdd (_movementVector vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [1, 1, 0, 1]]; + + private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); + _sideVector set [2, 0]; + private _end = _beg vectorAdd (_sideVector vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 1, 1, 1]]; +}]; diff --git a/addons/advanced_fatigue/functions/script_component.hpp b/addons/advanced_fatigue/functions/script_component.hpp deleted file mode 100644 index 6f79ffc902..0000000000 --- a/addons/advanced_fatigue/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\advanced_fatigue\script_component.hpp" diff --git a/addons/advanced_fatigue/initSettings.inc.sqf b/addons/advanced_fatigue/initSettings.inc.sqf new file mode 100644 index 0000000000..01eba8652d --- /dev/null +++ b/addons/advanced_fatigue/initSettings.inc.sqf @@ -0,0 +1,92 @@ +[ + QGVAR(enabled), + "CHECKBOX", + [LSTRING(Enabled), LSTRING(Enabled_Description)], + LSTRING(DisplayName), + true, + 1, + { + if (!_this) then { + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; + _staminaBarContainer ctrlSetFade 1; + _staminaBarContainer ctrlCommit 0; + }; + + [QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged) + }, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(enableStaminaBar), + "CHECKBOX", + [LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)], + LSTRING(DisplayName), + true, + 1, + { + if (!_this) then { + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; + _staminaBarContainer ctrlSetFade 1; + _staminaBarContainer ctrlCommit 0; + }; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(fadeStaminaBar), + "CHECKBOX", + [LSTRING(FadeStaminaBar), LSTRING(FadeStaminaBar_Description)], + LSTRING(DisplayName), + true, + 0, + { + if (!_this && GVAR(enabled) && GVAR(enableStaminaBar)) then { + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; + _staminaBarContainer ctrlSetFade 0; + _staminaBarContainer ctrlCommit 0; + }; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(performanceFactor), + "SLIDER", + [LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)], + LSTRING(DisplayName), + [0, 10, 1, 2], + 1, + { + // Recalculate values if the setting is changed mid-mission + if (GVAR(enabled) && hasInterface && !isNull ACE_player) then { + [ACE_player, ACE_player] call FUNC(handlePlayerChanged); + }; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(recoveryFactor), + "SLIDER", + [LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)], + LSTRING(DisplayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(loadFactor), + "SLIDER", + [LSTRING(LoadFactor), LSTRING(LoadFactor_Description)], + LSTRING(DisplayName), + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(terrainGradientFactor), + "SLIDER", + [LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)], + LSTRING(DisplayName), + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/advanced_fatigue/initSettings.sqf b/addons/advanced_fatigue/initSettings.sqf deleted file mode 100644 index 4e44d75132..0000000000 --- a/addons/advanced_fatigue/initSettings.sqf +++ /dev/null @@ -1,70 +0,0 @@ -[ - QGVAR(enabled), - "CHECKBOX", - [LSTRING(Enabled), LSTRING(Enabled_Description)], - LSTRING(DisplayName), - true, - true, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_Settings_fnc_init; - -[ - QGVAR(enableStaminaBar), - "CHECKBOX", - [LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)], - LSTRING(DisplayName), - true, - true, { - if (!_this) then { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlSetFade 1; - _staminaBarContainer ctrlCommit 0; - }; - } -] call CBA_Settings_fnc_init; - -[ - QGVAR(performanceFactor), - "SLIDER", - [LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(recoveryFactor), - "SLIDER", - [LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(loadFactor), - "SLIDER", - [LSTRING(LoadFactor), LSTRING(LoadFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(terrainGradientFactor), - "SLIDER", - [LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(swayFactor), - "SLIDER", - [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_Settings_fnc_init; diff --git a/addons/advanced_fatigue/script_component.hpp b/addons/advanced_fatigue/script_component.hpp index fcc8abd3c0..7e3255439f 100644 --- a/addons/advanced_fatigue/script_component.hpp +++ b/addons/advanced_fatigue/script_component.hpp @@ -16,14 +16,28 @@ #include "\z\ace\addons\main\script_macros.hpp" +#define UNDERWEAR_WEIGHT 3.5 + #define ANTPERCENT 0.8 #define SIM_BODYMASS 70 #define JOULES_PER_ML_O2 20.9 #define VO2MAX_STRENGTH 4.1 -#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * 0.23) -#define OXYGEN 0.9 -#define WATTSPERATP 7 +#define BIOMECH_EFFICIENCY 0.23 +#define REE 18.83 // ((0.5617 * SIM_BODYMASS + 42.57) * BIOMECH_EFFICIENCY) -#define AE1_MAXRESERVE 4000000 -#define AE2_MAXRESERVE 84000 -#define AN_MAXRESERVE 2300 +#define RESPIRATORY_BUFFER 60 + +#define MUSCLE_TEAR_RATE 0.00004 +#define MUSCLE_RECOVERY 0.00000386 + +#define AE1_ATP_RELEASE_RATE 13.3 // mmol +#define AE2_ATP_RELEASE_RATE 16.7 // mmol +#define AN_ATP_RELEASE_RATE 113.3 // mmol + +#define AE1_ATP_RECOVERY 6.60 // mmol +#define AE2_ATP_RECOVERY 5.83 // mmol +#define AN_ATP_RECOVERY 56.70 // mmol + +#define AE1_MAXRESERVE 4000000 // mmol +#define AE2_MAXRESERVE 84000 // mmol +#define AN_MAXRESERVE 2300 // mmol diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index b3a24a4396..5cd36ffce6 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -3,18 +3,23 @@ ACE Advanced Fatigue + ACE Fatiga Avanzada ACE Erweiterte Ausdauer ACE 進階疲勞 - ACE 进阶疲劳 - ACE アドバンスド ファティーグ + ACE 进阶体力 + ACE アドバンスド疲労 ACE Fatica Avanzata ACE 고급 피로도 - ACE Fatigue Avancée + ACE Fatigue avancée ACE Zaawansowane Zmęczenie ACE Продвинутая усталость + ACE Fadiga Avançada + ACE Pokročilá únava + ACE Gelişmiş Yorgunluk Performance Factor + Factor de rendimiento Leistungsfaktor パフォーマンス因数 Współczynnik wydolności @@ -24,33 +29,43 @@ 體力值 体力值 Фактор производительности + Fator de Performance + Faktor výkonu + Performans Faktörü Influences the overall performance of all players with no custom factor. Higher means better. + Afecta al rendimiento general de todos los jugadores sin opciones personalizadas. Más alto significa mejor Beinflusst die Leistungsfähigkeit aller Spieler ohne eigenen Leistungsfaktor. Ein höherer Wert bedeutet bessere Leistung. 個別の因数を設定されていない、全てのプレイヤーのあらゆるパフォーマンスに影響を与えます。 値が高ければ高いほど、良い効果が得られます。 Wpływa na ogólną wydolność organizmu u wszystkich graczy bez ustawionego niestandardowego współczynnika. Więcej znaczy lepiej. 모든 성능이 임의로 설정된 값 없이 영향받습니다. 값이 클수록 더 나은 성능을 발휘합니다 - Influence les performances générales de tous les joueurs sans facteurs personalisés. Une valeur plus élevée implique de meilleures performances. - Influenza qualsiasi prestazione di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore. + Impacte la performance globale de tous les joueurs n'ayant pas de facteur personnalisé.\nPlus la valeur est élevée, plus le joueur est performant. + Influenza la prestazione generale di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore. 影響所有玩家的體力表現,值越高代表體力越好 影响所有玩家的体力表现,值越高代表体力越好 - Влияет на общую производительность игроков, у которых не задано персональное значение. + Влияет на общую производительность игроков, у которых не задано персональное значение. Чем выше, тем лучше. + Influencia na performance geral de todos os jogadores sem nenhum fator personalizado. Quanto maior, melhor. + Ovlivňuje celkový výkon všech hráčů bez vlastního faktoru. Vyšší znamená lépe. Influences the overall performance of this unit. Higher means better. + Afecta al rendimiento de esta unidad. Más alto significa mejor Beinflusst die Leistungsfähigkeit dieser Einheit. Ein höherer Wert bedeutet bessere Leistung. このユニットのあらゆるパフォーマンスに影響を与えます。 値が高ければ高いほど、良い効果が得られます。 Wpływa na ogólną wydolność tej jednostki. Więcej znaczy lepiej. 모든 성능이 이 단위로 영향을 받습니다. 값이 클수록 더 나은 성능을 발휘합니다 - Influence les performances générales de cette unité. Une valeur plus élevée implique de meilleures performances. - Influenza qualsiasi prestazione di questa unità. Maggiore significa migliore. + Impacte la performance globale de cette unité.\nPlus la valeur est élevée, plus l'unité est performante. + Influenza la prestazione personalizzata di questa unità. Maggiore significa migliore. 影響這個單位的體力表現,值越高代表體力越好 影响这个单位的体力表现,值越高代表体力越好 - Влияет на общую производительность юнита. + Влияет на общую производительность юнита.Чем выше, тем лучше. + Influencia na performance geral dessa unidade. Quanto maior, melhor. + Ovlivňuje celkový výkon této jednotky. Vyšší znamená lépe. Recovery Factor + Factor de recuperación Erholungsfaktor 回復因数 Współczynnik regeneracji @@ -58,47 +73,60 @@ Facteur de récupération Fattore Recupero 回復值 - 回复值 + 恢复系数 Фактор восстановления + Fator de Recuperação + Faktor zotavení + Kurtarma Faktörü Changes how fast the player recovers when resting. Higher is faster. + Modifica cómo de rápido se recupera el jugador cuando descansa. Más alto significa mejor Ändert, wie schnell ein Spieler Ausdauer regeneriert. Ein höherer Wert bedeutet eine schnellere Regeneration. プレイヤーが休憩をとる際に、どのくらいの速度でスタミナ回復するかを設定します。 値が高ければ高いほど、早くなります。 Wpływa na czas regeneracji podczas postoju. Więcej znaczy szybciej. 얼마나 빨리 회복하는지를 바꿉니다. 값이 클수록 더 나은 성능을 발휘합니다 - Change la vitesse à laquelle les joueurs récupèrent leur endurance lorsqu'ils se reposent. Une valeur plus élevée implique une récupération plus rapide. - Determina in quanto tempo il giocatore recupera quando rilassato. Maggiore significa migliore. + Modifie la vitesse à laquelle le joueur récupère lorsqu'il se repose.\nPlus la valeur est élevée, plus la récupération est rapide. + Determina quanto velocemente il giocatore recupera le energie quando si ferma. Maggiore significa migliore. 決定玩家休息多久就能回復體力,值越高恢復越快 - 决定玩家休息多久就能回复体力,值越高恢复越快 + 决定玩家休息多久就能恢复体力,值越高恢复越快 Изменяет скорость восстановления игрока во время отдыха. Чем выше, тем быстрее. + Altera o quão rápido um jogador recupera quando descansando. Quanto maior, mais rápido. + Mění, jak rychle se hráč zotaví, když odpočívá. Vyšší je rychlejší. Load Factor + Factor de carga Gewichtsfaktor 重量因数 Współczynnik masy ekwipunku 부담 요인 - Facteur d'encombrement - Fattore Caricamento + Facteur de charge + Fattore Carico 負重量 - 负重量 + 重量系数 Фактор нагрузки + Fator de Carga + Faktor zatížení Increases or decreases how much weight influences the players performance. Zero means equipment weight has no performance influence. + Aumenta o disminuye cuanto influye el peso en el rendimiento del jugador. Cero significa que el peso no influye en el rendimiento Erhöht oder verringert, wie viel Einfluss das Ausrüstungsgewicht auf die Leistung hat. Null heißt, dass es keinen Einfluss hat. 装備重量がプレイヤーのパフォーマンスにもたらす影響を増減させます。 値をゼロに設定した場合、装備重量はパフォーマンスに影響を与えません。 Zmniejsza lub zwiększa wpływ ciężaru ekwipunku na wydolność gracza. Zero oznacza kompletny brak wpływu na wydolność. 플레이어가 무게에 따라 얼마나 영향받는지를 증가시키거나 감소시킵니다. 0의 경우 플레이어가 장비 무게에 영향받지 않습니다. - Augmente ou réduit l'influence que le poids à sur les performances des joueurs. Zéro implique que le poids de l'équipement n'a pas d'influence sur les performances. - Incrementa o decrementa quanto il peso influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non ha alcuna influenza nelle prestazioni. + Augmente ou diminue l'influence du poids sur les performances du joueur.\nUne valeur nulle indique que le poids de l'équipement n'a aucun impact sur les performances. + Determina quanto il peso trasportato influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non influisce sulle prestazioni. 增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現 - 增加或降低玩家所能承受的负重量. 如设定值为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. + Zvyšuje nebo snižuje, jak velká váha ovlivňuje výkon hráče. Nulová hodnota znamená, že hmotnost zařízení nemá žádný vliv na výkon. Terrain Gradient Factor + Factor de inclinación del terreno Terrainsteigungsfaktor 地形勾配因数 Współczynnik terenu @@ -106,71 +134,61 @@ Facteur d'inclinaison du terrain Fattore Pendenza Terreno 地形陡峭影響值 - 地形陡峭影响值 + 地形陡峭系数 Фактор местности + Fator de Inclinação do Terreno + Faktor stoupání terénu Sets how much steep terrain increases stamina loss. Higher means higher stamina loss. + Modifica cuanto afecta la inclinación al cansansio. Más alto significa más cansancio Beeinflusst, wie stark Steigungen den Ausdauerverbrauch erhöhen. Ein höherer Wert erhöht den Ausdauerverbrauch. 急勾配の地形がどれだけスタミナ消費を増大させるかを設定します。 値が高ければ高いほど、スタミナ消費が大きくなります。 Wpływa na to w jakim stopniu stromy teren wpływa na utratę wytrzymałości. Więcej oznacza szybszą utratę wytrzymałości. 경사도에 따라 얼마나 피로해지는지를 정합니다. 값이 클수록 더 많은 피로를 유발합니다. - Configure l'influence de l'inclinaison du terrain sur la perte d'endurance. Une valeur plus élevée implique une perte d'endurance plus importante. - Stabilisce quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa. + Définit à quel point un terrain escarpé réduit l'endurance du joueur.\nPlus la valeur est élevée, moins le joueur est endurant. + Determina quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa. 設定陡峭的地形將會影響多少體力的流失,值越高代表體力流失越快 - 设定陡峭的地形将会影响多少体力的流,失值越高代表体力流失越快 + 设定陡峭的地形将会影响多少体力的流失速度,值越高代表体力流失越快 Устанавливает, насколько крутая местность увеличивает потерю выносливости. Чем выше, тем быстрее теряется выносливость. - - - Sway factor - Verwacklungsfaktor - 手ぶれ因数 - 抖动因数 - 抖動因素 - Facteur de stabilisation - Fattore di oscillazione - Czynnik kołysania - Фактор колебания прицела - - - 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. - Влияет на колебания прицела оружия. Чем выше - тем больше. + Define o quanto que um terreno íngrime aumenta na perda de estamina. Quanto maior, maior a perda de estamina. + Nastavuje, o kolik strmý terén zvyšuje ztrátu výdrže. Vyšší znamená vyšší ztrátu výdrže. Enabled + Activada Aktiv - アドバンスド ファティーグを有効化する + 有効化 Włączone 활성화 Activé - Abilitato + Abilitata 啟用 启用 Включена + Ativado + Povoleno Enables/disables Advanced Fatigue. + Activa/desactiva la fatiga avanzada Aktiviert/deaktiviert Advanced Fatigue. - アドバンスド ファティーグを有効化します。 + アドバンスド疲労は高度な疲労管理システムを有効化します。 Włącza/wyłącza zaawansowaną wytrzymałość 고급 피로도 활성화/비활성화 - Active/désactive la fatigue avancée. - Abilita/disabilita la Fatica Avanzata. + Active/Désactive la fatigue avancée. + Abilita/Disabilita la Fatica Avanzata. 啟用/關閉進階體力. - 启用/关闭进阶体力. - Включает / Отключает Продвинутую усталость + 启用/关闭进阶体力。 + Включает/отключает Продвинутую усталость + Ativa/Desativa Fadiga Avançada. + Aktivuje / deaktivuje Pokročilou únavu. Show stamina bar + Mostrar barra de cansancio Zeige Ausdauerleiste - スタミナバーを表示する + スタミナバーを表示 Pokaż pasek wytrzymałości 피로도 막대 Afficher la barre d'endurance @@ -178,9 +196,12 @@ 顯示體力條 显示体力条 Показать шкалу усталости + Exibir barra de estamina + Zobrazit lištu výdrže Shows the stamina bar. + Muestra la barra de cansancio Zeigt die Ausdauerleiste an. スタミナバーを表示します。 Pokazuje pasek wytrzymałości. @@ -190,6 +211,39 @@ 顯示體力條 显示体力条 Показывает шкалу усталости. + Exibe a barra de estamina. + Zobrazuje lištu výdrže + + + Fade Stamina bar automatically + Desvanecer la barra de cansancio + Скрыть шкалу усталости автоматически + Blende Ausdauerleiste automatisch aus + 體力條自動淡去 + 自动淡化体力条 + Nascondi in automatico la barra della stamina + Automaticky schovat lištu výdrže + Fondu automatique de la barre d'endurance + 自動的にスタミナバーを非表示 + Chowaj pasek wytrzymałości automatycznie + Barra de stamina some automaticamente + Dayanıklılık çubuğunu otomatik olarak soldur + 자동으로 피로도 막대 숨기기 + + + Adjusts transparency of the bar based on stamina status. + Ajusta la ocultación progresiva de la barra de cansancio + Регулирует прозрачность шкалы в зависимости от статуса выносливости. + Passt die Transparenz der Ausdauerleiste abhängig vom Ausdauerstatus an. + 依照目前的體力程度調整體力條之透明度 + 根据体力状况调整体力条的透明度 + Regola la trasparenza della barra in base allo stato di affaticamento. + Upravuje průhlednost lišty v závislosti na současném stavu výdrže + Règle la transparence de la barre en fonction de l'état d'endurance. + スタミナの状態に応じて、自動的にバーの透明度を調整します。 + Dostosowuje przezroczystość paska na podstawie stanu wytrzymałości. + Ajusta a transparência da barra baseado no status da stamina + 피로도에 따라 피로도 막대의 투명도를 조절합니다. diff --git a/addons/advanced_throwing/ACE_Settings.hpp b/addons/advanced_throwing/ACE_Settings.hpp index 63de71cac7..2792e1953b 100644 --- a/addons/advanced_throwing/ACE_Settings.hpp +++ b/addons/advanced_throwing/ACE_Settings.hpp @@ -1,40 +1,17 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(Category); - displayName = CSTRING(Enable_DisplayName); - description = CSTRING(Enable_Description); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(showThrowArc) { - category = CSTRING(Category); - displayName = CSTRING(ShowThrowArc_DisplayName); - description = CSTRING(ShowThrowArc_Description); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(showMouseControls) { - category = CSTRING(Category); - displayName = CSTRING(ShowMouseControls_DisplayName); - description = CSTRING(ShowMouseControls_Description); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(enablePickUp) { - category = CSTRING(Category); - displayName = CSTRING(EnablePickUp_DisplayName); - description = CSTRING(EnablePickUp_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(enablePickUpAttached) { - category = CSTRING(Category); - displayName = CSTRING(EnablePickUpAttached_DisplayName); - description = CSTRING(EnablePickUpAttached_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; }; diff --git a/addons/advanced_throwing/CfgEventHandlers.hpp b/addons/advanced_throwing/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/advanced_throwing/CfgEventHandlers.hpp +++ b/addons/advanced_throwing/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/advanced_throwing/README.md b/addons/advanced_throwing/README.md index eea1c6e395..bba889d2f7 100644 --- a/addons/advanced_throwing/README.md +++ b/addons/advanced_throwing/README.md @@ -2,10 +2,3 @@ ace_advanced_throwing =================== Integrates advanced throwing by [Dslyecxi](https://github.com/dslyecxi). - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Jonpas](https://github.com/jonpas) diff --git a/addons/advanced_throwing/XEH_postInit.sqf b/addons/advanced_throwing/XEH_postInit.sqf index 7c0a194267..d91129b025 100644 --- a/addons/advanced_throwing/XEH_postInit.sqf +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -1,26 +1,19 @@ #include "script_component.hpp" // Fired XEH -[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; +GVAR(ammoEventHandlers) = createHashMap; +[QGVAR(throwFiredXEH), LINKFUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; // Exit on HC if (!hasInterface) exitWith {}; -// Ammo/Magazines look-up hash for correctness of initSpeed -GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; -{ - { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; }; - } count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); - nil -} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); - +// Temporary Wind Info indication +GVAR(tempWindInfo) = false; // Add keybinds ["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { // Condition - if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; + if !([ACE_player] call FUNC(canPrepare)) exitWith {false}; if (EGVAR(common,isReloading)) exitWith {true}; // Statement diff --git a/addons/advanced_throwing/XEH_preInit.sqf b/addons/advanced_throwing/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/advanced_throwing/XEH_preInit.sqf +++ b/addons/advanced_throwing/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/advanced_throwing/XEH_preStart.sqf b/addons/advanced_throwing/XEH_preStart.sqf index 022888575e..efd2ca1f7e 100644 --- a/addons/advanced_throwing/XEH_preStart.sqf +++ b/addons/advanced_throwing/XEH_preStart.sqf @@ -1,3 +1,21 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Ammo/Magazines look-up hash for correctness of initSpeed +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + +private _ammoMagLookup = createHashMap; + +{ + { + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + if (_ammo != "") then { + _ammoMagLookup set [configName (_cfgAmmo >> _ammo), _x]; + }; + } forEach (getArray (_cfgThrow >> _x >> "magazines")); +} forEach (getArray (_cfgThrow >> "muzzles")); + +uiNamespace setVariable [QGVAR(ammoMagLookup), compileFinal _ammoMagLookup]; diff --git a/addons/advanced_throwing/functions/fnc_canPrepare.sqf b/addons/advanced_throwing/functions/fnc_canPrepare.sqf index 87c6a7843c..827fac4b58 100644 --- a/addons/advanced_throwing/functions/fnc_canPrepare.sqf +++ b/addons/advanced_throwing/functions/fnc_canPrepare.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Checks if a throwable can be prepared. diff --git a/addons/advanced_throwing/functions/fnc_canThrow.sqf b/addons/advanced_throwing/functions/fnc_canThrow.sqf index e5211dd33c..8b2987eafa 100644 --- a/addons/advanced_throwing/functions/fnc_canThrow.sqf +++ b/addons/advanced_throwing/functions/fnc_canThrow.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Checks if a throwable can be thrown. @@ -19,7 +19,7 @@ params ["_unit"]; if !(_unit getVariable [QGVAR(inHand), false]) exitWith {false}; -if (vehicle _unit != _unit) exitWith { +if (!isNull objectParent _unit) exitWith { private _startPos = eyePos _unit; private _aimLinePos = AGLToASL (positionCameraToWorld [0, 0, 1]); private _intersections = lineIntersectsSurfaces [_startPos, _aimLinePos, _unit, objNull, false]; diff --git a/addons/advanced_throwing/functions/fnc_drawArc.sqf b/addons/advanced_throwing/functions/fnc_drawArc.sqf index 906650627f..47b893290e 100644 --- a/addons/advanced_throwing/functions/fnc_drawArc.sqf +++ b/addons/advanced_throwing/functions/fnc_drawArc.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Zapat, Dslyecxi, Jonpas * Draws throw arc. @@ -53,7 +53,7 @@ for "_i" from 0.05 to 1.45 step 0.1 do { if (lineIntersects [_prevTrajASL, _newTrajASL]) then { // Checks the "VIEW" LOD _cross = 2; // 2: View LOD Block (Red) } else { - if (!((lineIntersectsSurfaces [_prevTrajASL, _newTrajASL, _activeThrowable, ACE_player, true, 1, "GEOM", "FIRE"]) isEqualTo [])) then { + if ((lineIntersectsSurfaces [_prevTrajASL, _newTrajASL, _activeThrowable, ACE_player, true, 1, "GEOM", "FIRE"]) isNotEqualTo []) then { _cross = 3; // 3: GEOM/FIRE LOD Block (Yellow) - pass a3 bulding glass, but blocked on some CUP glass }; }; diff --git a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf index 42d52b7153..f85c33dbde 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Dslyecxi, Jonpas, SilentSpike + * Author: Dslyecxi, Jonpas, kymckay * Handles drawing the currently selected or cooked throwable. * * Arguments: @@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable // Get correct throw power for primed grenade if (_primed) then { - private _ammoType = typeOf _activeThrowable; - _throwableMag = GVAR(ammoMagLookup) getVariable _ammoType; - if (isNil "_throwableMag") then { - // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) - // Just use HandGrenade as it has an average initSpeed value - _throwableMag = "HandGrenade"; - }; + // If ammo type is not found: + // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) + // Just use HandGrenade as it has an average initSpeed value + _throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"]; }; // Some throwables have different classname for magazine and ammo @@ -118,7 +115,7 @@ if (abs _leanCoef < 0.15 || {vehicle ACE_player != ACE_player} || {weaponLowered private _posCameraWorld = AGLToASL (positionCameraToWorld [0, 0, 0]); _posHeadRel = _posHeadRel vectorAdd [-0.03, 0.01, 0.15]; // Bring closer to eyePos value -private _posFin = AGLToASL (ACE_player modelToWorldVisual _posHeadRel); +private _posFin = ACE_player modelToWorldVisualWorld _posHeadRel; private _throwType = ACE_player getVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; diff --git a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf index ffe1110dc2..3b88564eae 100644 --- a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf +++ b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Exits throw mode. @@ -53,6 +53,12 @@ _unit setVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]; // Remove controls hint (check if ever enabled is inside the function) call EFUNC(interaction,hideMouseHint); +// Hide wind info after throw, if it was temporarily enabled for the throw +if (GVAR(tempWindInfo)) then { + EGVAR(weather,WindInfo) = false; + GVAR(tempWindInfo) = false; +}; + // Remove throw action [_unit, "DefaultAction", _unit getVariable [QGVAR(throwAction), -1]] call EFUNC(common,removeActionEventHandler); diff --git a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf index 03ac62f6d2..eab95825e4 100644 --- a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf +++ b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Retrieve muzzle name from config. @@ -17,9 +17,9 @@ params ["_magazineClassname"]; -_magazineClassname = toLower _magazineClassname; +_magazineClassname = toLowerANSI _magazineClassname; private _throwMuzzles = getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); -_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLower _x})}; +_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLowerANSI _x})}; [_throwMuzzles select 0, ""] select (_throwMuzzles isEqualTo []) diff --git a/addons/advanced_throwing/functions/fnc_moduleInit.sqf b/addons/advanced_throwing/functions/fnc_moduleInit.sqf index 3f5d3bbd3f..ba67a500ee 100644 --- a/addons/advanced_throwing/functions/fnc_moduleInit.sqf +++ b/addons/advanced_throwing/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Initializes the Advanced Throwing module. diff --git a/addons/advanced_throwing/functions/fnc_onKeyDown.sqf b/addons/advanced_throwing/functions/fnc_onKeyDown.sqf index d0f8404203..c97a6343aa 100644 --- a/addons/advanced_throwing/functions/fnc_onKeyDown.sqf +++ b/addons/advanced_throwing/functions/fnc_onKeyDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Key down event. diff --git a/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf b/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf index 69abb9641b..9e6f57d9e8 100644 --- a/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf +++ b/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Mouse button down event. diff --git a/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf b/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf index f56b153557..290f6ca28e 100644 --- a/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf +++ b/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Mouse scroll wheel changed event. diff --git a/addons/advanced_throwing/functions/fnc_pickUp.sqf b/addons/advanced_throwing/functions/fnc_pickUp.sqf index 9fd49486d1..2484cb1baa 100644 --- a/addons/advanced_throwing/functions/fnc_pickUp.sqf +++ b/addons/advanced_throwing/functions/fnc_pickUp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Picks up a throwable from the ground. diff --git a/addons/advanced_throwing/functions/fnc_prepare.sqf b/addons/advanced_throwing/functions/fnc_prepare.sqf index 393f8301d3..c158ad5150 100644 --- a/addons/advanced_throwing/functions/fnc_prepare.sqf +++ b/addons/advanced_throwing/functions/fnc_prepare.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Prepares throwable or selects the next. @@ -21,7 +21,7 @@ TRACE_1("params",_unit); // Select next throwable if one already in hand if (_unit getVariable [QGVAR(inHand), false]) exitWith { TRACE_1("inHand",_unit); - if (!(_unit getVariable [QGVAR(primed), false])) then { + if !(_unit getVariable [QGVAR(primed), false]) then { TRACE_1("not primed",_unit); // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) // selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles) @@ -35,6 +35,11 @@ if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThr TRACE_1("no throwables",_unit); }; +// Temporarily enable wind info, to aid in throwing smoke grenades effectively +if (GVAR(enableTempWindInfo) && {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])}) then { + [] call EFUNC(weather,displayWindInfo); + GVAR(tempWindInfo) = true; +}; _unit setVariable [QGVAR(inHand), true]; diff --git a/addons/advanced_throwing/functions/fnc_prime.sqf b/addons/advanced_throwing/functions/fnc_prime.sqf index 22681d3ebc..26189fe20d 100644 --- a/addons/advanced_throwing/functions/fnc_prime.sqf +++ b/addons/advanced_throwing/functions/fnc_prime.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Primes the throwable, creates global throwable vehicle and throws Fired XEH. diff --git a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf index 5b7d2c9f0b..d45f2add93 100644 --- a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf +++ b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, Jonpas * When interact_menu starts rendering (from "interact_keyDown" event). @@ -31,7 +31,7 @@ _nearThrowables append (ACE_player nearObjects ["ACE_Chemlight_IR_Dummy", PICK_UP_DISTANCE]); { - if (!(_x in _throwablesHelped) && + if (!(_x in _throwablesHelped) && {!((attachedTo _x) getVariable [QGVAR(disablePickUp), false])} && {!(_x isKindOf "SmokeShellArty")} && {!(_x isKindOf "G_40mm_Smoke")} && // All smokes inherit from "GrenadeHand" >> "SmokeShell" {GVAR(enablePickUpAttached) || {!GVAR(enablePickUpAttached) && {isNull (attachedTo _x)}}} ) then { @@ -44,8 +44,7 @@ _addedPickUpHelpers pushBack _pickUpHelper; _throwablesHelped pushBack _x; }; - nil - } count _nearThrowables; + } forEach _nearThrowables; _args set [0, getPosASL ACE_player]; _args set [3, _nearThrowables]; @@ -56,11 +55,10 @@ { // Only handling with attachTo works nicely _x attachTo [_x getVariable [QGVAR(throwable), objNull], [0, 0, 0]]; - nil - } count _addedPickUpHelpers; + } forEach _addedPickUpHelpers; } else { TRACE_1("Cleaning Pick Up Helpers",count _addedPickUpHelpers); - {deleteVehicle _x} count _addedPickUpHelpers; + {deleteVehicle _x} forEach _addedPickUpHelpers; [_idPFH] call CBA_fnc_removePerFrameHandler; }; }, 0, [(getPosASL ACE_player) vectorAdd [-100, 0, 0], [], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index 3bc69be882..d6b38a6a0c 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, Jonpas * Throw selected throwable. @@ -20,7 +20,7 @@ TRACE_1("params",_unit); // Prime the throwable if it hasn't been cooking already // Next to proper simulation this also has to happen before delay for orientation of the throwable to be set -if (!(_unit getVariable [QGVAR(primed), false])) then { +if !(_unit getVariable [QGVAR(primed), false]) then { [_unit] call FUNC(prime); }; @@ -40,12 +40,12 @@ if (!(_unit getVariable [QGVAR(primed), false])) then { _velocity = [_velocity, THROWSTYLE_DROP_VEL] select _dropMode; private _p2 = (eyePos _unit) vectorAdd (AGLToASL (positionCameraToWorld _direction)) vectorDiff (AGLToASL (positionCameraToWorld [0, 0, 0])); - private _p1 = AGLtoASL (_activeThrowable modelToWorldVisual [0, 0, 0]); + private _p1 = _activeThrowable modelToWorldVisualWorld [0, 0, 0]; private _newVelocity = (_p1 vectorFromTo _p2) vectorMultiply _velocity; // Adjust for throwing from inside vehicles, where we have a vehicle-based velocity that can't be compensated for by a human - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { _newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit)); }; diff --git a/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf b/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf index 5461d5d010..bbbcbf3274 100644 --- a/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf +++ b/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: CBA Team * Throws Fired XEH. @@ -20,14 +20,25 @@ * * Public: No */ - +params ["_unit", "", "_muzzle", "", "_ammo"]; TRACE_1("Fired",_this); { _this call _x; -} forEach ((_this select 0) getVariable "cba_xeh_fired"); +} forEach (_unit 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]); +} forEach (configProperties [configFile >> "CfgWeapons" >> "Throw" >> _muzzle >> "EventHandlers", "isClass _x", true]); + +// Call ammo fired EH +{ _this call _x } forEach (GVAR(ammoEventHandlers) getOrDefaultCall [_ammo, { + private _cfg = configFile >> "CfgAmmo" >> _ammo >> "EventHandlers"; + private _eventHandlers = []; + { + private _eh = getText (_x >> "fired"); + if (_eh != "") then { _eventHandlers pushBack compile _eh }; + } forEach ([_cfg] + configProperties [_cfg, "isClass _x", true]); + _eventHandlers +}, true]); diff --git a/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf b/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf index 3dcb516c32..52f1a3b9e2 100644 --- a/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf +++ b/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Updates controls hints based on current state. diff --git a/addons/advanced_throwing/functions/script_component.hpp b/addons/advanced_throwing/functions/script_component.hpp deleted file mode 100644 index 1927269f9e..0000000000 --- a/addons/advanced_throwing/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\advanced_throwing\script_component.hpp" diff --git a/addons/advanced_throwing/initSettings.inc.sqf b/addons/advanced_throwing/initSettings.inc.sqf new file mode 100644 index 0000000000..d8396637c5 --- /dev/null +++ b/addons/advanced_throwing/initSettings.inc.sqf @@ -0,0 +1,50 @@ +private _category = format ["ACE %1", localize LSTRING(Category)]; +[ + QGVAR(enabled), + "CHECKBOX", + [LSTRING(Enable_DisplayName), LSTRING(Enable_Description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showThrowArc), + "CHECKBOX", + [LSTRING(ShowThrowArc_DisplayName), LSTRING(ShowThrowArc_Description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showMouseControls), "CHECKBOX", + [LSTRING(ShowMouseControls_DisplayName), LSTRING(ShowMouseControls_Description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(enablePickUp), "CHECKBOX", + [LSTRING(EnablePickUp_DisplayName), LSTRING(EnablePickUp_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enablePickUpAttached), "CHECKBOX", + [LSTRING(EnablePickUpAttached_DisplayName), LSTRING(EnablePickUpAttached_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableTempWindInfo), "CHECKBOX", + [LSTRING(EnableTempWindInfo_DisplayName), LSTRING(EnableTempWindInfo_Description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index a060927076..e0e526e12e 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -3,8 +3,9 @@ Advanced Throwing + Lanzamiento Avanzado Улучшенный бросок гранат - アドバンスド スローイング + アドバンスド投擲 Zaawansowane rzucanie Erweitertes Wurfsystem 고급 투척 @@ -12,11 +13,15 @@ Lancio Avanzato 進階投擲 进阶投掷 + Arremesso Avançado + Pokročilé házení + Gelişmiş Fırlatma Allows changing advanced throwing behaviour. + Permite modificar el comportamiento del lanzamiento avanzado Позволяет настраивать поведение улучшенного броска гранат. - アドバンスド スローイングの動作挙動を変更します。 + アドバンスド投擲は投擲の高度な動作挙動を変更可能にします。 Zezwala na zmianę zachowania zaawansowanego trybu rzucania. Erlaubt es, das Verhalten des erweiterten Wurfsystems zu ändern. 고급 투척 행위를 허가합니다 @@ -24,23 +29,30 @@ Permette il cambiamento della modalità di tiro. 允許使用更多不同的投擲方式 允许使用更多不同的投掷方式 + Permite mudar o comportamento do arremesso avançado. + Umožňuje změnit pokročilé chování při házení. Enable Advanced Throwing - Включить улучшенный бросок - アドバンスド スローイングを有効化する + Activar Lanzamiento Avanzado + Вкл. улучшенный бросок + アドバンスド投擲を有効化 Aktywuj zaawansowane rzucanie Aktiviere erweitertes Wurfsystem 고급 투척 활성화 - Active le lancé amélioré + Activer le lancé amélioré Abilita Lancio Avanzato 啟用進階投擲 启用进阶投掷 + Ativa o Arremesso Avançado + Povolit pokročilé házení + Gelişmiş Fırlatmayı Etkinleştir Enables advanced throwing system. + Activa el Lanzamiento Avanzado Включает систему улучшенного броска. - アドバンスド スローイングを有効化します。 + アドバンスド投擲は高度な投擲システムを有効化します。 Aktywuje system zaawansowanego rzucania. Aktiviert das erweiterte Wurfsystem. 고급 투척을 활성화 합니다 @@ -48,203 +60,280 @@ Abilita il sistema di lancio avanzato. 啟用進階投擲系統 启用进阶投掷系统 + Ativa o sistema de Arremesso Avançado. + Umožňuje pokročilý systém házení. + Gelişmiş fırlatma sistemini etkinleştirir. Show Throw Arc + Mostrar Arco de Lanzamiento Показать траекторию броска - 投てき軌道を表示する + 投擲軌道を表示 Pokaż trasę lotu Zeige Wurfbogen 투척 궤적 표시 Afficher l'arc de lancé Mostra Arco di Tiro 顯示投擲軌道 - 显示投掷轨道 + 显示投掷弧线 + Mostrar o Arco de Arremesso + Zobrazit oblouk vrhu + Atış Yayını Göster Enables visualization of the throw arc (where throwable will fly). + Activa la visualización del arco de lanzamiento (donde irá el objeto lanzado) Включает визуализацию траектории броска (как полетит граната). - 投てき軌道 (投てき物がどこに飛ぶか) の表示を有効化します。 + 投擲軌道 (投擲物がどこに飛ぶか) の表示を有効化します。 Wyświetla wizualizację trasy przelotu granatu. Aktiviert die Visualisierung des Wurfbogens (wohin das Objekt geworfen werden wird). 투척 궤도를 시각화 합니다(투척물이 어디로 갈지) - Active la visualisation de l'arc de lancé (où l'objet lancé va atterrir). + Active la visualisation de l'arc de lancé (la trajectoire de vol de l'objet). 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. + Zapíná vizualizaci oblouku vrhu (kam bude předmět hozen). Show Throwing Mouse Controls + Mostrar controles de ratón de lanzamiento Показывать управление мышью - 投てきのマウス操作を表示する + 投擲のマウス操作を表示 Pokaż podpowiedzi sterowania myszą Zeige Maussteuerung beim Werfen 마우스 조작 표시 Afficher les contrôles à la souris du lancé - Mostra Comandi Mouse Lancio + Mostra Comandi Mouse di Lancio 顯示滑鼠投擲控制提示 - 显示滑鼠投掷控制提示 + 显示鼠标投掷控制提示 + Mostrar os controles de mouse para Arremesso + Zobrazit ovládání házení myší Enables visual cues for mouse controls when throwable is prepared. + Activa muestras visuales para los controles del ratón cuando el objeto lanzable está preparado Включает отображение подсказок по управлению мышью, когда граната подготовлена. - 投てき物を構える時、マウス操作の説明表示を有効化します。 + 投擲物を構える時、マウス操作の説明表示を有効化します。 Wyświetla podpowiedzi sterowania myszą kiedy obiekt miotany jest w ręku. Aktiviert visuelle Hinweise zur Maussteuerung, wenn ein Objekt zum Werfen vorbereitet wird. 투척물을 준비시 마우스 조작을 시각화해서 보여줍니다 - Active les aides visuels pour les controles à la souris lorsqu'un lancé est préparé. + Active les aides visuelles pour les contrôles à la souris lorsqu'un lancé est préparé. 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. + Zapíná popisky pro ovládání myší, když je házený předmět připraven. Enable Throwables Pick Up - Включить подбор гранат - 投てき物の拾い上げを有効化する + Habilitar recoger objetos lanzados + Вкл. подбор гранат + 投擲物の拾い上げを有効化 Zezwól na podnoszenie obiektów miotanych Aktiviere Aufheben von Wurfobjekten 투척물 줍기 활성화 - Active la récupération des objets lancés - Abilita Raccogli Oggetti + Permettre le ramassage d'objets lançables + Abilita Raccolta Lanciabili 啟用可撿取地面投擲物 - 启用可捡取地面投掷物 + 启用捡取地面投掷物 + Permitir pegar arremessáveis + Zapnout zdvihání házených předmětů Enables ability to pick up throwables from the ground. + Activa la habilidad de coger objetos lanzados del suelo Включает возможность подбирать гранаты с земли. - 地面に落ちている投てき物を拾い上げる機能を有効化します。 + 地面に落ちている投擲物を拾い上げる機能を有効化します。 Umożliwia podnoszenie obiektów miotanych z ziemi. Aktiviert die Möglichkeit, geworfene Objekte wieder vom Boden aufzuheben. 땅에 떨어진 투척물을 주울 수 있게 해줍니다. - Active la capacité de récupérer les objets lancés sur le sol. - Abilita la possibilità di raccogliere un oggetto lanciabile da terra. + Active la possibilité de ramasser des objets lançables du sol. + Permette ai giocatori di raccogliere un oggetto lanciabile da terra. 啟用後, 可撿取地面上的投擲物 - 启用后, 可捡取地面上的投掷物 + 启用后,可捡取地面上的投掷物 + Permite que objetos arremessados sejam pegos do chão. (ACE Menu de Interação) + Zapíná schopnost zvednutí házených předmětů ze země. Enable Attached Throwables Pick Up - Включить подбор прикрепленных гранат - 取り付けられた投てき物の拾い上げを有効化する + Activar coger objetos lanzables que se enganchan + Вкл. подбор прикрепленных гранат + 装着済の投擲物の拾い上げを有効化 Zezwól na podnoszenie przyczepionych obiektów miotanych Aktiviere erneute Aufnahme befestigter Wurfobjekte 부착 투척물 줍기 활성화 - Active le ramassage d'objets lançables attachés - Abilita Raccogli Oggetti Lanciabili da altri Oggetti + Activer le ramassage d'objets lançables attachés + Abilita Raccolta Lanciabili Attaccati 啟用可撿取附著投擲物 - 启用可捡取附着投掷物 + 启用捡取附着投掷物 + Permitir pegar arremessáveis fixados + Zapnout zdvihání připnutých předmětů. Enables ability to pick up throwables from attached objects. + Activa la habilidad de lanzar objetos enganchados Включает возможность подбирать гранаты, прикрепленные к объектам. - 取り付けられた投てき物を、取り付け先から拾い上げる機能を有効化します。 + オブジェクトに装着された投擲可能物を拾い上げる機能を有効化します。 Umożliwia podnoszenie obiektów miotanych przyczepionych do innych obiektów. Aktiviert die Möglichkeit, befestigte Wurfobjekte erneut aufzunehmen. 부착된 투척물을 주울 수 있게 해줍니다. - Active la capacité à ramasser les objets lançables attaché à d'autres objets. - Abilita la possibilità di raccogliere gli oggetti lanciabili dagli altri oggetti. + Active la possibilité de ramasser des objets lançables attachés à d'autres objets. + Permette ai giocatori di raccogliere gli oggetti lanciabili da altri oggetti attaccati. 啟用後, 可撿取附著在物件上的投擲物 - 启用后, 可捡取附着在物件上的投掷物 + 启用后,可捡取附着在物体上的投掷物 + Permite que arremessáveis fixados em objetos sejam pegos. + Zapíná schopnost zvednutí předmětů z objektů ke kterým jsou připnuté. + + + Show Temporary Wind Info + Zeige temporäre Windinformationen + Mostra informazioni sul vento temporaneamente + 一時的に風の情報を表示 + 바람 정보 임시로 표시 + Afficher temporairement les informations sur le vent + Временно показать информацию о ветре + Mostrar información del viento temporalmente + + + Temporarily display Wind Info while throwing, to aid in placing smoke grenades effectively. + Zeige während des werfens Windinformationen an, um Rauchgranaten effektiver zu platzieren. + Mostra le informazioni sul vento durante il lancio di granate, facilitando il piazzamento ottimale di fumogeni. + 投擲行動中に風向きの情報を一時的に表示し、発煙手榴弾の煙幕を効果的に展開しやすくします。 + 연막탄을 효과적으로 배치하는 데 도움이 되도록 투척하는 동안 일시적으로 바람 정보를 표시합니다. + Affiche les informations sur le vent pendant le lancement pour placer les grenades fumigènes plus efficacement. + Временно отображайте информацию о ветре во время броска, чтобы помочь эффективно разместить дымовые шашки. + Mostrar información del viento temporalmente mientras se lanza, para ayudar a lanzar las granadas de humo de forma efectiva. Prepare/Change Throwable + Preparar/Cambiar objetos lanzables Подготовить/заменить гранату - 投てき物の準備/変更 + 投擲物の準備/変更 Przygotuj/zmień ob. miotany Wurfobjekt vorbereiten/wechseln 투척물 준비/변경 - Préparer/changer d'objet - Prepara/Cambia Oggetto lanciabile + Préparer/Changer d'objet lançable + Prepara/Cambia Oggetto Lanciabile 準備/變更投擲物 准备/变更投掷物 + Preparar/Mudar Arremessável + Připravit/změnit házený předmět Throwable Drop Mode (Hold) + Modo soltar objeto lanzable (Mantener pulsado) Режим броска гранаты (удерживать) - 投てきモード (押している間) + 投擲モード (押している間) Tryb upuszczania ob. miotanego (przytrzymaj) Wurfobjekt Fallmodus (halten) 투척물 떨어뜨리기 모드(꾹눌러서) Mode de lancé de l'objet (Tenir) - Modalità Oggetto Gettabile (Mantenere) + Modalità Gettare (Tieni premuto) 投擲模式 (按住) - 投掷模式 (按住) + 投掷模式(按住) + Modo de Arremesso (Segurar) + Mód puštění (Držet) Throwable Drop Mode (Toggle) + Modo soltar objeto lanzable (interruptor) Режим броска гранаты (переключить) - 投てきモード (切り替え) + 投擲モード (切り替え) Tryb upuszczania ob. miotanego (przełącz) Wurfobjekt Fallmodus (umschalten) 투척물 떨어뜨리기 모드(토글) Mode de lancé de l'objet (Basculer) - Modalità Oggetto lanciabile Gettabile (Interruttore) + Modalità Getta Oggetto (Cambia) 投擲模式 (切換) - 投掷模式 (切换) + 投掷模式(切换) + Modo de Arremesso (Alternar) + Mód puštění (Přepnout) Primed + Preparado Подготовлена 点火 Odbezpieczony Scharf gemacht 뇌관 작동 - Amorcer - Armato + amorcée + Innescato 引信開始燃燒 - 引信开始燃烧 + 已开引信 + Preparado + Odjištěný Throw + Lanzar Бросить 投げる Rzuć Werfen 던지기 Lancer - Lanciare + Lancia 投擲 投掷 + Arremessar + Hodit + At (Scroll) Change Mode + (Scroll) Cambiar Modo (Скролл) Изменить режим (スクロール) モード変更 (Kółko m.) zmień tryb (Scrollen) Modus wechseln (마우스 휠) 모드 변경 - (Molette souris) Changer de mode - (Scorrere) Cambio Modalità + (Défilement) Changer de mode + (Scorri) Cambia Modalità (滾輪) 變更模式 - (滚轮) 变更模式 + (滚轮)变更模式 + (Roda do Mouse) Alternar modo + (Scrollovat) Změnit mód + (Tekerlek) Modu Değiştir (Scroll) Extend + (Scroll) Extender (Скролл) Увеличить (スクロール) 腕を伸ばす (Kółko m.) przedłuż (Scrollen) Erweitern (마우스 휠) 연장 - (Molette souris) Etendre - (Scorrere) Estendere + (Défilement) Étendre + (Scorri) Estendi (滾輪) 延長 - (滚轮) 延长 + (滚轮)延长 + (Roda do Mouse) Estender + (Scrollovat) Oddálit + (Tekerlek) Uzat (Click) Cook + (Click) Cebar (Клик) Подготовить (クリック) 点火する (Kliknięcie) Odbezpiecz (Klicken) Abkochen (클릭) 예열 (Clique) Dégoupiller - (Click) Arma + (Click) Innesca (點擊) 提早拉開引信 - (点击) 提早拉开引信 + (点击)提早拉开引信 + (Clique) Cozinhar + (Klik) Odjistit + (Tıkla) Cook Pick Up + Coger Подобрать - 拾い上げる + 拾う Podnieś Aufheben 줍기 @@ -252,6 +341,9 @@ Raccogli 撿取 捡取 + Pegar + Zvednout + Al diff --git a/addons/ai/CfgEventHandlers.hpp b/addons/ai/CfgEventHandlers.hpp index 9e715077f3..8452cd4fdd 100644 --- a/addons/ai/CfgEventHandlers.hpp +++ b/addons/ai/CfgEventHandlers.hpp @@ -1,24 +1,24 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_DisplayLoad_EventHandlers { class RscDisplayCurator { - ADDON = QUOTE(call FUNC(drawCuratorGarrisonPathing)); + ADDON = QUOTE(call FUNC(initDisplayCurator)); }; }; diff --git a/addons/ai/README.md b/addons/ai/README.md index e3175b1006..7757530905 100644 --- a/addons/ai/README.md +++ b/addons/ai/README.md @@ -2,11 +2,3 @@ ace_ai ====== Overhaul of AI firing modes of vanilla weapons, encouraging the AI to use full-auto and bursts more often. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/ai/XEH_PREP.hpp b/addons/ai/XEH_PREP.hpp index 9596af3286..80c1e45239 100644 --- a/addons/ai/XEH_PREP.hpp +++ b/addons/ai/XEH_PREP.hpp @@ -1,4 +1,7 @@ +PREP(assignNVG); +PREP(assignNVGpfh); PREP(drawCuratorGarrisonPathing); PREP(garrison); -PREP(unGarrison); PREP(garrisonMove); +PREP(initDisplayCurator); +PREP(unGarrison); diff --git a/addons/ai/XEH_postInit.sqf b/addons/ai/XEH_postInit.sqf index 44f3c57472..7c4f79f8fb 100644 --- a/addons/ai/XEH_postInit.sqf +++ b/addons/ai/XEH_postInit.sqf @@ -16,7 +16,7 @@ } forEach _sections; }] call CBA_fnc_addEventHandler; -[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler; +[QGVAR(unGarrison), LINKFUNC(unGarrison)] call CBA_fnc_addEventHandler; [QGVAR(doMove), { params ["_unitsArray"]; @@ -68,3 +68,11 @@ params ["_unit", "_mode"]; _unit enableGunLights _mode; }] call CBA_fnc_addEventHandler; + + +if (isServer) then { + ["CAManBase", "init", { + // wait for HMD to be assigned so `hmd _unit` works + [LINKFUNC(assignNVG), _this, 1] call CBA_fnc_waitAndExecute; + }] call CBA_fnc_addClassEventHandler; +}; diff --git a/addons/ai/XEH_preInit.sqf b/addons/ai/XEH_preInit.sqf index b47cf6628d..b8b036fb31 100644 --- a/addons/ai/XEH_preInit.sqf +++ b/addons/ai/XEH_preInit.sqf @@ -6,4 +6,11 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +if (isServer) then { + GVAR(assignNVGthread) = false; + GVAR(assignNVGstate) = false; +}; + +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/ai/functions/fnc_assignNVG.sqf b/addons/ai/functions/fnc_assignNVG.sqf new file mode 100644 index 0000000000..0c930145a4 --- /dev/null +++ b/addons/ai/functions/fnc_assignNVG.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Assigns AI first found NVG in their inventory during night time and unassigns it during day time. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_ai_fnc_assignNVG + * + * Public: No + */ + +if (!GVAR(assignNVG)) exitWith {}; + +params ["_unit"]; + +if (alive _unit && {!isPlayer _unit}) then { + private _nvg = hmd _unit; + + if (GVAR(assignNVGstate)) then { + if (_nvg == "") then { + private _items = [_unit, false, true, true, true, false, false] call CBA_fnc_uniqueUnitItems; // backpack, vest, uniform + { + if (getText (configFile >> "CfgWeapons" >> _x >> "simulation") == "NVGoggles") exitWith { + _unit assignItem _x; + }; + } forEach _items; + }; + } else { + if (_nvg != "" && {currentVisionMode _unit == 0} && {_unit canAdd _nvg}) then { + _unit unassignItem _nvg; + }; + }; +}; diff --git a/addons/ai/functions/fnc_assignNVGpfh.sqf b/addons/ai/functions/fnc_assignNVGpfh.sqf new file mode 100644 index 0000000000..95e5495b3a --- /dev/null +++ b/addons/ai/functions/fnc_assignNVGpfh.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * waitAndExecute Handler for periodic NVG assignment. + * + * Arguments: + * None + + * Return Value: + * None + * + * Example: + * [] call ace_ai_fnc_assignNVGpfh + * + * Public: No + */ +TRACE_1("assignNVGpfh",count allUnits); + +if (!GVAR(assignNVG)) exitWith { TRACE_1("shutdown loop",_this); GVAR(assignNVGthread) = false; }; + +GVAR(assignNVGstate) = sunOrMoon < 1 || {moonIntensity > 0.8}; + +{ + _x call FUNC(assignNVG); +} forEach allUnits; + +[FUNC(assignNVGpfh), [], 300] call CBA_fnc_waitAndExecute; diff --git a/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf b/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf index de9a5b4dc7..561c8748a6 100644 --- a/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf +++ b/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf @@ -1,54 +1,56 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe - * Add draw3D eh to the curator interface. + * Draws AI garrison pathing while the Zeus display is open. * * Arguments: * None * - * Return value: + * Return Value: * None * + * Example: + * [] call ace_ai_fnc_drawCuratorGarrisonPathing + * * Public: No -*/ + */ -addMissionEventHandler ["Draw3D", { - if (findDisplay 312 isEqualTo displayNull) exitWith { - removeMissionEventHandler ["Draw3D", _thisEventHandler]; - }; +if (isNull findDisplay 312) exitWith { + removeMissionEventHandler ["Draw3D", _thisEventHandler]; +}; - private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; - { - _x params ["_unit", "_pos"]; +private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; - switch (true) do { - case (surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisualWorld [0,0,1], (AGLtoASL _pos), [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; - }; - - case (!surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisual [0,0,1], _pos, [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; - }; - - case (!surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisual [0,0,1], (AGLToASL _pos), [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; - }; - - case (surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisualWorld [0,0,1], _pos, [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; +{ + _x params ["_unit", "_pos"]; + + switch (true) do { + case (surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisualWorld [0,0,1], (AGLtoASL _pos), [1,0,0,1]]; }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; }; - } forEach _unitMoveList; -}]; + + case (!surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisual [0,0,1], _pos, [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; + }; + + case (!surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisual [0,0,1], (AGLToASL _pos), [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; + }; + + case (surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisualWorld [0,0,1], _pos, [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; + }; + }; +} forEach _unitMoveList; diff --git a/addons/ai/functions/fnc_garrison.sqf b/addons/ai/functions/fnc_garrison.sqf index 30238e42a7..4b8f84fce6 100644 --- a/addons/ai/functions/fnc_garrison.sqf +++ b/addons/ai/functions/fnc_garrison.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Garrison function used to garrison AI inside buildings. @@ -7,8 +7,8 @@ * 0: The building(s) nearest this position are used * 1: Limit the building search to those type of building * 2: Units that will be garrisoned - * 3: Radius to fill building(s) (default: 50) - * 4: 0: even filling, 1: building by building, 2: random filling (default: 0) + * 3: Radius to fill building(s) (default: 50) + * 4: 0: even filling, 1: building by building, 2: random filling (default: 0) * 5: True to fill building(s) from top to bottom (default: false) (note: only works with filling mode 0 and 1) * 6: Teleport units (default: false) @@ -33,7 +33,7 @@ if (_startingPos isEqualTo [0,0,0]) exitWith { [LSTRING(GarrisonInvalidPosition)] call EFUNC(common,displayTextStructured); }; -if (count _unitsArray == 0 || {isNull (_unitsArray select 0)}) exitWith { +if (_unitsArray isEqualTo [] || {isNull (_unitsArray select 0)}) exitWith { TRACE_1("fnc_garrison: Units error",_unitsArray); [LSTRING(GarrisonNoUnits)] call EFUNC(common,displayTextStructured); }; @@ -43,7 +43,7 @@ if (_fillingRadius >= 50) then { _buildings = [_buildings] call CBA_fnc_shuffle; }; -if (count _buildings == 0) exitWith { +if (_buildings isEqualTo []) exitWith { TRACE_1("fnc_garrison: Building error",_buildings); [LSTRING(GarrisonNoBuilding)] call EFUNC(common,displayTextStructured); }; @@ -128,7 +128,7 @@ switch (_fillingType) do { } else { private _pos = _building select 0; private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); - LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); @@ -177,7 +177,7 @@ switch (_fillingType) do { } else { private _pos = _building select 0; private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); - LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); @@ -224,7 +224,7 @@ switch (_fillingType) do { } else { private _pos = selectRandom _building; private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); - LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); @@ -258,7 +258,7 @@ switch (_fillingType) do { }; }; -TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)], _teleport); +TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)],_teleport); // Update the unit list and remove duplicate positions and units private _garrison_unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; @@ -279,5 +279,5 @@ if (_teleport) then { [_unitMoveList] call FUNC(garrisonMove); }; -TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left", count _unitsArray, count _buildingsIndex)], _unitsArray); +TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left",count _unitsArray,count _buildingsIndex)],_unitsArray); _unitsArray diff --git a/addons/ai/functions/fnc_garrisonMove.sqf b/addons/ai/functions/fnc_garrisonMove.sqf index 6bba35fbc3..4d1c471a0e 100644 --- a/addons/ai/functions/fnc_garrisonMove.sqf +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Internal function used by ace_ai_fnc_garrison to make the units move to the positions it picked. @@ -33,7 +33,7 @@ private _unitMoveListUnits = (_unitMoveList apply {_x select 0}); _x setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; } foreach _unitMoveListUnits; -// Avoid duplicate PFHs +// Avoid duplicate PFHs if (isNil QGVAR(garrison_moveUnitPFH)) then { missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), true, true]; @@ -81,13 +81,13 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; }; - LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]); + LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left",count _unitMoveList)]); }; // Check if unit is alive or even existing if (!alive _unit || {_unit getVariable [QGVAR(garrisoned), false]}) then { _unitMoveList deleteAt (_unitMoveList find _x); - LOG(format [ARR_2("garrisonMove PFH: unit dead, deleted or garrisoned via TP | %1 units left", count _unitMoveList)]); + LOG(format [ARR_2("garrisonMove PFH: unit dead, deleted or garrisoned via TP | %1 units left",count _unitMoveList)]); } else { private _unitPos = getPos _unit; @@ -114,7 +114,7 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { (_unit getVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, [0,0,0]]]) params ["_unitPosTimer", "_unitOldPos"]; // AI may sometimes not be able to report unitReady, this is to avoid the PFH running forever - switch true do { + switch true do { case ((_unitPos distance _pos) < 1.5) : { call _fnc_attemptSuccessful; }; @@ -127,7 +127,7 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { default { _unit setVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, _unitPos]]; - }; + }; }; }; }; diff --git a/addons/ai/functions/fnc_initDisplayCurator.sqf b/addons/ai/functions/fnc_initDisplayCurator.sqf new file mode 100644 index 0000000000..d3883ab8f3 --- /dev/null +++ b/addons/ai/functions/fnc_initDisplayCurator.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Initializes the Zeus display. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_ai_fnc_initDisplayCurator + * + * Public: No + */ + +addMissionEventHandler ["Draw3D", {call FUNC(drawCuratorGarrisonPathing)}]; diff --git a/addons/ai/functions/fnc_unGarrison.sqf b/addons/ai/functions/fnc_unGarrison.sqf index e098f4b130..09ebc3e63d 100644 --- a/addons/ai/functions/fnc_unGarrison.sqf +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Used to un-garrison units. @@ -28,7 +28,7 @@ _units = _units select {local _x}; private _leader = leader _unit; - TRACE_3("fnc_ungarrison: unit and leader",_unit , _leader, (_leader == _unit)); + TRACE_3("fnc_ungarrison: unit and leader",_unit,_leader,(_leader == _unit)); _unit setVariable [QGVAR(garrisonned), false, true]; diff --git a/addons/ai/functions/script_component.hpp b/addons/ai/functions/script_component.hpp deleted file mode 100644 index 91e8ec0809..0000000000 --- a/addons/ai/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\ai\script_component.hpp" diff --git a/addons/ai/initSettings.inc.sqf b/addons/ai/initSettings.inc.sqf new file mode 100644 index 0000000000..0b2642c7ae --- /dev/null +++ b/addons/ai/initSettings.inc.sqf @@ -0,0 +1,19 @@ +private _category = format ["ACE %1", LLSTRING(DisplayName)]; + +[ + QGVAR(assignNVG), "CHECKBOX", + [LSTRING(AssignNVG_DisplayName), LSTRING(AssignNVG_Description)], + _category, + false, + 1, + { + if (isServer) then { + params ["_enabled"]; + if (_enabled && {!GVAR(assignNVGthread)}) then { + TRACE_1("start loop",_this); + GVAR(assignNVGthread) = true; + [FUNC(assignNVGpfh), [], 1] call CBA_fnc_waitAndExecute; + }; + }; + } +] call CBA_fnc_addSetting; diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index ff6f123261..b9df8bb35a 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -1,10 +1,26 @@ - - + + + AI + AI + IA + IA + IA + SI + ИИ + KI + UI + IA + AI + AI + AI + AI + + Invalid position provided. Ungültige Position - Position invalide fourni + Position invalide fournie. 位置が無効です。 Posizione invalida fornita. 提供的位置無效 @@ -12,11 +28,15 @@ 위치가 잘못되었습니다. Podano błędną pozycję. Указана неверная позиция + Posição inválida fornecida. + Posición inválida proporcionada + Pozice není validní. + Geçersiz Konum - + No units provided. Keine Einheit ausgewählt - Aucune unité fourni + Aucune unité fournie. ユニットがありません。 Nessuna unità fornita. 找不到可用的單位 @@ -24,11 +44,15 @@ 병력이 없습니다. Nie podano żadnych jednostek. Не указаны юниты + Nenhuma unidade fornecida. + No hay unidades proporcionadas. + Nejsou k dispozici žádné jednotky. + Hiçbir Birim Bulunamadı - + 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 + Il n'y a pas assez de positions pour placer toutes les unités. 全ユニットを置くために十分な位置がありません。 Non ci sono abbastanza posizioni per piazzare tutte le unità. 沒有足夠的位置能擺放所有單位 @@ -36,11 +60,15 @@ 모든 병력을 배치 할 공간이 없습니다. Nie ma wystarczającej ilości pozycji, aby umieścić wszystkie jednostki. Недостаточно позиций для размещения всех юнитов + Não há posições suficientes para colocar todas as unidades. + No hay suficientes posiciones para colocar todas las unidades. + Není dostatek pozic pro všechny jednotky. + Tüm birimleri yerleştirmek için yeterli konum yok. - + No building found. Kein Gebäude gefunden - Aucun bâtiment trouvé + Aucun bâtiment trouvé. 建物がありません。 Nessun edificio trovato. 沒找到建築物 @@ -48,6 +76,34 @@ 건물이 없습니다. Nie znaleziono budynku. Здание не найдено + Nenhuma construção encontrada. + No se ha encontrado ningún edificio. + Nenalezena žádná budova. + Bir yapı bulunamadı + + + Auto-Equip NVGs + Automatyczne zakładanie NVG + Automatisch NVGs ausrüsten + Equipaggia NVG in automatico + 야투경 자동 창착 + Equipement JVN automatique + Equipar NVGs automaticamente + 暗視装置の自動装備 + Автоматическое оснащение ПНВ + Auto equipar gafas de visión nocturna + + + Equips NVG in inventory during night time and unequips it during day time.\nDoes not add NVGs to inventory! + Zakłada NVG w nocy i zdejmuje je w ciągu dnia.\nNie dodaje NVG do ekwipunku! + Rüstet NVG nachts aus dem Inventar aus und entfernt es tagsüber.\nFügt keine NVGs zum Inventar hinzu! + Equipaggia NVG dall'inventario durante la notte, e li mette nell'inventario durante il giorno.\nNon aggiunge NVG all'inventario se non sono presenti. + 야간에는 야투경을 소지품에 장착하고 주간에는 장착을 해제합니다.\n주의! 소지품에 야투경을 추가하는 것이 아닙니다! + Equipe des JVN pendant la nuit et les déséquipe le jour.\nN'ajoute pas les JVN dans l'intenvaire ! + Equipa o NVG do inventário durante a noite e desequipa durante o dia.\nNão adiciona NVGs ao inventário! + インベントリ内の暗視装置を夜間に装備し、日中は解除し収納します。\nこれはNVGをインベントリに追加しません。 + Экипирует ПНВ в ночное время и отключает его в дневное время.\nНе добавляет ПНВ в инвентарь! + Equipa las gafas de visión nocturna en el inventario cuando es de noche, y las desequipa cuando es de día.\nNo añade las gafas al inventario! diff --git a/addons/aircraft/CfgAmmo.hpp b/addons/aircraft/CfgAmmo.hpp index 0da9c7760f..4f88c8fa06 100644 --- a/addons/aircraft/CfgAmmo.hpp +++ b/addons/aircraft/CfgAmmo.hpp @@ -1,6 +1,6 @@ class CfgAmmo { class BulletBase; - class B_20mm : BulletBase { + class B_20mm: BulletBase { hit = 80; indirectHit = 12; indirectHitRange = 2; //2; @@ -15,14 +15,15 @@ class CfgAmmo { model = "\A3\Weapons_f\Data\bullettracer\tracer_red"; }; - class ACE_20mm_HE : B_20mm {}; - class ACE_20mm_AP : B_20mm { + class ACE_20mm_HE: B_20mm {}; + class ACE_20mm_AP: B_20mm { hit = 50; indirectHit = 12; indirectHitRange = 0.3; //2; explosive = 0; CraterEffects = ""; explosionEffects = ""; + EGVAR(vehicle_damage,incendiary) = 0.5; }; // adjust minigun caliber and deflection to other ammo @@ -39,9 +40,9 @@ class CfgAmmo { // also adjust tracer, "muh lightshow"; also adjust splash damage radius class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { - hit = 80; // default: 180 + hit = 70; // default: 180 indirectHit = 12; // default: 4 - indirectHitRange = 3; // default: 3 + indirectHitRange = 4; // default: 3 caliber = 1.4; // default: 5 deflecting = 3; // default: 5 fuseDistance = 3; // default: 10 @@ -49,6 +50,46 @@ class CfgAmmo { timeToLive = 40; // default: 6 }; + // adjust damage and splash damage, AP Rounds + class ACE_Gatling_30mm_AP_Plane_CAS_01_F: Gatling_30mm_HE_Plane_CAS_01_F { + explosive = 0.05; // default: 0.4 + caliber = 5; // default: 5 + deflecting = 8; // default: 5 + hit = 110; // default: 180 + indirectHit = 2.5; // default: 4 + indirectHitRange = 1; // default: 3 + fuseDistance = 0.2; // default: 10 + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + + // adds submunition logic, enabling multiple rounds per frame + class ACE_Gatling_30mm_Sub_HEI: SubmunitionBullet { + submunitionAmmo = "Gatling_30mm_HE_Plane_CAS_01_F"; + weaponType = "cannon"; + submunitionConeType[] = {"randomcenter", 3}; + submunitionConeAngle = 0.056; // in degrees, 0.055 ~= 0.001 mils minute, but present + model = "\A3\Weapons_f\Data\bullettracer\tracer_red.p3d"; + triggerTime = 0.005; + ACE_caliber = 1.4; + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + + class ACE_Gatling_30mm_Sub_AP: ACE_Gatling_30mm_Sub_HEI { + submunitionAmmo = "ACE_Gatling_30mm_AP_Plane_CAS_01_F"; + ACE_caliber = 1.4; + }; + + class ACE_Gatling_30mm_Sub_CM41: ACE_Gatling_30mm_Sub_HEI { + submunitionAmmo[] = {"ACE_Gatling_30mm_AP_Plane_CAS_01_F",0.8,"Gatling_30mm_HE_Plane_CAS_01_F",0.2}; + ACE_caliber = 1.4; + }; + + class ACE_Gatling_30mm_Sub_CM51: ACE_Gatling_30mm_Sub_HEI { + submunitionAmmo[] = {"ACE_Gatling_30mm_AP_Plane_CAS_01_F",0.83,"Gatling_30mm_HE_Plane_CAS_01_F",0.17}; + ACE_caliber = 1.4; + }; + + // adjust damage and splash damage, closer to bluefor gatling with same caliber class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F { hit = 70; // default: 150 diff --git a/addons/aircraft/CfgEventHandlers.hpp b/addons/aircraft/CfgEventHandlers.hpp index 93e3311cf2..f6503c2479 100644 --- a/addons/aircraft/CfgEventHandlers.hpp +++ b/addons/aircraft/CfgEventHandlers.hpp @@ -1,11 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/aircraft/CfgMagazines.hpp b/addons/aircraft/CfgMagazines.hpp index 19797b53d8..e8ae200cd9 100644 --- a/addons/aircraft/CfgMagazines.hpp +++ b/addons/aircraft/CfgMagazines.hpp @@ -2,9 +2,36 @@ class CfgMagazines { // shoot helper object to tripple rof class VehicleMagazine; class 1000Rnd_Gatling_30mm_Plane_CAS_01_F: VehicleMagazine { + ammo = "ACE_Gatling_30mm_Sub_CM51"; + displayName = CSTRING(GatlingDescriptionCM51); + displayNameShort = CSTRING(GatlingDescriptionShortCM51); count = 1170; }; + class ACE_1000Rnd_Gatling_30mm_Plane_CAS_HEI: 1000Rnd_Gatling_30mm_Plane_CAS_01_F { + ammo = "ACE_Gatling_30mm_Sub_HEI"; + displayName = CSTRING(GatlingDescriptionHEI); + displayNameShort = CSTRING(GatlingDescriptionShortHEI); + }; + + class ACE_1000Rnd_Gatling_30mm_Plane_CAS_AP: 1000Rnd_Gatling_30mm_Plane_CAS_01_F { + ammo = "ACE_Gatling_30mm_Sub_AP"; + displayName = CSTRING(GatlingDescriptionAP); + displayNameShort = CSTRING(GatlingDescriptionShortAP); + }; + + class ACE_1000Rnd_Gatling_30mm_Plane_CAS_CM41: 1000Rnd_Gatling_30mm_Plane_CAS_01_F { + ammo = "ACE_Gatling_30mm_Sub_CM41"; + displayName = CSTRING(GatlingDescriptionCM41); + displayNameShort = CSTRING(GatlingDescriptionShortCM41); + }; + + class ACE_1000Rnd_Gatling_30mm_Plane_CAS_CM51: 1000Rnd_Gatling_30mm_Plane_CAS_01_F { + ammo = "ACE_Gatling_30mm_Sub_CM51"; + displayName = CSTRING(GatlingDescriptionCM51); + displayNameShort = CSTRING(GatlingDescriptionShortCM51); + }; + // an extended magazine for the comanche class 300Rnd_20mm_shells; class ACE_500Rnd_20mm_shells_Comanche: 300Rnd_20mm_shells { diff --git a/addons/aircraft/CfgWeapons.hpp b/addons/aircraft/CfgWeapons.hpp index 5543925b5b..7c1a87e2fc 100644 --- a/addons/aircraft/CfgWeapons.hpp +++ b/addons/aircraft/CfgWeapons.hpp @@ -2,7 +2,7 @@ class Mode_FullAuto; class CfgWeapons { class RocketPods; - class ACE_AIR_SAFETY : RocketPods { + class ACE_AIR_SAFETY: RocketPods { CanLock = 0; displayName = "SAFE"; displayNameMagazine = "SAFE"; @@ -16,8 +16,21 @@ class CfgWeapons { magazineReloadTime = 0.1; }; - // bigger mag for comanche class CannonCore; + // Fix attrocious A-10 Cannon Dispersion; Add high ROF capability + class Gatling_30mm_Plane_CAS_01_F: CannonCore { + magazines[] += {"ACE_1000Rnd_Gatling_30mm_Plane_CAS_HEI","ACE_1000Rnd_Gatling_30mm_Plane_CAS_AP","ACE_1000Rnd_Gatling_30mm_Plane_CAS_CM41","ACE_1000Rnd_Gatling_30mm_Plane_CAS_CM51"}; + class LowROF: Mode_FullAuto { + multiplier = 3; + burst = 1; + burstRangeMax = 1; + reloadtime = 0.046; + dispersion = 0.0046; //0.279508497 = 0.25 * sqrt(0.8^-1); (80%, 5mil. https://en.wikipedia.org/wiki/GAU-8_Avenger#Accuracy) - Luke + magazines[] = {"1000Rnd_Gatling_30mm_Plane_CAS_01_F", "ACE_1000Rnd_Gatling_30mm_Plane_CAS_CM"}; + + }; + }; + // bigger mag for comanche class gatling_20mm: CannonCore { magazines[] += {"ACE_500Rnd_20mm_shells_Comanche"}; diff --git a/addons/aircraft/Heli_Attack_01_base_F.hpp b/addons/aircraft/Heli_Attack_01_base_F.hpp index 7e59abad48..37d1871c6d 100644 --- a/addons/aircraft/Heli_Attack_01_base_F.hpp +++ b/addons/aircraft/Heli_Attack_01_base_F.hpp @@ -3,8 +3,8 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"ACE_gatling_20mm_Comanche", "missiles_DAGR", "missiles_ASRAAM"}; - magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "4Rnd_AAA_missiles", "24Rnd_PG_missiles"}; + weapons[] = {"ACE_gatling_20mm_Comanche", "missiles_DAGR", "missiles_ASRAAM", "Laserdesignator_mounted"}; + magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "4Rnd_AAA_missiles", "24Rnd_PG_missiles", "Laserbatteries"}; turretInfoType = "Rsc_ACE_Helo_UI_Turret"; @@ -119,9 +119,8 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { class Heli_Attack_01_dynamicLoadout_base_F: Heli_Attack_01_base_F { class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"ACE_gatling_20mm_Comanche"}; - magazines[] = {"ACE_500Rnd_20mm_shells_Comanche"}; + weapons[] = {"ACE_gatling_20mm_Comanche", "Laserdesignator_mounted"}; + magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "Laserbatteries"}; }; }; }; - diff --git a/addons/aircraft/README.md b/addons/aircraft/README.md index c1bf72b3d7..20286990d1 100644 --- a/addons/aircraft/README.md +++ b/addons/aircraft/README.md @@ -4,12 +4,3 @@ ace_aircraft Changes to air weaponry, ejection and HUDs. - Contributions by Kimi (geraldbolso1899) for HUD updates - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) -- [jaynus](https://github.com/walterpearce) diff --git a/addons/aircraft/RscInGameUI.hpp b/addons/aircraft/RscInGameUI.hpp index 67116a7b62..10d41d7009 100644 --- a/addons/aircraft/RscInGameUI.hpp +++ b/addons/aircraft/RscInGameUI.hpp @@ -1,6 +1,6 @@ class RscControlsGroup; class RscText; -class RangeText: RscText{}; +class RangeText: RscText {}; class RscPicture; class RscOpticsText; class RscIGProgress; diff --git a/addons/aircraft/XEH_PREP.hpp b/addons/aircraft/XEH_PREP.hpp index 65407a32f0..a0338e8e4a 100644 --- a/addons/aircraft/XEH_PREP.hpp +++ b/addons/aircraft/XEH_PREP.hpp @@ -1,2 +1,6 @@ -PREP(initEjectAction); PREP(canShowEject); +PREP(droneAddActions); +PREP(droneGetTurretTargetPos); +PREP(droneModifyWaypoint); +PREP(droneSetWaypoint); +PREP(initEjectAction); diff --git a/addons/aircraft/XEH_postInit.sqf b/addons/aircraft/XEH_postInit.sqf new file mode 100644 index 0000000000..169a4d2d94 --- /dev/null +++ b/addons/aircraft/XEH_postInit.sqf @@ -0,0 +1,8 @@ +#include "script_component.hpp" + +[QGVAR(droneModifyWaypoint), LINKFUNC(droneModifyWaypoint)] call CBA_fnc_addEventHandler; +[QGVAR(droneSetWaypoint), LINKFUNC(droneSetWaypoint)] call CBA_fnc_addEventHandler; + +if (hasInterface) then { + ["ACE_controlledUAV", LINKFUNC(droneAddActions)] call CBA_fnc_addEventHandler; +}; diff --git a/addons/aircraft/functions/fnc_canShowEject.sqf b/addons/aircraft/functions/fnc_canShowEject.sqf index 6ec13d2bb9..9239c413a7 100644 --- a/addons/aircraft/functions/fnc_canShowEject.sqf +++ b/addons/aircraft/functions/fnc_canShowEject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Check if Eject action can be shown. @@ -30,6 +30,6 @@ _vehicle == vehicle _unit if (_unit == _x select FULLCREW_UNIT) exitWith { _ejectVarName = format [QGVAR(ejectAction_%1_%2), _x select FULLCREW_ROLE, _x select FULLCREW_TURRETPATH]; }; - } count fullCrew _vehicle; + } forEach fullCrew _vehicle; _vehicle getVariable [_ejectVarName, false] } diff --git a/addons/aircraft/functions/fnc_droneAddActions.sqf b/addons/aircraft/functions/fnc_droneAddActions.sqf new file mode 100644 index 0000000000..38ca53e4c6 --- /dev/null +++ b/addons/aircraft/functions/fnc_droneAddActions.sqf @@ -0,0 +1,121 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds actions to a drone + * + * Arguments: + * 0: vehicle + * + * Return Value: + * None + * + * Example: + * [v] call ace_aircraft_fnc_droneAddActions + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("droneAddActions",_vehicle); + +if (!alive _vehicle) exitWith {}; +if (_vehicle getVariable [QGVAR(droneActionsAdded), false]) exitWith {}; +_vehicle setVariable [QGVAR(droneActionsAdded), true]; + +// move to location +private _condition = { + params ["_vehicle"]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} +}; +private _statement = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; + [QGVAR(droneSetWaypoint), [_vehicle, _group, _pos, "MOVE"], _group] call CBA_fnc_targetEvent; +}; +private _action = [QGVAR(droneSetWaypointMove), localize "$STR_AC_MOVE", + "\a3\3DEN\Data\CfgWaypoints\Move_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); +[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + + +if (_vehicle isKindOf "Air") then { + // loiter at location + _condition = { + params ["_vehicle"]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} + }; + _statement = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; + [QGVAR(droneSetWaypoint), [_vehicle, _group, _pos, "LOITER"], _group] call CBA_fnc_targetEvent; + }; + _action = [QGVAR(droneSetWaypointLoiter), localize "$STR_AC_LOITER", + "\a3\3DEN\Data\CfgWaypoints\Loiter_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); + [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + + + // set height + _condition = { + params ["_vehicle"]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} + }; + _statement = { + params ["_vehicle", "", "_args"]; + private _group = group driver _vehicle; + [QGVAR(droneModifyWaypoint), [_vehicle, _group, "height", _args], _group] call CBA_fnc_targetEvent; + }; + _action = [QGVAR(setAltitude), localize "$STR_3den_waypoint_attribute_loiteraltitude_displayname", + "", {}, _condition] call EFUNC(interact_menu,createAction); + private _base = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + { + _action = [str _x, str _x, "", _statement, { true }, {}, _x] call EFUNC(interact_menu,createAction); + [_vehicle, 1, _base, _action] call EFUNC(interact_menu,addActionToObject); + } forEach [20, 50, 200, 500, 2000]; + + + // set loiter radius + _condition = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _index = (currentWaypoint _group) min count waypoints _group; + private _waypoint = [_group, _index]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} + && {(waypointType _waypoint) == "LOITER"} + }; + _statement = { + params ["_vehicle", "", "_args"]; + private _group = group driver _vehicle; + [QGVAR(droneModifyWaypoint), [_vehicle, _group, "radius", _args], _group] call CBA_fnc_targetEvent; + }; + _action = [QGVAR(lotierRadius), localize "$STR_3den_waypoint_attribute_loiterradius_displayname", + "", {}, _condition] call EFUNC(interact_menu,createAction); + _base = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + { + _action = [str _x, str _x, "", _statement, { true }, {}, _x] call EFUNC(interact_menu,createAction); + [_vehicle, 1, _base, _action] call EFUNC(interact_menu,addActionToObject); + } forEach [500, 750, 1000, 1250, 1500]; + + + // set loiter direction + _condition = { + params ["_vehicle", "", "_args"]; + private _group = group driver _vehicle; + private _index = (currentWaypoint _group) min count waypoints _group; + private _waypoint = [_group, _index]; + + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} + && {(waypointType _waypoint) == "LOITER"} && {(waypointLoiterType _waypoint) != _args} + }; + _statement = { + params ["_vehicle", "", "_args"]; + private _group = group driver _vehicle; + [QGVAR(droneModifyWaypoint), [_vehicle, _group, "dir", _args], _group] call CBA_fnc_targetEvent; + }; + _action = [QGVAR(lotierTypeR), localize "$STR_3den_waypoint_attribute_loiterdirection_displayname", + "\a3\3DEN\Data\Attributes\LoiterDirection\cw_ca.paa", _statement, _condition, {}, "CIRCLE"] call EFUNC(interact_menu,createAction); + [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + _action = [QGVAR(lotierTypeR), localize "$STR_3den_waypoint_attribute_loiterdirection_displayname", + "\a3\3DEN\Data\Attributes\LoiterDirection\ccw_ca.paa", _statement, _condition, {}, "CIRCLE_L"] call EFUNC(interact_menu,createAction); + [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +}; diff --git a/addons/aircraft/functions/fnc_droneGetTurretTargetPos.sqf b/addons/aircraft/functions/fnc_droneGetTurretTargetPos.sqf new file mode 100644 index 0000000000..f3914f4af6 --- /dev/null +++ b/addons/aircraft/functions/fnc_droneGetTurretTargetPos.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Get drone's target location, if aimed at infinity it will return a virtual point + * + * Arguments: + * 0: vehicle + * + * Return Value: + * [PosASL , Real ] + * + * Example: + * [v] call ace_aircraft_fnc_droneGetTurretTargetPos + * + * Public: No + */ + +params ["_vehicle"]; +private _turret = [0]; +TRACE_2("droneGetTurretTargetPos",_vehicle,_turret); + +private _turretConfig = [_vehicle, _turret] call CBA_fnc_getTurret; + +private _gunBeg = _vehicle selectionPosition getText (_turretConfig >> "gunBeg"); +private _gunEnd = _vehicle selectionPosition getText (_turretConfig >> "gunEnd"); + +if (_gunEnd isEqualTo _gunBeg) then { + // e.g. Darter doesn't have valid gunBeg/gunEnd + private _vehicleConfig = configOf _vehicle; + _gunBeg = _vehicle selectionPosition getText (_vehicleConfig >> "uavCameraGunnerDir"); + _gunEnd = _vehicle selectionPosition getText (_vehicleConfig >> "uavCameraGunnerPos"); +}; + +_gunBeg = AGLToASL (_vehicle modelToWorld _gunBeg); +_gunEnd = AGLToASL (_vehicle modelToWorld _gunEnd); +private _turretDir = _gunEnd vectorFromTo _gunBeg; +private _farPoint = _gunEnd vectorAdd (_turretDir vectorMultiply 4999); + +private _intersections = lineIntersectsSurfaces [_gunEnd, _farPoint, _vehicle, objNull, true, 1]; +if (_intersections isNotEqualTo []) then { + [_intersections select 0 select 0, true] +} else { + // Not looking at anything, just get a virtual point where the camera is pointing + _farPoint set [2, 0 max getTerrainHeightASL _farPoint]; + [_farPoint, false] +}; diff --git a/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf b/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf new file mode 100644 index 0000000000..b85e556587 --- /dev/null +++ b/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Modify the current waypoint of a drone + * + * Arguments: + * 0: Vehicle + * 1: Group + * 2: Type + * 3: Value + * + * Return Value: + * None + * + * Example: + * [v, group v, "height", 2000] call ace_aircraft_fnc_droneModifyWaypoint + * + * Public: No + */ + +params ["_vehicle", "_group", "_type", "_value"]; +TRACE_4("droneModifyWaypoint",_vehicle,_group,_type,_value); + +private _index = (currentWaypoint _group) min count waypoints _group; +private _waypoint = [_group, _index]; +switch (toLowerANSI _type) do { + case ("height"): { + private _pos = waypointPosition _waypoint; + _pos set [2, _value]; + _waypoint setWaypointPosition [_pos, 0]; + _vehicle flyInHeight _value; + }; + case ("radius"): { _waypoint setWaypointLoiterRadius _value; }; + case ("dir"): { _waypoint setWaypointLoiterType _value; }; +}; +_group setCurrentWaypoint _waypoint; diff --git a/addons/aircraft/functions/fnc_droneSetWaypoint.sqf b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf new file mode 100644 index 0000000000..5ffbbae825 --- /dev/null +++ b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Set new waypoint of a drone + * + * Arguments: + * 0: Vehicle + * 1: Group + * 2: Pos 2D + * 3: Type + * + * Return Value: + * None + * + * Example: + * [v, group v, [2000,5000], "LOITER"] call ace_aircraft_fnc_droneSetWaypoint + * + * Public: No + */ + +params ["_vehicle", "_group", "_pos", "_type"]; +TRACE_4("droneSetWaypoint",_vehicle,_group,_pos,_type); + +private _index = (currentWaypoint _group) min count waypoints _group; +private _waypoint = [_group, _index]; +// Try to save attributes from existing waypoint +private _currentHeight = round ((waypointPosition _waypoint) select 2); +private _currentLoiterRadius = waypointLoiterRadius _waypoint; +private _currentLoiterType = waypointLoiterType _waypoint; + +// Set pos to ATL +_pos set [ + 2, + [0, _currentHeight] select (_currentHeight >= 50) +]; + +// [_group] call CBA_fnc_clearWaypoints; +_waypoint = _group addWaypoint [_pos, 0]; +_waypoint setWaypointType _type; + +TRACE_3("",_currentHeight,_currentLoiterRadius,_currentLoiterType); +if (_currentHeight > 1) then { _vehicle flyInHeight _currentHeight; }; +if (_currentLoiterRadius > 1) then { _waypoint setWaypointLoiterRadius _currentLoiterRadius; }; +if (_currentLoiterType != "") then { _waypoint setWaypointLoiterType _currentLoiterType; }; + +_group setCurrentWaypoint _waypoint; diff --git a/addons/aircraft/functions/fnc_initEjectAction.sqf b/addons/aircraft/functions/fnc_initEjectAction.sqf index 8ec9e33ade..8fdf662c7c 100644 --- a/addons/aircraft/functions/fnc_initEjectAction.sqf +++ b/addons/aircraft/functions/fnc_initEjectAction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Add Eject action to vehicle if needed. @@ -19,7 +19,7 @@ params ["_vehicle"]; if (unitIsUAV _vehicle) exitWith {}; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _addAction = false; diff --git a/addons/aircraft/functions/script_component.hpp b/addons/aircraft/functions/script_component.hpp deleted file mode 100644 index 8614d199c3..0000000000 --- a/addons/aircraft/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\aircraft\script_component.hpp" diff --git a/addons/aircraft/stringtable.xml b/addons/aircraft/stringtable.xml index 0c52397242..c0cef87756 100644 --- a/addons/aircraft/stringtable.xml +++ b/addons/aircraft/stringtable.xml @@ -16,6 +16,7 @@ XM301 XM301 XM301 + XM301 Open Cargo Door @@ -28,10 +29,11 @@ Открыть грузовой отсек Apri la rampa di carico Abrir porta de carga - カーゴ ドアを開く + 貨物室ドアを 開く 화물칸 개방 開啟貨艙門 开启货舱门 + Kargo kapısını aç Close Cargo Door @@ -44,10 +46,136 @@ Закрыть грузовой отсек Chiudi la rampa di carico Fechar porta de carga - カーゴ ドアを閉じる + 貨物室ドアを 閉じる 화물칸 폐쇄 關閉貨艙門 关闭货舱门 + Kargo kapısını kapat + + + 30mm High-Explosive Incendiary + 30mm Alto Explosivo Incendiaria + 30毫米高爆燃燒彈 + 30 mm 高爆燃烧 + 30 mm High-Explosive Incendiary + 30mm Odłamkowo-Burzące - Zapalające + 30mm Yüksek Patlayıcı + 30mm Hochexplosiv/Brandladung + 30mm Esplosivo/Incendiario + 30mm 焼夷榴弾 + 30mm Tříštivo-trhavá zápalná střela + 30мм Осколочно-Фугасный Зажигательный + 30mm 고폭소이탄 + 30mm Alto-Explosivo Incendiária + + + 30mm HEI + 30mm AEI + 30毫米高爆燃燒 + 30mm 高爆燃烧 + 30mm HEI + 30 mm HEI + 30mm OB-Z + 30mm HEI + 30mm HEB + 30mm HEI + 30mm HEI + 30мм ОФЗ + 30mm HEI + 30mm AEI + + + 30mm DU Armor Piercing + 30mm UE Perforante de Blindaje + 30毫米貧化鈾穿甲彈 + 30 mm 贫铀穿甲 + 30 mm UA Armor Piercing + 30mm AP Uranio Impoverito + 30mm Zubożony Uran - Przebijające + 30mm DU Zırh Delici + 30mm abgereichertes panzerbrechendes Uraniumgeschoss + 30mm 劣化ウラン徹甲弾 + 30mm Protipancéřová střela z ochuzeného Uranu + 30мм ОУ Бронебойный Снаряд + 30mm 열화우라늄 철갑탄 + 30mm DU Perfurante de Blindagem + + + 30mm DU AP + 30mm UE AP + 30毫米貧鈾穿甲 + 30mm 贫铀穿甲 + 30 mm UA AP + 30mm AP-UI + 30mm ZU-P + 30mm DU AP + 30mm DU-PB + 30mm DU AP + 30 mm DU AP + 30мм ОУ БС + 30mm DU AP + 30mm DU AP + + + 30mm Combat Mix 4:1 DU:HEI + 30mm Mezcla de Combate 4:1 UE:AEI + 30毫米戰鬥混合彈4:1 穿甲:高爆 + 30mm 战斗混合 穿甲/高爆 4:1 + 30 mm Mix de Combat 4:1 UA:HEI + 30mm Misto 4:1 UI:HEI + 30mm Mieszanka bojowa 4:1 ZU:OB-Z + 30mm Combat Mix 4:1 DU:HEI + 30mm Kampfmischung 4:1 DU:HEB + 30mm コンバット ミックス 4:1 劣化ウラン徹甲弾:焼夷榴弾 + 30mm Bojový Mix 4:1 DU:HEI + 30мм Смешанное боепитание 4:1 ОУ:ОФЗ + 30mm 4:1 열화:고폭소이 + 30mm Mix de Combate 4:1 DU:AEI + + + 30mm CM 4:1 + 30mm MC 4:1 + 30毫米 穿高混合 4:1 + 30mm 穿爆混合 4:1 + 30 mm MdC 4:1 + 30mm Misto 4:1 + 30mm MB 4:1 + 30mm CM 4:1 + 30mm KM 4:1 + 30mm CM 4:1 + 30mm BM 4:1 + 30мм СБ 4:1 + 30mm CM 4:1 + + + 30mm Combat Mix 5:1 DU:HEI + 30mm Mezcla de Combate 5:1 UE:AEI + 30毫米戰鬥混合彈5:1 穿甲:高爆 + 30 mm 战斗混合 穿甲/高爆 5:1 + 30 mm Mix de Combat 5:1 UA:HEI + 30mm Misto 5:1 UI:HEI + 30mm Mieszanka bojowa 5:1 ZU:OB-Z + 30mm Combat Mix 5:1 DU:HEI + 30mm Kampfmischung 5:1 DU:HEB + 30mm コンバット ミックス 5:1 劣化ウラン徹甲弾:焼夷榴弾 + 30mm Bojový Mix 5:1 DU:HEI + 30мм Смешанное боепитание 5:1 ОУ:ОФЗ + 30mm 5:1 열화:고폭소이 + + + 30mm CM 5:1 + 30mm MC 5:1 + 30毫米 穿高混合 5:1 + 30mm 穿爆混合 5:1 + 30 mm MdC 5:1 + 30mm Misto 5:1 + 30mm MB 5:1 + 30mm CM 5:1 + 30mm KM 5:1 + 30mm CM 5:1 + 30mm BM 5:1 + 30мм СБ 5:1 + 30mm CM 5:1 diff --git a/addons/apl/README.md b/addons/apl/README.md index 13b5f9d268..10f826e4a9 100644 --- a/addons/apl/README.md +++ b/addons/apl/README.md @@ -2,10 +2,3 @@ ace_apl ============ Assets licensed under Arma Public License (APL). - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- None diff --git a/addons/apl/ace_csw_tripod_m122.p3d b/addons/apl/ace_csw_tripod_m122.p3d index 38e4199fe2..90cf2157ab 100644 Binary files a/addons/apl/ace_csw_tripod_m122.p3d and b/addons/apl/ace_csw_tripod_m122.p3d differ diff --git a/addons/apl/ace_csw_tripod_spg9.p3d b/addons/apl/ace_csw_tripod_spg9.p3d index ec19e4f103..1b5ede50fd 100644 Binary files a/addons/apl/ace_csw_tripod_spg9.p3d and b/addons/apl/ace_csw_tripod_spg9.p3d differ diff --git a/addons/apl/ace_envelope_small.p3d b/addons/apl/ace_envelope_small.p3d index 9bc35d7b4a..8b4c0e5f5e 100644 Binary files a/addons/apl/ace_envelope_small.p3d and b/addons/apl/ace_envelope_small.p3d differ diff --git a/addons/apl/ace_envelope_small4.p3d b/addons/apl/ace_envelope_small4.p3d index d139f6bbca..8cd6bc3325 100644 Binary files a/addons/apl/ace_envelope_small4.p3d and b/addons/apl/ace_envelope_small4.p3d differ diff --git a/addons/apl/ace_envelope_small4_nogeo.p3d b/addons/apl/ace_envelope_small4_nogeo.p3d index a39195505c..b3a261918f 100644 Binary files a/addons/apl/ace_envelope_small4_nogeo.p3d and b/addons/apl/ace_envelope_small4_nogeo.p3d differ diff --git a/addons/apl/model.cfg b/addons/apl/model.cfg index 7ed0ad7378..9d9a99a7d4 100644 --- a/addons/apl/model.cfg +++ b/addons/apl/model.cfg @@ -18,11 +18,14 @@ class CfgModels { skeletonName = ""; }; class ace_entrchtool: Default {}; - class ace_envelope_big: Default {}; - class ace_envelope_big4: Default {}; - class ace_envelope_big4_nogeo: Default {}; - class ace_envelope_small: Default {}; - class ace_envelope_small4: Default {}; - class ace_envelope_small4_nogeo: Default {}; + class ace_envelope: Default { + sections[] = {"velka"}; + }; + class ace_envelope_big: ace_envelope {}; + class ace_envelope_big4: ace_envelope {}; + class ace_envelope_big4_nogeo: ace_envelope {}; + class ace_envelope_small: ace_envelope {}; + class ace_envelope_small4: ace_envelope {}; + class ace_envelope_small4_nogeo: ace_envelope {}; class LWTS_optic: Default {}; -}; \ No newline at end of file +}; diff --git a/addons/arsenal/ACE_Arsenal_Actions.hpp b/addons/arsenal/ACE_Arsenal_Actions.hpp new file mode 100644 index 0000000000..a5b95241e2 --- /dev/null +++ b/addons/arsenal/ACE_Arsenal_Actions.hpp @@ -0,0 +1 @@ +class GVAR(actions) {}; diff --git a/addons/arsenal/ACE_Arsenal_Sorts.hpp b/addons/arsenal/ACE_Arsenal_Sorts.hpp new file mode 100644 index 0000000000..db16192468 --- /dev/null +++ b/addons/arsenal/ACE_Arsenal_Sorts.hpp @@ -0,0 +1,85 @@ +class GVAR(sorts) { + class sortBase { + scope = 1; + displayName = ""; + tabs[] = {{}, {}}; + statement = ""; + condition = QUOTE(true); + }; + + class ACE_alphabetically: sortBase { + scope = 2; + displayName = "$STR_a3_rscdisplayarsenal_sort_alphabet"; + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE({}); + }; + + class ACE_mod: sortBase { + scope = 2; + displayName = "$STR_a3_rscdisplayarsenal_sort_mod"; + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE(_this call FUNC(sortStatement_mod)); + }; + + class ACE_mass: sortBase { + scope = 2; + displayName = CSTRING(sortByWeightText); + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE(_this call FUNC(sortStatement_mass)); + }; + + class ACE_amount: sortBase { + scope = 2; + displayName = CSTRING(sortByAmountText); + tabs[] = {{}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE(_this call FUNC(sortStatement_amount)); + condition = QUOTE(_this select 0); // Only show for containers + }; + + class ACE_load: sortBase { + scope = 2; + displayName = CSTRING(sortByLoadText); + tabs[] = {{3,4,5}, {}}; + statement = QUOTE(getContainerMaxLoad (_this select 1)); + }; + + class ACE_accuracy: sortBase { + scope = 2; + displayName = CSTRING(sortByAccuracyText); + tabs[] = {{0,1}, {}}; + statement = QUOTE(_this call FUNC(sortStatement_accuracy)); + }; + + class ACE_rateOfFire: sortBase { + scope = 2; + displayName = CSTRING(sortByRateOfFireText); + tabs[] = {{0,1}, {}}; + statement = QUOTE(_this call FUNC(sortStatement_rateOfFire)); + }; + + class ACE_scopeMag: sortBase { + scope = 2; + displayName = CSTRING(sortByMagnificationText); + tabs[] = {{}, {0}}; + statement = QUOTE(_this call FUNC(sortStatement_scopeMag)); + }; + + class ACE_magCount: sortBase { + scope = 2; + displayName = CSTRING(sortByMagCountText); + tabs[] = {{}, {4}}; + statement = QUOTE(_this call FUNC(sortStatement_magCount)); + }; + + class ACE_protectionBallistic: sortBase { + scope = 2; + displayName = CSTRING(sortByProtectionBallistic); + tabs[] = {{3,4,6}, {}}; + statement = QUOTE([ARR_3(_this,1000000,1000)] call FUNC(sortStatement_protection)); + }; + + class ACE_protectionExplosive: ACE_protectionBallistic { + displayName = CSTRING(sortByProtectionExplosive); + statement = QUOTE([ARR_3(_this,1000,1000000)] call FUNC(sortStatement_protection)); + }; +}; diff --git a/addons/arsenal/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp index 1dd400856a..0856685447 100644 --- a/addons/arsenal/ACE_Arsenal_Stats.hpp +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -8,12 +8,12 @@ class GVAR(stats) { showText = 0; barStatement = ""; textStatement = ""; - condition = "true"; + condition = QUOTE(true); tabs[] = {{}, {}}; }; class ACE_bananaPotassium: statBase { scope = 2; - displayName= CSTRING(statPotassium); + displayName = CSTRING(statPotassium); showBar = 1; barStatement = "1"; condition = QUOTE((configName (_this select 1)) == 'ACE_Banana'); @@ -21,20 +21,21 @@ class GVAR(stats) { }; class ACE_mass: statBase { scope = 2; - displayName= "$STR_a3_rscdisplayarsenal_stat_weight"; + priority = 1.5; + displayName = "$STR_a3_rscdisplayarsenal_stat_weight"; showText = 1; - textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_mass)); + textStatement = QUOTE([ARR_2(_this select 0,_this select 1)] call FUNC(statTextStatement_mass)); tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}}; }; class ACE_rateOfFire: statBase { scope = 2; priority = 5; stats[] = {"reloadTime"}; - displayName= "$STR_a3_rscdisplayarsenal_stat_rof"; + displayName = "$STR_a3_rscdisplayarsenal_stat_rof"; showBar = 1; showText = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-1.4, 0.31)], [ARR_2(1, 0.01)])])] call FUNC(statBarStatement_rateOfFIre)); - textStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-1.4, 0.31)], false)])] call FUNC(statTextStatement_rateOfFire)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_2([ARR_2(-1.4,0.31)],[ARR_2(1,0.01)])])] call FUNC(statBarStatement_rateOfFIre)); + textStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_2([ARR_2(-1.4,0.31)],false)])] call FUNC(statTextStatement_rateOfFire)); tabs[] = {{0,1}, {}}; }; class ACE_accuracy: statBase { @@ -44,26 +45,26 @@ class GVAR(stats) { displayName = "$STR_a3_rscdisplayarsenal_stat_dispersion"; showBar = 1; showText = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(-4, -1.7)], [ARR_2(1, 0.01)], true)])] call FUNC(statBarStatement_accuracy)); - textStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-4, -1.7)], false)])] call FUNC(statTextStatement_accuracy)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(-4,-1.7)],[ARR_2(1,0.01)],true)])] call FUNC(statBarStatement_accuracy)); + textStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_2([ARR_2(-4,-1.7)],false)])] call FUNC(statTextStatement_accuracy)); tabs[] = {{0,1}, {}}; }; class ACE_maxZeroing: statBase { scope = 2; - priority = 3; + priority = 3.2; stats[] = {"maxZeroing"}; displayName = "$STR_a3_rscdisplayarsenal_stat_range"; showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 2500)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,2500)],[ARR_2(0.01,1)],false)])] call FUNC(statBarStatement_default)); tabs[] = {{0,1,2}, {}}; }; class ACE_impact: statBase { scope = 2; - priority = 2; + priority = 3.1; stats[] = {"hit", "initSpeed"}; displayName = "$STR_a3_rscdisplayarsenal_stat_impact"; showBar = 1; - barStatement = QUOTE([ARR_3(_this select 0, _this select 1, [ARR_3([ARR_2(0, 3.2)], [ARR_2(-1, 1100)], 2006)])] call FUNC(statBarStatement_impact)); + barStatement = QUOTE([ARR_3(_this select 0,_this select 1,[ARR_2([ARR_2(0,3.2)],[ARR_2(-1,1100)])])] call FUNC(statBarStatement_impact)); tabs[] = {{0,1,2}, {}}; }; class ACE_scopeMagnification: statBase { @@ -74,21 +75,37 @@ class GVAR(stats) { textStatement = QUOTE(call FUNC(statTextStatement_scopeMag)); tabs[] = {{}, {0}}; }; + class ACE_binoMagnification: statBase { + scope = 2; + priority = 2; + displayName = CSTRING(statMagnification); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_binoMag)); + tabs[] = {{9}, {}}; + }; class ACE_scopeVisionMode: statBase { scope = 2; - priority = 1; + priority = 1.6; displayName = CSTRING(statVisionMode); showText = 1; textStatement = QUOTE(call FUNC(statTextStatement_scopeVisionMode)); tabs[] = {{}, {0}}; }; + class ACE_binoVisionMode: statBase { + scope = 2; + priority = 1.6; + displayName = CSTRING(statVisionModeGeneric); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_binoVisionMode)); + tabs[] = {{8,9}, {}}; + }; class ACE_ballisticProtection: statBase { scope = 2; priority = 5; stats[] = {"passthrough"}; displayName = "$STR_a3_rscdisplayarsenal_stat_passthrough"; showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 0.63)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,0.63)],[ARR_2(0.01,1)],false)])] call FUNC(statBarStatement_default)); tabs[] = {{3,4,6}, {}}; }; class ACE_explosiveResistance: statBase { @@ -97,7 +114,7 @@ class GVAR(stats) { stats[] = {"armor"}; displayName = "$STR_a3_rscdisplayarsenal_stat_armor"; showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 0.80)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,0.80)],[ARR_2(0.01,1)],false)])] call FUNC(statBarStatement_default)); tabs[] = {{3,4,6}, {}}; }; class ACE_load: statBase { @@ -106,7 +123,9 @@ class GVAR(stats) { stats[] = {"maximumLoad"}; displayName = "$STR_a3_rscdisplayarsenal_stat_load"; showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 500)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + showText = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,500)],[ARR_2(0.01,1)],false)])] call FUNC(statBarStatement_default)); + textStatement = QUOTE(call FUNC(statTextStatement_load)); tabs[] = {{3,4,5}, {}}; }; class ACE_smokeChemTTL: statBase { @@ -115,8 +134,33 @@ class GVAR(stats) { stats[] = {"ammo"}; displayName = CSTRING(statTTL); showText = 1; - textStatement= QUOTE(call FUNC(statTextStatement_smokeChemTTL)); - condition = QUOTE((configName (_this select 1)) isKindOf [ARR_2('smokeShell', configFile >> 'CfgMagazines')]); + textStatement = QUOTE(call FUNC(statTextStatement_smokeChemTTL)); + condition = QUOTE((configName (_this select 1)) isKindOf [ARR_2('smokeShell',configFile >> 'CfgMagazines')]); tabs[] = {{}, {5}}; }; + class ACE_explosionTime: statBase { + scope = 2; + priority = 3; + displayName = CSTRING(StatExplosionTime); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_explosionTime)); + tabs[] = {{}, {5}}; + }; + class ACE_magCount: statBase { + scope = 2; + priority = 1; + displayName = CSTRING(statMagCount); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_magCount)); + tabs[] = {{}, {4}}; + }; + class ACE_illuminators: statBase { + scope = 2; + priority = 1; + stats[] = {}; + displayName = CSTRING(statIlluminators); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_illuminators)); + tabs[] = {{}, {1}}; + }; }; diff --git a/addons/arsenal/Cfg3DEN.hpp b/addons/arsenal/Cfg3DEN.hpp index 8b40f77bfe..1cec4a9c75 100644 --- a/addons/arsenal/Cfg3DEN.hpp +++ b/addons/arsenal/Cfg3DEN.hpp @@ -28,7 +28,7 @@ class Cfg3DEN { w = QUOTE(130 * ATTRIBUTE_W); h = QUOTE(106.83 * ATTRIBUTE_H); attributeLoad = QUOTE([ARR_2(_this,+_value)] call FUNC(attributeLoad)); - attributeSave = QUOTE(uiNamespace getVariable [ARR_2(QQGVAR(attributeValue),[ARR_2([], 0)])]); + attributeSave = QUOTE(uiNamespace getVariable [ARR_2(QQGVAR(attributeValue),[ARR_2([],0)])]); class controls { class ModeTitle: ctrlStatic { idc = -1; @@ -40,7 +40,7 @@ class Cfg3DEN { }; class Mode: ctrlToolbox { idc = IDC_ATTRIBUTE_MODE; - onToolBoxSelChanged = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0), _this select 1)] call FUNC(attributeMode)); + onToolBoxSelChanged = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0),_this select 1)] call FUNC(attributeMode)); x = QUOTE(5 * ATTRIBUTE_W); y = QUOTE(5 * ATTRIBUTE_H); w = QUOTE(125 * ATTRIBUTE_W); @@ -55,7 +55,7 @@ class Cfg3DEN { }; class Category: ctrlToolboxPictureKeepAspect { idc = IDC_ATTRIBUTE_CATEGORY; - onToolBoxSelChanged = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0), _this select 1)] call FUNC(attributeCategory)); + onToolBoxSelChanged = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0),_this select 1)] call FUNC(attributeCategory)); x = QUOTE(5 * ATTRIBUTE_W); y = QUOTE(15 * ATTRIBUTE_H); w = QUOTE(125 * ATTRIBUTE_W); @@ -110,7 +110,7 @@ class Cfg3DEN { h = QUOTE(65 * ATTRIBUTE_H); drawSideArrows = 1; disableOverflow = 1; - columns[] = {0.05, 0.15, 0.85}; + columns[] = {0.05, 0.15, 0.83, 0.87}; }; class ArrowLeft: ctrlButton { idc = IDC_ATTRIBUTE_LIST_LEFT; @@ -129,7 +129,8 @@ class Cfg3DEN { }; class SearchButton: ctrlButtonPicture { idc = IDC_ATTRIBUTE_SEARCH_BUTTON; - onButtonClick = QUOTE( \ + #pragma hemtt suppress pw3_padded_arg + onButtonClick = QUOTE(\ params ['_searchButton']; \ private _controlsGroup = ctrlParentControlsGroup _searchButton; \ private _searchBar = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR; \ @@ -147,7 +148,8 @@ class Cfg3DEN { class SearchBar: ctrlEdit { idc = IDC_ATTRIBUTE_SEARCHBAR; onKeyUp = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems)); - onMouseButtonClick = QUOTE( \ + #pragma hemtt suppress pw3_padded_arg + onMouseButtonClick = QUOTE(\ params [ARR_2('_searchBar','_button')]; \ if (_button != 1) exitWith {}; \ _searchBar ctrlSetText ''; \ diff --git a/addons/arsenal/CfgEventHandlers.hpp b/addons/arsenal/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/arsenal/CfgEventHandlers.hpp +++ b/addons/arsenal/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/arsenal/CfgWeapons.hpp b/addons/arsenal/CfgWeapons.hpp new file mode 100644 index 0000000000..c45bb7d5ec --- /dev/null +++ b/addons/arsenal/CfgWeapons.hpp @@ -0,0 +1,10 @@ +class CfgWeapons { + class ItemCore; + class ToolKit: ItemCore { + ACE_isTool = 1; // sort in Tools Tab + }; + class DetectorCore; + class MineDetector: DetectorCore { + ACE_isTool = 1; // sort in Tools Tab + }; +}; diff --git a/addons/arsenal/Display3DEN.hpp b/addons/arsenal/Display3DEN.hpp index b1b78b9f92..8377c38164 100644 --- a/addons/arsenal/Display3DEN.hpp +++ b/addons/arsenal/Display3DEN.hpp @@ -26,7 +26,7 @@ class Display3DEN { class GVAR(portVALoadouts) { text = CSTRING(portLoadoutsText); picture = QPATHTOEF(common,data\logo_ace3_ca.paa); - action = QUOTE(call DFUNC(portVALoadouts);); + action = QUOTE(call DFUNC(portVALoadouts)); }; }; }; diff --git a/addons/arsenal/RscDisplayMain.hpp b/addons/arsenal/RscDisplayMain.hpp index b20b99e31e..50b7c28505 100644 --- a/addons/arsenal/RscDisplayMain.hpp +++ b/addons/arsenal/RscDisplayMain.hpp @@ -9,7 +9,6 @@ class RscDisplayMain: RscStandardDisplay { class Controls: Controls { class Bootcamp; - class VRTraining; class Arsenal; class GVAR(mission): Arsenal { idc = -1; diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 656fc5b1d5..94d4739b60 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -1,5 +1,8 @@ +PREP(addAction); PREP(addDefaultLoadout); PREP(addListBoxItem); +PREP(addRightPanelButton); +PREP(addSort); PREP(addStat); PREP(addVirtualItems); PREP(attributeAddCompatible); @@ -13,9 +16,14 @@ PREP(attributeKeyDown); PREP(attributeLoad); PREP(attributeMode); PREP(attributeSelect); +PREP(baseAttachment); +PREP(baseOptic); +PREP(baseWeapon); +PREP(buttonActionsPage); PREP(buttonCargo); PREP(buttonClearAll); PREP(buttonExport); +PREP(buttonFavorites); PREP(buttonHide); PREP(buttonImport); PREP(buttonLoadoutsDelete); @@ -23,17 +31,24 @@ PREP(buttonLoadoutsLoad); PREP(buttonLoadoutsRename); PREP(buttonLoadoutsSave); PREP(buttonLoadoutsShare); -PREP(buttonStats); PREP(buttonStatsPage); +PREP(canEditDefaultLoadout); PREP(clearSearchbar); +PREP(compileActions); +PREP(compileSorts); PREP(compileStats); PREP(fillLeftPanel); PREP(fillLoadoutsList); PREP(fillRightPanel); +PREP(fillSort); +PREP(getVirtualItems); +PREP(handleActions); PREP(handleLoadoutsSearchbar); PREP(handleMouse); PREP(handleScrollWheel); PREP(handleSearchbar); +PREP(handleSearchInputChanged); +PREP(handleSearchModeToggle); PREP(handleStats); PREP(initBox); PREP(itemInfo); @@ -46,6 +61,7 @@ PREP(onLoadoutsClose); PREP(onLoadoutsOpen); PREP(onMouseButtonDown); PREP(onMouseButtonUp); +PREP(onPanelDblClick); PREP(onSelChangedLeft); PREP(onSelChangedLoadouts); PREP(onSelChangedRight); @@ -53,17 +69,37 @@ PREP(onSelChangedRightListnBox); PREP(open3DEN); PREP(openBox); PREP(portVALoadouts); +PREP(refresh); +PREP(removeAction); PREP(removeBox); +PREP(removeDefaultLoadout); +PREP(removeSort); PREP(removeStat); PREP(removeVirtualItems); +PREP(renameDefaultLoadout); +PREP(replaceUniqueItemsLoadout); PREP(scanConfig); PREP(showItem); PREP(sortPanel); +PREP(sortStatement_accuracy); +PREP(statTextStatement_binoMag); +PREP(statTextStatement_binoVisionMode); +PREP(sortStatement_amount); +PREP(sortStatement_magCount); +PREP(sortStatement_mass); +PREP(sortStatement_mod); +PREP(sortStatement_protection); +PREP(sortStatement_rateOfFire); +PREP(sortStatement_scopeMag); PREP(statBarStatement_accuracy); PREP(statBarStatement_default); PREP(statBarStatement_impact); PREP(statBarStatement_rateOfFIre); PREP(statTextStatement_accuracy); +PREP(statTextStatement_explosionTime); +PREP(statTextStatement_illuminators); +PREP(statTextStatement_load); +PREP(statTextStatement_magCount); PREP(statTextStatement_mass); PREP(statTextStatement_rateOfFire); PREP(statTextStatement_scopeMag); @@ -71,5 +107,7 @@ PREP(statTextStatement_scopeVisionMode); PREP(statTextStatement_smokeChemTTL); PREP(updateCamPos); PREP(updateRightPanel); +PREP(updateCurrentItemsList); PREP(updateUniqueItemsList); +PREP(updateVirtualItemsFlat); PREP(verifyLoadout); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index dcc5c7c7b5..7c7c677819 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -1,47 +1,61 @@ #include "script_component.hpp" #include "defines.hpp" +GVAR(currentBox) = objNull; + GVAR(EH_ID) = 0; GVAR(lastSearchTextLeft) = ""; GVAR(lastSearchTextRight) = ""; GVAR(lastSearchTextLoadouts) = ""; +GVAR(lastSortLeft) = ""; +GVAR(lastSortRight) = ""; +GVAR(lastSortDirectionLeft) = DESCENDING; +GVAR(lastSortDirectionRight) = DESCENDING; -[QGVAR(initBox), {_this call FUNC(initBox)}] call CBA_fnc_addEventHandler; -[QGVAR(removeBox), {_this call FUNC(removeBox)}] call CBA_fnc_addEventHandler; +[QGVAR(initBox), LINKFUNC(initBox)] call CBA_fnc_addEventHandler; +[QGVAR(removeBox), LINKFUNC(removeBox)] call CBA_fnc_addEventHandler; +[QGVAR(addDefaultLoadout), LINKFUNC(addDefaultLoadout)] call CBA_fnc_addEventHandler; +[QGVAR(removeDefaultLoadout), LINKFUNC(removeDefaultLoadout)] call CBA_fnc_addEventHandler; +[QGVAR(renameDefaultLoadout), LINKFUNC(renameDefaultLoadout)] call CBA_fnc_addEventHandler; + +[QGVAR(refresh), { + params ["_object"]; + + // If the arsenal is already open, refresh arsenal display + // Deliberate == check, fail on objNull + if (!isNil QGVAR(currentBox) && {GVAR(currentBox) == _object}) then { + [true, true] call FUNC(refresh); + }; +}] call CBA_fnc_addEventHandler; [QGVAR(broadcastFace), { params ["_unit", "_face"]; - _unit setFace _face; }] call CBA_fnc_addEventHandler; [QGVAR(broadcastVoice), { params ["_unit", "_voice"]; - _unit setSpeaker _voice; }] call CBA_fnc_addEventHandler; [QGVAR(loadoutUnshared), { params ["_contentPanelCtrl" , "_playerName", "_loadoutName"]; - if (!(isNil QGVAR(currentLoadoutsTab)) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { - + // If player is in arsenal in the shared tab and a loadout is unshared at the same time + if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { private _dataToCheck = _playerName + _loadoutName; - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbData [_i, 1]) == _dataToCheck) exitwith {_contentPanelCtrl lnbDeleteRow _i}; + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbData [_lbIndex, 1]) == _dataToCheck) exitWith { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; }; } else { - - if ( - profileName == _playerName && - {!(isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts})} - ) then { - - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _loadoutName) exitwith { - _contentPanelCtrl lnbSetPicture [[_i, 0], QPATHTOF(data\iconPublicBlank.paa)]; - _contentPanelCtrl lnbSetValue [[_i, 0], 0]; + if (profileName == _playerName && {!(isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts})}) then { + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _loadoutName) exitWith { + _contentPanelCtrl lnbSetPicture [[_lbIndex, 0], QPATHTOF(data\iconPublicBlank.paa)]; + _contentPanelCtrl lnbSetValue [[_lbIndex, 0], 0]; }; }; }; @@ -49,35 +63,113 @@ GVAR(lastSearchTextLoadouts) = ""; }] call CBA_fnc_addEventHandler; [QGVAR(loadoutShared), { - params ["_contentPanelCtrl" ,"_loadoutArgs"]; + params ["_contentPanelCtrl", "_loadoutArgs"]; _loadoutArgs params ["_playerName", "_loadoutName", "_loadoutData"]; - if (!(isNil QGVAR(currentLoadoutsTab)) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { + // If player is in arsenal in the shared tab and a loadout is shared at the same time + if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { + private _curSelData = _contentPanelCtrl lnbData [lnbCurSelRow _contentPanelCtrl, 1]; - private _curSelData =_contentPanelCtrl lnbData [(lnbCurSelRow _contentPanelCtrl), 1]; - ([_loadoutData] call FUNC(verifyLoadout)) params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"]; + _extendedLoadout params ["_loadout"]; private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; + private _cfgWeapons = configFile >> "CfgWeapons"; ADD_LOADOUTS_LIST_PICTURES _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; - if (_nullItemsAmount > 0) then { - + // Set color of row, depending if items are unavailable/missing + if (_nullItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; } else { - - if (_unavailableItemsAmount > 0) then { + if (_unavailableItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; }; }; + // Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; // Select previously selected loadout - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _curSelData) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _curSelData) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex + }; }; }; }] call CBA_fnc_addEventHandler; + +["CBA_loadoutSet", { + params ["_unit", "_loadout", "_extendedInfo"]; + + // Set face + private _face = _extendedInfo getOrDefault [QGVAR(face), ""]; + + if (_face != "") then { + private _id = [QGVAR(broadcastFace), [_unit, _face], QGVAR(centerFace_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_id, _unit] call CBA_fnc_removeGlobalEventJIP; + }; + + // Set voice + private _voice = _extendedInfo getOrDefault [QGVAR(voice), ""]; + + if (_voice != "") then { + private _id = [QGVAR(broadcastVoice), [_unit, _voice], QGVAR(centerVoice_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_id, _unit] call CBA_fnc_removeGlobalEventJIP; + }; + + // Set insignia + private _insignia = _extendedInfo getOrDefault [QGVAR(insignia), ""]; + + if (_insignia != "") then { + _unit setVariable ["BIS_fnc_setUnitInsignia_class", nil]; + [_unit, _insignia] call BIS_fnc_setUnitInsignia; + }; +}] call CBA_fnc_addEventHandler; + +["CBA_loadoutGet", { + params ["_unit", "_loadout", "_extendedInfo"]; + + // Set face if enabled + if (GVAR(loadoutsSaveFace)) then { + _extendedInfo set [QGVAR(face), face _unit]; + }; + + // Set voice if enabled + if (GVAR(loadoutsSaveVoice)) then { + _extendedInfo set [QGVAR(voice), (speaker _unit) call EFUNC(common,getConfigName)]; + }; + + // Set insignia if enabled + if (GVAR(loadoutsSaveInsignia)) then { + private _insignia = _unit call BIS_fnc_getUnitInsignia; + + if (_insignia != "") then { + _extendedInfo set [QGVAR(insignia), _insignia]; + }; + }; +}] call CBA_fnc_addEventHandler; + +// Compatibility for RHS attachment system. Also used by NIArms. +// Will only work for ACE_player, different arsenal centers will be ignored. RHS limitation. +if (!isNil "rhs_fnc_accGripod") then { + [QEGVAR(arsenal,weaponItemChanged), { + params ["_weapon", "_item", "_itemIndex"]; + if (EGVAR(arsenal,center) != ACE_player) exitWith {}; + + switch (_itemIndex) do { + case ITEM_INDEX_SIDE: { + call rhs_fnc_anpeq15_rail; + }; + case ITEM_INDEX_BIPOD: { + // Need this call to make sure RHS's functions are set + call rhs_fnc_accGripod; + if (getText (configFile >> "CfgWeapons" >> _item >> "rhs_grip_type") == "") then { + call rhs_grip_deinitialize; + }; + }; + }; + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index deb6935c6e..10cc3989e9 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -1,74 +1,94 @@ #include "script_component.hpp" #include "defines.hpp" +#define TOOLS_TAB_ICON "\A3\ui_f\data\igui\cfg\actions\repair_ca.paa" + ADDON = false; PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -// Arsenal -GVAR(modList) = ["","curator","kart","heli","mark","expansion","expansionpremium"]; +#include "initSettings.inc.sqf" -[QGVAR(camInverted), "CHECKBOX", localize LSTRING(invertCameraSetting), localize LSTRING(settingCategory), false] call CBA_Settings_fnc_init; -[QGVAR(enableModIcons), "CHECKBOX", [LSTRING(modIconsSetting), LSTRING(modIconsTooltip)], localize LSTRING(settingCategory), true] call CBA_Settings_fnc_init; -[QGVAR(fontHeight), "SLIDER", [LSTRING(fontHeightSetting), LSTRING(fontHeightTooltip)], localize LSTRING(settingCategory), [1, 10, 4.5, 1]] call CBA_Settings_fnc_init; -[QGVAR(enableIdentityTabs), "CHECKBOX", localize LSTRING(enableIdentityTabsSettings), localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init; - - -// Arsenal loadouts -[QGVAR(allowDefaultLoadouts), "CHECKBOX", [LSTRING(allowDefaultLoadoutsSetting), LSTRING(defaultLoadoutsTooltip)], localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init; -[QGVAR(allowSharedLoadouts), "CHECKBOX", localize LSTRING(allowSharingSetting), localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init; -[QGVAR(EnableRPTLog), "CHECKBOX", [LSTRING(printToRPTSetting), LSTRING(printToRPTTooltip)], localize LSTRING(settingCategory), false, false] call CBA_Settings_fnc_init; - -[QGVAR(statsToggle), { - params ["_display", "_showStats"]; - - private _statsCtrlGroupCtrl = _display displayCtrl IDC_statsBox; - private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; - private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; - private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; - - private _statsButtonCtrl = _display displayCtrl IDC_statsButton; - private _statsButtonCloseCtrl = _display displayCtrl IDC_statsButtonClose; - - { - _x ctrlShow (GVAR(showStats) && {_showStats}); - } forEach [ - _statsCtrlGroupCtrl, - _statsPreviousPageCtrl, - _statsNextPageCtrl, - _statsCurrentPageCtrl, - _statsButtonCloseCtrl - ]; - - _statsButtonCtrl ctrlShow (!GVAR(showStats) && {_showStats}) -}] call CBA_fnc_addEventHandler; - -[QGVAR(statsButton), { - _this call FUNC(buttonStats); -}] call CBA_fnc_addEventHandler; - -[QGVAR(statsChangePage), { - _this call FUNC(buttonStatsPage); -}] call CBA_fnc_addEventHandler; - - -[QGVAR(displayStats), { - _this call FUNC(handleStats); -}] call CBA_fnc_addEventHandler; +// Arsenal events +[QGVAR(statsChangePage), LINKFUNC(buttonStatsPage)] call CBA_fnc_addEventHandler; +[QGVAR(displayStats), LINKFUNC(handleStats)] call CBA_fnc_addEventHandler; +[QGVAR(actionsChangePage), LINKFUNC(buttonActionsPage)] call CBA_fnc_addEventHandler; +[QGVAR(displayActions), LINKFUNC(handleActions)] call CBA_fnc_addEventHandler; +call FUNC(compileActions); +call FUNC(compileSorts); call FUNC(compileStats); -// compatibility with CBA scripted 2d optics framework +[QUOTE(ADDON), {!isNil QGVAR(camera)}] call CBA_fnc_registerFeatureCamera; + +// Compatibility with CBA scripted optics and disposable framework [QGVAR(displayOpened), { - "cba_optics_arsenalOpened" call CBA_fnc_localEvent; - "cba_disposable_arsenalOpened" call CBA_fnc_localEvent; + "CBA_optics_arsenalOpened" call CBA_fnc_localEvent; + "CBA_disposable_arsenalOpened" call CBA_fnc_localEvent; + EGVAR(common,blockItemReplacement) = true; }] call CBA_fnc_addEventHandler; [QGVAR(displayClosed), { - "cba_optics_arsenalClosed" call CBA_fnc_localEvent; - "cba_disposable_arsenalClosed" call CBA_fnc_localEvent; + "CBA_optics_arsenalClosed" call CBA_fnc_localEvent; + "CBA_disposable_arsenalClosed" call CBA_fnc_localEvent; + EGVAR(common,blockItemReplacement) = false; }] call CBA_fnc_addEventHandler; +[QGVAR(cargoChanged), { + params ["_display"]; + // Only update actions if necessary, this can get performance-intensive using the arrow keys + if (!GVAR(updateActionsOnCargoChange)) exitWith {}; + private _actionInfo = [_display]; + _actionInfo append GVAR(actionInfo); + [QGVAR(displayActions), _actionInfo] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; + +// Setup Tools tab +[keys (uiNamespace getVariable [QGVAR(configItemsTools), createHashMap]), LLSTRING(toolsTab), TOOLS_TAB_ICON, -1, true] call FUNC(addRightPanelButton); + +// TODO: make IDCs able to match IDX with simple math? +GVAR(idxMap) = createHashMapFromArray [ + [IDC_buttonPrimaryWeapon, IDX_VIRT_PRIMARY_WEAPONS], + [IDC_buttonHandgun, IDX_VIRT_HANDGUN_WEAPONS], + [IDC_buttonSecondaryWeapon, IDX_VIRT_SECONDARY_WEAPONS], + [IDC_buttonHeadgear, IDX_VIRT_HEADGEAR], + [IDC_buttonUniform, IDX_VIRT_UNIFORM], + [IDC_buttonVest, IDX_VIRT_VEST], + [IDC_buttonBackpack, IDX_VIRT_BACKPACK], + [IDC_buttonGoggles, IDX_VIRT_GOGGLES], + [IDC_buttonNVG, IDX_VIRT_NVG], + [IDC_buttonBinoculars, IDX_VIRT_BINO], + [IDC_buttonMap, IDX_VIRT_MAP], + [IDC_buttonGPS, IDX_VIRT_COMMS], + [IDC_buttonRadio, IDX_VIRT_RADIO], + [IDC_buttonCompass, IDX_VIRT_COMPASS], + [IDC_buttonWatch, IDX_VIRT_WATCH] +]; + +// Make new hashmaps for face/voice/insignia so mission makers can disable them +// Copies of hashmaps aren't final +GVAR(faceCache) = +(uiNamespace getVariable QGVAR(faceCache)); +GVAR(voiceCache) = +(uiNamespace getVariable QGVAR(voiceCache)); +GVAR(insigniaCache) = +(uiNamespace getVariable QGVAR(insigniaCache)); + +// Get mission/campaign insignias +// BIS_fnc_setUnitInsignia will look in mission config, then campaign, then global config last, so overwrite accordingly +private _insigniaCondition = toString { + if (isNumber (_x >> "scope")) then { + getNumber (_x >> "scope") == 2 + } else { + true + }; +}; + +// Ref fnc_addListBoxItem, 0/nil = configFile, 1 = campaignConfigFile, 2 = missionConfigFile +{ + GVAR(insigniaCache) set [_x, 1]; +} forEach (_insigniaCondition configClasses (campaignConfigFile >> "CfgUnitInsignia")); +{ + GVAR(insigniaCache) set [_x, 2]; +} forEach (_insigniaCondition configClasses (missionConfigFile >> "CfgUnitInsignia")); + ADDON = true; diff --git a/addons/arsenal/XEH_preStart.sqf b/addons/arsenal/XEH_preStart.sqf index ed7f4f0345..7e56134010 100644 --- a/addons/arsenal/XEH_preStart.sqf +++ b/addons/arsenal/XEH_preStart.sqf @@ -2,4 +2,12 @@ #include "XEH_PREP.hpp" +// Cache for FUNC(baseWeapon) +uiNamespace setVariable [QGVAR(baseWeaponNameCache), createHashMap]; + +// Caches for names, pictures, mod icons +uiNamespace setVariable [QGVAR(addListBoxItemCache), createHashMap]; +uiNamespace setVariable [QGVAR(rightPanelCache), createHashMap]; +uiNamespace setVariable [QGVAR(sortCache), createHashMap]; + call FUNC(scanConfig); diff --git a/addons/arsenal/config.cpp b/addons/arsenal/config.cpp index 6eb4c895ce..78a07dcfed 100644 --- a/addons/arsenal/config.cpp +++ b/addons/arsenal/config.cpp @@ -8,15 +8,18 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"alganthe", "mharis001"}; + authors[] = {"alganthe", "mharis001", "Brett Mayson", "johnb43"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; #include "ui\RscAttributes.hpp" +#include "ui\RscCustomArsenalButton.hpp" #include "Display3DEN.hpp" #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" +#include "CfgWeapons.hpp" #include "RscDisplayMain.hpp" +#include "ACE_Arsenal_Sorts.hpp" #include "ACE_Arsenal_Stats.hpp" diff --git a/addons/arsenal/data/iconCustom.paa b/addons/arsenal/data/iconCustom.paa new file mode 100644 index 0000000000..8c0c6ff94f Binary files /dev/null and b/addons/arsenal/data/iconCustom.paa differ diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 35d2edc461..cd6d937426 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -5,7 +5,30 @@ #define WIDTH_TOTAL (safezoneW - 2 * (93 * GRID_W)) #define WIDTH_GAP (WIDTH_TOTAL / 100) -#define WIDTH_SINGLE ((WIDTH_TOTAL - 6 * WIDTH_GAP) / 5) +#define WIDTH_SINGLE ((WIDTH_TOTAL - 7 * WIDTH_GAP) / 6) + +// IDDs +#define IDD_MISSION 46 +#define IDD_RSCDISPLAYCURATOR 312 +#define IDD_DISPLAY3DEN 313 + +#define IDC_OK 1 // emulate "OK" button +#define IDC_CANCEL 2 // emulate "Cancel" button + +// Sorting +#define ASCENDING 0 +#define DESCENDING 1 + +// Favorites +#define FAVORITES_COLOR (GVAR(favoritesColor) + [1]) + +// Attachments +#define ITEM_INDEX_MUZZLE 0 +#define ITEM_INDEX_SIDE 1 +#define ITEM_INDEX_OPTIC 2 +#define ITEM_INDEX_BIPOD 3 +#define ITEM_INDEX_MAGAZINE 4 +#define ITEM_INDEX_MAGAZINE_SECONDARY 5 // IDCs #define IDD_ace_arsenal 1127001 @@ -27,6 +50,7 @@ #define IDC_buttonLoadouts 1003 #define IDC_buttonExport 1004 #define IDC_buttonImport 1005 +#define IDC_buttonFavorites 1006 #define IDC_infoBox 11 #define IDC_infoBackground 1101 #define IDC_infoName 1102 @@ -38,7 +62,9 @@ #define IDC_rightTabContent 14 #define IDC_rightTabContentListnBox 15 #define IDC_sortLeftTab 16 +#define IDC_sortLeftTabDirection 161 #define IDC_sortRightTab 17 +#define IDC_sortRightTabDirection 171 #define IDC_leftSearchbar 18 #define IDC_leftSearchbarButton 41 #define IDC_rightSearchbar 19 @@ -79,7 +105,7 @@ #define IDC_iconBackgroundVoice 2034 #define IDC_buttonVoice 2035 #define IDC_iconBackgroundInsigna 2036 -#define IDC_buttonInsigna 2037 +#define IDC_buttonInsignia 2037 #define IDC_iconBackgroundOptic 21 #define IDC_buttonOptic 22 #define IDC_iconBackgroundItemAcc 23 @@ -128,8 +154,22 @@ #define IDC_statsPreviousPage 52 #define IDC_statsNextPage 53 #define IDC_statsCurrentPage 54 -#define IDC_statsButton 55 -#define IDC_statsButtonClose 56 +#define IDC_actionsBox 90 +#define IDC_actionsBackground1 90010 +#define IDC_actionsBackground2 90011 +#define IDC_actionsText1 9001 +#define IDC_actionsButton1 9002 +#define IDC_actionsText2 9003 +#define IDC_actionsButton2 9004 +#define IDC_actionsText3 9005 +#define IDC_actionsButton3 9006 +#define IDC_actionsText4 9007 +#define IDC_actionsButton4 9008 +#define IDC_actionsText5 9009 +#define IDC_actionsButton5 9010 +#define IDC_actionsPreviousPage 91 +#define IDC_actionsNextPage 92 +#define IDC_actionsCurrentPage 93 #define IDD_loadouts_display 1127002 #define IDC_centerBox 3 @@ -165,6 +205,107 @@ #define IDC_ATTRIBUTE_IMPORT_BUTTON 8109 #define IDC_ATTRIBUTE_ADD_COMPATIBLE 8110 +// Indexes of categories +#define IDX_CAT_ALL 0 +#define IDX_CAT_PRIMARY_WEAPON 1 +#define IDX_CAT_SECONDARY_WEAPON 2 +#define IDX_CAT_HANDGUN_WEAPON 3 +#define IDX_CAT_OPTICS_ATTACHMENTS 4 +#define IDX_CAT_FLASHLIGHT_ATTACHMENTS 5 +#define IDX_CAT_MUZZLE_ATTACHMENTS 6 +#define IDX_CAT_BIPOD_ATTACHMENTS 7 +#define IDX_CAT_ITEMS_ALL 8 +#define IDX_CAT_HEADGEAR 9 +#define IDX_CAT_UNIFORM 10 +#define IDX_CAT_VEST 11 +#define IDX_CAT_BACKPACK 12 +#define IDX_CAT_GOGGLES 13 +#define IDX_CAT_NVG 14 +#define IDX_CAT_BINO 15 +#define IDX_CAT_MAP 16 +#define IDX_CAT_COMPASS 17 +#define IDX_CAT_RADIO 18 +#define IDX_CAT_WATCH 19 +#define IDX_CAT_COMMS 20 +#define IDX_CAT_GRENADES 21 +#define IDX_CAT_EXPLOSIVES 22 +#define IDX_CAT_MISC_ITEMS 23 + +// Indexes of virtual items array +#define IDX_VIRT_WEAPONS 0 +#define IDX_VIRT_PRIMARY_WEAPONS 0 +#define IDX_VIRT_SECONDARY_WEAPONS 1 +#define IDX_VIRT_HANDGUN_WEAPONS 2 + +#define IDX_VIRT_ATTACHMENTS 1 +#define IDX_VIRT_OPTICS_ATTACHMENTS 0 +#define IDX_VIRT_FLASHLIGHT_ATTACHMENTS 1 +#define IDX_VIRT_MUZZLE_ATTACHMENTS 2 +#define IDX_VIRT_BIPOD_ATTACHMENTS 3 + +#define IDX_VIRT_ITEMS_ALL 2 +#define IDX_VIRT_HEADGEAR 3 +#define IDX_VIRT_UNIFORM 4 +#define IDX_VIRT_VEST 5 +#define IDX_VIRT_BACKPACK 6 +#define IDX_VIRT_GOGGLES 7 +#define IDX_VIRT_NVG 8 +#define IDX_VIRT_BINO 9 +#define IDX_VIRT_MAP 10 +#define IDX_VIRT_COMPASS 11 +#define IDX_VIRT_RADIO 12 +#define IDX_VIRT_WATCH 13 +#define IDX_VIRT_COMMS 14 +#define IDX_VIRT_GRENADES 15 +#define IDX_VIRT_EXPLOSIVES 16 +#define IDX_VIRT_MISC_ITEMS 17 + +#define IDX_VIRT_UNIQUE_MISC_ITEMS 18 +#define IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL 19 +#define IDX_VIRT_UNIQUE_GRENADES 20 +#define IDX_VIRT_UNIQUE_EXPLOSIVES 21 +#define IDX_VIRT_UNIQUE_ATTACHMENTS 22 +#define IDX_VIRT_UNIQUE_BACKPACKS 23 +#define IDX_VIRT_UNIQUE_GOGGLES 24 +#define IDX_VIRT_UNIQUE_UNKNOWN_ITEMS 25 + +// Indexes of current items array +// Should match IDX_VIRT_X macros for any left panel tabs +#define IDX_CURR_PRIMARY_WEAPON 0 +#define IDX_CURR_SECONDARY_WEAPON 1 +#define IDX_CURR_HANDGUN_WEAPON 2 +#define IDX_CURR_HEADGEAR 3 +#define IDX_CURR_UNIFORM 4 +#define IDX_CURR_VEST 5 +#define IDX_CURR_BACKPACK 6 +#define IDX_CURR_GOGGLES 7 +#define IDX_CURR_NVG 8 +#define IDX_CURR_BINO 9 +#define IDX_CURR_MAP 10 +#define IDX_CURR_COMPASS 11 +#define IDX_CURR_RADIO 12 +#define IDX_CURR_WATCH 13 +#define IDX_CURR_COMMS 14 +#define IDX_CURR_UNIFORM_ITEMS 15 +#define IDX_CURR_VEST_ITEMS 16 +#define IDX_CURR_BACKPACK_ITEMS 17 +#define IDX_CURR_PRIMARY_WEAPON_ITEMS 18 +#define IDX_CURR_SECONDARY_WEAPON_ITEMS 19 +#define IDX_CURR_HANDGUN_WEAPON_ITEMS 20 +#define IDX_CURR_BINO_ITEMS 21 + +// Indexes of loadout items array +#define IDX_LOADOUT_PRIMARY_WEAPON 0 +#define IDX_LOADOUT_SECONDARY_WEAPON 1 +#define IDX_LOADOUT_HANDGUN_WEAPON 2 +#define IDX_LOADOUT_UNIFORM 3 +#define IDX_LOADOUT_VEST 4 +#define IDX_LOADOUT_BACKPACK 5 +#define IDX_LOADOUT_HEADGEAR 6 +#define IDX_LOADOUT_GOGGLES 7 +#define IDX_LOADOUT_BINO 8 +#define IDX_LOADOUT_ASSIGNEDITEMS 9 + #define SYMBOL_ITEM_NONE "−" #define SYMBOL_ITEM_REMOVE "×" #define SYMBOL_ITEM_VIRTUAL "∞" @@ -172,40 +313,14 @@ #define FADE_DELAY 0.15 #define CAM_DIS_MAX 5 +#define RIGHT_PANEL_CUSTOM_BUTTONS 61, 63, 65, 67, 69, 71, 73, 75, 77, 79 +#define RIGHT_PANEL_CUSTOM_BACKGROUND 60, 62, 64, 66, 68, 70, 72, 74, 76, 78 #define RIGHT_PANEL_ACC_IDCS IDC_buttonOptic, IDC_buttonItemAcc, IDC_buttonMuzzle, IDC_buttonBipod #define RIGHT_PANEL_ACC_BACKGROUND_IDCS IDC_iconBackgroundOptic, IDC_iconBackgroundItemAcc, IDC_iconBackgroundMuzzle, IDC_iconBackgroundBipod -#define RIGHT_PANEL_ITEMS_IDCS IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut, IDC_buttonMisc -#define RIGHT_PANEL_ITEMS_BACKGROUND_IDCS IDC_iconBackgroundMag, IDC_iconBackgroundMagALL, IDC_iconBackgroundThrow, IDC_iconBackgroundPut, IDC_iconBackgroundMisc +#define RIGHT_PANEL_ITEMS_IDCS IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut, IDC_buttonMisc, RIGHT_PANEL_CUSTOM_BUTTONS +#define RIGHT_PANEL_ITEMS_BACKGROUND_IDCS IDC_iconBackgroundMag, IDC_iconBackgroundMagALL, IDC_iconBackgroundThrow, IDC_iconBackgroundPut, IDC_iconBackgroundMisc, RIGHT_PANEL_CUSTOM_BACKGROUND #define ARROWS_IDCS IDC_arrowMinus, IDC_arrowPlus -#define GETDLC\ - {\ - private _dlc = "";\ - private _addons = configsourceaddonlist _this;\ - if (count _addons > 0) then {\ - private _mods = configsourcemodlist (configfile >> "CfgPatches" >> _addons select 0);\ - if (count _mods > 0) then {\ - _dlc = _mods select 0;\ - };\ - };\ - _dlc\ - } - -#define ADDMODICON\ - {\ - private _dlcName = _this call GETDLC;\ - if (_dlcName != "") then {\ - _ctrlPanel lbsetpictureright [_lbAdd,(modParams [_dlcName,["logo"]]) param [0,""]];\ - _modID = GVAR(modList) find _dlcName;\ - if (_modID < 0) then {_modID = GVAR(modList) pushback _dlcName;};\ - _ctrlPanel lbsetvalue [_lbAdd,_modID];\ - };\ - }; - -#define ADDBINOCULARSMAG\ - private _magazines = getarray (configfile >> "cfgweapons" >> _item >> "magazines");\ - if (count _magazines > 0) then {GVAR(center) addmagazine (_magazines select 0)}; - #define TOGGLE_RIGHT_PANEL_WEAPON\ {\ _x = _display displayCtrl _x;\ @@ -213,26 +328,21 @@ _x ctrlShow true;\ _x ctrlEnable true;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground,\ IDC_rightTabContent,\ IDC_sortRightTab,\ + IDC_sortRightTabDirection,\ RIGHT_PANEL_ACC_IDCS,\ IDC_rightSearchbar,\ IDC_rightSearchbarButton,\ IDC_buttonCurrentMag\ ];\ private _buttonCurrentMag2Ctrl = _display displayCtrl IDC_buttonCurrentMag2;\ -if (GVAR(currentLeftPanel) == IDC_buttonPrimaryWeapon) then {\ - _buttonCurrentMag2Ctrl ctrlSetFade 0;\ - _buttonCurrentMag2Ctrl ctrlShow true;\ - _buttonCurrentMag2Ctrl ctrlEnable true;\ -} else {\ - _buttonCurrentMag2Ctrl ctrlSetFade 1;\ - _buttonCurrentMag2Ctrl ctrlShow false;\ - _buttonCurrentMag2Ctrl ctrlEnable false;\ -};\ +_buttonCurrentMag2Ctrl ctrlSetFade 0;\ +_buttonCurrentMag2Ctrl ctrlShow true;\ +_buttonCurrentMag2Ctrl ctrlEnable true;\ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ {\ _x = _display displayCtrl _x;\ @@ -240,7 +350,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow false;\ _x ctrlEnable false;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_loadIndicator,\ RIGHT_PANEL_ITEMS_IDCS,\ IDC_rightTabContentListnBox,\ @@ -256,7 +366,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ safezoneH - 28 * GRID_H\ ];\ _x ctrlCommit 0;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground\ ]; @@ -268,12 +378,13 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow true;\ _x ctrlEnable true;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame, \ IDC_blockRighttBackground,\ IDC_loadIndicator,\ IDC_rightTabContentListnBox,\ IDC_sortRightTab,\ + IDC_sortRightTabDirection,\ IDC_tabRight,\ RIGHT_PANEL_ACC_IDCS,\ RIGHT_PANEL_ITEMS_IDCS,\ @@ -286,7 +397,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow false;\ _x ctrlEnable false;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_buttonCurrentMag,\ IDC_buttonCurrentMag2,\ IDC_iconBackgroundCurrentMag,\ @@ -301,10 +412,46 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ safezoneH - 34 * GRID_H\ ];\ _x ctrlCommit 0;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground\ -]; +];\ +if (!isNil QGVAR(customRightPanelButtons)) then {\ + private _miscOffset = 0;\ + {\ + if (!isNil "_x") then {\ + _x params ["", "_picture", "_tooltip"];\ + _miscOffset = _forEachIndex + 1;\ + private _plusId = _forEachIndex * 2;\ + if (isNull (_display displayCtrl (60 + _plusId))) then {\ + private _ctrl = _display ctrlCreate [QGVAR(customArsenalButton_Background), 60 + _plusId];\ + _ctrl ctrlSetPosition [\ + safezoneW + safezoneX - 13 * GRID_W,\ + safezoneY + (88 + (10 * _forEachIndex)) * GRID_H\ + ];\ + _ctrl ctrlCommit 0;\ + };\ + if (isNull (_display displayCtrl (61 + _plusId))) then {\ + _ctrl = _display ctrlCreate [QGVAR(customArsenalButton_Button), 61 + _plusId];\ + _ctrl ctrlSetPosition [\ + safezoneW + safezoneX - 10 * GRID_W,\ + safezoneY + (88 + (10 * _forEachIndex)) * GRID_H\ + ];\ + _ctrl ctrlSetText _picture;\ + _ctrl ctrlSetTooltip _tooltip;\ + _ctrl ctrlCommit 0;\ + };\ + };\ + } forEach GVAR(customRightPanelButtons);\ + {\ + _x = _display displayCtrl _x;\ + _x ctrlSetPosition [\ + safezoneW + safezoneX - (10 + (3 * _forEachIndex)) * GRID_W,\ + safezoneY + (88 + (10 * _miscOffset)) * GRID_H\ + ];\ + _x ctrlCommit 0;\ + } forEach [IDC_buttonMisc, IDC_iconBackgroundMisc];\ +}; #define TOGGLE_RIGHT_PANEL_HIDE\ {\ @@ -313,13 +460,14 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow false;\ _x ctrlEnable false;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground,\ IDC_loadIndicator,\ IDC_rightTabContent,\ IDC_rightTabContentListnBox,\ IDC_sortRightTab,\ + IDC_sortRightTabDirection,\ RIGHT_PANEL_ACC_BACKGROUND_IDCS,\ RIGHT_PANEL_ACC_IDCS,\ RIGHT_PANEL_ITEMS_BACKGROUND_IDCS,\ @@ -333,83 +481,15 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ IDC_iconBackgroundCurrentMag2\ ]; -#define LIST_DEFAULTS\ - [\ - [\ - (primaryweapon GVAR(center) call bis_fnc_baseWeapon),\ - (secondaryweapon GVAR(center) call bis_fnc_baseWeapon),\ - (handgunweapon GVAR(center) call bis_fnc_baseWeapon)\ - ],\ - [\ - [primaryWeaponItems GVAR(center), secondaryWeaponItems GVAR(center), handgunItems GVAR(center)],\ - [primaryWeaponMagazine GVAR(center), secondaryWeaponMagazine GVAR(center), handgunMagazine GVAR(center)]\ - ],\ - uniformItems GVAR(center) + vestItems GVAR(center) + backpackItems GVAR(center),\ - [headgear GVAR(center)],\ - [uniform GVAR(center)],\ - [vest GVAR(center)],\ - [backpack GVAR(center)],\ - [goggles GVAR(center)],\ - [hmd GVAR(center)],\ - [binocular GVAR(center)]\ -] - -#define CHECK_WEAPON_OR_ACC\ - (_weaponsArray select 0) findIf {_x == _item} > -1 ||\ - {(_weaponsArray select 1) findIf {_x == _item} > -1} ||\ - {(_weaponsArray select 2) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 9) findIf {_x == _item} > -1} ||\ - {(_accsArray select 0) findIf {_x == _item} > -1} ||\ - {(_accsArray select 1 findIf {_x == _item} > -1)} ||\ - {(_accsArray select 2) findIf {_x == _item} > -1} ||\ - {(_accsArray select 3) findIf {_x == _item} > -1} - -// PboProject 2.45 has problems with these macros for some reason, adding a single space before the \ fixes -#define CHECK_ASSIGNED_ITEMS \ - (GVAR(virtualItems) select 10) findIf {_x == _item} > -1 ||\ - {(GVAR(virtualItems) select 11) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 12) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 13) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 14) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 8) findIf {_x == _item} > -1} - -#define CHECK_CONTAINER \ - (GVAR(virtualItems) select 4) findIf {_x == _item} > -1 ||\ - {(GVAR(virtualItems) select 5) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 6) findIf {_x == _item} > -1} - -#define CLASS_CHECK_ITEM\ - isClass (_weaponCfg >> _item) ||\ - {isClass (_vehcCfg >> _item)} ||\ - {isClass (_glassesCfg >> _item)} ||\ - {isClass (_magCfg >> _item)} - -#define CHECK_CONTAINER_ITEMS \ - (GVAR(virtualItems) select 3) findIf {_x == _item} > -1 ||\ - {(_accsArray select 0) findIf {_x == _item} > -1} ||\ - {(_accsArray select 1) findIf {_x == _item} > -1} ||\ - {(_accsArray select 2) findIf {_x == _item} > -1} ||\ - {(_accsArray select 3) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 4) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 5) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 6) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 7) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 8) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 10) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 11) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 12) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 13) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 14) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 15) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 16) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 17) findIf {_x == _item} > -1} - #define ADD_LOADOUTS_LIST_PICTURES\ - _contentPanelCtrl lnbSetPicture [[_newRow, 2], getText (configFile >> "cfgWeapons" >> ((_loadout select 0) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 3], getText (configFile >> "cfgWeapons" >> ((_loadout select 1) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 4], getText (configFile >> "cfgWeapons" >> ((_loadout select 2) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 5], getText (configFile >> "cfgWeapons" >> ((_loadout select 3) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 6], getText (configFile >> "cfgWeapons" >> ((_loadout select 4) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "cfgVehicles" >> ((_loadout select 5) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (configFile >> "cfgWeapons" >> (_loadout select 6) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "cfgGlasses" >> (_loadout select 7) >> "picture")]; + _contentPanelCtrl lnbSetPicture [[_newRow, 2], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_PRIMARY_WEAPON) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 3], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_SECONDARY_WEAPON) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 4], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_HANDGUN_WEAPON) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 5], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_UNIFORM) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 6], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_VEST) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "CfgVehicles" >> (_loadout select IDX_LOADOUT_BACKPACK) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (_cfgWeapons >> _loadout select IDX_LOADOUT_HEADGEAR >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "CfgGlasses" >> _loadout select IDX_LOADOUT_GOGGLES >> "picture")]; + +#define ACTION_TYPE_TEXT 0 +#define ACTION_TYPE_BUTTON 1 diff --git a/addons/arsenal/functions/fnc_addAction.sqf b/addons/arsenal/functions/fnc_addAction.sqf new file mode 100644 index 0000000000..b04d56729a --- /dev/null +++ b/addons/arsenal/functions/fnc_addAction.sqf @@ -0,0 +1,129 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43 + * Adds custom action buttons. + * + * Arguments: + * 0: Tabs to add action to + * 1: Action class (unique string for each action) + * 2: Title + * 3: Actions + * 4: Condition (default: {true}) + * 5: Scope editor (default: 2) + * 6: Update when cargo content changes (default: false) + * + * Return Value: + * 0: Array of IDs + * + * Example: + * [[0, 5], "TAG_myActions", "My Actions", [ + * ["text", "Text", {true}, "Text"], + * ["statement", "Statement", {true}, "", {[_this select 0] call tag_fnc_myTextStatement}], + * ["button", "Button", {true}, "", {}, {_this call tag_fnc_myAction}] + * ]] call ace_arsenal_fnc_addAction + * + * Public: Yes + */ + +params [ + ["_tabs", [], [[]]], + ["_rootClass", "", [""]], + ["_title", "", [""]], + ["_actions", [], [[]]], + ["_rootCondition", {true}, [{}]], + ["_scopeEditor", 2, [0]], + ["_updateOnCargoChange", false, [false]] +]; + +// Compile actions from config (in case this is called before preInit) +call FUNC(compileActions); + +// Skip if not allowed in editor and in editor +if (is3DEN && {_scopeEditor != 2}) exitWith { + TRACE_1("Skipping action because in editor",_rootClass); + [] +}; + +// Class can't contain ~, because it's used for formatting result +if ("~" in _rootClass) exitWith { + TRACE_1("Classname can't contain '~'",_rootClass); + [] +}; + +private _return = []; + +private _fnc_addToGroup = { + params ["_group", "_tab"]; + + private _type = -1; + + { + _x params [["_class", "", [""]], ["_label", "", [""]], ["_condition", {true}, [{}]], ["_text", "", [""]], ["_textStatement", {}, [{}]], ["_statement", {}, [{}]]]; + + // Class can't contain ~, because it's used for formatting result + if (_class == "" || {"~" in _class}) then { + continue; + }; + + // Don't allow two of the same class + if (_group findIf {(_x select 0) == _class} != -1) then { + TRACE_1("An action with this ID already exists",_class); + continue; + }; + + _type = switch (false) do { + case (_text == ""): { + _statement = format ["{""%1""}", _text]; + ACTION_TYPE_TEXT + }; + case (_textStatement isEqualTo {}): { + _statement = _textStatement; + ACTION_TYPE_TEXT + }; + case (_statement isEqualTo {}): { + _statement = _statement; + ACTION_TYPE_BUTTON + }; + default { + -1 + }; + }; + + if (_type == -1) then { + continue; + }; + + _statement = compile format [QUOTE([GVAR(center)] call %1), _statement]; + + _group pushBack [_class, _type, _label, _statement, _condition]; + _return pushBack ([_rootClass, _class, _tab] joinString "~"); + } forEach _actions; +}; + +private _tab = []; +private _index = -1; +private _group = []; + +{ + _tab = GVAR(actionList) select _x; + _index = _tab findIf {(_x select 0) == _rootClass}; + + // Add to existing group + if (_index != -1) then { + [_tab select _index select 3, _x] call _fnc_addToGroup; + } else { + // Add to new group + _group = []; + + [_group, _x] call _fnc_addToGroup; + + _tab pushBack [_rootClass, _title, _rootCondition, _group]; + }; +} forEach _tabs; + +if (_updateOnCargoChange) then { + GVAR(updateActionsOnCargoChange) = true; +}; + +_return diff --git a/addons/arsenal/functions/fnc_addDefaultLoadout.sqf b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf index 2c18a38ca6..f54ff03eeb 100644 --- a/addons/arsenal/functions/fnc_addDefaultLoadout.sqf +++ b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: 654wak654 + * Author: 654wak654, johnb43 * Adds a loadout to the "Default Loadouts" list. - * If a loadout with the same name exists, it is overwritten. + * If a loadout with a similar name exists (case insensitve), it is overwritten. * * Arguments: * 0: Name of loadout - * 1: getUnitLoadout array + * 1: CBA extended loadout or getUnitLoadout array + * 2: Add globally (default: false) * * Return Value: * None @@ -17,15 +18,40 @@ * Public: Yes */ -params [["_name", "", [""]], ["_loadout", [], [[]], 10]]; +params [["_name", "", [""]], ["_loadout", [], [[]]], ["_global", false, [false]]]; + +if (_global) exitWith { + private _eventID = format [QGVAR(loadouts_%1), _name]; + [QGVAR(addDefaultLoadout), [_name, _loadout], _eventID] call CBA_fnc_globalEventJIP; +}; + +private _extendedInfo = createHashMap; + +// Check if CBA extended loadout array +if (count _loadout == 2) then { + _extendedInfo = _loadout select 1; + _loadout = _loadout select 0; +}; + +if (count _loadout != 10) exitWith {}; if (isNil QGVAR(defaultLoadoutsList)) then { GVAR(defaultLoadoutsList) = []; }; -private _loadoutIndex = (+(GVAR(defaultLoadoutsList))) findIf {(_x select 0) == _name}; -if (_loadoutIndex == -1) then { - GVAR(defaultLoadoutsList) pushBack [_name, _loadout]; +// Replace unique items with their bases and replace weapons with their base weapons +_loadout = [_loadout] call FUNC(replaceUniqueItemsLoadout); + +private _index = GVAR(defaultLoadoutsList) findIf {(_x select 0) == _name}; + +// If there is an already existing loadout with similar name, overwrite it +if (_index != -1) then { + GVAR(defaultLoadoutsList) set [_index, [_name, [_loadout, _extendedInfo]]]; } else { - GVAR(defaultLoadoutsList) set [_loadoutIndex, [_name, _loadout]]; + // Otherwise just add + GVAR(defaultLoadoutsList) pushBack [_name, [_loadout, _extendedInfo]]; +}; + +if (is3DEN) then { + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; }; diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index 8a3fb1491f..777b1efe87 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -1,62 +1,64 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* - * Author: Dedmen + * Author: Dedmen, johnb43 * Add a listbox row. * * Arguments: - * 0: Config category (must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice") - * 1: Classname + * 0: Config category, must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice" or "CfgUnitInsignia" + * 1: Classname (must be in config case) * 2: Panel control - * 3: Name of the picture entry in that Cfg class + * 3: Name of the picture entry in that Cfg class (default: "picture") + * 4: Config root (default: 0 -> configFile) * * Return Value: * None * + * Example: + * ["CfgWeapons", "launch_NLAW_F", _ctrl, "icon"] call ace_arsenal_fnc_addListBoxItem + * * Public: Yes -*/ -params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]]; + */ -private _cacheNamespace = _ctrlPanel; //For better readability. +params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]], ["_configRoot", 0, [0]]]; -private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; - -//_cachedItemInfo == [_displayName, _itemPicture, _modPicture, _modID] -if (_cachedItemInfo isEqualTo []) then {//Not in cache. So get info and put into cache. - - private _configPath = configFile >> _configCategory >> _className; - - _cachedItemInfo set [0, getText (_configPath >> "displayName")]; - //if _pictureEntryName is empty then this item has no Icons. (Faces) - _cachedItemInfo set [1, if (_pictureEntryName isEqualTo "") then {""} else {getText (_configPath >> _pictureEntryName)}]; - - //get name of DLC - private _dlcName = ""; - private _addons = configsourceaddonlist _configPath; - if !(_addons isEqualTo []) then { - private _mods = configsourcemodlist (configfile >> "CfgPatches" >> _addons select 0); - if !(_mods isEqualTo []) then { - _dlcName = _mods select 0; +private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLowerANSI _className) in GVAR(favorites))}; +if (_skip) then { + switch (GVAR(currentLeftPanel)) do { + case IDC_buttonPrimaryWeapon: { + _skip = !(_className in (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS)); + }; + case IDC_buttonHandgun: { + _skip = !(_className in (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS)); + }; + case IDC_buttonSecondaryWeapon: { + _skip = !(_className in (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS)); + }; + case IDC_buttonBinoculars: { + _skip = !(_className in (GVAR(currentItems) select IDX_CURR_BINO_ITEMS)); }; }; - - if (_dlcName != "") then { - _cachedItemInfo set [2, (modParams [_dlcName,["logo"]]) param [0,""]];//mod picture - _modID = GVAR(modList) find _dlcName; - if (_modID < 0) then {_modID = GVAR(modList) pushback _dlcName;};//We keep a ordered list of all mods for sorting later. - _cachedItemInfo set [3, _modID];//mod ID - } else { - _cachedItemInfo set [2, ""];//mod picture - _cachedItemInfo set [3, 0];//mod ID - }; - _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; }; -_cachedItemInfo params ["_displayName", "_itemPicture", "_modPicture", "_modID"]; +if (_skip) exitWith {}; -private _lbAdd = _ctrlPanel lbAdd _displayName; +// If not in cache, find info and cache it for later use +((uiNamespace getVariable QGVAR(addListBoxItemCache)) getOrDefaultCall [_configCategory + _className + str _configRoot, { + // Get classname (config case), display name, picture and DLC + private _configPath = ([configFile, campaignConfigFile, missionConfigFile] select _configRoot) >> _configCategory >> _className; + private _dlcName = _configPath call EFUNC(common,getAddon); + // If _pictureEntryName is empty, then this item has no picture (e.g. faces) + [configName _configPath, getText (_configPath >> "displayName"), if (_pictureEntryName == "") then {""} else {getText (_configPath >> _pictureEntryName)}, if (_dlcName != "") then {(modParams [_dlcName, ["logo"]]) param [0, ""]} else {""}] +}, true]) params ["_className", "_displayName", "_itemPicture", "_modPicture"]; + +private _lbAdd = _ctrlPanel lbAdd _displayName; _ctrlPanel lbSetData [_lbAdd, _className]; _ctrlPanel lbSetPicture [_lbAdd, _itemPicture]; -_ctrlPanel lbSetPictureRight [_lbAdd,["",_modPicture] select (GVAR(enableModIcons))]; -_ctrlPanel lbSetValue [_lbAdd,_modID]; +_ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; + +if ((toLowerANSI _className) in GVAR(favorites)) then { + _ctrlPanel lbSetColor [_lbAdd, FAVORITES_COLOR]; + _ctrlPanel lbSetSelectColor [_lbAdd, FAVORITES_COLOR]; +}; diff --git a/addons/arsenal/functions/fnc_addRightPanelButton.sqf b/addons/arsenal/functions/fnc_addRightPanelButton.sqf new file mode 100644 index 0000000000..a1bdb09d1d --- /dev/null +++ b/addons/arsenal/functions/fnc_addRightPanelButton.sqf @@ -0,0 +1,75 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: shukari, Schwaggot, johnb43 + * Adds a right panel button for uniforms, vests and backpacks with defined misc. items. + * + * Arguments: + * 0: Items, must be misc items + * 1: Tooltip (default: "") + * 2: Picture path (default: QPATHTOF(data\iconCustom.paa)) + * 3: Override a specific button (0-9) (default: -1) + * 4: Move button if its position is overridden (default: false) + * + * Return Value: + * Successful: Number of the slot (0-9) + * Error: -1 + * + * Example: + * [["ACE_bloodIV_500", "ACE_Banana"], "MedicalStuff", "\z\ace\addons\arsenal\data\iconCustom.paa", 5, false] call ace_arsenal_fnc_addRightPanelButton + * + * Public: Yes +*/ + +params [["_items", [], [[]]], ["_tooltip", "", [""]], ["_picture", QPATHTOF(data\iconCustom.paa), [""]], ["_override", -1, [0]], ["_moveOnOverwrite", false, [false]]]; + +if (isNil QGVAR(customRightPanelButtons)) then { + GVAR(customRightPanelButtons) = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]; +}; + +private _position = -1; + +// See if override is valid +if (_override >= 0 && {_override <= 9}) then { + _position = _override; +} else { + // Try to find an empty spot + private _emptyPos = GVAR(customRightPanelButtons) findIf {isNil "_x"}; + + if (_emptyPos != -1) then { + _position = _emptyPos; + }; +}; + +// If spot not found, return error +if (_position < 0 || {_position > 9}) exitWith { + -1 +}; + +// Check if we're overwriting a button that's being force-kept +private _currentButtonInPosition = GVAR(customRightPanelButtons) select _position; +if (!isNil "_currentButtonInPosition") then { + _currentButtonInPosition params ["_cbItems", "_cbPicture", "_cbTooltip", "_cbMove"]; + if (_cbMove) then { + [{_this call FUNC(addRightPanelButton)}, [_cbItems, _cbTooltip, _cbPicture, -1, _cbMove]] call CBA_fnc_execNextFrame; + }; +}; + +// If spot found, add items and return position +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _configItemInfo = ""; + +_items = _items select { + _configItemInfo = _cfgWeapons >> _x >> "ItemInfo"; + + _x isKindOf ["CBA_MiscItem", _cfgWeapons] && {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} || + {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} || + {getNumber (_cfgMagazines >> _x >> "ACE_isUnique") == 1} || + {getNumber (_cfgMagazines >> _x >> "ACE_asItem") == 1} +}; + +GVAR(customRightPanelButtons) set [_position, [_items apply {_x call EFUNC(common,getConfigName)}, _picture, _tooltip, _moveOnOverwrite]]; + +_position diff --git a/addons/arsenal/functions/fnc_addSort.sqf b/addons/arsenal/functions/fnc_addSort.sqf new file mode 100644 index 0000000000..767660402f --- /dev/null +++ b/addons/arsenal/functions/fnc_addSort.sqf @@ -0,0 +1,90 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson, johnb43 + * Adds a custom sorting method. + * + * Arguments: + * 0: Tabs to add sort to + * - 0: Left Tab Indexes + * - 1: Right Tab Indexes + * 1: Sort class (a unique string for each algorithm) + * 2: Title + * 3: Algorithm + * 4: Condition (default: {true}) + * + * Return Value: + * 0: Array of IDs + * + * Example: + * [[[0, 1], []], "fireRateSort", "Sort by fire rate", { + * params ["_itemCfg"]; + * private _fireModes = getArray (_itemCfg >> "modes"); + * private _fireRate = []; + * + * { + * _fireRate pushBackUnique (getNumber (_itemCfg >> _x >> "reloadTime")); + * } forEach _fireModes; + * + * _fireRate sort true; + * _fireRate param [0, 0] + * }] call ace_arsenal_fnc_addSort + * + * Public: Yes + */ + +params [ + ["_tabs", [[], []], [[]], 2], + ["_class", "", [""]], + ["_title", "", [""]], + ["_statement", {}, [{}]], + ["_condition", {true}, [{}]] +]; + +_tabs params [ + ["_leftTabs", [], [[]]], + ["_rightTabs", [], [[]]] +]; + +// Compile sorts from config (in case this is called before preInit) +call FUNC(compileSorts); + +private _return = []; + +private _fnc_addToTabs = { + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _sort = []; + private _sortName = ""; + private _currentTab = []; + + { + // Copy title, statement and condition + _sort = +_finalArray; + + // Make sort name + _sortName = [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; + _sort set [0, _sortName]; + + _currentTab = _tabsList select _x; + + // Find if there is an entry with same ID + if ((_currentTab findIf {(_x select 0) == _sortName}) == -1) then { + _currentTab pushBack _sort; + _return pushBack _sortName; + } else { + TRACE_1("A sort with this ID already exists",_sortName); + }; + } forEach _tabsToAddTo; +}; + +private _finalArray = ["", _title, _statement, _condition]; + +if (_leftTabs isNotEqualTo []) then { + [GVAR(sortListLeftPanel), _leftTabs, "L"] call _fnc_addToTabs; +}; + +if (_rightTabs isNotEqualTo []) then { + [GVAR(sortListRightPanel), _rightTabs, "R"] call _fnc_addToTabs; +}; + +_return diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf index 61e361fd0f..d618b96a93 100644 --- a/addons/arsenal/functions/fnc_addStat.sqf +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -1,35 +1,36 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Alganthe - * Add a stat to ACE Arsenal. + * Author: Alganthe, johnb43, LinkIsGrim + * Adds a stat to ACE Arsenal. * * Arguments: - * 0: Tabs to add the stat to (ARRAY of ARRAYS) - * 0.1: Left tab indexes (ARRAY of NUMBERS) - * 0.2 Right tab indexes (ARRAY of NUMBERS) - * 1: Stat class (STRING) (A unique string for each stat) - * 2: Config entries to pass (ARRAY of STRINGS) - * 3: Title (STRING) - * 4: Show bar / show text bools (ARRAY of BOOLS) - * 4.1 Show bar (BOOL) - * 4.2 Show text (BOOL) - * 5: Array of statements (ARRAY of ARRAYS) - * 5.1: Bar code (CODE) - * 5.2 Text code (CODE) - * 5.3 Condition code (CODE) - * 6: Priority (NUMBER) (Optional) + * 0: Tabs to add the stat to + * - 0: Left tab indexes + * - 1: Right tab indexes + * 1: Stat class (unique string for each stat) + * 2: Config entries to pass + * 3: Title + * 4: Show bar / show text bools + * - 0: Show bar (default: false) + * - 1: Show text (default: false) + * 5: Array of statements + * - 0: Bar code (default: {}) + * - 1: Text code (default: {}) + * - 2: Condition code (default: {true}) + * 6: Priority (default: 0) * * Return Value: - * 0: Array of IDs (ARRAY of STRINGS) + * 0: Array of IDs * * Example: - * [[[0,1,2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { - params ["_statsArray", "_itemCfg"]; - getNumber (_itemCfg >> _statsArray select 0) - }, {true}]] call ACE_arsenal_fnc_addStat + * [[[0, 1, 2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { + * params ["_statsArray", "_itemCfg"]; + * getNumber (_itemCfg >> _statsArray select 0) + * }, {true}]] call ace_arsenal_fnc_addStat * * Public: Yes -*/ + */ + params [ ["_tabs", [[], []], [[]], 2], ["_class", "", [""]], @@ -45,7 +46,10 @@ _tabs params [ ["_rightTabs", [], [[]]] ]; -_bools params [["_showBar", false, [false]], ["_showText", false, [false]]]; +_bools params [ + ["_showBar", false, [false]], + ["_showText", false, [false]] +]; _statements params [ ["_barStatement", {}, [{}]], @@ -53,47 +57,67 @@ _statements params [ ["_condition", {true}, [{}]] ]; +// Compile stats from config (in case this is called before preInit) call FUNC(compileStats); -private _returnArray = []; +private _return = []; +private _changes = []; private _fnc_addToTabs = { - params ["_tabsList", "_tabsToAddTo", "_sideString", "_returnIndex"]; + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _statName = ""; + private _currentTab = []; + private _stat = []; + { - private _currentTab = _tabsList select _x; + // Make stat name + _statName = [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; + _currentTab = _tabsList select _x; - private _finalID = [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; - - if ({{_x select 0 == _finalID} count _x > 0} count _currentTab > 0) then { - TRACE_1("A stat with this ID already exists", _finalID); + // Find if there is an entry with same ID + if (_currentTab findIf {_x select 5 == _statName} != -1) then { + TRACE_1("A stat with this ID already exists",_statName); } else { + _stat = +_finalArray; + _stat set [5, _statName]; - private _arrayToSave = +_finalArray; - _arrayToSave set [0, _finalID]; - _returnArray pushBack _finalID; + _currentTab pushBack _stat; - // Add to existing page if there's enough space, otherwise create a new page - if ({count _x < 5} count _currentTab > 0) then { - { - if (count _x < 5) exitWith { - (_currentTab select _forEachIndex) append [_arrayToSave]; - }; - } foreach _currentTab; - } else { - _currentTab pushBack [_arrayToSave]; - }; + _return pushBack _statName; + + // Store information, so that only tabs that were changed can be sorted again + _changes pushBackUnique [_x, _tabSide]; }; - } foreach _tabsToAddTo; + } forEach _tabsToAddTo; }; -private _finalArray = ["", _stats, _title, [_showBar, _showText], [_barStatement, _textStatement, _condition], _priority]; +private _finalArray = [_priority, _stats, _title, [_showBar, _showText], [_barStatement, _textStatement, _condition], ""]; -if (count _leftTabs > 0) then { - [GVAR(statsListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; +if (_leftTabs isNotEqualTo []) then { + [GVAR(statsListLeftPanel), _leftTabs, "L"] call _fnc_addToTabs; }; -if (count _rightTabs > 0) then { - [GVAR(statsListRightPanel), _rightTabs, "R", 1] call _fnc_addToTabs; +if (_rightTabs isNotEqualTo []) then { + [GVAR(statsListRightPanel), _rightTabs, "R"] call _fnc_addToTabs; }; -_returnArray +private _stats = []; +private _tabToChange = []; + +// Ensure priority is kept +{ + _x params ["_tab", "_tabSide"]; + + _tabToChange = [ + GVAR(statsListLeftPanel), + GVAR(statsListRightPanel) + ] select (_tabSide == "R"); + + _stats = _tabToChange select _tab; + + // Sort by priority + _stats sort false; +} forEach _changes; + +_return diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index 1d9a782603..19859f619c 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, Dedmen + * Author: Alganthe, Dedmen, johnb43 * Add virtual items to the provided target. * * Arguments: * 0: Target - * 1: Items - * 2: Add globally + * 1: Items + * 2: Add globally (default: false) * * Return Value: * None @@ -21,206 +21,112 @@ params [["_object", objNull, [objNull]], ["_items", [], [true, []]], ["_global", false, [false]]]; -if (_object == objNull) exitWith {}; -if (_items isEqualType [] && {count _items == 0}) exitWith {}; +if (isNull _object || {_items isEqualTo []}) exitWith {}; -private _cargo = _object getVariable [QGVAR(virtualItems), [ - [[], [], []], // Weapons 0, primary, secondary, handgun - [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod - [ ], // Magazines 2 - [ ], // Headgear 3 - [ ], // Uniform 4 - [ ], // Vest 5 - [ ], // Backpacks 6 - [ ], // Goggles 7 - [ ], // NVGs 8 - [ ], // Binoculars 9 - [ ], // Map 10 - [ ], // Compass 11 - [ ], // Radio slot 12 - [ ], // Watch slot 13 - [ ], // Comms slot 14 - [ ], // WeaponThrow 15 - [ ], // WeaponPut 16 - [ ] // InventoryItems 17 -]]; +private _cargo = _object getVariable QGVAR(virtualItems); -private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in variable for perf improvement +if (isNil "_cargo") then { + _cargo = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; + _cargo = createHashMapFromArray _cargo; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _cargo set [_index, createHashMap]; + }; +}; + +// If passed arguement is "true", add all items if (_items isEqualType true) then { if (_items) then { + private _weapons = _cargo get IDX_VIRT_WEAPONS; + private _weaponAttachments = _cargo get IDX_VIRT_ATTACHMENTS; private _configItems = uiNamespace getVariable QGVAR(configItems); + // Add onto existing items, in case some items that were already added aren't available by default in the arsenal { - (_x select 0) append (_x select 1); - (_x select 2) set [(_x select 3), (_x select 0) arrayIntersect (_x select 0)]; + (_x select 0) merge [_x select 1, true]; + (_x select 2) set [_x select 3, _x select 0]; } forEach [ - [(_cargo select 0 select 0),(_configItems select 0 select 0), _cargo select 0, 0], - [(_cargo select 0 select 1),(_configItems select 0 select 1), _cargo select 0, 1], - [(_cargo select 0 select 2),(_configItems select 0 select 2), _cargo select 0, 2], - [(_cargo select 1 select 0),(_configItems select 1 select 0), _cargo select 1, 0], - [(_cargo select 1 select 1),(_configItems select 1 select 1), _cargo select 1, 1], - [(_cargo select 1 select 2),(_configItems select 1 select 2), _cargo select 1, 2], - [(_cargo select 1 select 3),(_configItems select 1 select 3), _cargo select 1, 3] + [_weapons get IDX_VIRT_PRIMARY_WEAPONS, _configItems get IDX_VIRT_WEAPONS get IDX_VIRT_PRIMARY_WEAPONS, _weapons, IDX_VIRT_PRIMARY_WEAPONS], + [_weapons get IDX_VIRT_SECONDARY_WEAPONS, _configItems get IDX_VIRT_WEAPONS get IDX_VIRT_SECONDARY_WEAPONS, _weapons, IDX_VIRT_SECONDARY_WEAPONS], + [_weapons get IDX_VIRT_HANDGUN_WEAPONS, _configItems get IDX_VIRT_WEAPONS get IDX_VIRT_HANDGUN_WEAPONS, _weapons, IDX_VIRT_HANDGUN_WEAPONS], + [_weaponAttachments get IDX_VIRT_OPTICS_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_OPTICS_ATTACHMENTS, _weaponAttachments, IDX_VIRT_OPTICS_ATTACHMENTS], + [_weaponAttachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _weaponAttachments, IDX_VIRT_FLASHLIGHT_ATTACHMENTS], + [_weaponAttachments get IDX_VIRT_MUZZLE_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_MUZZLE_ATTACHMENTS, _weaponAttachments, IDX_VIRT_MUZZLE_ATTACHMENTS], + [_weaponAttachments get IDX_VIRT_BIPOD_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_BIPOD_ATTACHMENTS, _weaponAttachments, IDX_VIRT_BIPOD_ATTACHMENTS] ]; - for "_index" from 2 to 17 do { - (_cargo select _index) append (_configItems select _index); - _cargo set [_index, (_cargo select _index) arrayIntersect (_cargo select _index)]; + // Add onto existing items, in case some items that were already added aren't available by default in the arsenal + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + (_cargo get _index) merge [_configItems get _index, true]; + _cargo set [_index, _cargo get _index]; }; }; - } else { + // Make sure all items are in string form, then convert to config case (non-existent items return "") + _items = (_items select {_x isEqualType ""}) apply {_x call EFUNC(common,getConfigName)}; + + // Remove any invalid/non-existing items + _items = _items - [""]; + + private _configItems = uiNamespace getVariable QGVAR(configItems); + private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); + + // Convert all items to their baseWeapon + _items = _items apply {if (_x in _configItemsFlat) then {_x} else {_x call FUNC(baseWeapon)}}; + + // Remove any items not found by the arsenal + _items = _items select {_x in _configItemsFlat}; + + // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration + // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 { - if (_x isEqualType "") then { - private _configItemInfo = _configCfgWeapons >> _x >> "ItemInfo"; - private _simulationType = getText (_configCfgWeapons >> _x >> "simulation"); - switch true do { - case (isClass (_configCfgWeapons >> _x)): { - switch true do { - /* Weapon acc */ - case ( - isClass (_configItemInfo) && - {(getNumber (_configItemInfo >> "type")) in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} && - {!(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} - ): { - switch (getNumber (_configItemInfo >> "type")) do { - case TYPE_OPTICS: { - (_cargo select 1) select 0 pushBackUnique _x; - }; - case TYPE_FLASHLIGHT: { - (_cargo select 1) select 1 pushBackUnique _x; - }; - case TYPE_MUZZLE: { - (_cargo select 1) select 2 pushBackUnique _x; - }; - case TYPE_BIPOD: { - (_cargo select 1) select 3 pushBackUnique _x; - }; - }; - }; - /* Headgear */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_HEADGEAR}): { - (_cargo select 3) pushBackUnique _x; - }; - /* Uniform */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_UNIFORM}): { - (_cargo select 4) pushBackUnique _x; - }; - /* Vest */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_VEST}): { - (_cargo select 5) pushBackUnique _x; - }; - /* NVgs */ - case (_simulationType == "NVGoggles"): { - (_cargo select 8) pushBackUnique _x; - }; - /* Binos */ - case (_simulationType == "Binocular" || - {(_simulationType == 'Weapon') && {(getNumber (_configCfgWeapons >> _x >> 'type') == TYPE_BINOCULAR_AND_NVG)}}): { - (_cargo select 9) pushBackUnique _x; - }; - /* Map */ - case (_simulationType == "ItemMap"): { - (_cargo select 10) pushBackUnique _x; - }; - /* Compass */ - case (_simulationType == "ItemCompass"): { - (_cargo select 11) pushBackUnique _x; - }; - /* Radio */ - case (_simulationType == "ItemRadio"): { - (_cargo select 12) pushBackUnique _x; - }; - /* Watch */ - case (_simulationType == "ItemWatch"): { - (_cargo select 13) pushBackUnique _x; - }; - /* GPS */ - case (_simulationType == "ItemGPS"): { - (_cargo select 14) pushBackUnique _x; - }; - /* UAV terminals */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_UAV_TERMINAL}): { - (_cargo select 14) pushBackUnique _x; - }; - /* Weapon, at the bottom to avoid adding binos */ - case (isClass (_configCfgWeapons >> _x >> "WeaponSlotsInfo") && - {getNumber (_configCfgWeapons >> _x >> 'type') != TYPE_BINOCULAR_AND_NVG}): { - switch (getNumber (_configCfgWeapons >> _x >> "type")) do { - case TYPE_WEAPON_PRIMARY: { - (_cargo select 0) select 0 pushBackUnique ([_x] call bis_fnc_baseWeapon); - }; - case TYPE_WEAPON_HANDGUN: { - (_cargo select 0) select 2 pushBackUnique ([_x] call bis_fnc_baseWeapon); - }; - case TYPE_WEAPON_SECONDARY: { - (_cargo select 0) select 1 pushBackUnique ([_x] call bis_fnc_baseWeapon); - }; - }; - }; - /* Misc items */ - case ( - isClass (_configItemInfo) && - ((getNumber (_configItemInfo >> "type")) in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && - {(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || - {(getNumber (_configItemInfo >> "type")) in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {(getText (_configCfgWeapons >> _x >> "simulation")) == "ItemMineDetector"} - ): { - (_cargo select 17) pushBackUnique _x; - }; - }; - }; - case (isClass (configFile >> "CfgMagazines" >> _x)): { - // Lists to check against - private _grenadeList = []; - { - _grenadeList append getArray (_configCfgWeapons >> "Throw" >> _x >> "magazines"); - false - } count getArray (_configCfgWeapons >> "Throw" >> "muzzles"); + switch (true) do { + // Weapons + case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) set [_x, nil]; + }; + case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) set [_x, nil]; + }; + case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) set [_x, nil]; + }; - private _putList = []; - { - _putList append getArray (_configCfgWeapons >> "Put" >> _x >> "magazines"); - false - } count getArray (_configCfgWeapons >> "Put" >> "muzzles"); + // Weapon attachments + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x, nil]; + }; + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x, nil]; + }; + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x, nil]; + }; + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x, nil]; + }; - // Check what the magazine actually is - switch true do { - // Rifle, handgun, secondary weapons mags - case ( - ((getNumber (configFile >> "CfgMagazines" >> _x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW,TYPE_MAGAZINE_SECONDARY_AND_PUT,1536,TYPE_MAGAZINE_HANDGUN_AND_GL]) || - {(getNumber (configFile >> "CfgMagazines" >> _x >> QGVAR(hide))) == -1}) && - {!(_x in _grenadeList)} && - {!(_x in _putList)} - ): { - (_cargo select 2) pushBackUnique _x; - }; - // Grenades - case (_x in _grenadeList): { - (_cargo select 15) pushBackUnique _x; - }; - // Put - case (_x in _putList): { - (_cargo select 16) pushBackUnique _x; - }; + // Other + default { + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + if (_x in (_configItems get _index)) exitWith { + (_cargo get _index) set [_x, nil]; }; }; - case (isClass (configFile >> "CfgVehicles" >> _x)): { - if (getNumber (configFile >> "CfgVehicles" >> _x >> "isBackpack") == 1) then { - (_cargo select 6) pushBackUnique _x; - }; - }; - case (isClass (configFile >> "CfgGlasses" >> _x)): { - (_cargo select 7) pushBackUnique _x; - }; }; }; - } foreach _items; + } forEach _items; }; _object setVariable [QGVAR(virtualItems), _cargo, _global]; + +// If the arsenal is already open, refresh arsenal display +if (_global) then { + [QGVAR(refresh), _object] call CBA_fnc_globalEvent; +} else { + [QGVAR(refresh), _object] call CBA_fnc_localEvent; +}; diff --git a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf index 4f84f9624c..023ebf16cf 100644 --- a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf +++ b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: mharis001 + * Author: mharis001, johnb43 * Adds compatible attachments or magazines for all weapons in 3DEN attribute. * * Arguments: @@ -21,55 +21,63 @@ params ["_controlsGroup"]; private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); // Exit if selected category is not attachments or magazines -if !(_category in [4, 5, 6, 7, 8]) exitWith {}; +if !(_category in [IDX_CAT_OPTICS_ATTACHMENTS, IDX_CAT_FLASHLIGHT_ATTACHMENTS, IDX_CAT_MUZZLE_ATTACHMENTS, IDX_CAT_BIPOD_ATTACHMENTS, IDX_CAT_ITEMS_ALL]) exitWith {}; -private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); +private _configItems = uiNamespace getVariable QGVAR(configItems); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems"]; // Get list of all weapons in attribute items -(_configItems select 0) params ["_primaryWeapons", "_secondaryWeapons", "_handgunWeapons"]; -private _attributeWeapons = _attributeItems select {_x in _primaryWeapons || {_x in _secondaryWeapons} || {_x in _handgunWeapons}}; +private _attributeWeapons = []; + +{ + _attributeWeapons append (_attributeItems arrayIntersect (keys _y)); +} forEach (_configItems get IDX_VIRT_WEAPONS); + +private _itemsToAdd = createHashMap; // Add compatible attachments or magazines to attribute -private _cfgWeapons = configFile >> "CfgWeapons"; -private _itemsToAdd = []; - -if (_category == 8) then { - private _magazineGroups = uiNamespace getVariable QGVAR(magazineGroups); - private _cfgMagazines = configFile >> "CfgMagazines"; +if (_category == IDX_CAT_ITEMS_ALL) then { + // Add compatible attachments or magazines to attribute + private _compatibleMagazines = createHashMap; + // Get all compatible magazines for weapons { - private _weaponConfig = _cfgWeapons >> _x; - - { - private _muzzleConfig = if (_x == "this") then {_weaponConfig} else {_weaponConfig >> _x}; - - // Only add existent magazines and ensure correct classname case - private _magazines = getArray (_muzzleConfig >> "magazines") select {isClass (_cfgMagazines >> _x)}; - _magazines = _magazines apply {configName (_cfgMagazines >> _x)}; - _itemsToAdd append _magazines; - - { - _itemsToAdd append ([_magazineGroups, toLower _x] call CBA_fnc_hashGet); - } forEach getArray (_muzzleConfig >> "magazineWell"); - } forEach getArray (_weaponConfig >> "muzzles"); + _compatibleMagazines insert [true, compatibleMagazines _x, []]; } forEach _attributeWeapons; + + // Check if magazines are in configItems + { + if (_x in (_configItems get IDX_VIRT_ITEMS_ALL)) then { + _itemsToAdd set [_x, nil]; + }; + } forEach (keys _compatibleMagazines); } else { private _attachmentCategory = _category - 4; private _filter = ["optic", "pointer", "muzzle", "bipod"] select _attachmentCategory; + private _compatibleItems = createHashMap; + // CBA_fnc_compatibleItems returns config case sensitive names { - _itemsToAdd append ([_x, _filter] call CBA_fnc_compatibleItems); + _compatibleItems insert [true, [_x, _filter] call CBA_fnc_compatibleItems, []]; } forEach _attributeWeapons; - // Only add items with scope of 2 and ensure correct classname case - _itemsToAdd = _itemsToAdd select {getNumber (_cfgWeapons >> _x >> "scope") == 2}; - _itemsToAdd = _itemsToAdd apply {configName (_cfgWeapons >> _x)}; + // Check if attachments are in configItems + { + if ( + _x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_OPTICS_ATTACHMENTS) || + {_x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || + {_x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_MUZZLE_ATTACHMENTS)} || + {_x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_BIPOD_ATTACHMENTS)} + ) then { + _itemsToAdd set [_x, nil]; + }; + } forEach (keys _compatibleItems); }; -_attributeItems append _itemsToAdd; -_attributeValue set [0, _attributeItems arrayIntersect _attributeItems]; +// Only take items that can be found by default in the arsenal +_attributeItems insert [-1, keys _itemsToAdd, true]; +_attributeValue set [0, _attributeItems]; // Refresh the list for new items [_controlsGroup] call FUNC(attributeAddItems); diff --git a/addons/arsenal/functions/fnc_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf index 12611bbdeb..612e894a15 100644 --- a/addons/arsenal/functions/fnc_attributeAddItems.sqf +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: mharis001 - * Populates 3DEN attribute listbox with items of given category. + * Author: mharis001, johnb43 + * Populates 3DEN's ace arsenal attribute listbox with items of given category. * * Arguments: * 0: Attribute controls group @@ -18,105 +18,144 @@ params ["_controlsGroup"]; -private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; -private _filter = toLower ctrlText (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR); -private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); -private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; -TRACE_3("Populating list",_category,_filter,_attributeValue); +forceUnicode 0; // handle non-ANSI characters +private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); +private _filter = ctrlText (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR); +private _configItems = uiNamespace getVariable QGVAR(configItems); +private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); +private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems", "_attributeMode"]; + +TRACE_3("Populating list",_category,_filter,_attributeValue); +if (_filter != "") then { + _filter = _filter call EFUNC(common,escapeRegex); + _filter = ".*?" + (_filter splitString " " joinString ".*?") + ".*?/io"; +} else { + _filter = ".*?/io"; +}; + + private _modeSymbol = [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode; // Clear listbox private _listbox = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST; lnbClear _listbox; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgGlasses = configFile >> "CfgGlasses"; +private _dlcName = ""; + // Exit with current items (no specific category) -if (_category == -1) exitWith { +if (_category == IDX_CAT_ALL) exitWith { + private _config = configNull; + private _displayName = ""; + private _index = -1; + { // Get appropriate config for each item (different since items can be from any category) - private _config = switch (true) do { - case (_x in (_configItems select 2)); - case (_x in (_configItems select 15)); - case (_x in (_configItems select 16)): { - configFile >> "CfgMagazines" >> _x; - }; - case (_x in (_configItems select 6)): { - configFile >> "CfgVehicles" >> _x; - }; - case (_x in (_configItems select 7)): { - configFile >> "CfgGlasses" >> _x; - }; - default { - configFile >> "CfgWeapons" >> _x; - }; + _config = switch (true) do { + case (_x in _magazineMiscItems); + case (_x in (_configItems get IDX_VIRT_ITEMS_ALL)); + case (_x in (_configItems get IDX_VIRT_GRENADES)); + case (_x in (_configItems get IDX_VIRT_EXPLOSIVES)): {_cfgMagazines >> _x}; + case (_x in (_configItems get IDX_VIRT_BACKPACK)): {_cfgVehicles >> _x}; + case (_x in (_configItems get IDX_VIRT_GOGGLES)): {_cfgGlasses >> _x}; + default {_cfgWeapons >> _x}; }; + _displayName = getText (_config >> "displayName"); + // Add item if not filtered - private _displayName = getText (_config >> "displayName"); - if (toLower _displayName find _filter > -1) then { - private _picture = getText (_config >> "picture"); - private _index = _listbox lnbAddRow ["", _displayName, _modeSymbol]; + if (_displayName regexMatch _filter || {_x regexMatch _filter}) then { + _index = _listbox lnbAddRow ["", _displayName, _modeSymbol]; _listbox lnbSetData [[_index, 1], _x]; - _listbox lnbSetPicture [[_index, 0], _picture]; - _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; + _listbox lnbSetPicture [[_index, 0], getText (_config >> "picture")]; + _listbox lnbSetTooltip [[_index, 0], _x]; + + _dlcName = _config call EFUNC(common,getAddon); + + if (_dlcName != "") then { + _listbox lnbSetPicture [[_index, 2], (modParams [_dlcName, ["logo"]]) param [0, ""]]; + }; }; } forEach _attributeItems; - _listbox lnbSort [1]; + // Sort alphabetically + _listbox lnbSort [1, false]; }; // Get list of category items private _categoryItems = switch (true) do { - case (_category < 3): { - _configItems select 0 select _category; + // Weapons + case (_category < IDX_CAT_OPTICS_ATTACHMENTS): { + (_configItems get IDX_VIRT_WEAPONS) get (_category - 1) }; - case (_category < 7): { - _configItems select 1 select (_category - 3); + // Weapon attachments + case (_category < IDX_CAT_ITEMS_ALL): { + (_configItems get IDX_VIRT_ATTACHMENTS) get (_category - 4) }; + // Other default { - _configItems select (_category - 5); + _configItems get (_category - 6) }; }; // Get config for current category -private _config = switch (true) do { - case (_category in [7, 20, 21]): { - configFile >> "CfgMagazines"; - }; - case (_category == 11): { - configFile >> "CfgVehicles"; - }; - case (_category == 12): { - configFile >> "CfgGlasses"; - }; - default { - configFile >> "CfgWeapons"; - }; +private _cfgClass = switch (true) do { + case (_category in [IDX_CAT_ITEMS_ALL, IDX_CAT_GRENADES, IDX_CAT_EXPLOSIVES]): {_cfgMagazines}; + case (_category == IDX_CAT_BACKPACK): {_cfgVehicles}; + case (_category == IDX_CAT_GOGGLES): {_cfgGlasses}; + default {_cfgWeapons}; }; +private _displayName = ""; +private _symbol = SYMBOL_ITEM_NONE; +private _alpha = 0; +private _index = -1; +private _config = _cfgClass; + // Populate listbox with category items { - // Add item if not filtered - private _displayName = getText (_config >> _x >> "displayName"); - if (toLower _displayName find _filter > -1) then { - private _picture = getText (_config >> _x >> "picture"); - private _symbol = SYMBOL_ITEM_NONE; - private _alpha = 0.5; + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + if (_category == IDX_CAT_MISC_ITEMS) then { + _config = [_cfgClass, _cfgMagazines] select (_x in _magazineMiscItems); + }; + _displayName = getText (_config >> _x >> "displayName"); + + // Add item if not filtered + if (_displayName regexMatch _filter || {_x regexMatch _filter}) then { // Change symbol and alpha if item already selected if (_x in _attributeItems) then { _symbol = _modeSymbol; _alpha = 1; + } else { + _symbol = SYMBOL_ITEM_NONE; + _alpha = 0.5; }; - private _index = _listbox lnbAddRow ["", _displayName, _symbol]; + _index = _listbox lnbAddRow ["", _displayName, "", _symbol]; _listbox lnbSetData [[_index, 1], _x]; - _listbox lnbSetPicture [[_index, 0], _picture]; - _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; + _listbox lnbSetPicture [[_index, 0], getText (_config >> _x >> "picture")]; + _listbox lnbSetTooltip [[_index, 0], _x]; _listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]]; - _listbox lnbSetColor [[_index, 2], [1, 1, 1, _alpha]]; - }; -} forEach _categoryItems; + _listbox lnbSetColor [[_index, 3], [1, 1, 1, _alpha]]; -_listbox lnbSort [1]; + // Mod icon is in column 2 + _dlcName = (_config >> _x) call EFUNC(common,getAddon); + + if (_dlcName != "") then { + _listbox lnbSetPicture [[_index, 2], (modParams [_dlcName, ["logo"]]) param [0, ""]]; + _listbox lnbSetPictureColor [[_index, 2], [1, 1, 1, _alpha]]; + }; + }; +} forEach (keys _categoryItems); + +// Sort alphabetically +_listbox lnbSort [1, false]; + +// Reset unicode flag +forceUnicode -1; diff --git a/addons/arsenal/functions/fnc_attributeCategory.sqf b/addons/arsenal/functions/fnc_attributeCategory.sqf index e0c0468f8a..09b25724a9 100644 --- a/addons/arsenal/functions/fnc_attributeCategory.sqf +++ b/addons/arsenal/functions/fnc_attributeCategory.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: mharis001 - * Handles changing the category in 3DEN attribute. + * Handles changing the category in 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -24,7 +24,7 @@ uiNamespace setVariable [QGVAR(attributeCategory), _category]; // Show add compatible items button when category is attachments or magazines private _compatibleButton = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_ADD_COMPATIBLE; -private _enable = _category in [4, 5, 6, 7, 8]; +private _enable = _category in [IDX_CAT_OPTICS_ATTACHMENTS, IDX_CAT_FLASHLIGHT_ATTACHMENTS, IDX_CAT_MUZZLE_ATTACHMENTS, IDX_CAT_BIPOD_ATTACHMENTS, IDX_CAT_ITEMS_ALL]; _compatibleButton ctrlEnable _enable; _compatibleButton ctrlShow _enable; diff --git a/addons/arsenal/functions/fnc_attributeClear.sqf b/addons/arsenal/functions/fnc_attributeClear.sqf index a0a8cb070d..8e40e07703 100644 --- a/addons/arsenal/functions/fnc_attributeClear.sqf +++ b/addons/arsenal/functions/fnc_attributeClear.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: mharis001 - * Clears all items from current category in 3DEN attribute. + * Clears all items from current category in 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -18,28 +18,32 @@ params ["_controlsGroup"]; -private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; +private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; TRACE_1("Handling clear button",_category); // Remove all if no specific category -if (_category == -1) then { +if (_category == IDX_CAT_ALL) then { _attributeValue set [0, []]; } else { // Find category items and remove from list - private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); + private _configItems = uiNamespace getVariable QGVAR(configItems); private _categoryItems = switch (true) do { - case (_category < 3): { - _configItems select 0 select _category; + // Weapons + case (_category < IDX_CAT_OPTICS_ATTACHMENTS): { + (_configItems get IDX_VIRT_WEAPONS) get (_category - 1) }; - case (_category < 7): { - _configItems select 1 select (_category - 3); + // Weapon attachments + case (_category < IDX_CAT_ITEMS_ALL): { + (_configItems get IDX_VIRT_ATTACHMENTS) get (_category - 4) }; + // Other default { - _configItems select (_category - 5); + _configItems get (_category - 6) }; }; - _attributeValue set [0, (_attributeValue select 0) - _categoryItems]; + + _attributeValue set [0, (_attributeValue select 0) select {!(_x in _categoryItems)}]; }; // Refresh the list after clear diff --git a/addons/arsenal/functions/fnc_attributeDblClick.sqf b/addons/arsenal/functions/fnc_attributeDblClick.sqf index 6cb9314bcf..7c0d4f5a25 100644 --- a/addons/arsenal/functions/fnc_attributeDblClick.sqf +++ b/addons/arsenal/functions/fnc_attributeDblClick.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 - * Handles double clicking a row in 3DEN attribute listbox. + * Handles double clicking a row in 3DEN's ace arsenal attribute listbox. * * Arguments: * 0: Listbox diff --git a/addons/arsenal/functions/fnc_attributeImport.sqf b/addons/arsenal/functions/fnc_attributeImport.sqf index ec56df4b56..28604583a0 100644 --- a/addons/arsenal/functions/fnc_attributeImport.sqf +++ b/addons/arsenal/functions/fnc_attributeImport.sqf @@ -1,7 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* * Author: mharis001 - * Handles importing items list from clipboard into 3DEN attribute. + * Handles importing items list from clipboard into 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -15,8 +16,6 @@ * Public: No */ -params ["_controlsGroup"]; - private _importList = call compile copyFromClipboard; // Verify import list is in correct format @@ -24,23 +23,17 @@ if (isNil "_importList" || {!(_importList isEqualType [])} || {!(_importList isE playSound ["3DEN_notificationWarning", true]; }; -// Ensure imported items are in scanned config array and classname case is correct -private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); -private _configItemsFlat = _configItems select [2, 16]; -_configItemsFlat append (_configItems select 0); -_configItemsFlat append (_configItems select 1); +params ["_controlsGroup"]; -private _filteredList = []; +// Convert all items to config case +_importList = _importList apply {_x call EFUNC(common,getConfigName)}; -{ - private _item = _x; - { - private _index = _x findIf {_x == _item}; - if (_index > -1) then { - _filteredList pushBackUnique (_x select _index); - }; - } forEach _configItemsFlat; -} forEach _importList; +// Remove any invalid/non-existing items +_importList = _importList - [""]; + +// Ensure imported items are in scanned config array +private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); +private _filteredList = _importList select {_x in _configItemsFlat}; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue set [0, _filteredList]; diff --git a/addons/arsenal/functions/fnc_attributeInit.sqf b/addons/arsenal/functions/fnc_attributeInit.sqf index 8c1556fcd6..42e72056fc 100644 --- a/addons/arsenal/functions/fnc_attributeInit.sqf +++ b/addons/arsenal/functions/fnc_attributeInit.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 - * Initializes the objects 3DEN attribute at scenario start. + * Initializes the objects 3DEN's ace arsenal attribute at scenario start. * * Arguments: * 0: Attribute target @@ -24,13 +24,12 @@ if (_mode > 0) then { // Blacklist: add full arsenal and take items away [_object, true, true] call FUNC(initBox); - // Need to delay removal by 2 frames + // Wait until all items have been added, so that the blacklisted items can be removed [{ - [{ - params ["_object", "_items"]; - [_object, _items, true] call FUNC(removeVirtualItems); - }, _this] call CBA_fnc_execNextFrame; - }, [_object, _items]] call CBA_fnc_execNextFrame; + !isNil {(_this select 0) getVariable QGVAR(virtualItems)} + }, { + [_this select 0, _this select 1, true] call FUNC(removeVirtualItems); + }, [_object, _items], 20] call CBA_fnc_waitUntilAndExecute; // 20s timeout in case of failure } else { // Exit on whitelist mode with no items if (_items isEqualTo []) exitWith {}; diff --git a/addons/arsenal/functions/fnc_attributeKeyDown.sqf b/addons/arsenal/functions/fnc_attributeKeyDown.sqf index 300ab9f6c5..85fe522239 100644 --- a/addons/arsenal/functions/fnc_attributeKeyDown.sqf +++ b/addons/arsenal/functions/fnc_attributeKeyDown.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* * Author: mharis001 - * Handles keyboard input for the 3DEN attribute. + * Handles keyboard input for the 3DEN's ace arsenal attribute. * * Arguments: * 0: Display @@ -21,18 +21,23 @@ params ["_display", "_keyCode"]; TRACE_2("Attribute key down",_display,_keyCode); // Exit if attribute is not in focus -private _controlsGroup = uiNamespace getVariable QGVAR(attributeFocus); -if (isNil "_controlsGroup") exitWith {false}; +private _controlsGroup = uiNamespace getVariable [QGVAR(attributeFocus), controlNull]; + +if (isNull _controlsGroup) exitWith {false}; switch (_keyCode) do { + // Unselect item case DIK_LEFT; case DIK_NUMPADMINUS: { [_controlsGroup, false] call FUNC(attributeSelect); + true }; + // Select item case DIK_RIGHT; case DIK_NUMPADPLUS: { [_controlsGroup, true] call FUNC(attributeSelect); + true }; default {false}; diff --git a/addons/arsenal/functions/fnc_attributeLoad.sqf b/addons/arsenal/functions/fnc_attributeLoad.sqf index 355d5e113a..bd1ec98ab2 100644 --- a/addons/arsenal/functions/fnc_attributeLoad.sqf +++ b/addons/arsenal/functions/fnc_attributeLoad.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: mharis001 - * Initializes the 3DEN attribute. + * Initializes the 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -23,10 +23,8 @@ TRACE_1("Initializing 3DEN attribute",_value); // Store working attribute value uiNamespace setVariable [QGVAR(attributeValue), _value]; -// Add keyDown EH to display -// Does not work properly when added to controls group -private _display = ctrlParent _controlsGroup; -_display displayAddEventHandler ["KeyDown", {call FUNC(attributeKeyDown)}]; +// Add keyDown EH to display; Does not work properly when added to controls group +(ctrlParent _controlsGroup) displayAddEventHandler ["KeyDown", {call FUNC(attributeKeyDown)}]; // Handle selected mode if (_value select 1 > 0) then { diff --git a/addons/arsenal/functions/fnc_attributeMode.sqf b/addons/arsenal/functions/fnc_attributeMode.sqf index 807fea2ec4..9aab5c8869 100644 --- a/addons/arsenal/functions/fnc_attributeMode.sqf +++ b/addons/arsenal/functions/fnc_attributeMode.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: mharis001 - * Handles changing the mode in 3DEN attribute. + * Handles changing the mode in 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group diff --git a/addons/arsenal/functions/fnc_attributeSelect.sqf b/addons/arsenal/functions/fnc_attributeSelect.sqf index 7af0ecc764..2f9df7775e 100644 --- a/addons/arsenal/functions/fnc_attributeSelect.sqf +++ b/addons/arsenal/functions/fnc_attributeSelect.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: mharis001 - * Handles adding/removing an item from 3DEN attribute list. + * Handles adding/removing an item from 3DEN's ace arsenal attribute list. * * Arguments: * 0: Attribute controls group @@ -28,22 +28,26 @@ TRACE_2("Handling item selection",_itemClassname,_addItem); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems", "_attributeMode"]; -private _findItem = _attributeItems find _itemClassname; +private _itemIndex = _attributeItems find _itemClassname; // Add item if not already in list -if (_addItem && {_findItem < 0}) exitWith { +if (_addItem && {_itemIndex == -1}) exitWith { _attributeItems pushBack _itemClassname; + // Change symbol and increase alpha - _listbox lnbSetText [[_currentRow, 2], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode]; + _listbox lnbSetText [[_currentRow, 3], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode]; _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 1]]; - _listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 1]]; + _listbox lnbSetPictureColor [[_currentRow, 2], [1, 1, 1, 1]]; // mod icon is in column 2 + _listbox lnbSetColor [[_currentRow, 3], [1, 1, 1, 1]]; }; // Remove item if in list -if (!_addItem && {_findItem > -1}) exitWith { - _attributeItems deleteAt _findItem; +if (!_addItem && {_itemIndex != -1}) exitWith { + _attributeItems deleteAt _itemIndex; + // Change symbol and reduce alpha - _listbox lnbSetText [[_currentRow, 2], SYMBOL_ITEM_NONE]; + _listbox lnbSetText [[_currentRow, 3], SYMBOL_ITEM_NONE]; _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 0.5]]; - _listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 0.5]]; + _listbox lnbSetPictureColor [[_currentRow, 2], [1, 1, 1, 0.5]]; // mod icon is in column 2 + _listbox lnbSetColor [[_currentRow, 3], [1, 1, 1, 0.5]]; }; diff --git a/addons/arsenal/functions/fnc_baseAttachment.sqf b/addons/arsenal/functions/fnc_baseAttachment.sqf new file mode 100644 index 0000000000..968fd05d9b --- /dev/null +++ b/addons/arsenal/functions/fnc_baseAttachment.sqf @@ -0,0 +1,59 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, LinkIsGrim + * Returns base attachment for CBA scripted attachment + * Adapted from CBA_fnc_switchableAttachments + * + * Arguments: + * 0: Attachment + * + * Return Value: + * Base attachment + * + * Example: + * "ACE_acc_pointer_green_IR" call ace_arsenal_fnc_baseAttachment + * + * Public: Yes + */ + +params [["_item", "", [""]]]; + +TRACE_1("looking up base attachment",_item); + +private _switchableClasses = []; + +private _cfgWeapons = configfile >> "CfgWeapons"; +private _config = _cfgWeapons >> _item; +_item = configName _config; + +// If the switch config entries are inherited, ignore +if ( + (inheritsFrom (_config >> "MRT_SwitchItemNextClass") isNotEqualTo _config) || + {inheritsFrom (_config >> "MRT_SwitchItemPrevClass") isNotEqualTo _config} +) exitWith { + _item // return +}; + +while { + _config = _cfgWeapons >> getText (_config >> "MRT_SwitchItemNextClass"); + isClass _config && {_switchableClasses pushBackUnique configName _config != -1} +} do {}; + +_config = _cfgWeapons >> _item; +private _backward = []; +while { + _config = _cfgWeapons >> getText (_config >> "MRT_SwitchItemPrevClass"); + isClass _config && {_backward pushBackUnique configName _config != -1} +} do {}; + +_switchableClasses append _backward; +_switchableClasses = _switchableClasses arrayIntersect _switchableClasses; + +{ + if (getNumber (_cfgWeapons >> _x >> "scope") == 2) exitWith { + TRACE_2("found class",_item,_x); + _item = _x; + }; +} forEach _switchableClasses; + +_item diff --git a/addons/arsenal/functions/fnc_baseOptic.sqf b/addons/arsenal/functions/fnc_baseOptic.sqf new file mode 100644 index 0000000000..c3eb5e811a --- /dev/null +++ b/addons/arsenal/functions/fnc_baseOptic.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, LinkIsGrim + * Returns base optic for CBA scripted optics (PIP and 2D) + * + * Arguments: + * 0: Optic + * + * Return Value: + * Base optic + * + * Example: + * "CUP_optic_Elcan_SpecterDR_black_PIP" call ace_arsenal_fnc_baseOptic + * + * Public: Yes + */ + +params [["_optic", "", [""]]]; + +// PIP +private _baseClasses = configProperties [configFile >> "CBA_PIPItems", "getText _x == _optic"]; + +// Carry Handle +{ + _baseClasses append (configProperties [_x, "getText _x == _optic"]); +} forEach configProperties [configFile >> "CBA_CarryHandleTypes"]; + +if (_baseClasses isNotEqualTo []) then { + _optic = configName (_baseClasses select 0); +}; + +_optic diff --git a/addons/arsenal/functions/fnc_baseWeapon.sqf b/addons/arsenal/functions/fnc_baseWeapon.sqf new file mode 100644 index 0000000000..abeb0e0ab9 --- /dev/null +++ b/addons/arsenal/functions/fnc_baseWeapon.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: Karel Moricky, johnb43 + * Returns base weapon (weapon without any attachments), but it returns it in config sensitive case. + * Same as BIS_fnc_baseWeapon, except config case and uses cache. + * + * Arguments: + * 0: Weapon + * + * Return Value: + * Base weapon + * + * Example: + * ["arifle_AK12_GL_lush_arco_pointer_F"] call ace_arsenal_fnc_baseWeapon + * + * Public: Yes + */ + +params [["_weapon", "", [""]]]; + +// Check if item is cached +(uiNamespace getVariable QGVAR(baseWeaponNameCache)) getOrDefaultCall [toLowerANSI _weapon, { + private _cfgWeapons = configfile >> "CfgWeapons"; + private _config = _cfgWeapons >> _weapon; + + // If class doesn't exist, exit + if (!isClass _config) then { + _weapon + } else { + // Get manual base weapon + private _configBase = _cfgWeapons >> getText (_config >> "baseWeapon"); + + if (isClass _configBase) then { + configName _configBase + } else { + private _className = _weapon; + + // Get first parent without any attachments; Only take weapons available to the arsenal + // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration + // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 + while {isClass _config && {getNumber (_config >> "scope") > 0 && {if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2} else {true}}} && {getNumber (_config >> QGVAR(hide)) != 1}} do { + if (count (_config >> "LinkedItems") == 0) exitWith { + _className = configName _config; + }; + + _config = inheritsFrom _config; + }; + + _className + }; + }; +}, true] diff --git a/addons/arsenal/functions/fnc_buttonActionsPage.sqf b/addons/arsenal/functions/fnc_buttonActionsPage.sqf new file mode 100644 index 0000000000..b3a46a68e3 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonActionsPage.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Brett Mayson + * Handles the previous / next page buttons for actions. + * + * Arguments: + * 0: Arsenal display + * 1: Actions page + * 2: Previous (false) or next (true) page + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display", "_control", "_nextPage"]; + +TRACE_1("control enabled",ctrlEnabled _control); +if !(ctrlEnabled _control) exitWith {}; + +GVAR(currentActionPage) = GVAR(currentActionPage) + ([-1, 1] select _nextPage); + +GVAR(actionsInfo) params ["_panelControl", "_curSel", "_itemCfg"]; + +[QGVAR(displayActions), [_display, _panelControl, _curSel, _itemCfg]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index cc8cdf45bf..d7713a2518 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Add or remove item(s) when the + or - button is pressed in the right panel. * * Arguments: * 0: Arsenal display - * 1: Add or remove (-1: remove, 1: Add) + * 1: Add (1) or remove (-1) item * * Return Value: * None @@ -16,77 +16,110 @@ params ["_display", "_addOrRemove"]; -private _load = 0; -private _maxLoad = ""; -private _items = []; -private _ctrlList = (_display displayCtrl IDC_rightTabContentListnBox); +private _add = _addOrRemove > 0; + +private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; private _lnbCurSel = lnbCurSelRow _ctrlList; +private _isUnique = (_ctrlList lnbValue [_lnbCurSel, 2]) == 1; + +// If item is unique, don't allow adding more +if (_add && {_isUnique}) exitWith {}; + +private _containerItems = []; private _item = _ctrlList lnbData [_lnbCurSel, 0]; -if ((_ctrlList lnbValue [_lnbCurSel, 2]) == 1 && {_addOrRemove == 1}) exitWith {}; - -// Update item count and currentItems array -switch GVAR(currentLeftPanel) do { - - case IDC_buttonUniform : { - if (_addOrRemove > 0) then { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) addItemToUniform _item; - }; +// Update item count and currentItems array & get relevant container +private _container = switch (GVAR(currentLeftPanel)) do { + // Uniform + case IDC_buttonUniform: { + if (_add) then { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) addItemToUniform _item; + }; + } else { + // Backpacks need special command to be removed + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) get IDX_VIRT_BACKPACK)}) then { + [uniformContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; } else { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { GVAR(center) removeItemFromUniform _item; }; }; + }; - _load = loadUniform GVAR(center); - _maxLoad = gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass"); - _items = uniformItems GVAR(center); - GVAR(currentItems) set [15 ,_items]; + // Get all items from container + _containerItems = uniformItems GVAR(center); + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_UNIFORM) param [1, []]]; + + // Update load bar + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); + + uniformContainer GVAR(center) }; - - case IDC_buttonVest : { - if (_addOrRemove > 0) then { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) addItemToVest _item; - }; + // Vest + case IDC_buttonVest: { + if (_add) then { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) addItemToVest _item; + }; + } else { + // Backpacks need special command to be removed + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) get IDX_VIRT_BACKPACK)}) then { + [vestContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; } else { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { GVAR(center) removeItemFromVest _item; }; }; + }; - _load = loadVest GVAR(center); - _maxLoad = gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass"); - _items = vestItems GVAR(center); - GVAR(currentItems) set [16,_items]; + // Get all items from container + _containerItems = vestItems GVAR(center); + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_VEST) param [1, []]]; + + // Update load bar + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); + + vestContainer GVAR(center) }; - - case IDC_buttonBackpack : { - if (_addOrRemove > 0) then { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) addItemToBackpack _item; - }; + // Backpack + case IDC_buttonBackpack: { + if (_add) then { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) addItemToBackpack _item; + }; + } else { + // Backpacks need special command to be removed + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) get IDX_VIRT_BACKPACK)}) then { + [backpackContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; } else { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { GVAR(center) removeItemFromBackpack _item; }; }; + }; - _load = loadBackpack GVAR(center); - _maxLoad = backpack GVAR(center); - _items = backpackItems GVAR(center); - GVAR(currentItems) set [17,_items]; + // Get all items from container + _containerItems = backpackItems GVAR(center); + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_BACKPACK) param [1, []]]; + + // Update load bar + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); + + backpackContainer GVAR(center) }; }; -// Update progress bar status, weight info -private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; -_loadIndicatorBarCtrl progressSetPosition _load; - -private _value = {_x == _item} count _items; -_ctrlList lnbSetText [[_lnbCurSel, 2],str _value]; +// Find out how many items of that type there are and update the number displayed +_ctrlList lnbSetText [[_lnbCurSel, 2], str ({_item == _x} count _containerItems)]; [QGVAR(cargoChanged), [_display, _item, _addOrRemove, GVAR(shiftState)]] call CBA_fnc_localEvent; -[_ctrlList, _maxLoad] call FUNC(updateRightPanel); +// Refresh availibility of items based on space remaining in container +[_ctrlList, _container, _containerItems isNotEqualTo []] call FUNC(updateRightPanel); diff --git a/addons/arsenal/functions/fnc_buttonClearAll.sqf b/addons/arsenal/functions/fnc_buttonClearAll.sqf index 8e1d70d6eb..dbcc00e33c 100644 --- a/addons/arsenal/functions/fnc_buttonClearAll.sqf +++ b/addons/arsenal/functions/fnc_buttonClearAll.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Clear the current container. * * Arguments: @@ -15,48 +15,56 @@ params ["_display"]; -// Clear container -switch (GVAR(currentLeftPanel)) do { +// Clear chosen container, reset currentItems for that container and get relevant container +private _container = switch (GVAR(currentLeftPanel)) do { + // Uniform case IDC_buttonUniform: { - {GVAR(center) removeItemFromUniform _x} foreach (uniformItems GVAR(center)); - GVAR(currentItems) set [15, []]; + private _container = uniformContainer GVAR(center); + + // Remove everything (backpacks need special command for this) + clearWeaponCargoGlobal _container; + clearMagazineCargoGlobal _container; + clearItemCargoGlobal _container; + clearBackpackCargoGlobal _container; + + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, []]; + + _container }; + // Vest case IDC_buttonVest: { - {GVAR(center) removeItemFromVest _x} foreach (vestItems GVAR(center)); - GVAR(currentItems) set [16, []]; + private _container = vestContainer GVAR(center); + + // Remove everything (backpacks need special command for this) + clearWeaponCargoGlobal _container; + clearMagazineCargoGlobal _container; + clearItemCargoGlobal _container; + clearBackpackCargoGlobal _container; + + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, []]; + + _container }; + // Backpack case IDC_buttonBackpack: { - {GVAR(center) removeItemFromBackpack _x} foreach (backpackItems GVAR(center)); - GVAR(currentItems) set [17, []]; + // Remove everything + clearAllItemsFromBackpack GVAR(center); + + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, []]; + + backpackContainer GVAR(center) }; }; // Clear number of owned items private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; -for "_l" from 0 to (lbSize _ctrlList - 1) do { - _ctrlList lnbSetText [[_l, 2], str 0]; +for "_lbIndex" from 0 to (lbSize _ctrlList) - 1 do { + _ctrlList lnbSetText [[_lbIndex, 2], "0"]; }; -private _removeAllCtrl = _display displayCtrl IDC_buttonRemoveAll; -_removeAllCtrl ctrlSetFade 1; -_removeAllCtrl ctrlCommit FADE_DELAY; - // Update load bar -private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; -_loadIndicatorBarCtrl progressSetPosition 0; +(_display displayCtrl IDC_loadIndicatorBar) progressSetPosition 0; -private _maxLoad = switch (GVAR(currentLeftPanel)) do { - case IDC_buttonUniform: { - gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonVest: { - gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonBackpack: { - backpack GVAR(center) - }; -}; - -private _control = _display displayCtrl IDC_rightTabContentListnBox; -[_control, _maxLoad] call FUNC(updateRightPanel); +// Refresh availibility of items based on space remaining in container +[_ctrlList, _container, false] call FUNC(updateRightPanel); diff --git a/addons/arsenal/functions/fnc_buttonExport.sqf b/addons/arsenal/functions/fnc_buttonExport.sqf index 86caf418e3..3e5039a504 100644 --- a/addons/arsenal/functions/fnc_buttonExport.sqf +++ b/addons/arsenal/functions/fnc_buttonExport.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Export current loadout / default loadouts list to clipboard. @@ -15,39 +15,41 @@ params ["_display"]; if (GVAR(shiftState)) then { - if (isNil QGVAR(defaultLoadoutsList) || {GVAR(defaultLoadoutsList) isEqualTo []}) exitWith { - [_display, localize LSTRING(exportDefaultError)] call FUNC(message); + [_display, LLSTRING(exportDefaultError)] call FUNC(message); }; + // Export default loadout list private _listLength = count GVAR(defaultLoadoutsList); - for "_index" from -1 to _listLength do { - switch true do { + for "_index" from -1 to _listLength do { + switch (true) do { + // Beginning case (_index == -1): { "ace_clipboard" callExtension (format ["[%1", endl]); }; - + // End case (_index == _listLength): { "ace_clipboard" callExtension "];"; }; - + // Rest default { - "ace_clipboard" callExtension ([" ",str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""); + "ace_clipboard" callExtension ([" ", str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""); }; }; }; "ace_clipboard" callExtension "--COMPLETE--"; - [_display, localize LSTRING(exportDefault)] call FUNC(message); + [_display, LLSTRING(exportDefault)] call FUNC(message); } else { + // Export singular loadout + private _export = str (GVAR(center) call CBA_fnc_getLoadout); - private _export = str getUnitLoadout GVAR(center); "ace_clipboard" callExtension (_export + ";"); "ace_clipboard" callExtension "--COMPLETE--"; - [_display, localize LSTRING(exportCurrent)] call FUNC(message); + [_display, LLSTRING(exportCurrent)] call FUNC(message); }; [QGVAR(loadoutExported), [_display, GVAR(shiftState)]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonFavorites.sqf b/addons/arsenal/functions/fnc_buttonFavorites.sqf new file mode 100644 index 0000000000..1c7c7cd53f --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonFavorites.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: LinkIsGrim + * Switches the arsenal between displaying all items and favorites + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display", "_control"]; + +private _firstRun = false; + +if (isNil QGVAR(favoritesOnly)) then { + GVAR(favoritesOnly) = GVAR(defaultToFavorites); + _firstRun = true; +} else { + GVAR(favoritesOnly) = !GVAR(favoritesOnly); +}; + +_control ctrlSetText format ["%1: %2", localize "STR_GEAR_ITEMS", localize (["str_word_all", "STR_3DEN_Favorite_textPlural"] select GVAR(favoritesOnly))]; + +if (_firstRun) exitWith {}; + +[false] call FUNC(refresh); diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf index 23e4f7d081..d1bb5657b0 100644 --- a/addons/arsenal/functions/fnc_buttonHide.sqf +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -16,12 +16,13 @@ params ["_display"]; private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar); +private _ctrl = controlNull; { - private _ctrl = _display displayctrl _x; - _ctrl ctrlshow _showToggle; - _ctrl ctrlcommit 0.15; -} foreach [ + _ctrl = _display displayCtrl _x; + _ctrl ctrlShow _showToggle; + _ctrl ctrlCommit FADE_DELAY; +} forEach [ IDC_blockLeftFrame, IDC_blockLeftBackground, IDC_blockRightFrame, @@ -35,6 +36,8 @@ private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar); IDC_rightTabContentListnBox, IDC_sortLeftTab, IDC_sortRightTab, + IDC_sortLeftTabDirection, + IDC_sortRightTabDirection, IDC_leftSearchbarButton, IDC_rightSearchbarButton, IDC_leftSearchbar, @@ -49,11 +52,20 @@ private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar); IDC_buttonCurrentMag2, IDC_iconBackgroundCurrentMag, IDC_iconBackgroundCurrentMag2, - IDC_statsButton, + IDC_statsBox, IDC_statsPreviousPage, IDC_statsNextPage, IDC_statsCurrentPage, - IDC_statsButtonClose + IDC_actionsBox, + IDC_actionsPreviousPage, + IDC_actionsNextPage, + IDC_actionsCurrentPage ]; -[QGVAR(statsToggle), [_display, _showToggle]] call CBA_fnc_localEvent; +if (!_showToggle) exitWith {}; + +// When showing the stats/actions again, update them to fit with currently selected item +GVAR(actionsInfo) params ["_control", "_curSel", "_itemCfg"]; + +[QGVAR(displayStats), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; +[QGVAR(displayActions), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonImport.sqf b/addons/arsenal/functions/fnc_buttonImport.sqf index 3eefba41a4..8a83fe3ff0 100644 --- a/addons/arsenal/functions/fnc_buttonImport.sqf +++ b/addons/arsenal/functions/fnc_buttonImport.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Import loadout / default loadouts list from clipboard. * * Arguments: @@ -15,90 +15,69 @@ params ["_display"]; -private _data = call (compile copyFromClipboard); +// Can be either a singular loadout or an array of loadouts +private _extendedLoadout = call compile copyFromClipboard; -if (isNil "_data" || {!(_data isEqualType [])}) exitWith { - [_display, localize LSTRING(importFormatError)] call FUNC(message); +// If error, exit +if (isNil "_extendedLoadout" || {!(_extendedLoadout isEqualType [])}) exitWith { + [_display, LLSTRING(importFormatError)] call FUNC(message); }; if (GVAR(shiftState) && {is3DEN}) then { - + // Supports CBA extended loadout or getUnitLoadout arrays { if ( - count _x == 2 && - {_x select 0 isEqualType ""} && - {_x select 0 != ""} && - {_x select 1 isEqualType []} && - {count (_x select 1) == 10} + count _x == 2 && + {(_x select 0) isEqualType ""} && + {(_x select 0) != ""} && + {(_x select 1) isEqualType []} && + {count (_x select 1) in [2, 10]} ) then { _x call FUNC(addDefaultLoadout); }; - } foreach _data; + } forEach _extendedLoadout; + + [_display, LLSTRING(importedDefault)] call FUNC(message); - [_display, localize LSTRING(importedDefault)] call FUNC(message); set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; - } else { - if (count _data == 10) then { - GVAR(center) setUnitLoadout _data; + // If _extendedLoadout is in getUnitLoadout array, change into CBA extended loadout array + if (count _extendedLoadout == 10) then { + _extendedLoadout = [_extendedLoadout, createHashMap]; + }; - GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; - for "_index" from 0 to 15 do { - switch (_index) do { - case 0; - case 1; - case 2:{ - GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; - }; - case 3; - case 4; - case 5; - case 6; - case 7; - case 8; - case 9: { - GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; + // Check if CBA extended loadout array + if ((count _extendedLoadout) == 2) then { + [GVAR(center), _extendedLoadout] call CBA_fnc_setLoadout; - }; - case 10: { - {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); - }; - case 11: { - {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); - }; - case 12: { - {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); - }; - case 13: { - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; - }; - case 14: { - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; - }; - case 15: { - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; - }; - }; - }; + // Update current item list and unique items + [true] call FUNC(refresh); - - { - private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); - private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch", "itemgps"] find (tolower _simulationType)); - - GVAR(currentItems) set [_index, _x]; - } foreach (assignedItems GVAR(center)); - - call FUNC(updateUniqueItemsList); + _extendedLoadout params ["_loadout", "_extendedInfo"]; // Reapply insignia - [GVAR(center), ""] call bis_fnc_setUnitInsignia; - [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + if (QGVAR(insignia) in _extendedInfo) then { + GVAR(currentInsignia) = _extendedInfo getOrDefault [QGVAR(insignia), ""]; + } else { + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; + }; + // Save face + if (QGVAR(face) in _extendedInfo) then { + GVAR(currentFace) = _extendedInfo getOrDefault [QGVAR(face), GVAR(currentFace)]; + }; + + // Save voice + if (QGVAR(voice) in _extendedInfo) then { + GVAR(currentVoice) = _extendedInfo getOrDefault [QGVAR(voice), GVAR(currentVoice)]; + }; + + // Fill left panel [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); - [_display, localize LSTRING(importedCurrent)] call FUNC(message); + [_display, LLSTRING(importedCurrent)] call FUNC(message); }; }; -[QGVAR(loadoutImported), [_display, (GVAR(shiftState) && {is3DEN})]] call CBA_fnc_localEvent; +[QGVAR(loadoutImported), [_display, GVAR(shiftState) && {is3DEN}]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf index a1d39b1423..20f0f8b3da 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Delete / unshare loadout currently selected. * * Arguments: @@ -22,34 +22,37 @@ private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; private _contentPanelCursSel = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_contentPanelCursSel, 1]; +// If loadout is local or default if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { - - if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { - GVAR(defaultLoadoutsList) deleteAt (GVAR(defaultLoadoutsList) find ((GVAR(defaultLoadoutsList) select {_x select 0 == _loadoutName}) select 0)); - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + // Find loadout and delete from list + if (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts) then { + [_loadoutName, !is3DEN] call FUNC(removeDefaultLoadout); } else { - private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; - _data deleteAt (_data find ((_data select {_x select 0 == _loadoutName}) select 0)); + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + + _data deleteAt (_data findIf {(_x select 0) == _loadoutName}); }; _contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), nil]; _contentPanelCtrl lnbDeleteRow _contentPanelCursSel; - _contentPanelCtrl lnbSetCurSelRow (_contentPanelCursSel); + _contentPanelCtrl lnbSetCurSelRow _contentPanelCursSel; - [(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutDeleted), _loadoutName] joinString " "] call FUNC(message); + [findDisplay IDD_ace_arsenal, [LLSTRING(loadoutDeleted), _loadoutName] joinString " "] call FUNC(message); + + [QGVAR(onLoadoutDelete), [_loadoutName]] call CBA_fnc_localEvent; } else { - + // If loadout is shared private _profileName = profileName; // GVAR(center) could be a remote unit private _loadoutVar = _profileName + _loadoutName; - private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); + private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable [QGVAR(sharedLoadoutsVars), []]; GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars - [_loadoutVar], true]; _contentPanelCtrl lnbDeleteRow _contentPanelCursSel; - _contentPanelCtrl lnbSetCurSelRow (_contentPanelCursSel); + _contentPanelCtrl lnbSetCurSelRow _contentPanelCursSel; - [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; + [findDisplay IDD_ace_arsenal, [LLSTRING(loadoutUnshared), _loadoutName] joinString " "] call FUNC(message); - [(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutUnshared), _loadoutName] joinString " "] call FUNC(message); + [QGVAR(loadoutUnshared), [_contentPanelCtrl, _profileName, _loadoutName]] call CBA_fnc_remoteEvent; }; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf index 0a2faccc54..120a50ae9c 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Load selected loadout. * * Arguments: @@ -22,78 +22,45 @@ private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; private _curSel = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_curSel, 1]; -private _loadout = switch GVAR(currentLoadoutsTab) do { - +private _extendedLoadout = switch (GVAR(currentLoadoutsTab)) do { + // Local and default loadouts case IDC_buttonMyLoadouts; - case IDC_buttonDefaultLoadouts:{ + case IDC_buttonDefaultLoadouts: { (_contentPanelCtrl getVariable _loadoutName + str GVAR(currentLoadoutsTab)) select 0 }; - - case IDC_buttonSharedLoadouts:{ + // Shared loadouts + case IDC_buttonSharedLoadouts: { (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_curSel, 0]) + (_contentPanelCtrl lnbText [_curSel, 1]))) select 2 }; }; -GVAR(center) setUnitLoadout [_loadout, true]; +// Apply loadout to unit +[GVAR(center), _extendedLoadout, true] call CBA_fnc_setLoadout; -GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; -for "_index" from 0 to 15 do { - switch (_index) do { - case 0; - case 1; - case 2:{ - GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; - }; - case 3; - case 4; - case 5; - case 6; - case 7; - case 8; - case 9: { - GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; +// Update current item list and unique items +[true] call FUNC(refresh); - }; - case 10: { - {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); - }; - case 11: { - {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); - }; - case 12: { - {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); - }; - case 13: { - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; - }; - case 14: { - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; - }; - case 15: { - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; - }; - }; -}; -{ - private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); - - if (_simulationType != "NVGoggles") then { - if (_simulationType == "ItemGps" || _simulationType == "Weapon") then { - GVAR(currentItems) set [14, _x]; - } else { - - private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch"] find (tolower _simulationType)); - GVAR(currentItems) set [_index, _x]; - }; - }; -} forEach (assignedItems GVAR(center)); - -call FUNC(updateUniqueItemsList); +_extendedLoadout params ["_loadout", "_extendedInfo"]; // Reapply insignia -[GVAR(center), ""] call bis_fnc_setUnitInsignia; -[GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; +if (QGVAR(insignia) in _extendedInfo) then { + GVAR(currentInsignia) = _extendedInfo getOrDefault [QGVAR(insignia), ""]; +} else { + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; +}; -[(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutLoaded), _loadoutName] joinString " "] call FUNC(message); +// Update current face if necessary +if (QGVAR(face) in _extendedInfo) then { + GVAR(currentFace) = _extendedInfo getOrDefault [QGVAR(face), GVAR(currentFace)]; +}; + +// Update voice face if necessary +if (QGVAR(voice) in _extendedInfo) then { + GVAR(currentVoice) = _extendedInfo getOrDefault [QGVAR(voice), GVAR(currentVoice)]; +}; + +[findDisplay IDD_ace_arsenal, [LLSTRING(loadoutLoaded), _loadoutName] joinString " "] call FUNC(message); [QGVAR(onLoadoutLoad), [_loadout, _loadoutName]] call CBA_fnc_localEvent; +[QGVAR(onLoadoutLoadExtended), [_extendedLoadout, _loadoutName]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf index a1f9294669..d25fa485cf 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Rename selected loadout. * * Arguments: @@ -23,48 +23,45 @@ private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; private _curSelRow = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_curSelRow, 1]; -private _editBoxCtrl = _display displayCtrl IDC_textEditBox; -private _editBoxContent = ctrlText _editBoxCtrl; +// Get text from text edit box +private _editBoxContent = ctrlText (_display displayCtrl IDC_textEditBox); -private _data = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts && {is3DEN}); -private _similarLoadouts = _data select {_x select 0 == _editBoxContent}; +// If it's the exact same name, don't do anything +if (_editBoxContent isEqualTo _loadoutName) exitWith {}; -if (count _similarLoadouts > 0) exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(renameExistError)] call FUNC(message); +private _data = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (call FUNC(canEditDefaultLoadout) && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}); + +// If there is a loadout with a similar name and it's not chosen to be renamed, don't rename and exit +if (_editBoxContent != _loadoutName && {_data findIf {(_x select 0) == _editBoxContent} != -1}) exitWith { + [findDisplay IDD_ace_arsenal, LLSTRING(renameExistError)] call FUNC(message); }; // Update loadout info in profile / 3DEN and list namespaces -private _loadoutToRename = (_data select {_x select 0 == _loadoutName}) select 0; -(_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; +private _loadoutIndex = _data findIf {(_x select 0) == _loadoutName}; -_data set [_data find _loadoutToRename, [_editBoxContent, (_loadoutToRename select 1)]]; -_contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), nil]; -_contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_loadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]]; +// Set new name +(_data select _loadoutIndex) set [0, _editBoxContent]; -// Add new row -_contentPanelCtrl lnbDeleteRow _curSelRow; -private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; - -ADD_LOADOUTS_LIST_PICTURES - -if (_nullItemsAmount > 0) then { - - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; -} else { - - if (_unavailableItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; - }; -}; - -// Sort and select the current row -_contentPanelCtrl lnbSort [1, false]; -for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; -}; - -if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { +if (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts) then { set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; }; -[(findDisplay IDD_ace_arsenal), [_loadoutName, localize LSTRING(loadoutRenamed) ,_editBoxContent] joinString " "] call FUNC(message); +private _currentLoadoutsTab = str GVAR(currentLoadoutsTab); + +_contentPanelCtrl setVariable [_editBoxContent + _currentLoadoutsTab, _contentPanelCtrl getVariable [_loadoutName + _currentLoadoutsTab, []]]; +_contentPanelCtrl setVariable [_loadoutName + _currentLoadoutsTab, nil]; + +// Update the current row's loadout name +_contentPanelCtrl lnbSetText [[_curSelRow, 1], _editBoxContent]; + +// Sort loadouts alphabetically +_contentPanelCtrl lnbSort [1, false]; + +// Select the newly renamed loadout +for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex; + }; +}; + +[findDisplay IDD_ace_arsenal, [_loadoutName, LLSTRING(loadoutRenamed), _editBoxContent] joinString " "] call FUNC(message); diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf index 17c89b5f36..142a19c635 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Save selected loadout. * * Arguments: @@ -21,278 +21,161 @@ if !(ctrlEnabled _control) exitWith {}; private _editBoxCtrl = _display displayCtrl IDC_textEditBox; private _editBoxContent = ctrlText _editBoxCtrl; +// If no name given, throw error if (_editBoxContent == "") exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(saveEmptyNameBox)] call FUNC(message); + [findDisplay IDD_ace_arsenal, LLSTRING(saveEmptyNameBox)] call FUNC(message); }; -private _data = [+(profileNamespace getVariable [QGVAR(saved_loadouts),[]]), +(GVAR(defaultLoadoutsList))] select (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts && {is3DEN}); -private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; -private _cursSelRow = lnbCurSelRow _contentPanelCtrl; - -private _loadoutName = _contentPanelCtrl lnbText [_cursSelRow, 1]; -private _curSelLoadout = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; -private _loadout = getUnitLoadout GVAR(center); - -private _loadoutIndex = _data findIf {(_x select 0) == _editBoxContent}; -private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); +// Get shared loadouts +private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable [QGVAR(sharedLoadoutsVars), []]; // Make sure the loadout isn't yours (public tab) or being shared (my loadouts tab) -private _similarSharedLoadout = (profileName + _editBoxContent) in _sharedLoadoutsVars; -if ((_contentPanelCtrl lnbText [_cursSelRow, 0]) == profileName) exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(saveAuthorError)] call FUNC(message); +if ((profileName + _editBoxContent) in _sharedLoadoutsVars) exitWith { + [findDisplay IDD_ace_arsenal, LLSTRING(saveSharedError)] call FUNC(message); }; -if (_similarSharedLoadout) exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(saveSharedError)] call FUNC(message); +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _curSelRow = lnbCurSelRow _contentPanelCtrl; + +if ((_contentPanelCtrl lnbText [_curSelRow, 0]) == profileName) exitWith { + [findDisplay IDD_ace_arsenal, LLSTRING(saveAuthorError)] call FUNC(message); }; -switch (GVAR(currentLoadoutsTab)) do { - case IDC_buttonMyLoadouts:{ +// Get currently selected loadout name & loadout +private _loadoutName = _contentPanelCtrl lnbText [_curSelRow, 1]; +private _curSelLoadout = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; - for "_dataIndex" from 0 to 10 do { - switch (_dataIndex) do { +// Get unit's current loadout +private _extendedLoadout = GVAR(center) call CBA_fnc_getLoadout; +_extendedLoadout params ["_loadout"]; - case 0; - case 1; - case 2; - case 8: { - if (count (_loadout select _dataIndex) > 0) then { +private _loadouts = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select ((call FUNC(canEditDefaultLoadout)) && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}); +private _loadoutIndex = _loadouts findIf {(_x select 0) == _editBoxContent}; - private _weapon = (_loadout select _dataIndex) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_loadout select _dataIndex) set [0, _baseWeapon]; - }; - }; - }; - }; - - case 3; - case 4; - case 5: { - if (count (_loadout select _dataIndex) > 0) then { - private _containerContents = (_loadout select _dataIndex) select 1; - - if (count _containerContents > 0) then { - - { - if (count _x == 2) then { - - if ((_x select 0) isEqualType "") then { - - private _item = (_x select 0); - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - _x set [0, _uniqueBaseCfgText]; - }; - }; - } else { - private _weapon = (_x select 0) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_x select 0)set [0, _baseWeapon]; - }; - }; - }; - }; - } foreach _containerContents; - }; - }; - }; - - case 9: { - for "_subIndex" from 0 to 4 do { - private _item = (_loadout select _dataIndex) select _subIndex; - - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; - }; - }; - }; - }; - }; - }; - - if (GVAR(shiftState) && {is3DEN} && {!(_loadoutName isEqualTo "")} && {_cursSelRow != -1} && {!(_loadoutIndex isEqualto -1)}) exitwith { +// Return what loadout was saved +private _savedLoadout = switch (GVAR(currentLoadoutsTab)) do { + // Local loadouts tab + case IDC_buttonMyLoadouts: { + // If saved to default loadout + if (GVAR(shiftState) && FUNC(canEditDefaultLoadout) && {_loadoutName != ""} && {_curSelRow != -1} && {_loadoutIndex != -1}) then { private _defaultLoadoutsSearch = GVAR(defaultLoadoutsList) findIf {(_x select 0) == _loadoutName}; - if (_defaultLoadoutsSearch isEqualto -1) then { - GVAR(defaultLoadoutsList) pushBack [_loadoutName, _curSelLoadout]; - } else { - GVAR(defaultLoadoutsList) set [_defaultLoadoutsSearch , [ _loadoutName, _curSelLoadout]]; + + [_loadoutName, _curSelLoadout, !is3DEN] call FUNC(addDefaultLoadout); + + if (_defaultLoadoutsSearch == -1) then { + _loadoutIndex = (count GVAR(defaultLoadoutsList)) - 1; }; - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; - }; - if (_loadoutIndex isEqualto -1) then { - _data pushBack [_editBoxContent, _loadout]; + _curSelLoadout } else { - _data set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; - }; + // Replace unique items with their bases and replace weapons with their base weapons + _loadout = [_loadout] call FUNC(replaceUniqueItemsLoadout); - // Delete "old" loadout row - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbDeleteRow _i}; - }; + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; - private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + // Add or overwrite loadout in loadout storage + if (_loadoutIndex == -1) then { + _loadoutIndex = _data pushBack [_editBoxContent, _extendedLoadout]; + } else { + _data set [_loadoutIndex, [_editBoxContent, _extendedLoadout]]; + }; - ADD_LOADOUTS_LIST_PICTURES - - _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_loadout] call FUNC(verifyLoadout)]; - - _contentPanelCtrl lnbSort [1, false]; - - // Select newly saved loadout - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; - }; - - profileNamespace setVariable [QGVAR(saved_loadouts), _data]; - }; - - case IDC_buttonDefaultLoadouts:{ - - if (is3DEN) then { - - private _loadoutIndex = _data findIf {(_x select 0) == _editBoxContent}; - - for "_dataIndex" from 0 to 10 do { - switch (_dataIndex) do { - - case 0; - case 1; - case 2; - case 8: { - if (count (_loadout select _dataIndex) > 0) then { - - private _weapon = (_loadout select _dataIndex) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_loadout select _dataIndex) set [0, _baseWeapon]; - }; - }; - }; - }; - - case 3; - case 4; - case 5: { - if (count (_loadout select _dataIndex) > 0) then { - private _containerContents = (_loadout select _dataIndex) select 1; - - if (count _containerContents > 0) then { - - { - if (count _x == 2) then { - - if ((_x select 0) isEqualType "") then { - - private _item = (_x select 0); - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - _x set [0, _uniqueBaseCfgText]; - }; - }; - } else { - private _weapon = (_x select 0) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_x select 0)set [0, _baseWeapon]; - }; - }; - }; - }; - } foreach _containerContents; - }; - }; - }; - - case 9: { - for "_subIndex" from 0 to 4 do { - private _item = (_loadout select _dataIndex) select _subIndex; - - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; - }; - }; - }; - }; + // Refresh loadout list; Delete previous loadout row + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbDeleteRow _lbIndex; }; }; - if (_loadoutIndex == -1) then { - GVAR(defaultLoadoutsList) pushBack [_editBoxContent, _loadout]; - } else { - GVAR(defaultLoadoutsList) set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; - }; - - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbDeleteRow _i}; - }; - - private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + private _newRow = _contentPanelCtrl lnbAddRow ["", _editBoxContent]; + private _cfgWeapons = configFile >> "CfgWeapons"; ADD_LOADOUTS_LIST_PICTURES - _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_loadout] call FUNC(verifyLoadout)]; + _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout] call FUNC(verifyLoadout)]; + // Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; // Select newly saved loadout - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex; + }; }; - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; - } else { + _extendedLoadout + }; + }; + // Default loadouts tab + case IDC_buttonDefaultLoadouts: { + if (call FUNC(canEditDefaultLoadout)) then { + [_editBoxContent, _extendedLoadout, !is3DEN] call FUNC(addDefaultLoadout); + + // Get loadout index if (_loadoutIndex == -1) then { - _data pushBack [_editBoxContent, _curSelLoadout]; + _loadoutIndex = (count GVAR(defaultLoadoutsList)) - 1; + }; + + // Refresh loadout list; Delete previous loadout row + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; + }; + + private _newRow = _contentPanelCtrl lnbAddRow ["", _editBoxContent]; + private _cfgWeapons = configFile >> "CfgWeapons"; + + ADD_LOADOUTS_LIST_PICTURES + + _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout] call FUNC(verifyLoadout)]; + + // Sort loadouts alphabetically + _contentPanelCtrl lnbSort [1, false]; + + // Select newly saved loadout + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex; + }; + }; + + _extendedLoadout + } else { + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + + // Add or overwrite loadout in loadout storage + if (_loadoutIndex == -1) then { + _loadoutIndex = _data pushBack [_editBoxContent, _curSelLoadout]; } else { - _data set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _curSelLoadout]]; + _data set [_loadoutIndex, [_editBoxContent, _curSelLoadout]]; _contentPanelCtrl setVariable [_editBoxContent + str IDC_buttonMyLoadouts, [_curSelLoadout] call FUNC(verifyLoadout)]; }; - profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + _curSelLoadout }; }; + // Shared loadouts tab + case IDC_buttonSharedLoadouts: { + _loadout = (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_curSelRow, 0]) + (_contentPanelCtrl lnbText [_curSelRow, 1]))) select 2; - case IDC_buttonSharedLoadouts :{ - - _loadout = (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_cursSelRow, 0]) + (_contentPanelCtrl lnbText [_cursSelRow, 1]))) select 2; + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + // Add or overwrite loadout in loadout storage if (_loadoutIndex == -1) then { - _data pushBack [_editBoxContent, _loadout]; + _loadoutIndex = _data pushBack [_editBoxContent, _loadout]; } else { - _data set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; + _data set [_loadoutIndex, [_editBoxContent, _loadout]]; _contentPanelCtrl setVariable [_editBoxContent + str IDC_buttonMyLoadouts, [_loadout] call FUNC(verifyLoadout)]; }; - profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + _loadout }; }; -[(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutSaved), _editBoxContent] joinString " "] call FUNC(message); -private _savedLoadout = (_data select {_x select 0 == _editBoxContent}) select 0; -[QGVAR(onLoadoutSave), [_data find _savedLoadout, _savedLoadout]] call CBA_fnc_localEvent; + +[findDisplay IDD_ace_arsenal, [LLSTRING(loadoutSaved), _editBoxContent] joinString " "] call FUNC(message); + +[QGVAR(onLoadoutSave), [_loadoutIndex, _savedLoadout select 0]] call CBA_fnc_localEvent; +[QGVAR(onLoadoutSaveExtended), [_loadoutIndex, _savedLoadout]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf index a9a1dd9d08..b31e2edad2 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Share selected loadout. * * Arguments: @@ -23,33 +23,33 @@ private _contentPanelCursSel = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_contentPanelCursSel, 1]; private _profileName = profileName; // GVAR(center) could be a remote unit private _loadoutVar = _profileName + _loadoutName; -private _sharedLoadoutsVars = +(GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars)); +private _sharedLoadoutsVars = +(GVAR(sharedLoadoutsNamespace) getVariable [QGVAR(sharedLoadoutsVars), []]); -private _loadoutIndex = _sharedLoadoutsVars find _loadoutVar; private _loadoutData = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; -// Loadout set to private -if (_loadoutIndex > -1) then { +if (_loadoutVar in _sharedLoadoutsVars) then { + // Loadout is shared, set to private GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars - [_loadoutVar], true]; _contentPanelCtrl lnbSetPicture [[_contentPanelCursSel, 0], QPATHTOF(data\iconPublicBlank.paa)]; _contentPanelCtrl lnbSetValue [[_contentPanelCursSel, 0], 0]; - [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; -// Loadout set to public + [QGVAR(loadoutUnshared), [_contentPanelCtrl, _profileName, _loadoutName]] call CBA_fnc_remoteEvent; } else { - GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, [_profileName ,_loadoutName , _loadoutData], true]; + // Loadout is private, set to shared + GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, [_profileName, _loadoutName, _loadoutData], true]; _sharedLoadoutsVars pushBackUnique _loadoutVar; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars, true]; _contentPanelCtrl lnbSetPicture [[_contentPanelCursSel, 0], QPATHTOF(data\iconPublic.paa)]; _contentPanelCtrl lnbSetValue [[_contentPanelCursSel, 0], 1]; - [QGVAR(loadoutShared), [_contentPanelCtrl, [_profileName ,_loadoutName , _loadoutData]]] call CBA_fnc_remoteEvent; + + [QGVAR(loadoutShared), [_contentPanelCtrl, [_profileName, _loadoutName, _loadoutData]]] call CBA_fnc_remoteEvent; }; // Update share button text -_control ctrlSetText ( [ - localize LSTRING(buttonSharePrivateText), - localize LSTRING(buttonSharePublicText) +_control ctrlSetText ([ + LLSTRING(buttonSharePrivateText), + LLSTRING(buttonSharePublicText) ] select ((_contentPanelCtrl lnbValue [_contentPanelCursSel, 0]) == 1)); diff --git a/addons/arsenal/functions/fnc_buttonStats.sqf b/addons/arsenal/functions/fnc_buttonStats.sqf deleted file mode 100644 index 0eaac78a41..0000000000 --- a/addons/arsenal/functions/fnc_buttonStats.sqf +++ /dev/null @@ -1,31 +0,0 @@ -#include "script_component.hpp" -#include "..\defines.hpp" -/* - * Author: Alganthe - * Toggle the stats control group - * - * Arguments: - * 0: Arsenal display - * 1: Button control - * - * Return Value: - * None - * - * Public: No -*/ - -params ["_display"]; - -(_display displayCtrl IDC_statsButton) ctrlShow GVAR(showStats); -GVAR(showStats) = !GVAR(showStats); - -{ - (_display displayCtrl _x) ctrlShow GVAR(showStats); -} foreach [ - IDC_statsBox, - IDC_statsPreviousPage, - IDC_statsNextPage, - IDC_statsCurrentPage, - IDC_statsButtonClose -]; - diff --git a/addons/arsenal/functions/fnc_buttonStatsPage.sqf b/addons/arsenal/functions/fnc_buttonStatsPage.sqf index 48c9b4715e..33eec398e9 100644 --- a/addons/arsenal/functions/fnc_buttonStatsPage.sqf +++ b/addons/arsenal/functions/fnc_buttonStatsPage.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe - * Handles the previous / next page buttons for stats + * Handles the previous / next page buttons for stats. * * Arguments: * 0: Arsenal display - * 1: Previous or next (false = previous, true = next) + * 1: Stats page + * 2: Previous (false) or next (true) page * * Return Value: * None @@ -16,14 +17,11 @@ params ["_display", "_control", "_nextPage"]; -TRACE_1("control enabled", ctrlEnabled _control); +TRACE_1("control enabled",ctrlEnabled _control); if !(ctrlEnabled _control) exitWith {}; -GVAR(statsInfo) params ["_isLeftPanel", "_statsIndex", "_panelControl", "_curSel", "_itemCfg"]; +GVAR(currentStatPage) = GVAR(currentStatPage) + ([-1, 1] select _nextPage); -private _pageList = [GVAR(statsPagesRight), GVAR(statsPagesLeft)] select (_isLeftPanel); -private _newPageNumber = [(_pageList select _statsIndex) - 1, (_pageList select _statsIndex) + 1] select _nextPage; - -_pageList set [_statsIndex, _newPageNumber]; +GVAR(statsInfo) params ["", "_panelControl", "_curSel", "_itemCfg"]; [QGVAR(displayStats), [_display, _panelControl, _curSel, _itemCfg]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_canEditDefaultLoadout.sqf b/addons/arsenal/functions/fnc_canEditDefaultLoadout.sqf new file mode 100644 index 0000000000..c9258b9f42 --- /dev/null +++ b/addons/arsenal/functions/fnc_canEditDefaultLoadout.sqf @@ -0,0 +1,16 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: LinkIsGrim + * Whether the player can save a default loadout in the current mission state + * + * Arguments: + * None + * + * Return Value: + * Can Save + * + * Public: No +*/ + +is3DEN || EFUNC(common,hasZeusAccess) diff --git a/addons/arsenal/functions/fnc_clearSearchbar.sqf b/addons/arsenal/functions/fnc_clearSearchbar.sqf index a6b7b534dc..6595397e66 100644 --- a/addons/arsenal/functions/fnc_clearSearchbar.sqf +++ b/addons/arsenal/functions/fnc_clearSearchbar.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -7,7 +7,7 @@ * Arguments: * 0: Arsenal display * 1: Searchbar control - * 2: Right button state + * 2: Mouse button * * Return Value: * None @@ -15,11 +15,11 @@ * Public: No */ -params ["_display", "_control", "_rightButton"]; +params ["_display", "_control", "_buttonPressed"]; -if (_rightButton != 1) exitWith {}; +if (_buttonPressed != 1) exitWith {}; -_control ctrlSetText ''; +_control ctrlSetText ""; if (ctrlIDC _control == IDC_leftSearchbar) then { [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_compileActions.sqf b/addons/arsenal/functions/fnc_compileActions.sqf new file mode 100644 index 0000000000..9001a5558a --- /dev/null +++ b/addons/arsenal/functions/fnc_compileActions.sqf @@ -0,0 +1,114 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Brett Mayson + * Create the internal actions arrays when needed for the first time. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +if (!isNil QGVAR(actionList)) exitWith {}; + +private _actionList = [ + [], // Primary 0 + [], // Handgun 1 + [], // Launcher 2 + [], // Uniform 3 + [], // Vests 4 + [], // Backpacks 5 + [], // Headgear 6 + [], // Goggles 7 + [], // NVGs 8 + [], // Binoculars 9 + [], // Map 10 + [], // GPS 11 + [], // Radio 12 + [], // Compass 13 + [], // Watch 14 + [], // Face 15 + [], // Voice 16 + [] // Insignia 17 +]; + +private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)); + +GVAR(updateActionsOnCargoChange) = false; + +{ + private _scopeEditor = getNumber (_x >> "scopeEditor"); + + if (is3DEN && {_scopeEditor != 2}) then {continue}; + + private _configActions = "true" configClasses _x; + + private _rootClass = configName _x; + private _rootDisplayName = getText (_x >> "displayName"); + private _rootCondition = getText (_x >> "condition"); + private _rootTabs = getArray (_x >> "tabs"); + private _updateOnCargoChanged = getNumber (_x >> "updateOnCargoChanged"); + if (_updateOnCargoChanged > 0) then { + GVAR(updateActionsOnCargoChange) = true; + }; + + if (_rootCondition != "") then { + _rootCondition = compile _rootCondition; + } else { + _rootCondition = {true}; + }; + + private _group = []; + + { + private _class = configName _x; + private _label = getText (_x >> "label"); + private _condition = getText (_x >> "condition"); + private _statement = getText (_x >> "statement"); + private _text = getText (_x >> "text"); + private _textStatement = getText (_x >> "textStatement"); + + private _type = switch (false) do { + case (_text == ""): { + _statement = format ["""%1""", _text]; + ACTION_TYPE_TEXT + }; + case (_textStatement == ""): { + _statement = _textStatement; + ACTION_TYPE_TEXT + }; + case (_statement == ""): { + _statement = _statement; + ACTION_TYPE_BUTTON + }; + default { + -1 + }; + }; + + if (_type == -1) then { + continue; + }; + + _statement = compile format [QUOTE([GVAR(center)] call {%1}), _statement]; + + if (_condition != "") then { + _condition = compile _condition; + } else { + _condition = {true}; + }; + + // No duplicates are possible here + _group pushBack [_class, _type, _label, _statement, _condition]; + } forEach _configActions; + + { + (_actionList select _x) pushBack [_rootClass, _rootDisplayName, _rootCondition, _group]; + } forEach _rootTabs; +} forEach _configGroupEntries; + +GVAR(actionList) = _actionList; diff --git a/addons/arsenal/functions/fnc_compileSorts.sqf b/addons/arsenal/functions/fnc_compileSorts.sqf new file mode 100644 index 0000000000..0a1f7b781f --- /dev/null +++ b/addons/arsenal/functions/fnc_compileSorts.sqf @@ -0,0 +1,99 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson, johnb43 + * Create the internal sort arrays when needed for the first time. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +if (!isNil QGVAR(sortListLeftPanel)) exitWith {}; + +private _fnc_addToTabs = { + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _sort = []; + + { + // Copy title, statement and condition + _sort = +_finalArray; + + // Make sort name + _sort set [0, [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; + + // No duplicates are possible here + (_tabsList select _x) pushBack _sort; + } forEach _tabsToAddTo; +}; + +private _sortListLeftPanel = [ + [], // Primary 0 + [], // Handgun 1 + [], // Launcher 2 + [], // Uniform 3 + [], // Vests 4 + [], // Backpacks 5 + [], // Headgear 6 + [], // Goggles 7 + [], // NVGs 8 + [], // Binoculars 9 + [], // Map 10 + [], // GPS 11 + [], // Radio 12 + [], // Compass 13 + [], // Watch 14 + [], // Face 15 + [], // Voice 16 + [] // Insignia 17 +]; + +private _sortListRightPanel = [ + [], // Optics 0 + [], // Side accs 1 + [], // Muzzle 2 + [], // Bipod 3 + [], // Mag 4 + [], // Throw 5 + [], // Put 6 + [] // Misc 7 +]; + +private _class = ""; +private _displayName = ""; +private _statement = ""; +private _condition = ""; +private _finalArray = []; + +{ + _class = configName _x; + _displayName = getText (_x >> "displayName"); + _statement = getText (_x >> "statement"); + _condition = getText (_x >> "condition"); + (getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"]; + + if (_statement != "") then { + _statement = compile _statement; + }; + + if (_condition != "") then { + _condition = compile _condition; + }; + + _finalArray = ["", _displayName, _statement, _condition]; + + if (_leftTabsList isNotEqualTo []) then { + [_sortListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs; + }; + + if (_rightTabsList isNotEqualTo []) then { + [_sortListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; + }; +} forEach ("(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> QGVAR(sorts))); + +GVAR(sortListLeftPanel) = _sortListLeftPanel; +GVAR(sortListRightPanel) = _sortListRightPanel; diff --git a/addons/arsenal/functions/fnc_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf index 40c9d7cfa5..f19854793a 100644 --- a/addons/arsenal/functions/fnc_compileStats.sqf +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Alganthe - * Create the internal stats arrays when needed for the first time + * Author: Alganthe, johnb43 + * Create the internal stat arrays when needed for the first time. * * Arguments: * None @@ -15,121 +15,106 @@ if (!isNil QGVAR(statsListLeftPanel)) exitWith {}; private _fnc_addToTabs = { - params ["_tabsList", "_tabsToAddTo", "_sideString"]; + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _stat = []; + + // First gather all stats for a tab { - private _currentTab = _tabsList select _x; - private _availablePagesCount = {count _x < 5} count _currentTab; + // Make stat name + _stat = +_finalArray; + _stat set [5, [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; - private _arrayToSave = +_finalArray; - _arrayToSave set [0, ([_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString "")]; - - if (_availablePagesCount > 0) then { - - { - if (count _x < 5) exitWith { - (_currentTab select _forEachIndex) append [_arrayToSave]; - }; - } foreach _currentTab; - } else { - _currentTab pushBack [_arrayToSave]; - }; - } foreach _tabsToAddTo; + (_tabsList select _x) pushBack _stat; + } forEach _tabsToAddTo; }; +// Sort by priority private _fnc_sortLists = { - params ["_tabsList"]; + params ["_tabs"]; { - private _page = _x; - { - { - reverse _x; - } foreach _x; - - _x sort false; - - { - reverse _x; - } foreach _x; - } foreach _page; - } foreach _tabsList; + // Sort numerically + _x sort false; + } forEach _tabs; }; private _statsListLeftPanel = [ - [[]], // Primary 0 - [[]], // Handgun 1 - [[]], // Launcher 2 - [[]], // Uniform 3 - [[]], // Vests 4 - [[]], // Backpacks 5 - [[]], // Headgear 6 - [[]], // Goggles 7 - [[]], // NVGs 8 - [[]], // Binoculars 9 - [[]], // Map 10 - [[]], // GPS 11 - [[]], // Radio 12 - [[]], // Compass 13 - [[]] // Watch 14 + [], // Primary 0 + [], // Handgun 1 + [], // Launcher 2 + [], // Uniform 3 + [], // Vests 4 + [], // Backpacks 5 + [], // Headgear 6 + [], // Goggles 7 + [], // NVGs 8 + [], // Binoculars 9 + [], // Map 10 + [], // GPS 11 + [], // Radio 12 + [], // Compass 13 + [] // Watch 14 ]; private _statsListRightPanel = [ - [[]], // Optics 0 - [[]], // Side accs 1 - [[]], // Muzzle 2 - [[]], // Bipod 3 - [[]], // Mag 4 - [[]], // Throw 5 - [[]], // Put 6 - [[]] // Misc 7 + [], // Optics 0 + [], // Side accs 1 + [], // Muzzle 2 + [], // Bipod 3 + [], // Mag 4 + [], // Throw 5 + [], // Put 6 + [] // Misc 7 ]; -//------------------------- Config handling -private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> QGVAR(stats)); +private _finalArray = []; +private _class = ""; +private _stats = []; +private _displayName = ""; +private _showBar = false; +private _showText = false; +private _condition = ""; +private _priority = 0; { - private _finalArray = []; - - private _class = configName _x; - private _stats = getArray (_x >> "stats"); - private _displayName = getText (_x >> "displayName"); - private _showBar = getNumber (_x >> "showBar") == 1; - private _showText = getNumber (_x >> "showText") == 1; - private _condition = getText (_x >> "condition"); - private _priority = getNumber (_x >> "priority"); + _class = configName _x; + _stats = getArray (_x >> "stats"); + _displayName = getText (_x >> "displayName"); + _showBar = getNumber (_x >> "showBar") == 1; + _showText = getNumber (_x >> "showText") == 1; + _condition = getText (_x >> "condition"); + _priority = getNumber (_x >> "priority"); (getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"]; if (_condition != "") then { _condition = compile _condition; }; - _finalArray = ["", _stats, _displayName, [_showBar, _showText], [{}, {}, _condition], _priority]; + _finalArray = [_priority, _stats, _displayName, [_showBar, _showText], [{}, {}, _condition], ""]; if (_showBar) then { - private _barStatement = compile (getText (_x >> "barStatement")); - (_finalArray select 4) set [0, _barStatement]; + (_finalArray select 4) set [0, compile (getText (_x >> "barStatement"))]; }; if (_showText) then { - private _textStatement = compile (getText (_x >> "textStatement")); - (_finalArray select 4) set [1, _textStatement]; + (_finalArray select 4) set [1, compile (getText (_x >> "textStatement"))]; }; - TRACE_3("stats array", _finalArray, _leftTabsList, _rightTabsList); + TRACE_3("stats array",_finalArray,_leftTabsList,_rightTabsList); - if (count _leftTabsList > 0) then { + if (_leftTabsList isNotEqualTo []) then { [_statsListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs; }; - if (count _rightTabsList > 0) then { + if (_rightTabsList isNotEqualTo []) then { [_statsListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; }; -} foreach _configEntries; +} forEach ("(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> "ace_arsenal_stats")); +// Sort [_statsListLeftPanel] call _fnc_sortLists; [_statsListRightPanel] call _fnc_sortLists; -//------------------------- Config Handling - -missionNamespace setVariable [QGVAR(statsListLeftPanel), _statsListLeftPanel]; -missionNamespace setVariable [QGVAR(statsListRightPanel), _statsListRightPanel]; +GVAR(statsListLeftPanel) = _statsListLeftPanel; +GVAR(statsListRightPanel) = _statsListRightPanel; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index 5009f46e3a..1eb98d29ec 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Fill left panel. + * Author: Alganthe, johnb43, LinkIsGrim + * Fills left panel. * * Arguments: * 0: Arsenal display * 1: Tab control + * 2: Animate panel refresh * * Return Value: * None @@ -14,192 +15,131 @@ * Public: No */ -params ["_display", "_control"]; +params ["_display", "_control", ["_animate", true]]; private _ctrlIDC = ctrlIDC _control; +private _ctrlPanel = _display displayCtrl IDC_leftTabContent; +private _idxVirt = GVAR(idxMap) getOrDefault [_ctrlIDC, -1, true]; -if !(isNil QGVAR(currentLeftPanel)) then { +// Fade old control background +if (!isNil QGVAR(currentLeftPanel)) then { private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1); _previousCtrlBackground ctrlSetFade 1; - _previousCtrlBackground ctrlCommit FADE_DELAY; + _previousCtrlBackground ctrlCommit ([0, FADE_DELAY] select _animate); + + // When switching tabs, clear searchbox + if (GVAR(currentLeftPanel) != _ctrlIDC) then { + (_display displayCtrl IDC_leftSearchbar) ctrlSetText ""; + (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; + }; }; +// Show new control background private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); -private _ctrlPanel = _display displayCtrl IDC_leftTabContent; _ctrlBackground ctrlSetFade 0; -_ctrlBackground ctrlCommit FADE_DELAY; +_ctrlBackground ctrlCommit ([0, FADE_DELAY] select _animate); // Force a "refresh" animation of the panel -_ctrlPanel ctrlSetFade 1; -_ctrlPanel ctrlCommit 0; -_ctrlPanel ctrlSetFade 0; -_ctrlPanel ctrlCommit FADE_DELAY; +if (_animate) then { + _ctrlPanel ctrlSetFade 1; + _ctrlPanel ctrlCommit 0; + _ctrlPanel ctrlSetFade 0; + _ctrlPanel ctrlCommit FADE_DELAY; +}; _ctrlPanel lbSetCurSel -1; +// Purge old data +lbClear _ctrlPanel; -// Handle icons and filling -switch true do { - case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]) : { - // Purge old data - lbClear _ctrlPanel; - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; - - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach ((GVAR(virtualItems) select 0) select ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find _ctrlIDC)); - }; - - case (_ctrlIDC in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) : { - - lbClear _ctrlPanel; - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; - - // Filling - switch (_ctrlIDC) do { - case IDC_buttonUniform : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 4); - }; - - case IDC_buttonVest : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 5); - }; - - case IDC_buttonBackpack : { - { - ["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 6); - }; - }; - }; - - default { - GVAR(currentRightPanel) = nil; - - lbClear _ctrlPanel; - - if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then { - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; - }; - - switch (_ctrlIDC) do { - case IDC_buttonHeadgear: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 3); - }; - case IDC_buttonGoggles : { - { - ["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 7); - }; - case IDC_buttonNVG : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 8); - }; - case IDC_buttonBinoculars : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 9); - }; - case IDC_buttonMap : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 10); - }; - case IDC_buttonCompass : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 11); - }; - case IDC_buttonRadio : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 12); - }; - case IDC_buttonWatch : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 13); - }; - case IDC_buttonGPS : { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 14); - }; - case IDC_buttonFace : { - { - { - if ( - getnumber (_x >> "disabled") == 0 && - {getText (_x >> "head") != ""} && - {configName _x != "Default"} - ) then { - private _configName = configName _x; - private _displayName = getText (_x >> "displayName"); - private _lbAdd = _ctrlPanel lbAdd _displayName; - _ctrlPanel lbSetData [_lbAdd, _configName]; - _ctrlPanel lbSetTooltip [_lbAdd,format ["%1\n%2",_displayName, _configName]]; - _x call ADDMODICON; - }; - } foreach ("isClass _x" configClasses _x); - } foreach ("isClass _x" configClasses (configfile >> "cfgfaces")); - }; - case IDC_buttonVoice : { - private _voices = (configProperties [(configFile >> "CfgVoice"), "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [(configfile >> "CfgVoice" >> "NoVoice")]; - { - ["CfgVoice", configName _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); - } foreach _voices; - }; - case IDC_buttonInsigna : { - { - ["CfgUnitInsignia", configName _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); - } foreach ("true" configClasses (configFile >> "CfgUnitInsignia")); - - { - private _displayName = getText (_x >> "displayName"); - private _className = configName _x; - private _lbAdd = _ctrlPanel lbAdd _displayName; - - _ctrlPanel lbSetData [_lbAdd, _className]; - _ctrlPanel lbSetPicture [_lbAdd, getText (_x >> "texture")]; - _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; - } foreach ("true" configClasses (missionConfigFile >> "CfgUnitInsignia")); - }; - }; - }; +// For every left tab except faces and voices, add "Empty" entry +if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then { + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; }; -// Done -if (GVAR(currentLeftPanel) != _ctrlIDC) then { - (_display displayCtrl IDC_leftSearchbar) ctrlSetText ""; - (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +// Don't reset the current right panel for weapons, binos and containers +if !(_idxVirt in [IDX_VIRT_PRIMARY_WEAPONS, IDX_VIRT_SECONDARY_WEAPONS, IDX_VIRT_HANDGUN_WEAPONS, IDX_VIRT_BINO, IDX_VIRT_UNIFORM, IDX_VIRT_VEST, IDX_VIRT_BACKPACK]) then { + GVAR(currentRightPanel) = nil; }; - GVAR(currentLeftPanel) = _ctrlIDC; + +// Add items to the listbox +private _selectedItem = if (_idxVirt != -1) then { // Items + private _configParent = switch (_idxVirt) do { + case IDX_VIRT_GOGGLES: {"CfgGlasses"}; + case IDX_VIRT_BACKPACK: {"CfgVehicles"}; + default {"CfgWeapons"}; + }; + + private _items = if (_idxVirt < IDX_VIRT_HEADGEAR) then { + keys ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _idxVirt) + } else { + keys (GVAR(virtualItems) get _idxVirt) + }; + + { + [_configParent, _x, _ctrlPanel] call FUNC(addListBoxItem); + } forEach _items; + + GVAR(currentItems) select _idxVirt +} else { // Special cases + switch (_ctrlIDC) do { + // Faces + case IDC_buttonFace: { + private _lbAdd = -1; // micro-optimization + // Faces need to be added like this because their config path is + // configFile >> "CfgFaces" >> face category >> className + { + _y params ["_displayName", "_modPicture"]; + _lbAdd = _ctrlPanel lbAdd _displayName; + _ctrlPanel lbSetData [_lbAdd, _x]; + _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]]; + _ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; + } forEach GVAR(faceCache); // HashMap, not array + + GVAR(currentFace) + }; + // Voices + case IDC_buttonVoice: { + { + ["CfgVoice", _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); + } forEach (keys GVAR(voiceCache)); + + GVAR(currentVoice) + }; + // Insignia + case IDC_buttonInsignia: { + { + ["CfgUnitInsignia", _x, _ctrlPanel, "texture", _y] call FUNC(addListBoxItem); + } forEach GVAR(insigniaCache); + + GVAR(currentInsignia) + }; + // Unknown + default { + WARNING_1("Unknown arsenal left panel with IDC %1, update ace_arsenal_idxMap and relevant macros if adding a new tab",_ctrlIDC); + "" + }; + }; +}; + +// Trigger event [QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent; // Sort -private _sortLeftCtrl = _display displayCtrl IDC_sortLeftTab; -[_sortLeftCtrl, _sortLeftCtrl lbValue (lbCurSel _sortLeftCtrl)] call FUNC(sortPanel); +[_display, _control, _display displayCtrl IDC_sortLeftTab, _display displayCtrl IDC_sortLeftTabDirection] call FUNC(fillSort); -//Select current item -private _itemsToCheck = ((GVAR(currentItems) select [0,15]) + [GVAR(currentFace), GVAR(currentVoice), GVAR(currentInsignia)]) apply {tolower _x}; +// Try to select previously selected item again, otherwise select first item ("Empty") +if (_selectedItem != "") then { + private _index = 0; -for "_lbIndex" from 0 to (lbSize _ctrlPanel - 1) do { - private _currentData = _ctrlPanel lbData _lbIndex; - - if (!(_currentData isEqualTo "") && {tolower _currentData in _itemsToCheck}) exitWith { - _ctrlPanel lbSetCurSel _lbIndex; + for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { + if ((_ctrlPanel lbData _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; }; -}; -if (lbCurSel _ctrlPanel < 0) then { + + _ctrlPanel lbSetCurSel _index; +} else { _ctrlPanel lbSetCurSel 0; }; diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf index 433f0304df..6174193b73 100644 --- a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -1,12 +1,16 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Fill loadouts list. + * Author: Alganthe, johnb43, LinkIsGrim + * Fill loadouts list over multiple frames. LOADOUTS_PER_FRAME macro does what it says on the tin. + * Should only ever be called by display load (with optional params as default) and by itself. + * Listen to ace_arsenal_loadoutsListFilled event if you need to iterate over the loadouts list. * * Arguments: * 0: Loadouts display * 1: Tab control + * 2: Current frame filling loadouts list (default: 0) + * 3: Frames necessary to fill loadouts list (default: -1) * * Return Value: * None @@ -14,113 +18,152 @@ * Public: No */ -params ["_display", "_control"]; +// Can just be modified directly, no further setup needed +#define LOADOUTS_PER_FRAME 10 + +params ["_display", "_control", ["_currentFrame", 0], ["_framesToFill", -1]]; + +if (isNull _display) exitWith { + TRACE_2("display closed, aborting",_currentFrame,_framesToFill); +}; private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; -private _textEditBoxCtrl= _display displayCtrl IDC_textEditBox; -_textEditBoxCtrl ctrlSetText ""; -private _sharingEnabled = (GVAR(allowSharedLoadouts) && {isMultiplayer}); +if (_currentFrame == 0) then { + (_display displayCtrl IDC_textEditBox) ctrlSetText ""; + + // Force a "refresh" animation of the panel + _contentPanelCtrl ctrlSetFade 1; + _contentPanelCtrl ctrlCommit 0; + _contentPanelCtrl ctrlSetFade 0; + _contentPanelCtrl ctrlCommit FADE_DELAY; + + _contentPanelCtrl lnbSetCurSelRow -1; + lnbClear _contentPanelCtrl; +}; + private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); - -// Force a "refresh" animation of the panel -_contentPanelCtrl ctrlSetFade 1; -_contentPanelCtrl ctrlCommit 0; -_contentPanelCtrl ctrlSetFade 0; -_contentPanelCtrl ctrlCommit FADE_DELAY; - -_contentPanelCtrl lnbSetCurSelRow -1; -lnbClear _contentPanelCtrl; - -private _data = +(profileNamespace getvariable [QGVAR(saved_loadouts),[]]); +private _cfgWeapons = configFile >> "CfgWeapons"; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove +private _newRow = -1; if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { + private _loadoutNameAndTab = ""; + private _loadoutCachedInfo = ""; + private _sharingEnabled = GVAR(allowSharedLoadouts) && {isMultiplayer}; + private _loadouts = [ + profileNamespace getVariable [QGVAR(saved_loadouts), []], + GVAR(defaultLoadoutsList) + ] select (ctrlIDC _control == IDC_buttonDefaultLoadouts); + if (_currentFrame == 0) then { + _framesToFill = floor ((count _loadouts) / LOADOUTS_PER_FRAME); + TRACE_2("filling loadouts list",_currentFrame,_framesToFill); + _this set [3, _framesToFill]; + }; + // Add all loadouts to loadout list { _x params ["_loadoutName", "_loadoutData"]; - private _loadoutCachedInfo = _contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab)); + _loadoutNameAndTab = _loadoutName + str GVAR(currentLoadoutsTab); + _loadoutCachedInfo = _contentPanelCtrl getVariable _loadoutNameAndTab; + // If not in cache, get info and cache it if (isNil "_loadoutCachedInfo") then { - [_loadoutData] call FUNC(verifyLoadout) - } else { - _loadoutCachedInfo - } params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; + _loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout); + _contentPanelCtrl setVariable [_loadoutNameAndTab, _loadoutCachedInfo]; - // Log missing / nil items to RPT - if (GVAR(EnableRPTLog) && {isNil "_loadoutCachedInfo"} && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then { + _loadoutCachedInfo params ["", "_nullItemsList", "_unavailableItemsList", "_missingExtendedInfo"]; - private _printComponent = "ACE_Arsenal - Loadout:"; - private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " "; - private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " "; + // Log missing / nil items to RPT (only once per arsenal session) + if (GVAR(EnableRPTLog) && {(_nullItemsList isNotEqualTo []) || {_unavailableItemsList isNotEqualTo [] || {_missingExtendedInfo isNotEqualTo []}}}) then { + private _printComponent = "ACE_Arsenal - Loadout:"; + private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " "; + private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " "; + private _printMissingExtendedInfo = ["Missing extended loadout:", str _missingExtendedInfo] joinString " "; - diag_log text (format ["%1%5 %2%5 %3%5 %4", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, endl]); + diag_log text (format ["%1%6 %2%6 %3%6 %4%6 %5", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, _printMissingExtendedInfo, endl]); + }; }; + // Set position of loadouts different if in default loadout tab or if sharing is disabled if (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts || {!_sharingEnabled}) then { _contentPanelCtrl lnbSetColumnsPos [0, 0, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; } else { _contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; }; - private _newRow = _contentPanelCtrl lnbAddRow ["",_loadoutName]; + _loadoutCachedInfo params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"]; + _extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove + + _newRow = _contentPanelCtrl lnbAddRow ["", _loadoutName]; ADD_LOADOUTS_LIST_PICTURES - if (_nullItemsAmount > 0) then { - - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + // Change color on loadout lines that have items that aren't available or don't exist + if (_nullItemsList isNotEqualTo []) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red } else { - - if (_unavailableItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + if (_unavailableItemsList isNotEqualTo []) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray }; }; - _contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), [_loadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]]; - - if ((profileName + _loadoutName) in _sharedLoadoutsVars && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts}) then { + // If it's a shared loadout and player is in the private loadouts tab, add icon + if (((profileName + _loadoutName) in _sharedLoadoutsVars) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts}) then { _contentPanelCtrl lnbSetPicture [[_newRow, 0], QPATHTOF(data\iconPublic.paa)]; _contentPanelCtrl lnbSetValue [[_newRow, 0], 1]; }; - } foreach ([_data, +GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); + } forEach (_loadouts select [_currentFrame * LOADOUTS_PER_FRAME, [LOADOUTS_PER_FRAME, count _loadouts] select is3DEN]); } else { + private _allPlayerNames = allPlayers apply {name _x}; + private _loadouts = _sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}; + private _loadoutVar = ""; + if (_currentFrame == 0) then { + _framesToFill = floor ((count _loadouts) / LOADOUTS_PER_FRAME); + TRACE_2("filling loadouts list",_currentFrame,_framesToFill); + _this set [3, _framesToFill]; + }; { _x params ["_playerName", "_loadoutName", "_loadoutData"]; - if ((allPlayers apply {name _x}) find _playerName == -1) then { - - private _loadoutVar = _playerName + _loadoutName; + _loadoutVar = _playerName + _loadoutName; + // If player who shared loadout doesn't exist anymore, unshare loadout + if !(_playerName in _allPlayerNames) then { GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; - _sharedLoadoutsVars = _sharedLoadoutsVars - [_loadoutVar]; - GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars, true]; + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars - [_loadoutVar], true]; [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; } else { - - ([_loadoutData] call FUNC(verifyLoadout)) params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"]; + _extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove _contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; - private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; + _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; ADD_LOADOUTS_LIST_PICTURES - _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; + _contentPanelCtrl lnbSetData [[_newRow, 1], _loadoutVar]; - if (_nullItemsAmount > 0) then { - - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + // Change color on loadout lines that have items that aren't available or don't exist + if (_nullItemsList isNotEqualTo []) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red } else { - - if (_unavailableItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + if (_unavailableItemsList isNotEqualTo []) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray }; }; }; - } foreach (_sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}); + } forEach (_loadouts select [_currentFrame * LOADOUTS_PER_FRAME, [LOADOUTS_PER_FRAME, count _loadouts] select is3DEN]); }; +if (!is3DEN && _currentFrame != _framesToFill) exitWith { + _this set [2, _currentFrame + 1]; + [FUNC(fillLoadoutsList), _this] call CBA_fnc_execNextFrame; +}; +TRACE_3("finished",_currentFrame,_framesToFill,lnbSize _contentPanelCtrl); + [QGVAR(loadoutsListFilled), [_display, _control]] call CBA_fnc_localEvent; +// Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index a5f60c593c..d8dc7e2403 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Fill right panel. + * Author: Alganthe, johnb43 + * Fills right panel. * * Arguments: * 0: Arsenal display * 1: Tab control + * 2: Animate panel refresh (default: true) * * Return Value: * None @@ -14,354 +15,434 @@ * Public: No */ -params ["_display", "_control"]; - -private _ctrlIDC = ctrlIDC _control; +params ["_display", "_control", ["_animate", true]]; // Fade old control background -if !(isNil QGVAR(currentRightPanel)) then { +if (!isNil QGVAR(currentRightPanel)) then { private _previousCtrlBackground = _display displayCtrl (GVAR(currentRightPanel) - 1); _previousCtrlBackground ctrlSetFade 1; - _previousCtrlBackground ctrlCommit FADE_DELAY; + _previousCtrlBackground ctrlCommit ([0, FADE_DELAY] select _animate); }; // Show new control background +private _ctrlIDC = ctrlIDC _control; private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); _ctrlBackground ctrlShow true; _ctrlBackground ctrlSetFade 0; -_ctrlBackground ctrlCommit FADE_DELAY; +_ctrlBackground ctrlCommit ([0, FADE_DELAY] select _animate); private _searchbarCtrl = _display displayCtrl IDC_rightSearchbar; +// Show right search bar if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { _searchbarCtrl ctrlShow true; _searchbarCtrl ctrlSetFade 0; _searchbarCtrl ctrlCommit 0; }; -private _fnc_fill_right_Container = { - params ["_configCategory", "_className", "_isMagazine", ["_isUnique", false, [false]]]; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _rightPanelCache = uiNamespace getVariable QGVAR(rightPanelCache); - private _cacheNamespace = _ctrlPanel; - private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; - - // Not in cache. So get info and put into cache - if (_cachedItemInfo isEqualTo []) then { - private _configPath = configFile >> _configCategory >> _className; - - _cachedItemInfo set [0, getText (_configPath >> "displayName")]; - _cachedItemInfo set [1, getText (_configPath >> "picture")]; - _cachedItemInfo set [2, [getNumber (_configPath >> "itemInfo" >> "mass"), getNumber (_configPath >> "mass")] select _isMagazine]; - - _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; - }; - - _cachedItemInfo params ["_displayName","_picture", "_mass"]; - - private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; - private _columns = count lnbGetColumnsPosition _ctrlPanel; - - _ctrlPanel lnbSetData [[_lbAdd, 0], _x]; - _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; - _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; - _ctrlPanel setVariable [_x, _mass]; - _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select (_isUnique)]; - _ctrlPanel lbSetTooltip [_lbAdd * _columns,format ["%1\n%2", _displayName, _x]]; +private _currentCargo = []; // we only need this if we're filtering for favorites +if (GVAR(favoritesOnly)) then { + _currentCargo = itemsWithMagazines GVAR(center) + backpacks GVAR(center); + _currentCargo = _currentCargo arrayIntersect _currentCargo; }; -// Retrieve compatible mags -private _compatibleItems = []; -private _compatibleMagazines = [[[], []], [[], []], [[], []]]; -{ - if (_x != "") then { - private _weaponConfig = (configFile >> "CfgWeapons" >> _x); - private _index = _forEachIndex; +private _fnc_fillRightContainer = { + params ["_configCategory", "_className", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; - { - private _subIndex = _forEachIndex; - { - ((_compatibleMagazines select _index) select _subIndex) pushBackUnique (configName (configFile >> "CfgMagazines" >> _x)) - } foreach ([getArray (_weaponConfig >> _x >> "magazines"), getArray (_weaponConfig >> "magazines")] select (_x == "this")); + if (GVAR(favoritesOnly) && {!(_className in _currentCargo)} && {!((toLowerANSI _className) in GVAR(favorites))}) exitWith {}; - // Magazine groups - { - private _magazineGroups = uiNamespace getVariable [QGVAR(magazineGroups),["#CBA_HASH#",[],[],[]]]; - private _magArray = [_magazineGroups, toLower _x] call CBA_fnc_hashGet; - {((_compatibleMagazines select _index) select _subIndex) pushBackUnique _x} forEach _magArray; - } foreach ([getArray (_weaponConfig >> _x >> "magazineWell"), getArray (_weaponConfig >> "magazineWell")] select (_x == "this")); - - - } foreach getArray (_weaponConfig >> "muzzles"); + // If item is not in the arsenal, it must be unique + if (!_isUnique && {!(_className in GVAR(virtualItemsFlat))}) then { + _isUnique = true; }; -} foreach [primaryWeapon GVAR(center), handgunWeapon GVAR(center), secondaryWeapon GVAR(center)]; -private _itemsToCheck = []; -private _compatibleMagsPrimaryMuzzle = []; -private _compatibleMagsSecondaryMuzzle = []; + // If not in cache, find info and cache it for later use + (_rightPanelCache getOrDefaultCall [_configCategory + _className, { + // Get display name, picture and mass + private _configPath = configFile >> _configCategory >> _className; -private _allCompatibleMags = []; -{ - _allCompatibleMags append (_x select 0); - _allCompatibleMags append (_x select 1); -} foreach _compatibleMagazines; + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + if (_className in (uiNamespace getVariable QGVAR(magazineMiscItems))) then { + _configPath = _cfgMagazines >> _className; + }; + + // If an item with unknown origin is in the arsenal list, try to find it + if (_unknownOrigin && {isNull _configPath}) then { + _configPath = _className call CBA_fnc_getItemConfig; + + // Check if item is object (this should never happen) + if (isNull _configPath) then { + _configPath = _className call CBA_fnc_getObjectConfig; + }; + }; + + [getText (_configPath >> "displayName"), getText (_configPath >> "picture")] + }, true]) params ["_displayName", "_picture"]; + + private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; + _ctrlPanel lnbSetText [[_lbAdd, 1], _displayName]; + _ctrlPanel lnbSetData [[_lbAdd, 0], _className]; + _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; + _ctrlPanel lnbSetValue [[_lbAdd, 2], parseNumber _isUnique]; + _ctrlPanel lnbSetTooltip [[_lbAdd, 0], format ["%1\n%2", _displayName, _className]]; + if ((toLowerANSI _className) in GVAR(favorites)) then { + _ctrlPanel lnbSetColor [[_lbAdd, 1], FAVORITES_COLOR]; + _ctrlPanel lnbSetColorRight [[_lbAdd, 1], FAVORITES_COLOR]; + }; +}; private _ctrlPanel = _display displayCtrl IDC_rightTabContent; +private _listnBox = _display displayCtrl IDC_rightTabContentListnBox; + +// Retrieve compatible items +private _isContainer = false; +private _selectedItem = ""; +private _compatibleItems = []; +private _compatibleMagsMuzzle = []; +private _compatibleMagsAll = createHashMap; switch (GVAR(currentLeftPanel)) do { - case IDC_buttonPrimaryWeapon : { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 0 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 0 select 1; - _compatibleItems = (primaryWeapon GVAR(center)) call bis_fnc_compatibleItems; - _itemsToCheck = GVAR(currentItems) select 18; - }; + // If weapons or binoculars are chosen, get their compatible magazines & items + // Weapons and binoculars + case IDC_buttonPrimaryWeapon; + case IDC_buttonHandgun; + case IDC_buttonSecondaryWeapon; + case IDC_buttonBinoculars: { + (switch (GVAR(currentLeftPanel)) do { + case IDC_buttonPrimaryWeapon: { + [IDX_CURR_PRIMARY_WEAPON, IDX_CURR_PRIMARY_WEAPON_ITEMS] + }; + case IDC_buttonHandgun: { + [IDX_CURR_HANDGUN_WEAPON, IDX_CURR_HANDGUN_WEAPON_ITEMS] + }; + case IDC_buttonSecondaryWeapon: { + [IDX_CURR_SECONDARY_WEAPON, IDX_CURR_SECONDARY_WEAPON_ITEMS] + }; + case IDC_buttonBinoculars: { + [IDX_CURR_BINO, IDX_CURR_BINO_ITEMS] + }; + }) params ["_currentWeaponIndex", "_currentWeaponItemsIndex"]; - case IDC_buttonHandgun : { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 1 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 1 select 1; - _compatibleItems = (handgunWeapon GVAR(center)) call bis_fnc_compatibleItems; - _itemsToCheck = GVAR(currentItems) select 20; - }; + private _index = [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find _ctrlIDC; + private _weapon = GVAR(currentItems) select _currentWeaponIndex; - case IDC_buttonSecondaryWeapon : { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 2 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 2 select 1; - _compatibleItems = (secondaryWeapon GVAR(center)) call bis_fnc_compatibleItems; - _itemsToCheck = GVAR(currentItems) select 19; - }; + // Check if weapon attachement or magazine + if (_index != -1) then { + _selectedItem = (GVAR(currentItems) select _currentWeaponItemsIndex) select _index; + // If weapon attachment, get base weapon; Get compatible items + if (_index <= 3) then { + _compatibleItems = compatibleItems _weapon; + _selectedItem = _selectedItem call FUNC(baseWeapon); + } else { + // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) + // Assumption: One weapon can have two muzzles maximum + _compatibleMagsMuzzle = compatibleMagazines [_weapon, (_weapon call CBA_fnc_getMuzzles) param [_index - 4, ""]]; + }; + }; + }; + // Uniform, vest or backpack case IDC_buttonUniform; case IDC_buttonVest; - case IDC_buttonBackpack : { - _ctrlPanel = _display displayCtrl IDC_rightTabContentListnBox; + case IDC_buttonBackpack: { + _isContainer = true; + + // Get the currently selected item in panel + private _selectedItemIndex = lnbCurSelRow _listnBox; + + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _listnBox lnbData [_selectedItemIndex, 0]; + }; + + // This is for the "compatible magazines" tab when a container is open + if (_ctrlIDC == IDC_buttonMag) then { + // Get all compatibles magazines with unit's weapons (including compatible magazines that aren't in configItems) + { + _compatibleMagsAll insert [true, compatibleMagazines _x, []]; + } forEach [GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON, GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON, GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON, GVAR(currentItems) select IDX_CURR_BINO]; + }; }; }; +// Reset right panel content +lbClear _ctrlPanel; +lnbClear _listnBox; + +_ctrlPanel lbSetCurSel -1; +_listnBox lnbSetCurSelRow -1; + +if (_isContainer) then { + _ctrlPanel = _listnBox; +}; + // Force a "refresh" animation of the panel -_ctrlPanel ctrlSetFade 1; -_ctrlPanel ctrlCommit 0; -_ctrlPanel ctrlSetFade 0; -_ctrlPanel ctrlCommit FADE_DELAY; - -_itemsToCheck = _itemsToCheck apply {toLower _x}; -_compatibleItems = _compatibleItems apply {toLower _x}; - -lbClear (_display displayCtrl IDC_rightTabContentListnBox); -lbClear (_display displayCtrl IDC_rightTabContent); - -(_display displayCtrl IDC_rightTabContentListnBox) lbSetCurSel -1; -(_display displayCtrl IDC_rightTabContent) lbSetCurSel -1; - -private _leftPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]; - -if (_ctrlIDC in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] && {_leftPanelState}) then { - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; +if (_animate) then { + _ctrlPanel ctrlSetFade 1; + _ctrlPanel ctrlCommit 0; + _ctrlPanel ctrlSetFade 0; + _ctrlPanel ctrlCommit FADE_DELAY; }; +// Check if the left panel is a weapon. If so, right panel will be compatible items with weapon only +private _leftPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon, IDC_buttonBinoculars]; + +// Add an empty entry if left panel is a weapon or bino +if (_leftPanelState && {_ctrlIDC in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}) then { + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; +}; + +// Fill right panel according to category choice switch (_ctrlIDC) do { + // Optics, flashlights, muzzle attachments, bipods + case IDC_buttonOptic; + case IDC_buttonItemAcc; + case IDC_buttonMuzzle; + case IDC_buttonBipod: { + private _index = [IDX_VIRT_OPTICS_ATTACHMENTS, IDX_VIRT_FLASHLIGHT_ATTACHMENTS, IDX_VIRT_MUZZLE_ATTACHMENTS, IDX_VIRT_BIPOD_ATTACHMENTS] select ([RIGHT_PANEL_ACC_IDCS] find _ctrlIDC); - case IDC_buttonOptic : { if (_leftPanelState) then { { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 0) apply {toLower _x})); + if (_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)) then { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + }; + } forEach _compatibleItems; } else { { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 0); + ["CfgWeapons", _x] call _fnc_fillRightContainer; + } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)); + { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 0); + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get _index)); }; }; - - case IDC_buttonItemAcc : { + // Current primary & secondary muzzle compatible magazines + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2: { if (_leftPanelState) then { { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 1) apply {toLower _x})); - } else { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 1); - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 1); + if (_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { + ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); + }; + } forEach _compatibleMagsMuzzle; }; }; + // All compatible magazines + case IDC_buttonMag: { + { + if (_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { + ["CfgMagazines", _x] call _fnc_fillRightContainer; - case IDC_buttonMuzzle : { - if (_leftPanelState) then { + continue; + }; + + if (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)) then { + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; + }; + } forEach (keys _compatibleMagsAll); + }; + // All magazines + case IDC_buttonMagALL: { + { + ["CfgMagazines", _x] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + { + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)); + }; + // Grenades + case IDC_buttonThrow: { + { + ["CfgMagazines", _x] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_GRENADES)); + + { + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES)); + }; + // Explosives + case IDC_buttonPut: { + { + ["CfgMagazines", _x] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)); + + { + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES)); + }; + // Misc. items + case IDC_buttonMisc: { + // Don't add items that will be in a custom right panel button + private _items = createHashMap; + + if (!isNil QGVAR(customRightPanelButtons)) then { { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 2) apply {toLower _x})); - } else { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 2); - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 2); + if (!isNil "_x") then { + _items insert [true, _x select 0, []]; + }; + } forEach GVAR(customRightPanelButtons); }; - }; - case IDC_buttonBipod : { - if (_leftPanelState) then { + // "Regular" misc. items + { + if !(_x in _items) then { + ["CfgWeapons", _x] call _fnc_fillRightContainer; + }; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)); + // Unique items + { + if !(_x in _items) then { + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + }; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS)); + // Unique backpacks + { + if !(_x in _items) then { + ["CfgVehicles", _x, true] call _fnc_fillRightContainer; + }; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS)); + // Unique goggles + { + if !(_x in _items) then { + // _y indicates if an item is truly unique or if it's a non-inventory item in a container (e.g. goggles in backpack) + ["CfgGlasses", _x, _y] call _fnc_fillRightContainer; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES); + // Unknown items + { + if !(_x in _items) then { + // _y indicates if an item is truly unique or if it's a non-inventory item in a container (e.g. helmet in backpack) + ["CfgWeapons", _x, _y, true] call _fnc_fillRightContainer; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS); // if an item is here but in virtual items, it's just in the wrong place + }; + // Custom buttons + default { + private _items = (GVAR(customRightPanelButtons) param [[RIGHT_PANEL_CUSTOM_BUTTONS] find _ctrlIDC, []]) param [0, []]; + + if (_items isNotEqualTo []) then { { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 3) apply {toLower _x})); - } else { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 3); - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 3); + + switch (true) do { + // "Regular" misc. items + case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + ["CfgWeapons", _x] call _fnc_fillRightContainer; + }; + // Unique items + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS)): { + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + }; + // Unique backpacks + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS)): { + ["CfgVehicles", _x, true] call _fnc_fillRightContainer; + }; + // Unique goggles + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES)): { + ["CfgGlasses", _x, GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES get _x] call _fnc_fillRightContainer; + }; + // Unknown items + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS)): { + ["CfgWeapons", _x, GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS get _x, true] call _fnc_fillRightContainer; + }; + }; + } forEach _items; }; }; - - case IDC_buttonCurrentMag : { - if (_leftPanelState) then { - { - ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach ((GVAR(virtualItems) select 2) arrayIntersect _compatibleMagsPrimaryMuzzle); - }; - }; - - case IDC_buttonCurrentMag2 : { - if (_leftPanelState) then { - { - ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach ((GVAR(virtualItems) select 2) arrayIntersect _compatibleMagsSecondaryMuzzle); - }; - }; - - case IDC_buttonMag : { - { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 2) arrayIntersect _allCompatibleMags); - { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 19) arrayIntersect _allCompatibleMags); - }; - - case IDC_buttonMagALL : { - { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 2); - { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 19); - }; - - case IDC_buttonThrow : { - { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 15); - { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 20); - }; - - case IDC_buttonPut : { - { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 16); - { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 21); - }; - - case IDC_buttonMisc : { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 17); - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 18); - { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 23); - { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 24); - }; }; -(_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +// When switching tabs, clear searchbox +if (GVAR(currentRightPanel) != _ctrlIDC) then { + (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +}; +// Trigger event GVAR(currentRightPanel) = _ctrlIDC; - [QGVAR(rightPanelFilled), [_display, GVAR(currentLeftPanel), _ctrlIDC]] call CBA_fnc_localEvent; -// Add current items and change progress bar -if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { - - private _maxLoad = 0; +// Add current items, change progress bar of container load and get relevant container +if (_isContainer) then { + private _containerItems = []; private _container = switch (GVAR(currentLeftPanel)) do { - case IDC_buttonUniform : { + // Uniform + case IDC_buttonUniform: { + // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); - _maxLoad = gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass"); - uniformItems GVAR(center) + + // Get all items from container + _containerItems = uniformItems GVAR(center); + + uniformContainer GVAR(center) }; - case IDC_buttonVest : { + // Vest + case IDC_buttonVest: { + // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); - _maxLoad = gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass"); - vestItems GVAR(center) + + // Get all items from container + _containerItems = vestItems GVAR(center); + + vestContainer GVAR(center) }; - case IDC_buttonBackpack : { + // Backpack + case IDC_buttonBackpack: { + // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); - _maxLoad = backpack GVAR(center); - backpackItems GVAR(center) + + // Get all items from container + _containerItems = backpackItems GVAR(center); + + backpackContainer GVAR(center) }; }; - for "_l" from 0 to ((lnbsize _ctrlPanel select 0) - 1) do { - private _class = _ctrlPanel lnbData [_l, 0]; - _ctrlPanel lnbSetText [[_l, 2], ["0", str ({_x == _class} count _container)] select (_class in _container)]; + // Find out how many items of a type there are and update the number displayed + for "_lbIndex" from 0 to (lnbSize _ctrlPanel select 0) - 1 do { + private _xItem = _ctrlPanel lnbData [_lbIndex, 0]; + _ctrlPanel lnbSetText [[_lbIndex, 2], str ({_xItem == _x} count _containerItems)]; }; - [_ctrlPanel, _maxLoad] call FUNC(updateRightPanel); + // Refresh availibility of items based on space remaining in container + [_ctrlPanel, _container, _containerItems isNotEqualTo []] call FUNC(updateRightPanel); }; // Sorting -private _sortRightCtrl = _display displayCtrl IDC_sortRightTab; -private _sortRightCurSel = lbCurSel _sortRightCtrl; +[_display, _control, _display displayCtrl IDC_sortRightTab, _display displayCtrl IDC_sortRightTabDirection] call FUNC(fillSort); -if (lbSize _sortRightCtrl == 3) then { - _sortRightCtrl lbDelete 2; -}; +if (_selectedItem != "") then { + if (_isContainer) then { + // Try to select previously selected item again, otherwise select nothing + private _index = -1; -if (_leftPanelState) then { - _sortRightCtrl lbDelete 1; - _sortRightCtrl lbAdd (localize "STR_a3_rscdisplayarsenal_sort_mod"); - _sortRightCtrl lbSetValue [1, 1]; - - _sortRightCtrl lbSetCurSel ([0, _sortRightCurSel] select (_sortRightCurSel != 2)); -} else { - _sortRightCtrl lbDelete 1; - _sortRightCtrl lbAdd localize LSTRING(sortByWeightText); - _sortRightCtrl lbSetValue [1, 1]; - - _sortRightCtrl lbAdd localize LSTRING(sortByAmountText); - _sortRightCtrl lbSetValue [2, 2]; - - _sortRightCtrl lbSetCurSel _sortRightCurSel; -}; - -[_sortRightCtrl, _sortRightCtrl lbValue (lbCurSel _sortRightCtrl)] call FUNC(sortPanel); - -// Select current data if not in a container -if !(_itemsToCheck isEqualTo []) then { - for "_lbIndex" from 0 to (lbSize _ctrlPanel - 1) do { - private _currentData = _ctrlPanel lbData _lbIndex; - - if ((_currentData != "") && {tolower _currentData in _itemsToCheck}) exitWith { - _ctrlPanel lbSetCurSel _lbIndex; + for "_lbIndex" from 0 to (lnbSize _ctrlPanel select 0) - 1 do { + if ((_ctrlPanel lnbData [_lbIndex, 0]) == _selectedItem) exitWith { + _index = _lbIndex; + }; }; - }; - if (lbCurSel _ctrlPanel < 0) then { - _ctrlPanel lbSetCurSel 0; + _ctrlPanel lnbSetCurSelRow _index; + } else { + // Try to select previously selected item again, otherwise select first item ("Empty") + private _index = 0; + + for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { + if ((_ctrlPanel lbData _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + _ctrlPanel lbSetCurSel _index; + }; +} else { + if (_isContainer) then { + _ctrlPanel lnbSetCurSelRow -1; // select nothing + } else { + _ctrlPanel lbSetCurSel 0; // select "Empty" }; }; diff --git a/addons/arsenal/functions/fnc_fillSort.sqf b/addons/arsenal/functions/fnc_fillSort.sqf new file mode 100644 index 0000000000..6b14ee38e2 --- /dev/null +++ b/addons/arsenal/functions/fnc_fillSort.sqf @@ -0,0 +1,136 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe, Brett Mayson, johnb43 + * Fills the sort menu. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * 2: Sort control + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display", "_control", "_sortCtrl", "_sortDirectionCtrl"]; + +lbClear _sortCtrl; +lbClear _sortDirectionCtrl; + +private _right = false; +private _rightSort = ctrlIDC _sortCtrl == IDC_sortRightTab; + +// Handle sorting direction +private _lastSortDirection = [GVAR(lastSortDirectionLeft), GVAR(lastSortDirectionRight)] select _rightSort; +private _sortIndex = 0; +private _index = -1; + +{ + _x params ["_sortName", "_displayName", "_direction"]; + + _index = _sortDirectionCtrl lbAdd _displayName; + _sortDirectionCtrl lbSetData [_index, _sortName]; + _sortDirectionCtrl lbSetValue [_index, _direction]; + + if (_direction == _lastSortDirection) then { + _sortIndex = _index; + }; +} forEach [[QGVAR(descending), LLSTRING(sortDescending), DESCENDING], [QGVAR(ascending), LLSTRING(sortAscending), ASCENDING]]; + +// Prevent FUNC(sortPanel) being called twice in succession +GVAR(ignoreFirstSortPanelCall) = true; +_sortDirectionCtrl lbSetCurSel _sortIndex; + +// Handle sorting +private _sorts = if (_rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}) then { + _right = true; + + // Right panel for uniforms, vest and backpacks + GVAR(sortListRightPanel) select ( + switch (GVAR(currentRightPanel)) do { + case IDC_buttonOptic: {0}; + case IDC_buttonItemAcc: {1}; + case IDC_buttonMuzzle: {2}; + case IDC_buttonBipod: {3}; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: {4}; + case IDC_buttonThrow: {5}; + case IDC_buttonPut: {6}; + case IDC_buttonMisc: {7}; + } + ) +} else { + private _idc = ctrlIDC _control; + + switch (true) do { + // Right panel for weapons + case (_rightSort): { + GVAR(sortListRightPanel) select ( + switch (_idc) do { + case IDC_buttonOptic: {0}; + case IDC_buttonItemAcc: {1}; + case IDC_buttonMuzzle: {2}; + case IDC_buttonBipod: {3}; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: {4}; + case IDC_buttonThrow: {5}; + case IDC_buttonPut: {6}; + case IDC_buttonMisc: {7}; + } + ) + }; + // Left panel + default { + GVAR(sortListLeftPanel) select ([ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch, + IDC_buttonFace, + IDC_buttonVoice, + IDC_buttonInsignia + ] find _idc) + }; + } +}; + +private _lastSort = [GVAR(lastSortLeft), GVAR(lastSortRight)] select _rightSort; +_sortIndex = 0; + +{ + if (_x isEqualTo []) then { + continue; + }; + + _x params ["_sortName", "_displayName", "", "_condition"]; + + // Check if sort if available for this panel + if ([_right] call _condition) then { + _index = _sortCtrl lbAdd _displayName; + _sortCtrl lbSetData [_index, _sortName]; + + if (_displayName == _lastSort) then { + _sortIndex = _index; + }; + }; +} forEach _sorts; + +_sortCtrl lbSetCurSel _sortIndex; diff --git a/addons/arsenal/functions/fnc_getVirtualItems.sqf b/addons/arsenal/functions/fnc_getVirtualItems.sqf new file mode 100644 index 0000000000..0666b34087 --- /dev/null +++ b/addons/arsenal/functions/fnc_getVirtualItems.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43, Grim + * Gets list of virtual items available to the object. + * + * Arguments: + * 0: Target + * + * Return Value: + * Virtual Items + * + * Example: + * cursorObject call ace_arsenal_fnc_getVirtualItems + * + * Public: Yes +*/ +params [["_object", objNull, [objNull]]]; + +private _virtualItems = _object getVariable QGVAR(virtualItems); +if (isNil "_virtualItems") exitWith {createHashMap}; + +private _virtualItemsFlat = +_virtualItems; +private _weapons = _virtualItemsFlat deleteAt IDX_VIRT_WEAPONS; +private _attachments = _virtualItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; + +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItemsFlat merge [_virtualItemsFlat deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _virtualItemsFlat merge [_weapons deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _virtualItemsFlat merge [_attachments deleteAt _index, true]; +}; + +_virtualItemsFlat // return diff --git a/addons/arsenal/functions/fnc_handleActions.sqf b/addons/arsenal/functions/fnc_handleActions.sqf new file mode 100644 index 0000000000..03c25f77df --- /dev/null +++ b/addons/arsenal/functions/fnc_handleActions.sqf @@ -0,0 +1,149 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Brett Mayson + * Handles the actions control group + * + * Arguments: + * 0: Arsenal display + * 1: Current panel control + * 2: Current panel selection + * 3: Item config entry + * + * Return Value: + * None + * + * Public: No +*/ +params ["_display", "_control", "_curSel", "_itemCfg"]; + +GVAR(actionsInfo) = [_control, _curSel, _itemCfg]; + +private _panel = [ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch, + IDC_buttonFace, + IDC_buttonVoice, + IDC_buttonInsignia +] find GVAR(currentLeftPanel); + +private _groups = (GVAR(actionList) select _panel) select { + [GVAR(center)] call (_x select 2) +}; + +private _show = _groups isNotEqualTo []; +private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; +_actionsBoxCtrl ctrlShow _show; +_actionsBoxCtrl ctrlCommit FADE_DELAY; + +if (!_show) exitWith {}; + +private _actionsCurrentPageCtrl = _display displayCtrl IDC_actionsCurrentPage; + +private _currentPage = GVAR(currentActionPage); +private _pages = count _groups; + +if (_currentPage < 0) then { + _currentPage = _pages - 1; +}; + +if (_currentPage >= _pages) then { + _currentPage = 0; + GVAR(currentActionPage) = _currentPage; +}; + +{ + private _ctrl = _display displayCtrl _x; + _ctrl ctrlShow (_pages > 1); + _ctrl ctrlCommit 0; +} forEach [IDC_actionsPreviousPage, IDC_actionsNextPage]; + +private _group = _groups select _currentPage; +private _items = _group select 3 select { + [GVAR(center)] call (_x select 4) +}; + +_actionsCurrentPageCtrl ctrlSetText (_group select 1); +_actionsCurrentPageCtrl ctrlShow true; +_actionsCurrentPageCtrl ctrlCommit 0; + +private _activeCtrls = []; +{ + _x params ["", "_type", "_label", "_statement"]; + + private _idc = IDC_actionsText1 + _type + _forEachIndex * 2; + private _actionCtrl = _display displayCtrl _idc; + + switch (_type) do { + case ACTION_TYPE_BUTTON: { + _actionCtrl ctrlRemoveAllEventHandlers "ButtonClick"; + _actionCtrl ctrlAddEventHandler ["ButtonClick", { + if (is3DEN) exitWith {[true] call FUNC(refresh)}; + [{ + [true] call FUNC(refresh); + }] call CBA_fnc_execNextFrame; + }]; + + _actionCtrl ctrlAddEventHandler ["ButtonClick", _statement]; + _actionCtrl ctrlSetText _label; + _actionCtrl ctrlEnable true; + }; + case ACTION_TYPE_TEXT: { + private _text = call _statement; + + if (isNil "_text") then { + _text = ""; + }; + if (_text isEqualType []) then { + _text = _text joinString endl; + }; + + _actionCtrl ctrlSetText _text; + _actionCtrl ctrlSetPositionH (ctrlTextHeight _actionCtrl); + _actionCtrl ctrlEnable false; + }; + }; + + if (_activeCtrls isNotEqualTo []) then { + (ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; + _actionCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H); + } else { + _actionCtrl ctrlSetPositionY ((5 + _type) * GRID_H); + }; + + _actionCtrl ctrlShow true; + _actionCtrl ctrlCommit 0; + _activeCtrls pushBack _actionCtrl; +} forEach _items; + +{ + private _idc = ctrlIDC _x; + if (_idc < IDC_actionsText1 || _idc > IDC_actionsButton5) then {continue}; + + _x ctrlShow false; + _x ctrlEnable false; + _x ctrlSetPositionY 0; + _x ctrlCommit 0; +} forEach ((allControls _actionsBoxCtrl) select {!(_x in _activeCtrls)}); + +(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; +private _actionsBoxHeight = _lastPosY + _lastPosH + GRID_H; +_actionsBoxCtrl ctrlSetPositionH _actionsBoxHeight; +_actionsBoxCtrl ctrlCommit 0; + +private _background = _display displayCtrl IDC_actionsBackground1; +_background ctrlSetPositionH _actionsBoxHeight; +_background ctrlCommit 0; diff --git a/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf index 2911e7aa19..56d6c357d5 100644 --- a/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf +++ b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -16,30 +16,56 @@ params ["_display", "_control"]; -private _textString = ctrlText _control; - private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; -if !(GVAR(lastSearchTextLoadouts) isEqualTo "" || {(_textString find GVAR(lastSearchTextLoadouts)) == 0}) then {//don't refill if there is no need +// Get the currently selected item in panel +private _selectedLoadoutIndex = lnbCurSelRow _contentPanelCtrl; +private _selectedLoadout = ""; + +// If something is selected, save it +if (_selectedLoadoutIndex != -1) then { + _selectedLoadout = _contentPanelCtrl lnbText [_selectedLoadoutIndex, 1]; +}; + +private _searchString = ctrlText _control; + +// Don't refill if there is no need +if (GVAR(lastSearchTextLoadouts) != "" && {(_searchString find GVAR(lastSearchTextLoadouts)) != 0}) then { [_display, _display displayCtrl GVAR(currentLoadoutsTab)] call FUNC(fillLoadoutsList); }; -GVAR(lastSearchTextLoadouts) = _textString; -if (count _textString == 0) exitWith {}; +GVAR(lastSearchTextLoadouts) = _searchString; -private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +// If nothing searched, quit here +if (_searchString != "") then { + _searchString = toLower _searchString; -private _itemsToGo = (lnbSize _contentPanelCtrl) select 0; -private _lbIndex = 0; -while {_itemsToGo > 0} do { - private _currentData = _contentPanelCtrl lnbText [_lbIndex, 1]; - private _currentClassname = _contentPanelCtrl lnbData [_lbIndex, 0]; + private _loadoutName = ""; + private _loadout = []; + private _currentTab = str GVAR(currentLoadoutsTab); - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { - _contentPanelCtrl lnbDeleteRow _lbIndex; - } else { - _lbIndex = _lbIndex + 1; + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lnbSize _contentPanelCtrl select 0) - 1 to 0 step -1 do { + _loadoutName = toLower (_contentPanelCtrl lnbText [_lbIndex, 1]); + + // Remove item in panel if it doesn't match search, skip otherwise + if ((_loadoutName == "") || {!(_searchString in _loadoutName)}) then { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; }; - _itemsToGo = _itemsToGo - 1; }; -_contentPanelCtrl lnbSetCurSelRow -1; + +// Try to select previously selected item again, otherwise select nothing +if (_selectedLoadoutIndex != -1) then { + private _index = -1; + + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _selectedLoadout) exitWith { + _index = _lbIndex; + }; + }; + + _contentPanelCtrl lnbSetCurSelRow _index; +} else { + _contentPanelCtrl lnbSetCurSelRow -1; +}; diff --git a/addons/arsenal/functions/fnc_handleMouse.sqf b/addons/arsenal/functions/fnc_handleMouse.sqf index 7d2fa2c9e2..588999de8e 100644 --- a/addons/arsenal/functions/fnc_handleMouse.sqf +++ b/addons/arsenal/functions/fnc_handleMouse.sqf @@ -1,16 +1,16 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Karel Moricky, modified by Alganthe + * Author: Karel Moricky, modified by Alganthe, johnb43 * Update the camera position and pitch/bank. * Modernized a bit, modified to fit the rewrite. * * Arguments: * 0: Not used * 1: Arguments - * 1.1: Mouse area control - * 1.2: Mouse X position - * 1.3: Mouse Y position + * - 0: Mouse area control + * - 1: Mouse X position + * - 2: Mouse Y position * * Return Value: * None @@ -19,50 +19,53 @@ */ params ["", "_args"]; - _args params ["_control", "_mouseX", "_mouseY"]; -GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV", "_helperPos"]; + +GVAR(cameraPosition) params ["", "_dirH", "_dirV", "_helperPos"]; GVAR(mouseButtonState) params ["_LMB", "_RMB"]; if (count _LMB > 0) then { _LMB params ["_LMBcursorX", "_LMBcursorY"]; - private _dX = [(_mouseX - _LMBcursorX), (_LMBcursorX - _mouseX)] select GVAR(camInverted); - private _dY = [(_mouseY -_LMBcursorY), (_LMBcursorY - _mouseY)] select GVAR(camInverted); - GVAR(mouseButtonState) set [0,[_mouseX,_mouseY]]; + private _dX = [_mouseX - _LMBcursorX, _LMBcursorX - _mouseX] select GVAR(camInverted); + private _dY = [_mouseY -_LMBcursorY, _LMBcursorY - _mouseY] select GVAR(camInverted); - private _centerBox = boundingboxreal GVAR(center); + private _centerBox = boundingBoxReal GVAR(center); private _centerSizeBottom = _centerBox select 0 select 2; private _centerSizeUp = _centerBox select 1 select 2; - private _centerSize = sqrt ([_centerBox select 0 select 0,_centerBox select 0 select 1] distance [_centerBox select 1 select 0,_centerBox select 1 select 1]); + private _centerSize = sqrt ([_centerBox select 0 select 0, _centerBox select 0 select 1] distance [_centerBox select 1 select 0, _centerBox select 1 select 1]); + + _helperPos = [_helperPos, _dX * _centerSize, _dirH - 90] call BIS_fnc_relPos; - _helperPos = [_helperPos, _dX * _centerSize, _dirH - 90] call bis_fnc_relpos; _helperPos = [ - [0,0,((_helperPos select 2) - _dY * _centerSize) max _centerSizeBottom min _centerSizeUp], - ([0,0,0] distance2D _helperPos) min _centerSize, - [0,0,0] getDir _helperPos - ] call bis_fnc_relpos; + [0, 0, ((_helperPos select 2) - _dY * _centerSize) max _centerSizeBottom min _centerSizeUp], + ([0, 0, 0] distance2D _helperPos) min _centerSize, + [0, 0, 0] getDir _helperPos + ] call BIS_fnc_relPos; - _helperPos set [2,(_helperPos select 2) max ((boundingboxreal GVAR(center) select 0 select 2) + 0.2)]; + _helperPos set [2, (_helperPos select 2) max ((_centerBox select 0 select 2) + 0.2)]; - GVAR(cameraPosition) set [3,_helperPos]; + GVAR(cameraPosition) set [3, _helperPos]; + GVAR(mouseButtonState) set [0, [_mouseX, _mouseY]]; }; if (count _RMB > 0) then { _RMB params ["_RMBcursorX", "_RMBcursorY"]; + private _dX = (_RMBcursorX - _mouseX) * 0.75; private _dY = (_RMBcursorY - _mouseY) * 0.75; + _helperPos = [ - [0,0,_helperPos select 2], - [0,0,0] distance2D _helperPos, - ([0,0,0] getDir _helperPos) - _dX * 360 - ] call bis_fnc_relpos; + [0, 0, _helperPos select 2], + [0, 0, 0] distance2D _helperPos, + ([0, 0, 0] getDir _helperPos) - _dX * 360 + ] call BIS_fnc_relPos; - GVAR(cameraPosition) set [1,(_dirH - _dX * 360)]; - GVAR(cameraPosition) set [2,(_dirV - _dY * 100) max -89 min 89]; - GVAR(cameraPosition) set [3,_helperPos]; - GVAR(mouseButtonState) set [1,[_mouseX,_mouseY]]; + GVAR(cameraPosition) set [1, _dirH - _dX * 360]; + GVAR(cameraPosition) set [2, (_dirV - _dY * 100) max -89 min 89]; + GVAR(cameraPosition) set [3, _helperPos]; + GVAR(mouseButtonState) set [1, [_mouseX, _mouseY]]; }; -if (!alive (GVAR(center)) || isnull GVAR(center)) then { - (ctrlParent _control) closeDisplay 2; +if (!alive GVAR(center)) then { + (ctrlParent _control) closeDisplay IDC_CANCEL; }; diff --git a/addons/arsenal/functions/fnc_handleScrollWheel.sqf b/addons/arsenal/functions/fnc_handleScrollWheel.sqf index 0fec3e7c5b..6ca7be588f 100644 --- a/addons/arsenal/functions/fnc_handleScrollWheel.sqf +++ b/addons/arsenal/functions/fnc_handleScrollWheel.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" -#include "..\defines.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Handle the mouse wheel. * * Arguments: * 0: Not used - * 1: Mousewheel Z position + * 1: onMouseZChanged EH return + * - 0: Not used + * - 1: Mousewheel Z position * * Return Value: * None @@ -17,7 +18,8 @@ params ["", "_args"]; _args params ["", "_zPos"]; -private _distanceMax = ((boundingboxreal GVAR(center) select 0) vectordistance (boundingboxreal GVAR(center) select 1)) * 1.5; +private _boundingBoxReal = boundingBoxReal GVAR(center); +private _distanceMax = ((_boundingBoxReal select 0) vectorDistance (_boundingBoxReal select 1)) * 1.5; private _distanceMin = _distanceMax * 0.15; private _distance = GVAR(cameraPosition) select 0; diff --git a/addons/arsenal/functions/fnc_handleSearchInputChanged.sqf b/addons/arsenal/functions/fnc_handleSearchInputChanged.sqf new file mode 100644 index 0000000000..2c7364c6ef --- /dev/null +++ b/addons/arsenal/functions/fnc_handleSearchInputChanged.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: PabstMirror + * Handles user input in the search text boxes + * + * Arguments: + * 0: Search text input (left or right) + * 1: Text + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_ctrl", "_newText"]; + +if (!GVAR(liveUpdateSearch)) exitWith {}; + +private _display = ctrlParent _ctrl; + +if (GVAR(leftSearchbarFocus)) then { + [_display, _display displayCtrl IDC_leftSearchbar, false] call FUNC(handleSearchBar); +}; +if (GVAR(rightSearchbarFocus)) then { + [_display, _display displayCtrl IDC_rightSearchbar, false] call FUNC(handleSearchBar); +}; diff --git a/addons/arsenal/functions/fnc_handleSearchModeToggle.sqf b/addons/arsenal/functions/fnc_handleSearchModeToggle.sqf new file mode 100644 index 0000000000..b5c35b59a5 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleSearchModeToggle.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: PabstMirror + * Handles mouse clicks on search button to toggle live results + * + * Arguments: + * 0: Search button (left or right) + * 1: Mouse Button + * 2: Not used + * 3: Not used + * 4: Not used + * 5: Ctrl Button + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_ctrl", "_mouseButton", "", "", "", "_keyCtrl"]; + +if ((!_keyCtrl)) exitWith {}; // Ignore if not CTRL + Click + +GVAR(liveUpdateSearch) = !GVAR(liveUpdateSearch); + +private _display = ctrlParent _ctrl; +private _color = if (GVAR(liveUpdateSearch)) then { [0,1,0,0.5] } else { [0,0,0,0.5] }; +(_display displayCtrl IDC_leftSearchbarButton) ctrlSetBackgroundColor _color; +(_display displayCtrl IDC_rightSearchbarButton) ctrlSetBackgroundColor _color; diff --git a/addons/arsenal/functions/fnc_handleSearchbar.sqf b/addons/arsenal/functions/fnc_handleSearchbar.sqf index 5632006f43..d5ff2dc69a 100644 --- a/addons/arsenal/functions/fnc_handleSearchbar.sqf +++ b/addons/arsenal/functions/fnc_handleSearchbar.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles keyboard inputs inside the searchbars text boxes. * * Arguments: * 0: Arsenal display * 1: Searchbar control + * 2: Animate panel refresh (default: true) * * Return Value: * None @@ -14,79 +15,170 @@ * Public: No */ -params ["_display", "_control"]; +params ["_display", "_control", ["_animate", true]]; -private _textString = ctrlText _control; +forceUnicode 0; // handle non-ANSI characters +private _searchString = ctrlText _control; +private _searchPattern = ""; +if (_searchString != "") then { + _searchPattern = _searchString call EFUNC(common,escapeRegex); + _searchPattern = ".*?" + (_searchPattern splitString " " joinString ".*?") + ".*?/io"; +}; + +// Right panel search bar if ((ctrlIDC _control) == IDC_rightSearchbar) then { - if !(GVAR(lastSearchTextRight) isEqualTo "" || {(_textString find GVAR(lastSearchTextRight)) == 0}) then {//don't refill if there is no need - [_display, _display displayCtrl GVAR(currentRightPanel)] call FUNC(fillRightPanel); + // Don't refill if there is no need + if (GVAR(lastSearchTextRight) != "" && {(_searchString find GVAR(lastSearchTextRight)) != 0}) then { + [_display, _display displayCtrl GVAR(currentRightPanel), _animate] call FUNC(fillRightPanel); }; - GVAR(lastSearchTextRight) = _textString; - if (count _textString == 0) exitWith {}; - private _rightPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]; - private _rightPanelCtrl = [_display displayCtrl IDC_rightTabContentListnBox, _display displayCtrl IDC_rightTabContent] select (_rightPanelState); + GVAR(lastSearchTextRight) = _searchString; + // If nothing searched, quit here + if (_searchPattern == "") exitWith {}; + + private _rightPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon, IDC_buttonBinoculars]; + private _rightPanelCtrl = [_display displayCtrl IDC_rightTabContentListnBox, _display displayCtrl IDC_rightTabContent] select _rightPanelState; + + // If right panel selection is weapons or binoculars if (_rightPanelState) then { + // Get the currently selected item in panel + private _selectedItemIndex = lbCurSel _rightPanelCtrl; + private _selectedItem = ""; - private _itemsToGo = lbSize _rightPanelCtrl; - private _lbIndex = 0; - while {_itemsToGo > 0} do { - private _currentData = _rightPanelCtrl lbText _lbIndex; - private _currentClassname = _rightPanelCtrl lbData _lbIndex; + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _rightPanelCtrl lbData _selectedItemIndex; + }; - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + private _currentDisplayName = ""; + private _currentClassname = ""; + + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lbSize _rightPanelCtrl) - 1 to 0 step -1 do { + _currentDisplayName = _rightPanelCtrl lbText _lbIndex; + _currentClassname = _rightPanelCtrl lbData _lbIndex; + + // Remove item in panel if it doesn't match search, skip otherwise + if ((_currentDisplayName == "") || {!(_currentDisplayName regexMatch _searchPattern) && {!(_currentClassname regexMatch _searchPattern)}}) then { _rightPanelCtrl lbDelete _lbIndex; - } else { - _lbIndex = _lbIndex + 1; }; - _itemsToGo = _itemsToGo - 1; }; - _rightPanelCtrl lbSetCurSel -1; + + // Try to select previously selected item again, otherwise select nothing + if (_selectedItemIndex != -1) then { + private _index = -1; + + // Try to find previously selected item in panel + for "_lbIndex" from 0 to (lbSize _rightPanelCtrl) - 1 do { + if ((_rightPanelCtrl lbData _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + // Select old item if found, otherwise don't select anything + _rightPanelCtrl lbSetCurSel _index; + } else { + _rightPanelCtrl lbSetCurSel -1; + }; } else { + // Get the currently selected item in panel + private _selectedItemIndex = lnbCurSelRow _rightPanelCtrl; + private _selectedItem = ""; - private _itemsToGo = (lnbSize _rightPanelCtrl) select 0; - private _lbIndex = 0; - while {_itemsToGo > 0} do { - private _currentData = _rightPanelCtrl lnbText [_lbIndex, 1]; - private _currentClassname = _rightPanelCtrl lnbData [_lbIndex, 0]; - - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { - _rightPanelCtrl lnbDeleteRow _lbIndex; - } else { - _lbIndex = _lbIndex + 1; - }; - _itemsToGo = _itemsToGo - 1; + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _rightPanelCtrl lnbData [_selectedItemIndex, 0]; + }; + + private _currentDisplayName = ""; + private _currentClassname = ""; + + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lnbSize _rightPanelCtrl select 0) - 1 to 0 step -1 do { + _currentDisplayName = _rightPanelCtrl lnbText [_lbIndex, 1]; + _currentClassname = _rightPanelCtrl lnbData [_lbIndex, 0]; + + // Remove item in panel if it doesn't match search, skip otherwise + if ((_currentDisplayName == "") || {!(_currentDisplayName regexMatch _searchPattern) && {!(_currentClassname regexMatch _searchPattern)}}) then { + _rightPanelCtrl lnbDeleteRow _lbIndex; + }; + }; + + // Try to select previously selected item again, otherwise select nothing + if (_selectedItemIndex != -1) then { + private _index = -1; + + // Try to find previously selected item in panel + for "_lbIndex" from 0 to (lnbSize _rightPanelCtrl select 0) - 1 do { + if ((_rightPanelCtrl lnbData [_lbIndex, 0]) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + // Select old item if found, otherwise don't select anything + _rightPanelCtrl lnbSetCurSelRow _index; + } else { + _rightPanelCtrl lnbSetCurSelRow -1; }; - _rightPanelCtrl lnbSetCurSelRow -1; }; [_display, nil, nil, configNull] call FUNC(itemInfo); } else { - - if !(GVAR(lastSearchTextLeft) isEqualTo "" || {(_textString find GVAR(lastSearchTextLeft)) == 0}) then {//don't refill if there is no need - [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); + // Left panel search bar + // Don't refill if there is no need + if (GVAR(lastSearchTextLeft) != "" && {(_searchString find GVAR(lastSearchTextLeft)) != 0}) then { + [_display, _display displayCtrl GVAR(currentLeftPanel), _animate] call FUNC(fillLeftPanel); }; - GVAR(lastSearchTextLeft) = _textString; - if (count _textString == 0) exitWith {}; + + GVAR(lastSearchTextLeft) = _searchString; + + // If nothing searched, quit here + if (_searchPattern == "") exitWith {}; private _leftPanelCtrl = _display displayCtrl IDC_leftTabContent; + // Get the currently selected item in panel + private _selectedItemIndex = lbCurSel _leftPanelCtrl; + private _selectedItem = ""; - private _itemsToGo = (lbSize _leftPanelCtrl); - private _lbIndex = 0; - while {_itemsToGo > 0} do { - private _currentData = _leftPanelCtrl lbText _lbIndex; - private _currentClassname = _leftPanelCtrl lbData _lbIndex; - - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { - _leftPanelCtrl lbDelete _lbIndex; - } else { - _lbIndex = _lbIndex + 1; - }; - _itemsToGo = _itemsToGo - 1; + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _leftPanelCtrl lbData _selectedItemIndex; }; - _leftPanelCtrl lbSetCurSel -1; + + private _currentDisplayName = ""; + private _currentClassname = ""; + + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lbSize _leftPanelCtrl) - 1 to 0 step -1 do { + _currentDisplayName = _leftPanelCtrl lbText _lbIndex; + _currentClassname = _leftPanelCtrl lbData _lbIndex; + + // Remove item in panel if it doesn't match search, skip otherwise + if ((_currentDisplayName == "") || {!(_currentDisplayName regexMatch _searchPattern) && {!(_currentClassname regexMatch _searchPattern)}}) then { + _leftPanelCtrl lbDelete _lbIndex; + }; + }; + + // Try to select previously selected item again, otherwise select nothing + if (_selectedItemIndex != -1) then { + private _index = -1; + + for "_lbIndex" from 0 to (lbSize _leftPanelCtrl) - 1 do { + if ((_leftPanelCtrl lbData _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + _leftPanelCtrl lbSetCurSel _index; + } else { + _leftPanelCtrl lbSetCurSel -1; + }; + [_display, nil, nil, configNull] call FUNC(itemInfo); }; + +// Reset unicode flag +forceUnicode -1; diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf index 0c57f6c721..b5d435a101 100644 --- a/addons/arsenal/functions/fnc_handleStats.sqf +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe - * Handles the stats control group + * Handles the stats control group. * * Arguments: * 0: Arsenal display * 1: Current panel control - * 2: Current panel selection + * 2: Current panel selection * 3: Item config entry * * Return Value: @@ -16,20 +16,21 @@ * Public: No */ -params ["_display", "_control", "_curSel", "_itemCfg"]; +params ["_display", "_control", "_curSel", ["_itemCfg", configNull]]; private _statsBoxCtrl = _display displayCtrl IDC_statsBox; private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; -private _hideUnusedFnc = { - params ["_numbers"]; +private _fnc_hideUnused = { + params ["_count"]; - { - private _statsTitleCtrl = _display displayCtrl (5101 + ((_x - 1) * 4)); - private _statsTitleIDC = ctrlIDC _statsTitleCtrl; + if (_count <= 0) exitWith {}; + for "_i" from 0 to (_count - 1) do { + private _statsTitleIDC = IDC_statsTitle5 - (_i * 4); + private _statsTitleCtrl = _display displayCtrl _statsTitleIDC; private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); @@ -43,196 +44,28 @@ private _hideUnusedFnc = { _statsBarCtrl, _statsTextCtrl ]; - } forEach _numbers; + }; }; -if !(isNil "_itemCfg") then { +private _fnc_hideEverything = { + 5 call _fnc_hideUnused; - private _handleStatsFnc = { - params ["_statsIndex", "_leftPanel"]; - - // Get the proper list and page - if (_leftPanel) then { - [true, (GVAR(statsListLeftPanel)) select _statsIndex, GVAR(statsPagesLeft) select _statsIndex] - } else { - [false, (GVAR(statsListRightPanel)) select _statsIndex, GVAR(statsPagesRight) select _statsIndex] - } params ["_isLeftPanel", "_statsArray", "_currentPage"]; - - private _statsList = _statsArray select _currentPage; - - private _statsCount = 0; - - // Handle titles, bars and text - _statsList = _statsList select [0, 5]; - if !(_statsList isEqualTo []) then { - { - _x params ["_ID", "_configEntry", "_title", "_bools", "_statements"]; - _bools params ["_showBar", "_showText"]; - _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; - - private _statsTitleCtrl = _display displayCtrl (5101 + _forEachIndex * 4); - private _statsTitleIDC = ctrlIDC _statsTitleCtrl; - private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); - private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); - private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); - - _statsCount = _statsCount + 1; - _statsTitleCtrl ctrlSetText _title; - _statsTitleCtrl ctrlSetFade 0; - - // Handle bars - if (_showBar) then { - _statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement); - - _statsBackgroundCtrl ctrlSetFade 0; - _statsBarCtrl ctrlSetFade 0; - } else { - _statsBackgroundCtrl ctrlSetFade 1; - _statsBarCtrl ctrlSetFade 1; - }; - - // Handle text entries - if (_showText) then { - private _textStatementResult = [_configEntry, _itemCfg] call _textStatement; - - if (_textStatementResult isEqualtype "") then { - _statsTextCtrl ctrlSetText _textStatementResult; - } else { - _statsTextCtrl ctrlSetText (str _textStatementResult); - }; - _statsTextCtrl ctrlSetTextColor ([[1,1,1,1], [0,0,0,1]] select (_showBar)); - - _statsTextCtrl ctrlSetFade 0; - } else { - _statsTextCtrl ctrlSetFade 1; - }; - - { - _x ctrlCommit 0; - } forEach [ - _statsTitleCtrl, - _statsBackgroundCtrl, - _statsBarCtrl, - _statsTextCtrl - ]; - } forEach (_statsList select { - _x params ["_ID","_configEntry", "_title", "_bools", "_statements"]; - _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; - - ([_configEntry, _itemCfg] call _condition) - }); - }; - - // Resize the window - [[1, 2, 3, 4, 5] select [_statsCount, 5]] call _hideUnusedFnc; - _statsBoxCtrl ctrlSetPosition [ - (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, - safezoneY + 1.8 * GRID_H, - 47 * GRID_W, - ([11, (10 * _statsCount) + 5] select (_statsCount > 0)) * GRID_H - ]; - _statsBoxCtrl ctrlCommit 0; - - GVAR(statsInfo) = [_isLeftPanel, _statsIndex, _control, _curSel, _itemCfg]; - - // Toggle page buttons - _statsPreviousPageCtrl ctrlEnable !(_currentPage == 0); - _statsNextPageCtrl ctrlEnable !(_currentPage + 1 >= count _statsArray); - _statsCurrentPageCtrl ctrlSetText ([localize LSTRING(page), str (_currentPage + 1)] joinString " "); - - { - _x ctrlSetFade 0; - _x ctrlCommit 0; - } forEach [ - _statsPreviousPageCtrl, - _statsNextPageCtrl, - _statsCurrentPageCtrl - ]; - }; - - if (ctrlIDC _control == IDC_leftTabContent) then { - - if ([IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsigna] find GVAR(currentLeftPanel) > -1) then { - - [[1, 2, 3, 4, 5]] call _hideUnusedFnc; - _statsBoxCtrl ctrlSetPosition [ - (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, - safezoneY + 1.8 * GRID_H, - 47 * GRID_W, - 11 * GRID_H - ]; - _statsBoxCtrl ctrlCommit 0; - - { - _x ctrlSetFade 1; - _x ctrlCommit 0; - } forEach [ - _statsPreviousPageCtrl, - _statsNextPageCtrl, - _statsCurrentPageCtrl - ]; - } else { - [[ - IDC_buttonPrimaryWeapon, - IDC_buttonHandgun, - IDC_buttonSecondaryWeapon, - IDC_buttonUniform, - IDC_buttonVest, - IDC_buttonBackpack, - IDC_buttonHeadgear, - IDC_buttonGoggles, - IDC_buttonNVG, - IDC_buttonBinoculars, - IDC_buttonMap, - IDC_buttonGPS, - IDC_buttonRadio, - IDC_buttonCompass, - IDC_buttonWatch - ] find GVAR(currentLeftPanel), true] call _handleStatsFnc; - }; - } else { - - switch (GVAR(currentRightPanel)) do { - case IDC_buttonOptic: { - [0, false] call _handleStatsFnc; - }; - case IDC_buttonItemAcc: { - [1, false] call _handleStatsFnc; - }; - case IDC_buttonMuzzle: { - [2, false] call _handleStatsFnc; - }; - case IDC_buttonBipod: { - [3, false] call _handleStatsFnc; - }; - case IDC_buttonCurrentMag; - case IDC_buttonCurrentMag2; - case IDC_buttonMag; - case IDC_buttonMagALL: { - [4, false] call _handleStatsFnc; - }; - case IDC_buttonThrow: { - [5, false] call _handleStatsFnc; - }; - case IDC_buttonPut: { - [6, false] call _handleStatsFnc; - }; - case IDC_buttonMisc: { - [7, false] call _handleStatsFnc; - }; - }; - }; -} else { - - [[1, 2, 3, 4, 5]] call _hideUnusedFnc; + // Hide the stats box _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, safezoneY + 1.8 * GRID_H, - 47 * GRID_W, - 11 * GRID_H + 0, + 0 ]; _statsBoxCtrl ctrlCommit 0; + // Move action display + private _ctrl = _display displayCtrl IDC_actionsBox; + private _pos = ctrlPosition _ctrl; + _pos set [1, safezoneY + 1.8 * GRID_H]; + _ctrl ctrlSetPosition _pos; + _ctrl ctrlCommit 0; + { _x ctrlSetFade 1; _x ctrlCommit 0; @@ -242,3 +75,187 @@ if !(isNil "_itemCfg") then { _statsCurrentPageCtrl ]; }; + +// If nothing is chosen, hide stats +if (isNull _itemCfg) exitWith { + call _fnc_hideEverything +}; + +private _fnc_handleStats = { + params ["_statsIndex", "_leftPanel"]; + + private _statsPanel = [GVAR(statsListRightPanel), GVAR(statsListLeftPanel)] select _leftPanel; + + // Get all viable stats for this tab + private _statsTab = _statsPanel select _statsIndex select { + _x params ["", "_configEntry", "", "", "_statements"]; + _statements params ["", "", ["_condition", {true}, [{}]]]; + + ([_configEntry, _itemCfg] call _condition) + }; + + // If there are no stats to show (unlikely), just hide everything + if (_statsTab isEqualTo []) exitWith { + call _fnc_hideEverything + }; + + GVAR(currentStatPage) = GVAR(currentStatPage) min floor ((count _statsTab) / 5); + private _statsToDisplay = _statsTab select [GVAR(currentStatPage) * 5, 5]; + + + private _statsCount = 0; + + private _statsTitleCtrl = controlNull; + private _statsTitleIDC = -1; + private _statsBackgroundCtrl = controlNull; + private _statsBarCtrl = controlNull; + private _statsTextCtrl = controlNull; + private _textStatementResult = ""; + + { + _x params ["", "_configEntry", "_title", "_bools", "_statements"]; + _bools params ["_showBar", "_showText"]; + _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; + + _statsTitleCtrl = _display displayCtrl (IDC_statsTitle1 + _forEachIndex * 4); + _statsTitleIDC = ctrlIDC _statsTitleCtrl; + _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); + _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); + _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); + + _statsCount = _statsCount + 1; + _statsTitleCtrl ctrlSetText _title; + _statsTitleCtrl ctrlSetFade 0; + + // Handle bars + if (_showBar) then { + _statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement); + _statsBackgroundCtrl ctrlSetFade 0; + _statsBarCtrl ctrlSetFade 0; + } else { + _statsBackgroundCtrl ctrlSetFade 1; + _statsBarCtrl ctrlSetFade 1; + }; + + // Handle text entries + if (_showText) then { + _textStatementResult = [_configEntry, _itemCfg] call _textStatement; + + if !(_textStatementResult isEqualtype "") then { + _textStatementResult = str _textStatementResult; + }; + + _statsTextCtrl ctrlSetText _textStatementResult; + _statsTextCtrl ctrlSetTextColor ([[1, 1, 1, 1], [0, 0, 0, 1]] select (_showBar)); + _statsTextCtrl ctrlSetFade 0; + } else { + _statsTextCtrl ctrlSetFade 1; + }; + + { + _x ctrlCommit 0; + } forEach [ + _statsTitleCtrl, + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + } forEach _statsToDisplay; + + + // Resize the window + (5 - _statsCount) call _fnc_hideUnused; + private _height = 10 * _statsCount + 5; + _statsBoxCtrl ctrlSetPosition [ + (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, + safezoneY + 1.8 * GRID_H, + 47 * GRID_W, + _height * GRID_H + ]; + _statsBoxCtrl ctrlCommit 0; + + // Move the actions box + private _ctrl = _display displayCtrl IDC_actionsBox; + private _pos = ctrlPosition _ctrl; + _pos set [1, safezoneY + (_height + 3.6) * GRID_H]; + _ctrl ctrlSetPosition _pos; + _ctrl ctrlCommit 0; + + + GVAR(statsInfo) = [_leftPanel, _control, _curSel, _itemCfg]; + + // Toggle page buttons + _statsPreviousPageCtrl ctrlEnable (GVAR(currentStatPage) > 0); + _statsNextPageCtrl ctrlEnable ((GVAR(currentStatPage) + 1) * 5 < count _statsTab); + _statsCurrentPageCtrl ctrlSetText ([LLSTRING(page), str (GVAR(currentStatPage) + 1)] joinString " "); + + { + _x ctrlSetFade 0; + _x ctrlCommit 0; + } forEach [ + _statsPreviousPageCtrl, + _statsNextPageCtrl, + _statsCurrentPageCtrl + ]; +}; + +// Check if in left or right panel +if (ctrlIDC _control == IDC_leftTabContent) then { + // Faces, voices and insigna do not have stats + if ([IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia] find GVAR(currentLeftPanel) > -1) then { + call _fnc_hideEverything; + } else { + [[ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch + ] find GVAR(currentLeftPanel), true] call _fnc_handleStats; + }; +} else { + switch (GVAR(currentRightPanel)) do { + case IDC_buttonOptic: { + [0, false] call _fnc_handleStats; + }; + case IDC_buttonItemAcc: { + [1, false] call _fnc_handleStats; + }; + case IDC_buttonMuzzle: { + [2, false] call _fnc_handleStats; + }; + case IDC_buttonBipod: { + [3, false] call _fnc_handleStats; + }; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: { + [4, false] call _fnc_handleStats; + }; + case IDC_buttonThrow: { + [5, false] call _fnc_handleStats; + }; + case IDC_buttonPut: { + [6, false] call _fnc_handleStats; + }; + case IDC_buttonMisc: { + [7, false] call _fnc_handleStats; + }; + default { + if (GVAR(currentRightPanel) in [RIGHT_PANEL_CUSTOM_BUTTONS]) then { + [7, false] call _fnc_handleStats; + }; + }; + }; +}; diff --git a/addons/arsenal/functions/fnc_initBox.sqf b/addons/arsenal/functions/fnc_initBox.sqf index 1343a20f63..8651d25db8 100644 --- a/addons/arsenal/functions/fnc_initBox.sqf +++ b/addons/arsenal/functions/fnc_initBox.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Initialize a box / object for arsenal. * * Arguments: * 0: Target - * 1: Items or - * 2: Initialize globally + * 1: Items + * 2: Initialize globally (default: true) * * Return Value: * None @@ -22,40 +22,39 @@ params [["_object", objNull, [objNull]], ["_items", true, [[], true]], ["_global if (isNull _object) exitWith {}; -if (isNil QGVAR(EHIDArray)) then { - GVAR(EHIDArray) = []; -}; +if (_global && {isMultiplayer} && {isNil {_object getVariable QGVAR(initBoxJIP)}}) then { + private _id = [QGVAR(initBox), [_object, _items, false]] call CBA_fnc_globalEventJIP; -if (_global && {isMultiplayer} && {{_object in _x} count GVAR(EHIDArray) == 0}) then { + // Remove JIP EH if object is deleted + [_id, _object] call CBA_fnc_removeGlobalEventJIP; - private _ID = [QGVAR(initBox), [_object, _items, false]] call CBA_fnc_globalEventJIP; - [_ID, _object] call CBA_fnc_removeGlobalEventJIP; - - GVAR(EHIDArray) pushBack [_ID, _object]; - publicVariable QGVAR(EHIDArray); + // Save JIP ID + _object setVariable [QGVAR(initBoxJIP), _id, true]; } else { + // Only add interaction if there isn't one already present + if (((_object getVariable [QEGVAR(interact_menu,actions), []]) findIf {((_x select 0) select 0) == QGVAR(interaction)}) != -1) exitWith {}; - if ({(_x select 0) select 0 isEqualTo QGVAR(interaction)} count (_object getVariable [QEGVAR(interact_menu,actions), []]) == 0) then { + private _action = [ + QGVAR(interaction), + localize "STR_A3_Arsenal", + "", + { + params ["_target", "_player"]; - private _action = [ - QGVAR(interaction), - localize "STR_A3_Arsenal", - "", - { - params ["_target", "_player"]; + [_target, _player] call FUNC(openBox); + }, + { + params ["_target", "_player"]; - [_target, _player] call FUNC(openBox); - }, - { - params ["_target", "_player"]; - - [_player, _target] call EFUNC(common,canInteractWith) - }, - {}, - [] - ] call EFUNC(interact_menu,createAction); - [_object, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); + [_player, _target] call EFUNC(common,canInteractWith) + } + ] call EFUNC(interact_menu,createAction); + [_object, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); + // If items were set globally, do not add items locally + if (isNil {_object getVariable QGVAR(virtualItems)}) then { [_object, _items, false] call FUNC(addVirtualItems); }; + + [QGVAR(boxInitialized), [_object, _items]] call CBA_fnc_localEvent; }; diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf index 85a848c3bd..676783a8b5 100644 --- a/addons/arsenal/functions/fnc_itemInfo.sqf +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -1,13 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Update arsenal's info box. * * Arguments: * 0: Arsenal display * 1: Current panel control - * 2: Current panel selection + * 2: Current panel selection * 3: Item config entry * * Return Value: @@ -16,63 +17,60 @@ * Public: No */ -params ["_display", "_control", "_curSel" ,"_itemCfg"]; +params ["_display", "_control", "_curSel", "_itemCfg"]; private _ctrlInfo = _display displayCtrl IDC_infoBox; if (isClass _itemCfg) then { - _ctrlInfo ctrlSetFade 0; _ctrlInfo ctrlCommit FADE_DELAY; [QGVAR(displayStats), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; + [QGVAR(displayActions), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; // Name + author - private _ctrlInfoName = _display displayCtrl IDC_infoName; - _ctrlInfoName ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == 102)); - - private _ctrlInfoAuthor = _display displayctrl IDC_infoAuthor; - _ctrlInfoAuthor ctrlSetText ""; + (_display displayCtrl IDC_infoName) ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == CT_LISTNBOX)); private _itemAuthor = getText (_itemCfg >> "author"); - _ctrlInfoAuthor ctrlSetText ([localize "STR_AUTHOR_UNKNOWN", format [localize "STR_FORMAT_AUTHOR_SCRIPTED",_itemAuthor]] select (_itemAuthor != "")); + (_display displayctrl IDC_infoAuthor) ctrlSetText ([localize "STR_AUTHOR_UNKNOWN", format [localize "STR_FORMAT_AUTHOR_SCRIPTED", _itemAuthor]] select (_itemAuthor != "")); // DLC / mod icon private _ctrlDLC = _display displayctrl IDC_DLCIcon; private _ctrlDLCBackground = _display displayctrl IDC_DLCBackground; - private _dlc = _itemCfg call GETDLC; + private _dlc = _itemCfg call EFUNC(common,getAddon); + if (_dlc != "") then { + (modParams [_dlc, ["name", "logo", "logoOver"]]) params ["_name", "_logo", "_logoOver"]; - private _dlcParams = modParams [_dlc, ["name", "logo", "logoOver"]]; - _dlcParams params ["_name", "_logo", "_logoOver"]; - private _appId = getnumber (configfile >> "CfgMods" >> _dlc >> "appId"); + _ctrlDLC ctrlSetTooltip _name; + _ctrlDLC ctrlSetText _logo; + _ctrlDLCBackground ctrlSetFade 0; + _ctrlDLC ctrlSetFade 0; - _ctrlDLC ctrlsettooltip _name; - _ctrlDLC ctrlsettext _logo; - _ctrlDLCBackground ctrlsetfade 0; - _ctrlDLC ctrlsetfade 0; - if (_appId > 0) then { - _ctrlDLC ctrlseteventhandler ["mouseexit",format ["(_this select 0) ctrlsettext '%1';",_logo]]; - _ctrlDLC ctrlseteventhandler ["mouseenter",format ["(_this select 0) ctrlsettext '%1';",_logoOver]]; - _ctrlDLC ctrlseteventhandler [ - "buttonclick", - format ["uiNamespace setvariable ['RscDisplayDLCPreview_dlc','%1']; ctrlparent (_this select 0) createDisplay 'RscDisplayDLCPreview';", _dlc] + // If an item is from a DLC, set it so when you press the icon on the bottom right it opens the DLC page + if ((getNumber (configfile >> "CfgMods" >> _dlc >> "appId")) > 0) then { + _ctrlDLC ctrlSetEventHandler ["MouseExit", format ["(_this select 0) ctrlSetText '%1';", _logo]]; + _ctrlDLC ctrlSetEventHandler ["MouseEnter", format ["(_this select 0) ctrlSetText '%1';", _logoOver]]; + _ctrlDLC ctrlSetEventHandler [ + "ButtonClick", + format ["uiNamespace setVariable ['RscDisplayDLCPreview_dlc','%1']; ctrlParent (_this select 0) createDisplay 'RscDisplayDLCPreview';", _dlc] ]; } else { - _ctrlDLC ctrlRemoveAllEventHandlers "buttonclick"; - _ctrlDLC ctrlRemoveAllEventHandlers "mouseexit"; - _ctrlDLC ctrlRemoveAllEventHandlers "mouseenter"; + _ctrlDLC ctrlRemoveAllEventHandlers "MouseExit"; + _ctrlDLC ctrlRemoveAllEventHandlers "MouseEnter"; + _ctrlDLC ctrlRemoveAllEventHandlers "ButtonClick"; }; } else { - _ctrlDLC ctrlsetfade 1; - _ctrlDLCBackground ctrlsetfade 1; + _ctrlDLC ctrlSetFade 1; + _ctrlDLCBackground ctrlSetFade 1; }; - _ctrlDLC ctrlcommit 0; - _ctrlDLCBackground ctrlcommit 0; + _ctrlDLC ctrlCommit 0; + _ctrlDLCBackground ctrlCommit 0; } else { [QGVAR(displayStats), [_display, _control, -1, nil]] call CBA_fnc_localEvent; + [QGVAR(displayActions), [_display, _control, -1, nil]] call CBA_fnc_localEvent; _ctrlInfo ctrlSetFade 1; _ctrlInfo ctrlCommit FADE_DELAY; diff --git a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf index 220cb697f2..a8938e8c48 100644 --- a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf +++ b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -27,7 +27,6 @@ private _renameButtonCtrl = _display displayCtrl IDC_buttonRename; // Update UI visual elements if (GVAR(currentLoadoutsTab) != -1) then { - private _previousCtrlBackground = _display displayCtrl (GVAR(currentLoadoutsTab) - 1); _previousCtrlBackground ctrlSetBackgroundColor [0, 0, 0, 0.8]; _previousCtrlBackground ctrlCommit 0; @@ -45,26 +44,37 @@ _control ctrlSetTextColor [0, 0, 0, 1]; _control ctrlCommit 0; switch (ctrlIDC _control) do { + // Local loadouts case IDC_buttonMyLoadouts: { - _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabMyLoadoutsText)); + _centerBoxTitleCtrl ctrlSetText LLSTRING(tabMyLoadoutsText); + + if (call FUNC(canEditDefaultLoadout)) then { + _saveButtonCtrl ctrlSetTooltip format ["%1\n%2", LLSTRING(buttonSaveTooltip), LLSTRING(buttonSaveTooltip_shiftClick)]; + }; - if (is3den) then { _saveButtonCtrl ctrlSetTooltip format ["%1\n%2", localize LSTRING(buttonSaveTooltip), localize LSTRING(buttonSaveTooltip_shiftClick)]; }; _saveButtonCtrl ctrlEnable true; _saveButtonCtrl ctrlCommit 0; }; - + // Default loadouts case IDC_buttonDefaultLoadouts: { - _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabDefaultLoadoutsText)); + _centerBoxTitleCtrl ctrlSetText LLSTRING(tabDefaultLoadoutsText); - if (is3den) then { _saveButtonCtrl ctrlSetTooltip localize LSTRING(buttonSaveTooltip); }; - _saveButtonCtrl ctrlEnable (is3DEN); + if (call FUNC(canEditDefaultLoadout)) then { + _saveButtonCtrl ctrlSetTooltip LLSTRING(buttonSaveTooltip); + }; + + _renameButtonCtrl ctrlEnable is3DEN; // no renaming mid-mission + _saveButtonCtrl ctrlEnable call FUNC(canEditDefaultLoadout); _saveButtonCtrl ctrlCommit 0; }; - + // Shared loadouts case IDC_buttonSharedLoadouts: { - _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabSharedLoadoutsText)); + _centerBoxTitleCtrl ctrlSetText LLSTRING(tabSharedLoadoutsText); + + if (call FUNC(canEditDefaultLoadout)) then { + _saveButtonCtrl ctrlSetTooltip LLSTRING(buttonSaveTooltip); + }; - if (is3den) then { _saveButtonCtrl ctrlSetTooltip localize LSTRING(buttonSaveTooltip); }; _saveButtonCtrl ctrlEnable false; _saveButtonCtrl ctrlCommit 0; }; @@ -73,8 +83,9 @@ switch (ctrlIDC _control) do { { _x ctrlEnable false; _x ctrlCommit 0; -} foreach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; +} forEach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; +// Save new tab as current tab GVAR(currentLoadoutsTab) = ctrlIDC _control; [QGVAR(loadoutsTabChanged), [_display, _control]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_message.sqf b/addons/arsenal/functions/fnc_message.sqf index 8fbd48748f..b20689f6b9 100644 --- a/addons/arsenal/functions/fnc_message.sqf +++ b/addons/arsenal/functions/fnc_message.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -19,36 +19,38 @@ params ["_display", "_message"]; private _messageBoxCtrl = _display displayCtrl IDC_message; private _handle = _messageBoxCtrl getVariable QGVAR(messageBoxHandle); -if !(isNil "_handle") then { +// Stop previous message being displayed +if (!isNil "_handle") then { terminate _handle; }; _handle = [_display, _messageBoxCtrl, time + 5, _message, FADE_DELAY] spawn { disableSerialization; - _this params ["_display", "_control", "_timer", "_message", "_delay"]; + params ["_display", "_control", "_timer", "_message", "_delay"]; + + // Refresh message box, in case previous message box is still shown + _control ctrlSetText _message; + _control ctrlSetFade 1; + _control ctrlCommit 0; + + _control ctrlSetFade 0; + _control ctrlCommit _delay; while {_timer >= time} do { - switch true do { - case (_display isEqualTo displayNull): { - terminate _thisScript; - }; - - case (round (_timer - time) == 5): { - _control ctrlSetText _message; - _control ctrlSetFade 1; - _control ctrlCommit 0; - - _control ctrlSetFade 0; - _control ctrlCommit _delay; - }; + // If the display has been closed, quit + if (isNull _display) then { + terminate _thisScript; }; uiSleep 1; }; + // Hide message box and finish _control ctrlSetFade 1; _control ctrlCommit _delay; + terminate _thisScript; }; + _messageBoxCtrl setVariable [QGVAR(messageBoxHandle), _handle]; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 554947df85..6803d2d5de 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -1,10 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * onUnLoad EH for arsenal. * * Arguments: - * None + * 0: Not used + * 1: Args + * - 0: Not used + * - 1: Exit code * * Return Value: * None @@ -14,13 +17,10 @@ (_this select 1) params ["", "_exitCode"]; -private _cameraData = [getposAtl GVAR(camera), (getposAtl GVAR(camera)) vectorFromTo (getposAtl GVAR(cameraHelper))]; - [QGVAR(displayClosed), []] call CBA_fnc_localEvent; -removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; +removeMissionEventHandler ["Draw3D", GVAR(camPosUpdateHandle)]; if (is3DEN) then { - private _centerOriginParent = objectParent GVAR(centerOrigin); if !(isNull _centerOriginParent) then { @@ -31,11 +31,14 @@ if (is3DEN) then { // Apply the loadout from the dummy to all selected units if (_exitCode == 1) then { - { - _x setUnitLoadout (getUnitLoadout GVAR(center)); - } foreach (get3DENSelected "object"); + private _extendedLoadout = GVAR(center) call CBA_fnc_getLoadout; + private _objects = get3DENSelected "object"; - save3DENInventory (get3DENSelected "object"); + { + [_x, _extendedLoadout] call CBA_fnc_setLoadout; + } forEach _objects; + + save3DENInventory _objects; }; deleteVehicle GVAR(light); @@ -44,22 +47,14 @@ if (is3DEN) then { GVAR(centerOrigin) = nil; GVAR(light) = nil; - get3DENCamera cameraEffect ["internal","back"]; - ["ShowInterface",true] call bis_fnc_3DENInterface; - GVAR(visionMode) call bis_fnc_3DENVisionMode; + get3DENCamera cameraEffect ["Internal", "BACK"]; + ["ShowInterface", true] call BIS_fnc_3DENInterface; + GVAR(visionMode) call BIS_fnc_3DENVisionMode; } else { - // Select correct weapon - switch GVAR(selectedWeaponType) do { - case 0: {GVAR(center) selectWeapon primaryWeapon GVAR(center);}; - case 1: {GVAR(center) selectWeapon secondaryWeapon GVAR(center);}; - case 2: {GVAR(center) selectWeapon handgunWeapon GVAR(center);}; - }; - - if (!(isnull curatorCamera) && {ACE_player == player}) then { - curatorcamera cameraEffect ["internal","back"]; + if (!isNull curatorCamera && {ACE_player == player}) then { + curatorCamera cameraEffect ["Internal", "BACK"]; } else { - GVAR(camera) cameraEffect ["terminate","back"]; - ACE_player switchCamera GVAR(cameraView); + GVAR(camera) cameraEffect ["Terminate", "BACK"]; }; }; @@ -71,42 +66,68 @@ if (!isNil QGVAR(moduleUsed)) then { objNull remoteControl GVAR(center); }; -if (isMultiplayer) then { +ACE_player switchCamera GVAR(cameraView); - [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(center) + "_face"] call CBA_fnc_globalEventJIP; - [QGVAR(center) + "_face", GVAR(center)] call CBA_fnc_removeGlobalEventJIP; +// Restore curator camera state +if (!isNull curatorCamera) then { + GVAR(curatorCameraData) params ["_position", "_dirAndUp"]; - [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(center) + "_voice"] call CBA_fnc_globalEventJIP; - [QGVAR(center) + "_voice", GVAR(center)] call CBA_fnc_removeGlobalEventJIP; + curatorCamera setPosASL _position; + curatorCamera setVectorDirAndUp _dirAndUp; }; +// Make face and voice selection JIP compatible; 3DEN doesn't need this though +if (isMultiplayer && {!is3DEN}) then { + private _id = [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(centerFace_) + hashValue GVAR(center)] call CBA_fnc_globalEventJIP; + [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; + + _id = [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(centerVoice_) + hashValue GVAR(center)] call CBA_fnc_globalEventJIP; + [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; +}; + +GVAR(currentBox) = objNull; + GVAR(camera) = nil; GVAR(cameraHelper) = nil; +GVAR(curatorCameraData) = nil; + GVAR(mouseButtonState) = nil; GVAR(currentLeftPanel) = nil; GVAR(currentRightPanel) = nil; GVAR(leftSearchbarFocus) = nil; GVAR(rightSearchbarFocus) = nil; +GVAR(liveUpdateSearch) = nil; GVAR(shiftState) = nil; GVAR(leftTabFocus) = nil; GVAR(rightTabFocus) = nil; GVAR(rightTabLnBFocus) = nil; +GVAR(ignoreFirstSortPanelCall) = nil; +GVAR(refreshing) = nil; GVAR(selectedWeaponType) = nil; GVAR(virtualItems) = nil; +GVAR(virtualItemsFlat) = nil; +GVAR(virtualItemsFlatAll) = nil; GVAR(currentItems) = nil; GVAR(currentFace) = nil; GVAR(currentVoice) = nil; GVAR(currentInsignia) = nil; GVAR(currentAction) = nil; -GVAR(showStats) = nil; -GVAR(statsPagesLeft) = nil; -GVAR(statsPagesRight) = nil; +GVAR(currentStatPage) = nil; GVAR(statsInfo) = nil; +GVAR(currentActionPage) = nil; +GVAR(actionsInfo) = nil; + +profileNamespace setVariable [QGVAR(favorites), GVAR(favorites)]; +GVAR(favoritesOnly) = nil; +GVAR(favorites) = nil; + GVAR(center) = nil; GVAR(centerNotPlayer) = nil; +GVAR(ignoredVirtualItems) = nil; + [QUOTE(ADDON), []] call EFUNC(common,showHud); diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index 9af448fd09..0f0a5817c6 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * onLoad EH for arsenal. * * Arguments: - * 0: Ignored + * 0: Not used * 1: Arguments - * 1.1: Arsenal display + * - 0: Arsenal display * * Return Value: * None @@ -23,7 +23,7 @@ if (isNil QGVAR(center)) then { GVAR(center) = player; }; -GVAR(mouseButtonState) = [[],[]]; +GVAR(mouseButtonState) = [[], []]; if (isNil QGVAR(sharedLoadoutsNamespace)) then { GVAR(sharedLoadoutsNamespace) = true call CBA_fnc_createNamespace; @@ -36,153 +36,59 @@ if (isNil {GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars)}) if (isNil QGVAR(defaultLoadoutsList)) then { if (is3DEN) then { - GVAR(defaultLoadoutsList) = (QGVAR(DummyCategory) get3DENMissionAttribute QGVAR(DefaultLoadoutsListAttribute)); + GVAR(defaultLoadoutsList) = QGVAR(DummyCategory) get3DENMissionAttribute QGVAR(DefaultLoadoutsListAttribute); } else { GVAR(defaultLoadoutsList) = []; }; }; -if (isNil QGVAR(virtualItems)) then { - GVAR(virtualItems) = [[[], [], []], [[], [], [], []], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]; +if (isNil {profileNamespace getVariable QGVAR(saved_loadouts)}) then { + profileNamespace setVariable [QGVAR(saved_loadouts), []]; }; -GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; +if (isNil QGVAR(virtualItems)) then { + private _virtualItems = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; + + _virtualItems = createHashMapFromArray _virtualItems; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItems set [_index, createHashMap]; + }; + + GVAR(virtualItems) = _virtualItems; + + // Flatten out hashmaps for easy checking later + call FUNC(updateVirtualItemsFlat); +}; + +// Includes items not in the arsenal but equipped on player +GVAR(virtualItemsFlatAll) = +GVAR(virtualItemsFlat); GVAR(currentFace) = face GVAR(center); -GVAR(currentVoice) = speaker GVAR(center); -GVAR(currentInsignia) = GVAR(center) param [0, objNull, [objNull]] getVariable ["BIS_fnc_setUnitInsignia_class", ""]; +GVAR(currentVoice) = (speaker GVAR(center)) call EFUNC(common,getConfigName); +GVAR(currentInsignia) = GVAR(center) call BIS_fnc_getUnitInsignia; GVAR(currentAction) = "Stand"; GVAR(shiftState) = false; -GVAR(showStats) = true; -GVAR(statsPagesLeft) = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; -GVAR(statsPagesRight) = [0, 0, 0, 0, 0, 0, 0, 0]; -GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; +GVAR(currentStatPage) = 0; +GVAR(statsInfo) = [true, controlNull, nil, nil]; -// Add the items the player has to virtualItems -for "_index" from 0 to 10 do { - switch (_index) do { - // primary, secondary, handgun weapons - case 0: { - private _array = LIST_DEFAULTS select _index; +GVAR(currentActionPage) = 0; +GVAR(actionsInfo) = [controlNull, nil, nil]; - if !((_array select 0) isEqualTo "") then { - ((GVAR(virtualItems) select _index) select 0) pushBackUnique (_array select 0); - }; +// Update current item list +call FUNC(updateCurrentItemsList); - if !((_array select 1) isEqualTo "") then { - ((GVAR(virtualItems) select _index) select 1) pushBackUnique (_array select 1); - }; +// Setup favorites button text and switch to default mode defined by setting +[_display, _display displayCtrl IDC_buttonFavorites] call FUNC(buttonFavorites); +GVAR(favorites) = profileNamespace getVariable [QGVAR(favorites), createHashMap]; - if !((_array select 2) isEqualTo "") then { - ((GVAR(virtualItems) select _index) select 2) pushBackUnique (_array select 2); - }; - }; - - // Accs for the weapons above - case 1: { - private _array = LIST_DEFAULTS select _index; - _array params ["_accsArray", "_magsArray"]; - - { - private _subIndex = _forEachIndex; - - { - if (_x != "") then { - (GVAR(virtualItems) select _index) select ([2, 1, 0, 3] select _forEachIndex) pushBackUnique _x; - }; - } forEach _x; - } forEach _accsArray; - - { - if !(_x isEqualTo []) then { - - if (_x select 0 != "") then { - (GVAR(virtualItems) select 2) pushBackUnique (_x select 0); - }; - - if (count _x > 1 && {_x select 1 != ""}) then { - (GVAR(virtualItems) select 2) pushBackUnique (_x select 1); - }; - }; - } forEach _magsArray; - }; - - // Inventory items - case 2: { - call FUNC(updateUniqueItemsList); - }; - - // The rest - default { - private _array = (LIST_DEFAULTS select _index) select {!(_x isEqualTo "")}; - if !(_array isEqualTo []) then { - {(GVAR(virtualItems) select _index) pushBackUnique _x} forEach _array; - }; - }; - }; -}; - -// Fill current items -for "_index" from 0 to 15 do { - switch (_index) do { - case 0; - case 1; - case 2:{ - GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; - }; - case 3; - case 4; - case 5; - case 6; - case 7; - case 8; - case 9: { - GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; - - }; - case 10: { - {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); - }; - case 11: { - {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); - }; - case 12: { - {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); - }; - case 13: { - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; - }; - case 14: { - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; - }; - case 15: { - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; - }; - }; -}; - -{ - private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); - - if (_simulationType != "NVGoggles") then { - if (_simulationType == "ItemGps" || _simulationType == "Weapon") then { - GVAR(currentItems) set [14, _x]; - } else { - - private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch"] find (tolower _simulationType)); - GVAR(currentItems) set [_index, _x]; - }; - }; -} forEach (assignedItems GVAR(center)); - -GVAR(currentWeaponType) = switch true do { - case (currentWeapon GVAR(center) == GVAR(currentItems) select 0): {0}; - case (currentWeapon GVAR(center) == GVAR(currentItems) select 1): {1}; - case (currentWeapon GVAR(center) == GVAR(currentItems) select 2): {2}; - default {-1}; -}; +// This takes care of unique inventory items and unique equipment (arsenal doesn't have items/equipment whitelisted) +call FUNC(updateUniqueItemsList); [QGVAR(displayOpened), [_display]] call CBA_fnc_localEvent; @@ -222,7 +128,15 @@ _statsBoxCtrl ctrlSetPosition [ _statsBoxCtrl ctrlEnable false; _statsBoxCtrl ctrlCommit 0; -(_display displayCtrl IDC_statsButton) ctrlShow false; +// Handle actions +private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; +_actionsBoxCtrl ctrlSetPosition [ + (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, + safezoneY + 58.6 * GRID_H, + 47 * GRID_W, + 11 * GRID_H +]; +_actionsBoxCtrl ctrlCommit 0; // Disable import in MP if (isMultiplayer) then { @@ -233,7 +147,7 @@ if (isMultiplayer) then { }; //--------------- Camera prep -cutText ["","plain"]; +cutText ["", "PLAIN"]; showCommandingMenu ""; GVAR(cameraView) = cameraView; @@ -243,73 +157,71 @@ GVAR(center) switchCamera "internal"; private _mouseAreaCtrl = _display displayCtrl IDC_mouseArea; ctrlSetFocus _mouseAreaCtrl; +private _centerPos = position GVAR(center); + // 3DEN support, lifted from BIS_fnc_arsenal if (is3DEN) then { - GVAR(centerOrigin) = GVAR(center); GVAR(centerOrigin) hideObject true; private _centerOriginParent = objectParent GVAR(centerOrigin); + if !(isNull _centerOriginParent) then { _centerOriginParent hideObject true; }; - private _centerPos = position GVAR(centerOrigin); - - GVAR(center) = createAgent [typeOf GVAR(centerOrigin), position GVAR(centerOrigin), [], 0, "none"]; - GVAR(center) setPosAtl getPosAtl GVAR(centerOrigin); + GVAR(center) = createAgent [typeOf GVAR(centerOrigin), _centerPos, [], 0, "none"]; + GVAR(center) setPosATL getPosATL GVAR(centerOrigin); GVAR(center) setDir (getDir GVAR(centerOrigin)); GVAR(center) switchMove animationState GVAR(centerOrigin); - GVAR(center) switchAction "playerstand"; + GVAR(center) switchAction "playerStand"; GVAR(center) enableSimulation false; - GVAR(center) setUnitLoadout (getUnitLoadout GVAR(centerOrigin)); - GVAR(center) setFace GVAR(currentFace); - GVAR(center) setSpeaker GVAR(currentVoice); + [GVAR(center), GVAR(centerOrigin) call CBA_fnc_getLoadout] call CBA_fnc_setLoadout; //--- Create light for night editing (code based on BIS_fnc_3DENFlashlight) - private _intensity = 1; GVAR(light) = "#lightpoint" createVehicle _centerPos; - GVAR(light) setLightBrightness _intensity; - GVAR(light) setLightAmbient [1,1,1]; - GVAR(light) setLightColor [0,0,0]; - GVAR(light) lightAttachObject [GVAR(centerOrigin), [0, 0, -_intensity * 7]]; + GVAR(light) setLightBrightness 1; + GVAR(light) setLightAmbient [1, 1, 1]; + GVAR(light) setLightColor [0, 0, 0]; + GVAR(light) lightAttachObject [GVAR(centerOrigin), [0, 0, -7]]; //--- Use the same vision mode as in Eden - GVAR(visionMode)= -2 call bis_fnc_3DENVisionMode; - ["ShowInterface",false] spawn bis_fnc_3DENInterface; - if (get3denactionstate "togglemap" > 0) then {do3DENAction "togglemap";}; + GVAR(visionMode) = -2 call BIS_fnc_3DENVisionMode; + ["ShowInterface", false] spawn BIS_fnc_3DENInterface; + + if (get3DENActionState "toggleMap" > 0) then { + do3DENAction "toggleMap"; + }; + + private _ctrl = controlNull; { - private _ctrl = _display displayctrl _x; + _ctrl = _display displayCtrl _x; + _ctrl ctrlEnable false; _ctrl ctrlSetFade 0.6; _ctrl ctrlCommit 0; - } forEach [ - IDC_buttonFace, - IDC_buttonVoice, - IDC_buttonInsigna - ]; + } forEach [IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia]; - _buttonCloseCtrl = _display displayCtrl IDC_menuBarClose; + private _buttonCloseCtrl = _display displayCtrl IDC_menuBarClose; _buttonCloseCtrl ctrlSetText (localize "str_ui_debug_but_apply"); } else { - GVAR(centerNotPlayer) = (GVAR(center) != player); + GVAR(centerNotPlayer) = GVAR(center) != player; if (currentVisionMode ACE_Player == 1) then { GVAR(center) action ["NVGogglesOff", GVAR(center)]; }; + private _ctrl = controlNull; + { - private _ctrl = _display displayCtrl _x; + _ctrl = _display displayCtrl _x; + _ctrl ctrlEnable GVAR(enableIdentityTabs); _ctrl ctrlSetFade ([0.6, 0] select GVAR(enableIdentityTabs)); _ctrl ctrlCommit 0; - } forEach [ - IDC_buttonFace, - IDC_buttonVoice, - IDC_buttonInsigna - ]; + } forEach [IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia]; }; //--------------- Prepare the left panel @@ -317,9 +229,12 @@ GVAR(currentLeftPanel) = nil; GVAR(currentRightPanel) = nil; GVAR(leftSearchbarFocus) = false; GVAR(rightSearchbarFocus) = false; +GVAR(liveUpdateSearch) = false; GVAR(leftTabFocus) = false; GVAR(rightTabFocus) = false; GVAR(rightTabLnBFocus) = false; +GVAR(ignoreFirstSortPanelCall) = false; +GVAR(refreshing) = false; { private _panel = _display displayCtrl _x; @@ -327,25 +242,40 @@ GVAR(rightTabLnBFocus) = false; _panel ctrlCommit 0; } forEach [IDC_leftTabContent, IDC_rightTabContent, IDC_rightTabContentListnBox]; -[_display, _display displayCtrl IDC_buttonPrimaryWeapon] call FUNC(fillLeftPanel); +// Open left panel for current weapon, do some math +GVAR(selectedWeaponType) = [primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] find (currentWeapon GVAR(center)); +if (GVAR(selectedWeaponType) == -1) then { + GVAR(selectedWeaponType) = 0; // default to primary +}; + +private _leftPanelIDC = [IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun, IDC_buttonBinoculars] select GVAR(selectedWeaponType); + +[_display, _display displayCtrl _leftPanelIDC] call FUNC(fillLeftPanel); //--------------- Init camera if (isNil QGVAR(cameraPosition)) then { - GVAR(cameraPosition) = [5,0,0,[0,0,0.85]]; + GVAR(cameraPosition) = [5, 0, 0, [0, 0, 0.85]]; }; -GVAR(cameraHelper) = createAgent ["Logic", position GVAR(center) ,[] ,0 ,"none"]; +// Save curator camera state so camera position and direction are not modified while using arsenal +private _curatorCamera = curatorCamera; + +if (!isNull _curatorCamera) then { + GVAR(curatorCameraData) = [getPosASL _curatorCamera, [vectorDir _curatorCamera, vectorUp _curatorCamera]]; +}; + +GVAR(cameraHelper) = createAgent ["Logic", _centerPos, [], 0, "none"]; GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; -GVAR(camera) = "camera" camCreate position GVAR(center); -GVAR(camera) cameraEffect ["internal","back"]; -GVAR(camera) camPrepareFocus [-1,-1]; +GVAR(camera) = "camera" camCreate _centerPos; +GVAR(camera) cameraEffect ["internal", "back"]; +GVAR(camera) camPrepareFocus [-1, -1]; GVAR(camera) camPrepareFov 0.35; GVAR(camera) camCommitPrepared 0; showCinemaBorder false; -["#(argb,8,8,3)color(0,0,0,1)",false,nil,0,[0,0.5]] call bis_fnc_textTiles; +["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0, [0, 0.5]] call BIS_fnc_textTiles; //--------------- Reset camera pos -[nil, [controlNull,0,0]] call FUNC(handleMouse); -GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D",{ [] call FUNC(updateCamPos) }]; +[nil, [controlNull, 0, 0]] call FUNC(handleMouse); +GVAR(camPosUpdateHandle) = addMissionEventHandler ["Draw3D", {call FUNC(updateCamPos)}]; diff --git a/addons/arsenal/functions/fnc_onKeyDown.sqf b/addons/arsenal/functions/fnc_onKeyDown.sqf index 0c265873eb..4d62075f78 100644 --- a/addons/arsenal/functions/fnc_onKeyDown.sqf +++ b/addons/arsenal/functions/fnc_onKeyDown.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles keyboard inputs in arsenal. * * Arguments: * 0: Arsenal display - * 1: Key being pressed + * 1: Key being pressed * 2: Shift state * 3: Ctrl state * 4: Alt state @@ -25,12 +25,14 @@ GVAR(shiftState) = _shiftState; private _return = true; private _loadoutsDisplay = findDisplay IDD_loadouts_display; -if !(_loadoutsDisplay isEqualTo displayNull) then { - if !(GVAR(loadoutsSearchbarFocus)) then { - switch true do { +// If in loadout screen +if (!isNull _loadoutsDisplay) then { + // If loadout search bar isn't focussed + if (!GVAR(loadoutsSearchbarFocus)) then { + switch (true) do { // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; + _display closeDisplay IDC_CANCEL; }; // Search field case (_keyPressed == DIK_F && {_ctrlState}): { @@ -38,48 +40,37 @@ if !(_loadoutsDisplay isEqualTo displayNull) then { }; }; } else { - switch true do { + // If loadout search bar is focussed + switch (true) do { + // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; - }; - case (_keyPressed == DIK_BACKSPACE): { - _return = false; + _display closeDisplay IDC_CANCEL; }; + // Search case (_keyPressed == DIK_NUMPADENTER); case (_keyPressed == DIK_RETURN): { [_loadoutsDisplay, _loadoutsDisplay displayCtrl IDC_loadoutsSearchbar] call FUNC(handleLoadoutsSearchBar); }; + case (_keyPressed == DIK_BACKSPACE); case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { _return = false; }; }; }; - switch true do { - case (_keyPressed == DIK_C && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_V && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_A && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_X && {_ctrlState}): { - _return = false; - }; + switch (true) do { + case (_keyPressed in [DIK_C, DIK_V, DIK_A, DIK_X] && {_ctrlState}); case (GVAR(loadoutsPanelFocus) && {_keyPressed in [DIK_UP, DIK_DOWN]}): { _return = false; }; }; } else { - + // If in arsenal and no search bar is selected if (!GVAR(leftSearchbarFocus) && {!GVAR(rightSearchbarFocus)}) then { - - switch true do { + switch (true) do { // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; + _display closeDisplay IDC_CANCEL; }; // Hide button case (_keyPressed == DIK_BACKSPACE): { @@ -88,7 +79,7 @@ if !(_loadoutsDisplay isEqualTo displayNull) then { // Export button / export classname case (_keyPressed == DIK_C && {_ctrlState}): { if (GVAR(leftTabFocus) || {GVAR(rightTabFocus)} || {GVAR(rightTabLnBFocus)}) then { - switch true do { + switch (true) do { case (GVAR(leftTabFocus)): { private _control = (_display displayCtrl IDC_leftTabContent); _control lbData (lbCurSel _control) @@ -99,14 +90,14 @@ if !(_loadoutsDisplay isEqualTo displayNull) then { }; case (GVAR(rightTabLnBFocus)): { private _control = (_display displayCtrl IDC_rightTabContentListnBox); - _control lnbData [(lnbCurSelRow _control), 0] + _control lnbData [lnbCurSelRow _control, 0] }; } params ["_className"]; "ace_clipboard" callExtension (_className + ";"); "ace_clipboard" callExtension "--COMPLETE--"; - [_display, localize LSTRING(exportedClassnameText)] call FUNC(message); + [_display, LLSTRING(exportedClassnameText)] call FUNC(message); } else { [_display] call FUNC(buttonExport); }; @@ -115,36 +106,37 @@ if !(_loadoutsDisplay isEqualTo displayNull) then { case (_keyPressed == DIK_V && {_ctrlState}): { [_display] call FUNC(buttonImport); }; - // Search fields + // Focus search case (_keyPressed == DIK_F && {_ctrlState}): { ctrlSetFocus (_display displayCtrl IDC_leftSearchbar); }; // Switch vision mode - case (_keyPressed in (actionkeys "nightvision")): { + case (_keyPressed in (actionKeys "nightvision")): { if (isNil QGVAR(visionMode)) then { GVAR(visionMode) = 0; }; + GVAR(visionMode) = (GVAR(visionMode) + 1) % 3; - switch GVAR(visionMode) do { - //--- Normal + switch (GVAR(visionMode)) do { + // Normal case 0: { - camusenvg false; - false setCamUseTi 0; + camUseNVG false; + false setCamUseTI 0; }; - //--- NVG + // NVG case 1: { - camusenvg true; - false setCamUseTi 0; + camUseNVG true; + false setCamUseTI 0; }; - //--- TI + // TI default { - camusenvg false; - true setCamUseTi 0; + camUseNVG false; + true setCamUseTI 0; }; }; - playsound ["RscDisplayCurator_visionMode",true]; + playSound ["RscDisplayCurator_visionMode", true]; }; // Panel up down case (_keyPressed in [DIK_UP, DIK_DOWN]): { @@ -155,43 +147,34 @@ if !(_loadoutsDisplay isEqualTo displayNull) then { // Right panel lnb + and - buttons case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { if (GVAR(rightTabLnBFocus)) then { - [_display, [1, 0] select (_keyPressed == DIK_LEFT)] call FUNC(buttonCargo); + [_display, parseNumber (_keyPressed != DIK_LEFT)] call FUNC(buttonCargo); }; }; }; } else { - switch true do { + // If in arsenal and a search bar is selected + switch (true) do { + // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; - }; - case (_keyPressed == DIK_BACKSPACE): { - _return = false; + _display closeDisplay IDC_CANCEL; }; + // Search case (_keyPressed == DIK_NUMPADENTER); case (_keyPressed == DIK_RETURN): { if (GVAR(leftSearchbarFocus)) then { [_display, _display displayCtrl IDC_leftSearchbar] call FUNC(handleSearchBar); - }; + }; + if (GVAR(rightSearchbarFocus)) then { [_display, _display displayCtrl IDC_rightSearchbar] call FUNC(handleSearchBar); }; }; - case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { + case (_keyPressed in [DIK_LEFT, DIK_RIGHT]); + case (_keyPressed == DIK_BACKSPACE); + case (_keyPressed in [DIK_C, DIK_V, DIK_A, DIK_X] && {_ctrlState}): { _return = false; }; - case (_keyPressed == DIK_C && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_V && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_A && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_X && {_ctrlState}): { - _return = false; - }; - // Search fields + // Focus search fields case (_keyPressed == DIK_F && {_ctrlState}): { if (GVAR(rightSearchbarFocus)) then { ctrlSetFocus (_display displayCtrl IDC_leftSearchbar); diff --git a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf index 1b25ad4945..d6605c3e27 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -14,15 +14,11 @@ */ 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; +private _arsenalDisplay = findDisplay IDD_ace_arsenal; +private _mouseBlockCtrl = _arsenalDisplay displayCtrl IDC_mouseBlock; _mouseBlockCtrl ctrlEnable false; _mouseBlockCtrl ctrlCommit 0; @@ -30,4 +26,4 @@ _mouseBlockCtrl ctrlCommit 0; [QGVAR(loadoutsDisplayClosed), []] call CBA_fnc_localEvent; -[_arsenalDisplay , _arsenalDisplay displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); +[_arsenalDisplay, _arsenalDisplay displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf index d22124359d..dea351546b 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe * onLoad EH for arsenal loadouts display. * * Arguments: - * 0: Ignored + * 0: Not used * 1: Arguments - * 1.1: Loadouts display + * - 0: Loadouts display * * Return Value: * None @@ -30,13 +30,11 @@ 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; +// If default loadouts are disabled, disable button if !(GVAR(allowDefaultLoadouts)) then { private _buttonDefaultLoadoutsCtrl = _display displayCtrl IDC_buttonDefaultLoadouts; _buttonDefaultLoadoutsCtrl ctrlEnable false; @@ -47,6 +45,7 @@ if !(GVAR(allowDefaultLoadouts)) then { _buttonDefaultLoadoutsBackgroundCtrl ctrlCommit 0; }; +// If shared loadouts are disabled or it's singleplayer, disable button if !(GVAR(allowSharedLoadouts) && {isMultiplayer}) then { private _buttonShareLoadoutsCtrl = _display displayCtrl IDC_buttonSharedLoadouts; _buttonShareLoadoutsCtrl ctrlEnable false; diff --git a/addons/arsenal/functions/fnc_onMouseButtonDown.sqf b/addons/arsenal/functions/fnc_onMouseButtonDown.sqf index 0cb2c856a4..02a90cd037 100644 --- a/addons/arsenal/functions/fnc_onMouseButtonDown.sqf +++ b/addons/arsenal/functions/fnc_onMouseButtonDown.sqf @@ -1,4 +1,21 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +/* + * Author: commy2 + * Handles mouse button press. + * + * Arguments: + * 0: Not used + * 1: Args + * - 0: Not used + * - 1: Mouse button + * - 2: Mouse X position + * - 3: Mouse Y position + * + * Return Value: + * None + * + * Public: No +*/ params ["", "_args"]; _args params ["", "_buttonPressed", "_xPos", "_yPos"]; diff --git a/addons/arsenal/functions/fnc_onMouseButtonUp.sqf b/addons/arsenal/functions/fnc_onMouseButtonUp.sqf index 53848a4f8e..7efc638b63 100644 --- a/addons/arsenal/functions/fnc_onMouseButtonUp.sqf +++ b/addons/arsenal/functions/fnc_onMouseButtonUp.sqf @@ -1,4 +1,19 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +/* + * Author: commy2 + * Handles mouse button release. + * + * Arguments: + * 0: Not used + * 1: Args + * - 0: Not used + * - 1: Mouse button + * + * Return Value: + * None + * + * Public: No +*/ params ["", "_args"]; _args params ["", "_buttonPressed"]; diff --git a/addons/arsenal/functions/fnc_onPanelDblClick.sqf b/addons/arsenal/functions/fnc_onPanelDblClick.sqf new file mode 100644 index 0000000000..07287d74ce --- /dev/null +++ b/addons/arsenal/functions/fnc_onPanelDblClick.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" +/* + * Author: LinkIsGrim + * Add or remove item(s) to favorites when LShift is pressed + * + * Arguments: + * 0: Left panel control + * 1: Left panel selection + * + * Return Value: + * None + * + * Public: No +*/ +params ["_control", "_curSel"]; + +if !(GVAR(shiftState)) exitWith {}; + +if (GVAR(currentLeftPanel) in [IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsigina]) exitWith {}; + +private _isLnB = (ctrlType _control) == CT_LISTNBOX; + +private _favorited = false; + +// Favorites/blacklist will always be lowercase to handle configCase changes +private _item = ""; +if (_isLnB) then { + _item = toLowerANSI (_control lnbData [_curSel, 0]); +} else { + _item = toLowerANSI (_control lbData _curSel); +}; + +if (_item in GVAR(favorites)) then { + GVAR(favorites) deleteAt _item; +} else { + GVAR(favorites) set [_item, nil]; + _favorited = true; +}; + +private _color = ([[1, 1, 1], GVAR(favoritesColor)] select _favorited) + [1]; + +if (_isLnB) then { + _control lnbSetColor [[_curSel, 1], _color]; + _control lnbSetColorRight [[_curSel, 1], _color]; +} else { + _control lbSetColor [_curSel, _color]; + _control lbSetSelectColor [_curSel, _color]; +}; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 2322853e1a..e25016b303 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles selection changes on the left panel. * * Arguments: * 0: Left panel control - * 1: Left panel selection + * 1: Left panel selection * * Return Value: * None @@ -18,409 +19,690 @@ params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; -private _ctrlIDC = ctrlIDC _control; private _display = ctrlParent _control; -private _item = [_control lnbData [_curSel, 0], _control lbData _curSel] select !(ctrlType _control == 102); +private _item = [_control lbData _curSel, _control lnbData [_curSel, 0]] select (ctrlType _control == CT_LISTNBOX); -private _weaponDefaultRightPanel = _display displayCtrl IDC_buttonOptic; -private _selectCorrectPanelWeapon = [_weaponDefaultRightPanel, _display displayCtrl GVAR(currentRightPanel)] select (!(isNil QGVAR(currentRightPanel)) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}); +// When having chosen a new category, see if the current right panel can be kept open, otherwise take default +private _currentRightPanel = _display displayCtrl GVAR(currentRightPanel); +private _selectCorrectPanelWeapon = [_display displayCtrl IDC_buttonOptic, _currentRightPanel] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}); +private _selectCorrectPanelContainer = [_display displayCtrl IDC_buttonMisc, _currentRightPanel] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ITEMS_IDCS]}); -private _containerDefaultRightPanel = _display displayCtrl IDC_buttonMisc; -private _selectCorrectPanelContainer = [_containerDefaultRightPanel, _display displayCtrl GVAR(currentRightPanel)] select (!(isNil QGVAR(currentRightPanel)) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ITEMS_IDCS]}); +// Remove all magazines from the current weapon that aren't compatible with the new weapon +private _fnc_clearCurrentWeaponMags = { + private _compatibleMagsCurrentWeapon = compatibleMagazines _currentWeapon; + + // If nothing was selected, remove all magazines from the current weapon + if (_item != "") then { + _compatibleMagsCurrentWeapon = _compatibleMagsCurrentWeapon - _compatibleMags; + }; -private _fnc_clearPreviousWepMags = { - private _compatibleMags = getArray (configfile >> "cfgweapons" >> _baseWeapon >> "magazines"); { GVAR(center) removeMagazines _x; - } foreach _compatibleMags; + } forEach _compatibleMagsCurrentWeapon; - GVAR(currentItems) set [15, uniformItems GVAR(center)]; - GVAR(currentItems) set [16, vestItems GVAR(center)]; - GVAR(currentItems) set [17, backpackItems GVAR(center)]; + // Update currentItems + private _loadout = getUnitLoadout GVAR(center); + + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, (_loadout select IDX_LOADOUT_UNIFORM) param [1, []]]; + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, (_loadout select IDX_LOADOUT_VEST) param [1, []]]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, (_loadout select IDX_LOADOUT_BACKPACK) param [1, []]]; }; +// Check which right panel has changed switch (GVAR(currentLeftPanel)) do { + // Primary weapon + case IDC_buttonPrimaryWeapon: { + private _currentWeapon = GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON; - case IDC_buttonPrimaryWeapon : { - private _baseWeapon = ((GVAR(currentItems) select 0) call bis_fnc_baseWeapon); - + // If nothing selected, remove primary weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (primaryWeapon GVAR(center)); - GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; - GVAR(currentItems) set [0, _item]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON, ""]; TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 0) != _item && {_baseWeapon != _item}) then { - call _fnc_clearPreviousWepMags; + // Check if a new primary weapon was selected + if (_item != _currentWeapon) then { + // Get magazines that are compatible with the new weapon + private _compatibleMags = compatibleMagazines _item; - private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; - GVAR(center) addWeapon _item; - GVAR(center) addWeaponItem [_item, [(getArray (configfile >> "cfgweapons" >> _item >> "magazines")) select 0]]; + // Remove all magazines from the current weapon that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = primaryWeaponItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + { + if !(_x in GVAR(virtualItemsFlat)) then { + GVAR(center) removePrimaryWeaponItem _x; + }; + } forEach _linkedItems; + }; + + // Add old attachments and magazines back if they are compatible { - if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { - GVAR(center) addPrimaryWeaponItem _x; + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; }; - } foreach (GVAR(currentItems) select 18); + } forEach (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS); - private _primaryMags = primaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; - GVAR(currentItems) set [0, _item]; + (getUnitLoadout GVAR(center) select IDX_LOADOUT_PRIMARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; + }; + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON, _item]; }; TOGGLE_RIGHT_PANEL_WEAPON - [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelWeapon, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelWeapon}] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); }; + // Handgun weapon + case IDC_buttonHandgun: { + private _currentWeapon = GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON; - case IDC_buttonHandgun : { - private _baseWeapon = ((GVAR(currentItems) select 2) call bis_fnc_baseWeapon); - + // If nothing selected, remove handgun weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (handgunWeapon GVAR(center)); - GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; - GVAR(currentItems) set [2, _item]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON, ""]; TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 2) != _item && {_baseWeapon != _item}) then { - call _fnc_clearPreviousWepMags; + // Check if a new handgun weapon was selected + if (_item != _currentWeapon) then { + // Get magazines that are compatible with the new weapon + private _compatibleMags = compatibleMagazines _item; - private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; - GVAR(center) addWeapon _item; - GVAR(center) addWeaponItem [_item, [(getArray (configfile >> "cfgweapons" >> _item >> "magazines")) select 0]]; + // Remove all magazines from the current weapon that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = handgunItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + { + if !(_x in GVAR(virtualItemsFlat)) then { + GVAR(center) removeHandgunItem _x; + }; + } forEach _linkedItems; + }; + + // Add old attachments and magazines back if they are compatible { - if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { - GVAR(center) addHandgunItem _x; - }; - } foreach (GVAR(currentItems) select 20); - private _handgunMags = handgunMagazine GVAR(center); - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; - GVAR(currentItems) set [2, _item]; + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; + }; + } forEach (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS); + + (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; + }; + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON, _item]; }; TOGGLE_RIGHT_PANEL_WEAPON - [_display, [_selectCorrectPanelWeapon, _weaponDefaultRightPanel] select (GVAR(currentRightPanel) == IDC_buttonCurrentMag2)] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelWeapon, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelWeapon}] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); }; + // Secondary weapon + case IDC_buttonSecondaryWeapon: { + private _currentWeapon = GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON; + private _isDisposable = _item in (uiNamespace getVariable QGVAR(CBAdisposableLaunchers)); - case IDC_buttonSecondaryWeapon : { - private _baseWeapon = ((GVAR(currentItems) select 1) call bis_fnc_baseWeapon); - + // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (secondaryWeapon GVAR(center)); - GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; - GVAR(currentItems) set [1, _item]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON, ""]; + TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 1) != _item && {_baseWeapon != _item}) then { - call _fnc_clearPreviousWepMags; + // Check if a new secondary weapon was selected + if (_item != _currentWeapon) then { + // Get magazines that are compatible with the new weapon + private _compatibleMags = compatibleMagazines _item; - private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; - GVAR(center) addWeapon _item; - GVAR(center) addWeaponItem [_item, [(getArray (configfile >> "cfgweapons" >> _item >> "magazines")) select 0]]; + // Remove all magazines from the current weapon that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = secondaryWeaponItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + { + if !(_x in GVAR(virtualItemsFlat)) then { + GVAR(center) removeSecondaryWeaponItem _x; + }; + } forEach _linkedItems; + }; + + // Add old attachments and magazines back if they are compatible { - if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { - GVAR(center) addSecondaryWeaponItem _x; + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; }; - } foreach (GVAR(currentItems) select 19); + } forEach (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS); - private _secondaryMags = secondaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; - GVAR(currentItems) set [1, _item]; + (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; + }; + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON, _item]; }; TOGGLE_RIGHT_PANEL_WEAPON - [_display, [_selectCorrectPanelWeapon, _weaponDefaultRightPanel] select (GVAR(currentRightPanel) == IDC_buttonCurrentMag2)] call FUNC(fillRightPanel); + + // If item is a disposable launcher, delay a bit to show new compatible items + if (_isDisposable) then { + [{ + _this call FUNC(fillRightPanel); + }, [_display, _selectCorrectPanelWeapon]] call CBA_fnc_execNextFrame; + } else { + [_display, _selectCorrectPanelWeapon, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelWeapon}] call FUNC(fillRightPanel); + }; }; - call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + // If item is a disposable launcher, delay a bit to show new compatible items + if (_isDisposable) then { + [{ + // Make unit switch to new item + call FUNC(showItem); + + // Display new items's info on the bottom right + _this call FUNC(itemInfo); + }, [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item]] call CBA_fnc_execNextFrame; + } else { + // Make unit switch to new item + call FUNC(showItem); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; }; - - case IDC_buttonHeadgear : { - + // Headgear + case IDC_buttonHeadgear: { if (_item == "") then { removeHeadgear GVAR(center); - GVAR(currentItems) set [3, _item]; + GVAR(currentItems) set [IDX_CURR_HEADGEAR, ""]; } else { - if ((GVAR(currentItems) select 3) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_HEADGEAR) != _item) then { GVAR(center) addHeadgear _item; - GVAR(currentItems) set [3, _item]; + GVAR(currentItems) set [IDX_CURR_HEADGEAR, _item]; }; }; + + // Make unit switch to new item call FUNC(showItem); TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); }; - - case IDC_buttonUniform : { + // Uniform + case IDC_buttonUniform: { if (_item == "") then { + removeUniform GVAR(center); + + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, []]; + GVAR(currentItems) set [IDX_CURR_UNIFORM, ""]; - removeuniform GVAR(center); - GVAR(currentItems) set [15, []]; - GVAR(currentItems) set [4, _item]; TOGGLE_RIGHT_PANEL_HIDE } else { + if ((GVAR(currentItems) select IDX_CURR_UNIFORM) != _item) then { + // Get the unit's current loadout and just change the container + private _loadout = getUnitLoadout GVAR(center); + _loadout set [IDX_LOADOUT_UNIFORM, [_item, GVAR(currentItems) select IDX_CURR_UNIFORM_ITEMS]]; + GVAR(center) setUnitLoadout _loadout; - if ((GVAR(currentItems) select 4) != _item) then { - GVAR(center) forceAddUniform _item; + private _uniformItems = uniformItems GVAR(center); + private _index = count _uniformItems - 1; - while {count uniformItems GVAR(center) > 0} do { - GVAR(center) removeItemFromUniform (uniformItems GVAR(center) select 0); - }; //--- Remove default config contents + // Remove any items that can't fit in the container (this prevents overloading) + while {loadUniform GVAR(center) > 1 && {_index >= 0}} do { + GVAR(center) removeItemFromUniform (_uniformItems select _index); + DEC(_index); + }; - {GVAR(center) addItemtoUniform _x} foreach (GVAR(currentItems) select 15); - GVAR(currentItems) set [4, _item]; + GVAR(currentItems) set [IDX_CURR_UNIFORM, _item]; - [GVAR(center), ""] call bis_fnc_setUnitInsignia; - [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER - [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelContainer, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelContainer}] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Vest case IDC_buttonVest: { if (_item == "") then { - removeVest GVAR(center); - GVAR(currentItems) set [16, []]; - GVAR(currentItems) set [5, _item]; + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, []]; + GVAR(currentItems) set [IDX_CURR_VEST, ""]; + TOGGLE_RIGHT_PANEL_HIDE } else { + if ((GVAR(currentItems) select IDX_CURR_VEST) != _item) then { + // Get the unit's current loadout and just change the container + private _loadout = getUnitLoadout GVAR(center); + _loadout set [IDX_LOADOUT_VEST, [_item, GVAR(currentItems) select IDX_CURR_VEST_ITEMS]]; + GVAR(center) setUnitLoadout _loadout; - if ((GVAR(currentItems) select 5) != _item) then { - GVAR(center) addVest _item; - while {count vestItems GVAR(center) > 0} do { - GVAR(center) removeItemFromVest (VestItems GVAR(center) select 0); - }; //--- Remove default config contents - {GVAR(center) addItemToVest _x} foreach (GVAR(currentItems) select 16); + private _vestItems = vestItems GVAR(center); + private _index = count _vestItems - 1; - GVAR(currentItems) set [5, _item]; + // Remove any items that can't fit in the container (this prevents overloading) + while {loadVest GVAR(center) > 1 && {_index >= 0}} do { + GVAR(center) removeItemFromVest (_vestItems select _index); + DEC(_index); + }; + + GVAR(currentItems) set [IDX_CURR_VEST, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER - [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelContainer, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelContainer}] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonBackpack : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Backpack + case IDC_buttonBackpack: { if (_item == "") then { - removeBackpack GVAR(center); - GVAR(currentItems) set [17, []]; - GVAR(currentItems) set [6, _item]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, []]; + GVAR(currentItems) set [IDX_CURR_BACKPACK, ""]; + TOGGLE_RIGHT_PANEL_HIDE } else { + if ((GVAR(currentItems) select IDX_CURR_BACKPACK) != _item) then { + // Get the unit's current loadout and just change the container + private _loadout = getUnitLoadout GVAR(center); + _loadout set [IDX_LOADOUT_BACKPACK, [_item, GVAR(currentItems) select IDX_CURR_BACKPACK_ITEMS]]; + GVAR(center) setUnitLoadout _loadout; - if ((GVAR(currentItems) select 6) != _item) then { - removeBackpack GVAR(center); - GVAR(center) addBackpackGlobal _item; - while {count backpackItems GVAR(center) > 0} do { - GVAR(center) removeItemFromBackpack (backpackItems GVAR(center) select 0); - }; //--- Remove default config contents - {GVAR(center) addItemToBackpack _x} foreach (GVAR(currentItems) select 17); + private _backpackItems = backpackItems GVAR(center); + private _index = count _backpackItems - 1; - GVAR(currentItems) set [6, _item]; + // Remove any items that can't fit in the container (this prevents overloading) + while {loadBackpack GVAR(center) > 1 && {_index >= 0}} do { + GVAR(center) removeItemFromBackpack (_backpackItems select _index); + DEC(_index); + }; + + GVAR(currentItems) set [IDX_CURR_BACKPACK, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER - [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelContainer, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelContainer}] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgVehicles" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonGoggles : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgVehicles" >> _item] call FUNC(itemInfo); + }; + // Facewear + case IDC_buttonGoggles: { if (_item == "") then { removeGoggles GVAR(center); - GVAR(currentItems) set [7, _item]; + GVAR(currentItems) set [IDX_CURR_GOGGLES, ""]; } else { - if ((GVAR(currentItems) select 7) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_GOGGLES) != _item) then { GVAR(center) addGoggles _item; - GVAR(currentItems) set [7, _item]; + GVAR(currentItems) set [IDX_CURR_GOGGLES, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgGlasses" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonNVG : { + TOGGLE_RIGHT_PANEL_HIDE + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgGlasses" >> _item] call FUNC(itemInfo); + }; + // NVG + case IDC_buttonNVG: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 8); - GVAR(currentItems) set [8, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_NVG); + GVAR(currentItems) set [IDX_CURR_NVG, ""]; } else { - if ((GVAR(currentItems) select 8) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_NVG) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [8, _item]; + GVAR(currentItems) set [IDX_CURR_NVG, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonBinoculars : { + TOGGLE_RIGHT_PANEL_HIDE + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Binoculars + case IDC_buttonBinoculars: { + private _currentWeapon = GVAR(currentItems) select IDX_CURR_BINO; + + // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { + call _fnc_clearCurrentWeaponMags; + GVAR(center) removeWeapon (binocular GVAR(center)); - GVAR(currentItems) set [9, _item]; - } else { - if ((GVAR(currentItems) select 9) != _item) then { - GVAR(center) addWeapon _item; - GVAR(currentItems) set [9, _item]; - call FUNC(showItem); - ADDBINOCULARSMAG - }; - }; - call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_BINO, ""]; - case IDC_buttonMap : { + TOGGLE_RIGHT_PANEL_HIDE + } else { + // Check if a new binocular was selected + if (_item != _currentWeapon) then { + // Get magazines that are compatible with the new binocular + private _compatibleMags = compatibleMagazines _item; + + // Remove all magazines from the current binocular that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; + + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = binocularItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + { + if !(_x in GVAR(virtualItemsFlat)) then { + GVAR(center) removeBinocularItem _x; + }; + } forEach _linkedItems; + }; + + // Add old attachments and magazines back if they are compatible + { + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; + }; + } forEach (GVAR(currentItems) select IDX_CURR_BINO_ITEMS); + + (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; + }; + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_BINO, _item]; + }; + + TOGGLE_RIGHT_PANEL_WEAPON + + [_display, _selectCorrectPanelWeapon, !GVAR(refreshing) && {_currentRightPanel isNotEqualTo _selectCorrectPanelWeapon}] call FUNC(fillRightPanel); + }; + + // Make unit switch to new item + call FUNC(showItem); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Map + case IDC_buttonMap: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 10) select 0; - GVAR(currentItems) set [10, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_MAP); + GVAR(currentItems) set [IDX_CURR_MAP, ""]; } else { - if ((GVAR(currentItems) select 10) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_MAP) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [10, _item]; + GVAR(currentItems) set [IDX_CURR_MAP, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonCompass : { + TOGGLE_RIGHT_PANEL_HIDE + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Compass + case IDC_buttonCompass: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 11) select 0; - GVAR(currentItems) set [11, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_COMPASS); + GVAR(currentItems) set [IDX_CURR_COMPASS, ""]; } else { - if ((GVAR(currentItems) select 11) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_COMPASS) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [11, _item]; + GVAR(currentItems) set [IDX_CURR_COMPASS, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonRadio : { + TOGGLE_RIGHT_PANEL_HIDE + + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Radio + case IDC_buttonRadio: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 12) select 0; - GVAR(currentItems) set [12, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_RADIO); + GVAR(currentItems) set [IDX_CURR_RADIO, ""]; } else { - if ((GVAR(currentItems) select 12) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_RADIO) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [12, _item]; + GVAR(currentItems) set [IDX_CURR_RADIO, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonWatch : { + TOGGLE_RIGHT_PANEL_HIDE + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Watch + case IDC_buttonWatch: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 13); - GVAR(currentItems) set [13, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_WATCH); + GVAR(currentItems) set [IDX_CURR_WATCH, ""]; } else { - if ((GVAR(currentItems) select 13) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_WATCH) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [13, _item]; + GVAR(currentItems) set [IDX_CURR_WATCH, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonGPS : { + TOGGLE_RIGHT_PANEL_HIDE + + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // GPS or UAV Terminal + case IDC_buttonGPS: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 14) select 0; - GVAR(currentItems) set [14, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_COMMS); + GVAR(currentItems) set [IDX_CURR_COMMS, ""]; } else { - if ((GVAR(currentItems) select 14) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_COMMS) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [14, _item]; + GVAR(currentItems) set [IDX_CURR_COMMS, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonFace : { + TOGGLE_RIGHT_PANEL_HIDE + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Face + case IDC_buttonFace: { private _face = [_item, "Default"] select (_item == ""); GVAR(center) setFace _face; GVAR(currentFace) = _face; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgFaces" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonVoice : { + TOGGLE_RIGHT_PANEL_HIDE + + [_display, _control, _curSel, configFile >> "CfgFaces" >> _item] call FUNC(itemInfo); + }; + // Voice + case IDC_buttonVoice: { GVAR(center) setSpeaker _item; GVAR(currentVoice) = _item; + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgVoice" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonInsigna : { - [GVAR(center), _item] call bis_fnc_setUnitInsignia; + TOGGLE_RIGHT_PANEL_HIDE + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgVoice" >> _item] call FUNC(itemInfo); + }; + // Insignia + case IDC_buttonInsignia: { + [GVAR(center), _item] call BIS_fnc_setUnitInsignia; GVAR(currentInsignia) = _item; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - private _unitInsigniaConfig = (configFile >> "CfgUnitInsignia" >> _item); + // Check for correct config: First mission, then campaign and finally regular config + private _itemCfg = missionConfigFile >> "CfgUnitInsignia" >> _item; - if (configName _unitInsigniaConfig isEqualTo "") then { - [_display, _control, _curSel, (missionConfigFile >> "CfgUnitInsignia" >> _item)] call FUNC(itemInfo); - } else { - [_display, _control, _curSel, _unitInsigniaConfig] call FUNC(itemInfo); + if (isNull _itemCfg) then { + _itemCfg = campaignConfigFile >> "CfgUnitInsignia" >> _item; }; + + if (isNull _itemCfg) then { + _itemCfg = configFile >> "CfgUnitInsignia" >> _item; + }; + + // Display new items's info on the bottom right + [_display, _control, _curSel, _itemCfg] call FUNC(itemInfo); }; }; -(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", GVAR(center) call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); diff --git a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf index 529f69da75..c7e084f9ef 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe * Handles selection changes on loadouts panel. * * Arguments: - * 0: Loadouts panel control - * 1: Loadouts panel selection + * 0: Arsenal display + * 1: Loadouts panel control + * 2: Currently selected loadout's index * * Return Value: * None @@ -23,74 +24,76 @@ private _deleteButtonCtrl = _display displayCtrl IDC_buttonDelete; private _renameButtonCtrl = _display displayCtrl IDC_buttonRename; private _textEditBoxCtrl= _display displayCtrl IDC_textEditBox; +// If nothing selected, disable all buttons if (_curSel == -1) exitWith { - if (GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts) then { _saveButtonCtrl ctrlEnable false; _saveButtonCtrl ctrlCommit 0; }; - _shareButtonCtrl ctrlSetText (localize LSTRING(buttonSharePrivateText)); + _shareButtonCtrl ctrlSetText LLSTRING(buttonSharePrivateText); { _x ctrlEnable false; _x ctrlCommit 0; - } foreach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; + } forEach [_shareButtonCtrl, _loadButtonCtrl, _renameButtonCtrl, _deleteButtonCtrl]; }; switch (GVAR(currentLoadoutsTab)) do { - + // Local loadouts case IDC_buttonMyLoadouts: { - + // Enable shared loadouts if option is enabled and MP _shareButtonCtrl ctrlEnable (GVAR(allowSharedLoadouts) && {isMultiplayer}); _shareButtonCtrl ctrlCommit 0; - _loadButtonCtrl ctrlEnable true; - _loadButtonCtrl ctrlCommit 0; - - _shareButtonCtrl ctrlSetText ( [ - localize LSTRING(buttonSharePrivateText), - localize LSTRING(buttonSharePublicText) + // Rename share button, depending if it's already shared or not + _shareButtonCtrl ctrlSetText ([ + LLSTRING(buttonSharePrivateText), + LLSTRING(buttonSharePublicText) ] select ((_control lnbValue [_curSel, 0]) == 1)); + // Enable all other buttons { _x ctrlEnable true; _x ctrlCommit 0; - } foreach [_renameButtonCtrl, _deleteButtonCtrl]; + } forEach [_loadButtonCtrl, _renameButtonCtrl, _deleteButtonCtrl]; _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); }; - + // Default loadouts case IDC_buttonDefaultLoadouts: { - + // Enable saving and loading for everyone { _x ctrlEnable true; _x ctrlCommit 0; - } foreach [_saveButtonCtrl, _loadButtonCtrl]; + } forEach [_saveButtonCtrl, _loadButtonCtrl]; + // Disable sharing button _shareButtonCtrl ctrlEnable false; _shareButtonCtrl ctrlCommit 0; + // Enable delete and renaming button if in 3DEN { - _x ctrlEnable (is3DEN); + _x ctrlEnable (call FUNC(canEditDefaultLoadout)); _x ctrlCommit 0; - } foreach [_deleteButtonCtrl, _renameButtonCtrl]; + } forEach [_renameButtonCtrl, _deleteButtonCtrl]; _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); }; - + // Shared loadouts case IDC_buttonSharedLoadouts: { - + // Enable saving and loading for everyone { _x ctrlEnable true; _x ctrlCommit 0; - } foreach [_saveButtonCtrl, _loadButtonCtrl]; + } forEach [_saveButtonCtrl, _loadButtonCtrl]; + // Disable sharing button _shareButtonCtrl ctrlEnable false; _shareButtonCtrl ctrlCommit 0; + // If admin or loadout author, enable button for shared loadout if ((serverCommandAvailable "#logout") || {(_control lnbText [_curSel, 0]) == profileName}) then { - _deleteButtonCtrl ctrlEnable true; _deleteButtonCtrl ctrlCommit 0; } else { diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index 38e051b4e2..abec68ceee 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles selection changes on the right panel. * * Arguments: * 0: Right panel control - * 1: Right panel selection + * 1: Right panel selection * * Return Value: * None @@ -18,61 +18,192 @@ params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; -private _ctrlIDC = ctrlIDC _control; private _display = ctrlParent _control; private _item = _control lbData _curSel; +private _currentItemsIndex = IDX_CURR_PRIMARY_WEAPON_ITEMS + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun, IDC_buttonBinoculars] find GVAR(currentLeftPanel)); +private _itemIndex = [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find GVAR(currentRightPanel); +// Check which right panel has changed +switch (_currentItemsIndex) do { + // Primary weapon + case IDX_CURR_PRIMARY_WEAPON_ITEMS: { + private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex; + // If removal + if (_item == "") then { + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select 5; -private _fnc_selectItem = { - params ["_item", "_currentItemsIndex", "_itemIndex"]; + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removePrimaryWeaponItem _secondaryMagazine; + GVAR(center) removePrimaryWeaponItem _secondaryMagazine; - switch (_currentItemsIndex) do { - case 18: { - if (_item == "") then { - GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select 18) select _itemIndex); - private _primaryMags = primaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _secondaryMagazine, true]; } else { - GVAR(center) addPrimaryWeaponItem _item; - private _primaryMags = primaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; + GVAR(center) removePrimaryWeaponItem _currentItemInSlot; + }; + } else { + // Don't add item if it isn't a magazine or a different item than what the unit already has + if (_itemIndex >= 4 || {_item != _currentItemInSlot}) then { + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = primaryWeapon GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; + }; }; - [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); }; - case 19: { - if (_item == "") then { - if (cba_disposable_replaceDisposableLauncher && !isNil {cba_disposable_LoadedLaunchers getVariable secondaryWeapon GVAR(center)}) exitWith { TRACE_1("ignoring unload of disposable",secondaryWeapon GVAR(center)); }; - GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select 19) select _itemIndex); - private _secondaryMags = secondaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; - } else { - GVAR(center) addSecondaryWeaponItem _item; - private _secondaryMags = secondaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; + // Call event for compatibility + [QGVAR(weaponItemChanged), [primaryWeapon GVAR(center), _item, _itemIndex]] call CBA_fnc_localEvent; + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_PRIMARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); + }; + // Secondary weapon + case IDX_CURR_SECONDARY_WEAPON_ITEMS: { + private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; + private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil "CBA_disposable_loadedLaunchers"} && + { + if (CBA_disposable_loadedLaunchers isEqualType createHashMap) then { // after CBA 3.18 + (secondaryWeapon GVAR(center)) in CBA_disposable_loadedLaunchers + } else { + !isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon player)} + } + }; + + // If removal + if (_item == "") then { + // Don't unload magazines from diposable weapons + if (_isDisposable && {_itemIndex >= 4}) exitWith { + TRACE_1("Ignoring unload of magazine from disposable",secondaryWeapon GVAR(center)); + }; + + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removeSecondaryWeaponItem _secondaryMagazine; + GVAR(center) removeSecondaryWeaponItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removeSecondaryWeaponItem _currentItemInSlot; + }; + } else { + // Don't add item if it isn't a magazine or a different item than what the unit already has + if (_itemIndex >= 4 || {_item != _currentItemInSlot}) then { + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = secondaryWeapon GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; + }; }; - [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); }; - case 20: { - if (_item == "") then { - GVAR(center) removeHandgunItem ((GVAR(currentItems) select 20) select _itemIndex); - private _handgunMags = handgunMagazine GVAR(center); - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; - } else { - GVAR(center) addHandgunItem _item; - private _handgunMags = handgunMagazine GVAR(center); - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; - }; - [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + // Call event for compatibility + [QGVAR(weaponItemChanged), [secondaryWeapon GVAR(center), _item, _itemIndex]] call CBA_fnc_localEvent; + + // Update currentItems + if !(_isDisposable && {_itemIndex >= 4}) then { + (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; }; + + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); + }; + // Handgun weapon + case IDX_CURR_HANDGUN_WEAPON_ITEMS: { + private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex; + if (_item == "") then { + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removeHandgunItem _secondaryMagazine; + GVAR(center) removeHandgunItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removeHandgunItem _currentItemInSlot; + }; + } else { + // Don't add item if it isn't a magazine or a different item than what the unit already has + if (_itemIndex >= 4 || {_item != _currentItemInSlot}) then { + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = handgunWeapon GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; + }; + }; + }; + + // Call event for compatibility + [QGVAR(weaponItemChanged), [handgunWeapon GVAR(center), _item, _itemIndex]] call CBA_fnc_localEvent; + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); + }; + // Binoculars + case IDX_CURR_BINO_ITEMS: { + private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex; + if (_item == "") then { + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removeBinocularItem _secondaryMagazine; + GVAR(center) removeBinocularItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [binocular GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removeBinocularItem _currentItemInSlot; + }; + } else { + // Don't add item if it isn't a magazine or a different item than what the unit already has + if (_itemIndex >= 4 || {_item != _currentItemInSlot}) then { + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = binocular GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; + }; + }; + }; + + // Call event for compatibility + [QGVAR(weaponItemChanged), [binocular GVAR(center), _item, _itemIndex]] call CBA_fnc_localEvent; + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); }; }; -[ - _item, - 18 + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find GVAR(currentLeftPanel)), - [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find GVAR(currentRightPanel) -] call _fnc_selectItem; - -(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); +// Update weight display +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", GVAR(center) call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); diff --git a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf index c2b14c6462..c1bdafba69 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles selection changes on the right panel (listnbox). * * Arguments: * 0: Right panel control - * 1: Right panel selection + * 1: Right panel selection * * Return Value: * None @@ -16,36 +16,41 @@ params ["_control", "_curSel"]; -if (_curSel < 0) exitwith {}; +if (_curSel < 0 || {!(GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack])}) exitWith {}; -private _ctrlIDC = ctrlIDC _control; -private _display = ctrlParent _control; -private _item = [_control lnbData [_curSel, 0], _control lbData _curSel] select !(ctrlType _control == 102); +private _hasItems = false; -private _fnc_selectRight = { - params ["_item", "_cfgEntry"]; +// Get relevant container +private _container = switch (GVAR(currentLeftPanel)) do { + case IDC_buttonUniform: { + _hasItems = (GVAR(currentItems) select IDX_CURR_UNIFORM_ITEMS) isNotEqualTo []; - // Load remaining - private _maxLoad = switch (GVAR(currentLeftPanel)) do { - case IDC_buttonUniform: { - gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonVest: { - gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonBackpack: { - backpack GVAR(center) - }; + uniformContainer GVAR(center) }; + case IDC_buttonVest: { + _hasItems = (GVAR(currentItems) select IDX_CURR_VEST_ITEMS) isNotEqualTo []; - [_control, _maxLoad] call FUNC(updateRightPanel); - [_display, _control, _curSel, (configFile >> _cfgEntry >> _item)] call FUNC(itemInfo); + vestContainer GVAR(center) + }; + case IDC_buttonBackpack: { + _hasItems = (GVAR(currentItems) select IDX_CURR_BACKPACK_ITEMS) isNotEqualTo []; + + backpackContainer GVAR(center) + }; }; -if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { +// Refresh availibility of items based on space remaining in container +[_control, _container, _hasItems] call FUNC(updateRightPanel); - [ - _item, - ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut]) - ] call _fnc_selectRight; +private _item = _control lnbData [_curSel, 0]; +private _cfgEntry = ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut] || {_item in (uiNamespace getVariable [QGVAR(magazineMiscItems), []])}); + +_cfgEntry = configFile >> _cfgEntry >> _item; + +// If e.g. in misc. items, item could be e.g. a backpack +if (isNull _cfgEntry) then { + _cfgEntry = _item call CBA_fnc_getItemConfig; }; + +// Display item info on the bottom right +[ctrlParent _control, _control, _curSel, _cfgEntry] call FUNC(itemInfo); diff --git a/addons/arsenal/functions/fnc_open3DEN.sqf b/addons/arsenal/functions/fnc_open3DEN.sqf index 103ec870e1..b9dcd710fd 100644 --- a/addons/arsenal/functions/fnc_open3DEN.sqf +++ b/addons/arsenal/functions/fnc_open3DEN.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe - * Replace the 3DEN "edit loadout" menu action + * Replace the 3DEN "edit loadout" menu action. * * Arguments: * None @@ -9,9 +9,8 @@ * Return Value: * None * - * * Public: No */ -private _entity = (uinamespace getvariable ["bis_fnc_3DENEntityMenu_data",[]]) param [1, objnull]; +private _entity = (uiNamespace getVariable ["BIS_fnc_3DENEntityMenu_data", []]) param [1, objNull]; [_entity, _entity, true] call FUNC(openBox); diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf index ce02e6e343..dd983776d1 100644 --- a/addons/arsenal/functions/fnc_openBox.sqf +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Open arsenal. * * Arguments: * 0: Box * 1: Unit to open the arsenal on - * 2: Ignore virtual items and fill arsenal + * 2: Ignore virtual items and fill arsenal (default: false) * * Return Value: * None @@ -26,33 +27,48 @@ if ( {!(isNull objectParent _center) && {!is3DEN}} ) exitWith {}; -if (isNil {_object getVariable [QGVAR(virtualItems), nil]} && {!_mode}) exitWith { - [localize LSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); +// If object has no arsenal and chosen option is to not ignore virtual items of object, exit +private _virtualItems = _object getVariable QGVAR(virtualItems); + +if (isNil "_virtualItems" && {!_mode}) exitWith { + [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); }; +// Don't execute in scheduled environment if (canSuspend) exitWith { - [{_this call FUNC(openBox)}, _this] call CBA_fnc_directCall; + [FUNC(openBox), _this] call CBA_fnc_directCall; }; -private _displayToUse = [findDisplay 46, findDIsplay 312] select (!isNull findDisplay 312); -_displayToUse = [_displayToUse, findDisplay 313] select (is3DEN); +private _displayToUse = findDisplay IDD_RSCDISPLAYCURATOR; +_displayToUse = [_displayToUse, findDisplay IDD_MISSION] select (isNull _displayToUse); +_displayToUse = [_displayToUse, findDisplay IDD_DISPLAY3DEN] select is3DEN; -if (isNil "_displayToUse" || {!isnil QGVAR(camera)}) exitWith { - [localize LSTRING(CantOpenDisplay), false, 5, 1] call EFUNC(common,displayText); -}; - -if (_mode) then { - GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); -} else { - GVAR(virtualItems) = +(_object getVariable [QGVAR(virtualItems), [ - [[], [], []], [[], [], [], []], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] - ]]); +// Check if the display is available and that there isn't already a camera for the arsenal +if (isNull _displayToUse || {!isNil QGVAR(camera)}) exitWith { + [LLSTRING(CantOpenDisplay), false, 5, 1] call EFUNC(common,displayText); }; GVAR(center) = _center; +GVAR(currentBox) = _object; + +if (_mode) then { + // Add all the items from the game that the arsenal has detected + GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); + GVAR(virtualItemsFlat) = +(uiNamespace getVariable QGVAR(configItemsFlat)); + + GVAR(ignoredVirtualItems) = true; +} else { + // Add only specified items to the arsenal + GVAR(virtualItems) = +_virtualItems; + + // Flatten out hashmaps for easy checking later + call FUNC(updateVirtualItemsFlat); +}; if (is3DEN) then { _displayToUse createDisplay QGVAR(display); } else { - [{(_this select 0) createDisplay (_this select 1)}, [_displayToUse, QGVAR(display)]] call CBA_fnc_execNextFrame; + [{ + _this createDisplay QGVAR(display); + }, _displayToUse] call CBA_fnc_execNextFrame; }; diff --git a/addons/arsenal/functions/fnc_portVALoadouts.sqf b/addons/arsenal/functions/fnc_portVALoadouts.sqf index 0e403eae92..eb2c942abd 100644 --- a/addons/arsenal/functions/fnc_portVALoadouts.sqf +++ b/addons/arsenal/functions/fnc_portVALoadouts.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: alganthe + * Author: Alganthe, johnb43 * Port VA loadouts to ACE Arsenal. * * Arguments: @@ -9,34 +9,46 @@ * Return Value: * None * + * Example: + * call ace_arsenal_fnc_portVALoadouts + * * Public: Yes */ -private _VALoadouts = +(profilenamespace getvariable ["bis_fnc_saveInventory_data",[]]); -private _aceLoadouts = +(profileNamespace getVariable [QGVAR(saved_loadouts),[]]); +private _unit = player; -if (isNull player) exitWith { - [localize LSTRING(portLoadoutsPlayerError)] call BIS_fnc_error; +// Need a player object to transfer loadouts +if (isNull _unit) exitWith { + [LLSTRING(portLoadoutsPlayerError)] call BIS_fnc_error; }; +// Check if there are any VA loadouts +private _VALoadouts = profileNamespace getVariable ["BIS_fnc_saveInventory_data", []]; + if (_VALoadouts isEqualTo []) exitWith { - [localize LSTRING(portLoadoutsLoadoutError)] call BIS_fnc_error; + [LLSTRING(portLoadoutsLoadoutError)] call BIS_fnc_error; }; -for "_i" from 0 to (count _VALoadouts - 1) step 2 do { +private _aceLoadouts = +(profileNamespace getVariable [QGVAR(saved_loadouts),[]]); +private _name = ""; +private _index = -1; + +// Go through all VA loadouts and save them as ACE Arsenal loadouts +for "_i" from 0 to (count _VALoadouts) - 1 step 2 do { _name = _VALoadouts select _i; - _inventory = _VALoadouts select (_i + 1); - private _sameNameLoadoutsList = _aceLoadouts select {_x select 0 == _name}; - [player, [profilenamespace, _name]] call bis_fnc_loadinventory; + // Load VA loadout onto player + [_unit, [profileNamespace, _name]] call BIS_fnc_loadInventory; - private _loadout = getUnitLoadout player; - - if (count _sameNameLoadoutsList > 0) then { - _aceLoadouts set [_aceLoadouts find (_sameNameLoadoutsList select 0), [_name, _loadout]]; + // See if there is an already existing loadout with the same name + _index = _aceLoadouts findIf {(_x select 0) == _name}; + // If there is an already existing loadout with same name, overwrite it (in CBA extended loadout array) + if (_index != -1) then { + _aceLoadouts set [_index, [_name, [getUnitLoadout _unit, createHashMap]]]; } else { - _aceLoadouts pushBack [_name, _loadout]; + // Otherwise just add + _aceLoadouts pushBack [_name, [getUnitLoadout _unit, createHashMap]]; }; }; diff --git a/addons/arsenal/functions/fnc_refresh.sqf b/addons/arsenal/functions/fnc_refresh.sqf new file mode 100644 index 0000000000..849b49d16b --- /dev/null +++ b/addons/arsenal/functions/fnc_refresh.sqf @@ -0,0 +1,73 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Brett Mayson, johnb43 + * Refreshes the arsenal to show external changes. + * + * Arguments: + * 0: Update current and unique items lists (default: true) + * 1: Update virtual items list (default: false) + * 2: Use panel refresh animation (default: false) + * + * Return Value: + * None + * + * Example: + * call ace_arsenal_fnc_refresh + * + * Public: Yes +*/ +params [["_updateItems", true, [true]], ["_updateVirtualItems", false, [false]], ["_animate", false, [false]]]; +TRACE_2("",_updateItems,_updateVirtualItems); + +// Don't execute in scheduled environment +if (canSuspend) exitWith { + [{_this call FUNC(refresh)}, _this] call CBA_fnc_directCall; +}; + +private _display = findDisplay IDD_ace_arsenal; + +// Exit quietly if no display found +if (isNull _display) exitWith {}; + +if (_updateItems) then { + // Update current item list + call FUNC(updateCurrentItemsList); + + // This takes care of unique inventory items (arsenal doesn't have it whitelisted) + if (!_updateVirtualItems) then { + call FUNC(updateUniqueItemsList); + }; +}; + +private _virtualItems = GVAR(currentBox) getVariable QGVAR(virtualItems); + +if (is3DEN) then { + _virtualItems = uiNamespace getVariable QGVAR(configItems); // GVAR(currentBox) is nil in 3DEN + _animate = true; // CBA frame functions are disabled during preInit +}; + +// Do not close an arsenal if it was opened with ignoring the existing content (see FUNC(openBox)) +if (isNil "_virtualItems" && {isNil QGVAR(ignoredVirtualItems)}) exitWith { + [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); + // Delay a frame in case this is running on display open + [{(findDisplay IDD_ace_arsenal) closeDisplay 0}] call CBA_fnc_execNextFrame; +}; + +if (_updateVirtualItems) then { + GVAR(virtualItems) = +_virtualItems; + call FUNC(updateVirtualItemsFlat); + + // Gotta update this regardless of condition to prevent desync + call FUNC(updateUniqueItemsList); +}; + +// Don't refresh left panel if in loadout tab +if (!isNull findDisplay IDD_loadouts_display) exitWith {}; + +if (!_animate) then { + GVAR(refreshing) = true; + [{GVAR(refreshing) = false}, nil, 3] call CBA_fnc_execAfterNFrames; +}; + +[_display, _display displayCtrl GVAR(currentLeftPanel), _animate] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_removeAction.sqf b/addons/arsenal/functions/fnc_removeAction.sqf new file mode 100644 index 0000000000..8e9639caa9 --- /dev/null +++ b/addons/arsenal/functions/fnc_removeAction.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Remove a custom action button from ACE Arsenal. + * + * Arguments: + * 0: Array of IDs + * + * Return Value: + * None + * + * Example: + * [["TAG_myActions~text~0", "TAG_myActions~statement~0", "TAG_myActions~button~0"]] call ace_arsenal_fnc_removeAction + * + * Public: Yes +*/ + +params ["_IDList"]; + +// Compile sorts from config (in case this is called before preInit) +call FUNC(compileActions); + +// Remove entries (all names are unique, there are no duplicates) +{ + (_x splitString "~") params ["_rootClass", "_class", "_tab"]; + + _tab = parseNumber _tab; + + { + if ((_x select 0) == _rootClass) exitWith { + (_x select 3) deleteAt ((_x select 3) findIf {(_x select 0) == _class}); + + // If no entries left in group, remove group + if ((_x select 3) isEqualTo []) then { + (GVAR(actionList) select _tab) deleteAt _forEachIndex; + }; + }; + } forEach (GVAR(actionList) select _tab); +} forEach _IDList; + +nil // return diff --git a/addons/arsenal/functions/fnc_removeBox.sqf b/addons/arsenal/functions/fnc_removeBox.sqf index ed4ec7de4d..9fa3ec377a 100644 --- a/addons/arsenal/functions/fnc_removeBox.sqf +++ b/addons/arsenal/functions/fnc_removeBox.sqf @@ -1,11 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Remove arsenal from target. * * Arguments: * 0: Target - * 1: Remove globally + * 1: Remove globally (default: true) * * Return Value: * None @@ -18,18 +19,37 @@ params [["_object", objNull, [objNull]], ["_global", true, [true]]]; -if (isNull _object || {isNil QGVAR(EHIDArray)}) exitWith {}; +if (isNull _object) exitWith {}; -if (_global && {isMultiplayer}) then { - private _ID = (GVAR(EHIDArray) select {_x select 1 == _object}) select 0; +private _id = _object getVariable QGVAR(initBoxJIP); - if !(isNil "_ID") then { - [_ID select 0] call CBA_fnc_removeGlobalEventJIP; - GVAR(EHIDArray) deleteAt (GVAR(EHIDArray) find _ID); - publicVariable QGVAR(EHIDArray); - [QGVAR(removeBox), [_object, false]] call CBA_fnc_globalEvent; - }; +if (_global && {isMultiplayer} && {!isNil "_id"}) then { + // Remove event from JIP queue + _id call CBA_fnc_removeGlobalEventJIP; + + // Reset JIP ID + _object setVariable [QGVAR(initBoxJIP), nil, true]; + + // Remove box for everyone + [QGVAR(removeBox), [_object, false]] call CBA_fnc_globalEvent; + + // Remove from JIP + _object setVariable [QGVAR(virtualItems), nil, true]; } else { - _object setVariable [QGVAR(virtualItems), nil, false]; + _object setVariable [QGVAR(virtualItems), nil]; [_object, 0, ["ACE_MainActions", QGVAR(interaction)]] call EFUNC(interact_menu,removeActionFromObject); + [QGVAR(boxRemoved), _object] call CBA_fnc_localEvent; +}; + +// If the arsenal is already open and not ignoring content (see FUNC(openBox)), close arsenal display +// Deliberate == check, fail on objNull +if (!isNil QGVAR(currentBox) && {GVAR(currentBox) == _object} && {isNil QGVAR(ignoredVirtualItems)}) then { + // Delay a frame in case this is running on display open/close + [{ + private _display = findDisplay IDD_ace_arsenal; + if (isNull _display) exitWith {}; + + [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); + _display closeDisplay 0; + }] call CBA_fnc_execNextFrame; }; diff --git a/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf b/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf new file mode 100644 index 0000000000..3ca877f7fd --- /dev/null +++ b/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Removes a loadout from the "Default Loadouts" list. + * + * Arguments: + * 0: Name of loadout + * 1: Remove globally (default: false) + * + * Return Value: + * None + * + * Example: + * ["Squad Leader", true] call ace_arsenal_fnc_removeDefaultLoadout + * + * Public: Yes +*/ +params [["_name", "", [""]], ["_global", false, [false]]]; + +if (_global) exitWith { + private _eventID = format [QGVAR(loadouts_%1), _name]; + [_eventID] call CBA_fnc_removeGlobalEventJIP; + [QGVAR(removeDefaultLoadout), [_name]] call CBA_fnc_globalEvent; +}; + +GVAR(defaultLoadoutsList) deleteAt (GVAR(defaultLoadoutsList) findIf {(_x select 0) == _name}); + +if (is3DEN) then { + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; +}; diff --git a/addons/arsenal/functions/fnc_removeSort.sqf b/addons/arsenal/functions/fnc_removeSort.sqf new file mode 100644 index 0000000000..a5e9fb1d77 --- /dev/null +++ b/addons/arsenal/functions/fnc_removeSort.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Remove a sort from ACE Arsenal. + * + * Arguments: + * 0: Array of IDs + * + * Return Value: + * None + * + * Example: + * [["scopeSortL00", "scopeSortL01", "scopeSortL02", "scopeSortR07"]] call ace_arsenal_fnc_removeSort; + * + * Public: Yes +*/ + +params ["_IDList"]; + +// Compile sorts from config (in case this is called before preInit) +call FUNC(compileSorts); + +private _currentID = ""; +private _stringCount = 0; +private _tabSide = ""; +private _tab = ""; +private _tabToChange = []; + +{ + _currentID = _x; + _stringCount = count _currentID; + + // Make sure to keep at least 1 sort per category, so make default sort not deletable + if ("ace_alphabetically" in toLowerANSI (_currentID select [0, _stringCount - 3])) then { + continue; + }; + + // Get tab info + _tabSide = _currentID select [_stringCount - 3, 1]; + _tab = _currentID select [_stringCount - 2, 2]; + + _tab = parseNumber _tab; + + // Check which side to delete it from + _tabToChange = if (_tabSide == "R") then { + GVAR(sortListRightPanel) select _tab + } else { + GVAR(sortListLeftPanel) select _tab + }; + + // Remove entry (all names are unique, there are no duplicates) + _tabToChange deleteAt (_tabToChange findIf {_x select 0 == _currentID}); +} forEach _IDList; diff --git a/addons/arsenal/functions/fnc_removeStat.sqf b/addons/arsenal/functions/fnc_removeStat.sqf index 79f2173798..af2cbf11fc 100644 --- a/addons/arsenal/functions/fnc_removeStat.sqf +++ b/addons/arsenal/functions/fnc_removeStat.sqf @@ -1,60 +1,47 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Remove a stat from ACE Arsenal. * * Arguments: - * 0: Array of IDs (ARRAY) + * 0: Array of IDs * * Return Value: * None * * Example: - * [["scopeStatL00","scopeStatL01","scopeStatL02","scopeStatR07"]] call ace_arsenal_fnc_removeStat; + * [["scopeStatL00", "scopeStatL01", "scopeStatL02", "scopeStatR07"]] call ace_arsenal_fnc_removeStat; * * Public: Yes */ params ["_IDList"]; +// Compile stats from config (in case this is called before preInit) call FUNC(compileStats); +private _currentID = ""; +private _stringCount = 0; +private _tabSide = ""; +private _tab = ""; +private _tabToChange = []; + { - private _currentID = _x; - private _stringCount = count _currentID; - private _side = _currentID select [_stringCount - 3, 1]; - private _tab = _currentID select [_stringCount - 2, 2]; + // Get tab info + _currentID = _x; + _stringCount = count _currentID; + _tabSide = _currentID select [_stringCount - 3, 1]; + _tab = _currentID select [_stringCount - 2, 2]; + _tab = parseNumber _tab; - private _tabToChange = if (_side == "R") then { + // Check which side to delete it from + _tabToChange = if (_tabSide == "R") then { GVAR(statsListRightPanel) select _tab } else { GVAR(statsListLeftPanel) select _tab }; - { - _x deleteAt (_x findIf {_x select 0 == _currentID}); - } foreach _tabToChange; -} foreach _IDList; - -// Clear empty pages -private _fnc_deleteEmptyPage = { - params ["_list"]; - { - private _evaluatedTab = _forEachIndex; - { - if (count _x == 0) then { - _markedForDeletion pushBack [_evaluatedTab, _forEachIndex]; - }; - } foreach _x; - - { - (_list select (_x select 0)) deleteAt (_x select 1); - } foreach _markedForDeletion; - } foreach (_this select 0); -}; - -private _markedForDeletion = []; - -[GVAR(statsListLeftPanel)] call _fnc_deleteEmptyPage; -[GVAR(statsListRightPanel)] call _fnc_deleteEmptyPage; + // Delete stat + _tabToChange deleteAt (_tabToChange findIf {_x select 5 == _currentID}); +} forEach _IDList; diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf index d96d16e3d6..71db2b15a1 100644 --- a/addons/arsenal/functions/fnc_removeVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Remove virtual items to the provided target. * * Arguments: * 0: Target - * 1: Items - * 2: Add globally + * 1: Items + * 2: Remove globally (default: false) * * Return Value: * None @@ -18,65 +19,93 @@ * Public: Yes */ -params [ ["_object", objNull, [objNull]], ["_items", [], [true, [""]]], ["_global", false, [false]] ]; +params [["_object", objNull, [objNull]], ["_items", [], [true, [""]]], ["_global", false, [false]]]; -if (_object == objNull) exitWith {}; -if (_items isEqualType [] && {count _items == 0}) exitWith {}; - -private _cargo = _object getVariable [QGVAR(virtualItems), [ - [[], [], []], // Weapons 0, primary, handgun, secondary - [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod - [ ], // Magazines 2 - [ ], // Headgear 3 - [ ], // Uniform 4 - [ ], // Vest 5 - [ ], // Backpacks 6 - [ ], // Goggles 7 - [ ], // NVGs 8 - [ ], // Binoculars 9 - [ ], // Map 10 - [ ], // Compass 11 - [ ], // Radio slot 12 - [ ], // Watch slot 13 - [ ], // Comms slot 14 - [ ], // WeaponThrow 15 - [ ], // WeaponPut 16 - [ ] // InventoryItems 17 -]]; +if (isNull _object || {_items isEqualTo []}) exitWith {}; if (_items isEqualType true) then { if (_items) then { [_object, _global] call FUNC(removeBox); - _object setVariable [QGVAR(virtualItems), nil, _global]; }; } else { + private _cargo = _object getVariable QGVAR(virtualItems); - // Make sure all items are in string form - _items = _items select {_x isEqualType "" && {_x != ""}}; + if (isNil "_cargo") exitWith { + [_object, _global] call FUNC(removeBox); + }; + // Make sure all items are in string form, then convert to config case (non-existent items return "") + _items = (_items select {_x isEqualType ""}) apply {_x call EFUNC(common,getConfigName)}; + + // Remove any invalid/non-existing items + _items = _items - [""]; + + private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); + + // Convert all items to their baseWeapon + _items = _items apply {if (_x in _configItemsFlat) then {_x} else {_x call FUNC(baseWeapon)}}; + + // Remove items from lists { - if (_forEachIndex isEqualTo 0) then { - _cargo set [_forEachIndex, [(_x select 0) - _items, (_x select 1) - _items, (_x select 2) - _items]]; - } else { - if (_forEachIndex isEqualTo 1) then { - _cargo set [_forEachIndex, [(_x select 0) - _items, (_x select 1) - _items, (_x select 2) - _items, (_x select 3) - _items]]; - } else { - _cargo set [_cargo find _x, _x - _items]; + switch (true) do { + // Weapons + case (_x in ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) deleteAt _x; + }; + + // Weapon attachments + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) deleteAt _x; + }; + + // Other + default { + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + if (_x in (_cargo get _index)) exitWith { + (_cargo get _index) deleteAt _x; + }; + }; }; }; - } foreach _cargo; + } forEach _items; - private _itemCount = { - if (_x isEqualTo (_cargo select 0) || {_x isEqualTo (_cargo select 1)}) then { - !(_x isEqualTo [[],[],[]] || {_x isEqualTo [[],[],[],[]]}) - } else { - !(_x isEqualTo []) - }; - } count _cargo; + private _empty = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; - if (_itemCount == 0) then { + _empty = createHashMapFromArray _empty; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _empty set [_index, createHashMap]; + }; + + // If nothing is left, remove arsenal from object + if (_cargo isEqualTo _empty) then { [_object, _global] call FUNC(removeBox); } else { _object setVariable [QGVAR(virtualItems), _cargo, _global]; + + // If the arsenal is already open, refresh arsenal display + if (_global) then { + [QGVAR(refresh), _object] call CBA_fnc_globalEvent; + } else { + [QGVAR(refresh), _object] call CBA_fnc_localEvent; + }; }; }; diff --git a/addons/arsenal/functions/fnc_renameDefaultLoadout.sqf b/addons/arsenal/functions/fnc_renameDefaultLoadout.sqf new file mode 100644 index 0000000000..b28088b9b6 --- /dev/null +++ b/addons/arsenal/functions/fnc_renameDefaultLoadout.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Renames a loadout from the "Default Loadouts" list. + * + * Arguments: + * 0: Current name of loadout + * 1: New name of loadout + * + * Return Value: + * None + * + * Example: + * ["Squad Leader", "Team Leader"] call ace_arsenal_fnc_renameDefaultLoadout + * + * Public: Yes +*/ +params [["_currentName", "", [""]], ["_newName", "", [""]]]; + +if (_currentName isEqualTo _newName) exitWith {}; + +private _loadoutIndex = GVAR(defaultLoadoutsList) findIf {(_x select 0) == _currentName}; +if (_loadoutIndex isEqualTo -1) exitWith {}; + +(GVAR(defaultLoadoutsList) select _loadoutIndex) set [0, _newName]; diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf new file mode 100644 index 0000000000..061180beaa --- /dev/null +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -0,0 +1,199 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43 + * Replaces unique items in a loadout with their base items. Weapons are replaced with their base weapon. + * + * Arguments: + * 0: CBA extended loadout or getUnitLoadout array + * + * Return Value: + * Sanitised loadout (getUnitLoadout array) + * + * Example: + * [getUnitLoadout player] call ace_arsenal_fnc_replaceUniqueItemsLoadout + * + * Public: Yes +*/ + +params [["_loadout", [], [[]]]]; + +// IF CBA extended loadout, just take getUnitLoadout array +if (count _loadout == 2) then { + _loadout = _loadout select 0; +}; + +if (count _loadout != 10) exitWith {[]}; + +private _weaponsInfo = []; +private _uniqueBaseCfgText = ""; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; + +{ + switch (_forEachIndex) do { + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + _weaponsInfo = _x; + + // Check weapon & weapon attachments + { + // Magazines in weapons have 2 entries: Name and ammo count + if (_forEachIndex in [4, 5]) then { + _x params [["_magazine", ""], "_count"]; + + if (_magazine != "") then { + _uniqueBaseCfgText = (getText (_cfgMagazines >> _magazine >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _weaponsInfo set [_forEachIndex, [_uniqueBaseCfgText, _count]]; + }; + }; + } else { + // Other + if (_x != "") then { + _weaponsInfo set [_forEachIndex, _x call FUNC(baseWeapon)]; + }; + }; + } forEach _weaponsInfo; + }; + // Uniform, vest, backpack + case IDX_LOADOUT_UNIFORM; + case IDX_LOADOUT_VEST; + case IDX_LOADOUT_BACKPACK: { + _x params [["_containerClass", ""], ["_items", []]]; + + if (_containerClass != "") then { + if (_forEachIndex == IDX_LOADOUT_BACKPACK) then { + // Check for non-preset first + _uniqueBaseCfgText = [_containerClass, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + // Check if non-preset backpack has a unique base + _uniqueBaseCfgText = (getText (_cfgVehicles >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + _x set [0, _containerClass]; + } else { + _uniqueBaseCfgText = (getText (_cfgWeapons >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + + // Check if container has items that need replacing with a defined base + { + switch (true) do { + // Containers have 2 entries: Name and isBackpack + case (_x isEqualTypeArray ["", false]): { + _x params ["_containerClass", "_isBackpack"]; + + if (_containerClass != "") then { + if (_isBackpack) then { + // Check for non-preset first + _uniqueBaseCfgText = [_containerClass, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + // Check if non-preset backpack has a unique base + _uniqueBaseCfgText = (getText (_cfgVehicles >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + _x set [0, _containerClass]; + } else { + _uniqueBaseCfgText = (getText (_cfgWeapons >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + }; + }; + // Misc. items have 2 entries: Name and amount + case (_x isEqualTypeArray ["", 0]): { + _x params ["_item"]; + + if (_item != "") then { + _uniqueBaseCfgText = (getText (_cfgWeapons >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + }; + // Weapons have 2 entries: Weapon info array and amount + case (_x isEqualTypeArray [[], 0]): { + _x params ["_weaponsInfo"]; + + // Check weapon & weapon attachments + { + // Magazines in weapons have 2 entries: Name and ammo count + if (_forEachIndex in [4, 5]) then { + _x params [["_magazine", ""], "_count"]; + + if (_magazine != "") then { + _uniqueBaseCfgText = (getText (_cfgMagazines >> _magazine >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _weaponsInfo set [_forEachIndex, [_uniqueBaseCfgText, _count]]; + }; + }; + } else { + // Other + if (_x != "") then { + _weaponsInfo set [_forEachIndex, _x call FUNC(baseWeapon)]; + }; + }; + } forEach _weaponsInfo; + }; + // Magazines have 3 entries: Name, amount and ammo count + case (_x isEqualTypeArray ["", 0, 0]): { + _x params ["_item"]; + + if (_item != "") then { + _uniqueBaseCfgText = (getText (_cfgMagazines >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + }; + }; + } forEach _items; + }; + }; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + // Check if assignedItems have items that need replacing with a defined base + private _items = _x; + + { + if (_x != "") then { + _uniqueBaseCfgText = (getText (_cfgWeapons >> _x >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _items set [_forEachIndex, _uniqueBaseCfgText]; + }; + }; + } forEach _items; + }; + }; +} forEach _loadout; + +_loadout diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 2bddbf4c5c..fef97e8bd8 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -1,7 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* - * Author: Dedmen - * Cache an array of all the compatible items for arsenal. + * Author: Dedmen, johnb43 + * Cache an array of all the compatible items for arsenals. * * Arguments: * None @@ -12,178 +13,311 @@ * Public: No */ -private _cargo = [ - [[], [], []], // Weapons 0, primary, secondary, handgun - [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod - [ ], // Magazines 2 - [ ], // Headgear 3 - [ ], // Uniform 4 - [ ], // Vest 5 - [ ], // Backpacks 6 - [ ], // Goggles 7 - [ ], // NVGs 8 - [ ], // Binoculars 9 - [ ], // Map 10 - [ ], // Compass 11 - [ ], // Radio slot 12 - [ ], // Watch slot 13 - [ ], // Comms slot 14 - [ ], // WeaponThrow 15 - [ ], // WeaponPut 16 - [ ] // InventoryItems 17 +private _configItems = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] ]; -private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in variable for perf improvement +_configItems = createHashMapFromArray _configItems; +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _configItems set [_index, createHashMap]; +}; + +// Cache tools for separate tab +private _toolList = createHashMap; + +// https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration +// https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 +private _filterFunction = toString { + isClass _x && {if (isNumber (_x >> "scopeArsenal")) then {getNumber (_x >> "scopeArsenal") == 2 && {getNumber (_x >> "scope") > 0}} else {getNumber (_x >> "scope") == 2}} && {getNumber (_x >> QGVAR(hide)) != 1} +}; + +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _className = ""; +private _simulationType = ""; +private _configItemInfo = ""; +private _hasItemInfo = false; +private _itemInfoType = 0; +private _isMiscItem = false; +private _isTool = false; + +// Get weapons and other various items { - private _configItemInfo = _x >> "ItemInfo"; - private _simulationType = getText (_x >> "simulation"); - private _className = configName _x; - private _hasItemInfo = isClass (_configItemInfo); - private _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; + _className = configName _x; + _simulationType = getText (_x >> "simulation"); + _configItemInfo = _x >> "ItemInfo"; + _hasItemInfo = isClass (_configItemInfo); + _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; + _isMiscItem = _className isKindOf ["CBA_MiscItem", _cfgWeapons]; + _isTool = getNumber (_x >> "ACE_isTool") isEqualTo 1; - switch true do { - /* Weapon acc */ + switch (true) do { + // Weapon attachments case ( - _hasItemInfo && - {_itemInfoType in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} && - {!(configName _x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} - ): { - - //Convert type to array index - (_cargo select 1) select ([TYPE_OPTICS,TYPE_FLASHLIGHT,TYPE_MUZZLE,TYPE_BIPOD] find _itemInfoType) pushBackUnique _className; + _hasItemInfo && + {!_isMiscItem} && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]} + ): { + // Convert type to array index + ((_configItems get IDX_VIRT_ATTACHMENTS) get ([TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] find _itemInfoType)) set [_className call FUNC(baseWeapon), nil]; }; - /* Headgear */ + // Headgear case (_itemInfoType == TYPE_HEADGEAR): { - (_cargo select 3) pushBackUnique _className; + (_configItems get IDX_VIRT_HEADGEAR) set [_className, nil]; }; - /* Uniform */ + // Uniform case (_itemInfoType == TYPE_UNIFORM): { - (_cargo select 4) pushBackUnique _className; + (_configItems get IDX_VIRT_UNIFORM) set [_className, nil]; }; - /* Vest */ + // Vest case (_itemInfoType == TYPE_VEST): { - (_cargo select 5) pushBackUnique _className; + (_configItems get IDX_VIRT_VEST) set [_className, nil]; }; - /* NVgs */ + // NVGs case (_simulationType == "NVGoggles"): { - (_cargo select 8) pushBackUnique _className; + (_configItems get IDX_VIRT_NVG) set [_className, nil]; }; - /* Binos */ - case (_simulationType == "Binocular" || - ((_simulationType == 'Weapon') && {(getNumber (_x >> 'type') == TYPE_BINOCULAR_AND_NVG)})): { - (_cargo select 9) pushBackUnique _className; + // Binos + case ( + _simulationType == "Binocular" || + {_simulationType == "Weapon" && {getNumber (_x >> "type") == TYPE_BINOCULAR_AND_NVG}} + ): { + (_configItems get IDX_VIRT_BINO) set [_className call FUNC(baseWeapon), nil]; }; - /* Map */ + // Map case (_simulationType == "ItemMap"): { - (_cargo select 10) pushBackUnique _className; + (_configItems get IDX_VIRT_MAP) set [_className, nil]; }; - /* Compass */ + // Compass case (_simulationType == "ItemCompass"): { - (_cargo select 11) pushBackUnique _className; + (_configItems get IDX_VIRT_COMPASS) set [_className, nil]; }; - /* Radio */ + // Radio case (_simulationType == "ItemRadio"): { - (_cargo select 12) pushBackUnique _className; + (_configItems get IDX_VIRT_RADIO) set [_className, nil]; }; - /* Watch */ + // Watch case (_simulationType == "ItemWatch"): { - (_cargo select 13) pushBackUnique _className; + (_configItems get IDX_VIRT_WATCH) set [_className, nil]; }; - /* GPS */ - case (_simulationType == "ItemGPS"): { - (_cargo select 14) pushBackUnique _className; + // GPS and UAV terminals + case ( + _simulationType == "ItemGPS" || + {_itemInfoType == TYPE_UAV_TERMINAL} + ): { + (_configItems get IDX_VIRT_COMMS) set [_className, nil]; }; - /* UAV terminals */ - case (_itemInfoType == TYPE_UAV_TERMINAL): { - (_cargo select 14) pushBackUnique _className; - }; - /* Weapon, at the bottom to avoid adding binos */ - case (isClass (_x >> "WeaponSlotsInfo") && - {getNumber (_x >> 'type') != TYPE_BINOCULAR_AND_NVG}): { + // Weapon, at the bottom to avoid adding binos + case ( + isClass (_x >> "WeaponSlotsInfo") && + {getNumber (_x >> "type") != TYPE_BINOCULAR_AND_NVG} + ): { switch (getNumber (_x >> "type")) do { case TYPE_WEAPON_PRIMARY: { - (_cargo select 0) select 0 pushBackUnique (_className call bis_fnc_baseWeapon); + ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) set [_className call FUNC(baseWeapon), nil]; }; case TYPE_WEAPON_HANDGUN: { - (_cargo select 0) select 2 pushBackUnique (_className call bis_fnc_baseWeapon); + ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) set [_className call FUNC(baseWeapon), nil]; }; case TYPE_WEAPON_SECONDARY: { - (_cargo select 0) select 1 pushBackUnique (_className call bis_fnc_baseWeapon); + ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) set [_className call FUNC(baseWeapon), nil]; }; }; }; - /* Misc items */ + // Misc. items case ( - _hasItemInfo && - (_itemInfoType in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && - {(_className isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || - {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {(getText ( _x >> "simulation")) == "ItemMineDetector"} - ): { - (_cargo select 17) pushBackUnique _className; + _hasItemInfo && + {_isMiscItem && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]}} || + {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {_simulationType == "ItemMineDetector"} + ): { + (_configItems get IDX_VIRT_MISC_ITEMS) set [_className, nil]; + if (_isTool) then {_toolList set [_className, nil]}; }; }; -} foreach configProperties [_configCfgWeapons, "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; +} forEach configProperties [_cfgWeapons, _filterFunction, true]; -private _grenadeList = []; -{ - _grenadeList append getArray (_configCfgWeapons >> "Throw" >> _x >> "magazines"); -} foreach getArray (_configCfgWeapons >> "Throw" >> "muzzles"); - -private _putList = []; -{ - _putList append getArray (_configCfgWeapons >> "Put" >> _x >> "magazines"); -} foreach getArray (_configCfgWeapons >> "Put" >> "muzzles"); +// Get all grenades +// Explicitly don't look at scope for these, we want hidden items to be sorted as grenades/explosives properly +private _grenadeList = createHashMap; { - private _className = configName _x; + _grenadeList insert [true, (getArray (_cfgWeapons >> "Throw" >> _x >> "magazines")) apply {_x call EFUNC(common,getConfigName)}, []]; +} forEach getArray (_cfgWeapons >> "Throw" >> "muzzles"); - switch true do { - // Rifle, handgun, secondary weapons mags - case ( - ((getNumber (_x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW,TYPE_MAGAZINE_SECONDARY_AND_PUT,1536,TYPE_MAGAZINE_HANDGUN_AND_GL]) || - {(getNumber (_x >> QGVAR(hide))) == -1}) && - {!(_className in _grenadeList)} && - {!(_className in _putList)} - ): { - (_cargo select 2) pushBackUnique _className; +// Get all explosives, mines, IEDS and similar +private _putList = createHashMap; + +{ + _putList insert [true, (getArray (_cfgWeapons >> "Put" >> _x >> "magazines")) apply {_x call EFUNC(common,getConfigName)}, []]; +} forEach getArray (_cfgWeapons >> "Put" >> "muzzles"); + +// Get all magazine misc items +private _magazineMiscItems = createHashMap; + +{ + _magazineMiscItems set [configName _x, nil]; +} forEach ((toString {getNumber (_x >> "ACE_isUnique") == 1 || getNumber (_x >> "ACE_asItem") == 1}) configClasses _cfgMagazines); + +// Remove invalid/non-existent entries +_grenadeList deleteAt ""; +_putList deleteAt ""; +_magazineMiscItems deleteAt ""; + +// Get all other grenades, explosives (and similar) and magazines +{ + _className = configName _x; + + switch (true) do { + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + case (_className in _magazineMiscItems): { + (_configItems get IDX_VIRT_MISC_ITEMS) set [_className, nil]; + if (getNumber (_x >> "ACE_isTool") isEqualTo 1) then {_toolList set [_className, nil]}; }; // Grenades case (_className in _grenadeList): { - (_cargo select 15) pushBackUnique _className; + (_configItems get IDX_VIRT_GRENADES) set [_className, nil]; }; - // Put + // Explosives case (_className in _putList): { - (_cargo select 16) pushBackUnique _className; + (_configItems get IDX_VIRT_EXPLOSIVES) set [_className, nil]; + }; + // Primary, handgun & secondary weapon magazines, and magazines that are forced with "ace_arsenal_hide = -1" + case ( + getNumber (_x >> QGVAR(hide)) == -1 || + {getNumber (_x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL, TYPE_MAGAZINE_MISSILE]} + ): { + (_configItems get IDX_VIRT_ITEMS_ALL) set [_className, nil]; }; }; -} foreach configProperties [(configFile >> "CfgMagazines"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; +} forEach configProperties [_cfgMagazines, _filterFunction, true]; +// Get all backpacks { if (getNumber (_x >> "isBackpack") == 1) then { - (_cargo select 6) pushBackUnique (configName _x); + (_configItems get IDX_VIRT_BACKPACK) set [configName _x, nil]; }; -} foreach configProperties [(configFile >> "CfgVehicles"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; +} forEach configProperties [configFile >> "CfgVehicles", _filterFunction, true]; + +// Get all facewear +{ + (_configItems get IDX_VIRT_GOGGLES) set [configName _x, nil]; +} forEach configProperties [configFile >> "CfgGlasses", _filterFunction, true]; + +// Get all faces +private _faceCache = createHashMap; +private _dlcName = ""; +private _modPicture = ""; +private _faceCategory = ""; { - (_cargo select 7) pushBackUnique (configName _x); -} foreach configProperties [(configFile >> "CfgGlasses"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; + _faceCategory = configName _x; -private _magazineGroups = [[],[]] call CBA_fnc_hashCreate; - -private _cfgMagazines = configFile >> "CfgMagazines"; - -{ - private _magList = []; { - private _magazines = (getArray _x) select {isClass (_cfgMagazines >> _x)}; //filter out non-existent magazines - _magazines = _magazines apply {configName (_cfgMagazines >> _x)}; //Make sure classname case is correct - _magList append _magazines; - } foreach configProperties [_x, "isArray _x", true]; + if (getNumber (_x >> "disabled") == 0 && {getText (_x >> "head") != ""} && {configName _x != "Default"}) then { + _dlcName = _x call EFUNC(common,getAddon); + _modPicture = ""; - [_magazineGroups, toLower configName _x, _magList arrayIntersect _magList] call CBA_fnc_hashSet; -} foreach configProperties [(configFile >> "CfgMagazineWells"), "isClass _x", true]; + if (_dlcName != "") then { + _modPicture = (modParams [_dlcName, ["logo"]]) param [0, ""]; + }; -uiNamespace setVariable [QGVAR(configItems), _cargo]; -uiNamespace setVariable [QGVAR(magazineGroups), _magazineGroups]; + _faceCache set [configName _x, [getText (_x >> "displayName"), _modPicture, _faceCategory]]; + }; + } forEach ("true" configClasses _x); +} forEach ("true" configClasses (configfile >> "CfgFaces")); + +// Get all voices +private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [configfile >> "CfgVoice" >> "NoVoice"]; +_voiceCache = _voiceCache apply {configName _x}; + +// Get all insignia +private _insigniaCache = "(if (isNumber (_x >> 'scope')) then {getNumber (_x >> 'scope')} else {2}) == 2" configClasses (configFile >> "CfgUnitInsignia"); +_insigniaCache = _insigniaCache apply {configName _x}; + +// Get all disposable launchers +private _launchersConfig = configProperties [configFile >> "CBA_DisposableLaunchers"]; +private _launchers = createHashMap; +private _launcher = ""; + +// Get the loaded launchers (used launchers aren't necessary) +{ + // Convert to config case + _launcher = ((getArray _x) param [0, ""]) call EFUNC(common,getConfigName); + + if (_launcher != "") then { + _launchers set [_launcher, nil]; + }; +} forEach _launchersConfig; + +private _configItemsFlat = +_configItems; +private _weapons = _configItemsFlat deleteAt IDX_VIRT_WEAPONS; +private _attachments = _configItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; + +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _configItemsFlat merge [_configItemsFlat deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _configItemsFlat merge [_weapons deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _configItemsFlat merge [_attachments deleteAt _index, true]; +}; + +// This contains config case entries only +uiNamespace setVariable [QGVAR(configItems), compileFinal _configItems]; +uiNamespace setVariable [QGVAR(configItemsFlat), compileFinal _configItemsFlat]; +uiNamespace setVariable [QGVAR(faceCache), compileFinal _faceCache]; +uiNamespace setVariable [QGVAR(voiceCache), compileFinal (_voiceCache createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(insigniaCache), compileFinal (_insigniaCache createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(grenadeCache), compileFinal _grenadeList]; +uiNamespace setVariable [QGVAR(putCache), compileFinal _putList]; +uiNamespace setVariable [QGVAR(magazineMiscItems), compileFinal _magazineMiscItems]; +uiNamespace setVariable [QGVAR(CBAdisposableLaunchers), compileFinal _launchers]; +uiNamespace setVariable [QGVAR(configItemsTools), compileFinal _toolList]; + +// Compatibility: Override baseWeapon for RHS optics +// No good way to do this via script for other RHS attachments, needs manual compat +private _baseWeaponCache = uiNamespace getVariable QGVAR(baseWeaponNameCache); +{ + private _baseAttachment = configName (_cfgWeapons >> getText (_x >> "rhs_optic_base")); + if (_baseAttachment != "") then { + _baseWeaponCache set [toLowerANSI configName _x, _baseAttachment]; + }; +} forEach ("getText (_x >> 'rhs_optic_base') != ''" configClasses _cfgWeapons); + +// Compatibility: Override baseWeapon for CBA Scripted Optics +// Adapted from https://github.com/Theseus-Aegis/Mods/blob/master/addons/armory/functions/fnc_getBaseVariant.sqf +private _isScriptedOptic = toString { + isClass (_x >> "CBA_ScriptedOptic") || + {(getText (_x >> "weaponInfoType")) regexMatch "CBA_scriptedOptic.*?"} +}; + +{ + private _xClass = toLowerANSI configName _x; + private _baseOptic = _xClass call FUNC(baseOptic); + if (_baseOptic != "" && {_baseOptic != _xClass}) then { + TRACE_2("updating baseOptic",_xClass,_baseOptic); + _baseWeaponCache set [_xClass, _baseOptic]; + }; +} forEach (_isScriptedOptic configClasses _cfgWeapons); + +// Compatibility: Override baseWeapon for CBA Scripted Attachments +private _isScriptedAttachment = toString { + getText (_x >> "MRT_SwitchItemNextClass") != "" || + {getText (_x >> "MRT_SwitchItemPrevClass") != ""} +}; + +{ + private _xClass = toLowerANSI configName _x; + private _baseAttachment = _xClass call FUNC(baseAttachment); + if (_baseAttachment != "" && {_baseAttachment != _xClass}) then { + TRACE_2("updating baseAttachment",_xClass,_baseAttachment); + _baseWeaponCache set [_xClass, _baseAttachment]; + }; +} forEach (_isScriptedAttachment configClasses _cfgWeapons); diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index d9bf74f061..f47f12d2bf 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* * Author: Alganthe @@ -15,57 +15,55 @@ if (GVAR(centerNotPlayer)) exitWith {}; -private _nextAction = switch (GVAR(currentLeftPanel)) do { +if (EGVAR(common,isReloading)) exitWith { // if player is reloading then wait until it's done so we don't send magazines to the shadow realm + [{!EGVAR(common,isReloading)}, FUNC(showItem)] call CBA_fnc_waitUntilAndExecute; +}; - case IDC_buttonPrimaryWeapon : { - ["Civil", "PrimaryWeapon"] select ((GVAR(currentItems) select 0) != "") +// Determine action to play based on current category selection +private _nextAction = switch (GVAR(currentLeftPanel)) do { + // Primary weapon + case IDC_buttonPrimaryWeapon: { + ["Civil", "PrimaryWeapon"] select ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) != "") }; - case IDC_buttonSecondaryWeapon : { - ["Civil", "SecondaryWeapon"] select (GVAR(currentItems) select 1 != "") + // Secondary weapon + case IDC_buttonSecondaryWeapon: { + ["Civil", "SecondaryWeapon"] select ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) != "") }; - case IDC_buttonHandgun : { - ["Civil", "HandGunOn"] select (GVAR(currentItems) select 2 != "") + // Handgun weapon + case IDC_buttonHandgun: { + ["Civil", "HandGunOn"] select ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) != "") }; - case IDC_buttonHeadgear; - case IDC_buttonUniform; - case IDC_buttonVest; - case IDC_buttonBackpack; - case IDC_buttonGoggles; - case IDC_buttonMap; - case IDC_buttonGPS; - case IDC_buttonRadio; - case IDC_buttonCompass; - case IDC_buttonWatch; - case IDC_buttonFace; - case IDC_buttonNVG : { - "Civil" + // Binoculars + case IDC_buttonBinoculars: { + ["Civil", "Binoculars"] select ((GVAR(currentItems) select IDX_CURR_BINO) != "") }; - case IDC_buttonBinoculars : { - ["Civil", "Binoculars"] select (GVAR(currentItems) select 9 != "") - }; - case IDC_buttonInsigna : { + // Insignia + case IDC_buttonInsignia: { "Salute" }; - case IDC_buttonVoice : { + // Voice + case IDC_buttonVoice: { GVAR(center) directSay "CuratorObjectPlaced"; "Civil" }; + // Other + default { + "Civil" + }; }; +// Play the action if a new category of item was selected if (_nextAction != GVAR(currentAction)) then { - switch (_nextAction) do { - case "PrimaryWeapon": { - GVAR(selectedWeaponType) = 0; - }; - case "SecondaryWeapon": { - GVAR(selectedWeaponType) = 1; - }; - case "HandGunOn": { - GVAR(selectedWeaponType) = 2; - }; + GVAR(selectedWeaponType) = switch (_nextAction) do { + case "PrimaryWeapon": {0}; + case "SecondaryWeapon": {1}; + case "HandGunOn": {2}; + case "Binoculars": {3}; + default {GVAR(selectedWeaponType)}; }; if (simulationEnabled GVAR(center)) then { + GVAR(center) call EFUNC(common,stopGesture); // reset gesture state (if arsenal is opened on animation transition, animations played whilst in the arsenal break) GVAR(center) playActionNow _nextAction; } else { GVAR(center) switchAction _nextAction; @@ -73,3 +71,7 @@ if (_nextAction != GVAR(currentAction)) then { GVAR(currentAction) = _nextAction; }; + +if !(GVAR(currentAction) in ["Civil", "Salute"]) then { + GVAR(center) selectWeapon ([primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] select GVAR(selectedWeaponType)); // select correct weapon, prevents floating weapons +}; diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index 5d3a2af017..f9803a429e 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -1,12 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, Dedmen - * Sort arsenal panel. + * Author: Alganthe, Dedmen, Brett Mayson, johnb43 + * Sort an arsenal panel. * * Arguments: - * 0: Panel's control to sort - * 1: Sorting mode + * 0: Control * * Return Value: * None @@ -14,60 +13,267 @@ * Public: No */ -params ["_control", "_mode"]; +params ["_control"]; + +// https://community.bistudio.com/wiki/toString, see comment +// However, using 55295 did not work as expected, 55291 was found by trial and error +#define HIGHEST_VALUE_CHAR 55291 + +// When filling the sorting panel, FUNC(sortPanel) is called twice, so ignore first call +if (GVAR(ignoreFirstSortPanelCall)) exitWith { + GVAR(ignoreFirstSortPanelCall) = false; +}; private _display = ctrlParent _control; -private ["_panel", "_curSel", "_selected"]; +private _rightSort = (ctrlIDC _control) in [IDC_sortRightTab, IDC_sortRightTabDirection]; +private _right = _rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}; +private _sortCtrl = _display displayCtrl ([IDC_sortLeftTab, IDC_sortRightTab] select _rightSort); +private _sortDirectionCtrl = _display displayCtrl ([IDC_sortLeftTabDirection, IDC_sortRightTabDirection] select _rightSort); -// Right panel -if (ctrlIDC _control == 17 && {GVAR(currentLeftPanel) in [IDC_buttonUniform ,IDC_buttonVest, IDC_buttonBackpack]}) then { - _panel = _display displayCtrl IDC_rightTabContentListnBox; - _curSel = lnbCurSelRow _panel; - _selected = _panel lnbData [_curSel, 0]; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgFaces = configFile >> "CfgFaces"; +private _cfgUnitInsignia = configFile >> "CfgUnitInsignia"; +private _cfgUnitInsigniaCampaign = campaignConfigFile >> "CfgUnitInsignia"; +private _cfgUnitInsigniaMission = missionConfigFile >> "CfgUnitInsignia"; - switch (_mode) do { - case 0: { - _panel lnbSort [1, false]; - }; - - case 1: { - _panel lnbSortByValue [0, false]; - }; - - case 2: { - for "_i" from 0 to (((lnbsize _panel) select 0) - 1) do { - _panel lnbSetText [[_i, 2], str (parseNumber (_panel lnbText [_i, 2]) / 1000)]; - }; - - _panel lnbSort [2, true]; - - - for "_i" from 0 to (((lnbsize _panel) select 0) - 1) do { - _panel lnbSetText [[_i, 2], str (parseNumber (_panel lnbText [_i, 2]) * 1000)]; - }; - }; - }; - - if (_cursel >= 0) then { - for '_i' from 0 to (((lnbsize _panel) select 0) - 1) do { - if ((_panel lnbdata [_i, 0]) == _selected) exitwith {_panel lnbSetCurSelRow _i}; - }; - }; -// Left panel +if (_rightSort) then { + [ + if (_right) then { + _display displayCtrl IDC_rightTabContentListnBox + } else { + _display displayCtrl IDC_rightTabContent + }, + switch (GVAR(currentRightPanel)) do { + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonThrow; + case IDC_buttonPut; + case IDC_buttonMag; + case IDC_buttonMagALL: {_cfgMagazines}; + default {configFile >> "CfgWeapons"}; + }, + GVAR(sortListRightPanel) select ( + switch (GVAR(currentRightPanel)) do { + case IDC_buttonOptic: { 0 }; + case IDC_buttonItemAcc: { 1 }; + case IDC_buttonMuzzle: { 2 }; + case IDC_buttonBipod: { 3 }; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: { 4 }; + case IDC_buttonThrow: { 5 }; + case IDC_buttonPut: { 6 }; + case IDC_buttonMisc: { 7 }; + } + ) + ] } else { - _panel = _display displayCtrl ([IDC_leftTabContent, IDC_rightTabContent] select (ctrlIDC _control == 17)); - _curSel = lbCurSel _panel; - _selected = _panel lbData _curSel; + [ + _display displayCtrl IDC_leftTabContent, + switch (GVAR(currentLeftPanel)) do { + case IDC_buttonBackpack: {configFile >> "CfgVehicles"}; + case IDC_buttonGoggles: {configFile >> "CfgGlasses"}; + case IDC_buttonFace: {_cfgFaces}; + case IDC_buttonVoice: {configFile >> "CfgVoice"}; + case IDC_buttonInsignia: {_cfgUnitInsignia}; + default {configFile >> "CfgWeapons"}; + }, + (GVAR(sortListLeftPanel) select ([ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch, + IDC_buttonFace, + IDC_buttonVoice, + IDC_buttonInsignia + ] find GVAR(currentLeftPanel))) + ] +} params ["_panel", "_cfgClass", "_sorts"]; - if (_mode > 0) then { - lbSortByValue _panel; +// Get sort & sort direction +private _sortName = _sortCtrl lbData (0 max lbCurSel _sortCtrl); +private _sortDirection = _sortDirectionCtrl lbValue (0 max lbCurSel _sortDirectionCtrl); +(_sorts select (0 max (_sorts findIf {(_x select 0) == _sortName}))) params ["", "_displayName", "_statement"]; + +// Update last sort & sort direction +missionNamespace setVariable [ + [QGVAR(lastSortLeft), QGVAR(lastSortRight)] select _rightSort, + _displayName +]; + +missionNamespace setVariable [ + [QGVAR(lastSortDirectionLeft), QGVAR(lastSortDirectionRight)] select _rightSort, + _sortDirection +]; + +// Get currently selected item +private _curSel = if (_right) then { + lnbCurSelRow _panel +} else { + lbCurSel _panel +}; + +private _selected = if (_right) then { + _panel lnbData [_curSel, 0] +} else { + _panel lbData _curSel +}; + +private _item = ""; +private _quantity = ""; +private _itemCfg = configNull; +private _value = ""; +private _name = ""; +private _fillerChar = toString [1]; + +private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); +private _sortCache = uiNamespace getVariable QGVAR(sortCache); +private _faceCache = uiNamespace getVariable QGVAR(faceCache); +private _insigniaCache = uiNamespace getVariable QGVAR(insigniaCache); + +private _countColumns = if (_right) then { + count lnbGetColumnsPosition _panel +} else { + 0 +}; + +private _for = if (_right) then { + for "_i" from 0 to (lnbSize _panel select 0) - 1 +} else { + for "_i" from 0 to (lbSize _panel) - 1 +}; + +_for do { + // Get item + _item = if (_right) then { + _panel lnbData [_i, 0] } else { - lbsort _panel; + _panel lbData _i }; - if (_cursel >= 0) then { - for '_i' from 0 to (lbsize _panel - 1) do { - if ((_panel lbdata _i) == _selected) exitwith {_panel lbSetCurSel _i}; + // Check if entry is "Empty" + if (!_right && {(_panel lbValue _i) == -1}) then { + // Set to lowest/highest lexicographical value, so that "Empty" is always at the top + _panel lbSetTextRight [_i, ["", toString [HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR]] select (_sortDirection == ASCENDING)]; + + continue; + }; + + // Get item's count + _quantity = if (_right) then { + parseNumber (_panel lnbText [_i, 2]) + } else { + 0 + }; + + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + if (_item in _magazineMiscItems) then { + _cfgClass = _cfgMagazines; + }; + + // Check item's config + _itemCfg = if !(_cfgClass in [_cfgFaces, _cfgUnitInsignia]) then { + _cfgClass >> _item + } else { + // If insignia, check for correct config: First mission, then campaign and finally regular config + if (_cfgClass == _cfgUnitInsignia) then { + _itemCfg = _cfgUnitInsigniaMission >> _item; + + if (isNull _itemCfg) then { + _itemCfg = _cfgUnitInsigniaCampaign >> _item; + }; + + if (isNull _itemCfg) then { + _itemCfg = _cfgUnitInsignia >> _item; + }; + + _itemCfg + } else { + // If face, check correct category + _cfgClass >> (_faceCache getOrDefault [_item, []]) param [2, "Man_A3"] >> _item + }; + }; + + // Some items may not belong to the config class for the panel (e.g. misc. items panel can have unique items) + if (isNull _itemCfg) then { + _itemCfg = _item call CBA_fnc_getItemConfig; + }; + + // Value can be any type + _value = _sortCache getOrDefaultCall [format ["%1_%2_%3", _sortName, _item, _quantity], { + private _value = [_itemCfg, _item, _quantity] call _statement; + + // If number, convert to string (keep 2 decimal after comma; Needed for correct weight sorting) + if (_value isEqualType 0) then { + _value = [_value, 8, 2] call CBA_fnc_formatNumber; + }; + + // If empty string, add alphabetically small char at beginning to make it sort correctly + if (_value isEqualTo "") then { + _value = "_"; + }; + + _value + }, true]; + + // Set the right text temporarily, so it can be used for sorting + if (_right) then { + // Use value, display name and classname to sort, which means a fixed alphabetical order is guaranteed + // Filler char has lowest lexicographical value possible + _panel lnbSetTextRight [[_i, 1], format ["%1%2%4%3", _value, _panel lnbText [_i, 1], _item, _fillerChar]]; + } else { + if (_item != "") then { + // Use value, display name and classname to sort, which means a fixed alphabetical order is guaranteed + // Filler char has lowest lexicographical value possible + _panel lbSetTextRight [_i, format ["%1%2%4%3", _value, _panel lbText _i, _item, _fillerChar]]; + }; + }; +}; + +// Sort alphabetically, find the previously selected item and select it again +if (_right) then { + [_panel, 1] lnbSortBy ["TEXT", _sortDirection == ASCENDING, false, true, true]; // do not support unicode, as it's much more performance intensive (~3x more) + + _for do { + // Remove sorting text, as it blocks the item name otherwise + _panel lnbSetTextRight [[_i, 1], ""]; + + if (_curSel != -1 && {(_panel lnbData [_i, 0]) == _selected}) then { + _panel lnbSetCurSelRow _i; + + // To avoid unnecessary checks after previsouly selected item was found + _curSel = -1; + }; + }; +} else { + _panel lbSortBy ["TEXT", _sortDirection == ASCENDING, false, true, true]; // do not support unicode, as it's much more performance intensive (~3x more) + + _for do { + _item = _panel lbData _i; + + // Check if valid item (problems can be caused when searching) + if (_item != "") then { + // Remove sorting text, as it blocks the item name otherwise + _panel lbSetTextRight [_i, ""]; + }; + + if (_curSel != -1 && {_item == _selected}) then { + _panel lbSetCurSel _i; + + // To avoid unnecessary checks after previsouly selected item was found + _curSel = -1; }; }; }; diff --git a/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf b/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf new file mode 100644 index 0000000000..48e09246ee --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Alganthe, Brett Mayson + * Statement to sort weapons by their accuracy. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _dispersion = []; + +{ + if (getNumber (_config >> _x >> "showToPlayer") != 0) then { + private _n = log getNumber (_config >> _x >> "dispersion"); + + if (!finite _n) then { + _n = 0; + }; + + _dispersion pushBackUnique _n; + }; +} forEach (getArray (_config >> "modes")); + +_dispersion sort true; + +10000000 - round ((_dispersion param [0, 0]) * 100000) diff --git a/addons/arsenal/functions/fnc_sortStatement_amount.sqf b/addons/arsenal/functions/fnc_sortStatement_amount.sqf new file mode 100644 index 0000000000..533de80e4f --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_amount.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Statement to sort items by the amount in inventory. + * + * Arguments: + * 0: Not used + * 1: Not used + * 2: Quantity + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["", "", "_quantity"]; + +10000 - _quantity diff --git a/addons/arsenal/functions/fnc_sortStatement_magCount.sqf b/addons/arsenal/functions/fnc_sortStatement_magCount.sqf new file mode 100644 index 0000000000..6c35911665 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_magCount.sqf @@ -0,0 +1,17 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Statement to sort magazines by their ammo count. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +getNumber (_config >> "count") diff --git a/addons/arsenal/functions/fnc_sortStatement_mass.sqf b/addons/arsenal/functions/fnc_sortStatement_mass.sqf new file mode 100644 index 0000000000..6aa4524ea0 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_mass.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Alganthe, Brett Mayson + * Statement to sort items by their mass. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _mass = getNumber (_config >> "mass"); + +if (_mass == 0 && {isClass (_config >> "itemInfo")}) then { + _mass = getNumber (_config >> "itemInfo" >> "mass"); +}; + +if (_mass == 0 && {isClass (_config >> "WeaponSlotsInfo")}) then { + _mass = getNumber (_config >> "WeaponSlotsInfo" >> "mass"); +}; + +_mass diff --git a/addons/arsenal/functions/fnc_sortStatement_mod.sqf b/addons/arsenal/functions/fnc_sortStatement_mod.sqf new file mode 100644 index 0000000000..ab94520217 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_mod.sqf @@ -0,0 +1,17 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson, johnb43 + * Statement to sort items by the mod they belong to. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Mod Name to Sort By + * + * Public: No +*/ + +params ["_config"]; + +(modParams [_config call EFUNC(common,getAddon), ["name"]]) param [0, ""] diff --git a/addons/arsenal/functions/fnc_sortStatement_protection.sqf b/addons/arsenal/functions/fnc_sortStatement_protection.sqf new file mode 100644 index 0000000000..f2a479f3b4 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_protection.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Statement to sort items by their protection (combination of ballistic and explosive). + * + * Arguments: + * 0: Item Config + * 1: Ballistic (passthrough) coefficent + * 2: Explosive (armor) coefficent + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_itemInfo", "_ballisticCo", "_explosiveCo"]; +_itemInfo params ["_config"]; + +(([[_config], ["passthrough", "armor"]] call BIS_fnc_configExtremes) select 1) params [["_passthroughMax", 0], ["_armorMax", 0]]; + +_passthroughMax * _ballisticCo + _armorMax * _explosiveCo; diff --git a/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf b/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf new file mode 100644 index 0000000000..c5190bb1ba --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: Alganthe, Brett Mayson + * Statement to sort weapons by their rate of fire. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _fireRate = []; + +{ + _fireRate pushBackUnique getNumber (_config >> _x >> "reloadTime"); +} forEach (getArray (_config >> "modes")); + +_fireRate sort true; +_fireRate = _fireRate param [0, 0]; + +if (_fireRate == 0) exitWith {0}; + +round (60 / _fireRate) diff --git a/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf new file mode 100644 index 0000000000..4f0998aba5 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Alganthe, Brett Mayson + * Statement to sort optics by their magnification. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _minZoom = 999; // FOV, so smaller is more zoomed in + +{ + _minZoom = _minZoom min getNumber (_x >> "opticsZoomMin"); +} forEach configProperties [_config >> "ItemInfo" >> "OpticsModes", "isClass _x"]; + +if (_minZoom in [0, 999]) exitWith {"?"}; + +round ((0.25 / _minZoom) * 10) diff --git a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf index fa8ff55c35..e15d3fb659 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf @@ -1,35 +1,38 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Accuracy bar statement. * * Arguments: - * 0: stats array (ARRAY) - * 1: item config path (CONFIG) - * 2: Args - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Bar limits (ARRAY of SCALAR) + * 0: Not used + * 1: Item config path + * 2: Args + * - 0: Stat limits + * - 1: Bar limits * * Return Value: - * Number + * * * Public: No */ -params ["_stat", "_config", "_args"]; +params ["", "_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; -} foreach _fireModes; + if (getNumber (_config >> _x >> "showToPlayer") != 0) then { + private _n = log (getNumber (_config >> _x >> "dispersion")); + + if (!finite _n) then { + _n = 0; + }; + + _dispersion pushBackUnique _n; + }; +} forEach (getArray (_config >> "modes")); _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/functions/fnc_statBarStatement_default.sqf b/addons/arsenal/functions/fnc_statBarStatement_default.sqf index 4eb0a36f98..0246e765fd 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_default.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_default.sqf @@ -1,21 +1,24 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Generic bar statement for stats. * * Arguments: - * 0: stat (STRING) - * 1: item config path (CONFIG) - * 2: Args for configExtreme - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Bar limits (ARRAY of SCALAR) - * 2.3: Evaluate as a logarithmic number (BOOL) + * 0: Stat + * 1: Item config path + * 2: Args for configExtreme + * - 0: Stat limits + * - 1: Bar limits + * - 2: Evaluate as a logarithmic number * * Return Value: - * Number + * Bar statement + * + * Example: + * ["ACE_maxZeroing", _config, [[0, 2500], [0.01, 1], false]] call ace_arsenal_fnc_statBarStatement_default * * Public: Yes -*/ + */ params ["_stat", "_config", "_args"]; _args params ["_statMinMax", "_barLimits", "_configExtremeBool"]; diff --git a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf index c8839e85c2..6707370440 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf @@ -1,15 +1,15 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Impact bar statement. * * Arguments: - * 0: stats array (ARRAY) - * 1: item config path (CONFIG) - * 2: Args for configExtreme - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Bar limits (ARRAY of SCALAR) - * 2.3: Evaluate as a logarithmic number (BOOL) + * 0: Stats array + * 1: Item config path + * 2: Args for configExtreme + * - 0: Stats limits + * - 1: Bar limits * * Return Value: * Number @@ -18,7 +18,7 @@ */ params ["_stats", "_config", "_args"]; -_args params ["_hitMinMax", "_initSpeedMinMax", "_launcherTabIDC"]; +_args params ["_hitMinMax", "_initSpeedMinMax"]; private _statValues = [ [_config], @@ -31,4 +31,5 @@ private _statValues = [ _hit = linearConversion [_hitMinMax select 0, _hitMinMax select 1, _hit, 0.01, 1]; _initSpeed = linearConversion [_initSpeedMinMax select 0, _initSpeedMinMax select 1, _initSpeed, 0.01, 1]; -[sqrt(_hit^2 * _initSpeed), _hit] select (GVAR(currentLeftPanel) == _launcherTabIDC) +// If launcher tab +[sqrt (_hit ^ 2 * _initSpeed), _hit] select (GVAR(currentLeftPanel) == IDC_buttonSecondaryWeapon) diff --git a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf index 6b268a3e56..562e920642 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf @@ -1,14 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Rate of fire bar statement. * * Arguments: - * 0: stats array (ARRAY) - * 1: item config path (CONFIG) - * 2: Args - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Bar limits (ARRAY of SCALAR) + * 0: Not used + * 1: Item config path + * 2: Args + * - 0: Stat limits + * - 1: Bar limits * * Return Value: * Number @@ -16,17 +16,20 @@ * Public: No */ -params ["_stat", "_config", "_args"]; +params ["", "_config", "_args"]; _args params ["_statMinMax", "_barLimits"]; -private _fireModes = getArray (_config >> "modes"); private _fireRate = []; { private _n = log (getNumber (_config >> _x >> "reloadTime")); - if (!finite _n) then {_n = 0;}; + + if (!finite _n) then { + _n = 0; + }; + _fireRate pushBackUnique _n; -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _fireRate sort true; diff --git a/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf index cb2687097b..10a929df67 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf @@ -1,34 +1,30 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Accuracy text statement. * * Arguments: - * 0: stat (STRING) - * 1: item config path (CONFIG) - * 2: Args for configExtreme - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Evaluate as a logarithmic number (BOOL) + * 0: Not used + * 1: Item config path * * Return Value: - * Number + * Stat Text * * Public: No */ -params ["_stat", "_config", "_args"]; -_args params ["_statMinMax", "_configExtremeBool"]; +params ["", "_config"]; +TRACE_1("statTextStatement_accuracy",_config); -private _fireModes = getArray (_config >> "modes"); private _dispersion = []; { if (getNumber (_config >> _x >> "showToPlayer") != 0) then { _dispersion pushBackUnique (getNumber (_config >> _x >> "dispersion")); }; -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _dispersion sort true; _dispersion = _dispersion param [0, 0]; -format ["%1 MIL (%2 MOA)", (_dispersion * 1000) toFixed 2, (_dispersion / pi * 10800) ToFixed 1]; +format ["%1 MIL (%2 MOA)", (_dispersion * 1000) toFixed 2, (_dispersion / pi * 10800) toFixed 1]; diff --git a/addons/arsenal/functions/fnc_statTextStatement_binoMag.sqf b/addons/arsenal/functions/fnc_statTextStatement_binoMag.sqf new file mode 100644 index 0000000000..15ff9f0347 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_binoMag.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, LinkIsGrim + * Text statement for the binocular magnification stat. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_binoMag",_config); + +private _minZoom = getNumber (_config >> "opticsZoomMin"); // FOV, so smaller is more zoomed in +private _maxZoom = getNumber (_config >> "opticsZoomMax"); + +if (_minZoom == 0) exitWith {"?"}; + +private _maxMagnification = (0.25 / _minZoom) toFixed 1; +private _minMagnification = (0.25 / _maxZoom); +if (_minMagnification < 1) then { + _minMagnification = 1; +}; +_minMagnification = _minMagnification toFixed 1; + +if (_minMagnification == _maxMagnification) exitWith { + format ["%1x", _maxMagnification] +}; + +format ["%1x-%2x", _minMagnification, _maxMagnification] diff --git a/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf new file mode 100644 index 0000000000..df4260ba1a --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Dedmen, johnb43, LinkIsGrim + * Text statement for the binocular/NVG vision mode stat. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_binoVisionMode",_config); + +private _text = []; +private _visionModes = getArray (_config >> "visionMode") apply {toLowerANSI _x}; +{ + if (_x in _visionModes) then { + _text pushBack (localize ([LSTRING(VisionNormal), LSTRING(VisionNight), LSTRING(VisionThermal)] select _forEachIndex)); + }; +} forEach ["normal", "nvg", "ti"]; + +_text joinString ", " diff --git a/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf b/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf new file mode 100644 index 0000000000..5b4d637299 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Text statement for the explosion time stat. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Example: + * [_stats, _config] call ace_arsenal_fnc_statTextStatement_explosionTime + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_explosionTime",_config); + +private _ammoConfig = configFile >> "CfgAmmo" >> getText (_config >> "ammo"); +private _timeToLive = getNumber (_ammoConfig >> "timeToLive"); +private _explosionTime = getNumber (_ammoConfig >> "explosionTime"); + +// Handle IR grenades +if (_explosionTime > _timeToLive) exitWith { + "-" +}; + +if (_explosionTime == -1) exitWith { + LLSTRING(DetonatesOnImpact) +}; + +format ["%1s", _explosionTime] diff --git a/addons/arsenal/functions/fnc_statTextStatement_illuminators.sqf b/addons/arsenal/functions/fnc_statTextStatement_illuminators.sqf new file mode 100644 index 0000000000..3f982f575c --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_illuminators.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Text statement for the pointer slot capabilites. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Example: + * [[], configFile >> "CfgWeapons" >> "acc_pointer_IR"] call ace_arsenal_fnc_statTextStatement_illuminators + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_illuminators",_config); + +private _allModes = []; +private _allItems = [configName _config] call CBA_fnc_switchableAttachments; +if (_allItems isEqualTo []) then { _allItems = [configName _config] }; + +{ + private _xCfg = configFile >> "CfgWeapons" >> _x >> "ItemInfo"; + private _laser = (getText (_xCfg >> "Pointer" >> "irLaserPos")) != ""; + private _illum = (getNumber (_xCfg >> "Flashlight" >> "intensity")) > 0; + private _isIR = (_laser && {([_xCfg >> "Pointer" >> "isIR", "NUMBER", 1] call CBA_fnc_getConfigEntry) == 1}) + || {_illum && {([_xCfg >> "Flashlight" >> "irLight", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1}}; + + private _text = switch (true) do { // shorthand roughly based on PEQ-15 + case (_laser && _illum): { ["VIS-DUAL", "IR-DUAL"] select _isIR }; // DUAL + case (_laser): { ["VIS-AIM", "IR-AIM"] select _isIR }; // AIM + case (_illum): { ["VIS-ILM", "IR-ILM"] select _isIR }; // ILLUMIATION + default { "_" }; // there are some purely cosmetic attachements + }; + _allModes pushBackUnique _text; +} forEach _allItems; + +_allModes joinString ", " diff --git a/addons/arsenal/functions/fnc_statTextStatement_load.sqf b/addons/arsenal/functions/fnc_statTextStatement_load.sqf new file mode 100644 index 0000000000..032019f582 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_load.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Text statement for the load stat. + * + * Arguments: + * 0: Stats + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["_stats", "_config"]; +TRACE_2("statTextStatement_load",_stats,_config); + +if (!isNull (_config >> "ItemInfo" >> "containerClass")) then { // Uniform/Vest + _config = configfile >> "CfgVehicles" >> getText (_config >> "ItemInfo" >> "containerClass"); +}; + +private _load = getNumber (_config >> (_stats # 0)); + +if (_load <= 0) exitWith { LELSTRING(common,none) }; +format ["%1kg (%2lb)", (_load * 0.1 * (1 / 2.2046)) toFixed 2, (_load * 0.1) toFixed 2] diff --git a/addons/arsenal/functions/fnc_statTextStatement_magCount.sqf b/addons/arsenal/functions/fnc_statTextStatement_magCount.sqf new file mode 100644 index 0000000000..82d68d4848 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_magCount.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Text statement for the magazine capacity stat. + * + * Arguments: + * 0: Stats Array (not used) + * 1: Item config path + * + * Return Value: + * String to display + * + * Public: No +*/ + +params ["", "_config"]; +TRACE_1("statTextStatement_magCount",_config); + +getNumber (_config >> "count"); diff --git a/addons/arsenal/functions/fnc_statTextStatement_mass.sqf b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf index 9c2a0501a6..d87334c64f 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_mass.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf @@ -1,19 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Text statement for the mass stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ params ["", "_config"]; +TRACE_1("statTextStatement_mass",_config); private _mass = getNumber (_config >> "mass"); @@ -25,4 +26,4 @@ if (_mass == 0 && {isClass (_config >> "WeaponSlotsInfo")}) then { _mass = getNumber (_config >> "WeaponSlotsInfo" >> "mass"); }; -format ["%1kg (%2lb)",((_mass * 0.1 * (1/2.2046) * 100) / 100) ToFixed 2, ((_mass * 0.1 * 100) / 100) ToFixed 2] +format ["%1kg (%2lb)", ((_mass * 0.1 * (1 / 2.2046) * 100) / 100) toFixed 2, ((_mass * 0.1 * 100) / 100) toFixed 2] diff --git a/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf index edc6fafc9b..5d35e9a4e0 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf @@ -1,33 +1,30 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Rate of fire text statement. * * Arguments: - * 0: stat (STRING) - * 1: item config path (CONFIG) - * 2: Args for configExtreme - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Evaluate as a logarithmic number (BOOL) + * 0: Not used + * 1: Item config path * * Return Value: - * String + * Stat Text * * Public: No */ -params ["_stat", "_config", "_args"]; -_args params ["_statMinMax", "_configExtremeBool"]; +params ["", "_config"]; +TRACE_1("statTextStatement_rateOfFire",_config); -private _fireModes = getArray (_config >> "modes"); private _fireRate = []; { _fireRate pushBackUnique (getNumber (_config >> _x >> "reloadTime")); -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _fireRate sort true; _fireRate = _fireRate param [0, 0]; if (_fireRate == 0) exitWith {"PEWPEWPEW"}; + format ["%1 rpm", round (60 / _fireRate)] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf index f817ff6c3f..af6ef4b24e 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf @@ -1,14 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Text statement for the scope magnification stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ @@ -17,10 +17,31 @@ params ["", "_config"]; TRACE_1("statTextStatement_scopeMag",_config); private _minZoom = 999; // FOV, so smaller is more zoomed in +private _maxZoom = 1.25; // Cap at 1x zoomed out + +private _opticsModes = "true" configClasses (_config >> "ItemInfo" >> "OpticsModes"); { + // If there is a primary mode then just use that + if (getNumber (_x >> "useModelOptics") == 1 || {count _opticsModes == 1}) exitWith { + _minZoom = getNumber (_x >> "opticsZoomMin"); + _maxZoom = getNumber (_x >> "opticsZoomMax"); + }; + // Otherwise go through the optic's modes _minZoom = _minZoom min (getNumber (_x >> "opticsZoomMin")); -} forEach configProperties [_config >> "ItemInfo" >> "OpticsModes"]; + _maxZoom = _maxZoom max (getNumber (_x >> "opticsZoomMax")); +} forEach _opticsModes; if (_minZoom in [0, 999]) exitWith {"?"}; -format ["%1x", (0.25/_minZoom) toFixed 1] +private _maxMagnification = (0.25 / _minZoom) toFixed 1; +private _minMagnification = (0.25 / _maxZoom); +if (_minMagnification < 1) then { + _minMagnification = 1; +}; +_minMagnification = _minMagnification toFixed 1; + +if (_minMagnification == _maxMagnification) exitWith { + format ["%1x", _maxMagnification] +}; + +format ["%1x-%2x", _minMagnification, _maxMagnification] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf index f5a29f1996..7348be5bc3 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf @@ -1,14 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Dedmen + * Author: Dedmen, johnb43 * Text statement for the scope Night vision support stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ @@ -17,12 +17,12 @@ params ["", "_config"]; TRACE_1("statTextStatement_scopeVisionMode",_config); private _opticsModes = ("true" configClasses (_config >> "ItemInfo" >> "OpticsModes")) apply { - private _visionMode = getArray (_x >> "visionMode"); + private _visionMode = getArray (_x >> "visionMode") apply {toLowerANSI _x}; [ - getNumber (_x >> "useModelOptics") == 1, //is in optics - _visionMode isEqualTo [], //optional NVG - "NVG" in _visionMode, //Integrated NVG - "Ti" in _visionMode //Integrated Thermal + getNumber (_x >> "useModelOptics") == 1, // Is in optics + _visionMode isEqualTo [], // Optional NVG + "nvg" in _visionMode, // Integrated NVG + "ti" in _visionMode // Integrated Thermal ] }; @@ -33,35 +33,43 @@ private _secondaryNVGSupported = false; { _x params ["_isPrimary", "_optionalNvg", "_integratedNVG", "_integratedTi"]; + if (_isPrimary) then { if (_integratedNVG) then { _primaryNVGIntegrated = true; }; + if (_optionalNvg) then { _primaryNVGSupported = true; }; + if (_integratedTi) then { _primaryTiIntegrated = true; }; } else { if (_optionalNvg) then { _secondaryNVGSupported = true; - } - } + }; + }; } forEach _opticsModes; -//Detecting Primary by useModelOptics works in 99.9% of cases. -//But on some scopes (from one specific mod) even the primary mode has useModelOptics=false -//So we have this workaround +// Detecting Primary by useModelOptics works in 99.9% of cases. +// But on some scopes (from one specific mod) even the primary mode has useModelOptics=false +// So we have this workaround -if ( - count _opticsModes == 1 || //If we only have a single mode. And it's a secondary, then consider it primary. - {{_x select 1} count _opticsModes == count _opticsModes} //If every mode supports it. Then then the primary also supports it -) then { +// If we only have a single mode and it's a secondary, then consider it primary. +if (count _opticsModes == 1 && {!(_opticsModes select 0 select 0)}) then { _primaryNVGSupported = _secondaryNVGSupported; }; -if (_primaryNVGIntegrated) exitWith {LLSTRING(statVisionMode_IntPrim)}; +// If all modes support NVGs, then the primary also supports it +if (!_primaryNVGSupported && {(_opticsModes select {_x select 1}) isEqualTo _opticsModes}) then { + _primaryNVGSupported = true; +}; + +if (_primaryTiIntegrated && _primaryNVGIntegrated) exitWith {LLSTRING(statVisionMode_intPrimTi)}; +if (_primaryTiIntegrated) exitWith {LLSTRING(statVisionMode_ti)}; +if (_primaryNVGIntegrated) exitWith {LLSTRING(statVisionMode_intPrim)}; if (_primaryNVGSupported) exitWith {LLSTRING(statVisionMode_supPrim)}; if (_secondaryNVGSupported) exitWith {LLSTRING(statVisionMode_supSec)}; diff --git a/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf b/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf index edbcc715ae..729a024073 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf @@ -1,25 +1,25 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Text statement for the smoke / chemlight time to live stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ params ["", "_config"]; +TRACE_1("statTextStatement_smokeChemTTL",_config); private _TTL = getNumber (configFile >> "CfgAmmo" >> getText (_config >> "ammo") >> "timeToLive"); if (_TTL > 3600) then { - - _TTL = _TTL / 60^2; + _TTL = _TTL / 3600; _TTL = str _TTL splitString "."; if (count _TTL > 1) then { @@ -35,6 +35,5 @@ if (_TTL > 3600) then { ] }; } else { - - format ["%1m", round (_TTL / 60)]; + format ["%1m", round (_TTL / 60)] }; diff --git a/addons/arsenal/functions/fnc_updateCamPos.sqf b/addons/arsenal/functions/fnc_updateCamPos.sqf index 66bad37936..0bbfeffded 100644 --- a/addons/arsenal/functions/fnc_updateCamPos.sqf +++ b/addons/arsenal/functions/fnc_updateCamPos.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Karel Moricky, modified by Alganthe - * Update camera position + * Update camera position. * Modernized a bit, modified vars to fit arsenal rewrite. * * Arguments: @@ -10,12 +10,16 @@ * Return Value: * None * + * Example: + * call ace_arsenal_fnc_updateCamPos + * * Public: Yes -*/ + */ -GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV"]; -[GVAR(cameraHelper), [_dirH + 180, - _dirV, 0]] call bis_fnc_setobjectrotation; -GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; //--- Reattach for smooth movement +GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV"]; + +[GVAR(cameraHelper), [_dirH + 180, - _dirV, 0]] call BIS_fnc_setObjectRotation; +GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; // Reattach for smooth movement GVAR(camera) setPos (GVAR(cameraHelper) modelToWorld [0, -_distance, 0]); GVAR(camera) setVectorDirAndUp [vectorDir GVAR(cameraHelper), vectorUp GVAR(cameraHelper)]; diff --git a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf new file mode 100644 index 0000000000..0dcf3866b9 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf @@ -0,0 +1,89 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43 + * Updates the list of current items. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], [], []]; + +private _isWeapon = false; +private _indexCurrentItems = -1; + +// Add the items the player has to currentItems +{ + switch (_forEachIndex) do { + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + _x params [["_weapon", ""], ["_muzzle", ""], ["_flashlight", ""], ["_optics", ""], ["_primaryMagazine", []], ["_secondaryMagazine", []], ["_bipod", ""]]; + + // Find baseweapon of weapon + if (_weapon != "") then { + _weapon = _weapon call FUNC(baseWeapon); + }; + + _isWeapon = _forEachIndex != IDX_LOADOUT_BINO; + + // If bino, add it in a different place than regular weapons + GVAR(currentItems) set [[IDX_CURR_BINO, _forEachIndex] select _isWeapon, _weapon]; + + _indexCurrentItems = [IDX_CURR_BINO_ITEMS, IDX_CURR_PRIMARY_WEAPON_ITEMS + _forEachIndex] select _isWeapon; + + // Add weapon attachments + { + (GVAR(currentItems) select _indexCurrentItems) set [[2, 1, 0, 3] select _forEachIndex, if (_x != "") then {_x call FUNC(baseWeapon)} else {_x}]; + } forEach [_optics, _flashlight, _muzzle, _bipod]; + + // Add magazines + { + // Magazines are at index 4 & 5 in array -> That's why +4 + (GVAR(currentItems) select _indexCurrentItems) set [_forEachIndex + 4, _x param [0, ""]]; + } forEach [_primaryMagazine, _secondaryMagazine]; + }; + // Uniform + case IDX_LOADOUT_UNIFORM: { + GVAR(currentItems) set [IDX_CURR_UNIFORM, _x param [0, ""]]; + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, _x param [1, []]]; + }; + // Vest + case IDX_LOADOUT_VEST: { + GVAR(currentItems) set [IDX_CURR_VEST, _x param [0, ""]]; + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, _x param [1, []]]; + }; + // Backpack + case IDX_LOADOUT_BACKPACK: { + _x params [["_backpack", ""], ["_items", []]]; + if (_backpack != "") then { + _backpack = [_backpack, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + }; + GVAR(currentItems) set [IDX_CURR_BACKPACK, _backpack]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, _items]; + }; + // Helmet + case IDX_LOADOUT_HEADGEAR: { + GVAR(currentItems) set [IDX_CURR_HEADGEAR, _x]; + }; + // Facewear + case IDX_LOADOUT_GOGGLES: { + GVAR(currentItems) set [IDX_CURR_GOGGLES, _x]; + }; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + { + // Order of storing currentItems is different than what getUnitLoadout returns, so do some math + GVAR(currentItems) set [IDX_CURR_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex), _x]; + } forEach _x; + }; + }; +} forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout diff --git a/addons/arsenal/functions/fnc_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf index 8114b8a568..e43f06c74f 100644 --- a/addons/arsenal/functions/fnc_updateRightPanel.sqf +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Update the right panel (listnbox). * * Arguments: * 0: Right panel control - * 1: Max load of the current container + * 1: Container + * 2: If container has items * * Return Value: * None @@ -14,44 +15,45 @@ * Public: No */ -params ["_control", "_maxLoad"]; +params ["_control", "_container", "_hasItems"]; -private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; -private _curSel = lnbCurSelRow _control; +private _loadRemaining = maxLoad _container - loadAbs _container; -(lnbSize _control) params ["_rows"]; +private _item = ""; +private _color = []; +private _alpha = 1; -_maxLoad = getnumber (configfile >> "CfgVehicles" >> _maxLoad >> "maximumLoad"); -_maxLoad = _maxLoad * (1 - (progressPosition _loadIndicatorBarCtrl)); -_maxLoad = parseNumber (_maxLoad toFixed 2); // Required to avoid an issue where even though the typename returns "SCALAR" it doesn't act as one. +// Grey out items that are too big to fit in remaining space of the container +for "_row" from 0 to (lnbSize _control select 0) - 1 do { + _item = _control lnbData [_row, 0]; + _color = _control lnbColor [_row, 1]; -// Grey out items too big -for "_r" from 0 to (_rows - 1) do { - private _mass = _control getVariable (_control lnbData [_r, 0]); - private _class = _control lnbText [_r, 1]; - - private _alpha = [0.25, 1.0] select (_mass <= _maxLoad); - private _color = [1, 1, 1, _alpha]; - _control lnbSetColor [[_r, 1],_color]; - _control lnbSetColor [[_r, 2],_color]; + // Lower alpha on color for items that can't fit + _alpha = [0.25, 1] select (_container canAdd _item); + _color set [3, _alpha]; + _control lnbSetColor [[_row, 1], _color]; + _control lnbSetColor [[_row, 2], [1, 1, 1, _alpha]]; }; -// Remove all from container show / hide +private _display = ctrlParent _control; + +// If there are items inside container, show "remove all" button private _removeAllCtrl = _display displayCtrl IDC_buttonRemoveAll; -if (progressPosition _loadIndicatorBarCtrl > 0) then { +// A separate "_hasItems" argument is needed, because items can have no mass +_removeAllCtrl ctrlSetFade 0; +_removeAllCtrl ctrlShow _hasItems; +_removeAllCtrl ctrlEnable _hasItems; +_removeAllCtrl ctrlCommit FADE_DELAY; - _removeAllCtrl ctrlSetFade 0; - _removeAllCtrl ctrlShow true; - _removeAllCtrl ctrlEnable true; - _removeAllCtrl ctrlCommit FADE_DELAY; -}; +// Update weight display +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", GVAR(center) call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); -(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); +private _curSel = lnbCurSelRow _control; -// change button color if unique or too big +// Disable '+' button if item is unique or too big to fit in remaining space if (_curSel != -1) then { private _plusButtonCtrl = _display displayCtrl IDC_arrowPlus; - _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_control getVariable (_control lnbData [_curSel, 0])) > _maxLoad}); + _plusButtonCtrl ctrlEnable ((_control lnbValue [_curSel, 2]) != 1 && {_container canAdd (_control lnbData [_curSel, 0])}); _plusButtonCtrl ctrlCommit FADE_DELAY; }; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 7405950631..9b7eb6327a 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -1,8 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Update the list of unique items. + * Author: Alganthe, johnb43 + * Updates the list of unique inventory items and unique equipment. + * Unique inventory items are items within containers that can't be multiplied using the arsenal. + * Unique equipment are any items (such as weapons, containers, etc.) that can't be multiplied using the arsenal. * * Arguments: * None @@ -13,106 +15,298 @@ * Public: No */ -GVAR(virtualItems) set [18, []]; -GVAR(virtualItems) set [19, []]; -GVAR(virtualItems) set [20, []]; -GVAR(virtualItems) set [21, []]; -GVAR(virtualItems) set [22, [[], [], [], []]]; -GVAR(virtualItems) set [23, []]; -GVAR(virtualItems) set [24, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_MISC_ITEMS, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GRENADES, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_EXPLOSIVES, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_BACKPACKS, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GOGGLES, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_UNKNOWN_ITEMS, createHashMap]; -private _array = LIST_DEFAULTS select 2; -private _itemsCache = uiNamespace getVariable QGVAR(configItems); +private _configItems = uiNamespace getVariable QGVAR(configItems); -private _configCfgWeapons = configFile >> "CfgWeapons"; -private _configMagazines = configFile >> "CfgMagazines"; -private _configVehicles = configFile >> "CfgVehicles"; -private _configGlasses = configFile >> "CfgGlasses"; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgGlasses = configFile >> "CfgGlasses"; +// Remove unique equipment in every panel +private _items = createHashMap; + +private _fnc_uniqueEquipment = { + params ["_items", "_item", ["_removeAllUniqueItems", true]]; + + // Remove all unique equipment from tab + if (_removeAllUniqueItems) then { + private _itemsToDelete = []; + + { + if (!isNil "_y") then { + _itemsToDelete pushBack _x; + }; + } forEach _items; + + { + _items deleteAt _x; + GVAR(virtualItemsFlatAll) deleteAt _x; + } forEach _itemsToDelete; + }; + + // Add item as a unique equipment + if (_item != "") then { + _items set [_item, true, true]; + GVAR(virtualItemsFlatAll) set [_item, true, true]; + }; +}; + +// Add the items the player has to virtualItems as unique equipment { - switch true do { - // Weapon mag - case ( - isClass (_configMagazines >> _x) && - {_x in (_itemsCache select 2)} && - {!(_x in (GVAR(virtualItems) select 2))} - ): { - (GVAR(virtualItems) select 19) pushBackUnique _x; + switch (_forEachIndex) do { + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + _x params [["_weapon", ""], ["_muzzle", ""], ["_flashlight", ""], ["_optics", ""], ["_primaryMagazine", []], ["_secondaryMagazine", []], ["_bipod", ""]]; + + // If bino, add it in a different place than regular weapons + _items = if (_forEachIndex != IDX_LOADOUT_BINO) then { + (GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _forEachIndex + } else { + GVAR(virtualItems) get IDX_VIRT_BINO + }; + + // Remove all unique equipment in tab; Add weapon as a unique equipment + [_items, _weapon call FUNC(baseWeapon)] call _fnc_uniqueEquipment; + + private _removeUniqueItems = _forEachIndex == IDX_LOADOUT_PRIMARY_WEAPON; + + // Add weapon attachments + { + // Remove all unique equipment in tab; Add weapon attachment as a unique equipment + [(GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _forEachIndex, _x call FUNC(baseWeapon), _removeUniqueItems] call _fnc_uniqueEquipment; + } forEach [_optics, _flashlight, _muzzle, _bipod]; + + // Add magazines + { + // Remove all unique equipment in tab; Add magazine as unique equipment + [GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL, _x param [0, ""], _removeUniqueItems && {_forEachIndex == 0}] call _fnc_uniqueEquipment; + } forEach [_primaryMagazine, _secondaryMagazine]; }; - // Mag throw - case ( - isClass (_configMagazines >> _x) && - {_x in (_itemsCache select 15)} && - {!(_x in (GVAR(virtualItems) select 15))} - ): { - (GVAR(virtualItems) select 20) pushBackUnique _x; - }; + // Uniform, vest, backpack + case IDX_LOADOUT_UNIFORM; + case IDX_LOADOUT_VEST; + case IDX_LOADOUT_BACKPACK: { + _x params [["_containerClass", ""]]; - // Mag put - case ( - isClass (_configMagazines >> _x) && - {_x in (_itemsCache select 16)} && - {!(_x in (GVAR(virtualItems) select 16))} - ): { - (GVAR(virtualItems) select 21) pushBackUnique _x; - }; + // Handle preset (loaded/AI) backpacks + if (_containerClass != "" && _forEachIndex == IDX_LOADOUT_BACKPACK) then { + _containerClass = [_containerClass, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + }; - // acc - case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select 1) select 0))} && - {_x in ((_itemsCache select 1) select 0)} - ): { - ((GVAR(virtualItems) select 22) select 0) pushBackUnique _x; + // Remove all unique equipment in tab; Add container as a unique equipment + [GVAR(virtualItems) get (_forEachIndex + 1), _containerClass] call _fnc_uniqueEquipment; }; - - // acc - case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select 1) select 1))} && - {_x in ((_itemsCache select 1) select 1)} - ): { - ((GVAR(virtualItems) select 22) select 1) pushBackUnique _x; + // Helmet + case IDX_LOADOUT_HEADGEAR: { + // Remove all unique equipment in tab; Add item as a unique equipment + [GVAR(virtualItems) get IDX_VIRT_HEADGEAR, _x] call _fnc_uniqueEquipment; }; - - // acc - case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select 1) select 2))} && - {_x in ((_itemsCache select 1) select 2)} - ): { - ((GVAR(virtualItems) select 22) select 2) pushBackUnique _x; - }; - // acc - case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select 1) select 3))} && - {_x in ((_itemsCache select 1) select 3)} - ): { - ((GVAR(virtualItems) select 22) select 3) pushBackUnique _x; - }; - - // Misc - case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in (GVAR(virtualItems) select 17))} && - {!(_x in ((_itemsCache select 1) select 0))} && - {!(_x in ((_itemsCache select 1) select 1))} && - {!(_x in ((_itemsCache select 1) select 2))} && - {!(_x in ((_itemsCache select 1) select 3))} - ): { - (GVAR(virtualItems) select 18) pushBackUnique _x; - }; - - // Backpacks - case (isClass (_configVehicles >> _x)): { - (GVAR(virtualItems) select 23) pushBackUnique _x; - }; - // Facewear - case (isClass (_configGlasses >> _x)): { - (GVAR(virtualItems) select 24) pushBackUnique _x; + case IDX_LOADOUT_GOGGLES: { + // Remove all unique equipment in tab; Add item as a unique equipment + [GVAR(virtualItems) get IDX_VIRT_GOGGLES, _x] call _fnc_uniqueEquipment; + }; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + { + // Order of storing virtualItems is different than what getUnitLoadout returns, so do some math + // Remove all unique equipment in tab; Add item as a unique equipment + [GVAR(virtualItems) get (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex)), _x] call _fnc_uniqueEquipment; + } forEach _x; }; }; -} foreach _array; +} forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout + +// Get all items from unit +_items = itemsWithMagazines GVAR(center) + backpacks GVAR(center); +private _isMagazine = false; +private _isWeapon = false; +private _isGrenade = false; +private _isPut = false; +private _isMiscItem = false; +private _config = configNull; +private _simulationType = ""; +private _configItemInfo = ""; +private _hasItemInfo = false; +private _itemInfoType = 0; +private _baseWeapon = ""; +private _weapons = GVAR(virtualItems) get IDX_VIRT_WEAPONS; +private _attachments = GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS; + +{ + _isMagazine = isClass (_cfgMagazines >> _x); + _isWeapon = isClass (_cfgWeapons >> _x); + + switch (true) do { + // Magazines + case (_isMagazine): { + _config = _cfgMagazines >> _x; + _isGrenade = _x in (uiNamespace getVariable QGVAR(grenadeCache)); + _isPut = _x in (uiNamespace getVariable QGVAR(putCache)); + _isMiscItem = _x in (uiNamespace getVariable QGVAR(magazineMiscItems)); + + switch (true) do { + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && + {_isMiscItem} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; + }; + // Grenades + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES)) && + {_isGrenade} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES) set [_x, nil]; + }; + // Explosives + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)) && + {_isPut} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES) set [_x, nil]; + }; + // Primary, Handgun, Secondary weapon magazines + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) && + {!_isGrenade && {!_isPut} && {!_isMiscItem}} && + {_x in (_configItems get IDX_VIRT_ITEMS_ALL) || + {getNumber (_config >> QGVAR(hide)) == -1} || + {getNumber (_config >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL, TYPE_MAGAZINE_MISSILE]}} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) set [_x, nil]; + }; + // Unknown + default { + // Don't add items that are part of the arsenal + if ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES))} && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES))} && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL))} + ) then { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, true]; + }; + }; + }; + }; + // Weapons + case (_isWeapon): { + _config = _cfgWeapons >> _x; + _simulationType = getText (_config >> "simulation"); + _configItemInfo = _config >> "ItemInfo"; + _hasItemInfo = isClass (_configItemInfo); + _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; + _isMiscItem = _x isKindOf ["CBA_MiscItem", _cfgWeapons]; + + _baseWeapon = if (!_isMiscItem) then { + _x call FUNC(baseWeapon) + } else { + _x + }; + + switch (true) do { + // Optics + case ( + !(_baseWeapon in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_OPTICS}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x, nil]; + }; + // Flashlights + case ( + !(_baseWeapon in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_FLASHLIGHT}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x, nil]; + }; + // Muzzle attachments + case ( + !(_baseWeapon in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_MUZZLE}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x, nil]; + }; + // Bipods + case ( + !(_baseWeapon in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_BIPOD}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x, nil]; + }; + // Misc. items + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && // misc. items don't use 'baseWeapon' + {_x in (_configItems get IDX_VIRT_MISC_ITEMS) || + {_hasItemInfo && + {_isMiscItem && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]}} || + {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {_simulationType == "ItemMineDetector"}}} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; + }; + // Unknown + default { + // Don't add attachments or misc. items + if ( + !(_baseWeapon in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS)) && + {!(_baseWeapon in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && + {!(_baseWeapon in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS))} && + {!(_baseWeapon in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS))} && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS))} + ) then { + // If item is a weapon (including binos), make it unique + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, + _baseWeapon in (_weapons get IDX_VIRT_PRIMARY_WEAPONS) || + {_baseWeapon in (_weapons get IDX_VIRT_HANDGUN_WEAPONS)} || + {_baseWeapon in (_weapons get IDX_VIRT_SECONDARY_WEAPONS)} || + {_baseWeapon in (GVAR(virtualItems) get IDX_VIRT_BINO)} + ]; + }; + }; + }; + }; + // Backpacks + case (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS) set [_x, nil]; + }; + // Facewear + case (isClass (_cfgGlasses >> _x)): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES) set [_x, !(_x in (GVAR(virtualItems) get IDX_VIRT_GOGGLES))]; + }; + // Unknown + default { + // Don't add items that are part of the arsenal + if !(_x in GVAR(virtualItemsFlatAll)) then { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, true]; + }; + }; + }; +} forEach (_items arrayIntersect _items); diff --git a/addons/arsenal/functions/fnc_updateVirtualItemsFlat.sqf b/addons/arsenal/functions/fnc_updateVirtualItemsFlat.sqf new file mode 100644 index 0000000000..974624d9b8 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateVirtualItemsFlat.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43, Grim + * Updates flattened list of virtual items for checking + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +private _virtualItemsFlat = +GVAR(virtualItems); +private _weapons = _virtualItemsFlat deleteAt IDX_VIRT_WEAPONS; +private _attachments = _virtualItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; + +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItemsFlat merge [_virtualItemsFlat deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _virtualItemsFlat merge [_weapons deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _virtualItemsFlat merge [_attachments deleteAt _index, true]; +}; + +GVAR(virtualItemsFlat) = _virtualItemsFlat; diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index 12509333bb..10cd9a2553 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Verify the provided loadout. + * Author: Alganthe, johnb43 + * Verify the provided loadout: Check what items do not exist and what items aren't available in current arsenal. * * Arguments: - * 0: Loadout (getUnitLoadout format) + * 0: Loadout (CBA Extended Loadout or getUnitLoadout format) * * Return Value: * Verified loadout and missing / unavailable items list and count @@ -13,227 +13,97 @@ * Public: No */ +#define NOT_IN_ARSENAL !(_name in GVAR(virtualItemsFlat)) + params ["_loadout"]; -private _weaponCfg = configFile >> "CfgWeapons"; -private _magCfg = configFile >> "CfgMagazines"; -private _vehcCfg = configFile >> "CfgVehicles"; -private _glassesCfg = configFile >> "CfgGlasses"; -private _weaponsArray = GVAR(virtualItems) select 0; -private _accsArray = GVAR(virtualItems) select 1; +private _extendedInfo = createHashMap; -private _nullItemsAmount = 0; -private _unavailableItemsAmount = 0; +// Check if the provided loadout is a CBA extended loadout +if (count _loadout == 2) then { + _extendedInfo = +(_loadout select 1); // Copy the hashmap to prevent events from modifiyng the profileNamespace extendedInfo + if (_extendedInfo isEqualType []) then { // Hashmaps are serialized as arrays, convert back to hashmap + _extendedInfo = createHashMapFromArray _extendedInfo; + _loadout set [1, _extendedInfo]; // Also fix source variable, technically not needed but doesn't hurt + }; + _loadout = _loadout select 0; +}; + +private _name = ""; +private _itemArray = []; private _nullItemsList = []; private _unavailableItemsList = []; +private _missingExtendedInfo = []; -private _fnc_weaponCheck = { - params ["_dataPath"]; - - if (count _dataPath != 0) then { - { - if (_x isEqualType "") then { - - private _item = _x; - - if (_item != "") then { - if (isClass (_weaponCfg >> _item)) then { - if !(CHECK_WEAPON_OR_ACC) then { - - _unavailableItemsList pushBackUnique _item; - _dataPath set [_forEachIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - _dataPath set [_forEachIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - }; +// Search for all items and check their availability +private _fnc_filterLoadout = { + _this apply { + if (_x isEqualType "" && {_x != ""}) then { + _name = _x call EFUNC(common,getConfigName); + // If item doesn't exist in config, "" is returned + if (_name == "") then { + _nullItemsList pushBack _x; } else { - - if (count _x != 0) then { - private _mag = _x select 0; - - if (isClass (_magCfg >> _mag)) then { - if !(_mag in (GVAR(virtualItems) select 2)) then { - - _unavailableItemsList pushBackUnique _mag; - _dataPath set [_forEachIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _mag; - _dataPath set [_forEachIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - }; - }; - } foreach _dataPath; - }; -}; - -for "_dataIndex" from 0 to 9 do { - switch (_dataIndex) do { - case 0; - case 1; - case 2; - case 8: { - [_loadout select _dataIndex] call _fnc_weaponCheck; - }; - - case 3; - case 4; - case 5: { - private _containerArray = (_loadout select _dataIndex); - - if (count _containerArray != 0) then { - - _containerArray params ["_item", "_containerItems"]; - - if (isClass (_vehcCfg >> _item) || {isClass (_weaponCfg >> _item)}) then { - if !(CHECK_CONTAINER) then { - - _unavailableItemsList pushBackUnique _item; - _loadout set [_dataIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - } else { - - if (count _containerItems != 0) then { - { - private _currentIndex = _forEachIndex; - - switch (count _x) do { - case 2: { - - if ((_x select 0) isEqualType "") then { - - private _item = _x select 0; - - if (CLASS_CHECK_ITEM) then { - if !(CHECK_CONTAINER_ITEMS) then { - - _unavailableItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - } else { - - [(((_loadout select _dataIndex) select 1) select _currentIndex) select 0] call _fnc_weaponCheck; - }; - }; - - case 3: { - private _item = _x select 0; - - if (isClass (_magCfg >> _item)) then { - if !( - _item in (GVAR(virtualItems) select 2) || - _item in (GVAR(virtualItems) select 15) || - _item in (GVAR(virtualItems) select 16) - ) then { - - _unavailableItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - }; - }; - } foreach _containerItems; + // Check if item or its base weapon exist in the arsenal + if NOT_IN_ARSENAL then { + _name = _name call FUNC(baseWeapon); + if NOT_IN_ARSENAL then { + // This could be a backpack + private _temp = [_name, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + if (_temp == "") then { // It's not + _unavailableItemsList pushBack _name; + _name = ""; + } else { // It is + _name = _temp; + // Check if it's available again + if NOT_IN_ARSENAL then { + _unavailableItemsList pushBack _name; + _name = ""; + }; }; }; - } else { - - _nullItemsList pushBackUnique _item; - _loadout set [_dataIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; }; }; - }; - case 6: { - private _item = _loadout select _dataIndex; - - if (_item != "") then { - - if (isClass (_weaponCfg >> _item)) then { - - if !(_item in (GVAR(virtualItems) select 3)) then { - - _unavailableItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - }; - }; - - case 7: { - private _item = _loadout select _dataIndex; - - if (_item != "") then { - - if (isClass (_glassesCfg >> _item)) then { - - if !(_item in (GVAR(virtualItems) select 7)) then { - - _unavailableItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - }; - }; - - case 9: { - for "_subIndex" from 0 to 5 do { - private _item = (_loadout select _dataIndex) select _subIndex; - - if (_item != "") then { - - if (isClass (_weaponCfg >> _item)) then { - - if !(CHECK_ASSIGNED_ITEMS) then { - - _unavailableItemsList pushBackUnique _item; - (_loadout select _dataIndex) set [_subIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - (_loadout select _dataIndex) set [_subIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; - }; + _name + } else { + // Handle arrays + if (_x isEqualType []) then { + _itemArray = _x call _fnc_filterLoadout; + // If "" is given as a container, an error is thrown, therefore, filter out all unavailable/null containers + if (count _itemArray == 2 && {(_itemArray select 0) isEqualTo ""} && {(_itemArray select 1) isEqualType []}) then { + _itemArray = []; }; + _itemArray + } else { + // All other types and empty strings + _x }; }; }; }; -[_loadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList] +// Convert loadout to config case and replace null/unavailable items +// Loadout might come from a different modpack, which might have different config naming +_loadout = _loadout call _fnc_filterLoadout; + +{ + private _class = _extendedInfo getOrDefault [_x, ""]; + private _cache = missionNamespace getVariable (_x + "Cache"); + + // Previously voices were stored in lower case (speaker command returns lower case), so this is to make old loadouts compatible + if (_class != "" && {_x == QGVAR(voice)}) then { + _class = _class call EFUNC(common,getConfigName); + }; + if (_class != "" && {!(_class in _cache)}) then { + _missingExtendedInfo pushBack [_x, _class]; + _extendedInfo deleteAt _x; + }; +} forEach [QGVAR(insignia), QGVAR(face), QGVAR(voice)]; + +// Raise event for 3rd party: mostly for handling extended info +// Pass all items, including duplicates +[QGVAR(loadoutVerified), [_loadout, _extendedInfo, _nullItemsList, _unavailableItemsList, _missingExtendedInfo]] call CBA_fnc_localEvent; + +[[_loadout, _extendedInfo], _nullItemsList arrayIntersect _nullItemsList, _unavailableItemsList arrayIntersect _unavailableItemsList, _missingExtendedInfo] diff --git a/addons/arsenal/functions/script_component.hpp b/addons/arsenal/functions/script_component.hpp deleted file mode 100644 index 523addf768..0000000000 --- a/addons/arsenal/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\arsenal\script_component.hpp" \ No newline at end of file diff --git a/addons/arsenal/initSettings.inc.sqf b/addons/arsenal/initSettings.inc.sqf new file mode 100644 index 0000000000..bc093eb522 --- /dev/null +++ b/addons/arsenal/initSettings.inc.sqf @@ -0,0 +1,107 @@ +// Arsenal +private _category = LLSTRING(settingCategory); +[ + QGVAR(camInverted), + "CHECKBOX", + LLSTRING(invertCameraSetting), + _category, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(enableModIcons), + "CHECKBOX", + [LSTRING(modIconsSetting), LSTRING(modIconsTooltip)], + _category, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(fontHeight), + "SLIDER", + [LSTRING(fontHeightSetting), LSTRING(fontHeightTooltip)], + _category, + [1, 10, 4.5, 1] +] call CBA_fnc_addSetting; + +[ + QGVAR(enableIdentityTabs), + "CHECKBOX", + LLSTRING(enableIdentityTabsSettings), + _category, + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(defaultToFavorites), + "CHECKBOX", + [LSTRING(defaultToFavoritesSetting), LSTRING(defaultToFavoritesTooltip)], + _category, + false, + 2 // never overwrite the client +] call CBA_fnc_addSetting; + +[ + QGVAR(favoritesColor), + "COLOR", + [LSTRING(favoritesColorSetting), LSTRING(favoritesColorTooltip)], + _category, + [0.9, 0.875, 0.6], + 2 // never overwrite the client +] call CBA_fnc_addSetting; + +private _loadoutCategory = LLSTRING(loadoutSubcategory); + +// Arsenal loadouts +[ + QGVAR(allowDefaultLoadouts), + "CHECKBOX", + [LSTRING(allowDefaultLoadoutsSetting), LSTRING(defaultLoadoutsTooltip)], + [_category, _loadoutCategory], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(allowSharedLoadouts), + "CHECKBOX", + LLSTRING(allowSharingSetting), + [_category, _loadoutCategory], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(EnableRPTLog), + "CHECKBOX", + [LSTRING(printToRPTSetting), + LSTRING(printToRPTTooltip)], + [_category, _loadoutCategory], + false, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(loadoutsSaveFace), + "CHECKBOX", + LLSTRING(loadoutsSaveFaceSetting), + [_category, _loadoutCategory], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(loadoutsSaveVoice), + "CHECKBOX", + LLSTRING(loadoutsSaveVoiceSetting), + [_category, _loadoutCategory], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(loadoutsSaveInsignia), + "CHECKBOX", + LLSTRING(loadoutsSaveInsigniaSetting), + [_category, _loadoutCategory], + true +] call CBA_fnc_addSetting; diff --git a/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp b/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp index 0f36260026..6e90665ffc 100644 --- a/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp +++ b/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp @@ -1,3 +1,4 @@ +// These files are from the VR mission, not the base addon folder class Extended_PreInit_EventHandlers { class ADDON { init = QUOTE(call compile preprocessFileLineNumbers 'XEH_preInit.sqf'); diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf index 5b24421c20..3ce0dd54d0 100644 --- a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -8,30 +8,33 @@ cba_diagnostic_projectileMaxLines = 10; [QGVAR(displayOpened), { private _player = player; - // player pose + // Player pose [{ - switch (true) do { - case (primaryWeapon _this != ""): { - _this switchMove "amovpercmstpslowwrfldnon"; - }; - case (handgunWeapon _this != ""): { - _this switchMove "amovpercmstpslowwpstdnon"; - }; - default { + switch (currentWeapon _this) do { + case (""): { _this switchMove "amovpercmstpsnonwnondnon"; }; + case (primaryWeapon _this): { + _this switchMove "amovpercmstpslowwrfldnon"; + }; + case (handgunWeapon _this): { + _this switchMove "amovpercmstpslowwpstdnon"; + }; + case (binocular _this); + case (secondaryWeapon _this): {}; // deliberately nothing }; }, _player] call CBA_fnc_execNextFrame; - // hide everything except the player + // Hide everything except the player { _x enableSimulation false; _x hideObject true; - } forEach (allMissionObjects "" - [_player]); + } forEach (allMissionObjects "" - [_player] - attachedObjects _player); - if ((_player getVariable ["cba_projectile_firedEhId", -1]) != -1) then { + if ((_player getVariable ["CBA_projectile_firedEhId", -1]) != -1) then { _player call CBA_fnc_removeUnitTrackProjectiles; }; + _player setFatigue 0; // Esc to close mission @@ -44,6 +47,7 @@ cba_diagnostic_projectileMaxLines = 10; if (_key isEqualTo DIK_ESCAPE && {!_shift}) then { [_display] spawn { disableSerialization; + params ["_display"]; private _return = [ @@ -54,58 +58,63 @@ cba_diagnostic_projectileMaxLines = 10; ] call BIS_fnc_GUImessage; if (_return) then { - profileNamespace setVariable [QGVAR(missionLastLoadout), getUnitLoadout player]; - _display closeDisplay 2; - findDisplay 46 closeDisplay 0; + // Save loadout for next time arsenal mission is played + profileNamespace setVariable [QGVAR(missionLastLoadout), [player] call CBA_fnc_getLoadout]; + + // Quit mission + _display closeDisplay IDC_CANCEL; + findDisplay IDD_MISSION closeDisplay 0; }; }; + true }; }]; - private _buttonClose = _display displayCtrl IDC_menuBarClose; - _buttonClose ctrlSetText localize "str_a3_rscdisplayarsenal_buttonok"; + (_display displayCtrl IDC_menuBarClose) ctrlSetText localize "str_a3_rscdisplayarsenal_buttonok"; } call CBA_fnc_execNextFrame; }] call CBA_fnc_addEventHandler; [QGVAR(displayClosed), { private _player = player; - // unhide everthing + // Unhide everthing { _x enableSimulation true; _x hideObject false; } forEach allMissionObjects ""; - // update VR unit gear + private _unit = objNull; + + // Update VR unit gear { - private _unit = _x; + _unit = _x; removeVest _unit; - _unit addVest vest _player; + if (vest _player != "") then { _unit addVest vest _player; }; removeBackpack _unit; - _unit addBackpack backpack _player; - + if (backpack _player != "") then { _unit addBackpack backpack _player; }; removeHeadgear _unit; - _unit addHeadgear headgear _player; - + if (headgear _player != "") then { _unit addHeadgear headgear _player; }; removeGoggles _unit; - _unit addGoggles goggles _player; + if (goggles _player != "") then { _unit addGoggles goggles _player; }; removeAllWeapons _unit; - _unit addWeapon primaryWeapon _player; + if (primaryWeapon _player != "") then { _unit addWeapon primaryWeapon _player; }; + { _unit addPrimaryWeaponItem _x; } forEach primaryWeaponItems _player; - _unit addWeapon secondaryWeapon _player; + if (secondaryWeapon _player != "") then { _unit addWeapon secondaryWeapon _player; }; { _unit addSecondaryWeaponItem _x; } forEach secondaryWeaponItems _player; - _unit addWeapon handgunWeapon _player; + if (handgunWeapon _player != "") then { _unit addWeapon handgunWeapon _player; }; + { _unit addHandgunItem _x; } forEach handgunItems _player; diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf index 329d5fd1a5..6d6acca865 100644 --- a/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf +++ b/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf @@ -1,4 +1,6 @@ #include "script_component.hpp" +INFO("Loading VR Mission"); + PREP(onPause); PREP(createTarget); diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf index 7ff1ea58e6..502f7b888d 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -1,18 +1,26 @@ #include "script_component.hpp" +/* + * Author: commy2 + * + * Public: No +*/ params ["_type", "_position", ["_group", grpNull], "_varName"]; + private _player = player; if (isNull _group) then { - _group = creategroup east; + _group = createGroup east; }; -private _target = _group createUnit [_type, [10,10,0], [], 0, "NONE"]; +private _target = _group createUnit [_type, [10, 10, 0], [], 0, "NONE"]; +// _varName is used for respawning unit if (isNil "_varName") then { _varName = _target call BIS_fnc_netId; }; +// Set up AI _target setPos _position; _target setDir (_position getDir _player); _target doWatch position _player; @@ -30,33 +38,43 @@ _target setSpeaker "BASE"; params ["_target", "_time"]; if (speaker _target == "BASE") exitWith {time > _time}; + _target setSpeaker "BASE"; + false }, {}, [_target, time + 1]] call CBA_fnc_waitUntilAndExecute; _player reveal [_target, 4]; -_target addVest vest _player; -_target addBackpack backpack _player; -_target addHeadgear headgear _player; -_target addGoggles goggles _player; -_target addWeapon primaryWeapon _player; -_target addWeapon secondaryWeapon _player; -_target addWeapon handgunWeapon _player; +// Copy player's gear onto target +if (vest _player != "") then { _target addVest vest _player; }; +if (backpack _player != "") then { _target addBackpack backpack _player; }; +if (headgear _player != "") then { _target addHeadgear headgear _player; }; +if (goggles _player != "") then { _target addGoggles goggles _player; }; +if (primaryWeapon _player != "") then { _target addWeapon primaryWeapon _player; }; +if (secondaryWeapon _player != "") then { _target addWeapon secondaryWeapon _player; }; +if (handgunWeapon _player != "") then { _target addWeapon handgunWeapon _player; }; +// Save AI for respawn _target setVehicleVarName _varName; -missionNamespace setvariable [_varName, _target]; +missionNamespace setVariable [_varName, _target]; _target switchMove "amovpercmstpslowwrfldnon"; _target setVariable ["origin", _position]; -_target addEventHandler ["killed", { +// When killed, respawn AI +_target addEventHandler ["Killed", { params ["_target"]; + + // Killed may fire twice, 2nd will be null - https://github.com/acemod/ACE3/pull/7561 + if (isNull _target) exitWith { TRACE_1("Ignoring null death",_target); }; + private _position = _target getVariable ["origin", position _target]; private _varName = vehicleVarName _target; [_target, true] spawn BIS_fnc_VREffectKilled; + // When unit's corpse is deleted, spawn in new one of same type [{isNull (_this select 0)}, { (_this select 1) call FUNC(createTarget); }, [_target, [typeOf _target, _position, group _target, _varName]]] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf index 25e49405bf..f7536cae67 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf @@ -1,15 +1,32 @@ #include "script_component.hpp" +#include "\z\ace\addons\arsenal\defines.hpp" +/* + * Author: commy2 + * + * Public: No +*/ params ["_display"]; +// Change the abort button to a return button private _ctrlButtonAbort = _display displayCtrl 104; -_ctrlButtonAbort ctrlSetText localize LSTRING(Mission); -_ctrlButtonAbort ctrlSetTooltip localize LSTRING(ReturnToArsenal); +_ctrlButtonAbort ctrlSetText LLSTRING(Mission); +_ctrlButtonAbort ctrlSetTooltip LLSTRING(ReturnToArsenal); _ctrlButtonAbort ctrlSetEventHandler ["ButtonClick", { - params ["_control"]; - ctrlParent _control closeDisplay 2; - {[player, player, true] call FUNC(openBox)} call CBA_fnc_execNextFrame; + // Don't open arsenal unless it's the player, on foot + if (player == call CBA_fnc_currentUnit && {isNull objectParent player}) then { + params ["_control"]; + + // Close pause menu + (ctrlParent _control) closeDisplay IDC_CANCEL; + + // Open the arsenal again + { + [player, player, true] call FUNC(openBox); + } call CBA_fnc_execNextFrame; + }; + true } call EFUNC(common,codeToString)]; diff --git a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf index 111202d04e..28e19bba47 100644 --- a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf +++ b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf @@ -1,43 +1,41 @@ #include "script_component.hpp" +#include "\z\ace\addons\arsenal\defines.hpp" params ["_unit"]; private _loadout = profileNamespace getVariable QGVAR(missionLastLoadout); +// Load loadout from previous arsenal mission session if (!isNil "_loadout") then { - _unit setUnitLoadout _loadout; + [_unit, _loadout] call CBA_fnc_setLoadout; }; _unit allowDamage false; -//--- Static targets in various distance +// Static targets at various distances { - private _position = _unit getRelPos [_x, _forEachIndex]; - ["O_Soldier_VR_F", _position] call FUNC(createTarget); + ["O_Soldier_VR_F", _unit getRelPos [_x, _forEachIndex]] call FUNC(createTarget); } forEach [10, 20, 30, 40, 50, 100, 500, 1000, 2000]; -//--- Target line +// Target line to the left of the player private _position = _unit getRelPos [20, -90]; for "_i" from 0 to 5 do { - private _position = _position vectorAdd [0, -3 + _i, 0]; - ["O_Soldier_VR_F", _position] call FUNC(createTarget); + ["O_Soldier_VR_F", _position vectorAdd [0, -3 + _i, 0]] call FUNC(createTarget); }; -//--- Target cluster +// Target cluster to the right of the player _position = _unit getRelPos [20, 90]; for "_i" from 0 to 8 do { private _index = floor (_i / 3); - private _position = _position vectorAdd [_index * 1.5, 1.5 + (_i % 3), 0]; - - private _target = ["O_Soldier_VR_F", _position] call FUNC(createTarget); + private _target = ["O_Soldier_VR_F", _position vectorAdd [_index * 1.5, 1.5 + (_i % 3), 0]] call FUNC(createTarget); _target switchMove (["aidlpercmstpslowwrfldnon", "aidlpknlmstpslowwrfldnon_ai", "aidlppnemstpsraswrfldnon_ai"] select _index); _target setUnitPos (["UP", "MIDDLE", "DOWN"] select _index); }; -//--- Target patrol +// Target patrol: Spawn waypoints around player private _group = createGroup east; { @@ -51,6 +49,7 @@ private _group = createGroup east; _position = _unit getRelPos [10, 180]; +// Spawn in AI for patrol for "_i" from 0 to 1 do { private _target = ["O_Soldier_VR_F", _position] call FUNC(createTarget); @@ -60,11 +59,11 @@ for "_i" from 0 to 1 do { _target setSpeedMode "LIMITED"; }; -//--- Armored vehicles +// Armored vehicles to the rear of the player private _vehicles = []; private _step = 15; -_position = [position _unit select 0,(position _unit select 1) + 30,0]; +_position = _unit getRelPos [30, 180]; { private _row = _forEachIndex; @@ -76,7 +75,7 @@ _position = [position _unit select 0,(position _unit select 1) + 30,0]; private _vehicle = createVehicle [_x, _position, [], 0, "NONE"]; _vehicle setPos _position; _vehicle setDir 180; - _vehicle setVelocity [0,0,-1]; + _vehicle setVelocity [0, 0, -1]; _vehicle call BIS_fnc_VRHitpart; private _marker = _vehicle call BIS_fnc_boundingBoxMarker; @@ -93,23 +92,29 @@ _position = [position _unit select 0,(position _unit select 1) + 30,0]; "Land_VR_Target_MBT_01_cannon_F" ]]; -_vehicles spawn { - waituntil { - private _allDisabled = true; +private _massDestructionAchieved = getStatValue "MarkMassVirtualDestruction"; - { - _hitAlive = _x getVariable ["bis_fnc_VRHitParts_hitalive", []]; - _allDisabled = _allDisabled && ({!_x} count _hitAlive >= 2); - sleep 0.1; - } forEach _this; +// Don't check for achievement conditions if achievement already aquired +if (!isNil "_massDestructionAchieved" && {_massDestructionAchieved isEqualTo 1}) then { + _vehicles spawn { + waitUntil { + private _allDisabled = true; - _allDisabled + { + _hitAlive = _x getVariable ["BIS_fnc_VRHitParts_hitalive", []]; + _allDisabled = _allDisabled && ({!_x} count _hitAlive >= 2); + + sleep 0.1; + } forEach _this; + + _allDisabled + }; + + setStatValue ["MarkMassVirtualDestruction", 1]; }; - - setStatValue ["MarkMassVirtualDestruction", 1]; }; -//--- Cover objects +// Cover objects private _coverObjects = [ "Land_VR_CoverObject_01_kneel_F", "Land_VR_CoverObject_01_kneelHigh_F", @@ -118,42 +123,45 @@ private _coverObjects = [ "Land_VR_CoverObject_01_standHigh_F" ]; +private _coverObjectsCount = count _coverObjects; + +// Set up cover objects for "_i" from 5 to 11 do { private _direction = 180 + _i * 45; private _position = _unit getRelPos [(abs sin _direction + abs cos _direction) * 3, _direction]; - private _block = createVehicle [_coverObjects select (_i % count _coverObjects), _position, [], 0, "NONE"]; + private _block = createVehicle [_coverObjects select (_i % _coverObjectsCount), _position, [], 0, "NONE"]; _block setPos _position; }; -//--- Starting point +// Starting point private _square = createVehicle ["VR_Area_01_square_1x1_grey_F", position _unit, [], 0, "NONE"]; _square setPosASL getPosASL _unit; private _marker = createMarker [QGVAR(start), getPosWorld _unit]; _marker setMarkerType "mil_start"; -//--- Open Arsenal +// Init Arsenal [_unit, true, false] call FUNC(initBox); -[{!isNull findDisplay 46}, { +// Wait until the mission screen is available +[{!isNull findDisplay IDD_MISSION}, { [_this, _this, true] call FUNC(openBox); }, _unit] call CBA_fnc_waitUntilAndExecute; -//--- Salute +// Salute _unit addEventHandler ["AnimChanged", { params ["_unit", "_anim"]; - _anim = _anim splitString "_"; - if ("salute" in _anim) then { + if ("salute" in (_anim splitString "_")) then { { _x playAction "salute"; } forEach ((_unit nearObjects ["CAManBase", 10]) - [_unit]); }; }]; -["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0.1, [0,0.5]] spawn BIS_fnc_textTiles; +["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0.1, [0, 0.5]] spawn BIS_fnc_textTiles; -//--- Target markers +// Target markers private _markers = []; { @@ -164,12 +172,14 @@ private _markers = []; _markers pushBack _marker; } forEach (allMissionObjects "CAManBase" - [_unit]); +// Make the markers move with the targets _markers spawn { while {true} do { { private _target = missionNamespace getVariable _x; _x setMarkerPos position _target; } forEach _this; + sleep 0.1; }; }; diff --git a/addons/arsenal/missions/Arsenal.VR/mission.sqm b/addons/arsenal/missions/Arsenal.VR/mission.sqm index c43d901f6e..b23f61c1bf 100644 --- a/addons/arsenal/missions/Arsenal.VR/mission.sqm +++ b/addons/arsenal/missions/Arsenal.VR/mission.sqm @@ -1,163 +1,163 @@ version=12; class Mission { - addOns[]= - { - "A3_Map_VR", - "A3_Characters_F_BLUFOR", - "a3_characters_f_beta", - "a3_characters_f" - }; - addOnsAuto[]= - { - "A3_Characters_F_BLUFOR", - "a3_characters_f", - "A3_Map_VR" - }; - randomSeed=5486937; - class Intel - { - briefingName="@STR_A3_Arsenal"; - startWeather=0; - startWind=0.099999994; - startWaves=0.099999994; - forecastWeather=0; - forecastWind=0.099999994; - forecastWaves=0.099999994; - forecastLightnings=0.099999994; - year=2035; - month=2; - day=24; - hour=12; - minute=0; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; - class Groups - { - items=1; - class Item0 - { - side="CIV"; - class Vehicles - { - items=1; - class Item0 - { - position[]={4256,5,4192}; - azimut=180; - id=0; - side="CIV"; - vehicle="C_man_1"; - player="PLAYER COMMANDER"; - leader=1; - skill=0.60000002; - }; - }; - }; - }; - class Sensors - { - items=1; - class Item0 - { - position[]={4271.2827,5,4170.251}; - a=0; - b=0; - interruptable=1; - age="UNKNOWN"; - expCond="cheat1"; - expActiv="endmission ""end1"""; - class Effects - { - }; - }; - }; + addOns[]= + { + "A3_Map_VR", + "A3_Characters_F_BLUFOR", + "a3_characters_f_beta", + "a3_characters_f" + }; + addOnsAuto[]= + { + "A3_Characters_F_BLUFOR", + "a3_characters_f", + "A3_Map_VR" + }; + randomSeed=5486937; + class Intel + { + briefingName="@STR_A3_Arsenal"; + startWeather=0; + startWind=0.099999994; + startWaves=0.099999994; + forecastWeather=0; + forecastWind=0.099999994; + forecastWaves=0.099999994; + forecastLightnings=0.099999994; + year=2035; + month=2; + day=24; + hour=12; + minute=0; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; + class Groups + { + items=1; + class Item0 + { + side="CIV"; + class Vehicles + { + items=1; + class Item0 + { + position[]={4256,5,4192}; + azimut=180; + id=0; + side="CIV"; + vehicle="C_man_1"; + player="PLAYER COMMANDER"; + leader=1; + skill=0.60000002; + }; + }; + }; + }; + class Sensors + { + items=1; + class Item0 + { + position[]={4271.2827,5,4170.251}; + a=0; + b=0; + interruptable=1; + age="UNKNOWN"; + expCond="cheat1"; + expActiv="endmission ""end1"""; + class Effects + { + }; + }; + }; }; class Intro { - addOns[]= - { - "A3_Map_VR" - }; - addOnsAuto[]= - { - "A3_Map_VR" - }; - randomSeed=12455686; - class Intel - { - timeOfChanges=1800.0002; - startWeather=0; - startWind=0.1; - startWaves=0.1; - forecastWeather=0; - forecastWind=0.1; - forecastWaves=0.1; - forecastLightnings=0.1; - year=2035; - day=28; - hour=13; - minute=37; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=12455686; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; }; class OutroWin { - addOns[]= - { - "A3_Map_VR" - }; - addOnsAuto[]= - { - "A3_Map_VR" - }; - randomSeed=9312504; - class Intel - { - timeOfChanges=1800.0002; - startWeather=0; - startWind=0.1; - startWaves=0.1; - forecastWeather=0; - forecastWind=0.1; - forecastWaves=0.1; - forecastLightnings=0.1; - year=2035; - day=28; - hour=13; - minute=37; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=9312504; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; }; class OutroLoose { - addOns[]= - { - "A3_Map_VR" - }; - addOnsAuto[]= - { - "A3_Map_VR" - }; - randomSeed=15192082; - class Intel - { - timeOfChanges=1800.0002; - startWeather=0; - startWind=0.1; - startWaves=0.1; - forecastWeather=0; - forecastWind=0.1; - forecastWaves=0.1; - forecastLightnings=0.1; - year=2035; - day=28; - hour=13; - minute=37; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=15192082; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; }; diff --git a/addons/arsenal/missions/Arsenal.VR/script_component.hpp b/addons/arsenal/missions/Arsenal.VR/script_component.hpp index e1e6528a49..da24982170 100644 --- a/addons/arsenal/missions/Arsenal.VR/script_component.hpp +++ b/addons/arsenal/missions/Arsenal.VR/script_component.hpp @@ -1,4 +1,4 @@ -#include "\z\ace\addons\arsenal\script_component.hpp" +#include "..\..\script_component.hpp" #undef PREP // make.py can't redefine already defined macros #define PREP(var) FUNC(var) = compileFinal preprocessFileLineNumbers format ["fnc_%1.sqf", QUOTE(var)] diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index d42e27d519..cf858ec24d 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -3,42 +3,55 @@ Hide + Ocultar Cacher Verstecken Ukryj 隠す - Nascondere + Nascondi 숨김 隱藏 隐藏 Спрятать + Ocultar + Skrýt + Gizle Hide interface - Cache l'interface + Ocultar interfaz + Masque l'interface Oberfläche verstecken Ukryj interfejs - インターフェイスを隠す + インターフェースを隠す Nascondi interfaccia 인터페이스 숨기기 隱藏介面 - 隐藏介面 + 隐藏界面 Скрыть интерфейс + Oculta a Interface + Skrýt rozhraní + Arayüzü gizle Loadouts - Équipements + Equipamiento + Sets d'équipement Ausrüstungen Zestawy wyposażenia 装備 Equipaggiamenti 로드아웃 裝備 - 装备 + 负载 Комплекты + Loadouts + Sady vybavení + Kıyafetler Export + Exportar Exporter Exportieren Eksportuj @@ -46,11 +59,15 @@ Esporta 내보내기 匯出 - 汇出 + 导出 Экспорт + Exportar + Export + Dışa Aktar Import + Importar Importer Importieren Importuj @@ -58,11 +75,15 @@ Importa 가져오기 匯入 - 汇入 + 导入 Импорт + Importar + Import + Içe Aktar Close + Cerrar Fermer Schließen Zamknij @@ -72,22 +93,30 @@ 關閉 关闭 Закрыть + Fechar + Zavřít + Kapat - No virtual item available - Aucun objet virtuel disponible + No virtual items available + Ningún objeto virtual disponible + Aucun objet virtuel disponible. Kein virtuelles Objekt verfügbar Brak dostępnych przedmiotów wirtualnych - 利用可能なバーチャル アイテムはありません + 利用可能な仮想アイテムはありません Nessun oggetto virtuale disponibile 가상장비 사용 불가 沒有可用的虛擬物品 没有可用的虚拟物品 Виртуальный предмет недоступен + Nenhum item virtual disponível + Není dostupný žádný virtuální předmět + Kullanılabilir sanal öğe yok Save - Enregister + Guardar + Enregistrer Speichern Zapisz 保存 @@ -96,51 +125,61 @@ 保存 保存 Сохранить + Salvar + Uložit + Kaydet Save the current loadout - Enregistre l'équipement actuel + Guardar el equipamiento actual + Enregistre l'équipement actuel. Ausgewählte Ausrüstung speichern Zapisz obecny zestaw 現在の装備を保存します Salva l'equipaggiamento corrente 현재 로드아웃 저장 保存當前的裝備 - 保存当前的装备 + 保存当前的负载 Сохранить текущий комплект экипировки + Salva o loadout atual + Uložit současnou sadu vybavení + Geçerli kıyafetleri kaydet [Shift+Click to save to mission defaults] - [Shift + クリック] でミッション標準として保存します + [Shift+Click para guardar equipamiento predefinido + [Umschalt+Linksklick um als Standard-Missionsausrüstung zu speichern] + [Shift + クリックでミッションの標準装備として保存します] Shift + Klik aby zapisac jako domyślne dla misji [Shift+Клик, чтобы сохранить в настройках по умолчанию] - - - Rename - Renommer - Umbenennen - Zmień nazwę - 改名 - Rinomina - 이름바꾸기 - 重新命名 - 重新命名 - Переименовать + [Shift+Clique para salvar nos padrões da missão] + [Shift+Clic pour enregistrer en tant qu'équipement prédéfini.] + [Shift+左鍵來保存至任務預設] + [Shift+左鍵 以保存至任务默认值] + [Shift+Click per salvare come equipaggiamento predefinito della missione] + [Shift+Klik pro uložení jako standardního vybavení pro misi] + [Shift+Click varsayılan kıyafetlere kaydet] + [쉬프트+클릭 하여 임무 기본으로 설정] Rename the selected loadout - Renomme l'équipement sélectionné + Renombrar el equipamiento seleccionado + Renomme le set d'équipement sélectionné. Ausgewählte Ausrüstung umbenennen Zmień nazwę wybranego zestawu 選択中の装備を改名します Rinomina l'equipaggiamento selezionato 선택한 로드아웃의 이름 바꾸기 重新命名當前選擇的裝備 - 重新命名当前选择的装备 + 重命名当前选择的负载 Переименовать выбранный комплект экипировки + Renomeia o loadout selecionado + Přejmenovat vybranou sadu vybavení + Seçili kıyafetleri yeniden adlandır Load + Cargar Charger Laden Wczytaj @@ -150,21 +189,29 @@ 載入 载入 Загрузить + Carregar + Nahrát + Yükle Load the selected loadout - Charger l'équipement sélectionné + Cargar el equipamiento seleccionado + Charge le set d'équipement sélectionné. Ausgewählte Ausrüstung laden Wczytaj wybrany zestaw 選択中の装備を読み込みます Carica l'equipaggiamento selezionato 선택한 로드아웃 불러오기 載入當前選擇的裝備 - 载入当前选择的装备 + 载入当前选择的负载 Загрузить выбранный комплект экипировки + Carrega o loadout selecionado + Nahrát vybranou sadu vybavení + Seçili kıyafetleri yükle Delete + Eliminar Supprimer Entfernen Skasuj @@ -174,21 +221,29 @@ 刪除 删除 Удалить + Apagar + Smazat + Sil Delete the selected loadout - Supprimer l'équipement sélectionné + Eliminar el equipamiento seleccionado + Supprime le set d'équipement sélectionné. Ausgewählte Ausrüstung entfernen Skasuj wybrany zestaw 選択中の装備を削除します Elimina l'equipaggiamento selezionato 선택한 로드아웃 삭제하기 刪除當前選擇的裝備 - 删除当前选择的装备 + 删除当前选择的负载 Удалить выбранный комплект экипировки + Apaga o loadout selecionado + Smazat vybranou sadu vybavení + Seçili kıyafetleri sil My loadouts + Mis equipamientos Mes équipements Meine Ausrüstungen Moje zestawy @@ -196,47 +251,63 @@ I miei equipaggiamenti 내 로드아웃 我的裝備 - 我的装备 + 我的负载 Мои комплекты + Meus loadouts + Moje sady vybavení + Benim kıyafetlerim Loadouts saved in your profile - Équipements enregistrés dans votre profil + Equipamientos guardados en el perfil + Sets d'équipement enregistrés dans votre profil. Ausrüstungen, die in deinem Profil gespeichert sind Zestawy zapisane w Twoim profilu プロフィールに保存された装備です Gli equipaggiamenti salvati nel tuo profilo 프로필에 저장된 로드아웃 裝備已保存到你的設定檔中 - 装备已保存到你的设定档中 + 负载已保存到你的档案中 Комплекты экипировки, сохраненные в вашем профиле + Loadouts salvos em seu perfil + Sadz vybavení uložené ve vašem profilu + Profiline kaydedilmiş kıyafetlerin Default loadouts - Équipements de base + Equipamientos por defecto + Équipements prédéfinis Standard-Ausrüstungen Domyślne zestawy - 標準の装備 - Equipaggiamenti standard + 標準装備 + Equipaggiamenti predefiniti 기본 로드아웃 預設裝備 - 预设装备 + 默认负载 По умолчанию + Loadouts padrões + Standardní sady vybavení + Varsayılan Kıyafetler Loadouts made available by the mission maker - Équipements faits par l'auteur de la mission + Equipamientos disponibles del editor de la misión + Sets d'équipement mis à disposition par le créateur de mission. Ausrüstungen, die durch den Missionsersteller zur Verfügung gestellt worden sind Zestawy udostępnione przez twórcę misji - 装備はミッション著者によって利用できます + ミッション著者によって作成された装備です Equipaggiamenti resi disponibili dal creatore della missione 미션메이커가 허용한 로드아웃 任務作者提供的預設裝備 - 任务作者提供的预设装备 + 任务作者提供的负载 Комплекты экипировки, предоставляемые создателем миссии + Loadouts definidos pelo criador da missão + Sady vybavení od autora mise + Görevi hazırlayan kişi tarafından kullanıma sunulan teçhizatlar Public loadouts + Equipamientos públicos Équipements publics Veröffentlichte Ausrüstungen Publiczne zestawy @@ -244,59 +315,173 @@ Equipaggiamenti pubblici 공용 로드아웃 公用裝備 - 公用装备 + 公用负载 Публичные комплекты + Loadouts públicos + Veřejné sady vybavení + Herkese Açık Kıyafetler Loadouts shared by you and other players - Équipements mis à disposition par vous ou les autres joueurs + Equipamientos compartidos por ti y otros jugadores + Sets d'équipement partagés par vous-même ou par d'autres joueurs. Ausrüstungen, die von dir und anderen Spielern geteilt wurden Zestawy udostępnione przez Ciebie i innych graczy 自分か他人によって共有された装備です Equipaggiamenti condivisi da te e da altri giocatori 플레이어들이 공유하는 로드아웃 由你與其他玩家分享的裝備配置 - 由你与其他玩家分享的装备配置 + 你和其他玩家分享的负载配置 Комплекты экипировки, опубликованные вами и другими игроками + Loadouts compartilhados por você ou outros jogadores + Sady vybavení sdílené vámi a ostatními hráči + Senin veya diğer kişiler tarafından paylaşılan kıyafetler Sort by weight + Ordenar por peso Trier par poids Nach Gewicht sortieren Sortuj wg wagi - 重量で並び替え + 重量順に並び替え Ordina per peso - 무게로 정렬 + 무게 순서로 정렬 以重量排序 以重量排序 Сортировка по весу + Ordenar por peso + Seřadit podle váhy + Kiloya göre sırala Sort by amount + Ordenar por cantidad Trier par quantité Nach Menge sortieren Sortuj wg ilości - 量で並び替え - Ordina per quantitativo - 갯수로 정렬 + 数量順に並び替え + Ordina per quantità + 갯수 순서로 정렬 以數量排序 以数量排序 Сортировка по количеству + Ordenar por quantidade + Seřadit podle množství + Miktara göre sırala + + + Sort by load + Nach Tragelast sortieren + Trier par capacité de chargement + Ordina per capacità di carico + 容量順に並び替え + Ordenar por capacidad + Сортировка по вместимости + Sortuj po rozmiarze + 공간 순서로 정렬 + 以容量排序 + Ordenar por capacidade + + + Sort by accuracy + Nach Genauigkeit sortieren + Trier par précision + Ordina per precisione + 精度順に並び替え + Isabet doğruluğuna göre sırala + Ordenar por precisión + Сортировка по точности + Sortuj po celności + 정확도 순서로 정렬 + 以精度排序 + Ordenar por precisão + + + Sort by rate of fire + Nach Schussrate sortieren + Trier par cadence de tir + Ordina per cadenza di tiro + 連射速度順に並び替え + Atış hızına göre sırala + Ordenar por cadencia de tiro + Сортировка по темпу стрельбы + Sortuj po szybkostrzelności + 발사속도 순서로 정렬 + 以射速排序 + Ordenar por cadência + + + Sort by magnification + Nach Vergrößerung sortieren + Trier par grossissement + Ordina per ingrandimento + 倍率順に並び替え + Ordenar por magnificación + Сортировка по кратности приближения + Sortuj po przybliżeniu + 배율 순서로 정렬 + 以放大倍数排序 + Ordenar por magnificação + + + Sort by ammo count + Nach Munitionszahl sortieren + Trier par nombre de munitions + Ordina per numero di colpi + 装弾数順に並び替え + Mermi sayısına göre sırala + Ordenar por cantidad de munición + Сортировка по количеству боеприпасов + Sortuj po ilości amunicji + 총알 갯수 순서롤 정렬 + 以弹量排序 + Ordenar por quantidade de munição + + + Sort by ballistic protection + Trier par protection balistique + Ordina per protezione balistica + 防弾性能順に並び替え + Ordenar por protección balística + Сортировка по баллистической защите + Sortuj po ochronie balistycznej + Nach ballistischem Schutz sortieren + 방탄 성능 순서로 정렬 + 以防弹性能排序 + Ordenar por proteção balística + + + Sort by explosive protection + Trier par résistance aux explosifs + Ordina per protezione esplosiva + 防爆性能順に並び替え + Ordenar por protección de explosivos + Сортировка по защите от взрывов + Sortuj po ochronie przeciw wybuchom + Nach Explosionsschutz sortieren + 방폭 성능 순서로 정렬 + 以防爆性能排序 + Ordenar por proteção a explosivos Share or stop sharing the selected loadout - Partager ou arrêter de partager cet équipement + Compartir o dejar de compartir el equipamiento seleccionado + Partager ou cesser de partager le set d'équipement sélectionné. Ausgewählte Ausrüstung teilen oder nicht mehr teilen Udostępnij lub przestań udostępniać wybrany zestaw 選択した装備の共有設定 Condividi o smetti di condividere l'equipaggiamento selezionato - 선택한 로드아웃 공유 혹은 공유중지 + 선택한 로드아웃 공유 혹은 공유 중지 開始/停止分享當前選擇的裝備 - 开始/停止分享当前选择的装备 + 开始/停止分享当前选择的负载 Открыть или закрыть общий доступ к комплекту экипировки + Compartilhar ou parar de compartilhar o loadout selecionado + Sdílet nebo přestat sdílet vybranou sadu vybavení + Seçili kıyafeti paylaş ya da paylaşmayı durdur. Private + Privado Privé Privat Prywatny @@ -306,9 +491,13 @@ 私用 私用 Приватный + Privado + Soukromé + Özel Public + Público Public Öffentlich Publiczny @@ -318,46 +507,62 @@ 公用 公用 Публичный + Público + Veřejné + Herkese Açık The default loadouts list is empty! - La liste d'équipements de base est vide ! + La lista de equipamientos por defecto está vacía! + La liste des équipements prédéfinis est vide ! Die Standard-Ausrüstungen-Liste ist leer! Lista domyślnych zestawów jest pusta! - 標準の装備一欄が空です! - La lista degli equipaggiamenti standard è vuota! + 標準装備の一覧は空です! + La lista degli equipaggiamenti predefiniti è vuota! 기본 로드아웃 목록이 비어있습니다! 沒有預設的裝備清單! - 没有预设的装备清单! + 没有默认负载清单! Список комплекта экипировки пуст! + A lista de loadouts padrões está vazia! + Seznam standardních sad vybavení je prázdný! + Varsayılan kıyafetler listesi boş ! Default loadouts list exported to clipboard - Liste d'équipements de base exportée dans le presse papier + Lista de equipamientos por defecto exportada al portapapeles + Liste des équipements prédéfinis exportée dans le presse-papier. Standard-Ausrüstungen-Liste in die Zwischenablage exportiert Lista domyślnych zestawów została eksportowana do schowka - 標準の装備一欄はクリップボードへエクスポートされました - La lista degli equipaggiamenti standard è stata esportata negli appunti + 標準装備の一覧をクリップボードへエクスポートしました + La lista degli equipaggiamenti predefiniti è stata esportata negli appunti 클립보드에 기본 로드아웃 목록 내보내기 預設的裝備清單已匯出到剪貼簿中 - 预设的装备清单已汇出到剪贴簿中 + 默认负载清单已导出到剪贴板 Список комплекта экипировки по умолчанию экспортирован в буфер + A lista de loadouts padrões foi exportada pra área de transferência + Seznam standardních sad vybavení byl exportován do schránky + Varsayılan kıyafetler listesi panoya dışa aktar Current loadout exported to clipboard - Équipement actuel exporté dans le presse papier + Equipamiento actual exportado al portapapeles + Équipement actuel exporté dans le presse-papier. Derzeitige Ausrüstung in die Zwischenablage exportiert Obecny zestaw został eksportowany do schowka - 現在の装備はクリップボードへ出力されました + 現在の装備をクリップボードへ出力しました Equipaggiamento corrente esportato negli appunti 현재 로드아웃을 클립보드로 내보냈습니다. 當前的裝備已匯出到剪貼簿中 - 当前的装备已汇出到剪贴簿中 + 当前负载已导出到剪贴板 Текущий список комплекта экипировки экспортирован в буфер + Loadout atual foi exportado pra área de transferência + Současná sada vybavení byla exportována do schránky + Geçerli kıyafeti panoya dışa aktar Wrong format provided - Mauvais format fourni + Formato incorrecto proporcionado + Mauvais format fourni. Falsches Format verwendet Podano zły format 間違ったフォーマットが入力されました @@ -366,141 +571,189 @@ 提供的格式錯誤 提供的格式错误 Неверный формат импорта + Format incorreto fornecido + Byl dodán špatný formát + Yanlış format Default loadouts list imported from clipboard - Liste d'équipements de base importée depuis le presse papier + Lista de equipamientos importada desde el portapapeles + Liste des équipements prédéfinis importée depuis le presse-papier. Standard-Ausrüstungen-Liste aus der Zwischenablage importiert Lista domyślnych zestawów została importowana ze schowka - 標準の装備一欄はクリップボードからインポートされました - La lista degli equipaggiamenti standard è stata importata dagli appunti + 標準装備の一覧をクリップボードからインポートしました + La lista degli equipaggiamenti predefiniti è stata importata dagli appunti 클립보드에서 기본 로드아웃 가져오기 預設的裝備清單已從剪貼簿中匯入 - 预设的装备清单已从剪贴簿中汇入 + 默认负载已从剪贴板导入 Список комплекта экипировки по умолчанию импортирован из буфера + A lista de loadouts padrões foi importada da área de transferência + Seznam standardních sad vybavení byl importován ze schránky + Varsayılan kıyafetler listesini içe aktar Loadout imported from clipboard - Équipement importé depuis le presse papier + Equipamiento importado del portapapeles + Set d'é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 + Sada vybavení byla importována ze schránky + Kıyafetleri içe aktar The following loadout was deleted: - L'équipement suivant fut supprimé: + El siguiente equipamiento ha sido eliminado: + Le set d'équipement suivant a été supprimé : Folgende Ausrüstung wurde entfernt: Następujący zestaw został skasowany: - 次の装備は削除されました: + 装備を削除しました: Il seguente equipaggiamento è stato eliminato: 다음 로드아웃이 삭제됨 : 以下的裝備已被刪除: - 以下的装备已被删除: + 以下的负载已被删除: Удален комплект экипировки: + O seguinte loadout foi apagado: + Tato sada vybavení byla smazána: + Bu kıyafet silindi: The following loadout is not public anymore: - L'équipement suivant n'est plus public: + El siguiente equipamiento ha dejado de ser público: + Le set d'équipement suivant n'est plus public : Folgende Ausrüstung ist nicht mehr öffentlich: Następujący zestaw nie jest już publiczny: - 次の装備は非公開になりました: + 装備を非公開にしました: Il seguente equipaggiamento non è più pubblico: 다음 로드아웃이 더이상 공용이 아님: 以下的裝備已不再被分享: - 以下的装备已不再被分享: + 以下的负载已不再被分享: Этот комплект экипировки больше не публичный: + O seguinte loadout não é mais público: + Tato sada vybavení již není veřejná: + Bu kıyafet artık herkese açık değil : The name field is empty! - Le champ nom est vide ! + El campo de nombre está vacío! + 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! + Pole "Jméno" je prázdné! + Isim alanı boş! You are the author of this loadout - Vous êtes l'auteur de cet équipement + Tú eres el autor de este equipamiento + Vous êtes l'auteur de ce set d'équipement. Du bist der Ersteller dieser Ausrüstung Jesteś autorem tego zestawu あなたはこの装備の作者です Sei l'autore di questo equipaggiamento 이 로드아웃의 제작자입니다. 你是這個裝備的作者 - 你是这个装备的作者 + 你是这个负载的作者 Вы автор этого комплекта экипировки + Você é o autor desse loadout + Jste autorem této sady vybavení + Bu kıyafetin sahibi sensin A loadout of yours with the same name is public - Un de vos équipements avec le même nom est public + Un equipamiento tuyo con el mismo nombre ya es público + Un de vos sets d'équipement ayant le même nom est public. Eine deiner Ausrüstungen mit dem gleichen Namen ist öffentlich Jeden z Twoich zestawów nazwany tak samo jest już publiczny - あなたの装備は既に公開されているものと同名です + あなたのものと同じ名前の装備が既に公開されています Un tuo equipaggiamento con lo stesso nome è pubblico 같은 이름의 로드아웃이 공용에 있습니다. 已有相同名稱的裝備在公用分享區 - 已有相同名称的装备在公用分享区 + 已有相同名称的负载在公用分享区 Ваш комплект экипировки с таким же именем является публичным + Um loadout seu com o mesmo nome é público + Vaše sada vybavení se stejným jménem je veřejná + Bu kıyafetler zaten aynı isim de paylaşılmış. The following loadout was saved: - L'équipement suivant fut enregistré: + El siguiente equipamiento ha sido guardado: + Le set d'équipement suivant a été enregistré : Folgende Ausrüstung wurde gespeichert: Następujący zestaw został zapisany: - 次の装備は保存されました: + 装備を保存しました: Il seguente equipaggiamento è stato salvato: 다음 로드아웃이 저장됨: 以下的裝備已被保存: - 以下的装备已被保存: + 以下的负载已被保存: Сохранен комплект экипировки: + O seguinte loadout foi salvo: + Tato sada vybavení byla uložena: + Bu kıyafet kaydedildi: The following loadout was loaded: - L'équipement suivant fut chargé: + El siguiente equipamiento ha sido cargado: + Le set d'équipement suivant a été chargé : Folgene Ausrüstung wurde geladen: Następujący zestaw został wczytany: - 次の装備が読み込みされました: + 装備を読み込みました: Il seguente equipaggiamento è stato caricato: 다음 로드아웃을 불러옴: 以下的裝備已被載入: - 以下的装备已被载入: + 以下的负载已被载入: Загружен комплект экипировки: + O seguinte loadout foi carregado: + Tato sada vybavení byla načtena: + Bu kıyafet yüklendi: A loadout with the same name already exist! - Un équipement avec le même nom existe déjà ! + Ya existe un equipamiento con el mismo nombre! + Un set d'équipement ayant le même nom existe déjà ! Eine Ausrüstung mit dem gleichen Namen existiert bereits! Zestaw z tą nazwą już istnieje! - 既にその名前は装備に使われています! + 既に同じ名前の装備が存在しています! Un equipaggiamento con lo stesso nome è gia esistente! 같은 이름의 로드아웃이 이미 존재합니다! 已有相同名稱的裝備! - 已有相同名称的装备! + 已有相同名称的负载! Комплект с таким именем уже существует! + Um loadout com o mesmo nome já existe! + Již existuje sada vybavení se stejným jménem! + Aynı isim de başka kıyafetler var! was renamed to - fut renommé en + ha sido renombrado a + a été renommé en wurde umbenannt in zmienił nazwę na - 次の名前に変更されました - E' stato rinominato in + を次の名前に変更しました: + È stato rinominato in 이름이 다음과 같이 변경됨: 已被改名為 已被改名为 был переименован в + foi renameado para + bylo přejmenováno na + değişti, yeni isim Invert camera controls + Invertir controles de cámara Inverser les contrôles de la caméra Kamerasteuerung invertieren Odwróć sterowanie kamerą @@ -510,9 +763,13 @@ 反轉攝影機控制 反转摄影机控制 Инвертировать управление камерой + Inverter controles da câmera + Obrátit ovládání kamery + Kamera kontrollerini ters çevir Enable mod icons + Habilitar iconos de mods Afficher les icônes de mod Aktiviert Mod-Icons Włącz ikony modów @@ -521,47 +778,63 @@ 모드 아이콘 허가 啟用模組圖示 启用模组图示 - Включить иконки модов + Вкл. иконки модов + Ativar ícones de mods + Zapnout ikony modů + Mod simgelerini etkinleştir Panel font height - taille de police des panneaux + Tamaño de fuente del panel + Taille de police des panneaux Schrifthöhe für die linke und rechte Liste Wysokość czcionki - パネルにあるフォントの高さ + パネルのフォントの高さ Altezza carattere del pannello 패널 폰트 높이 面板字體高度 面板字体高度 Размер шрифта панели + Altura da fonte do painel + Výška fontu panelů + Panel yazı tipi büyüklüğü Allow default loadouts - Activer l'onglet équipement de base + Permitir equipamientos por defecto + Autoriser les équipements prédéfinis Erlaubt die Benutzung der Standardausrüstungen Zezwól na użycie domyślnych zestawów - 標準の装備を許可 - Consenti equipaggiamenti standard + 標準装備を許可 + Consenti equipaggiamenti predefiniti 기본 로드아웃 허용 允許預設裝備 - 允许预设装备 + 允许默认负载 Разрешить комплекты по умолчанию + Permitir loadouts padrões + Povolit standardní sady vybavení + Varsayılan kıyafetlere izin ver Allow loadout sharing - Autoriser le partage d'équipement + Permitir compartir equipamientos + Autoriser le partage des sets d'équipement Erlaubt das Teilen von Ausrüstungen Zezwól na udostępnianie zestawów - 装備の共有を許可 + 装備共有を許可 Consenti condivisione equipaggiamenti 로드아웃 공유 허용 允許分享裝備 - 允许分享装备 + 允许分享负载 Разрешить публикацию комплектов + Permitir compartilhar loadouts + Povolit sdílení sad vybavení + Kıyafet paylaşmaya izin ver Log missing / unavailable items - Enregistrer les objets manquants + Registrar los objetos no encontrados o no disponibles + Consigner les objets manquants ou indisponibles Aktiviert die Aufzeichnung fehlender Gegenstände in der RPT Rejestruj brakujące / niedostępne przedmioty 欠落 / 利用不可アイテムを記録 @@ -570,9 +843,13 @@ 記錄遺失/無法使用的項目 记录遗失/无法使用的项目 Вести журнал недоступных предметов + Registrar em log itens indisponíveis/não encontrados + Zalogovat chybějící/nedostupné předměty + Kayıp / mevcut olmayan öğeleri günlüğe kaydet Primary magazine + Cargador principal Chargeur principal Główny magazynek プライマリ弾倉 @@ -580,11 +857,15 @@ 주무기 탄약 Primärmagazin 主要武器彈匣 - 主要武器弹匣 + 主武器弹匣 Основной магазин + Carregador Primário + Hlavní zásobník + Birinci Cephane Secondary magazine + Cargador secundario Chargeur secondaire Dodatkowy magazynek セカンダリ弾倉 @@ -592,203 +873,293 @@ 보조무기 탄약 Sekundärmagazin 次要武器彈匣 - 次要武器弹匣 + 副武器弹匣 Вторичный магазин + Carregador Secundário + Vedlejší zásobník + Ikinci Cephane ACE Arsenal + ACE Arsenal ACE Arsenal ACE-Arsenal ACE Arsenał ACE 武器庫 ACE Arsenale - ACE 아스날 + ACE 무기고 ACE虛擬軍火庫 - ACE虚拟军火库 + ACE 虚拟军火库 ACE Арсенал + ACE Arsenal + ACE Arzenál + ACE Arsenal + + + Loadouts + Equipamiento + Sets d'équipement + Ausrüstungen + Zestawy wyposażenia + 装備 + Equipaggiamenti + 로드아웃 + 裝備 + 负载 + Комплекты + Loadouts + Sady vybavení + Kıyafetler Allow the use of the default loadouts tab - Autorise l'usage de l'onglet équipements de base + Permitir el uso de la pestaña de equipamientos por defecto + Active l'onglet "Équipements prédéfinis". Zezwól na użycie zakładki domyślnych zestawów - 標準の装備タブの使用を許可します - Consenti l'uso della sezione per gli equipaggiamenti standard + 標準装備タブの使用を許可します + Consenti l'uso della sezione per gli equipaggiamenti predefiniti 기본 로드아웃 탭 사용 허가 Erlaube die Nutzung des Standardausrüstungsreiters 允許使用預設的裝備 - 允许使用预设的装备 + 允许使用默认的负载 Разрешить использование вкладки комплектов экипировки по умолчанию + Permite o uso da aba de loadouts padrões + Povolit používání záložky standardních sad vybavení + Varsayılan Kıyafetler sekmesinin kullanımına izin ver Show / hide mod icons for the left panel - Montrer / cacher les icones de mod pour le panneau de gauche + Mostrar / ocultar iconos de mods en el panel izquierdo + Affiche/masque les icônes de mod du panneau gauche. Pokaż / ukryj ikony modów w lewym panelu - 左パネルにある MOD アイコンの表示 / 非表示をします + 左パネルにあるMODアイコンを表示/非表示します Mostra / nascondi le icone delle mod dal pannello sinistro 왼쪽 패널의 모드 아이콘 표시 / 숨기기 Zeigt/Versteckt Mod-Symbole in der linken Leiste 在左面板中顯示/隱藏模組圖示 在左面板中显示/隐藏模组图示 Показать / скрыть значки модов в левой панели + Mostra / Esconde os ícones de mods no painel esquerdo + Ukázat/Skrýt ikony modů v levém panelu + Sol panel de mod ikonlarını göster/gizle Change the font height for text in the left / right panels - Change la taille de police du texte des panneaux gauche / droite + Cambiar el tamaño de fuente para el texto de los paneles izquierdo y derecho + Change la taille de police des panneaux latéraux. Zmień wysokość czcionki dla tekstu lewego i prawego panelu - 右か左パネルにあるフォントの高さを変更します。 + 左右パネル内の文字フォントの高さを変更します。 Cambia l'altezza del font per il testo sul pannello sinistro / destro 왼쪽 / 오른쪽 패널 텍스트의 글꼴 높이 변경 Ändert die Schriftgröße für die linke/rechte Leiste 變更左/右面板中的字體高度 变更左/右面板中的字体高度 Изменить размер шрифта для текста в левой / правой панелях + Muda o tamanho da fonte para os textos nos painéis esquerdo e direito + Změnit výšku fontu pro text v levém/pravém panelu + Sağ ve sol panel de ki yazıların boyutunu değiştir. Log missing / unavailable items in the RPT - Enregistre les objets manquants / indisponibles dans le RPT + Registrar elementos no encontrados o no disponibles en el RPT + Consigne les objets manquants ou indisponibles dans le RPT. Rejestruj brakujące / niedostępne przedmioty do pliku RPT - PRT で欠落 / 利用不可アイテムを記録します + PRTに欠落/利用不可アイテムを記録します Log mancante / oggetto non disponibile nell' RPT RPT에 누락 된 항목 / 사용할 수없는 항목 기록 Fehlende Gegenstände werden in der RPT aufgezeichnet 記錄遺失/無法使用的項目到RPT檔案中 - 记录遗失/无法使用的项目到RPT档案中 + 记录遗失/无法使用的项目到 RPT Вести журнал отсутствующих / недоступных предметов в RPT + Registrar em log itens indisponíveis no RPT + Zalogovat chybějící/nedostupné předměty do RPT logu + Kayıp / mevcut olmayan öğeleri RPT'nin içine kaydet. Unable to open ACE arsenal - Impossible d'ouvrir ACE arsenal + No es posible abrir el arsenal de ACE + Impossible d'ouvrir l'arsenal ACE. Kann ACE-Arsenal nicht anzeigen Impossibile aprire l'arsenale ACE ACE 武器庫を開けません ACE 아스날을 열 수 없음 無法開啟ACE虛擬軍火庫 - 无法开启ACE虚拟军火库 + 无法开启 ACE 虚拟军火库 Nie można otworzyć arsenału ACE Невозможно открыть ACE Арсенал + Não foi possível abrir o ACE Arsenal + Nepodařilo se otevřít ACE Arzenál + ACE Arsenal açılamıyor Import BI VA loadouts to ACE Arsenal - Importe les loadouts de BI VA dans ACE Arsenal + Importar equipamientos de BI Arsenal hacia el arsenal de ACE + Importer les sets BI VA dans l'arsenal ACE Importiert die BI-VA-Ausrüstungen in das ACE-Arsenal - 標準の VA 装備から ACE 武器庫へ取り込み - 바닐라 로드아웃을 ace 아스날로 가져오기 + BI 武器庫の装備を ACE 武器庫へインポート + 바닐라 로드아웃을 ACE 아스날로 가져오기 匯入BI原廠虛擬軍火庫的裝備到ACE虛擬軍火庫中 - 汇入BI原厂虚拟军火库的装备到ACE虚拟军火库中 + 导入 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 + Importovat sady vybavení z BI VA do ACE Arzenálu No player unit available! Place a unit and mark it as "Player". - Aucune unité joueur disponible ! Placez une unité et marquez la en tant que "joueur". + Ninguna unidad de jugador disponible! Coloca una unidad y márcala como "Jugador". + Aucune unité joueur disponible ! Placez une unité et marquez-la en tant que "joueur". Keine Spielereinheit verfügbar. Setze eine Einheit und markiere sie als "Spieler". - プレイヤー ユニットがありません!ユニットを設置し"Player"と名付けてください。 + プレイヤーユニットがありません!ユニットを設置し"プレイヤー"に設定してください。 플레이어 유닛을 사용할 수 없습니다! 유닛을 놓고 "플레이어"라고 표시하십시오. 沒有可用的玩家單位!請擺放一個單位並設定成"玩家" - 没有可用的玩家单位!请摆放一个单位并设定成"玩家"。 + 没有可用的玩家单位!请摆放一个单位并设定成“玩家”。 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". + Žádná jednotka hráče není dostupná! Umístěte jednotku a nastavte ji jako "Hráč". No loadouts to import. - Aucun loadout à importer. + No hay equipamientos para importar. + Aucun équipement à importer. Keine Ausrüstungen zum Importieren インポートする装備がありません。 - 가져올 로드 아웃이 없습니다. + 가져올 로드아웃이 없습니다. 沒有裝備被匯入 - 没有装备被汇入。 + 没有负载被导入。 Non ci sono equipaggiamenti da importare. Brak zestawów wyposażenia do zaimportowania. Нет комплектов для импорта + Nenhum loadout para importar. + Žádné sadz vybavení k importu. + Hiç bir kıyafet içe aktarılmadı. ACE Arsenal + ACE Arsenal ACE-Arsenal ACE 武器庫 - ACE 아스날 + ACE 무기고 ACE虛擬軍火庫 - ACE虚拟军火库 + ACE 虚拟军火库 Arsenale ACE Arsenał ACE ACE Арсенал + ACE Arsenal + Arsenal ACE + ACE Arzenál + ACE Arsenal Return to ACE Arsenal. + Volver al arsenal de ACE Zurück zum ACE-Arsenal. ACE 武器庫へ戻ります。 - ACE 아스날로 돌아가기 + ACE 무기고로 돌아가기 返回到ACE虛擬軍火庫 - 返回到ACE虚拟军火库。 + 返回到 ACE 虚拟军火库。 Torna all'arsenale ACE Wróć do arsenału ACE. Вернуться в ACE Арсенал + Voltar para o ACE Arsenal + Retour à l'arsenal ACE + Vrátit se do ACE Arzenálu + ACE Arsenal'e dön. Use ACE Arsenal to try out different weapons and equipment. + Usar el arsenal de ACE para probar diferentes armas y equipamiento. Verwende ACE-Arsenal und sieh dir verschiedene Waffen und Ausrüstung an und probiere sie aus. 様々な武器と装備を試せるよう ACE 武器庫を使用します。 - ACE Arsenal을 사용하여 다른 무기와 장비를 시험해보십시오. + ACE 무기고를 사용하여 다른 무기와 장비를 시험해보십시오. 使用ACE虛擬軍火庫來嘗試不同的武器與裝備 - 使用ACE虚拟军火库来尝试不同的武器与装备。 + 使用 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. + Utilisez l'arsenal ACE pour essayer différentes armes ou équipements. + Použijte ACE Arzenál k vyzkoušní různých zbraní a výbavy. Try weapons and equipment and create your own loadouts. + Probar armas y equipo y crear tus propios equipamientos. Probiere verschiedene Waffen und Ausrüstung aus und stelle dir eigene Ausrüstungsprofile zusammen. 様々な武器と装備を試して、あなただけの装備を作成してください。 무기와 장비를 사용해보고 자신의 로드아웃을 만듭니다. 嘗試不同的武器與裝備來組合你個人的裝備配置 - 尝试不同的武器与装备来组合你个人的装备配置。 + 尝试不同的武器与装备来组合你个人的负载配置。 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. + Essayez des armes et du matériel et créez vos propres sets d'équipement. + Vyzkoušejte zbraně a výbavu a vytvořte si vlastní sady vybavení. Open the loadouts screen + Abrir la pantalla de equipamientos Öffnet das Ausrüstungsmenü - Affiche la page des équipements + Affiche les sets d'équipement. 開啟裝備選單 - 开启装备选单 + 开启负载菜单 装備画面を開く Apri la pagina degli equipaggiamenti Otwórz ekran zestawów Открыть окно комплектов экипировки + Abre a tela de loadouts + Otevřít obrazovku se sadami vybavení + Kıyafetler ekranını aç + 로드아웃 화면 열기 Export current / default loadouts + Exportar el equipamiento actual / predefinido Exportiert aktuelles / standard Loadout - Exporte l'équipement actuel ou la liste d'équipements de base + Exporte le set d'équipement actuel/les sets prédéfinis. 匯出當前/預設的裝備 - 汇出当前/预设的装备 + 导出当前/预设的装备 現在/標準装備をエクスポートします Esporta l'equipaggiamento attuale oppure la lista degli equipaggiamenti di base Eksportuj obecne / domyślne zestawy wyposażenia Экспорт комплектов экипировки + Exporta loadout atual / loadouts padrões + Exportovat současný/standardní sady vybavení + 현재/기본 로드아웃을 내보냅니다 Import current / default loadouts + Importar el equipamiento actual / predefinido Importiert aktuelles / standard Loadout - Importer l'équipement actuel ou la liste d'équipements de base + Importe le set d'équipement actuel/les sets prédéfinis. 匯入當前/預設的裝備 - 汇入当前/预设的装备 + 导入当前/预设的负载 現在/標準装備をインポートします Importa l'equipaggiamento attuale oppure la lista degli equipaggiamenti di base Importuj obecne / domyślne zestawy wyposażenia Импорт комплектов экипировки + Importa loadout atual / loadouts padrões + Importovat současný/standardní sady vybavení + 현재/기본 로드아웃 을 불러옵니다 Potassium levels + Niveles de potasio + Kaliumspiegel Taux de potassium - カリウム レベル 钾水平 鉀水平 - Ilvello di potassio + Livello di potassio Poziomy potasu Уровень Калия + Níveis de Potássio + Úrovně draslíku + Potasyum seviyeleri + カリウム含有量 + 칼륨 레벨 Magnification @@ -800,7 +1171,7 @@ Увеличение Vergrößerung Zvětšení - Aumentox + Aumento 배율 放大倍数 拡大倍率 @@ -808,46 +1179,168 @@ Nightvision Support + Soporte de visión nocturna Nachtsicht Unterstützung - 暗視装置への対応有無 + 暗視装置への対応 Wsparcie noktowizyjne Supporto visore notturno Поддержка ночного видения + Suporte de Visão Noturna + Support JVN + 夜視鏡支援 + 支持夜视仪 + Podpora nočního vidění + Gece Görüş Desteği + 야간투시 지원 Primary supported + Primaria soportada Primär unterstützt プライマリが対応 Wspierane przez broń główną Primario supportato Поддерживается осн. прицелом + Primária suportada + Primaire supportée + 主武器支援 + 主镜支持 + Hlavní část hledí podporuje + 주무기 지원 Secondary supported + Secundaria soportada Sekundär unterstützt セカンダリが対応 Wspierane przez broń drugorzędną Secondario supportato Поддерживается доп. прицелом + Secundária suportada + Secondaire supportée + 次要武器支援 + 副镜支持 + Vedlejší část hledí podporuje + 보조무기 지원 - + Primary integrated + Primaria integrada Primär Integriert プライマリに内蔵 Zintegrowane z bronią główną Primario integrato Интегрирован в осн. прицел + Primária integrada + Primaire intégrée + 整合主武器 + 主镜内置 + Integrováno do hlavní části hledí + 주무기 내장 + + + Thermal integrated + Termico integrato + 熱画像装置内蔵 + Интегрирован тепловизор. + 열화상 내장 + Thermique intégrée + Thermal integriert + Térmica integrada + + + Thermal & Primary integrated + Termico e Primario integrato + 熱画像装置内蔵・プライマリに内蔵 + Интегрирован тепловизор и осн.прицел. + 열화상과 주무기 내장 + Thermique et primaire intégrés + Thermal und in Primärwaffe integriert + Térmica y Primaria integrada Not Supported + No soportada Nicht unterstützt - セカンダリに内蔵 + 非対応 Nie wspierane Non supportato Не поддерживается + Não suportado + Non supporté + 不支援 + 不支持 + Není podporováno + Desteklenmiyor + 지원되지 않음 + + + Vision Mode + Sichtmodus + 映像モード + Modalità Visiva + 視覺模式 + 视觉模式 + 보기 모드 + Mode de vision + Tryb Wizji + Режим видения + Modo de Visão + Režim sledování + Görüş Modu + Modo de visión + + + Normal + Normal + Normalna + Normal + Нормальное + Normální + Normal + Normale + Normale + 通常 + 일반 + 正常 + 正常 + Normal + + + Night + Nacht + Noc + Visão Norturna + Ночное + Noční + Nocturna + Notturno + Nocturne + 暗視 + 야간 + 夜视 + 夜視 + Gece + + + Thermal + Wärme + Termo + Térmica + Тепловизор + Termální + Térmica + Termico + Thermique + 熱画像 + 열상 + 热成像 + 熱成像 + Termal Page + Página Seite Page ページ @@ -856,39 +1349,56 @@ Pagina Strona Стр. + Página + Stránka + Sayfa + 페이지 Enable the faces / voices / insignias tabs + Habilitar las pestañas de caras / voces / insignias Aktiviere die Gesichter-, Stimmen- und Abzeichenübersicht - Activer les onglets faces / voix / insignes - 顔 / 声 / 記章タブを有効化 - 启用脸谱/声音/徽章/选项 + Activer les onglets visages/voix/insignes + 顔/声/バッジ(記章)タブを有効化 + 启用脸谱/语音/徽章选项 啟用臉譜/聲音/徽章選項 Abilita volti, voci e insegne Aktywuj zakładki twarz / głos / insygnia - Включить вкладки Лиц / Голосов / Знаков различия + Вкл. вкладки: лица, голоса, эмблемы + Ativar as abas de rostos / vozes / insígnias + Povolit záložky s tvářemi, hlasy a insigniemi + Yüzler/sesler/peçler bölmelerini etkinleştir + 얼굴/음성/부대마크 탭 활성화 Empty the selected container + Vaciar el contenedor seleccionado Aktuellen Container leeren Vider le conteneur selectionné 選択されたコンテナは空です - 选择的箱子是空的 + 选择的容器是空的 清空選擇的箱子 Svuota il contenitore selezionato Opróżnij wybrany pojemnik Очистить контейнер + Esvaziar o cointâiner selecionado + Vyprázdnit vybraný nosič + 선택한 보관함 비우기 Exported class name to clipboard + Exportar el nombre de clase al portapapeles Der Klassenname wurde in die Zwischenablage exportiert - Nom de classe exporté dans le presse papier + 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 + Jméno třídy exportováno do schránky + 클래스 이름 복사하기 Mode @@ -912,7 +1422,7 @@ Lista blanca Whitelist Seznam povolených - Lista branca + Lista Branca Liste blanche Fehérlista Вайтлист @@ -921,14 +1431,23 @@ 화이트리스트 白名單 白名单 + Beyaz Liste Blacklist + Lista negra Blacklist 禁止リスト Lista Nera Czarna lista (lista wykluczeń) Чёрный список + Lista Negra + Liste noire + 黑名單 + 黑名单 + Seznam zakázaných + Kara Liste + 블랙리스트 Items @@ -948,41 +1467,274 @@ Export current items list as an array for use in scripts + Exportar la lista actual de objetos como una tabla para su uso en scripts Exportiert aktuelle Gegenstände als Array, um es in Scripten zu verwenden - スクリプト用に現在のアイテム リストをアレイでエクスポートします + スクリプト用に現在のアイテムリストをアレイでエクスポートします Esporta l'attuale lista di elementi come un array, per essere usati negli script Eksportuj obecną listę przedmiotów jako tablicę do wykorzystania w skryptach + Exportar a lista atual de itens como uma matriz para usar em scripts Экспорт текущего списка предметов в виде массива для использования в скриптах + Exporte l'équipement actuel dans le presse-papier, sous la forme d'un tableau à utiliser dans les scripts. + 匯出目前的物品列表為陣列用於腳本編寫 + 导出目前的物品列表为排列以用于脚本编写 + Exportovat současný seznam předmětů jako pole pro použití ve skriptech + 스크립트에서 사용을 위해 현재 항목 목록을 배열로 내보내기 Import items list array from clipboard (should be the same format as export) + Importar tabla de lista de objetos desde el portapapeles (debe ser el mismo formato que la lista exportada) 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) + Importe un tableau d'équipements depuis le presse-papier (le format doit être identique à celui de l'exportation). + 從剪貼簿匯入物品列表之陣列(應該與匯出的格式一樣) + 从剪贴板导入物品列表排列(应与导出的格式一样) + Importa elenco appunti (deve essere nello stesso formato di un elenco esportato) + Importovat pole se seznamem předmětů ze schránky (měl by být ve stejném formátu jako export) + 클립보드에서 항목 목록을 배열로 가져옵니다(내보내기와 동일한 형식이어야 함). Add Compatible Items + Añadir objetos compatibles Füge kompatible Gegenstände hinzu Dodaj kompatybilne przedmioty 対応アイテムを追加 Добавить совместимые предметы + Adicionar itens compatíveis + Ajouter des objets compatibles + 增加相容的物品 + 添加兼容物品 + Aggiungi Oggetti Compatibili + Přidat kompatibilní předměty + 호환 아이템 추가 Will automatically add compatible attachments or magazines (based on selected category) for all weapons in current items list + Añade automáticamente accesorios o cargadores (de la categoría seleccionada) a todas las armas de la lista de objetos Es werden automatisch kompatible Aufsätze oder Magazine für alle ausgewählten Waffen hinzugefügt Automatycznie doda kompatybilne dodatki oraz magazynki (odpowiednio do każdej kategorii) dla wszystkich broni na liście - 現在のアイテム リスト内にある全武器に対応するアタッチメントと弾倉 (選択したカテゴリに基づき) を自動的に追加します + 現在のアイテムリスト内の全武器に対応する アタッチメントと弾倉(選択したカテゴリに基づく)を自動的に追加します Добавляет совместимые приспособления или магазины (в зависимости от выбранной категории) для всего оружия в текущем списке предметов + Irá automaticamente adicionar acessórios ou carregadores (baseado na categoria selecionada) para todas as armas na lista de itens atual + Ajoute automatiquement des accessoires ou des chargeurs compatibles (en fonction de la catégorie sélectionnée), pour toutes les armes de la liste actuelle. + 將會自動增加相容的配件以及彈匣(基於選擇的類型)至妳目前物品列表中的全部武器 + 将自动为当前物品列表中的所有武器添加兼容的配件或弹匣(基于选定的类别) + Aggiungerà automaticamente accessori o caricatori (in base alla categoria selezionata) per tutte le armi nell'elenco degli oggetti correnti + Automaticky přídá kompatibilní zásobníky (na základě vybrané kategorie) ro všechny zbraně v současném seznamu předmětů + 현재 아이템 목록에 있는 모든 무기에 해당하는부착물과 탄창(선택한 카테고리에 따라)을 자동으로 추가합니다. Time to live + Tiempo de vida Lebenszeit - Durée de vie - 有効時間 + Durée d'expiration + 効力持続時間 Czas by żyć - Scadenza (TTL) + Tempo di vita Время действия + Time to live + 有效時間 + 有效时间 + Time to live + Bitme Süresi + 유효 시간 + + + Fuse Time + Retard avant détonation + Задержка детонации + Opoźnienie zapalnika + 信管設定時間 + Tempo di spoletta + Tiempo de espoleta + Detonationsverzögerung + 引信时间 + 신관 시간 + Atraso de detonação + + + Detonates on impact + Aufschlagzünder + Spoletta a impatto + Détonation à l'impact + Детонация от удара + Detonuj przy uderzeniu + 着発信管 + Detona mediante impacto + 碰炸引信 + 충격 신관 + Detona por impacto + + + Save Face + 얼굴 저장 + Сохранить лицо + Guardar Cara + Salva faccia + 顔の保存 + Zapisz Twarz + Gesicht Speichern + Sauvegarder le visage + Salvar Rosto + + + Save Voice + 목소리 저장 + Сохранить голос + Guardar Voz + Salva voce + 声の保存 + Zapisz Głos + Stimme Speichern + Sauvegarder la voix + Salvar Voz + + + Save Insignia + 계급장 저장 + Сохранить эмблему + Guardar Insignia + Salva insegna + バッジ(記章)の保存 + Zapisz Naszywkę + Insignia Speichern + Sauvegarder l'insigne + Salvar Insígnia + + + Descending + 降順 + Malejąco + Absteigend + Decrescente + 내림차순 + Décroissant + Decrescente + Нисходящий + Descendiente + + + Ascending + 昇順 + Rosnąco + Aufsteigend + Ascendente + 오름차순 + Croissant + Crescente + Восходящий + Ascendiente + + + Tools + Nástroje + Werkzeuge + Инструменты + Narzędzia + Strumenti + Herramientas + Outils + 工具 + ツール + 도구 + Ferramentas + 工具 + Araçlar + + + Ammo count + 弾薬数 + Ilość amunicji + Munitionszahl + Numero di colpi + 장탄 수 + Nombre de munitions + Quantidade de munição + Количество боеприпасов + Cantidad de munición + + + Illuminators + Illuminateurs + Illuminanti + Leuchtmittel + 조명 + Iluminadores + イルミネーター + Осветители + Iluminadores + + + Default to Favorites + お気に入りを標準に + Domyślnie do Ulubionych + Mostra solo Preferiti come predefinito + Standardmäßig auf Favoriten eingestellt + 즐겨찾기 기본값 + Favoris par défaut + Favoritos por padrão + По умолчанию - Избранное + Favoritos por defecto + + + Controls whether the ACE Arsenal defaults to showing all items or favorites. + ACE 武器庫が標準ですべてのアイテムを表示するか、お気に入りを表示するかを制御します。 + Kontroluje, czy ACE Arsenal domyślnie wyświetla wszystkie przedmioty, czy tylko ulubione. + Controlla se lo stato predefinito dell'arsenale ACE mostra tutti gli oggetti o solo i preferiti. + Steuert, ob das ACE Arsenal standardmäßig alle Gegenstände oder nur Favoriten anzeigt. + ACE 아스널이 기본적으로 모든 아이템 또는 즐겨찾기를 표시할 지 여부를 조정합니다. + Contrôle si l'arsenal ACE affiche par défaut tous les éléments ou les favoris. + Controla se o Arsenal ACE exibe por padrão todos os itens ou favoritos. + Определяет, будет ли в арсенале ACE по умолчанию отображаться все предметы или избранное. + Controla si el Arsenal de ACE muestra por defecto todos los objetos o sólo los favoritos + + + Favorites Color + お気に入りの色 + Kolor Ulubionych + Favoritenfarbe + Colore preferiti + 즐겨찾기 색상 + Couleurs favorites + Cor dos favoritos + Избранный цвет + Color de Favoritos + + + Highlight color for favorited items. + お気に入りアイテムのハイライト色。 + Kolor podświetlenia ulubionych elementów. + Hervorhebungsfarbe für Lieblingsgegenstände. + Colore che mette in mostra i preferiti nella lista. + 즐겨찾기한 아이템을 색상으로 강조합니다. + Met en surbrillance les éléments favoris. + Cor de destaque para itens favoritados. + Выделите цветом любимые предметы. + Color de marcado para los objetos favoritos + + + Switch between displaying all items or your favorites.\nDouble click while holding Shift to add or remove an item. + アイテムをすべて表示するかお気に入りのみを表示するかを切り替えます。\nアイテムをお気に入りに追加または削除するには、Shiftキーを押しながらダブルクリックします。 + Przełączanie między wyświetlaniem wszystkich przedmiotów lub tylko ulubionych. \nKliknij dwukrotnie, przytrzymując Shift, aby dodać lub usunąć przedmiot. + Wechseln Sie zwischen der Anzeige aller Elemente oder Ihrer Favoriten.\nDoppelklicken Sie bei gedrückter Umschalttaste, um ein Element hinzuzufügen oder zu entfernen. + Cambia tra mostrare tutti gli oggetti o solo i tuoi preferiti.\nShift + Doppio Click per aggiungere o rimuovere un preferito. + 모든 아이템을 표시하거나 즐겨찾기를 표시할 때 전환합니다\nShift 키를 누른 상태에서 두 번 클릭하여 아이템을 추가하거나 제거합니다. + Change entre l'affichage de tous les éléments ou de vos favoris.\nDouble-cliquez en maintenant la touche Maj enfoncée pour ajouter ou supprimer un élément. + Alterna entre a exibição de todos os itens ou seus favoritos.\nClique duas vezes enquanto mantém pressionada a tecla Shift para adicionar ou remover um item. + Переключайтесь между отображением всех элементов или ваших избранных.\nДважды щелкните, удерживая Shift, чтобы добавить или удалить элемент. + Alterna entre mostrar todos los objetos o sólo los favoritos.\nDoble click mientras se pulsa Shift para añadir o quitar un objeto. + + + Search\nCTRL + Click to enable live results + Suche\nSTRG + Click für Live-Aktualisierung während des Schreibens + Cerca\nCTRL + Click per modificare i risultati mentre scrivi + 検索\nCTRL + クリックで検索結果の即時表示を有効化 + 검색\nCtrl + 클릭으로 실시간 검색 결과를 활성화 + Поиск\nCtrl + Click для включения результатов в реальном времени + Recherche\nCTRL + clic pour modifier les résultats tout en écrivant + Buscar\nCTRL + Click habilita los objetos en directo diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index 2794e42119..dc70caa0c2 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -3,18 +3,18 @@ class GVAR(display) { idd = IDD_ace_arsenal; - enableSimulation=1; - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(display))] call FUNC(onArsenalOpen)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(display))] call FUNC(onArsenalClose)); - onKeyDown = QUOTE([ARR_3('onKeyDown', _this, QQGVAR(display))] call FUNC(onKeyDown)); + enableSimulation = 1; + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(display))] call FUNC(onArsenalOpen)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(display))] call FUNC(onArsenalClose)); + onKeyDown = QUOTE([ARR_3('onKeyDown',_this,QQGVAR(display))] call FUNC(onKeyDown)); onKeyUp = QUOTE(GVAR(shiftState) = _this select 2); - onMouseButtonDown = QUOTE([ARR_3('onMouseButtonDown', _this, QQGVAR(display))] call FUNC(onMouseButtonDown)); - onMouseButtonUp = QUOTE([ARR_3('onMouseButtonUp', _this, QQGVAR(display))] call FUNC(onMouseButtonUp)); - icon="\A3\Ui_f\data\Logos\a_64_ca.paa"; - logo="\A3\Ui_f\data\Logos\arsenal_1024_ca.paa"; + onMouseButtonDown = QUOTE([ARR_3('onMouseButtonDown',_this,QQGVAR(display))] call FUNC(onMouseButtonDown)); + onMouseButtonUp = QUOTE([ARR_3('onMouseButtonUp',_this,QQGVAR(display))] call FUNC(onMouseButtonUp)); + icon = "\A3\Ui_f\data\Logos\a_64_ca.paa"; + logo = "\A3\Ui_f\data\Logos\arsenal_1024_ca.paa"; class ControlsBackground { class blackLeft: ctrlStatic { - colorBackground[]={0,0,0,1}; + colorBackground[] = {0,0,0,1}; x = QUOTE(safezoneXAbs); y = QUOTE(safezoneY); w = QUOTE(safezoneXAbs - safezoneX); @@ -28,9 +28,9 @@ class GVAR(display) { class mouseArea: ctrlStatic { idc = IDC_mouseArea; style = 16; - onMouseMoving = QUOTE([ARR_3('onMouseMoving', _this, GVAR(display))] call FUNC(handleMouse)); - onMouseHolding = QUOTE([ARR_3('onMouseHolding', _this, GVAR(display))] call FUNC(handleMouse)); - onMouseZChanged = QUOTE([ARR_3('onMouseZChanged', _this, GVAR(display))] call FUNC(handleScrollWheel)); + onMouseMoving = QUOTE([ARR_3('onMouseMoving',_this,GVAR(display))] call FUNC(handleMouse)); + onMouseHolding = QUOTE([ARR_3('onMouseHolding',_this,GVAR(display))] call FUNC(handleMouse)); + onMouseZChanged = QUOTE([ARR_3('onMouseZChanged',_this,GVAR(display))] call FUNC(handleScrollWheel)); x = QUOTE(safezoneX); y = QUOTE(safezoneY); w = QUOTE(safezoneW); @@ -41,8 +41,8 @@ class GVAR(display) { class ArrowLeft: ctrlButton { idc = IDC_arrowMinus; text = "-"; - colorBackground[]={0,0,0,0.8}; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), -1)] call FUNC(buttonCargo)); + colorBackground[] = {0,0,0,0.8}; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),-1)] call FUNC(buttonCargo)); fade = 1; enable = 0; x = 0.5; @@ -53,8 +53,8 @@ class GVAR(display) { }; class ArrowRight: ArrowLeft { idc = IDC_arrowPlus; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), 1)] call FUNC(buttonCargo)); - text="+"; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),1)] call FUNC(buttonCargo)); + text = "+"; }; class blockLeftFrame: RscFrame { idc = IDC_blockLeftFrame; @@ -149,10 +149,10 @@ class GVAR(display) { class message: RscText { idc = IDC_message; fade = 1; - style=2; - shadow=0; - colorBackground[]={0,0,0,0.69999999}; - text=""; + style = 2; + shadow = 0; + colorBackground[] = {0,0,0,0.69999999}; + text = ""; x = QUOTE(0.5 - WIDTH_TOTAL / 2); y = QUOTE(safeZoneH + safezoneY - 25 * GRID_H); w = QUOTE(WIDTH_TOTAL); @@ -175,8 +175,8 @@ class GVAR(display) { h = QUOTE(7 * GRID_H); text = CSTRING(buttonHideText); sizeEx = QUOTE(5 * GRID_H); - shortcuts[] = {"0x0E"}; tooltip = CSTRING(buttonHideTooltip); + onMouseEnter = QUOTE(ctrlSetFocus (_this select 0)); onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonHide)); }; class buttonLoadouts: buttonHide { @@ -200,10 +200,17 @@ class GVAR(display) { tooltip = CSTRING(buttonImportTooltip); onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonImport)); }; + class buttonFavorites: buttonHide { + idc = IDC_buttonFavorites; + x = QUOTE(5 * WIDTH_GAP + 4 * WIDTH_SINGLE); + text = ""; + tooltip = CSTRING(buttonFavoritesTooltip); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),(_this select 0))] call FUNC(buttonFavorites)); + }; class buttonClose: ctrlButtonOK { idc = IDC_menuBarClose; colorBackground[] = {0,0,0,0.8}; - x = QUOTE(5 * WIDTH_GAP + 4 * WIDTH_SINGLE); + x = QUOTE(6 * WIDTH_GAP + 5 * WIDTH_SINGLE); y = QUOTE(0); w = QUOTE(WIDTH_SINGLE); h = QUOTE(7 * GRID_H); @@ -260,7 +267,7 @@ class GVAR(display) { fade = 1; color[] = {1,1,1,1}; colorActive[] = {1,1,1,1}; - text="#(argb,8,8,3)color(1,1,1,1)"; + text = "#(argb,8,8,3)color(1,1,1,1)"; x = QUOTE(80 * GRID_W); y = QUOTE(0); w = QUOTE(12 * GRID_W); @@ -281,7 +288,7 @@ class GVAR(display) { y = QUOTE(0); w = QUOTE(47 * GRID_W); h = QUOTE(55 * GRID_H); - colorBackground[]={0.1,0.1,0.1,0.5}; + colorBackground[] = {0.1,0.1,0.1,0.5}; }; class statsStaticBackground2: ctrlStaticBackground { idc = -1; @@ -289,7 +296,7 @@ class GVAR(display) { y = QUOTE(0); w = QUOTE(47 * GRID_W); h = QUOTE(5 * GRID_H); - colorBackground[]={0.1,0.1,0.1,0.8}; + colorBackground[] = {0.1,0.1,0.1,0.8}; }; class statsTitle1: RscText { idc = IDC_statsTitle1; @@ -298,8 +305,8 @@ class GVAR(display) { y = QUOTE(5 * GRID_H); w = QUOTE(45 * GRID_W); h = QUOTE(5 * GRID_H); - colorBackground[]={0,0,0,0}; - colorText[]={0.7,0.7,0.7,1}; + colorBackground[] = {0,0,0,0}; + colorText[] = {0.7,0.7,0.7,1}; sizeEx = QUOTE(5 * GRID_H); text = ""; }; @@ -310,7 +317,7 @@ class GVAR(display) { y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); h = QUOTE(4 * GRID_H); - colorBackground[]={1,1,1,0.15}; + colorBackground[] = {1,1,1,0.15}; }; class statsBar1: ctrlProgress { idc = IDC_statsBar1; @@ -326,10 +333,10 @@ class GVAR(display) { }; class statsText1: RscText { idc = IDC_statsText1; - shadow=0; + shadow = 0; fade = 1; - colorShadow[]={1,1,1,1}; - colorText[]={0,0,0,1}; + colorShadow[] = {1,1,1,1}; + colorText[] = {0,0,0,1}; x = QUOTE(0 * GRID_W); y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); @@ -396,7 +403,7 @@ class GVAR(display) { class statsBar5: statsBar1 { idc = IDC_statsBar5; y = QUOTE(50 * GRID_H); - colorBackground[]={1,1,1,0.15}; + colorBackground[] = {1,1,1,0.15}; }; class statsText5: statsText1 { idc = IDC_statsText5; @@ -404,24 +411,13 @@ class GVAR(display) { }; }; }; - class statsButton: ctrlButton { - idc = IDC_statsButton; - style= 2; - text=">"; - onButtonClick = QUOTE(ARR_2([QQGVAR(statsButton), [ctrlParent (_this select 0)]]) call CBA_fnc_localEvent); - x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); - y = QUOTE(safezoneY + 1.8 * GRID_H); - w = QUOTE(6 * GRID_W); - h = QUOTE(6 * GRID_H); - sizeEx = QUOTE(5 * GRID_H); - }; class statsPreviousPage: ctrlButton { idc = IDC_statsPreviousPage; - style= 2; - text="<"; - colorBackground[]={0,0,0,0}; - colorBackgroundDisabled[]= {0,0,0,0}; - onButtonClick = QUOTE(ARR_2([QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0), _this select 0, false)]]) call CBA_fnc_localEvent); + style = 2; + text = "<"; + colorBackground[] = {0,0,0,0}; + colorBackgroundDisabled[] = {0,0,0,0}; + onButtonClick = QUOTE([ARR_2(QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0),_this select 0,false)])] call CBA_fnc_localEvent); x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); y = QUOTE(safezoneY + 1.8 * GRID_H); w = QUOTE(5 * GRID_W); @@ -431,30 +427,125 @@ class GVAR(display) { class statsNextPage: statsPreviousPage { idc = IDC_statsNextPage; text = ">"; - onButtonClick = QUOTE(ARR_2([QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0), _this select 0, true)]]) call CBA_fnc_localEvent); - x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 30 * GRID_W); + onButtonClick = QUOTE([ARR_2(QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0),_this select 0,true)])] call CBA_fnc_localEvent); + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 42 * GRID_W); }; class statsCurrentPage: RscText { idc = IDC_statsCurrentPage; style = ST_CENTER; x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 5 * GRID_W); y = QUOTE(safezoneY + 1.8 * GRID_H); - w = QUOTE(25 * GRID_W); + w = QUOTE(37 * GRID_W); h = QUOTE(5 * GRID_H); - colorBackground[]={0,0,0,0}; - shadow=2; + colorBackground[] = {0,0,0,0}; + shadow = 2; sizeEx = QUOTE(5 * GRID_H); text = ""; }; - class statsButtonClose: ctrlButtonPicture { - idc = IDC_statsButtonClose; - colorBackground[]={0,0,0,0}; - text="\a3\3DEN\Data\Displays\Display3DEN\search_end_ca.paa"; - onButtonClick = QUOTE(ARR_2([QQGVAR(statsButton), [ctrlParent (_this select 0)]]) call CBA_fnc_localEvent); - x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 42 * GRID_W); - y = QUOTE(safezoneY + 1.8 * GRID_H); - w = QUOTE(5 * GRID_W); - h = QUOTE(5 * GRID_H); + class actionsBox: RscControlsGroupNoScrollbars { + idc = IDC_actionsBox; + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); + y = QUOTE(safezoneY + 58.6 * GRID_H); + w = QUOTE(47 * GRID_W); + h = QUOTE(55 * GRID_H); + class controls { + class actionsStaticBackground1: ctrlStaticBackground { + idc = IDC_actionsBackground1; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(47 * GRID_W); + h = QUOTE(55 * GRID_H); + colorBackground[]={0.1,0.1,0.1,0.5}; + }; + class actionsStaticBackground2: ctrlStaticBackground { + idc = IDC_actionsBackground2; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(47 * GRID_W); + h = QUOTE(5 * GRID_H); + colorBackground[]={0.1,0.1,0.1,0.8}; + }; + class actionsText1: RscTextMulti { + idc = IDC_actionsText1; + x = QUOTE(0 * GRID_W); + y = QUOTE(5 * GRID_H); + w = QUOTE(45 * GRID_W); + h = QUOTE(5 * GRID_H); + colorBackground[]={0,0,0,0}; + colorText[]={0.7,0.7,0.7,1}; + sizeEx = QUOTE(5 * GRID_H); + text = ""; + }; + class actionsButton1: ctrlButton { + idc = IDC_actionsButton1; + text = ""; + x = QUOTE(1 * GRID_W); + y = QUOTE(6 * GRID_H); + w = QUOTE(45 * GRID_W); + h = QUOTE(4 * GRID_H); + }; + class actionsText2: actionsText1 { + idc = IDC_actionsText2; + y = QUOTE(10 * GRID_H); + }; + class actionsButton2: actionsButton1 { + idc = IDC_actionsButton2; + y = QUOTE(11 * GRID_H); + }; + class actionsText3: actionsText1 { + idc = IDC_actionsText3; + y = QUOTE(15 * GRID_H); + }; + class actionsButton3: actionsButton1 { + idc = IDC_actionsButton3; + y = QUOTE(16 * GRID_H); + }; + class actionsText4: actionsText1 { + idc = IDC_actionsText4; + y = QUOTE(20 * GRID_H); + }; + class actionsButton4: actionsButton1 { + idc = IDC_actionsButton4; + y = QUOTE(21 * GRID_H); + }; + class actionsText5: actionsText1 { + idc = IDC_actionsText5; + y = QUOTE(25 * GRID_H); + }; + class actionsButton5: actionsButton1 { + idc = IDC_actionsButton5; + y = QUOTE(26 * GRID_H); + }; + class actionsPreviousPage: ctrlButton { + idc = IDC_actionsPreviousPage; + style= 2; + text="<"; + colorBackground[]={0,0,0,0}; + colorBackgroundDisabled[]= {0,0,0,0}; + onButtonClick = QUOTE([ARR_2(QQGVAR(actionsChangePage),[ARR_3(ctrlParent (_this select 0),_this select 0,false)])] call CBA_fnc_localEvent); + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(5 * GRID_W); + h = QUOTE(5 * GRID_H); + sizeEx = QUOTE(5.5 * GRID_H); + }; + class actionsNextPage: actionsPreviousPage { + idc = IDC_actionsNextPage; + text = ">"; + onButtonClick = QUOTE([ARR_2(QQGVAR(actionsChangePage),[ARR_3(ctrlParent (_this select 0),_this select 0,true)])] call CBA_fnc_localEvent); + x = QUOTE(42 * GRID_W); + }; + class actionsCurrentPage: RscText { + idc = IDC_actionsCurrentPage; + style = ST_CENTER; + x = QUOTE(5 * GRID_W); + w = QUOTE(37 * GRID_W); + colorBackground[]={0,0,0,0}; + shadow=2; + sizeEx = QUOTE(5 * GRID_H); + text = ""; + }; + }; }; class mouseBlock: RscText { idc = IDC_mouseBlock; @@ -466,14 +557,16 @@ class GVAR(display) { }; class leftTabContent: RscListBox { idc = IDC_leftTabContent; - colorBackground[]={0,0,0,0}; - colorSelectBackground[]={1,1,1,0.5}; - colorSelectBackground2[]={1,1,1,0.5}; - colorPictureSelected[]={1,1,1,1}; - colorSelect[]={1,1,1,1}; - colorSelect2[]={1,1,1,1}; - colorPictureRightSelected[]={1,1,1,1}; + colorBackground[] = {0,0,0,0}; + colorSelectBackground[] = {1,1,1,0.5}; + colorSelectBackground2[] = {1,1,1,0.5}; + colorPictureSelected[] = {1,1,1,1}; + colorSelect[] = {1,1,1,1}; + colorSelect2[] = {1,1,1,1}; + colorPictureRightSelected[] = {1,1,1,1}; + colorTextRight[] = {0.5, 0.5, 0.5, 0}; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedLeft)); + onLBDblClick = QUOTE(_this call FUNC(onPanelDblClick)); onSetFocus = QUOTE(GVAR(leftTabFocus) = true); onKillFocus = QUOTE(GVAR(leftTabFocus) = false); x = QUOTE(safezoneX + 13 * GRID_W); @@ -484,29 +577,32 @@ class GVAR(display) { }; class rightTabContent: leftTabContent { idc = IDC_rightTabContent; - drawSideArrows=1; - disableOverflow=1; + drawSideArrows = 1; + disableOverflow = 1; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedRight)); + onLBDblClick = QUOTE(_this call FUNC(onPanelDblClick)); onSetFocus = QUOTE(GVAR(rightTabFocus) = true); onKillFocus = QUOTE(GVAR(rightTabFocus) = false); x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); h = QUOTE(safezoneH - 28 * GRID_H); }; - class rightTabContentListnBox : RscListNBox { + class rightTabContentListnBox: RscListNBox { idc = IDC_rightTabContentListnBox; - colorBackground[]={0,0,0,0}; - colorSelectBackground[]={1,1,1,0.5}; - colorSelectBackground2[]={1,1,1,0.5}; - colorPictureSelected[]={1,1,1,1}; - colorSelect[]={1,1,1,1}; - colorSelect2[]={1,1,1,1}; - colorPictureRightSelected[]={1,1,1,1}; - columns[]={0.07, 0.15, 0.75}; + colorBackground[] = {0,0,0,0}; + colorSelectBackground[] = {1,1,1,0.5}; + colorSelectBackground2[] = {1,1,1,0.5}; + colorPictureSelected[] = {1,1,1,1}; + colorSelect[] = {1,1,1,1}; + colorSelect2[] = {1,1,1,1}; + colorPictureRightSelected[] = {1,1,1,1}; + colorTextRight[] = {0.5, 0.5, 0.5, 0}; + columns[] = {0.07, 0.15, 0.75}; idcLeft = IDC_arrowMinus; idcRIght = IDC_arrowPlus; - drawSideArrows=1; - disableOverflow=1; + drawSideArrows = 1; + disableOverflow = 1; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedRightListnBox)); + onLBDblClick = QUOTE(_this call FUNC(onPanelDblClick)); onSetFocus = QUOTE(GVAR(rightTabLnBFocus) = true); onKillFocus = QUOTE(GVAR(rightTabLnBFocus) = false); x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); @@ -519,42 +615,30 @@ class GVAR(display) { idc = IDC_sortLeftTab; x = QUOTE(safezoneX + 13 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); - w = QUOTE(80 * GRID_W); + w = QUOTE(40 * GRID_W); h = QUOTE(6 * GRID_H); onLBSelChanged = QUOTE(_this call FUNC(sortPanel)); sizeEx = QUOTE(5 * GRID_H); - class Items { - class Alphabet { - text="$STR_a3_rscdisplayarsenal_sort_alphabet"; - default=1; - value= 0; - }; - class Mod { - text="$STR_a3_rscdisplayarsenal_sort_mod"; - value= 1; - }; - }; + }; + class sortLeftTabDirection: sortLeftTab { + idc = IDC_sortLeftTabDirection; + x = QUOTE(safezoneX + 53 * GRID_W); + w = QUOTE(40 * GRID_W); }; class sortRightTab: sortLeftTab { idc = IDC_sortRightTab; x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - class Items { - class Alphabet { - text="$STR_a3_rscdisplayarsenal_sort_alphabet"; - default=1; - value= 0; - }; - class Weight { - text="$STR_a3_rscdisplayarsenal_sort_mod"; - value= 1; - }; - }; + }; + class sortRightTabDirection: sortLeftTabDirection { + idc = IDC_sortRightTabDirection; + x = QUOTE(safezoneX + safezoneW - 53 * GRID_W); }; class leftSearchbar: ctrlEdit { idc = IDC_leftSearchbar; onSetFocus = QUOTE(GVAR(leftSearchbarFocus) = true); onKillFocus = QUOTE(GVAR(leftSearchbarFocus) = false); - onMouseButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(clearSearchbar)); + onMouseButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0),_this select 0,_this select 1)] call FUNC(clearSearchbar)); + onEditChanged = QUOTE(call FUNC(handleSearchInputChanged)); x = QUOTE(safezoneX + 13 * GRID_W); y = QUOTE(safezoneY + 1.8 * GRID_H); w = QUOTE(74 * GRID_W); @@ -564,14 +648,16 @@ class GVAR(display) { class leftSearchbarButton: ctrlButtonPicture { idc = IDC_leftSearchbarButton; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; - colorBackground[]={0,0,0,0.5}; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_leftSearchbar)] call FUNC(handleSearchbar)); + tooltip = CSTRING(buttonSearchTooltip); + colorBackground[] = {0,0,0,0.5}; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),ctrlParent (_this select 0) displayCtrl IDC_leftSearchbar)] call FUNC(handleSearchbar)); + onMouseButtonDown = QUOTE(call FUNC(handleSearchModeToggle)); x = QUOTE(safezoneX + 87 * GRID_W); y = QUOTE(safezoneY + 1.8 * GRID_H); w = QUOTE(6 * GRID_W); h = QUOTE(6 * GRID_H); }; - class rightSearchbar: leftSearchBar { + class rightSearchbar: leftSearchbar { idc = IDC_rightSearchbar; onSetFocus = QUOTE(GVAR(rightSearchbarFocus) = true); onKillFocus = QUOTE(GVAR(rightSearchbarFocus) = false); @@ -579,7 +665,7 @@ class GVAR(display) { }; class rightSearchbarButton: leftSearchbarButton { idc = IDC_rightSearchbarButton; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_rightSearchbar)] call FUNC(handleSearchbar)); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),ctrlParent (_this select 0) displayCtrl IDC_rightSearchbar)] call FUNC(handleSearchbar)); x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); }; class tabLeft: RscControlsGroupNoScrollbars { @@ -591,9 +677,9 @@ class GVAR(display) { class controls { class iconBackgroundPrimaryWeapon: ctrlStaticBackground { idc = IDC_iconBackgroundPrimaryWeapon; - fade=1; - enable=0; - colorBackground[]={0,0,0,1}; + fade = 1; + enable = 0; + colorBackground[] = {0,0,0,1}; x = QUOTE(0); y = QUOTE(0 * GRID_H); w = QUOTE(12 * GRID_W); @@ -601,204 +687,204 @@ class GVAR(display) { }; class buttonPrimaryWeapon: RscButtonArsenal { idc = IDC_buttonPrimaryWeapon; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_PrimaryWeapon"; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(fillLeftPanel)); - colorBackground[]={0,0,0,0.5}; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_PrimaryWeapon"; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(fillLeftPanel)); + colorBackground[] = {0,0,0,0.5}; x = QUOTE(0 * GRID_W); y = QUOTE(0 * GRID_H); w = QUOTE(9 * GRID_W); h = QUOTE(9 * GRID_H); }; - class iconBackgroundHandgun: IconBackgroundPrimaryWeapon { + class iconBackgroundHandgun: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundHandgun; y = QUOTE(10 * GRID_H); }; class buttonHandgun: buttonPrimaryWeapon { idc = IDC_buttonHandgun; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Handgun_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_Handgun"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Handgun_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Handgun"; y = QUOTE(10 * GRID_H); }; - class iconBackgroundSecondaryWeapon: IconBackgroundPrimaryWeapon { + class iconBackgroundSecondaryWeapon: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundSecondaryWeapon; y = QUOTE(20 * GRID_H); }; class buttonSecondaryWeapon: buttonPrimaryWeapon { idc = IDC_buttonSecondaryWeapon; - tooltip="$STR_A3_RscDisplayArsenal_tab_SecondaryWeapon"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\SecondaryWeapon_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_SecondaryWeapon"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\SecondaryWeapon_ca.paa"; y = QUOTE(20 * GRID_H); }; - class iconBackgroundHeadgear: IconBackgroundPrimaryWeapon { + class iconBackgroundHeadgear: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundHeadgear; y = QUOTE(30 * GRID_H); }; class buttonHeadgear: buttonPrimaryWeapon { idc = IDC_buttonHeadgear; - tooltip="$STR_A3_RscDisplayArsenal_tab_Headgear"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Headgear_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Headgear"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Headgear_ca.paa"; y = QUOTE(30 * GRID_H); }; - class iconBackgroundUniform: IconBackgroundPrimaryWeapon { + class iconBackgroundUniform: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundUniform; y = QUOTE(40 * GRID_H); }; class buttonUniform: buttonPrimaryWeapon { idc = IDC_buttonUniform; - tooltip="$STR_A3_RscDisplayArsenal_tab_Uniform"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Uniform_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Uniform"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Uniform_ca.paa"; y = QUOTE(40 * GRID_H); }; - class iconBackgroundVest: IconBackgroundPrimaryWeapon { + class iconBackgroundVest: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundVest; y = QUOTE(50 * GRID_H); }; class buttonVest: buttonPrimaryWeapon { idc = IDC_buttonVest; - tooltip="$STR_A3_RscDisplayArsenal_tab_Vest"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Vest_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Vest"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Vest_ca.paa"; y = QUOTE(50 * GRID_H); }; - class iconBackgroundBackpack: IconBackgroundPrimaryWeapon { + class iconBackgroundBackpack: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundBackpack; y = QUOTE(60 * GRID_H); }; class buttonBackpack: buttonPrimaryWeapon { idc = IDC_buttonBackpack; - tooltip="$STR_A3_RscDisplayArsenal_tab_Backpack"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Backpack_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Backpack"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Backpack_ca.paa"; y = QUOTE(60 * GRID_H); }; - class iconBackgroundGoggles: IconBackgroundPrimaryWeapon { + class iconBackgroundGoggles: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundGoggles; y = QUOTE(70 * GRID_H); }; class buttonGoggles: buttonPrimaryWeapon { idc = IDC_buttonGoggles; - tooltip="$STR_A3_RscDisplayArsenal_tab_Goggles"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Goggles_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Goggles"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Goggles_ca.paa"; y = QUOTE(70 * GRID_H); }; - class iconBackgroundNVG: IconBackgroundPrimaryWeapon { + class iconBackgroundNVG: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundNVG; y = QUOTE(80 * GRID_H); }; class buttonNVG: buttonPrimaryWeapon { idc = IDC_buttonNVG; - tooltip="$STR_A3_RscDisplayArsenal_tab_NVGs"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\NVGs_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_NVGs"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\NVGs_ca.paa"; y = QUOTE(80 * GRID_H); }; - class iconBackgroundBinoculars: IconBackgroundPrimaryWeapon { + class iconBackgroundBinoculars: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundBinoculars; y = QUOTE(90 * GRID_H); }; class buttonBinoculars: buttonPrimaryWeapon { idc = IDC_buttonBinoculars; - tooltip="$STR_A3_RscDisplayArsenal_tab_Binoculars"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Binoculars_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Binoculars"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Binoculars_ca.paa"; y = QUOTE(90 * GRID_H); }; - class iconBackgroundMap: IconBackgroundPrimaryWeapon { + class iconBackgroundMap: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundMap; y = QUOTE(100 * GRID_H); }; class buttonMap: buttonPrimaryWeapon { idc = IDC_buttonMap; - tooltip="$STR_A3_RscDisplayArsenal_tab_Map"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Map_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Map"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Map_ca.paa"; y = QUOTE(100 * GRID_H); }; - class iconBackgroundGPS: IconBackgroundPrimaryWeapon { + class iconBackgroundGPS: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundGPS; y = QUOTE(110 * GRID_H); }; class buttonGPS: buttonPrimaryWeapon { idc = IDC_buttonGPS; - tooltip="$STR_A3_RscDisplayArsenal_tab_GPS"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\GPS_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_GPS"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\GPS_ca.paa"; y = QUOTE(110 * GRID_H); }; - class iconBackgroundRadio: IconBackgroundPrimaryWeapon { + class iconBackgroundRadio: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundRadio; y = QUOTE(120 * GRID_H); }; class buttonRadio: buttonPrimaryWeapon { idc = IDC_buttonRadio; - tooltip="$STR_A3_RscDisplayArsenal_tab_Radio"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Radio_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Radio"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Radio_ca.paa"; y = QUOTE(120 * GRID_H); }; - class iconBackgroundCompass: IconBackgroundPrimaryWeapon { + class iconBackgroundCompass: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundCompass; y = QUOTE(130 * GRID_H); }; class buttonCompass: buttonPrimaryWeapon { idc = IDC_buttonCompass; - tooltip="$STR_A3_RscDisplayArsenal_tab_Compass"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Compass_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Compass"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Compass_ca.paa"; y = QUOTE(130 * GRID_H); }; - class iconBackgroundWatch: IconBackgroundPrimaryWeapon { + class iconBackgroundWatch: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundWatch; y = QUOTE(140 * GRID_H); }; class buttonWatch: buttonPrimaryWeapon { idc = IDC_buttonWatch; - tooltip="$STR_A3_RscDisplayArsenal_tab_Watch"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Watch_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Watch"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Watch_ca.paa"; y = QUOTE(140 * GRID_H); }; - class iconBackgroundFace: IconBackgroundPrimaryWeapon { + class iconBackgroundFace: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundFace; y = QUOTE(150 * GRID_H); }; class buttonFace: buttonPrimaryWeapon { idc = IDC_buttonFace; - tooltip="$STR_A3_RscDisplayArsenal_tab_Face"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Face_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Face"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Face_ca.paa"; y = QUOTE(150 * GRID_H); }; - class iconBackgroundVoice: IconBackgroundPrimaryWeapon { + class iconBackgroundVoice: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundVoice; y = QUOTE(160 * GRID_H); }; class buttonVoice: buttonPrimaryWeapon { idc = IDC_buttonVoice; - tooltip="$STR_A3_RscDisplayArsenal_tab_Voice"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Voice_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Voice"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Voice_ca.paa"; y = QUOTE(160 * GRID_H); }; - class iconBackgroundInsigna: IconBackgroundPrimaryWeapon { + class iconBackgroundInsigna: iconBackgroundPrimaryWeapon { idc = IDC_iconBackgroundInsigna; y = QUOTE(170 * GRID_H); }; class buttonInsigna: buttonPrimaryWeapon { - idc = IDC_buttonInsigna; - tooltip="$STR_A3_RscDisplayArsenal_tab_Insignia"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Insignia_ca.paa"; + idc = IDC_buttonInsignia; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Insignia"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Insignia_ca.paa"; y = QUOTE(170 * GRID_H); }; }; }; class iconBackgroundOptic: ctrlStaticBackground { idc = IDC_iconBackgroundOptic; - colorBackground[]={0,0,0,1}; - fade=1; - enable=0; - x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); + colorBackground[] = {0,0,0,1}; + fade = 1; + enable = 0; + x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); w = QUOTE(12 * GRID_W); h = QUOTE(9 * GRID_H); }; class buttonOptic: RscButtonArsenal { idc = IDC_buttonOptic; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemOptic"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa"; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(fillRightPanel)); - colorBackground[]={0,0,0,0.5}; - x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemOptic"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa"; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(fillRightPanel)); + colorBackground[] = {0,0,0,0.5}; + x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); w = QUOTE(9 * GRID_W); h = QUOTE(9 * GRID_H); @@ -809,8 +895,8 @@ class GVAR(display) { }; class buttonItemAcc: buttonOptic { idc = IDC_buttonItemAcc; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemAcc"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemAcc"; y = QUOTE(safezoneY + 18 * GRID_H); }; class iconBackgroundMuzzle: iconBackgroundOptic { @@ -819,8 +905,8 @@ class GVAR(display) { }; class buttonMuzzle: buttonOptic { idc = IDC_buttonMuzzle; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemMuzzle"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemMuzzle"; y = QUOTE(safezoneY + 28 * GRID_H); }; class iconBackgroundBipod: iconBackgroundOptic { @@ -829,8 +915,8 @@ class GVAR(display) { }; class buttonBipod: buttonOptic { idc = IDC_buttonBipod; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemBipod"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemBipod"; y = QUOTE(safezoneY + 38 * GRID_H); }; class iconBackgroundCurrentMag: iconBackgroundOptic { @@ -839,8 +925,8 @@ class GVAR(display) { }; class buttonCurrentMag: buttonOptic { idc = IDC_buttonCurrentMag; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; - tooltip= CSTRING(buttonCurrentMagTooltip); + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; + tooltip = CSTRING(buttonCurrentMagTooltip); y = QUOTE(safezoneY + 48 * GRID_H); }; class iconBackgroundCurrentMag2: iconBackgroundOptic { @@ -849,8 +935,8 @@ class GVAR(display) { }; class buttonCurrentMag2: buttonOptic { idc = IDC_buttonCurrentMag2; - text= QPATHTOF(data\iconSecondaryMuzzle); - tooltip= CSTRING(buttonCurrentMag2Tooltip); + text = QPATHTOF(data\iconSecondaryMuzzle); + tooltip = CSTRING(buttonCurrentMag2Tooltip); y = QUOTE(safezoneY + 58 * GRID_H); }; class iconBackgroundMag: iconBackgroundOptic { @@ -859,8 +945,8 @@ class GVAR(display) { }; class buttonMag: buttonOptic { idc = IDC_buttonMag; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMag"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMag"; y = QUOTE(safezoneY + 48 * GRID_H); }; class iconBackgroundMagALL: iconBackgroundOptic { @@ -869,8 +955,8 @@ class GVAR(display) { }; class buttonMagALL: buttonOptic { idc = IDC_buttonMagALL; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMagAll"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMagAll"; y = QUOTE(safezoneY + 58 * GRID_H); }; class iconBackgroundThrow: iconBackgroundOptic { @@ -879,8 +965,8 @@ class GVAR(display) { }; class buttonThrow: buttonOptic { idc = IDC_buttonThrow; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoThrow"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoThrow"; y = QUOTE(safezoneY + 68 * GRID_H); }; class iconBackgroundPut: iconBackgroundOptic { @@ -889,8 +975,8 @@ class GVAR(display) { }; class buttonPut: buttonOptic { idc = IDC_buttonPut; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoPut"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoPut"; y = QUOTE(safezoneY + 78 * GRID_H); }; class iconBackgroundMisc: iconBackgroundOptic { @@ -899,19 +985,20 @@ class GVAR(display) { }; class buttonMisc: buttonOptic { idc = IDC_buttonMisc; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMisc"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMisc"; y = QUOTE(safezoneY + 88 * GRID_H); }; + class buttonRemoveAll: ctrlButtonPicture { idc = IDC_buttonRemoveAll; text = QPATHTOF(data\iconClearContainer.paa); tooltip = CSTRING(buttonClearContainerTooltip); - colorBackground[]={0,0,0,0.5}; + colorBackground[] = {0,0,0,0.5}; onButtonClick = QUOTE(ctrlParent (_this select 0) call FUNC(buttonClearAll)); - fade=1; - enable=0; - x = QUOTE(safezoneW + safezoneX - 11 * GRID_W); + fade = 1; + enable = 0; + x = QUOTE(safezoneW + safezoneX - 11 * GRID_W); y = QUOTE(safeZoneH + safezoneY - 29 * GRID_H); w = QUOTE(9 * GRID_W); h = QUOTE(9 * GRID_H); @@ -921,12 +1008,12 @@ class GVAR(display) { class GVAR(loadoutsDisplay) { idd = IDD_loadouts_display; - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(loadoutsDisplay))] call FUNC(onLoadoutsOpen)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(loadoutsDisplay))] call FUNC(onLoadoutsClose)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(loadoutsDisplay))] call FUNC(onLoadoutsOpen)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(loadoutsDisplay))] call FUNC(onLoadoutsClose)); class controls { class centerBox: ctrlControlsGroupNoScrollbars { idc = IDC_centerBox; - x = QUOTE(safezoneW + safezoneX - (180 * GRID_W)); + x = QUOTE(safezoneW + safezoneX - (180 * GRID_W)); y = QUOTE(safezoneY + (5 * GRID_H)); w = QUOTE(160 * GRID_W); h = QUOTE(safezoneH - (34 * GRID_H)); @@ -957,15 +1044,15 @@ class GVAR(loadoutsDisplay) { h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H); }; - class contentPanel: RscListnBox { + class contentPanel: RscListNBox { idc = IDC_contentPanel; - columns[]={0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90}; - drawSideArrows=0; - disableOverflow=1; + columns[] = {0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90}; + drawSideArrows = 0; + disableOverflow = 1; onSetFocus = QUOTE(GVAR(loadoutsPanelFocus) = true); onKillFocus = QUOTE(GVAR(loadoutsPanelFocus) = false); - onLBSelChanged = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(onSelChangedLoadouts)); - onLBDblClick = QUOTE([ARR_2(ctrlParent (_this select 0), (ctrlParent (_this select 0)) displayCtrl IDC_buttonLoad)] call FUNC(buttonLoadoutsLoad)); + onLBSelChanged = QUOTE([ARR_3(ctrlParent (_this select 0),_this select 0,_this select 1)] call FUNC(onSelChangedLoadouts)); + onLBDblClick = QUOTE([ARR_2(ctrlParent (_this select 0),(ctrlParent (_this select 0)) displayCtrl IDC_buttonLoad)] call FUNC(buttonLoadoutsLoad)); x = QUOTE(0); y = QUOTE(5 * GRID_H); w = QUOTE(160 * GRID_W); @@ -973,17 +1060,17 @@ class GVAR(loadoutsDisplay) { sizeEx = QUOTE(7 * GRID_H); }; class textTitle: RscText { - idc= -1; - text="$STR_DISP_GAME_NAME"; + idc = -1; + text = "$STR_DISP_GAME_NAME"; x = QUOTE(0 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(15 * GRID_W); h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H); - colorBackground[]={0,0,0,0.2}; + colorBackground[] = {0,0,0,0.2}; }; class textEditBox: ctrlEdit { - idc= IDC_textEditBox; + idc = IDC_textEditBox; x = QUOTE(15 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(65 * GRID_W); @@ -994,7 +1081,7 @@ class GVAR(loadoutsDisplay) { idc = IDC_loadoutsSearchbar; onSetFocus = QUOTE(GVAR(loadoutsSearchbarFocus) = true); onKillFocus = QUOTE(GVAR(loadoutsSearchbarFocus) = false); - onMouseButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(clearSearchbar)); + onMouseButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0),_this select 0,_this select 1)] call FUNC(clearSearchbar)); x = QUOTE(83 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(72 * GRID_W); @@ -1004,8 +1091,8 @@ class GVAR(loadoutsDisplay) { class loadoutsSearchbarButton: ctrlButtonPicture { idc = -1; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; - colorBackground[]={0,0,0,0.5}; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_loadoutsSearchbar)] call FUNC(handleLoadoutsSearchbar)); + colorBackground[] = {0,0,0,0.5}; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),ctrlParent (_this select 0) displayCtrl IDC_loadoutsSearchbar)] call FUNC(handleLoadoutsSearchbar)); x = QUOTE(155 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(5 * GRID_W); @@ -1017,53 +1104,52 @@ class GVAR(loadoutsDisplay) { y = QUOTE(safezoneH - (44 * GRID_H)); w = QUOTE(30 * GRID_W); h = QUOTE(10 * GRID_H); - text= CSTRING(buttonSaveText); - tooltip= CSTRING(buttonSaveTooltip); + text = CSTRING(buttonSaveText); + tooltip = CSTRING(buttonSaveTooltip); sizeEx = QUOTE(5 * GRID_H); - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsSave)); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(buttonLoadoutsSave)); colorBackground[] = {0,0,0,0.8}; }; class buttonRename: buttonSave { idc = IDC_buttonRename; x = QUOTE(32.5 * GRID_W); - text= CSTRING(buttonRenameText); - tooltip= CSTRING(buttonRenameTooltip); - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsRename)); + text = ECSTRING(common,rename); + tooltip = CSTRING(buttonRenameTooltip); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(buttonLoadoutsRename)); }; class buttonLoad: buttonSave { idc = IDC_buttonLoad; x = QUOTE(65 * GRID_W); - text= CSTRING(buttonLoadText); - tooltip= CSTRING(buttonLoadTooltip); - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsLoad)); + text = CSTRING(buttonLoadText); + tooltip = CSTRING(buttonLoadTooltip); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(buttonLoadoutsLoad)); }; class buttonShare: buttonSave { idc = IDC_buttonShare; x = QUOTE(97.5 * GRID_W); - text= CSTRING(buttonSharePrivateText); - tooltip= CSTRING(buttonShareTooltip); - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsShare)); + text = CSTRING(buttonSharePrivateText); + tooltip = CSTRING(buttonShareTooltip); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(buttonLoadoutsShare)); }; class buttonDelete: buttonSave { idc = IDC_buttonDelete; x = QUOTE(130 * GRID_W); - text= CSTRING(buttonDeleteText); - tooltip= CSTRING(buttonDeleteTooltip); + text = CSTRING(buttonDeleteText); + tooltip = CSTRING(buttonDeleteTooltip); colorBackgroundActive[] = {0.5,0,0,1}; - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsDelete)); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(buttonLoadoutsDelete)); }; }; }; class buttonClose: ctrlButton { idc = -1; - x = QUOTE(safezoneW + safezoneX - 32 * GRID_W); + x = QUOTE(safezoneW + safezoneX - 32 * GRID_W); y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); w = QUOTE(30 * GRID_W); h = QUOTE(7 * GRID_H); sizeEx = QUOTE(5 * GRID_H); - text= CSTRING(buttonCloseText); - shortcuts[]= {"0x01"}; - tooltip= ""; + text = CSTRING(buttonCloseText); + tooltip = ""; onButtonClick = QUOTE(ctrlParent (_this select 0) closeDisplay 2); }; class buttonBar: ctrlControlsGroupNoScrollbars { @@ -1089,9 +1175,9 @@ class GVAR(loadoutsDisplay) { w = QUOTE(52 * GRID_W); h = QUOTE(7 * GRID_H); sizeEx = QUOTE(5 * GRID_H); - text= CSTRING(tabMyLoadoutsText); - tooltip= CSTRING(tabMyLoadoutsTooltip); - onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(loadoutsChangeTab)); + text = CSTRING(tabMyLoadoutsText); + tooltip = CSTRING(tabMyLoadoutsTooltip); + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(loadoutsChangeTab)); }; class buttonDefaultLoadoutsBackground: buttonMyLoadoutsBackground { idc = IDC_buttonDefaultLoadoutsBackground; @@ -1100,8 +1186,8 @@ class GVAR(loadoutsDisplay) { class buttonDefaultLoadouts: buttonMyLoadouts { idc = IDC_buttonDefaultLoadouts; x = QUOTE(54.5 * GRID_W); - text= CSTRING(tabDefaultLoadoutsText); - tooltip= CSTRING(tabDefaultLoadoutsTooltip); + text = CSTRING(tabDefaultLoadoutsText); + tooltip = CSTRING(tabDefaultLoadoutsTooltip); }; class buttonSharedLoadoutsBackground: buttonMyLoadoutsBackground { idc = IDC_buttonSharedLoadoutsBackground; @@ -1110,8 +1196,8 @@ class GVAR(loadoutsDisplay) { class buttonSharedLoadouts: buttonMyLoadouts { idc = IDC_buttonSharedLoadouts; x = QUOTE(109 * GRID_W); - text= CSTRING(tabSharedLoadoutsText); - tooltip= CSTRING(tabSharedLoadoutsTooltip); + text = CSTRING(tabSharedLoadoutsText); + tooltip = CSTRING(tabSharedLoadoutsTooltip); }; }; }; diff --git a/addons/arsenal/ui/RscCustomArsenalButton.hpp b/addons/arsenal/ui/RscCustomArsenalButton.hpp new file mode 100644 index 0000000000..0aa077f424 --- /dev/null +++ b/addons/arsenal/ui/RscCustomArsenalButton.hpp @@ -0,0 +1,22 @@ +class GVAR(customArsenalButton_Button): RscButtonArsenal { + x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); + y = QUOTE(safezoneY + 88 * GRID_H); + w = QUOTE(9 * GRID_W); + h = QUOTE(9 * GRID_H); + + text = QPATHTOF(data\iconCustom.paa); + tooltip = ""; + onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0),_this select 0)] call FUNC(fillRightPanel)); + colorBackground[] = {0,0,0,0.5}; +}; + +class GVAR(customArsenalButton_Background): ctrlStaticBackground { + x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); + y = QUOTE(safezoneY + 88 * GRID_H); + w = QUOTE(12 * GRID_W); + h = QUOTE(9 * GRID_H); + + colorBackground[] = {0,0,0,1}; + fade = 1; + enable = 0; +}; diff --git a/addons/arsenal/ui/script_component.hpp b/addons/arsenal/ui/script_component.hpp deleted file mode 100644 index 523addf768..0000000000 --- a/addons/arsenal/ui/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\arsenal\script_component.hpp" \ No newline at end of file diff --git a/addons/artillerytables/$PBOPREFIX$ b/addons/artillerytables/$PBOPREFIX$ new file mode 100644 index 0000000000..090539769e --- /dev/null +++ b/addons/artillerytables/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\artillerytables diff --git a/addons/artillerytables/CfgEventHandlers.hpp b/addons/artillerytables/CfgEventHandlers.hpp new file mode 100644 index 0000000000..2a3f71f852 --- /dev/null +++ b/addons/artillerytables/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/artillerytables/CfgMagazines.hpp b/addons/artillerytables/CfgMagazines.hpp new file mode 100644 index 0000000000..e6abdcf06e --- /dev/null +++ b/addons/artillerytables/CfgMagazines.hpp @@ -0,0 +1,6 @@ +class CfgMagazines { + class 32Rnd_155mm_Mo_shells; + class 8Rnd_82mm_Mo_shells: 32Rnd_155mm_Mo_shells { + GVAR(airFriction) = -0.0001; + }; +}; diff --git a/addons/artillerytables/CfgVehicles.hpp b/addons/artillerytables/CfgVehicles.hpp new file mode 100644 index 0000000000..04424e6079 --- /dev/null +++ b/addons/artillerytables/CfgVehicles.hpp @@ -0,0 +1,7 @@ +class CfgVehicles { + class StaticWeapon; + class StaticMortar: StaticWeapon { + // Small mortars seem to need the alternate elevation calculations, + GVAR(showGunLaying) = 2; + }; +}; diff --git a/addons/artillerytables/CfgWeapons.hpp b/addons/artillerytables/CfgWeapons.hpp new file mode 100644 index 0000000000..f3716173f9 --- /dev/null +++ b/addons/artillerytables/CfgWeapons.hpp @@ -0,0 +1,16 @@ +class CfgWeapons { + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + class ACE_artilleryTable: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(rangetable_displayName); + descriptionShort = CSTRING(rangetable_description); + picture = QPATHTOF(UI\icon_rangeTable.paa); + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.1; + }; + }; +}; diff --git a/addons/artillerytables/README.md b/addons/artillerytables/README.md new file mode 100644 index 0000000000..03d7f0ac29 --- /dev/null +++ b/addons/artillerytables/README.md @@ -0,0 +1,7 @@ +ace_artillerytables +========== + +Universal artillery rangetables. + +#### Items Added: +`ACE_artilleryTable` diff --git a/addons/artillerytables/RscRangeTable.hpp b/addons/artillerytables/RscRangeTable.hpp new file mode 100644 index 0000000000..ef11d7eac8 --- /dev/null +++ b/addons/artillerytables/RscRangeTable.hpp @@ -0,0 +1,95 @@ +class GVAR(rangeTableDialog) { + idd = -1; + movingEnable = 1; + onLoad = QUOTE(with uiNameSpace do { GVAR(rangeTableDialog) = _this select 0 };); + objects[] = {}; + + class ControlsBackground { + class TableBackground: RscPicture { + idc = -1; + text = QPATHTOF(UI\RangeTable_background.paa); + x = "18 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "16.2634559672906 * (safeZoneH / 40)"; + h = "23 * ((safeZoneH / 1.2) / 25)"; + colorBackground[] = {1,1,1,1}; + }; + class LeftSideBackground: RscText { + idc = -1; + x = "13 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "5 * (safeZoneH / 40)"; + h = "23 * ((safeZoneH / 1.2) / 25)"; + colorBackground[] = {0,0,0,0.8}; + }; + }; + class controls { + class TheTable: RscListNBox { + idc = IDC_TABLE; + x = "18 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "3.76 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "16.2634559672906 * (safeZoneH / 40)"; + h = "20.24 * ((safeZoneH / 1.2) / 25)"; + columns[] = {"10/867", "86/867", "171/867", "238/867", "320/867", "405/867", "485/867", "546/867", "607/867", "668/867", "729/867", "790/867"}; + rowHeight = "0.015 * safeZoneH"; + sizeEx = "0.014 * safeZoneH"; + font = "EtelkaMonospacePro"; + drawSideArrows = 1; + idcLeft = -1; + idcRight = -1; + colorText[] = {0, 0, 0, 1}; + shadow = "0"; + colorSelectBackground[] = {0, 0, 0, 0.025}; + colorSelectBackground2[] = {0, 0, 0, 0.025}; + colorScrollbar[] = {0.95,0,0.95,1}; + class ListScrollBar: ScrollBar { + color[] = {0,0,0,0.6}; + }; + }; + class ChargeListBox: RscListBox { + idc = IDC_CHARGELIST; + x = "13 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "2 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "5 * (safeZoneH / 40)"; + h = "22 * ((safeZoneH / 1.2) / 25)"; + onLBSelChanged = QUOTE([] call FUNC(rangeTableUpdate)); + }; + class elevationHigh: ctrlButton { + idc = IDC_BUTTON_ELEV_HIGH; + text = "High"; + onButtonClick = QUOTE([true] call FUNC(rangeTableUpdate)); + x = "13.1 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "1.1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "2.3 * (safeZoneH / 40)"; + h = "0.8 * ((safeZoneH / 1.2) / 25)"; + }; + class elevationLow: elevationHigh { + idc = IDC_BUTTON_ELEV_LOW; + text = "Low"; + onButtonClick = QUOTE([false] call FUNC(rangeTableUpdate)); + x = "15.6 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + }; + class CloseBackground: RscText { + idc = -1; + x = "33.7634559672906 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "0.5 * (safeZoneH / 40)"; + h = "0.5 * ((safeZoneH / 1.2) / 25)"; + colorBackground[] = {0,0,0,0.5}; + }; + class CloseActiveText: RscActiveText { + idc = -1; + style = 48; + color[] = {1,1,1,0.7}; + text = "A3\Ui_f\data\GUI\Rsc\RscDisplayArcadeMap\icon_exit_cross_ca.paa"; + x = "33.7634559672906 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH) / 2)"; + y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2)) / 2)"; + w = "0.5 * (safeZoneH / 40)"; + h = "0.5 * ((safeZoneH / 1.2) / 25)"; + colorText[] = {1,1,1,0.7}; + colorActive[] = {1,1,1,1}; + tooltip = "Close"; + onButtonClick = "closeDialog 0"; + }; + }; +}; diff --git a/addons/artillerytables/RscTitles.hpp b/addons/artillerytables/RscTitles.hpp new file mode 100644 index 0000000000..c26f302a00 --- /dev/null +++ b/addons/artillerytables/RscTitles.hpp @@ -0,0 +1,41 @@ +class RscTitles { + class GVAR(modeDisplay) { + idd = -1; + onLoad = QUOTE(with uiNameSpace do { GVAR(display) = _this select 0 };); + movingEnable = 0; + duration = 60; + fadeIn = "false"; + fadeOut = "false"; + class controls { + class ModeControlGroup: RscControlsGroupNoScrollbars { + idc = IDC_MODECONTROLGROUP; + x = "3.8 * (((safezoneW / safezoneH) min 1.2) / 40) + (profilenamespace getvariable ['IGUI_GRID_WEAPON_X',((safezoneX + safezoneW) - (10 * (((safezoneW / safezoneH) min 1.2) / 40)) - 4.3 * (((safezoneW / safezoneH) min 1.2) / 40))])"; + y = "2.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (profilenamespace getVariable ['IGUI_GRID_WEAPON_Y', (safezoneY + 0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))])"; + w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + + class controls { + class Charge: RscText { + idc = IDC_CHARGE; + colorText[] = {1, 1, 1, 1}; + colorBackground[] = {0, 0, 0, 0}; + x = "0"; + y = "0"; + w = "(2) * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + sizeEx = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + }; + class Azimuth: Charge { + idc = IDC_AZIMUTH; + x = "(2) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "(3) * (((safezoneW / safezoneH) min 1.2) / 40)"; + }; + class Elevation: Azimuth { + idc = IDC_ELEVATION; + x = "(5) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + }; + }; + }; + }; + }; +}; diff --git a/addons/artillerytables/UI/RangeTable_background.paa b/addons/artillerytables/UI/RangeTable_background.paa new file mode 100644 index 0000000000..bf4b5ee044 Binary files /dev/null and b/addons/artillerytables/UI/RangeTable_background.paa differ diff --git a/addons/artillerytables/UI/icon_rangeTable.paa b/addons/artillerytables/UI/icon_rangeTable.paa new file mode 100644 index 0000000000..9273b849d7 Binary files /dev/null and b/addons/artillerytables/UI/icon_rangeTable.paa differ diff --git a/addons/artillerytables/XEH_PREP.hpp b/addons/artillerytables/XEH_PREP.hpp new file mode 100644 index 0000000000..7ef48b61dd --- /dev/null +++ b/addons/artillerytables/XEH_PREP.hpp @@ -0,0 +1,8 @@ +TRACE_1("prep",_this); + +PREP(firedEH); +PREP(interactMenuOpened); +PREP(rangeTableOpen); +PREP(rangeTableUpdate); +PREP(turretChanged); +PREP(turretPFEH); diff --git a/addons/artillerytables/XEH_postInit.sqf b/addons/artillerytables/XEH_postInit.sqf new file mode 100644 index 0000000000..4f0e203208 --- /dev/null +++ b/addons/artillerytables/XEH_postInit.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" + +["CBA_settingsInitialized", { + TRACE_2("CBA_settingsInitialized",GVAR(advancedCorrections),GVAR(disableArtilleryComputer)); + + if (hasInterface) then { + // Add hud overlay for actuall azimuth and elevation: + GVAR(pfID) = -1; + ["turret", LINKFUNC(turretChanged), true] call CBA_fnc_addPlayerEventHandler; + + // Add ability to dynamically open rangetables: + ["ace_interactMenuOpened", LINKFUNC(interactMenuOpened)] call CBA_fnc_addEventHandler; + }; + + if (GVAR(advancedCorrections)) then { + ["LandVehicle", "init", { + params ["_vehicle"]; + private _vehicleCfg = configOf _vehicle; + // config "ace_artillerytables_applyCorrections" [0 disabled, 1 enabled] falls back to artilleryScanner + private _applyCorrections = if (isNumber (_vehicleCfg >> QGVAR(applyCorrections))) then { + getNumber (_vehicleCfg >> QGVAR(applyCorrections)) + } else { + getNumber (_vehicleCfg >> "artilleryScanner") + }; + if (_applyCorrections == 1) then { + TRACE_2("adding firedEH",_vehicle,configName _vehicleCfg); + _vehicle addEventHandler ["Fired", {call FUNC(firedEH)}]; + }; + }, true, [], true] call CBA_fnc_addClassEventHandler; + }; +}] call CBA_fnc_addEventHandler; + +#ifdef DEBUG_MODE_FULL +#include "dev\showShotInfo.inc.sqf" +#include "dev\checkConfigs.inc.sqf" +#endif diff --git a/addons/artillerytables/XEH_preInit.sqf b/addons/artillerytables/XEH_preInit.sqf new file mode 100644 index 0000000000..894773534a --- /dev/null +++ b/addons/artillerytables/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/optionals/compat_rhs_afrf3/XEH_preStart.sqf b/addons/artillerytables/XEH_preStart.sqf similarity index 100% rename from optionals/compat_rhs_afrf3/XEH_preStart.sqf rename to addons/artillerytables/XEH_preStart.sqf diff --git a/addons/artillerytables/config.cpp b/addons/artillerytables/config.cpp new file mode 100644 index 0000000000..1f6fa9f74e --- /dev/null +++ b/addons/artillerytables/config.cpp @@ -0,0 +1,44 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {"ACE_artilleryTable"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +class ACE_Extensions { + class ace_artillerytables { + windows = 1; + client = 1; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" + + +// Common UI Stuff: +class RscText; +class RscListBox; +class RscListNBox; +class RscPicture; +class RscControlsGroup; +class RscControlsGroupNoScrollbars; +class ScrollBar; +class RscActiveText; +class RscStructuredText; +class ctrlButton; + +#include "RscTitles.hpp" +#include "RscRangeTable.hpp" + diff --git a/addons/artillerytables/dev/checkConfigs.inc.sqf b/addons/artillerytables/dev/checkConfigs.inc.sqf new file mode 100644 index 0000000000..1dfcea7f9f --- /dev/null +++ b/addons/artillerytables/dev/checkConfigs.inc.sqf @@ -0,0 +1,21 @@ +//pragma SKIP_COMPILE +diag_log text "-------------------------------------------"; +INFO("Showing entries with custom configs"); +diag_log text "-------------------------------------------"; + + +private _fnc_showPropertyDefined = { + params ["_configBase", "_configProperty"]; + + private _customAll = configProperties [_configBase, 'isClass _x && {isNumber (_x >> _configProperty)}', true]; + private _customExplicit = _customAll select {[] isNotEqualTo configProperties [_x, 'configName _x == _configProperty', false]}; + diag_log text format ["%1 with custom %2: %3 Explicit, %4 Total]", configName _configBase, _configProperty, count _customExplicit, count _customAll]; + diag_log text format [" - Defined: %1", _customExplicit apply {configName _x}]; + diag_log text format [" - Inherited: %1", _customAll apply {[configName _x, getNumber (_x >> _configProperty)]}]; +}; + +[configFile >> "CfgMagazines", QGVAR(airFriction)] call _fnc_showPropertyDefined; +[configFile >> "CfgVehicles", QGVAR(showGunLaying)] call _fnc_showPropertyDefined; +[configFile >> "CfgVehicles", QGVAR(applyCorrections)] call _fnc_showPropertyDefined; + +diag_log text "-------------------------------------------"; diff --git a/addons/artillerytables/dev/showShotInfo.inc.sqf b/addons/artillerytables/dev/showShotInfo.inc.sqf new file mode 100644 index 0000000000..ac99acbdc1 --- /dev/null +++ b/addons/artillerytables/dev/showShotInfo.inc.sqf @@ -0,0 +1,48 @@ +//pragma SKIP_COMPILE +// #include "..\script_component.hpp" + +INFO("showing shot info"); + +["LandVehicle", "fired", { + params ["_shooter", "", "", "", "_ammo", "", "_proj"]; + ((velocity _proj) call CBA_fnc_vect2Polar) params ["_mag", "_dir", "_elev"]; + private _shootPos = getPosASL _shooter; + if (_dir < 0) then {_dir = _dir + 360;}; + + private _offsetElev = _elev - (missionNamespace getVariable [QGVAR(predictedElevation), -999]); + private _offsetAz = _dir - (missionNamespace getVariable [QGVAR(predictedAzimuth), -999]); + + hintSilent format ["%1 m/s\nAz: %2 [%3]\nEl: %4 [%5]\nError Az: %6\nError EL: %7",_mag toFixed 1, _dir toFixed 2, ((6400 / 360) * _dir) toFixed 0, _elev toFixed 2, ((6400 / 360) * _elev) toFixed 0, + _offsetAz toFixed 3, _offsetElev toFixed 3]; + TRACE_2("",_offsetAz,_offsetElev); + private _submunitionAmmo = getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo"); + + [{ + params ["_proj", "_shootPos", "_lastPos", "_submunitionAmmo"]; + if ((isNull _proj) && {_submunitionAmmo != ""}) then { + _proj = nearestObject [_lastPos, _submunitionAmmo]; + _this set [0, _proj]; + }; + if (isNull _proj) exitWith {true}; + _this set [2, getPosASL _proj]; + false + }, { + params ["", "_shootPos", "_lastPos"]; + private _mkrB = createMarker [format ["shotInfo-%1-%2",_shootPos,_lastPos], _lastPos]; + _mkrB setMarkerType "mil_dot"; + _mkrB setMarkerColor "ColorGreen"; + _mkrB setMarkerSize [0.5,0.5]; + private _diff = _lastPos vectorDiff _shootPos; + _mkrB setMarkerText format ["%1", _diff apply {round _x}]; + + private _dist2d = _shootPos distance2d _lastPos; + private _dir = _shootPos getDir _lastPos; + private _height = (_lastPos select 2) - (_shootPos select 2); + _mkrB setMarkerText format ["Dist: %1m Az: %2[%3] Height:%4", _dist2d toFixed 0, _dir toFixed 2, ((6400 / 360) * _dir) toFixed 0, _height toFixed 0]; + }, [_proj, _shootPos, [0,0,0], _submunitionAmmo]] call CBA_fnc_waitUntilAndExecute; + + private _mkrA = createMarker [format ["shotInfo-%1",_shootPos], _shootPos]; + _mkrA setMarkerType "mil_dot"; + _mkrA setMarkerColor "ColorRed"; + _mkrA setMarkerSize [0.5,0.5]; +}] call CBA_fnc_addClassEventHandler; diff --git a/addons/artillerytables/functions/fnc_firedEH.sqf b/addons/artillerytables/functions/fnc_firedEH.sqf new file mode 100644 index 0000000000..5aa46c6969 --- /dev/null +++ b/addons/artillerytables/functions/fnc_firedEH.sqf @@ -0,0 +1,89 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Called when the mortar is fired. + * + * Arguments: + * 0: mortar - Object the event handler is assigned to + * 1: weapon - Fired weapon + * 2: muzzle - Muzzle that was used + * 3: mode - Current mode of the fired weapon + * 4: ammo - Ammo used + * 5: magazine - magazine name which was used + * 6: projectile - Object of the projectile that was shot + * 7: gunner - Gunner + * + * Return Value: + * None + * + * Example: + * [bisFiredEH] call ace_artillerytables_fnc_firedEH + * + * Public: No + */ + +params ["_vehicle", "", "", "", "", "_magazine", "_projectile", "_gunner"]; +TRACE_4("firedEH",_vehicle,_magazine,_projectile,_gunner); + +if !([_gunner] call EFUNC(common,isPlayer)) exitWith {}; // AI don't know how to use (this does give them more range than a player) +if ((gunner _vehicle) != _gunner) exitWith {}; // check if primaryGunner + + +// Get airFriction +private _airFriction = DEFAULT_AIR_FRICTION; +if (isNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction))) then { + _airFriction = getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction)); +}; +TRACE_1("",_airFriction); +if (_airFriction == 0) exitWith {}; // 0 disables everything + +BEGIN_COUNTER(adjustmentsCalc); + +// Calculate air density +private _altitude = (getPosASL _vehicle) select 2; +private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); +private _pressure = _altitude call EFUNC(weather,calculateBarometricPressure); +private _relativeHumidity = EGVAR(weather,currentHumidity); +private _airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); +private _relativeDensity = _airDensity / 1.225; +TRACE_5("Weather",_temperature,_pressure,_relativeHumidity,_airDensity,_relativeDensity); + +private _kFactor = _airFriction * _relativeDensity; +private _newMuzzleVelocityCoefficent = (((_temperature + 273.13) / 288.13 - 1) / 40 + 1); +TRACE_2("",_kFactor,_newMuzzleVelocityCoefficent); + +// Apply powder effects +if (_newMuzzleVelocityCoefficent != 1) then { + private _bulletVelocity = velocity _projectile; + private _bulletSpeed = vectorMagnitude _bulletVelocity; + _bulletVelocity = (vectorNormalized _bulletVelocity) vectorMultiply (_bulletSpeed * _newMuzzleVelocityCoefficent); + _projectile setVelocity _bulletVelocity; +}; + +if (_airFriction > 0) exitWith {}; // positive value indicates it has vanilla airFriction, so we can just exit + +[{ + params ["_projectile", "_kFactor", "_time"]; + + if (isNull _projectile) exitWith {true}; + + private _deltaT = CBA_missionTime - _time; + _this set[2, CBA_missionTime]; + + private _bulletVelocity = velocity _projectile; + private _trueVelocity = _bulletVelocity vectorDiff wind; + private _trueSpeed = vectorMagnitude _trueVelocity; + + private _drag = _deltaT * _kFactor * _trueSpeed; + private _accel = _trueVelocity vectorMultiply _drag; + // TRACE_3("",_bulletVelocity,_trueSpeed,_accel); + _bulletVelocity = _bulletVelocity vectorAdd _accel; + + _projectile setVelocity _bulletVelocity; + + false +}, { + // TRACE_1("done",_this); +}, [_projectile, _kFactor, CBA_missionTime]] call CBA_fnc_waitUntilAndExecute; + +END_COUNTER(adjustmentsCalc); diff --git a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf new file mode 100644 index 0000000000..4ba6342fc8 --- /dev/null +++ b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf @@ -0,0 +1,108 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Interaction menu opened, search for nearby artillery vehicles. + * + * Arguments: + * 0: Menu Type (1 is self interaction) + * + * Return Value: + * Can Open + * + * Example: + * [1] call ace_artillerytables_fnc_interactMenuOpened + * + * Public: No + */ + +params ["_menuType"]; +TRACE_1("interactMenuOpened",_menuType); + +if (_menuType != 1) exitWith {}; +if !("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems))) exitWith {}; + +private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []]; +private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []]; +TRACE_2("searching for new vehicles",_vehicleAdded,_rangeTablesShown); + +{ + private _vehicleCfg = configOf _x; + // config "ace_artillerytables_showRangetable" [0 disabled, 1 enabled] falls back to artilleryScanner + private _showRangetable = if (isNumber (_vehicleCfg >> QGVAR(showRangetable))) then { + getNumber (_vehicleCfg >> QGVAR(showRangetable)) + } else { + getNumber (_vehicleCfg >> "artilleryScanner") + }; + if ((_showRangetable == 1) && {!(_x in _vehicleAdded)}) then { + private _vehicle = _x; + private _turret = []; + private _turretCfg = configNull; // find turret with artillery, will be one with primaryGunner = 1 (e.g. RHS PRP-3) + { + private _xTurretCfg = [_vehicleCfg, _x] call CBA_fnc_getTurret; + if ((getNumber (_xTurretCfg >> "primaryGunner")) == 1) exitWith { + _turret = _x; + _turretCfg = _xTurretCfg; + }; + } forEach allTurrets _vehicle; + TRACE_3("",_vehicle,configName _vehicleCfg,_turret); + if (isNull _turretCfg) exitWith { ERROR_1("no primaryGunner %1",configName _vehicleCfg); }; + if ((count _turret) != 1) then { WARNING_2("sub turret %1-%2",configName _vehicleCfg,_turret); }; + + private _weaponsTurret = _vehicle weaponsTurret _turret; + if ((count _weaponsTurret) != 1) exitWith { WARNING_1("multiple weapons - %1",configName _vehicleCfg); }; + private _weapon = _weaponsTurret select 0; + + private _turretAnimBody = getText (_turretCfg >> "animationSourceBody"); + private _turretAnimGun = getText (_turretCfg >> "animationSourceGun"); + + // For artillery with detached camera (I_Truck_02_MRL_F) need to use animationSourcePhase + // But that command won't always work, so fallback to animationPhase + private _currentElevRad = _vehicle animationSourcePhase _turretAnimGun; + if (isNil "_currentElevRad") then { _currentElevRad = _vehicle animationPhase _turretAnimGun; }; + private _currentTraverseRad = _vehicle animationSourcePhase _turretAnimBody; + if (isNil "_currentTraverseRad") then { _currentTraverseRad = _vehicle animationPhase _turretAnimBody; }; + + // Some turrets (MK6) have a neutralX rotation that we need to add to min/max config elevation to get actual limits + private _weaponDir = _vehicle weaponDirection _weapon; + private _turretRot = [vectorDir _vehicle, vectorUp _vehicle, deg _currentTraverseRad] call CBA_fnc_vectRotate3D; + private _neutralX = (acos ((_turretRot vectorCos _weaponDir) min 1)) - (deg _currentElevRad); // vectorCos can return values outside of -1..1 + _neutralX = (round (_neutralX * 10)) / 10; // minimize floating point errors + private _minElev = _neutralX + getNumber (_turretCfg >> "minElev"); + private _maxElev = _neutralX + getNumber (_turretCfg >> "maxElev"); + + private _applyCorrections = if (isNumber (_vehicleCfg >> QGVAR(applyCorrections))) then { + getNumber (_vehicleCfg >> QGVAR(applyCorrections)) + } else { + getNumber (_vehicleCfg >> "artilleryScanner") + }; + private _advCorrection = GVAR(advancedCorrections) && {_applyCorrections == 1}; + if ((missionNamespace getVariable [QEGVAR(mk6Mortar,airResistanceEnabled), false]) && {_vehicle isKindOf "Mortar_01_base_F"}) then { + _advCorrection = true; + }; + + // check weapon and limits in case different vehicles use the same weapon (cammo variants should still produce the same array) + private _info = [_weapon, _minElev, _maxElev, _advCorrection]; + + _vehicleAdded pushBack _vehicle; + ace_player setVariable [QGVAR(vehiclesAdded), _vehicleAdded]; + + private _index = _rangeTablesShown pushBackUnique _info; + TRACE_2("",_info,_index); + if (_index != -1) then { + private _statement = { + params ["", "", "_info"]; + TRACE_1("interaction statement",_info); + [FUNC(rangeTableOpen), _info] call CBA_fnc_execNextFrame; // delay a frame because of interaction menu closing dialogs + }; + private _condition = { + //IGNORE_PRIVATE_WARNING ["_player"]; + ("ACE_artilleryTable" in (_player call EFUNC(common,uniqueItems))) && {[_player, objNull, ["notOnMap", "isNotSitting", "isNotInside"]] call EFUNC(common,canInteractWith)} + }; + private _displayName = format ["%1%2", getText (_vehicleCfg >> "displayName"),["","*"] select _advCorrection]; + private _action = [format ['QGVAR(%1)',_index], _displayName, QPATHTOF(UI\icon_rangeTable.paa), _statement, _condition, {}, _info] call EFUNC(interact_menu,createAction); + [ace_player, 1, ["ACE_SelfActions", "ACE_Equipment"], _action] call EFUNC(interact_menu,addActionToObject); + TRACE_1("added action",_displayName); + ace_player setVariable [QGVAR(rangeTablesShown), _rangeTablesShown]; + }; + }; +} forEach (nearestObjects [ace_player, ["LandVehicle"], 25]); diff --git a/addons/artillerytables/functions/fnc_rangeTableOpen.sqf b/addons/artillerytables/functions/fnc_rangeTableOpen.sqf new file mode 100644 index 0000000000..508b8c894c --- /dev/null +++ b/addons/artillerytables/functions/fnc_rangeTableOpen.sqf @@ -0,0 +1,95 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Opens the rangetable and fills the charge listbox. + * + * Arguments: + * 0: Weapon configname + * 1: Elevation Min (Deg) + * 2: Elevation Max (Deg) + * 3: Advanced Corrections Enabled + * + * Return Value: + * None + * + * Example: + * ["mortar_155mm_AMOS", -5, 80, true] call ace_artillerytables_fnc_rangeTableOpen + * + * Public: No + */ + +params ["_weaponName", "_elevMin", "_elevMax", "_advCorrection"]; +TRACE_4("rangeTableOpen",_weaponName,_elevMin,_elevMax,_advCorrection); + +BEGIN_COUNTER(rangeTableOpen); + +createDialog QGVAR(rangeTableDialog); +private _dialog = uiNamespace getVariable [QGVAR(rangeTableDialog), displayNull]; +if (isNull _dialog) exitWith{ERROR("Dialog failed to open");}; +private _ctrlChargeList = _dialog displayCtrl IDC_CHARGELIST; +_dialog setVariable [QGVAR(elevMin),_elevMin]; +_dialog setVariable [QGVAR(elevMax),_elevMax]; +_dialog setVariable [QGVAR(advCorrection),_advCorrection]; +TRACE_2("created dialog",_dialog,_ctrlChargeList); + +// Get Mags: +private _mags = [_weaponName] call CBA_fnc_compatibleMagazines; +if (_mags isEqualTo []) exitWith {WARNING_1("No Mags",_weaponName);}; +private _magCfg = configFile >> "CfgMagazines"; +private _magParamsArray = []; +_mags = _mags apply { + private _initSpeed = getNumber (_magCfg >> _x >> "initSpeed"); + _magParamsArray pushBackUnique _initSpeed; + private _airFriction = 0; + private _magAirFriction = getNumber (_magCfg >> _x >> QGVAR(airFriction)); + if (_magAirFriction <= 0) then { + if (_advCorrection) then { + _airFriction = [DEFAULT_AIR_FRICTION, _magAirFriction] select (isNumber (_magCfg >> _x >> QGVAR(airFriction))); + }; + } else { + // positive value, use ammo's airFriction (regardless of setting) + private _ammo = getText (_magCfg >> _x >> "ammo"); + _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); + }; + _magParamsArray pushBackUnique _airFriction; + [getText (_magCfg >> _x >> "displayNameShort"), getText (_magCfg >> _x >> "displayName"), _initSpeed, _airFriction] +}; +_mags = _mags arrayIntersect _mags; +TRACE_2("",_magParamsArray,_mags); +if ((count _magParamsArray) == 2) then { // test if all magazines share the parameters + _mags = [["", "All Magazines", (_mags select 0) select 2, (_mags select 0) select 3]]; // simplify +}; + +// Get Firemodes: +private _fireModes = getArray (configFile >> "CfgWeapons" >> _weaponName >> "modes"); +_fireModes = (_fireModes apply {configFile >> "CfgWeapons" >> _weaponName >> _x}) select {1 == getNumber (_x >> "showToPlayer")}; +_fireModes = _fireModes apply {[getNumber (_x >> "artilleryCharge"), configName _x]}; +_fireModes sort true; +private _allSameCharge = ((count _fireModes) == 1) && {((_fireModes select 0) select 0) == 1}; +TRACE_2("",_allSameCharge,_fireModes); + +GVAR(magModeData) = []; +{ + _x params ["_xDisplayNameShort", "_xDisplayName", "_xInitSpeed", "_xAirFriction"]; + if (_allSameCharge) then { + _ctrlChargeList lbAdd _xDisplayNameShort; + _ctrlChargeList lbSetTooltip [count GVAR(magModeData), format ["%1\n%2 m/s\n%3", _xDisplayName, _xInitSpeed toFixed 1, _xAirFriction]]; + GVAR(magModeData) pushBack [_xInitSpeed, _xAirFriction]; + } else { + { + _x params ["_xModeCharge"]; + _ctrlChargeList lbAdd format ["[Charge %1] %2", _forEachIndex, _xDisplayNameShort]; // forEachIndex is from firemodes + _ctrlChargeList lbSetTooltip [count GVAR(magModeData), format ["%1\n%2 m/s\n%3", _xDisplayName, (_xInitSpeed * _xModeCharge) toFixed 1, _xAirFriction]]; + GVAR(magModeData) pushBack [_xInitSpeed * _xModeCharge, _xAirFriction]; + } forEach _fireModes; + }; +} forEach _mags; + + +if (isNil QGVAR(lastElevationMode)) then {GVAR(lastElevationMode) = true;}; +if (isNil QGVAR(lastTablePage)) then {GVAR(lastTablePage) = 0;}; +if ((GVAR(lastTablePage) >= (count GVAR(magModeData))) || {GVAR(lastTablePage) < 0}) then { GVAR(lastTablePage) = 0; }; + +END_COUNTER(rangeTableOpen); +TRACE_2("trigger update",GVAR(lastElevationMode),GVAR(lastTablePage)); +_ctrlChargeList lbSetCurSel GVAR(lastTablePage); // triggers call to FUNC(rangeTableUpdate) diff --git a/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf b/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf new file mode 100644 index 0000000000..3e50f9d7ad --- /dev/null +++ b/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf @@ -0,0 +1,64 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Called when listbox selection changes. Updates the rangetable with new values. + * + * Arguments: + * 0: Elevation Mode (true = high,false=low) + * + * Return Value: + * None + * + * Example: + * [] call ace_artillerytables_fnc_rangeTableUpdate + * + * Public: No + */ + +private _dialog = uiNamespace getVariable [QGVAR(rangeTableDialog), displayNull]; +private _ctrlRangeTable = _dialog displayCtrl IDC_TABLE; +private _ctrlChargeList = _dialog displayCtrl IDC_CHARGELIST; +private _ctrlElevationHigh = _dialog displayCtrl IDC_BUTTON_ELEV_HIGH; +private _ctrlElevationLow = _dialog displayCtrl IDC_BUTTON_ELEV_LOW; + +GVAR(lastElevationMode) = param [0, GVAR(lastElevationMode)]; // update if passed a new value +GVAR(lastTablePage) = lbCurSel _ctrlChargeList; + +// get data for currently selected mag/mode combo: +(GVAR(magModeData) select GVAR(lastTablePage)) params [["_muzzleVelocity", -1], ["_airFriction", 0]]; +private _elevMin = _dialog getVariable [QGVAR(elevMin), 0]; +private _elevMax = _dialog getVariable [QGVAR(elevMax), 0]; +_ctrlElevationHigh ctrlSetTextColor ([[0.25,0.25,0.25,1],[1,1,1,1]] select GVAR(lastElevationMode)); +_ctrlElevationLow ctrlSetTextColor ([[1,1,1,1],[0.25,0.25,0.25,1]] select GVAR(lastElevationMode)); + + +lnbClear _ctrlRangeTable; +// Call extension with current data and start workers +TRACE_5("callExtension:start",_muzzleVelocity,_airFriction,_elevMin,_elevMax,GVAR(lastElevationMode)); +private _ret = "ace_artillerytables" callExtension ["start", [_muzzleVelocity,_airFriction,_elevMin,_elevMax,GVAR(lastElevationMode)]]; +TRACE_1("",_ret); + +// Non-blocking read data out of extension as it becomes availiable +[{ + private _dialog = uiNamespace getVariable [QGVAR(rangeTableDialog), displayNull]; + private _ctrlRangeTable = _dialog displayCtrl IDC_TABLE; + if (isNull _dialog) exitWith {true}; + + private _status = 1; // 1 = data on line, 2 - data not ready, 3 - done + while {_status == 1} do { + private _ret = ("ace_artillerytables" callExtension ["getline", []]); + // TRACE_1("callExtension:getline",_ret); + _status = _ret select 1; + if (_status == 1) then { _ctrlRangeTable lnbAddRow parseSimpleArray (_ret select 0) }; + }; + + (_status == 3) // exit loop when all data read +}, { + // put dummy line at end because scrolling is problematic and can't see last line + private _dialog = uiNamespace getVariable [QGVAR(rangeTableDialog), displayNull]; + private _ctrlRangeTable = _dialog displayCtrl IDC_TABLE; + if (isNull _dialog) exitWith {TRACE_1("dialog closed",_this);}; + + _ctrlRangeTable lnbAddRow ["", "", "", "", "", "", "", "", "", "", ""]; + TRACE_1("table filled",_ctrlRangeTable); +}, []] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/artillerytables/functions/fnc_turretChanged.sqf b/addons/artillerytables/functions/fnc_turretChanged.sqf new file mode 100644 index 0000000000..b2c6bafb65 --- /dev/null +++ b/addons/artillerytables/functions/fnc_turretChanged.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Turret changed, determine if we are in the gunner seat of an artillery vehicle. + * + * Arguments: + * 0: Player + * 1: Turret + * + * Return Value: + * Nothing + * + * Example: + * [player, [0]] call ace_artillerytables_fnc_turretChanged + * + * Public: No + */ + +params ["_player", "_turret"]; +private _vehicle = vehicle _player; +private _typeOf = typeOf _vehicle; +private _vehicleCfg = configOf _vehicle; + +// config "ace_artillerytables_showGunLaying" [0 disabled, 1 enabled, 2 enabled w/ alt elevationMode] falls back to artilleryScanner +private _showGunLaying = if (isNumber (_vehicleCfg >> QGVAR(showGunLaying))) then { + getNumber (_vehicleCfg >> QGVAR(showGunLaying)) +} else { + getNumber (_vehicleCfg >> "artilleryScanner") +}; +TRACE_4("turretChanged",_player,_typeOf,_turret,_showGunLaying); + +if (GVAR(pfID) >= 0) then { + TRACE_1("removing pfEH and display",GVAR(pfID)); + [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; + GVAR(pfID) = -1; + if (!isNull (uiNamespace getVariable [QGVAR(display), displayNull])) then { + ([QGVAR(modeDisplay)] call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; + }; +}; + +if ((alive _player) && {_showGunLaying > 0} && {_player == gunner _vehicle}) then { + private _turretCfg = [_typeOf, _turret] call CBA_fnc_getTurret; + private _turretAnimBody = getText (_turretCfg >> "animationSourceBody"); + private _useAltElevation = (_showGunLaying == 2); // StaticMortars need elevation calculated differently, see FUNC(turretPFEH) + + // If the memory point is invalid, then the turret will always use real weapon dir (e.g. CUP BM21) + private _memoryPointGunnerOptics = getText (_turretCfg >> "memoryPointGunnerOptics"); + private _invalidGunnerMem = (_vehicle selectionPosition [_memoryPointGunnerOptics, "Memory"]) isEqualTo [0,0,0]; + if (_invalidGunnerMem) then { INFO_3("[%1-%2] turret's memoryPointGunnerOptics invalid [%3]",typeOf _vehicle,_turret,_memoryPointGunnerOptics); }; + + private _weaponsTurret = _vehicle weaponsTurret _turret; + if ((count _weaponsTurret) != 1) then { WARNING_2("not singular weapon in turret - %1 - %2",_typeOf,_turret); }; + private _weapon = _weaponsTurret param [0, ""]; + + private _fireModes = getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); + _fireModes = (_fireModes apply {configFile >> "CfgWeapons" >> _weapon >> _x}) select {1 == getNumber (_x >> "showToPlayer")}; + _fireModes = _fireModes apply {[getNumber (_x >> "artilleryCharge"), configName _x]}; + _fireModes sort true; + _fireModes = _fireModes apply {_x select 1}; + + GVAR(pfID) = [LINKFUNC(turretPFEH), 0, [_vehicle, _turret, _fireModes, _useAltElevation, _turretAnimBody, _invalidGunnerMem]] call CBA_fnc_addPerFrameHandler; + TRACE_4("added pfEH",GVAR(pfID),_useAltElevation,_turretAnimBody,_invalidGunnerMem); + + #ifdef DEBUG_MODE_FULL + private _ballisticsComputer = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ballisticsComputer"); + private _elevationMode = getNumber (_turretCfg >> "elevationMode"); + private _discreteDistance = getArray (_turretCfg >> "discreteDistance"); + TRACE_4("",_weapon,_ballisticsComputer,_elevationMode,_discreteDistance); + #endif +}; diff --git a/addons/artillerytables/functions/fnc_turretPFEH.sqf b/addons/artillerytables/functions/fnc_turretPFEH.sqf new file mode 100644 index 0000000000..9ad10de1aa --- /dev/null +++ b/addons/artillerytables/functions/fnc_turretPFEH.sqf @@ -0,0 +1,92 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Shows real azimuth and elevation on hud + * + * Arguments: + * 0: PFEH Args + * + * Return Value: + * Nothing + * + * Example: + * [[...]] call ace_artillerytables_fnc_turretPFEH + * + * Public: No + */ + +(_this select 0) params ["_vehicle", "_turret", "_fireModes", "_useAltElevation", "_turretAnimBody", "_invalidGunnerMem"]; + +if (shownArtilleryComputer && {GVAR(disableArtilleryComputer)}) then { + // Still Don't like this solution, but it works + closeDialog 0; + [localize LSTRING(disableArtilleryComputer_displayName)] call EFUNC(common,displayTextStructured); +}; + +// Restart display if null (not just at start, this will happen periodicly) +if (isNull (uiNamespace getVariable [QGVAR(display), displayNull])) then { + TRACE_1("creating display",_this); + ([QGVAR(modeDisplay)] call BIS_fnc_rscLayer) cutRsc [QGVAR(modeDisplay), "PLAIN", 1, false]; +}; + +private _ctrlGroup = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl 1000; +if (cameraView != "GUNNER") exitWith { // need to be in gunner mode, so we can check where the optics are aiming at + _ctrlGroup ctrlShow false; +}; +_ctrlGroup ctrlShow true; + +BEGIN_COUNTER(pfeh); + +private _currentFireMode = (weaponState [_vehicle, _turret]) select 2; +private _currentChargeMode = _fireModes find _currentFireMode; + +private _lookVector = (AGLtoASL (positionCameraToWorld [0,0,0])) vectorFromTo (AGLtoASL (positionCameraToWorld [0,0,1])); +private _weaponDir = _vehicle weaponDirection (currentWeapon _vehicle); + +// Calc real azimuth/elevation +// (looking at the sky VS looking at ground will radicaly change fire direction because BIS) +private _display = uiNamespace getVariable ["ACE_dlgArtillery", displayNull]; +private _useRealWeaponDir = if ((isNull (_display displayCtrl 173)) || {(_vehicle ammo (currentWeapon _vehicle)) == 0}) then { + // With no ammo, distance display will be empty, but gun will still fire at wonky angle if aimed at ground + private _testSeekerPosASL = AGLtoASL (positionCameraToWorld [0,0,0]); + private _testPoint = _testSeekerPosASL vectorAdd (_lookVector vectorMultiply viewDistance); + !((terrainIntersectASL [_testSeekerPosASL, _testPoint]) || {lineIntersects [_testSeekerPosASL, _testPoint, _vehicle]}); +} else { + ((ctrlText (_display displayCtrl 173)) == "--") +}; + +private _realElevation = asin (_weaponDir select 2); +private _realAzimuth = 0; +if (_useRealWeaponDir || _invalidGunnerMem) then { + // No range (looking at sky), it will follow weaponDir: + _realAzimuth = (_weaponDir select 0) atan2 (_weaponDir select 1) +} else { + // Valid range, will fire at camera dir + // Azimuth will still be look dir EVEN IF elevation has flipped over 90! (on steep hills) + _realAzimuth = ((_lookVector select 0) atan2 (_lookVector select 1)); + if (_useAltElevation) then { + // Some small mortars have odd launch angles (I think due to the addition of neutral elevation constant with the manual elevation) + // This gets very close, (should be less than 0.5deg deviation on a 20deg slope) + private _currentTraverseRad = _vehicle animationSourcePhase _turretAnimBody; + if (isNil "_currentTraverseRad") then { _currentTraverseRad = _vehicle animationPhase _turretAnimBody; }; + // Get turret roatation around it's z axis, then calc weapon elev in it's projection + private _turretRot = [vectorDir _vehicle, vectorUp _vehicle, deg _currentTraverseRad] call CBA_fnc_vectRotate3D; + _realElevation = (acos ((_turretRot vectorCos _weaponDir) min 1)) + ((_turretRot call CBA_fnc_vect2polar) select 2); + if (_realElevation > 90) then { _realElevation = 180 - _realElevation; }; // does not flip azimuth! + }; +}; +if (_realAzimuth < 0) then { _realAzimuth = _realAzimuth + 360; }; // mils will be 0-6400 + +private _ctrlCharge = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_CHARGE; +private _ctrlAzimuth = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_AZIMUTH; +private _ctrlElevation = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_ELEVATION; + +_ctrlAzimuth ctrlSetText Format ["AZ: %1", [DEGTOMILS * _realAzimuth, 4, 0] call CBA_fnc_formatNumber]; +_ctrlElevation ctrlSetText Format ["EL: %1", [DEGTOMILS * _realElevation, 4, 0] call CBA_fnc_formatNumber]; +_ctrlCharge ctrlSetText format ["CH: %1", _currentChargeMode]; + +// avalible for other addons (mk6) +GVAR(predictedAzimuth) = _realAzimuth; +GVAR(predictedElevation) = _realElevation; + +END_COUNTER(pfeh); diff --git a/addons/artillerytables/initSettings.inc.sqf b/addons/artillerytables/initSettings.inc.sqf new file mode 100644 index 0000000000..f34190f910 --- /dev/null +++ b/addons/artillerytables/initSettings.inc.sqf @@ -0,0 +1,19 @@ +private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art"], LLSTRING(rangetable_displayName)]; + +[ + QGVAR(advancedCorrections), "CHECKBOX", + [LSTRING(advancedCorrections_displayName), LSTRING(advancedCorrections_description)], + _categoryName, + false, // default value + true, // isGlobal + {[QGVAR(advancedCorrections), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(disableArtilleryComputer), "CHECKBOX", + [LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)], + _categoryName, + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/artillerytables/script_component.hpp b/addons/artillerytables/script_component.hpp new file mode 100644 index 0000000000..128c3c17ff --- /dev/null +++ b/addons/artillerytables/script_component.hpp @@ -0,0 +1,25 @@ +#define COMPONENT artillerytables +#define COMPONENT_BEAUTIFIED ArtilleryTables +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#include "\z\ace\addons\main\script_macros.hpp" + + +// This is a good fit for most large artillery, but a little low for lighter mortars +#define DEFAULT_AIR_FRICTION -0.00006 + +#define DEGTOMILS 17.7777778 + +#define IDC_MODECONTROLGROUP 1000 +#define IDC_CHARGE 1001 +#define IDC_AZIMUTH 1002 +#define IDC_ELEVATION 1003 + +#define IDC_TABLE 2001 +#define IDC_CHARGELIST 2002 +#define IDC_BUTTON_ELEV_HIGH 2003 +#define IDC_BUTTON_ELEV_LOW 2004 diff --git a/addons/artillerytables/stringtable.xml b/addons/artillerytables/stringtable.xml new file mode 100644 index 0000000000..ba5962ae52 --- /dev/null +++ b/addons/artillerytables/stringtable.xml @@ -0,0 +1,103 @@ + + + + + Artillery Rangetable + Artillerieschusstafel + 火炮射程表 + 火炮射表 + Tavola balistica per artiglieria + Dělostřelecké tabulky střelby + 火砲用 射表 + Tabela Strzelnicza + Table de tir d'artillerie + Tabela de Artilharia + Tabla de distancias de artillería + Topçu Menzil Tablosu + Артиллерийская баллистическая таблица + 포병 사격거리표 + + + Universal Artillery Rangetable + Universale Artillerieschusstafel + 通用的火炮射程表 + 通用火炮射表 + Tavola balistica universale per artiglieria + Univerzální dělostřelecká tabulka střelby + 砲兵火砲用の汎用射撃表 + Uniwersalna Tabela Strzelnicza + Table de tir universelle pour l'artillerie. + Tabela de Artilharia Universal + Tabla de distancias universal de artillería + Uluslar arası Topçu Menzil Tablosu + Универсальная артиллерийская баллистическая таблица + 범용 포병 사격거리표 + + + Air Resistance + Opór powietrza + Resistencia al aire + Luftwiderstand + Odpor vzduchu + Resistência do Ar + Résistance de l'air + Légellenállás + Сопротивление воздуха + Resistenza dell'Aria + 空気抵抗 + 공기저항 + 空气阻力 + 空氣阻力 + Hava Direnci + + + For player shots, model air resistance and wind effects + Modeluj opór powietrza oraz wpływ wiatru na tor lotu pocisku dla strzałów z moździerza Mk6 przez graczy + Para disparos del jugador, modelar la resistencia del aire y los efectos de viento + Für Spielerschüsse, Luftwiderstand und Windeffekte + Pro střelbu hráče používat odpor vzduchu a vliv větru + Para disparos do jogador, modelo de resistência de ar e efeitos de vento + Pour les tirs des joueurs, simule la résistance de l'air et les effets du vent. + Játékos általi lövésekhez, legyen-e számított légellenállás és szélhatás + Для выстрелов игрока. Моделирует сопротивление воздуха и эффект ветра + Per Proiettili dei Giocatori, simula la Resistenza dell'Aria e gli Effetti del Vento + プレイヤーが射撃すると、空気抵抗モデルと風による影響を与えます。 + 플레이어가 사격 시 공기저항과 바람에 영향을 받습니다 + 设定由玩家射击的炮弹是否受到空气阻力与风力的影响 + 設定由玩家射擊的迫擊砲,將會受到空氣阻力與風力的影響 + Oyuncu atışları, hava direnci ve rüzgar efektleri için + + + Artillery Computer Disabled + Artilleriecomputer ausgeschaltet + 停用火炮電腦 + 停用弹道计算机 + Computer balistico disattivato + Zakázat používání dělostřeleckého počítače + 砲撃コンピュータの無効化 + Wyłączony Komputer Artyleryjski + Désactiver l'ordinateur de tir + Computador de Artilharia Desabilitado + Computadora de artillería deshabilitada + Topçu Bilgisayarı Devre Dışı + Орудийный компьютер отключён + 탄도계산컴퓨터 비활성화 + + + Disable the vanilla artillery computers + Deaktiviert die Vanilla-Artilleriecomputer + 停用原本的火炮控制電腦 + 禁用游戏自带的弹道计算机 + Disattiva il computer balistico vanilla + Zakázat používání dělostřeleckého počítače základní hry + ゲームの砲撃コンピュータを無効化します。 + Wyłącza komputer artyleryjski wprowadzony w vanili + Désactive l'ordinateur de tir vanilla. + Desabilitar o computador de artilharia padrão + Deshabilita la computadora de artillería por defecto de Arma 3 + Topçu bilgisayarını devre dışı bırak + Отключить ванильный орудийный компьютер + 바닐라 탄도계산컴퓨터를 비활성화 합니다. + + + diff --git a/addons/atragmx/CfgEventHandlers.hpp b/addons/atragmx/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/atragmx/CfgEventHandlers.hpp +++ b/addons/atragmx/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/atragmx/CfgWeapons.hpp b/addons/atragmx/CfgWeapons.hpp index 2fa31fc628..c6eeb566c6 100644 --- a/addons/atragmx/CfgWeapons.hpp +++ b/addons/atragmx/CfgWeapons.hpp @@ -12,6 +12,7 @@ class CfgWeapons { picture = QPATHTOF(UI\ATRAG_Icon.paa); icon = "iconObject_circle"; mapSize = 0.034; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; diff --git a/addons/atragmx/README.md b/addons/atragmx/README.md index 1b68573051..17245373cb 100644 --- a/addons/atragmx/README.md +++ b/addons/atragmx/README.md @@ -2,10 +2,3 @@ ace_atragmx =============== ATragMX - Handheld ballistics calculator - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/atragmx/RscTitles.hpp b/addons/atragmx/RscTitles.hpp index 834c4eb8af..6196346c57 100644 --- a/addons/atragmx/RscTitles.hpp +++ b/addons/atragmx/RscTitles.hpp @@ -14,12 +14,12 @@ class ATragMX_RscText { colorBackground[]={0,0,0,0}; colorText[]={0,0,0,1}; text=""; - x=0; - y=0; - h=0.037; - w=0.30; + x="0"; + y="0"; + h="0.037"; + w="0.30"; font="TahomaB"; - SizeEx=0.03; + SizeEx="0.03"; shadow=0; }; class ATragMX_RscButton { @@ -38,32 +38,32 @@ class ATragMX_RscButton { soundEscape[]={"",0,1}; type=1; style="0x02+0x100"; - x=0; - y=0; - w=0.03; - h=0.03; + x="0"; + y="0"; + w="0.03"; + h="0.03"; font="TahomaB"; - SizeEx=0.025; - offsetX=0.003; - offsetY=0.003; - offsetPressedX=0.0020; - offsetPressedY=0.0020; + SizeEx="0.025"; + offsetX="0.003"; + offsetY="0.003"; + offsetPressedX="0.0020"; + offsetPressedY="0.0020"; borderSize=0; shadow=0; }; class ATragMX_RscEdit { type=2; style=ST_RIGHT; - x=0; - y=0; - w=0.05; - h=0.03; + x="0"; + y="0"; + w="0.05"; + h="0.03"; colorDisabled[]={0,0,0,0.0}; colorBackground[]={0,0,0,0}; colorText[]={0,0,0,1}; colorSelection[]={0,0,0,0.25}; font="TahomaB"; - sizeEx=0.025; + sizeEx="0.025"; text=""; size=0.2; autocomplete=""; @@ -72,10 +72,10 @@ class ATragMX_RscEdit { class ATragMX_RscToolbox { type=6; style=ST_LEFT; - x=0; - y=0; - w=0.2; - h=0.03; + x="0"; + y="0"; + w="0.2"; + h="0.03"; colorDisabled[]={0,0,0,0.0}; colorBackground[]={1,1,1,1}; colorText[]={0,0,0,1}; @@ -86,7 +86,7 @@ class ATragMX_RscToolbox { colorTextDisable[]={0.4,0.4,0.4,1}; colorDisable[]={0.4,0.4,0.4,1}; font="TahomaB"; - sizeEx=0.027; + sizeEx="0.027"; rows=1; columns=2; strings[]={"Entry 1","Entry 2"}; @@ -98,7 +98,7 @@ class ATragMX_RscListBox { type=5; style=LB_TEXTURES; font="TahomaB"; - sizeEx=0.028; + sizeEx="0.028"; rowHeight=0.03; colorDisabled[]={0,0,0,0.0}; colorBackground[]={1,1,1,1}; @@ -109,14 +109,14 @@ class ATragMX_RscListBox { colorSelectBackground[]={0.925,0.925,0.925,1}; colorSelectBackground2[]={0.925,0.925,0.925,1}; period=0; - maxHistoryDelay=1.0; + maxHistoryDelay="1.0"; autoScrollSpeed=-1; - autoScrollDelay=5; + autoScrollDelay="5"; autoScrollRewind=0; soundSelect[]={"",0.09,1}; class ScrollBar { - width=0.05; + width="0.05"; color[]={0.15,0.21,0.23,0.3}; colorActive[]={0.15,0.21,0.23,0.3}; colorDisabled[]={0.15,0.21,0.23,0.3}; @@ -126,7 +126,7 @@ class ATragMX_RscListBox { thumb="\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; }; - class ListScrollBar : ScrollBar { + class ListScrollBar: ScrollBar { }; }; class ATragMX_RscListNBox: ATragMX_RscListBox { @@ -154,125 +154,125 @@ class ATragMX_Display { moving=1; type=0; font="TahomaB"; - SizeEX=0.025; + SizeEX="0.025"; idc=720000; style=48; - x=0.55*safezoneW+safezoneX-0.256; - y=0.265*safezoneH+safezoneY-0.1; - w=1.024; - h=1.024*4/3; + x="0.55*safezoneW+safezoneX-0.256"; + y="0.265*safezoneH+safezoneY-0.1"; + w="1.024"; + h="1.024*4/3"; colorBackground[]={1,1,1,1}; colorText[]={1,1,1,1}; - text=PATHTOF(UI\atrag_d.paa); + text=QPATHTOF(UI\atrag_d.paa); }; class POWER: ATragMX_RscButton { idc=-1; - x=0.55*safezoneW+safezoneX+0.145; - y=0.265*safezoneH+safezoneY+0.94; - w=0.045; - h=0.045*4/3; + x="0.55*safezoneW+safezoneX+0.145"; + y="0.265*safezoneH+safezoneY+0.94"; + w="0.045"; + h="0.045*4/3"; colorBackground[]={0,0,0,0.0}; action="closeDialog 0"; }; class BACK: POWER { idc=-1; - w=0.06; - x=0.55*safezoneW+safezoneX+0.3122; + w="0.06"; + x="0.55*safezoneW+safezoneX+0.3122"; action=QUOTE(call FUNC(init); call FUNC(update_target_selection)); }; class WINDOWS: ATragMX_RscButton { idc=-1; - x=0.55*safezoneW+safezoneX+0.130; - y=0.265*safezoneH+safezoneY+0.88; - w=0.035; - h=0.035*4/3; + x="0.55*safezoneW+safezoneX+0.130"; + y="0.265*safezoneH+safezoneY+0.88"; + w="0.035"; + h="0.035*4/3"; colorBackground[]={0,0,0,0.0}; }; class OK: WINDOWS { idc=-1; - x=0.55*safezoneW+safezoneX+0.347; - y=0.265*safezoneH+safezoneY+0.878; + x="0.55*safezoneW+safezoneX+0.347"; + y="0.265*safezoneH+safezoneY+0.878"; }; class TOP: ATragMX_RscButton { idc=-1; - x=0.55*safezoneW+safezoneX+0.242; - y=0.265*safezoneH+safezoneY+0.85; - w=0.03; - h=0.03; + x="0.55*safezoneW+safezoneX+0.242"; + y="0.265*safezoneH+safezoneY+0.85"; + w="0.03"; + h="0.03"; colorBackground[]={0,0,0,0.0}; action=QUOTE(-1 call FUNC(cycle_gun_list)); }; class BOTTOM: TOP { idc=-1; - y=0.265*safezoneH+safezoneY+0.955; + y="0.265*safezoneH+safezoneY+0.955"; action=QUOTE(+1 call FUNC(cycle_gun_list)); }; class LEFT: ATragMX_RscButton { idc=-1; - x=0.55*safezoneW+safezoneX+0.1925; - y=0.265*safezoneH+safezoneY+0.9; - w=0.05; - h=0.03; + x="0.55*safezoneW+safezoneX+0.1925"; + y="0.265*safezoneH+safezoneY+0.9"; + w="0.05"; + h="0.03"; colorBackground[]={0,0,0,0}; action=QUOTE(((4 + GVAR(currentTarget) - 1) % 4) call FUNC(change_target_slot)); }; class RIGHT: LEFT { idc=-1; - x=0.55*safezoneW+safezoneX+0.2725; + x="0.55*safezoneW+safezoneX+0.2725"; action=QUOTE(((4 + GVAR(currentTarget) + 1) % 4) call FUNC(change_target_slot)); }; class TOP_LEFT: ATragMX_RscButton { idc=-1; - x=0.55*safezoneW+safezoneX+0.162; - y=0.265*safezoneH+safezoneY+0.82; - w=0.031; - h=0.031*4/3; + x="0.55*safezoneW+safezoneX+0.162"; + y="0.265*safezoneH+safezoneY+0.82"; + w="0.031"; + h="0.031*4/3"; colorBackground[]={0,0,0,0.0}; }; class TOP_RIGHT: TOP_LEFT { idc=-1; - x=0.55*safezoneW+safezoneX+0.315; + x="0.55*safezoneW+safezoneX+0.315"; }; class TEXT_GUN_FRAME: ATragMX_RscText { idc=1001; style=64; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.25; - w=0.0925; - h=0.205; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.25"; + w="0.0925"; + h="0.205"; text=""; }; class TEXT_ATMOSPHERE_FRAME: TEXT_GUN_FRAME { idc=1002; - x=0.550*safezoneW+safezoneX+0.205; + x="0.550*safezoneW+safezoneX+0.205"; }; class TEXT_TARGET_FRAME: TEXT_GUN_FRAME { idc=1003; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; }; class TEXT_RESULT_FRAME: TEXT_GUN_FRAME { idc=1004; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.46; - w=0.2825; - h=0.15; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.46"; + w="0.2825"; + h="0.15"; }; class TEXT_GUN_PROFILE: ATragMX_RscText { idc=1000; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.20; - w=0.18; - h=0.03; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.20"; + w="0.18"; + h="0.03"; style=ST_LEFT; - sizeEx=0.025; + sizeEx="0.025"; text=""; }; class TEXT_D: ATragMX_RscButton { idc=600; - w=0.0231; - x=0.550*safezoneW+safezoneX+0.29; - y=0.265*safezoneH+safezoneY+0.20; + w="0.0231"; + x="0.550*safezoneW+safezoneX+0.29"; + y="0.265*safezoneH+safezoneY+0.20"; colorText[]={0,0,0,1}; colorDisabled[]={0.8,0.8,0.8,1}; colorBackgroundDisabled[]={0,0,0,1}; @@ -282,20 +282,20 @@ class ATragMX_Display { }; class TEXT_E: TEXT_D { idc=601; - x=0.550*safezoneW+safezoneX+0.3131; + x="0.550*safezoneW+safezoneX+0.3131"; text="E"; action=QUOTE(GVAR(currentUnit)=1; call FUNC(update_unit_selection)); }; class TEXT_M: TEXT_E { idc=602; - x=0.550*safezoneW+safezoneX+0.3362; + x="0.550*safezoneW+safezoneX+0.3362"; text="M"; action=QUOTE(GVAR(currentUnit)=2; call FUNC(update_unit_selection)); }; class TEXT_RANGE_CARD: TEXT_D { idc=603; - w=0.03; - x=0.550*safezoneW+safezoneX+0.36; + w="0.03"; + x="0.550*safezoneW+safezoneX+0.36"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="RC"; @@ -304,9 +304,9 @@ class ATragMX_Display { class TEXT_GUN: ATragMX_RscButton { idc=4000; - w=0.0925; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.25; + w="0.0925"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.25"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="Gun"; @@ -315,41 +315,41 @@ class ATragMX_Display { class TEXT_BORE_HEIGHT: TEXT_GUN_PROFILE { idc=10; style=ST_LEFT; - y=0.265*safezoneH+safezoneY+0.285; + y="0.265*safezoneH+safezoneY+0.285"; text="BH"; }; class TEXT_BORE_HEIGHT_OUTPUT: TEXT_BORE_HEIGHT { idc=100; style=ST_RIGHT; - w=0.058; - x=0.550*safezoneW+safezoneX+0.145; - y=0.265*safezoneH+safezoneY+0.285; + w="0.058"; + x="0.550*safezoneW+safezoneX+0.145"; + y="0.265*safezoneH+safezoneY+0.285"; }; class TEXT_BULLET_MASS: TEXT_BORE_HEIGHT { idc=11; style=ST_LEFT; - y=0.265*safezoneH+safezoneY+0.320; + y="0.265*safezoneH+safezoneY+0.320"; text="BW"; }; class TEXT_BULLET_MASS_OUTPUT: TEXT_BORE_HEIGHT_OUTPUT { idc=110; - y=0.265*safezoneH+safezoneY+0.320; + y="0.265*safezoneH+safezoneY+0.320"; }; class TEXT_AIR_FRICTION: TEXT_BORE_HEIGHT { idc=12; - y=0.265*safezoneH+safezoneY+0.355; + y="0.265*safezoneH+safezoneY+0.355"; text="C1"; }; class TEXT_AIR_FRICTION_OUTPUT: TEXT_BORE_HEIGHT_OUTPUT { idc=120; - y=0.265*safezoneH+safezoneY+0.355; + y="0.265*safezoneH+safezoneY+0.355"; }; class TEXT_MUZZLE_VELOCITY: ATragMX_RscButton { idc=13; style=0; - w=0.03; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.390; + w="0.03"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.390"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="MV"; @@ -357,69 +357,69 @@ class ATragMX_Display { }; class TEXT_MUZZLE_VELOCITY_OUTPUT: TEXT_BORE_HEIGHT_OUTPUT { idc=130; - y=0.265*safezoneH+safezoneY+0.390; + y="0.265*safezoneH+safezoneY+0.390"; }; class TEXT_ZERO_RANGE: TEXT_BORE_HEIGHT { idc=14; - y=0.265*safezoneH+safezoneY+0.425; + y="0.265*safezoneH+safezoneY+0.425"; text="ZR"; }; class TEXT_ZERO_RANGE_OUTPUT: TEXT_BORE_HEIGHT_OUTPUT { idc=140; - y=0.265*safezoneH+safezoneY+0.425; + y="0.265*safezoneH+safezoneY+0.425"; }; class TEXT_ATMOSPHERE: TEXT_GUN { idc=4001; - x=0.550*safezoneW+safezoneX+0.205; + x="0.550*safezoneW+safezoneX+0.205"; text="Atmsphr"; action=QUOTE(0 call FUNC(toggle_atmo_env_data)); }; class TEXT_TEMPERATURE: TEXT_BULLET_MASS { idc=20; - x=0.550*safezoneW+safezoneX+0.20; + x="0.550*safezoneW+safezoneX+0.20"; text="Tmp"; }; class TEXT_TEMPERATURE_OUTPUT: TEXT_TEMPERATURE { idc=200; style=ST_RIGHT; - w=0.050; - x=0.550*safezoneW+safezoneX+0.245; - y=0.265*safezoneH+safezoneY+0.320; + w="0.050"; + x="0.550*safezoneW+safezoneX+0.245"; + y="0.265*safezoneH+safezoneY+0.320"; text=""; }; class TEXT_BAROMETRIC_PRESSURE: TEXT_TEMPERATURE { idc=21; - x=0.550*safezoneW+safezoneX+0.20; - y=0.265*safezoneH+safezoneY+0.355; + x="0.550*safezoneW+safezoneX+0.20"; + y="0.265*safezoneH+safezoneY+0.355"; text="BP"; }; class TEXT_BAROMETRIC_PRESSURE_OUTPUT: TEXT_TEMPERATURE_OUTPUT { idc=210; - y=0.265*safezoneH+safezoneY+0.355; + y="0.265*safezoneH+safezoneY+0.355"; }; class TEXT_RELATIVE_HUMIDITY: TEXT_BAROMETRIC_PRESSURE { idc=22; - y=0.265*safezoneH+safezoneY+0.390; + y="0.265*safezoneH+safezoneY+0.390"; text="RH"; }; class TEXT_RELATIVE_HUMIDITY_OUTPUT: TEXT_TEMPERATURE_OUTPUT { idc=220; - y=0.265*safezoneH+safezoneY+0.390; + y="0.265*safezoneH+safezoneY+0.390"; }; class TEXT_ALTITUDE: TEXT_BORE_HEIGHT { idc=23; - x=0.550*safezoneW+safezoneX+0.20; + x="0.550*safezoneW+safezoneX+0.20"; text="Alt"; }; class TEXT_ALTITUDE_OUTPUT: TEXT_TEMPERATURE_OUTPUT { idc=230; - y=0.265*safezoneH+safezoneY+0.285; + y="0.265*safezoneH+safezoneY+0.285"; }; class TEXT_TARGET_A: ATragMX_RscButton { idc=500; - w=0.0231; - x=0.550*safezoneW+safezoneX+0.205; - y=0.265*safezoneH+safezoneY+0.425; + w="0.0231"; + x="0.550*safezoneW+safezoneX+0.205"; + y="0.265*safezoneH+safezoneY+0.425"; colorText[]={0,0,0,1}; colorDisabled[]={0.8,0.8,0.8,1}; colorBackgroundDisabled[]={0,0,0,1}; @@ -429,180 +429,180 @@ class ATragMX_Display { }; class TEXT_TARGET_B: TEXT_TARGET_A { idc=501; - x=0.550*safezoneW+safezoneX+0.2281; + x="0.550*safezoneW+safezoneX+0.2281"; text="B"; action=QUOTE(1 call FUNC(change_target_slot)); }; class TEXT_TARGET_C: TEXT_TARGET_A { idc=502; - x=0.550*safezoneW+safezoneX+0.2512; + x="0.550*safezoneW+safezoneX+0.2512"; text="C"; action=QUOTE(2 call FUNC(change_target_slot)); }; class TEXT_TARGET_D: TEXT_TARGET_A { idc=503; - x=0.550*safezoneW+safezoneX+0.2743; + x="0.550*safezoneW+safezoneX+0.2743"; text="D"; action=QUOTE(3 call FUNC(change_target_slot)); }; class TEXT_TARGET: TEXT_GUN { idc=4002; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; text="Target"; action=QUOTE(0 call FUNC(toggle_target_data)); }; class TEXT_WIND_SPEED: TEXT_BORE_HEIGHT { idc=30; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; text="WS"; }; class TEXT_WIND_SPEED_OUTPUT: TEXT_BORE_HEIGHT_OUTPUT { idc=300; - w=0.058; - x=0.550*safezoneW+safezoneX+0.335; - y=0.265*safezoneH+safezoneY+0.285; + w="0.058"; + x="0.550*safezoneW+safezoneX+0.335"; + y="0.265*safezoneH+safezoneY+0.285"; text="0"; }; class TEXT_WIND_DIRECTION: TEXT_BULLET_MASS { idc=31; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; text="WD"; }; class TEXT_WIND_DIRECTION_OUTPUT: TEXT_WIND_SPEED_OUTPUT { idc=310; - y=0.265*safezoneH+safezoneY+0.32; + y="0.265*safezoneH+safezoneY+0.32"; }; class TEXT_INCLINATION_ANGLE: TEXT_AIR_FRICTION { idc=32; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; text="IA"; }; class TEXT_INCLINATION_ANGLE_OUTPUT: TEXT_WIND_SPEED_OUTPUT { idc=320; - y=0.265*safezoneH+safezoneY+0.355; + y="0.265*safezoneH+safezoneY+0.355"; }; class TEXT_TARGET_SPEED: TEXT_MUZZLE_VELOCITY { idc=33; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; text="TS"; action=QUOTE(0 call FUNC(toggle_target_speed_assist)); }; class TEXT_TARGET_SPEED_OUTPUT: TEXT_WIND_SPEED_OUTPUT { idc=330; - y=0.265*safezoneH+safezoneY+0.39; + y="0.265*safezoneH+safezoneY+0.39"; }; class TEXT_TARGET_RANGE: TEXT_TARGET_SPEED { idc=34; - y=0.265*safezoneH+safezoneY+0.425; + y="0.265*safezoneH+safezoneY+0.425"; text="TR"; action=QUOTE(0 call FUNC(toggle_target_range_assist)); }; class TEXT_TARGET_RANGE_INPUT: TEXT_WIND_SPEED_OUTPUT { idc=340; - y=0.265*safezoneH+safezoneY+0.425; + y="0.265*safezoneH+safezoneY+0.425"; }; class TEXT_ELEVATION: TEXT_GUN_PROFILE { idc=40; - w=0.05; - x=0.550*safezoneW+safezoneX+0.115; - y=0.265*safezoneH+safezoneY+0.50; + w="0.05"; + x="0.550*safezoneW+safezoneX+0.115"; + y="0.265*safezoneH+safezoneY+0.50"; text="Elev"; }; class TEXT_ABSOLUTE: TEXT_GUN_PROFILE { idc=4003; - w=0.07; + w="0.07"; style=ST_CENTER; - x=0.550*safezoneW+safezoneX+0.17; - y=0.265*safezoneH+safezoneY+0.47; + x="0.550*safezoneW+safezoneX+0.17"; + y="0.265*safezoneH+safezoneY+0.47"; text="Abs"; }; class TEXT_RELATIVE: TEXT_ABSOLUTE { idc=4004; - x=0.550*safezoneW+safezoneX+0.245; + x="0.550*safezoneW+safezoneX+0.245"; text="Rel"; }; class TEXT_CURRENT: TEXT_ABSOLUTE { idc=4005; - x=0.550*safezoneW+safezoneX+0.32; + x="0.550*safezoneW+safezoneX+0.32"; text="Cur"; }; class TEXT_ELEVATION_OUTPUT_ABSOLUTE: ATragMX_RscText { idc=400; - style=ST_WITH_RECT+ST_RIGHT; - sizeEx=0.025; - w=0.065; - h=0.032; - x=0.550*safezoneW+safezoneX+0.17; - y=0.265*safezoneH+safezoneY+0.50; + style=QUOTE(ST_WITH_RECT+ST_RIGHT); + sizeEx="0.025"; + w="0.065"; + h="0.032"; + x="0.550*safezoneW+safezoneX+0.17"; + y="0.265*safezoneH+safezoneY+0.50"; text=""; }; class TEXT_ELEVATION_OUTPUT_RELATIVE: TEXT_ELEVATION_OUTPUT_ABSOLUTE { idc=401; - x=0.550*safezoneW+safezoneX+0.2465; + x="0.550*safezoneW+safezoneX+0.2465"; }; class TEXT_ELEVATION_INPUT_CURRENT: TEXT_ELEVATION_OUTPUT_ABSOLUTE { idc=402; - x=0.550*safezoneW+safezoneX+0.323; + x="0.550*safezoneW+safezoneX+0.323"; }; class TEXT_WINDAGE: TEXT_ELEVATION { idc=41; - y=0.265*safezoneH+safezoneY+0.535; + y="0.265*safezoneH+safezoneY+0.535"; text="Wind"; }; class TEXT_WINDAGE_OUTPUT_ABSOLUTE: TEXT_ELEVATION_OUTPUT_ABSOLUTE { idc=410; - y=0.265*safezoneH+safezoneY+0.535; + y="0.265*safezoneH+safezoneY+0.535"; }; class TEXT_WINDAGE_OUTPUT_RELATIVE: TEXT_WINDAGE_OUTPUT_ABSOLUTE { idc=411; - x=0.550*safezoneW+safezoneX+0.2465; + x="0.550*safezoneW+safezoneX+0.2465"; }; class TEXT_WINDAGE_INPUT_CURRENT: TEXT_WINDAGE_OUTPUT_ABSOLUTE { idc=412; - x=0.550*safezoneW+safezoneX+0.323; + x="0.550*safezoneW+safezoneX+0.323"; }; class TEXT_LEAD: TEXT_GUN { idc=42; - w=0.05; - x=0.550*safezoneW+safezoneX+0.115; - y=0.265*safezoneH+safezoneY+0.57; + w="0.05"; + x="0.550*safezoneW+safezoneX+0.115"; + y="0.265*safezoneH+safezoneY+0.57"; text="Lead"; action=QUOTE(GVAR(showWind2) = !GVAR(showWind2); call FUNC(update_result); call FUNC(update_target)); }; class TEXT_LEAD_OUTPUT: TEXT_ELEVATION_OUTPUT_ABSOLUTE { idc=420; - y=0.265*safezoneH+safezoneY+0.57; + y="0.265*safezoneH+safezoneY+0.57"; }; class TEXT_RESET_SCOPE_ZERO: TEXT_GUN { idc=4006; - w=0.07; + w="0.07"; style=ST_CENTER; colorBackground[]={0,0,0,0}; - x=0.550*safezoneW+safezoneX+0.2465; - y=0.265*safezoneH+safezoneY+0.57; + x="0.550*safezoneW+safezoneX+0.2465"; + y="0.265*safezoneH+safezoneY+0.57"; text="Reset"; action=QUOTE(call FUNC(reset_relative_click_memory)); }; class TEXT_UPDATE_SCOPE_ZERO: TEXT_RESET_SCOPE_ZERO { idc=4007; - x=0.550*safezoneW+safezoneX+0.323; + x="0.550*safezoneW+safezoneX+0.323"; text="Update"; action=QUOTE(call FUNC(update_relative_click_memory)); }; class TEXT_GUN_LIST: TEXT_GUN { idc=4008; style=ST_LEFT; - y=0.265*safezoneH+safezoneY+0.65; + y="0.265*safezoneH+safezoneY+0.65"; text="GunList"; action=QUOTE(call FUNC(toggle_gun_list)); }; class TEXT_SCOPE_UNIT: TEXT_GUN_LIST { idc=2000; style=ST_CENTER; - w=0.06; - x=0.550*safezoneW+safezoneX+0.205; + w="0.06"; + x="0.550*safezoneW+safezoneX+0.205"; colorBackground[]={0,0,0,0}; text="TMOA"; action=QUOTE(call FUNC(cycle_scope_unit)); @@ -610,15 +610,15 @@ class ATragMX_Display { class TEXT_SCOPE_CLICK_NUMBER: TEXT_GUN_LIST { idc=2001; style=ST_CENTER; - w=0.025; - x=0.550*safezoneW+safezoneX+0.27; + w="0.025"; + x="0.550*safezoneW+safezoneX+0.27"; text="4"; action=QUOTE(call FUNC(toggle_solution_setup)); }; class TEXT_OPTIONS: TEXT_GUN_LIST { idc=3000; style=ST_RIGHT; - x=0.550*safezoneW+safezoneX+0.3; + x="0.550*safezoneW+safezoneX+0.3"; text="Options"; action=QUOTE(false call FUNC(toggle_option_menu)); }; @@ -627,22 +627,22 @@ class ATragMX_Display { colorBackground[]={0.15,0.21,0.23,0.2}; colorBackgroundActive[]={0.15,0.21,0.23,0.2}; colorFocused[]={0.15,0.21,0.23,0.2}; - x=0.550*safezoneW+safezoneX+0.105; - y=0.265*safezoneH+safezoneY+0.17; - w=0.3; - h=0.535; - offsetPressedX=0.0; - offsetPressedY=0.0; + x="0.550*safezoneW+safezoneX+0.105"; + y="0.265*safezoneH+safezoneY+0.17"; + w="0.3"; + h="0.535"; + offsetPressedX="0.0"; + offsetPressedY="0.0"; action=QUOTE(false call FUNC(toggle_option_menu)); }; class TEXT_OPTIONS_LIST_OUTPUT: ATragMX_RscListBox { idc=3002; style=0; - w=0.17; - h=0.28; - x=0.550*safezoneW+safezoneX+0.225; - y=0.265*safezoneH+safezoneY+0.355; - sizeEx=0.025; + w="0.17"; + h="0.28"; + x="0.550*safezoneW+safezoneX+0.225"; + y="0.265*safezoneH+safezoneY+0.355"; + sizeEx="0.025"; onMouseButtonClick=QUOTE(true call FUNC(toggle_option_menu)); }; @@ -652,9 +652,9 @@ class ATragMX_Display { }; class TEXT_RANGE_CARD_SETUP: ATragMX_RscButton { idc=5001; - w=0.055675; - x=0.550*safezoneW+safezoneX+0.28; - y=0.265*safezoneH+safezoneY+0.20; + w="0.055675"; + x="0.550*safezoneW+safezoneX+0.28"; + y="0.265*safezoneH+safezoneY+0.20"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="Setup"; @@ -662,32 +662,32 @@ class ATragMX_Display { }; class TEXT_RANGE_CARD_DONE: TEXT_RANGE_CARD_SETUP { idc=5002; - x=0.550*safezoneW+safezoneX+0.3362; + x="0.550*safezoneW+safezoneX+0.3362"; text="Done"; action=QUOTE(call FUNC(toggle_range_card)); }; class TEXT_RANGE_CARD_COLUMN_1_CAPTION: ATragMX_RscButton { idc=5003; style=ST_LEFT; - w=0.07; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.24; + w="0.07"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.24"; colorBackground[]={0.15,0.21,0.23,0.3}; text="Meters"; }; class TEXT_RANGE_CARD_COLUMN_2_CAPTION: TEXT_RANGE_CARD_COLUMN_1_CAPTION { idc=5004; - x=0.550*safezoneW+safezoneX+0.180625; + x="0.550*safezoneW+safezoneX+0.180625"; text="Elev"; }; class TEXT_RANGE_CARD_COLUMN_3_CAPTION: TEXT_RANGE_CARD_COLUMN_1_CAPTION { idc=5005; - x=0.550*safezoneW+safezoneX+0.25125; + x="0.550*safezoneW+safezoneX+0.25125"; text="Wind"; }; class TEXT_RANGE_CARD_COLUMN_4_CAPTION: TEXT_RANGE_CARD_COLUMN_1_CAPTION { idc=5006; - x=0.550*safezoneW+safezoneX+0.321875; + x="0.550*safezoneW+safezoneX+0.321875"; text="TmFlt"; action=QUOTE(call FUNC(cycle_range_card_columns)); }; @@ -696,98 +696,98 @@ class ATragMX_Display { columns[]={0.0, 0.225, 0.475, 0.7}; idcLeft=50061; idcRight=50062; - w=0.285; - h=0.42; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.27; + w="0.285"; + h="0.42"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.27"; }; class TEXT_GUN_LIST_OUTPUT: ATragMX_RscListNBox { idc=6000; columns[]={-0.05}; - w=0.16; - h=0.45; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.24; - sizeEx=0.018; + w="0.16"; + h="0.45"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.24"; + sizeEx="0.018"; colorSelectBackground[]={0.15,0.21,0.23,0.3}; colorSelectBackground2[]={0.15,0.21,0.23,0.3}; onLBDblClick=QUOTE(true call FUNC(toggle_gun_list)); }; class TEXT_GUN_LIST_COLUMN_CAPTION: TEXT_GUN_PROFILE { idc=6001; - w=0.16; + w="0.16"; colorBackground[]={0.15,0.21,0.23,0.3}; text="AtragGun.gun"; }; class TEXT_GUN_LIST_OPEN_GUN: ATragMX_RscButton { idc=6002; style=ST_RIGHT; - w=0.115; - x=0.550*safezoneW+safezoneX+0.28; - y=0.265*safezoneH+safezoneY+0.20; + w="0.115"; + x="0.550*safezoneW+safezoneX+0.28"; + y="0.265*safezoneH+safezoneY+0.20"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; - sizeEx=0.024; + sizeEx="0.024"; text="Open Gun"; action=QUOTE(true call FUNC(toggle_gun_list)); }; class TEXT_GUN_LIST_SAVE_GUN: TEXT_GUN_LIST_OPEN_GUN { idc=6003; - y=0.265*safezoneH+safezoneY+0.24; + y="0.265*safezoneH+safezoneY+0.24"; text="Save Gun"; action=QUOTE(call FUNC(save_gun)); }; class TEXT_GUN_LIST_ADD_NEW_GUN: TEXT_GUN_LIST_OPEN_GUN { idc=6004; - y=0.265*safezoneH+safezoneY+0.28; + y="0.265*safezoneH+safezoneY+0.28"; text="Add New Gun"; action=QUOTE(false call FUNC(show_gun_list); true call FUNC(show_add_new_gun)); }; class TEXT_GUN_LIST_DELETE_GUN: TEXT_GUN_LIST_OPEN_GUN { idc=6005; - y=0.265*safezoneH+safezoneY+0.34; + y="0.265*safezoneH+safezoneY+0.34"; text="Delete Gun"; action=QUOTE(call FUNC(delete_gun)); }; class TEXT_GUN_LIST_NOTE: TEXT_GUN_LIST_OPEN_GUN { idc=6006; - y=0.265*safezoneH+safezoneY+0.40; + y="0.265*safezoneH+safezoneY+0.40"; text="Note"; }; class TEXT_GUN_LIST_DONE: TEXT_GUN_LIST_OPEN_GUN { idc=6007; - y=0.265*safezoneH+safezoneY+0.65; + y="0.265*safezoneH+safezoneY+0.65"; text="Done"; action=QUOTE(false call FUNC(toggle_gun_list)); }; class TEXT_TARGET_RANGE_ASSIST_CAPTION: ATragMX_RscText { idc=7000; - style=16+0x200; + style="16+0x200"; lineSpacing=1.0; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.24; - w=0.29; - h=0.10; - sizeEx=0.022; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.24"; + w="0.29"; + h="0.10"; + sizeEx="0.022"; text="When using WIDTH to size a target, UP/Down Angle does not effect range calculation but will effect bullet drop."; }; class TEXT_TARGET_RANGE_ASSIST_MEASUREMENT_METHOD: TEXT_TARGET_RANGE_ASSIST_CAPTION { idc=7001; style=ST_LEFT; - x=0.550*safezoneW+safezoneX+0.115; - y=0.265*safezoneH+safezoneY+0.35; - w=0.12; - h=0.03; - sizeEx=0.027; + x="0.550*safezoneW+safezoneX+0.115"; + y="0.265*safezoneH+safezoneY+0.35"; + w="0.12"; + h="0.03"; + sizeEx="0.027"; text="Using Target:"; }; class TEXT_TARGET_RANGE_ASSIST_WIDTH_HEIGHT: ATragMX_RscToolbox { idc=7002; - w=0.14; - x=0.550*safezoneW+safezoneX+0.24; - y=0.265*safezoneH+safezoneY+0.35; + w="0.14"; + x="0.550*safezoneW+safezoneX+0.24"; + y="0.265*safezoneH+safezoneY+0.35"; strings[]={"Height","Width"}; values[]={1,0}; onToolBoxSelChanged=QUOTE(GVAR(rangeAssistUseTargetHeight) = ((_this select 1) == 0)); @@ -795,89 +795,89 @@ class ATragMX_Display { class TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE: TEXT_TARGET_RANGE_ASSIST_MEASUREMENT_METHOD { idc=7003; style=ST_RIGHT; - x=0.550*safezoneW+safezoneX+0.092; - y=0.265*safezoneH+safezoneY+0.4; - w=0.128; + x="0.550*safezoneW+safezoneX+0.092"; + y="0.265*safezoneH+safezoneY+0.4"; + w="0.128"; text="Target Size"; }; class TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { idc=7004; - y=0.265*safezoneH+safezoneY+0.45; + y="0.265*safezoneH+safezoneY+0.45"; text="Image Size"; }; class TEXT_TARGET_RANGE_ASSIST_ANGLE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { idc=7005; - y=0.265*safezoneH+safezoneY+0.5; + y="0.265*safezoneH+safezoneY+0.5"; text="Angle"; }; class TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { idc=7006; - y=0.265*safezoneH+safezoneY+0.55; + y="0.265*safezoneH+safezoneY+0.55"; text="Est Range"; }; class TEXT_TARGET_RANGE_ASSIST_CALC_1: TEXT_MUZZLE_VELOCITY { idc=7007; - w=0.0231; - x=0.550*safezoneW+safezoneX+0.22; - y=0.265*safezoneH+safezoneY+0.4; - sizeEx=0.03; + w="0.0231"; + x="0.550*safezoneW+safezoneX+0.22"; + y="0.265*safezoneH+safezoneY+0.4"; + sizeEx="0.03"; text="!"; action=QUOTE(0 call FUNC(calculate_target_range_assist)); }; class TEXT_TARGET_RANGE_ASSIST_CALC_2: TEXT_TARGET_RANGE_ASSIST_CALC_1 { idc=7008; - y=0.265*safezoneH+safezoneY+0.45; + y="0.265*safezoneH+safezoneY+0.45"; action=QUOTE(1 call FUNC(calculate_target_range_assist)); }; class TEXT_TARGET_RANGE_ASSIST_CALC_3: TEXT_TARGET_RANGE_ASSIST_CALC_1 { idc=7009; - y=0.265*safezoneH+safezoneY+0.55; + y="0.265*safezoneH+safezoneY+0.55"; action=QUOTE(2 call FUNC(calculate_target_range_assist)); }; class TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT: ATragMX_RscEdit { idc=7010; - w=0.065; - x=0.550*safezoneW+safezoneX+0.2475; - y=0.265*safezoneH+safezoneY+0.4; + w="0.065"; + x="0.550*safezoneW+safezoneX+0.2475"; + y="0.265*safezoneH+safezoneY+0.4"; }; class TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE_INPUT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT { idc=7011; - y=0.265*safezoneH+safezoneY+0.45; + y="0.265*safezoneH+safezoneY+0.45"; }; class TEXT_TARGET_RANGE_ASSIST_ANGLE_INPUT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT { idc=7012; - y=0.265*safezoneH+safezoneY+0.5; + y="0.265*safezoneH+safezoneY+0.5"; }; class TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE_INPUT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT { idc=7013; - y=0.265*safezoneH+safezoneY+0.55; + y="0.265*safezoneH+safezoneY+0.55"; }; class TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_UNIT: TEXT_TARGET_RANGE_ASSIST_CALC_1 { idc=7014; - w=0.07; - x=0.550*safezoneW+safezoneX+0.32; + w="0.07"; + x="0.550*safezoneW+safezoneX+0.32"; text="cm"; action=QUOTE(call FUNC(cycle_target_size_units)); }; class TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE_UNIT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_UNIT { idc=7015; - y=0.265*safezoneH+safezoneY+0.45; + y="0.265*safezoneH+safezoneY+0.45"; text="MIL"; action=QUOTE(call FUNC(cycle_image_size_units)); }; class TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE_UNIT: TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE { idc=7016; style=ST_LEFT; - w=0.07; - x=0.550*safezoneW+safezoneX+0.32; + w="0.07"; + x="0.550*safezoneW+safezoneX+0.32"; text="Meters"; }; class TEXT_TARGET_RANGE_ASSIST_DONE: ATragMX_RscButton { idc=7017; style=ST_CENTER; - w=0.07; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.60; + w="0.07"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.60"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="Done"; @@ -885,41 +885,41 @@ class ATragMX_Display { }; class TEXT_TARGET_RANGE_ASSIST_CANCEL: TEXT_TARGET_RANGE_ASSIST_DONE { idc=7018; - x=0.550*safezoneW+safezoneX+0.180625; + x="0.550*safezoneW+safezoneX+0.180625"; text="Cancel"; action=QUOTE(0 call FUNC(toggle_target_range_assist)); }; class TEXT_TARGET_RANGE_ASSIST_PREV: TEXT_TARGET_RANGE_ASSIST_DONE { idc=7019; - x=0.550*safezoneW+safezoneX+0.25125; + x="0.550*safezoneW+safezoneX+0.25125"; text="Prev"; action=""; }; class TEXT_TARGET_RANGE_ASSIST_NEXT: TEXT_TARGET_RANGE_ASSIST_DONE { idc=7020; - x=0.550*safezoneW+safezoneX+0.321875; + x="0.550*safezoneW+safezoneX+0.321875"; text="Next"; action=""; }; class TEXT_TARGET_SPEED_ASSIST_TARGET_RANGE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { idc=8000; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="Target Range"; }; class TEXT_TARGET_SPEED_ASSIST_NUM_TICKS: TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE { idc=8001; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="Num Ticks"; }; class TEXT_TARGET_SPEED_ASSIST_TIME: TEXT_TARGET_RANGE_ASSIST_ANGLE { idc=8002; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="Time (secs)"; }; class TEXT_TARGET_SPEED_ASSIST_TARGET_ESTIMATED_SPEED: TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE { idc=8003; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="Est Speed"; }; class TEXT_TARGET_SPEED_ASSIST_TARGET_RANGE_INPUT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT { @@ -936,15 +936,15 @@ class ATragMX_Display { }; class TEXT_TARGET_SPEED_ASSIST_TARGET_ESTIMATED_SPEED_OUTPUT: TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE { idc=8007; - w=0.065; - x=0.550*safezoneW+safezoneX+0.2475; - y=0.265*safezoneH+safezoneY+0.55; + w="0.065"; + x="0.550*safezoneW+safezoneX+0.2475"; + y="0.265*safezoneH+safezoneY+0.55"; colorBackground[]={0.15,0.21,0.23,0.3}; text="0"; }; class TEXT_TARGET_SPEED_ASSIST_TARGET_RANGE_UNIT: TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE_UNIT { idc=8008; - y=0.265*safezoneH+safezoneY+0.4; + y="0.265*safezoneH+safezoneY+0.4"; text="Meters"; }; class TEXT_TARGET_SPEED_ASSIST_NUM_TICKS_UNIT: TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE_UNIT { @@ -954,7 +954,7 @@ class ATragMX_Display { }; class TEXT_TARGET_SPEED_ASSIST_TIMER_START: TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE_UNIT { idc=8010; - y=0.265*safezoneH+safezoneY+0.5; + y="0.265*safezoneH+safezoneY+0.5"; text="Start"; action=QUOTE(call FUNC(target_speed_assist_timer)); }; @@ -979,31 +979,31 @@ class ATragMX_Display { class TEXT_TARGET_SPEED_ASSIST_TIMER_STOP_BACKGROUND: ATragMX_RscButton { idc=9000; - w=0.285; - h=0.49; - x=0.550*safezoneW+safezoneX+0.11; - y=0.265*safezoneH+safezoneY+0.2; + w="0.285"; + h="0.49"; + x="0.550*safezoneW+safezoneX+0.11"; + y="0.265*safezoneH+safezoneY+0.2"; colorBackground[]={0,0,0,0}; colorBackgroundActive[]={0,0,0,0}; action=QUOTE(GVAR(speedAssistTimer)=false); }; class TEXT_TARGET_SPEED_ASSIST_TIME_OUTPUT: ATragMX_RscText { idc=9001; - x=0.550*safezoneW+safezoneX+0.22; - y=0.265*safezoneH+safezoneY+0.51; - w=0.08; - h=0.09; + x="0.550*safezoneW+safezoneX+0.22"; + y="0.265*safezoneH+safezoneY+0.51"; + w="0.08"; + h="0.09"; style=ST_CENTER; - sizeEx=0.05; + sizeEx="0.05"; text="0.0"; }; class TEXT_TARGET_SPEED_ASSIST_TIMER_STOP: ATragMX_RscButton { idc=9002; style=ST_CENTER; - w=0.07; - h=0.04; - x=0.550*safezoneW+safezoneX+0.225; - y=0.265*safezoneH+safezoneY+0.60; + w="0.07"; + h="0.04"; + x="0.550*safezoneW+safezoneX+0.225"; + y="0.265*safezoneH+safezoneY+0.60"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="Stop"; @@ -1012,17 +1012,17 @@ class ATragMX_Display { class TEXT_RANGE_CARD_SETUP_START_RANGE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { idc=10000; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="Start Range"; }; class TEXT_RANGE_CARD_SETUP_END_RANGE: TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE { idc=10001; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="End Range"; }; class TEXT_RANGE_CARD_SETUP_INCREMENT: TEXT_TARGET_RANGE_ASSIST_ANGLE { idc=10002; - x=0.550*safezoneW+safezoneX+0.12; + x="0.550*safezoneW+safezoneX+0.12"; text="Increment"; }; class TEXT_RANGE_CARD_SETUP_START_RANGE_INPUT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT { @@ -1055,20 +1055,20 @@ class ATragMX_Display { class TEXT_ADD_NEW_GUN_CAPTION: ATragMX_RscText { idc=11000; style=ST_LEFT; - w=0.25; - h=0.04; - x=0.550*safezoneW+safezoneX+0.12; - y=0.265*safezoneH+safezoneY+0.24; - sizeEx=0.025; + w="0.25"; + h="0.04"; + x="0.550*safezoneW+safezoneX+0.12"; + y="0.265*safezoneH+safezoneY+0.24"; + sizeEx="0.025"; text="New Gun Name"; }; class TEXT_ADD_NEW_GUN_GUN_NAME_INPUT: ATragMX_RscEdit { idc=11001; style=ST_LEFT; - w=0.225; - h=0.04; - x=0.550*safezoneW+safezoneX+0.12; - y=0.265*safezoneH+safezoneY+0.28; + w="0.225"; + h="0.04"; + x="0.550*safezoneW+safezoneX+0.12"; + y="0.265*safezoneH+safezoneY+0.28"; text=""; onKeyDown=QUOTE(call FUNC(trim_gun_name)); onKeyUp=QUOTE(call FUNC(trim_gun_name)); @@ -1076,10 +1076,10 @@ class ATragMX_Display { class TEXT_ADD_NEW_GUN_OK: ATragMX_RscButton { idc=11002; style=ST_CENTER; - w=0.1; - h=0.04; - x=0.550*safezoneW+safezoneX+0.12; - y=0.265*safezoneH+safezoneY+0.33; + w="0.1"; + h="0.04"; + x="0.550*safezoneW+safezoneX+0.12"; + y="0.265*safezoneH+safezoneY+0.33"; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="OK"; @@ -1087,82 +1087,82 @@ class ATragMX_Display { }; class TEXT_ADD_NEW_GUN_CANCEL: TEXT_ADD_NEW_GUN_OK { idc=11003; - x=0.550*safezoneW+safezoneX+0.245; + x="0.550*safezoneW+safezoneX+0.245"; text="Cancel"; action=QUOTE(false call FUNC(show_add_new_gun); true call FUNC(show_gun_list)); }; class TEXT_GUN_AMMO_DATA_BORE_HEIGHT: TEXT_BORE_HEIGHT { idc=12000; - w=0.22; - y=0.265*safezoneH+safezoneY+0.28; + w="0.22"; + y="0.265*safezoneH+safezoneY+0.28"; text="Bore (cm)"; }; class TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT: ATragMX_RscEdit { idc=120000; - w=0.06; - x=0.550*safezoneW+safezoneX+0.335; - y=0.265*safezoneH+safezoneY+0.28; + w="0.06"; + x="0.550*safezoneW+safezoneX+0.335"; + y="0.265*safezoneH+safezoneY+0.28"; }; class TEXT_GUN_AMMO_DATA_BULLET_MASS: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=12001; - y=0.265*safezoneH+safezoneY+0.320; + y="0.265*safezoneH+safezoneY+0.320"; text="Bullet Weight (grams)"; }; class TEXT_GUN_AMMO_DATA_BULLET_MASS_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=120010; - y=0.265*safezoneH+safezoneY+0.320; + y="0.265*safezoneH+safezoneY+0.320"; }; class TEXT_GUN_AMMO_DATA_BULLET_DIAMETER: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=12002; - y=0.265*safezoneH+safezoneY+0.360; + y="0.265*safezoneH+safezoneY+0.360"; text="Bullet Diam (cm)"; }; class TEXT_GUN_AMMO_DATA_BULLET_DIAMETER_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=120020; - y=0.265*safezoneH+safezoneY+0.360; + y="0.265*safezoneH+safezoneY+0.360"; }; class TEXT_GUN_AMMO_DATA_AIR_FRICTION: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=12003; - y=0.265*safezoneH+safezoneY+0.400; + y="0.265*safezoneH+safezoneY+0.400"; text="C1 Coefficient"; }; class TEXT_GUN_AMMO_DATA_AIR_FRICTION_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=120030; - y=0.265*safezoneH+safezoneY+0.400; + y="0.265*safezoneH+safezoneY+0.400"; }; class TEXT_GUN_AMMO_DATA_RIFLE_TWIST: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=12004; - y=0.265*safezoneH+safezoneY+0.440; + y="0.265*safezoneH+safezoneY+0.440"; text="Rifle Twist (cm/trn)"; }; class TEXT_GUN_AMMO_DATA_RIFLE_TWIST_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=120040; - y=0.265*safezoneH+safezoneY+0.440; + y="0.265*safezoneH+safezoneY+0.440"; }; class TEXT_GUN_AMMO_DATA_MUZZLE_VELOCITY: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=12005; - y=0.265*safezoneH+safezoneY+0.480; + y="0.265*safezoneH+safezoneY+0.480"; text="Muzzle Velocity (m/s)"; }; class TEXT_GUN_AMMO_DATA_MUZZLE_VELOCITY_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=120050; - y=0.265*safezoneH+safezoneY+0.480; + y="0.265*safezoneH+safezoneY+0.480"; }; class TEXT_GUN_AMMO_DATA_ZERO_RANGE: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=12006; - y=0.265*safezoneH+safezoneY+0.520; + y="0.265*safezoneH+safezoneY+0.520"; text="Zero Range (meters)"; }; class TEXT_GUN_AMMO_DATA_ZERO_RANGE_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=120060; - y=0.265*safezoneH+safezoneY+0.520; + y="0.265*safezoneH+safezoneY+0.520"; }; class TEXT_GUN_AMMO_DATA_ZERO_RANGE_METER_INDICATOR: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=120061; - w=0.05; - x=0.550*safezoneW+safezoneX+0.315; - y=0.265*safezoneH+safezoneY+0.520; + w="0.05"; + x="0.550*safezoneW+safezoneX+0.315"; + y="0.265*safezoneH+safezoneY+0.520"; text=""; }; class TEXT_GUN_AMMO_DATA_DONE: TEXT_TARGET_SPEED_ASSIST_DONE { @@ -1182,63 +1182,63 @@ class ATragMX_Display { class TEXT_ATMO_ENV_DATA_DEFAULT: TEXT_LEAD { idc=13000; - w=0.08; - x=0.550*safezoneW+safezoneX+0.15; - y=0.265*safezoneH+safezoneY+0.320; + w="0.08"; + x="0.550*safezoneW+safezoneX+0.15"; + y="0.265*safezoneH+safezoneY+0.320"; text="Default"; action=QUOTE(call FUNC(restore_atmo_default)); }; class TEXT_ATMO_ENV_DATA_AT: TEXT_TARGET_A { idc=13001; - w=0.04; - x=0.550*safezoneW+safezoneX+0.24; - y=0.265*safezoneH+safezoneY+0.320; + w="0.04"; + x="0.550*safezoneW+safezoneX+0.24"; + y="0.265*safezoneH+safezoneY+0.320"; text="AT"; action=QUOTE(GVAR(atmosphereModeTBH) = false; call FUNC(update_atmo_selection)); }; class TEXT_ATMO_ENV_DATA_TBH: TEXT_ATMO_ENV_DATA_AT { idc=13002; - x=0.550*safezoneW+safezoneX+0.28; + x="0.550*safezoneW+safezoneX+0.28"; text="TBH"; action=QUOTE(GVAR(atmosphereModeTBH) = true; call FUNC(update_atmo_selection)); }; class TEXT_ATMO_ENV_DATA_ALTITUDE: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=13003; - x=0.550*safezoneW+safezoneX+0.115; - y=0.265*safezoneH+safezoneY+0.400; + x="0.550*safezoneW+safezoneX+0.115"; + y="0.265*safezoneH+safezoneY+0.400"; text="Altitude (ft)"; }; class TEXT_ATMO_ENV_DATA_ALTITUDE_INPUT: TEXT_GUN_AMMO_DATA_BORE_HEIGHT_INPUT { idc=130030; - x=0.550*safezoneW+safezoneX+0.330; - y=0.265*safezoneH+safezoneY+0.400; + x="0.550*safezoneW+safezoneX+0.330"; + y="0.265*safezoneH+safezoneY+0.400"; }; class TEXT_ATMO_ENV_DATA_TEMPERATURE: TEXT_ATMO_ENV_DATA_ALTITUDE { idc=13004; - y=0.265*safezoneH+safezoneY+0.440; + y="0.265*safezoneH+safezoneY+0.440"; text="temperature (F)"; }; class TEXT_ATMO_ENV_DATA_TEMPERATURE_INPUT: TEXT_ATMO_ENV_DATA_ALTITUDE_INPUT { idc=130040; - y=0.265*safezoneH+safezoneY+0.440; + y="0.265*safezoneH+safezoneY+0.440"; }; class TEXT_ATMO_ENV_DATA_BAROMETRIC_PRESSURE: TEXT_ATMO_ENV_DATA_ALTITUDE { idc=13005; - y=0.265*safezoneH+safezoneY+0.480; + y="0.265*safezoneH+safezoneY+0.480"; text="Barom Pres (in.merc.)"; }; class TEXT_ATMO_ENV_DATA_BAROMETRIC_PRESSURE_INPUT: TEXT_ATMO_ENV_DATA_ALTITUDE_INPUT { idc=130050; - y=0.265*safezoneH+safezoneY+0.480; + y="0.265*safezoneH+safezoneY+0.480"; }; class TEXT_ATMO_ENV_DATA_RELATIVE_HUMIDITY: TEXT_ATMO_ENV_DATA_ALTITUDE { idc=13006; - y=0.265*safezoneH+safezoneY+0.520; + y="0.265*safezoneH+safezoneY+0.520"; text="Relative Humidity (%)"; }; class TEXT_ATMO_ENV_DATA_RELATIVE_HUMIDITY_INPUT: TEXT_ATMO_ENV_DATA_ALTITUDE_INPUT { idc=130060; - y=0.265*safezoneH+safezoneY+0.520; + y="0.265*safezoneH+safezoneY+0.520"; }; class TEXT_ATMO_ENV_DATA_DONE: TEXT_TARGET_SPEED_ASSIST_DONE { idc=13007; @@ -1257,144 +1257,144 @@ class ATragMX_Display { class TEXT_ATMO_ENV_DATA_CALC_METHOD: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=13011; style=64; - w=0.14; - h=0.07; - x=0.550*safezoneW+safezoneX+0.235; - y=0.265*safezoneH+safezoneY+0.29; + w="0.14"; + h="0.07"; + x="0.550*safezoneW+safezoneX+0.235"; + y="0.265*safezoneH+safezoneY+0.29"; text="Calc Method"; }; class TEXT_TARGET_DATA_LATITUDE: TEXT_BORE_HEIGHT { idc=14000; - w=0.22; - y=0.265*safezoneH+safezoneY+0.28; + w="0.22"; + y="0.265*safezoneH+safezoneY+0.28"; text="Latitude"; }; class TEXT_TARGET_DATA_LATITUDE_INPUT: ATragMX_RscEdit { idc=140000; - w=0.06; - x=0.550*safezoneW+safezoneX+0.335; - y=0.265*safezoneH+safezoneY+0.28; + w="0.06"; + x="0.550*safezoneW+safezoneX+0.335"; + y="0.265*safezoneH+safezoneY+0.28"; }; class TEXT_TARGET_DATA_DIR_OF_FIRE: TEXT_TARGET_DATA_LATITUDE { idc=14001; - y=0.265*safezoneH+safezoneY+0.320; + y="0.265*safezoneH+safezoneY+0.320"; text="Dir of Fire (deg from N)"; }; class TEXT_TARGET_DATA_DIR_OF_FIRE_INPUT: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140010; - y=0.265*safezoneH+safezoneY+0.320; + y="0.265*safezoneH+safezoneY+0.320"; }; class TEXT_TARGET_DATA_WIND_SPEED: TEXT_TARGET_DATA_LATITUDE { idc=14002; - w=1.2; - y=0.265*safezoneH+safezoneY+0.360; + w="1.2"; + y="0.265*safezoneH+safezoneY+0.360"; text="Wind Speed (m/s)"; }; class TEXT_TARGET_DATA_WIND_SPEED_1: TEXT_TARGET_DATA_LATITUDE { idc=141020; colorText[]={0,0,0,0.6}; - w=0.05; - h=0.03; - sizeEx=0.025; - x=0.550*safezoneW+safezoneX+0.270; - y=0.265*safezoneH+safezoneY+0.357; + w="0.05"; + h="0.03"; + sizeEx="0.025"; + x="0.550*safezoneW+safezoneX+0.270"; + y="0.265*safezoneH+safezoneY+0.357"; text="1"; }; class TEXT_TARGET_DATA_WIND_SPEED_INPUT_1: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140020; - w=0.045; - x=0.550*safezoneW+safezoneX+0.290; - y=0.265*safezoneH+safezoneY+0.360; + w="0.045"; + x="0.550*safezoneW+safezoneX+0.290"; + y="0.265*safezoneH+safezoneY+0.360"; }; class TEXT_TARGET_DATA_WIND_SPEED_2: TEXT_TARGET_DATA_WIND_SPEED_1 { idc=141021; - x=0.550*safezoneW+safezoneX+0.330; + x="0.550*safezoneW+safezoneX+0.330"; text="2"; }; class TEXT_TARGET_DATA_WIND_SPEED_INPUT_2: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140021; - w=0.045; - x=0.550*safezoneW+safezoneX+0.350; - y=0.265*safezoneH+safezoneY+0.360; + w="0.045"; + x="0.550*safezoneW+safezoneX+0.350"; + y="0.265*safezoneH+safezoneY+0.360"; }; class TEXT_TARGET_DATA_WIND_DIRECTION: TEXT_TARGET_DATA_LATITUDE { idc=14003; - y=0.265*safezoneH+safezoneY+0.400; + y="0.265*safezoneH+safezoneY+0.400"; text="Wind Direction (clock)"; }; class TEXT_TARGET_DATA_WIND_DIRECTION_INPUT: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140030; - y=0.265*safezoneH+safezoneY+0.400; + y="0.265*safezoneH+safezoneY+0.400"; }; class TEXT_TARGET_DATA_INCLINATION_ANGLE: TEXT_TARGET_DATA_LATITUDE { idc=14004; - w=1.2; - y=0.265*safezoneH+safezoneY+0.440; + w="1.2"; + y="0.265*safezoneH+safezoneY+0.440"; text="Inclination Angle"; }; class TEXT_TARGET_DATA_INCLINATION_ANGLE_COSINE: TEXT_TARGET_DATA_LATITUDE { idc=141041; colorText[]={0,0,0,0.6}; - w=0.05; - h=0.03; - sizeEx=0.025; - x=0.550*safezoneW+safezoneX+0.270; - y=0.265*safezoneH+safezoneY+0.437; + w="0.05"; + h="0.03"; + sizeEx="0.025"; + x="0.550*safezoneW+safezoneX+0.270"; + y="0.265*safezoneH+safezoneY+0.437"; text="c"; }; class TEXT_TARGET_DATA_INCLINATION_ANGLE_INPUT_COSINE: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140041; - w=0.045; - x=0.550*safezoneW+safezoneX+0.290; - y=0.265*safezoneH+safezoneY+0.440; + w="0.045"; + x="0.550*safezoneW+safezoneX+0.290"; + y="0.265*safezoneH+safezoneY+0.440"; onKeyUp=QUOTE(if (_this select 1 == 28) then {0 call FUNC(update_inclination_angle)}); }; class TEXT_TARGET_DATA_INCLINATION_ANGLE_DEGREE: TEXT_TARGET_DATA_INCLINATION_ANGLE_COSINE { idc=141040; - x=0.550*safezoneW+safezoneX+0.330; + x="0.550*safezoneW+safezoneX+0.330"; text="d"; }; class TEXT_TARGET_DATA_INCLINATION_ANGLE_INPUT_DEGREE: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140040; - w=0.045; - x=0.550*safezoneW+safezoneX+0.350; - y=0.265*safezoneH+safezoneY+0.440; + w="0.045"; + x="0.550*safezoneW+safezoneX+0.350"; + y="0.265*safezoneH+safezoneY+0.440"; onKeyUp=QUOTE(if (_this select 1 == 28) then {1 call FUNC(update_inclination_angle)}); }; class TEXT_TARGET_DATA_TARGET_SPEED: TEXT_TARGET_DATA_LATITUDE { idc=14005; - y=0.265*safezoneH+safezoneY+0.480; + y="0.265*safezoneH+safezoneY+0.480"; text="Target Speed (m/s)"; }; class TEXT_TARGET_DATA_TARGET_SPEED_INPUT: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140050; - y=0.265*safezoneH+safezoneY+0.480; + y="0.265*safezoneH+safezoneY+0.480"; }; class TEXT_TARGET_DATA_TARGET_SPEED_DIRECTION: ATragMX_RscButton { idc=140051; colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; - w=0.0231; - x=0.550*safezoneW+safezoneX+0.305; - y=0.265*safezoneH+safezoneY+0.480; + w="0.0231"; + x="0.550*safezoneW+safezoneX+0.305"; + y="0.265*safezoneH+safezoneY+0.480"; text=">"; action=QUOTE(call FUNC(cycle_target_speed_direction)); }; class TEXT_TARGET_DATA_TARGET_RANGE: TEXT_TARGET_DATA_LATITUDE { idc=14006; - y=0.265*safezoneH+safezoneY+0.520; + y="0.265*safezoneH+safezoneY+0.520"; text="Target Range (meters)"; }; class TEXT_TARGET_DATA_TARGET_RANGE_INPUT: TEXT_TARGET_DATA_LATITUDE_INPUT { idc=140060; - y=0.265*safezoneH+safezoneY+0.520; + y="0.265*safezoneH+safezoneY+0.520"; }; class TEXT_TARGET_DATA_TARGET_RANGE_METER_INDICATOR: TEXT_TARGET_DATA_LATITUDE { idc=140061; - w=0.05; - x=0.550*safezoneW+safezoneX+0.315; - y=0.265*safezoneH+safezoneY+0.520; + w="0.05"; + x="0.550*safezoneW+safezoneX+0.315"; + y="0.265*safezoneH+safezoneY+0.520"; text=""; }; class TEXT_TARGET_DATA_DONE: TEXT_TARGET_SPEED_ASSIST_DONE { @@ -1415,176 +1415,176 @@ class ATragMX_Display { class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=15000; style=64; - w=0.25; - h=0.07; - x=0.550*safezoneW+safezoneX+0.13; - y=0.265*safezoneH+safezoneY+0.32; + w="0.25"; + h="0.07"; + x="0.550*safezoneW+safezoneX+0.13"; + y="0.265*safezoneH+safezoneY+0.32"; text="Show result in"; }; class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_1: TEXT_TARGET_A { idc=15001; - w=0.04; - x=0.550*safezoneW+safezoneX+0.14; - y=0.265*safezoneH+safezoneY+0.35; + w="0.04"; + x="0.550*safezoneW+safezoneX+0.14"; + y="0.265*safezoneH+safezoneY+0.35"; text="1"; action=QUOTE(GVAR(currentScopeClickNumberTemp) = 1; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_2: TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_1 { idc=15002; - x=0.550*safezoneW+safezoneX+0.18; + x="0.550*safezoneW+safezoneX+0.18"; text="2"; action=QUOTE(GVAR(currentScopeClickNumberTemp) = 2; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_3: TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_1 { idc=15003; - x=0.550*safezoneW+safezoneX+0.22; + x="0.550*safezoneW+safezoneX+0.22"; text="3"; action=QUOTE(GVAR(currentScopeClickNumberTemp) = 3; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_4: TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_1 { idc=15004; - x=0.550*safezoneW+safezoneX+0.26; + x="0.550*safezoneW+safezoneX+0.26"; text="4"; action=QUOTE(GVAR(currentScopeClickNumberTemp) = 4; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_8: TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_1 { idc=15005; - x=0.550*safezoneW+safezoneX+0.30; + x="0.550*safezoneW+safezoneX+0.30"; text="8"; action=QUOTE(GVAR(currentScopeClickNumberTemp) = 8; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_10: TEXT_SOLUTION_SETUP_SHOW_RESULT_IN_1 { idc=15006; - x=0.550*safezoneW+safezoneX+0.34; + x="0.550*safezoneW+safezoneX+0.34"; text="10"; action=QUOTE(GVAR(currentScopeClickNumberTemp) = 10; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_CLICKS_PER: TEXT_GUN_AMMO_DATA_BORE_HEIGHT { idc=15007; style=64; - w=0.25; - h=0.07; - x=0.550*safezoneW+safezoneX+0.13; - y=0.265*safezoneH+safezoneY+0.42; + w="0.25"; + h="0.07"; + x="0.550*safezoneW+safezoneX+0.13"; + y="0.265*safezoneH+safezoneY+0.42"; text="Clicks per"; }; class TEXT_SOLUTION_SETUP_CLICKS_PER_TMOA: TEXT_TARGET_A { idc=15008; - w=0.05; - x=0.550*safezoneW+safezoneX+0.15; - y=0.265*safezoneH+safezoneY+0.45; + w="0.05"; + x="0.550*safezoneW+safezoneX+0.15"; + y="0.265*safezoneH+safezoneY+0.45"; text="TMOA"; action=QUOTE(GVAR(currentScopeClickUnitTemp) = 0; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_CLICKS_PER_SMOA: TEXT_SOLUTION_SETUP_CLICKS_PER_TMOA { idc=15009; - x=0.550*safezoneW+safezoneX+0.23; + x="0.550*safezoneW+safezoneX+0.23"; text="SMOA"; action=QUOTE(GVAR(currentScopeClickUnitTemp) = 1; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_CLICKS_PER_MILS: TEXT_SOLUTION_SETUP_CLICKS_PER_TMOA { idc=15010; - x=0.550*safezoneW+safezoneX+0.31; + x="0.550*safezoneW+safezoneX+0.31"; text="MILS"; action=QUOTE(GVAR(currentScopeClickUnitTemp) = 2; call FUNC(update_solution_setup)); }; class TEXT_SOLUTION_SETUP_DONE: TEXT_TARGET_SPEED_ASSIST_DONE { idc=15011; - x=0.550*safezoneW+safezoneX+0.18; - y=0.265*safezoneH+safezoneY+0.55; + x="0.550*safezoneW+safezoneX+0.18"; + y="0.265*safezoneH+safezoneY+0.55"; action=QUOTE(1 call FUNC(toggle_solution_setup)); }; class TEXT_SOLUTION_SETUP_CANCEL: TEXT_TARGET_SPEED_ASSIST_CANCEL { idc=15012; - x=0.550*safezoneW+safezoneX+0.26; - y=0.265*safezoneH+safezoneY+0.55; + x="0.550*safezoneW+safezoneX+0.26"; + y="0.265*safezoneH+safezoneY+0.55"; action=QUOTE(0 call FUNC(toggle_solution_setup)); }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE: TEXT_BORE_HEIGHT { idc=16000; - w=0.22; - y=0.265*safezoneH+safezoneY+0.25; - sizeEx=0.022; + w="0.22"; + y="0.265*safezoneH+safezoneY+0.25"; + sizeEx="0.022"; text="Temperature"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE { idc=16001; - x=0.550*safezoneW+safezoneX+0.215; - sizeEx=0.022; + x="0.550*safezoneW+safezoneX+0.215"; + sizeEx="0.022"; text="Muzzle velocity"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1: ATragMX_RscEdit { idc=160021; - w=0.082; - h=0.035; - x=0.550*safezoneW+safezoneX+0.128; - y=0.265*safezoneH+safezoneY+0.29; + w="0.082"; + h="0.035"; + x="0.550*safezoneW+safezoneX+0.128"; + y="0.265*safezoneH+safezoneY+0.29"; text="0"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_2: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160022; - y=0.265*safezoneH+safezoneY+0.325; + y="0.265*safezoneH+safezoneY+0.325"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_3: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160023; - y=0.265*safezoneH+safezoneY+0.360; + y="0.265*safezoneH+safezoneY+0.360"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_4: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160024; - y=0.265*safezoneH+safezoneY+0.395; + y="0.265*safezoneH+safezoneY+0.395"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_5: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160025; - y=0.265*safezoneH+safezoneY+0.430; + y="0.265*safezoneH+safezoneY+0.430"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_6: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160026; - y=0.265*safezoneH+safezoneY+0.465; + y="0.265*safezoneH+safezoneY+0.465"; }; class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_7: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160027; - y=0.265*safezoneH+safezoneY+0.500; + y="0.265*safezoneH+safezoneY+0.500"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_1: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { idc=160031; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_2: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_2 { idc=160032; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_3: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_3 { idc=160033; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_4: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_4 { idc=160034; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_5: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_5 { idc=160035; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_6: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_6 { idc=160036; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_7: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_7 { idc=160037; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_MUZZLE_VELOCITY_DATA_CLEAR: TEXT_TARGET_DATA_NEXT { idc=16004; style=ST_CENTER; - h=0.035; - y=0.265*safezoneH+safezoneY+0.3625; + h="0.035"; + y="0.265*safezoneH+safezoneY+0.3625"; text="Clear"; action=QUOTE(call FUNC(clear_muzzle_velocity_data)); }; class TEXT_MUZZLE_VELOCITY_DATA_QUESTIONMARK: TEXT_MUZZLE_VELOCITY_DATA_CLEAR { idc=16005; - y=0.265*safezoneH+safezoneY+0.430; + y="0.265*safezoneH+safezoneY+0.430"; text="?"; action=""; }; @@ -1605,91 +1605,91 @@ class ATragMX_Display { class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE: TEXT_BORE_HEIGHT { idc=17000; - w=0.22; - x=0.550*safezoneW+safezoneX+0.15; - y=0.265*safezoneH+safezoneY+0.25; - sizeEx=0.022; + w="0.22"; + x="0.550*safezoneW+safezoneX+0.15"; + y="0.265*safezoneH+safezoneY+0.25"; + sizeEx="0.022"; text="Meters"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE { idc=17001; - x=0.550*safezoneW+safezoneX+0.235; - sizeEx=0.022; + x="0.550*safezoneW+safezoneX+0.235"; + sizeEx="0.022"; text="BC-Coef"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1: ATragMX_RscEdit { idc=170021; - w=0.082; - h=0.035; - x=0.550*safezoneW+safezoneX+0.128; - y=0.265*safezoneH+safezoneY+0.29; + w="0.082"; + h="0.035"; + x="0.550*safezoneW+safezoneX+0.128"; + y="0.265*safezoneH+safezoneY+0.29"; text="0"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_2: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170022; - y=0.265*safezoneH+safezoneY+0.325; + y="0.265*safezoneH+safezoneY+0.325"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_3: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170023; - y=0.265*safezoneH+safezoneY+0.360; + y="0.265*safezoneH+safezoneY+0.360"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_4: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170024; - y=0.265*safezoneH+safezoneY+0.395; + y="0.265*safezoneH+safezoneY+0.395"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_5: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170025; - y=0.265*safezoneH+safezoneY+0.430; + y="0.265*safezoneH+safezoneY+0.430"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_6: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170026; - y=0.265*safezoneH+safezoneY+0.465; + y="0.265*safezoneH+safezoneY+0.465"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_7: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170027; - y=0.265*safezoneH+safezoneY+0.500; + y="0.265*safezoneH+safezoneY+0.500"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_1: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { idc=170031; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_2: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_2 { idc=170032; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_3: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_3 { idc=170033; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_4: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_4 { idc=170034; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_5: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_5 { idc=170035; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_6: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_6 { idc=170036; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_7: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_7 { idc=170037; - x=0.550*safezoneW+safezoneX+0.225; + x="0.550*safezoneW+safezoneX+0.225"; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_QUESTIONMARK: TEXT_TARGET_DATA_NEXT { idc=17004; style=ST_CENTER; - w=0.04; - h=0.035; - y=0.265*safezoneH+safezoneY+0.35; + w="0.04"; + h="0.035"; + y="0.265*safezoneH+safezoneY+0.35"; text="?"; action=""; }; class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_CLEAR: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_QUESTIONMARK { idc=17005; - w=0.07; - y=0.265*safezoneH+safezoneY+0.4175; + w="0.07"; + y="0.265*safezoneH+safezoneY+0.4175"; text="Clear"; action=QUOTE(call FUNC(clear_c1_ballistic_coefficient_data)); }; @@ -1711,130 +1711,130 @@ class ATragMX_Display { class TEXT_TRUING_DROP_ZERO_RANGE: ATragMX_RscText { idc=18000; style=ST_LEFT; - x=0.550*safezoneW+safezoneX+0.115; - y=0.265*safezoneH+safezoneY+0.220; - w=0.135; - h=0.03; - sizeEx=0.025; + x="0.550*safezoneW+safezoneX+0.115"; + y="0.265*safezoneH+safezoneY+0.220"; + w="0.135"; + h="0.03"; + sizeEx="0.025"; text="ZR=100meters"; }; class TEXT_TRUING_DROP_DROP_UNIT: TEXT_TRUING_DROP_ZERO_RANGE { idc=18001; style=ST_LEFT; - x=0.550*safezoneW+safezoneX+0.25; + x="0.550*safezoneW+safezoneX+0.25"; text="Drop=mil"; }; class TEXT_TRUING_DROP_TARGET_RANGE: TEXT_TRUING_DROP_ZERO_RANGE { idc=18002; - y=0.265*safezoneH+safezoneY+0.35; - sizeEx=0.027; + y="0.265*safezoneH+safezoneY+0.35"; + sizeEx="0.027"; text="Target Range"; }; class TEXT_TRUING_DROP_DROP: TEXT_TRUING_DROP_TARGET_RANGE { idc=18003; - w=0.07; - y=0.265*safezoneH+safezoneY+0.40; + w="0.07"; + y="0.265*safezoneH+safezoneY+0.40"; text="Drop"; }; class TEXT_TRUING_DROP_MUZZLE_VELOCITY: TEXT_TRUING_DROP_DROP { idc=18004; - y=0.265*safezoneH+safezoneY+0.50; + y="0.265*safezoneH+safezoneY+0.50"; text="MV"; }; class TEXT_TRUING_DROP_C1_BALLISTIC_COEFFICIENT: TEXT_TRUING_DROP_DROP { idc=18005; - y=0.265*safezoneH+safezoneY+0.55; + y="0.265*safezoneH+safezoneY+0.55"; text="C1"; }; class TEXT_TRUING_DROP_DROP_OUTPUT: ATragMX_RscEdit { idc=18006; - style=ST_WITH_RECT+ST_RIGHT; + style=QUOTE(ST_WITH_RECT+ST_RIGHT); colorBackground[]={0.15,0.21,0.23,0.3}; colorDisabled[]={0,0,0,1}; - w=0.06; - y=0.265*safezoneH+safezoneY+0.40; - x=0.550*safezoneW+safezoneX+0.17; + w="0.06"; + y="0.265*safezoneH+safezoneY+0.40"; + x="0.550*safezoneW+safezoneX+0.17"; text=""; }; class TEXT_TRUING_DROP_MUZZLE_VELOCITY_OUTPUT: TEXT_TRUING_DROP_DROP_OUTPUT { idc=18007; - y=0.265*safezoneH+safezoneY+0.50; + y="0.265*safezoneH+safezoneY+0.50"; text=""; }; class TEXT_TRUING_DROP_C1_BALLISTIC_COEFFICIENT_OUTPUT: TEXT_TRUING_DROP_DROP_OUTPUT { idc=18008; - y=0.265*safezoneH+safezoneY+0.55; + y="0.265*safezoneH+safezoneY+0.55"; text=""; }; class TEXT_TRUING_DROP_SUPER: TEXT_TARGET_A { idc=18009; - w=0.06; - x=0.550*safezoneW+safezoneX+0.25; - y=0.265*safezoneH+safezoneY+0.30; + w="0.06"; + x="0.550*safezoneW+safezoneX+0.25"; + y="0.265*safezoneH+safezoneY+0.30"; text="SUPER"; action=QUOTE(GVAR(truingDropMode) = 0; call FUNC(update_truing_drop_selection)); }; class TEXT_TRUING_DROP_SUB: TEXT_TRUING_DROP_SUPER { idc=18010; - x=0.550*safezoneW+safezoneX+0.32; + x="0.550*safezoneW+safezoneX+0.32"; text="SUB"; action=QUOTE(GVAR(truingDropMode) = 1; call FUNC(update_truing_drop_selection)); }; class TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT: ATragMX_RscEdit { idc=18011; - style=ST_WITH_RECT+ST_RIGHT; + style=QUOTE(ST_WITH_RECT+ST_RIGHT); colorDisabled[]={0,0,0,0.6}; - w=0.06; - x=0.550*safezoneW+safezoneX+0.25; - y=0.265*safezoneH+safezoneY+0.35; + w="0.06"; + x="0.550*safezoneW+safezoneX+0.25"; + y="0.265*safezoneH+safezoneY+0.35"; }; class TEXT_TRUING_DROP_TARGET_RANGE_SUB_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT { idc=18012; - x=0.550*safezoneW+safezoneX+0.32; + x="0.550*safezoneW+safezoneX+0.32"; }; class TEXT_TRUING_DROP_DROP_SUPER_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT { idc=18013; - y=0.265*safezoneH+safezoneY+0.40; + y="0.265*safezoneH+safezoneY+0.40"; }; class TEXT_TRUING_DROP_DROP_SUB_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUB_INPUT { idc=18014; - y=0.265*safezoneH+safezoneY+0.40; + y="0.265*safezoneH+safezoneY+0.40"; }; class TEXT_TRUING_DROP_CALC: TEXT_GUN_LIST { idc=18015; style=ST_CENTER; - w=0.11; - x=0.550*safezoneW+safezoneX+0.26; - y=0.265*safezoneH+safezoneY+0.45; + w="0.11"; + x="0.550*safezoneW+safezoneX+0.26"; + y="0.265*safezoneH+safezoneY+0.45"; text="Calc"; action=QUOTE(true call FUNC(calculate_truing_drop)); }; class TEXT_TRUING_DROP_MV_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT { idc=18016; - y=0.265*safezoneH+safezoneY+0.50; + y="0.265*safezoneH+safezoneY+0.50"; }; class TEXT_TRUING_DROP_C1_BALLISTIC_COEFFICIENT_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUB_INPUT { idc=18017; - y=0.265*safezoneH+safezoneY+0.55; + y="0.265*safezoneH+safezoneY+0.55"; }; class TEXT_TRUING_DROP_ACCEPT: TEXT_GUN_LIST { idc=18018; - w=0.085; - h=0.04; - x=0.550*safezoneW+safezoneX+0.125; - y=0.265*safezoneH+safezoneY+0.60; + w="0.085"; + h="0.04"; + x="0.550*safezoneW+safezoneX+0.125"; + y="0.265*safezoneH+safezoneY+0.60"; text="Accept"; action=QUOTE(1 call FUNC(toggle_truing_drop)); }; class TEXT_TRUING_DROP_CANCEL: TEXT_TRUING_DROP_ACCEPT { idc=18019; - x=0.550*safezoneW+safezoneX+0.210; + x="0.550*safezoneW+safezoneX+0.210"; text="Cancel"; action=QUOTE(0 call FUNC(toggle_truing_drop)); }; class TEXT_TRUING_DROP_RESTORE: TEXT_TRUING_DROP_CANCEL { idc=18020; - x=0.550*safezoneW+safezoneX+0.29525; + x="0.550*safezoneW+safezoneX+0.29525"; text="Restore"; action=QUOTE(true call FUNC(restore_truing_drop)); }; diff --git a/addons/atragmx/XEH_postInit.sqf b/addons/atragmx/XEH_postInit.sqf index 9034016212..01eb14d928 100644 --- a/addons/atragmx/XEH_postInit.sqf +++ b/addons/atragmx/XEH_postInit.sqf @@ -1,8 +1,10 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" GVAR(active) = false; GVAR(initialised) = false; -[QEGVAR(vector,rangefinderData), {_this call FUNC(sord)}] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(sord)] call CBA_fnc_addEventHandler; diff --git a/addons/atragmx/functions/fnc_add_new_gun.sqf b/addons/atragmx/functions/fnc_add_new_gun.sqf index 94415852f9..7ef1367b53 100644 --- a/addons/atragmx/functions/fnc_add_new_gun.sqf +++ b/addons/atragmx/functions/fnc_add_new_gun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Adds a new (default) gun profile to the profileNamespace diff --git a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf index 1f06d79988..9fe18a258d 100644 --- a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf +++ b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates distance at which the bullet velocity drops below the threshold velocity diff --git a/addons/atragmx/functions/fnc_calculate_range_card.sqf b/addons/atragmx/functions/fnc_calculate_range_card.sqf index 473e49a8a1..23fef6d414 100644 --- a/addons/atragmx/functions/fnc_calculate_range_card.sqf +++ b/addons/atragmx/functions/fnc_calculate_range_card.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the range card output based on the current data set diff --git a/addons/atragmx/functions/fnc_calculate_solution.sqf b/addons/atragmx/functions/fnc_calculate_solution.sqf index 3c854499d9..7efc25ebbf 100644 --- a/addons/atragmx/functions/fnc_calculate_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_solution.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the fireing solution diff --git a/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf index 51f00cdaaf..dc9c62c3fc 100644 --- a/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the target range and updates the output fields diff --git a/addons/atragmx/functions/fnc_calculate_target_solution.sqf b/addons/atragmx/functions/fnc_calculate_target_solution.sqf index 775467f5de..7fd70ca09a 100644 --- a/addons/atragmx/functions/fnc_calculate_target_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_solution.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the fireing solution and updates the result input/output fields diff --git a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf index 1e28a82339..69af9eba16 100644 --- a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the target speed and updates the output fields diff --git a/addons/atragmx/functions/fnc_calculate_truing_drop.sqf b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf index be6ebd1eda..5191848d05 100644 --- a/addons/atragmx/functions/fnc_calculate_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the truing drop and updates the output fields @@ -60,7 +60,7 @@ if (_parseInput) then { _subsonicDrop = _transonicDrop max _subsonicDrop; }; -if ((GVAR(truingDropDropData) select 0) == 0 || {!([_transonicRange, _subsonicRange] isEqualTo GVAR(truingDropRangeData))}) then { +if ((GVAR(truingDropDropData) select 0) == 0 || {[_transonicRange, _subsonicRange] isNotEqualTo GVAR(truingDropRangeData)}) then { if (isNil QGVAR(targetSolutionInput)) then { call FUNC(calculate_target_solution); }; diff --git a/addons/atragmx/functions/fnc_can_show.sqf b/addons/atragmx/functions/fnc_can_show.sqf index 6d3ed1f6ec..ffa538f542 100644 --- a/addons/atragmx/functions/fnc_can_show.sqf +++ b/addons/atragmx/functions/fnc_can_show.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Tests if the ATragMX dialog can be shown @@ -15,4 +15,5 @@ * Public: No */ -(("ACE_ATragMX" in (uniformItems ACE_player)) || ("ACE_ATragMX" in (vestItems ACE_player))) && !(underwater ACE_player); +!underwater ACE_player && +{"ACE_ATragMX" in ([ACE_player] call EFUNC(common,uniqueItems))} diff --git a/addons/atragmx/functions/fnc_change_gun.sqf b/addons/atragmx/functions/fnc_change_gun.sqf index 9b3863420b..2c0f3e33bc 100644 --- a/addons/atragmx/functions/fnc_change_gun.sqf +++ b/addons/atragmx/functions/fnc_change_gun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Selects a new gun profile and updates the gun column and the result input/output fields diff --git a/addons/atragmx/functions/fnc_change_target_slot.sqf b/addons/atragmx/functions/fnc_change_target_slot.sqf index 71118748d9..e2a0479998 100644 --- a/addons/atragmx/functions/fnc_change_target_slot.sqf +++ b/addons/atragmx/functions/fnc_change_target_slot.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Selects a target slot (A, B, C or D) diff --git a/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf index 22aa0ac3f8..477b9760fe 100644 --- a/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Clears the c1 ballistic coefficient data fields diff --git a/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf index 4e686202e1..7c814c7bb4 100644 --- a/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Clears the muzzle velocity data fields diff --git a/addons/atragmx/functions/fnc_clear_user_data.sqf b/addons/atragmx/functions/fnc_clear_user_data.sqf index e166b56880..850b10aece 100644 --- a/addons/atragmx/functions/fnc_clear_user_data.sqf +++ b/addons/atragmx/functions/fnc_clear_user_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Removes all user data from the profileNamespace diff --git a/addons/atragmx/functions/fnc_create_dialog.sqf b/addons/atragmx/functions/fnc_create_dialog.sqf index 2b1975b567..e1655abfb0 100644 --- a/addons/atragmx/functions/fnc_create_dialog.sqf +++ b/addons/atragmx/functions/fnc_create_dialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Creates the ATragMX dialog @@ -28,9 +28,7 @@ if (!GVAR(initialised)) then { TRACE_1("",GVAR(initialised)); }; -if (GVAR(active)) exitWith { false }; -if (underwater ACE_player) exitWith { false }; -if (!("ACE_ATragMX" in (uniformItems ACE_player)) && !("ACE_ATragMX" in (vestItems ACE_player))) exitWith { false }; +if (GVAR(active) || {!(call FUNC(can_show))}) exitWith {false}; createDialog 'ATragMX_Display'; diff --git a/addons/atragmx/functions/fnc_cycle_gun_list.sqf b/addons/atragmx/functions/fnc_cycle_gun_list.sqf index 7d0c6b5ab4..dab0b174e9 100644 --- a/addons/atragmx/functions/fnc_cycle_gun_list.sqf +++ b/addons/atragmx/functions/fnc_cycle_gun_list.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the gun list @@ -10,7 +10,7 @@ * None * * Example: - * call ace_atragmx_fnc_cycle_scope_unit + * call ace_atragmx_fnc_cycle_gun_list * * Public: No */ diff --git a/addons/atragmx/functions/fnc_cycle_image_size_units.sqf b/addons/atragmx/functions/fnc_cycle_image_size_units.sqf index 70b35ec58c..3fc0de9664 100644 --- a/addons/atragmx/functions/fnc_cycle_image_size_units.sqf +++ b/addons/atragmx/functions/fnc_cycle_image_size_units.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the image size units diff --git a/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf b/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf index 65361b9860..26056817a2 100644 --- a/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf +++ b/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the num ticks units diff --git a/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf b/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf index b9432996cb..deed82901a 100644 --- a/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf +++ b/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the range card columns diff --git a/addons/atragmx/functions/fnc_cycle_scope_unit.sqf b/addons/atragmx/functions/fnc_cycle_scope_unit.sqf index 74c5a37dd4..74b3e81daa 100644 --- a/addons/atragmx/functions/fnc_cycle_scope_unit.sqf +++ b/addons/atragmx/functions/fnc_cycle_scope_unit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the scope units diff --git a/addons/atragmx/functions/fnc_cycle_target_size_units.sqf b/addons/atragmx/functions/fnc_cycle_target_size_units.sqf index 36165ddae5..f53932cbfb 100644 --- a/addons/atragmx/functions/fnc_cycle_target_size_units.sqf +++ b/addons/atragmx/functions/fnc_cycle_target_size_units.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the target size units diff --git a/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf b/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf index 42d3232d54..522423ea23 100644 --- a/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf +++ b/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Cycles through the target directions left/right @@ -10,7 +10,7 @@ * None * * Example: - * call ace_atragmx_fnc_cycle_target_direction + * call ace_atragmx_fnc_cycle_target_speed_direction * * Public: No */ diff --git a/addons/atragmx/functions/fnc_delete_gun.sqf b/addons/atragmx/functions/fnc_delete_gun.sqf index b5c209717d..43b2618e49 100644 --- a/addons/atragmx/functions/fnc_delete_gun.sqf +++ b/addons/atragmx/functions/fnc_delete_gun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Deletes the currently selected gun profile from the profileNamespace diff --git a/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf b/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf index bcbd2b87c5..0927e6a73b 100644 --- a/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf +++ b/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Evalutes input from the option menu diff --git a/addons/atragmx/functions/fnc_init.sqf b/addons/atragmx/functions/fnc_init.sqf index 2dcd34d493..5c3cedc88c 100644 --- a/addons/atragmx/functions/fnc_init.sqf +++ b/addons/atragmx/functions/fnc_init.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Inits all global variables with the default values diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 3ffcaf976c..515bc9013e 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Inits the gun list from user profile @@ -15,7 +15,7 @@ * Public: No */ -LOG_2("Trying to load gunlist from profile [Version: %1][Count: %2]", profileNamespace getVariable [ARR_2(QGVAR(profileNamespaceVersion), 'none')], count (profileNamespace getVariable [ARR_2(QGVAR(gunList), [])])); +LOG_2("Trying to load gunlist from profile [Version: %1][Count: %2]",profileNamespace getVariable [ARR_2(QGVAR(profileNamespaceVersion),'none')],count (profileNamespace getVariable [ARR_2(QGVAR(gunList),[])])); private _resetGunList = true; if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == ATRAGMX_PROFILE_NAMESPACE_VERSION && {count (profileNamespace getVariable ["ACE_ATragMX_gunList", []]) > 0}) then { @@ -23,7 +23,7 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == _resetGunList = false; { // Verify each gun has correct param type - if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith { + if !(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false]) exitWith { _resetGunList = true; }; } forEach GVAR(gunList); @@ -32,19 +32,20 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == if (_resetGunList) then { WARNING("Reseting Profile Gunlist"); // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation, Persistent - GVAR(gunList) = [["12.7x108mm" , 812, 100, 0.0958029, -0.00063800, 8.89, 0, 2, 10, 120, 0, 0, 48.28, 12.7, 38.10, 0.630, 1, "ASM" , [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + GVAR(gunList) = [["12.7x108mm" , 820, 100, 0.0946366, -0.00065098, 8.89, 0, 2, 10, 120, 0, 0, 48.28, 12.7, 38.10, 0.630, 1, "ASM" , [[-15,801],[0,808],[10,815],[15,820],[25,834],[30,843],[35,854]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["12.7x108mm APDS" , 1060, 100, 0.0766151, -0.00036000, 8.89, 0, 2, 10, 120, 0, 0, 27.95, 11.08, 38.10, 1.052, 1, "ICAO" , [[-15,1041],[0,1048],[10,1055],[15,1060],[25,1074],[30,1083],[35,1094]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["12.7x99mm AMAX" , 852, 100, 0.0907214, -0.00037397, 8.89, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 38.10, 1.050, 1, "ASM" , [[-15,833],[0,840],[10,847],[15,852],[25,866],[30,875],[35,886]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["12.7x99mm" , 892, 100, 0.0879633, -0.00058679, 8.89, 0, 2, 10, 120, 0, 0, 41.92, 12.7, 38.10, 0.670, 1, "ASM" , [[-15,873],[0,880],[10,887],[15,892],[25,906],[30,915],[35,926]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["12.7x54mm" , 299, 100, 0.3567550, -0.00019568, 6.60, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 24.13, 1.050, 1, "ASM" , [[-15,297],[0,298],[10,299],[15,299],[25,301],[30,302],[35,303]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".50 Beowulf" , 562, 100, 0.1425100, -0.00205896, 6.60, 0, 2, 10, 120, 0, 0, 21.71, 12.7, 50.80, 0.210, 1, "ASM" , [[-15,560],[0,561],[10,562],[15,562],[25,564],[30,565],[35,566]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + [".50 Beowulf" , 549, 100, 0.1468500, -0.00209809, 6.60, 0, 2, 10, 120, 0, 0, 21.64, 12.7, 50.80, 0.210, 1, "ASM" , [[-15,547],[0,548],[10,549],[15,549],[25,551],[30,552],[35,553]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], [".408 CheyTac 305gr", 1059, 100, 0.0686329, -0.00065414, 7.37, 0, 2, 10, 120, 0, 0, 19.76, 10.4, 33.02, 0.569, 1, "ICAO", [[-15,1040],[0,1047],[10,1054],[15,1059],[25,1073],[30,1082],[35,1093]], [[0, 0.605], [1110, 0.569], [1500, 0.560], [1790, 0.551], [1990, 0.547], [2140, 0.545], [2300, 0.544]], true], [".408 CheyTac 419gr", 859, 100, 0.0816039, -0.00046249, 7.37, 0, 2, 10, 120, 0, 0, 27.15, 10.4, 33.02, 0.866, 1, "ICAO", [[-15,840],[0,847],[10,854],[15,859],[25,873],[30,882],[35,893]] , [[0, 0.872], [1440, 0.862], [1630, 0.859], [1870, 0.852], [2090, 0.843], [2230, 0.838], [2420, 0.833]], true], - ["9.3×64mm" , 862, 100, 0.0875873, -0.00110727, 8.13, 0, 2, 10, 120, 0, 0, 14.90, 9.30, 35.56, 0.368, 1, "ASM" , [[-15,843],[0,850],[10,857],[15,862],[25,876],[30,885],[35,896]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["9.3×64mm" , 780, 100, 0.0953568, -0.00080801, 8.13, 0, 2, 10, 120, 0, 0, 17.00, 9.65, 36.00, 0.515, 1, "ICAO", [[-15,761],[0,768],[10,775],[15,780],[25,794],[30,803],[35,814]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], [".338LM 250gr" , 872, 100, 0.0809096, -0.00060841, 7.37, 0, 2, 10, 120, 0, 0, 16.20, 8.58, 25.40, 0.645, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0, 0.656], [1300, 0.64], [1460, 0.636], [1770, 0.625], [1920, 0.621], [2030, 0.619], [2190, 0.618]], true], [".338LM 300gr" , 792, 100, 0.0890193, -0.00055706, 7.37, 0, 2, 10, 120, 0, 0, 19.44, 8.58, 25.40, 0.759, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0, 0.734], [1300, 0.726], [1500, 0.720], [1770, 0.708], [1880, 0.705], [2000, 0.702], [2110, 0.700]], true], @@ -52,7 +53,7 @@ if (_resetGunList) then { [".300WM Mk248 Mod0" , 857, 100, 0.0825862, -0.00072468, 7.37, 0, 2, 10, 120, 0, 0, 12.31, 7.80, 25.40, 0.537, 1, "ICAO", [[-15,838],[0,845],[10,852],[15,857],[25,871],[30,880],[35,891]] , [[0, 0.546], [1210, 0.529], [1470, 0.520], [1570, 0.518], [1730, 0.515], [1880, 0.513], [1970, 0.513]], true], [".300WM Mk248 Mod1" , 839, 100, 0.0841417, -0.00063027, 7.37, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.619, 1, "ICAO", [[-15,820],[0,827],[10,834],[15,839],[25,853],[30,862],[35,873]] , [[0, 0.623], [1150, 0.614], [1330, 0.609], [1620, 0.598], [1770, 0.595], [1970, 0.592], [2030, 0.591]], true], - [".300WM Berger OTM" , 792, 100, 0.0891300, -0.00055262, 7.37, 0, 2, 10, 120, 0, 0, 14.90, 7.80, 25.40, 0.715, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0, 0.721], [1400, 0.708], [1570, 0.703], [1860, 0.692], [1990, 0.689], [2140, 0.686], [2220, 0.685]], true], + [".300WM Berger OTM" , 792, 100, 0.0891300, -0.00054587, 7.37, 0, 2, 10, 120, 0, 0, 14.90, 7.80, 25.40, 0.715, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0, 0.721], [1400, 0.708], [1570, 0.703], [1860, 0.692], [1990, 0.689], [2140, 0.686], [2220, 0.685]], true], ["7.62x54mmR" , 828, 100, 0.0853677, -0.00103739, 7.11, 0, 2, 10, 120, 0, 0, 9.849, 7.92, 24.13, 0.400, 1, "ICAO", [[-15,809],[0,816],[10,823],[15,828],[25,842],[30,851],[35,862]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], @@ -63,20 +64,21 @@ 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.1047820, -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], ["6.5mm Creedmor" , 822, 100, 0.0800956, -0.00062437, 6.35, 0, 2, 10, 120, 0, 0, 9.072, 6.71, 22.86, 0.632, 1, "ICAO", [[-15,803],[0,810],[10,817],[15,822],[25,836],[30,845],[35,856]] , [[0, 0.635], [1150, 0.627], [1350, 0.621], [1630, 0.611], [1760, 0.607], [1860, 0.606], [2020, 0.604]], true], - ["5.8x42mm DBP87" , 942, 100, 0.0916742, -0.00121087, 9.91, 0, 2, 10, 120, 0, 0, 4.150, 5.99, 24.40, 0.313, 1, "ICAO", [[-15,923],[0,930],[10,937],[15,942],[25,956],[30,965],[35,976]] , [[0, 0.323], [760, 0.309], [970, 0.303], [1030, 0.302], [1130, 0.301], [1210, 0.300], [1510, 0.299]], true], + ["5.8x42mm DBP87" , 942, 100, 0.0916742, -0.00121087, 9.91, 0, 2, 10, 120, 0, 0, 4.150, 6.00, 24.40, 0.313, 1, "ICAO", [[-15,923],[0,930],[10,937],[15,942],[25,956],[30,965],[35,976]] , [[0, 0.323], [760, 0.309], [970, 0.303], [1030, 0.302], [1130, 0.301], [1210, 0.300], [1510, 0.299]], true], + ["5.8x42mm DBP88" , 895, 100, 0.0883716, -0.00096786, 8.89, 0, 2, 10, 120, 0, 0, 5.000, 6.00, 20.60, 0.416, 1, "ICAO", [[-15,876],[0,883],[10,890],[15,895],[25,909],[30,918],[35,929]] , [[0, 0.416], [800, 0.416], [900, 0.413], [1000, 0.410], [1100, 0.406], [1200, 0.404], [1300, 0.402]], true], ["5.56x45mm M855" , 862, 100, 0.0825404, -0.00130094, 7.11, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.302, 1, "ASM" , [[-15,843],[0,849],[10,857],[15,862],[25,876],[30,885],[35,898]] , [[0, 0.306], [670, 0.298], [880, 0.291], [1000, 0.289], [1150, 0.288], [1340, 0.288], [1410, 0.288]], true], ["5.56x45mm Mk262" , 812, 100, 0.0872422, -0.00111805, 7.11, 0, 2, 10, 120, 0, 0, 4.990, 5.70, 17.78, 0.361, 1, "ASM" , [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["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.430, 5.60, 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/atragmx/functions/fnc_insert_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_insert_c1_ballistic_coefficient_data.sqf index 69d23b4e43..c4b66d319d 100644 --- a/addons/atragmx/functions/fnc_insert_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_insert_c1_ballistic_coefficient_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Inserts entry in the c1 ballistic coefficient vs. distance interpolation table diff --git a/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf index 0e508e37e1..be646af89b 100644 --- a/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Inserts entry in the muzzle velocity vs. temperature interpolation table diff --git a/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf index 3d0b348874..16881c93b6 100644 --- a/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf +++ b/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Lookup the correct C1 ballistic coefficient in the c1 ballistic coefficient vs. distance interpolation table diff --git a/addons/atragmx/functions/fnc_on_close_dialog.sqf b/addons/atragmx/functions/fnc_on_close_dialog.sqf index d9ebf1cb00..e1809d1eb4 100644 --- a/addons/atragmx/functions/fnc_on_close_dialog.sqf +++ b/addons/atragmx/functions/fnc_on_close_dialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * On close Dialog diff --git a/addons/atragmx/functions/fnc_parse_input.sqf b/addons/atragmx/functions/fnc_parse_input.sqf index d03b8bd186..1c3ea3398a 100644 --- a/addons/atragmx/functions/fnc_parse_input.sqf +++ b/addons/atragmx/functions/fnc_parse_input.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Parses all input fields in the gun-, atmosphere- and target column, the result input fields and the muzzle velocity data input fields diff --git a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf index 3ae566557b..cbbb4603e3 100644 --- a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf +++ b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Reads gun list entries from the config and appends them to the gun list @@ -74,7 +74,7 @@ private _validate_preset = { ERROR(_errorMsg); _valid = false; }; - if (!((_this select 17) in ["ASM", "ICAO"])) then { + if !((_this select 17) in ["ASM", "ICAO"]) then { private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17]; ERROR(_errorMsg); _valid = false; diff --git a/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf index 273d73a3e3..327adce1b3 100644 --- a/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf +++ b/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Recalculates the c1 ballistic coefficient based on the current target range diff --git a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf index c46cd9ab16..f7e4709cc1 100644 --- a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf +++ b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Recalculates the muzzle velocity based on the muzzle velocity vs. temperature interpolation input diff --git a/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf b/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf index 4a847123df..5beea4cd38 100644 --- a/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf +++ b/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Resets the relative click memory and updates the result input/output fields diff --git a/addons/atragmx/functions/fnc_restore_atmo_default.sqf b/addons/atragmx/functions/fnc_restore_atmo_default.sqf index 9b03c337b2..62b6faa8b5 100644 --- a/addons/atragmx/functions/fnc_restore_atmo_default.sqf +++ b/addons/atragmx/functions/fnc_restore_atmo_default.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Restores the atmospheric data defaults diff --git a/addons/atragmx/functions/fnc_restore_truing_drop.sqf b/addons/atragmx/functions/fnc_restore_truing_drop.sqf index 301c94f7a8..ca8f51882a 100644 --- a/addons/atragmx/functions/fnc_restore_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_restore_truing_drop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Restores the truing drop defaults diff --git a/addons/atragmx/functions/fnc_restore_user_data.sqf b/addons/atragmx/functions/fnc_restore_user_data.sqf index beb2c50c4d..c72a154acd 100644 --- a/addons/atragmx/functions/fnc_restore_user_data.sqf +++ b/addons/atragmx/functions/fnc_restore_user_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Reads user data from profileNamespace diff --git a/addons/atragmx/functions/fnc_save_gun.sqf b/addons/atragmx/functions/fnc_save_gun.sqf index 2560dbd42b..0780958041 100644 --- a/addons/atragmx/functions/fnc_save_gun.sqf +++ b/addons/atragmx/functions/fnc_save_gun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Saves the currently select gun profile into the profileNamespace diff --git a/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf index 95ac59b705..0a41e8f3f8 100644 --- a/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shifts all c1 ballistic coefficient entries in the c1 ballistic coefficient vs. distance interpolation table diff --git a/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf index 4d4e4d2b22..ae588c623d 100644 --- a/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shifts all muzzle velocity entries in the muzzle velocity vs. temperature interpolation table diff --git a/addons/atragmx/functions/fnc_show_add_new_gun.sqf b/addons/atragmx/functions/fnc_show_add_new_gun.sqf index a00860490b..11fad2eaa3 100644 --- a/addons/atragmx/functions/fnc_show_add_new_gun.sqf +++ b/addons/atragmx/functions/fnc_show_add_new_gun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides add new gun controls diff --git a/addons/atragmx/functions/fnc_show_atmo_env_data.sqf b/addons/atragmx/functions/fnc_show_atmo_env_data.sqf index b07843e18a..4c9b58402d 100644 --- a/addons/atragmx/functions/fnc_show_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_show_atmo_env_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the atmosphere and environmental data controls diff --git a/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf index 34f598ac6c..f482f1e6e3 100644 --- a/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the c1 ballistic coefficient data controls diff --git a/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf index 108108a14c..854784ddaf 100644 --- a/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the gun ammo data controls diff --git a/addons/atragmx/functions/fnc_show_gun_list.sqf b/addons/atragmx/functions/fnc_show_gun_list.sqf index 714e9a0d12..7c9aacadb9 100644 --- a/addons/atragmx/functions/fnc_show_gun_list.sqf +++ b/addons/atragmx/functions/fnc_show_gun_list.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the gun list controls diff --git a/addons/atragmx/functions/fnc_show_main_page.sqf b/addons/atragmx/functions/fnc_show_main_page.sqf index 7b12af4439..048282f99c 100644 --- a/addons/atragmx/functions/fnc_show_main_page.sqf +++ b/addons/atragmx/functions/fnc_show_main_page.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the main menu controls diff --git a/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf index e12263d36f..b4a195f183 100644 --- a/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the muzzle velocity data controls diff --git a/addons/atragmx/functions/fnc_show_range_card.sqf b/addons/atragmx/functions/fnc_show_range_card.sqf index 02f65164bb..98052ce760 100644 --- a/addons/atragmx/functions/fnc_show_range_card.sqf +++ b/addons/atragmx/functions/fnc_show_range_card.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the range card controls diff --git a/addons/atragmx/functions/fnc_show_range_card_setup.sqf b/addons/atragmx/functions/fnc_show_range_card_setup.sqf index 183e115b1b..15558ceb98 100644 --- a/addons/atragmx/functions/fnc_show_range_card_setup.sqf +++ b/addons/atragmx/functions/fnc_show_range_card_setup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the range card setup controls diff --git a/addons/atragmx/functions/fnc_show_solution_setup.sqf b/addons/atragmx/functions/fnc_show_solution_setup.sqf index 4eafd38a31..e7846be426 100644 --- a/addons/atragmx/functions/fnc_show_solution_setup.sqf +++ b/addons/atragmx/functions/fnc_show_solution_setup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the solution setup controls diff --git a/addons/atragmx/functions/fnc_show_target_data.sqf b/addons/atragmx/functions/fnc_show_target_data.sqf index 6987047cbf..7d8329ba2a 100644 --- a/addons/atragmx/functions/fnc_show_target_data.sqf +++ b/addons/atragmx/functions/fnc_show_target_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target data controls diff --git a/addons/atragmx/functions/fnc_show_target_range_assist.sqf b/addons/atragmx/functions/fnc_show_target_range_assist.sqf index 89453c9134..83516ef5c6 100644 --- a/addons/atragmx/functions/fnc_show_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_show_target_range_assist.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target range assist controls diff --git a/addons/atragmx/functions/fnc_show_target_speed_assist.sqf b/addons/atragmx/functions/fnc_show_target_speed_assist.sqf index 267c3676b6..3efa6ed6d4 100644 --- a/addons/atragmx/functions/fnc_show_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_show_target_speed_assist.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target speed assist controls diff --git a/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf index fca074547f..b0a2b9b0c2 100644 --- a/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target speed assist timer controls diff --git a/addons/atragmx/functions/fnc_show_truing_drop.sqf b/addons/atragmx/functions/fnc_show_truing_drop.sqf index ca69346c49..5e7f60f4d4 100644 --- a/addons/atragmx/functions/fnc_show_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_show_truing_drop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows/Hides the truing drop controls diff --git a/addons/atragmx/functions/fnc_sord.sqf b/addons/atragmx/functions/fnc_sord.sqf index a6c3d2b5b8..f50e1042c3 100644 --- a/addons/atragmx/functions/fnc_sord.sqf +++ b/addons/atragmx/functions/fnc_sord.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Handles incoming data packets from the Vectronix Vector LRF @@ -12,7 +12,7 @@ * None * * Example: - * [1000, 45, 1] call ace_microdagr_fnc_recieveRangefinderData + * [1000, 45, 1] call ace_atragmx_fnc_sord * * Public: No */ diff --git a/addons/atragmx/functions/fnc_store_gun_list.sqf b/addons/atragmx/functions/fnc_store_gun_list.sqf index d5c3d7657d..ff007a8c9f 100644 --- a/addons/atragmx/functions/fnc_store_gun_list.sqf +++ b/addons/atragmx/functions/fnc_store_gun_list.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Saves the persistent gun list entries into profileNamespace @@ -10,7 +10,7 @@ * None * * Example: - * call ace_atragmx_fnc_store_user_data + * call ace_atragmx_fnc_store_gun_list * * Public: No */ diff --git a/addons/atragmx/functions/fnc_store_user_data.sqf b/addons/atragmx/functions/fnc_store_user_data.sqf index 09b710e1d4..d40652c5fb 100644 --- a/addons/atragmx/functions/fnc_store_user_data.sqf +++ b/addons/atragmx/functions/fnc_store_user_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Saves user data into profileNamespace diff --git a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf index 69be94dd8f..5408edee3a 100644 --- a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows and starts the target speed assist timer @@ -26,7 +26,7 @@ if !(ctrlVisible 9000) then { params ["_args"]; _args params ["_startTime"]; - if (!(GVAR(speedAssistTimer))) exitWith { + if !(GVAR(speedAssistTimer)) exitWith { GVAR(speedAssistTimer) = true; ctrlSetText [8006, Str(Round((CBA_missionTime - _startTime) * 10) / 10)]; diff --git a/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf b/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf index 6f2fc11e27..a7ce8ad93c 100644 --- a/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the atmospheric data screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf index 088658b747..a8cd7ce52a 100644 --- a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the c1 ballistic coefficient data screen on/off @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 17000) then { false call FUNC(show_c1_ballistic_coefficient_data); diff --git a/addons/atragmx/functions/fnc_toggle_coriolis.sqf b/addons/atragmx/functions/fnc_toggle_coriolis.sqf index aad845ce35..2e5e9fc06e 100644 --- a/addons/atragmx/functions/fnc_toggle_coriolis.sqf +++ b/addons/atragmx/functions/fnc_toggle_coriolis.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the coriolis and spin drift output on/off diff --git a/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf index 1be813fec6..01b324fc9f 100644 --- a/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the gun ammo data screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_gun_list.sqf b/addons/atragmx/functions/fnc_toggle_gun_list.sqf index 291faf98a4..cdd4a631b9 100644 --- a/addons/atragmx/functions/fnc_toggle_gun_list.sqf +++ b/addons/atragmx/functions/fnc_toggle_gun_list.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the gun list screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf index 64aadc62cb..34326b251d 100644 --- a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the muzzle velocity data screen on/off @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 16000) then { false call FUNC(show_muzzle_velocity_data); diff --git a/addons/atragmx/functions/fnc_toggle_option_menu.sqf b/addons/atragmx/functions/fnc_toggle_option_menu.sqf index c39846f466..5762a5741f 100644 --- a/addons/atragmx/functions/fnc_toggle_option_menu.sqf +++ b/addons/atragmx/functions/fnc_toggle_option_menu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the option menu on/off diff --git a/addons/atragmx/functions/fnc_toggle_range_card.sqf b/addons/atragmx/functions/fnc_toggle_range_card.sqf index f34b60c146..7a025e1904 100644 --- a/addons/atragmx/functions/fnc_toggle_range_card.sqf +++ b/addons/atragmx/functions/fnc_toggle_range_card.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the range card screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf b/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf index fb98cfcb0e..5c499b8b82 100644 --- a/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf +++ b/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the range card setup screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_solution_setup.sqf b/addons/atragmx/functions/fnc_toggle_solution_setup.sqf index 11c3c0f4bc..8d233b204a 100644 --- a/addons/atragmx/functions/fnc_toggle_solution_setup.sqf +++ b/addons/atragmx/functions/fnc_toggle_solution_setup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the solution setup screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_target_data.sqf b/addons/atragmx/functions/fnc_toggle_target_data.sqf index ecfcab2c41..a012a879c1 100644 --- a/addons/atragmx/functions/fnc_toggle_target_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the target data screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf index ac1934ee3e..1e6c485e99 100644 --- a/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the target range assist screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf index 47d14a32d9..009074105e 100644 --- a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the target speed assist screen on/off diff --git a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf index dbacceb52f..2d13619de0 100644 --- a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Toggles the truing drop screen on/off @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 18000) then { false call FUNC(show_truing_drop); diff --git a/addons/atragmx/functions/fnc_trim_gun_name.sqf b/addons/atragmx/functions/fnc_trim_gun_name.sqf index 46f20bede6..77fcbdf1ba 100644 --- a/addons/atragmx/functions/fnc_trim_gun_name.sqf +++ b/addons/atragmx/functions/fnc_trim_gun_name.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Trims the gun name input field diff --git a/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf index 8a6046d1d8..84371ca852 100644 --- a/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf +++ b/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Trues the c1 ballistic coefficient diff --git a/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf index cee3af2536..f8fb9e621c 100644 --- a/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf +++ b/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Trues the muzzle velocity diff --git a/addons/atragmx/functions/fnc_update_atmo_env_data.sqf b/addons/atragmx/functions/fnc_update_atmo_env_data.sqf index 27a1e1510b..340924b5aa 100644 --- a/addons/atragmx/functions/fnc_update_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_update_atmo_env_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the atmospheric data fields diff --git a/addons/atragmx/functions/fnc_update_atmo_selection.sqf b/addons/atragmx/functions/fnc_update_atmo_selection.sqf index caa7c206cc..caafe1eed2 100644 --- a/addons/atragmx/functions/fnc_update_atmo_selection.sqf +++ b/addons/atragmx/functions/fnc_update_atmo_selection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the atmospheric data input method diff --git a/addons/atragmx/functions/fnc_update_atmosphere.sqf b/addons/atragmx/functions/fnc_update_atmosphere.sqf index 438dfe04f2..7d52315892 100644 --- a/addons/atragmx/functions/fnc_update_atmosphere.sqf +++ b/addons/atragmx/functions/fnc_update_atmosphere.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all atmosphere column input fields diff --git a/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf index a7a20d31df..4c0c6d7175 100644 --- a/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the c1 ballistic coefficient data fields diff --git a/addons/atragmx/functions/fnc_update_gun.sqf b/addons/atragmx/functions/fnc_update_gun.sqf index 2df4bbe1ee..5a5dab00fa 100644 --- a/addons/atragmx/functions/fnc_update_gun.sqf +++ b/addons/atragmx/functions/fnc_update_gun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all gun column input fields diff --git a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf index 3a2c1a8106..59bd014973 100644 --- a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the gun ammo data fields diff --git a/addons/atragmx/functions/fnc_update_inclination_angle.sqf b/addons/atragmx/functions/fnc_update_inclination_angle.sqf index f0150c1cfe..532b3d94e8 100644 --- a/addons/atragmx/functions/fnc_update_inclination_angle.sqf +++ b/addons/atragmx/functions/fnc_update_inclination_angle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the inclination angle input fields diff --git a/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf index 55453ce6e9..23193aa903 100644 --- a/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the muzzle velocity data fields diff --git a/addons/atragmx/functions/fnc_update_range_card.sqf b/addons/atragmx/functions/fnc_update_range_card.sqf index 3af37cf3f6..066bd65174 100644 --- a/addons/atragmx/functions/fnc_update_range_card.sqf +++ b/addons/atragmx/functions/fnc_update_range_card.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the range card listbox content diff --git a/addons/atragmx/functions/fnc_update_relative_click_memory.sqf b/addons/atragmx/functions/fnc_update_relative_click_memory.sqf index ae847d6c13..8ef06914ac 100644 --- a/addons/atragmx/functions/fnc_update_relative_click_memory.sqf +++ b/addons/atragmx/functions/fnc_update_relative_click_memory.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the relative click memory diff --git a/addons/atragmx/functions/fnc_update_result.sqf b/addons/atragmx/functions/fnc_update_result.sqf index 21c192549c..cfd8f460a9 100644 --- a/addons/atragmx/functions/fnc_update_result.sqf +++ b/addons/atragmx/functions/fnc_update_result.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the result input and output fields @@ -90,7 +90,7 @@ if (GVAR(showWind2)) then { _elevationAbs = Round(_elevationAbs * 100) / 100; if (_elevationAbs > 0) then { - ctrlSetText [400, format["%1", abs(_elevationAbs)]]; + ctrlSetText [400, str abs _elevationAbs]; } else { if (_elevationAbs < 0) then { ctrlSetText [400, format["%1D", abs(_elevationAbs)]]; @@ -100,7 +100,7 @@ if (_elevationAbs > 0) then { }; _elevationRel = Round(_elevationRel * 100) / 100; if (_elevationRel > 0) then { - ctrlSetText [401, format["%1", abs(_elevationRel)]]; + ctrlSetText [401, str abs _elevationRel]; } else { if (_elevationRel < 0) then { ctrlSetText [401, format["%1D", abs(_elevationRel)]]; @@ -110,7 +110,7 @@ if (_elevationRel > 0) then { }; _elevationCur = Round(_elevationCur * 100) / 100; if (_elevationCur > 0) then { - ctrlSetText [402, format["%1", abs(_elevationCur)]]; + ctrlSetText [402, str abs _elevationCur]; } else { if (_elevationCur < 0) then { ctrlSetText [402, format["%1D", abs(_elevationCur)]]; diff --git a/addons/atragmx/functions/fnc_update_scope_unit.sqf b/addons/atragmx/functions/fnc_update_scope_unit.sqf index 05f7f85b93..d1f0e9cf17 100644 --- a/addons/atragmx/functions/fnc_update_scope_unit.sqf +++ b/addons/atragmx/functions/fnc_update_scope_unit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the scope unit fields diff --git a/addons/atragmx/functions/fnc_update_solution_setup.sqf b/addons/atragmx/functions/fnc_update_solution_setup.sqf index 37ea36c069..0c8353cfcb 100644 --- a/addons/atragmx/functions/fnc_update_solution_setup.sqf +++ b/addons/atragmx/functions/fnc_update_solution_setup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all solution setup input fields diff --git a/addons/atragmx/functions/fnc_update_target.sqf b/addons/atragmx/functions/fnc_update_target.sqf index 72e6e1f208..a87ba9ba54 100644 --- a/addons/atragmx/functions/fnc_update_target.sqf +++ b/addons/atragmx/functions/fnc_update_target.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all target column input fields diff --git a/addons/atragmx/functions/fnc_update_target_data.sqf b/addons/atragmx/functions/fnc_update_target_data.sqf index ce4b5cb924..92b5df50a0 100644 --- a/addons/atragmx/functions/fnc_update_target_data.sqf +++ b/addons/atragmx/functions/fnc_update_target_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all target column input fields @@ -10,7 +10,7 @@ * None * * Example: - * call ace_atragmx_fnc_update_target + * call ace_atragmx_fnc_update_target_data * * Public: No */ diff --git a/addons/atragmx/functions/fnc_update_target_selection.sqf b/addons/atragmx/functions/fnc_update_target_selection.sqf index 55f39c80fe..e45d6ef8a2 100644 --- a/addons/atragmx/functions/fnc_update_target_selection.sqf +++ b/addons/atragmx/functions/fnc_update_target_selection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all input fields based on the currently selected target diff --git a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf index d331523432..ad0f0dda0e 100644 --- a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf +++ b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the truing drop data fields diff --git a/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf b/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf index f2fffd8fe3..461b4ccf9b 100644 --- a/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf +++ b/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the truing drop input method diff --git a/addons/atragmx/functions/fnc_update_unit_selection.sqf b/addons/atragmx/functions/fnc_update_unit_selection.sqf index ab3edb9256..ce735e773c 100644 --- a/addons/atragmx/functions/fnc_update_unit_selection.sqf +++ b/addons/atragmx/functions/fnc_update_unit_selection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates all input fields based on the currently selected unit diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index 4de6370591..8a3eca1344 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the scope base angle based on the zero range input @@ -35,7 +35,7 @@ if (!GVAR(atmosphereModeTBH)) then { _relativeHumidity = 0.5; }; -private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { +private _scopeBaseAngle = if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { diff --git a/addons/atragmx/functions/script_component.hpp b/addons/atragmx/functions/script_component.hpp deleted file mode 100644 index 6e49f39695..0000000000 --- a/addons/atragmx/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\atragmx\script_component.hpp" \ No newline at end of file diff --git a/addons/atragmx/initKeybinds.sqf b/addons/atragmx/initKeybinds.inc.sqf similarity index 100% rename from addons/atragmx/initKeybinds.sqf rename to addons/atragmx/initKeybinds.inc.sqf diff --git a/addons/atragmx/stringtable.xml b/addons/atragmx/stringtable.xml index 4c11ea8add..a7c08712aa 100644 --- a/addons/atragmx/stringtable.xml +++ b/addons/atragmx/stringtable.xml @@ -16,6 +16,7 @@ ATragMX ATragMX ATragMX + ATragMX Open ATragMX @@ -31,7 +32,8 @@ ATragMX を開く ATragMX 열기 開啟ATragMX - 开启ATragMX + 开启 ATragMX + ATragMX'i aç Rugged PDA with ATragMX @@ -44,10 +46,11 @@ Megerősített PDA, ATragMX-el PDA s ATragMX PDA Robusto com ATragMX - ATragMX 付きの携行型端末 + ATragMX を搭載した頑丈な携帯情報端末 ATragMX가 달린 PDA 裝有軍用PDA的ATragMX - 装有军用PDA的ATragMX + 装有 ATragMX 的军用 PDA + Rugged PDA with ATragMX Open ATragMX @@ -63,7 +66,8 @@ ATragMX を開く ATragMX 열기 開啟ATragMX - 开启ATragMX + 开启 ATragMX + ATragMX'i aç diff --git a/addons/attach/CfgEventHandlers.hpp b/addons/attach/CfgEventHandlers.hpp index 7bb7a9bae5..0da123e61b 100644 --- a/addons/attach/CfgEventHandlers.hpp +++ b/addons/attach/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); }; }; class Extended_GetIn_EventHandlers { diff --git a/addons/attach/CfgVehicles.hpp b/addons/attach/CfgVehicles.hpp index ce0d7df21a..7d5c611f2c 100644 --- a/addons/attach/CfgVehicles.hpp +++ b/addons/attach/CfgVehicles.hpp @@ -13,7 +13,7 @@ class GVAR(DetachVehicle) { \ displayName = CSTRING(Detach); \ condition = QUOTE(_this call FUNC(canDetach)); \ - statement = QUOTE(_this call FUNC(detach) ); \ + statement = QUOTE(_this call FUNC(detach)); \ exceptions[] = {"isNotSwimming"}; \ showDisabled = 0; \ icon = QPATHTOF(UI\detach_ca.paa); \ @@ -86,6 +86,10 @@ class CfgVehicles { dayLight = 0; onlyInNvg = 1; useFlare = 0; + maxLifetime = "8 * 60 * 60"; + blinkingPattern[] = {0.1, 1.1}; // 0.1 s on, 1.1 s off + blinkingStartsOn = 1; + blinkingPatternGuarantee = 1; }; side = 7;//-1=NO_SIDE yellow box,3=CIV grey box,4=NEUTRAL yellow box,6=FRIENDLY green box,7=LOGIC no radar signature @@ -102,6 +106,12 @@ class CfgVehicles { brightness = 10; }; + class NVG_TargetBase: All { + class NVGMarker { + maxLifetime = "8 * 60 * 60"; + }; + }; + class NATO_Box_Base; class Box_NATO_Support_F: NATO_Box_Base { class TransportItems { diff --git a/addons/attach/GUI_VirtualAmmo.hpp b/addons/attach/GUI_VirtualAmmo.hpp index c05e0e62a5..d70573fba2 100644 --- a/addons/attach/GUI_VirtualAmmo.hpp +++ b/addons/attach/GUI_VirtualAmmo.hpp @@ -5,7 +5,7 @@ class RscTitles { duration = 9999999; fadein = 0; fadeout = 0; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(virtualAmmoDisplay), _this select 0)]); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(virtualAmmoDisplay),_this select 0)]); class controls {}; class objects { class TheObject { diff --git a/addons/attach/README.md b/addons/attach/README.md index 3bce88839c..21fa4f1bf6 100644 --- a/addons/attach/README.md +++ b/addons/attach/README.md @@ -5,13 +5,3 @@ Introducing the ability to attach various throwables to yourself or vehicles, to #### Items Added: `ACE_IR_Strobe_Item` - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [esteldunedain](https://github.com/esteldunedain) -- [bux578](https://github.com/bux578) -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/attach/functions/fnc_attach.sqf b/addons/attach/functions/fnc_attach.sqf index 21652f296d..6a0c408271 100644 --- a/addons/attach/functions/fnc_attach.sqf +++ b/addons/attach/functions/fnc_attach.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: eRazeri, esteldunedain, PabstMirror * Attach an item to the unit @@ -26,10 +26,12 @@ if ((_itemClassname == "") || {(!_silentScripted) && {!(_this call FUNC(canAttac private _itemVehClass = getText (configFile >> "CfgWeapons" >> _itemClassname >> "ACE_Attachable"); private _onAttachText = getText (configFile >> "CfgWeapons" >> _itemClassname >> "displayName"); +private _itemModelOrientation = getArray (configFile >> "CfgWeapons" >> _itemClassname >> QGVAR(orientation)); if (_itemVehClass == "") then { _itemVehClass = getText (configFile >> "CfgMagazines" >> _itemClassname >> "ACE_Attachable"); _onAttachText = getText (configFile >> "CfgMagazines" >> _itemClassname >> "displayName"); + _itemModelOrientation = getArray (configFile >> "CfgWeapons" >> _itemClassname >> QGVAR(orientation)); }; if (_itemVehClass == "") exitWith {ERROR("no ACE_Attachable for Item");}; @@ -38,12 +40,13 @@ private _onAttachText = format [localize LSTRING(Item_Attached), _onAttachText]; if (_unit == _attachToVehicle) then { //Self Attachment private _attachedItem = _itemVehClass createVehicle [0,0,0]; - _attachedItem attachTo [_unit, [0.05, -0.09, 0.1], "leftshoulder"]; + _attachedItem attachTo [_unit, [0.07, -0.06, 0.085], "leftshoulder", true]; if (!_silentScripted) then { _unit removeItem _itemClassname; // Remove item [_onAttachText, 2] call EFUNC(common,displayTextStructured); }; _unit setVariable [QGVAR(attached), [[_attachedItem, _itemClassname]], true]; + [QGVAR(attached), [_attachedItem, _itemClassname, _silentScripted]] call CBA_fnc_localEvent; } else { GVAR(placeAction) = PLACE_WAITING; @@ -67,14 +70,14 @@ if (_unit == _attachToVehicle) then { //Self Attachment [{ params ["_args","_idPFH"]; - _args params ["_unit","_attachToVehicle","_itemClassname","_itemVehClass","_onAttachText","_actionID"]; + _args params ["_unit","_attachToVehicle","_itemClassname","_itemVehClass","_onAttachText","_actionID", "_itemModelOrientation"]; private _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0.6]) vectorDiff (positionCameraToWorld [0,0,0]); if (cameraView == "EXTERNAL") then { _virtualPosASL = _virtualPosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); }; private _virtualPos = _virtualPosASL call EFUNC(common,ASLToPosition); - private _lineInterection = lineIntersects [eyePos ACE_player, _virtualPosASL, ACE_player]; + private _lineInterection = ((lineIntersectsSurfaces [eyePos ACE_player, _virtualPosASL, ACE_player]) isNotEqualTo []); //Don't allow placing in a bad position: if (_lineInterection && {GVAR(placeAction) == PLACE_APPROVE}) then {GVAR(placeAction) = PLACE_WAITING;}; @@ -94,7 +97,7 @@ if (_unit == _attachToVehicle) then { //Self Attachment (QGVAR(virtualAmmo) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; if (GVAR(placeAction) == PLACE_APPROVE) then { - [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAttachText, _virtualPos] call FUNC(placeApprove); + [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAttachText, _virtualPos, _itemModelOrientation] call FUNC(placeApprove); }; } else { //Show the virtual object: @@ -111,9 +114,13 @@ if (_unit == _attachToVehicle) then { //Self Attachment ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetPosition _screenPos; private _dir = (positionCameraToWorld [0,0,1]) vectorFromTo (positionCameraToWorld [0,0,0]); private _angle = asin (_dir select 2); - private _up = [0, cos _angle, sin _angle]; - ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetModelDirAndUp [[1,0,0], _up]; + + // Tranform yaw/roll angle to vector, defaults are pre-#9623 behavior + _itemModelOrientation params [["_roll", 0], ["_yaw", 90]]; + private _dirAndUp = [[[0,1,0], [0,0,1]], _yaw, 0, _roll] call BIS_fnc_transformVectorDirAndUp; + private _dirAndUp = [_dirAndUp, 0, _angle, 0] call BIS_fnc_transformVectorDirAndUp; + ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetModelDirAndUp _dirAndUp; }; }; - }, 0, [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAttachText, _actionID]] call CBA_fnc_addPerFrameHandler; + }, 0, [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAttachText, _actionID, _itemModelOrientation]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/attach/functions/fnc_canAttach.sqf b/addons/attach/functions/fnc_canAttach.sqf index 00e7b34e8a..a9277155d9 100644 --- a/addons/attach/functions/fnc_canAttach.sqf +++ b/addons/attach/functions/fnc_canAttach.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if a unit can attach a specific item. diff --git a/addons/attach/functions/fnc_canDetach.sqf b/addons/attach/functions/fnc_canDetach.sqf index 8ff4ef3249..7202ba410f 100644 --- a/addons/attach/functions/fnc_canDetach.sqf +++ b/addons/attach/functions/fnc_canDetach.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if a unit has an item attached and if it can remove that item. diff --git a/addons/attach/functions/fnc_detach.sqf b/addons/attach/functions/fnc_detach.sqf index 5ff12967ce..d953b02bd1 100644 --- a/addons/attach/functions/fnc_detach.sqf +++ b/addons/attach/functions/fnc_detach.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: eRazeri and esteldunedain * Detach an item from a unit @@ -16,7 +16,7 @@ * Public: No */ -params ["_attachToVehicle","_unit"], +params ["_attachToVehicle","_unit"]; TRACE_2("params",_attachToVehicle,_unit); private _attachedList = _attachToVehicle getVariable [QGVAR(attached), []]; @@ -46,16 +46,18 @@ if (isNull _attachedObject || {_itemName == ""}) exitWith {ERROR("Could not find private _isChemlight = _attachedObject isKindOf "Chemlight_base"; // Exit if can't add the item -if (!(_unit canAdd _itemName) && {!_isChemlight}) exitWith { - [localize LSTRING(Inventory_Full)] call EFUNC(common,displayTextStructured); +if (!([_unit, _itemName] call CBA_fnc_canAddItem) && {!_isChemlight}) exitWith { + [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); }; +[QGVAR(detaching), [_attachedObject, _itemName, false]] call CBA_fnc_localEvent; + // Add item to inventory (unless it's a chemlight) if (!_isChemlight) then { _unit addItem _itemName; }; -if (toLower _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then { +if (toLowerANSI _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then { // Hack for dealing with X_IR_Grenade effect not dissapearing on deleteVehicle detach _attachedObject; _attachedObject setPos ((getPos _unit) vectorAdd [0, 0, -1000]); diff --git a/addons/attach/functions/fnc_getChildrenActions.sqf b/addons/attach/functions/fnc_getChildrenActions.sqf index 22b4c28892..e64d2847f6 100644 --- a/addons/attach/functions/fnc_getChildrenActions.sqf +++ b/addons/attach/functions/fnc_getChildrenActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth de Wet (LH), PabstMirror, mharis001 * Returns children actions for attachable items. diff --git a/addons/attach/functions/fnc_handleGetIn.sqf b/addons/attach/functions/fnc_handleGetIn.sqf index b2203958a0..16afd0dd63 100644 --- a/addons/attach/functions/fnc_handleGetIn.sqf +++ b/addons/attach/functions/fnc_handleGetIn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles when a unit gets in to a vehicle. @@ -25,9 +25,10 @@ if (!local _unit) exitWith {}; private _attachedList = _unit getVariable [QGVAR(attached), []]; if (_attachedList isEqualTo []) exitWith {}; -(_attachedList select 0) params ["_xObject"]; +(_attachedList select 0) params ["_xObject", "_xItemName"]; if (!isNull _xObject) then { TRACE_1("detaching and moving attached light",_xObject); + [QGVAR(detaching), [_xObject, _xItemName, true]] call CBA_fnc_localEvent; detach _xObject; _xObject setPos ((getPos _unit) vectorAdd [0, 0, -1000]); [{ diff --git a/addons/attach/functions/fnc_handleGetOut.sqf b/addons/attach/functions/fnc_handleGetOut.sqf index 4e1dac1e89..b81fa93cfa 100644 --- a/addons/attach/functions/fnc_handleGetOut.sqf +++ b/addons/attach/functions/fnc_handleGetOut.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles when a unit gets in to a vehicle. diff --git a/addons/attach/functions/fnc_handleKilled.sqf b/addons/attach/functions/fnc_handleKilled.sqf index 0aaf0b03cb..2183b05b42 100644 --- a/addons/attach/functions/fnc_handleKilled.sqf +++ b/addons/attach/functions/fnc_handleKilled.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Handles when vehicle or man is killed. + * Handles when vehicle or man is killed. * Note: Runs where unit is local. * * Arguments: @@ -28,7 +28,7 @@ if (_attachedList isEqualTo []) exitWith {}; TRACE_2("detaching",_xObject,_deadUnit); detach _xObject; //If it's a vehicle, also delete the attached - if (!(_deadUnit isKindOf "CAManBase")) then { + if !(_deadUnit isKindOf "CAManBase") then { _xObject setPos ((getPos _deadUnit) vectorAdd [0, 0, -1000]); [{deleteVehicle (_this select 0)}, [_xObject], 2] call CBA_fnc_waitAndExecute; }; diff --git a/addons/attach/functions/fnc_placeApprove.sqf b/addons/attach/functions/fnc_placeApprove.sqf index d0101695b4..2f0c4d6b75 100644 --- a/addons/attach/functions/fnc_placeApprove.sqf +++ b/addons/attach/functions/fnc_placeApprove.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Pabst Mirror (based on Explosive attach by Garth de Wet (LH)) * Approves placement of the lightObject, scans for an appropriate location and attaches * A player can release the attachObject with it floating in mid-air. - * This will use lineIntersectsWith to scan towards the center of the vehicle to find a collision - * ArmA's collision detection is of couse terrible and often misses collisions (difference between what we see and collision LOD) + * This will use lineIntersectsSurfaces to scan towards the center of the vehicle to find a collision + * Arma's collision detection is of couse terrible and often misses collisions (difference between what we see and collision LOD) * So it does multiple scans at slighly different angles * This is VERY computationaly intensive, but doesn't happen that often. * @@ -15,17 +15,18 @@ * 3: Light Vehicle Classname * 4: On Attach Text * 5: Starting Pos of dummy item + * 5: Orientation of model * * Return Value: * None * * Example: - * No + * None * * Public: No */ -params ["_unit", "_attachToVehicle", "_itemClassname", "_itemVehClass", "_onAttachText", "_startingPosition"]; +params ["_unit", "_attachToVehicle", "_itemClassname", "_itemVehClass", "_onAttachText", "_startingPosition", "_itemModelOrientation"]; TRACE_6("params",_unit,_attachToVehicle,_itemClassname,_itemVehClass,_onAttachText,_startingPosition); private _startingOffset = _attachToVehicle worldToModel _startingPosition; @@ -93,6 +94,19 @@ _endPosTestOffset set [2, (_startingOffset select 2)]; private _attachedObject = _itemVehClass createVehicle (getPos _unit); _attachedObject attachTo [_attachToVehicle, _endPosTestOffset]; +// Get wanted orientation if any is set +_itemModelOrientation params [["_roll", 0], ["_yaw", 90]]; +private _dirAndUp = [[[0,1,0],[0,0,1]], -_yaw, 0, _roll] call BIS_fnc_transformVectorDirAndUp; + +// Transform dir and up vector from player model to world, then to model-space of _attachToVehicle +private _dir = _unit vectorModelToWorldVisual _dirAndUp#0; +_dir = _attachToVehicle vectorWorldToModelVisual _dir; + +private _up = _unit vectorModelToWorldVisual _dirAndUp#1; +_up = _attachToVehicle vectorWorldToModelVisual _up; + +_attachedObject setVectorDirAndUp [_dir, _up]; + //Remove Item from inventory _unit removeItem _itemClassname; @@ -100,5 +114,6 @@ _unit removeItem _itemClassname; private _attachList = _attachToVehicle getVariable [QGVAR(attached), []]; _attachList pushBack [_attachedObject, _itemClassname]; _attachToVehicle setVariable [QGVAR(attached), _attachList, true]; +[QGVAR(attached), [_attachedObject, _itemClassname, false]] call CBA_fnc_localEvent; [_onAttachText, 2] call EFUNC(common,displayTextStructured); diff --git a/addons/attach/functions/script_component.hpp b/addons/attach/functions/script_component.hpp deleted file mode 100644 index b28de85182..0000000000 --- a/addons/attach/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\attach\script_component.hpp" \ No newline at end of file diff --git a/addons/attach/stringtable.xml b/addons/attach/stringtable.xml index 252f25e4ed..2d5671dec1 100644 --- a/addons/attach/stringtable.xml +++ b/addons/attach/stringtable.xml @@ -13,9 +13,10 @@ Tárgy hozzácsatolása Прикрепить предмет アイテムを取り付ける - 물건 부착 + 아이템 부착 附掛裝備>> 附挂装备>> + Eşyayı bağla Attach @@ -32,6 +33,7 @@ 부착 附掛 附挂 + Bağla Detach item @@ -40,14 +42,15 @@ Odczep przedmiot Détacher l'objet Odepnout předmět - Separar item + Desprender item Stacca l'oggetto Tárgy lecsatolása Отсоединить アイテムを外す - 분리 + 떼내기 取下裝備 取下装备 + Eşyayı sök IR Strobe Attached @@ -63,7 +66,8 @@ 赤外線ストロボを取り付けました 적외선 스트로브 부착됨 已附掛紅外線頻閃器 - 已附挂红外线频闪器 + 已附挂红外频闪器 + IR Strobe Bağlandı IR Strobe Detached @@ -77,9 +81,10 @@ Infravörös jeladó lecsatolva ИК-маяк отсоединён 赤外線ストロボを外しました - 적외선 스트로브 분리됨 + 적외선 스트로브 떼어냄 已取下紅外線頻閃器 - 已取下红外线频闪器 + 已取下红外频闪器 + IR Strobe Söküldü IR Grenade Attached @@ -95,7 +100,8 @@ 赤外線グレネードを取り付けました 적외선 수류탄 부착됨 已附掛紅外線手榴彈 - 已附挂红外线手榴弹 + 已附挂红外手雷 + IR Bombası Bağlandı IR Grenade Detached @@ -109,9 +115,10 @@ Infravörös gránát lecsatolva ИК-граната отсоединена 赤外線グレネードを外しました - 적외선 수류탄 분리됨 + 적외선 수류탄 떼어냄 已取下紅外線手榴彈 - 已取下红外线手榴弹 + 已取下红外手雷 + IR Bombası Söküldü Chemlight Attached @@ -125,9 +132,10 @@ Chemlight hozzácsatolva Химсвет прикреплён ケミライトを取り付けました - 켐라이트 부착됨 + 화학조명 부착됨 已附掛螢光棒 - 已附挂萤光棒 + 已附挂荧光棒 + Işık Çubuğu Bağlandı Chemlight Detached @@ -141,25 +149,10 @@ Chemlight hozzácsatolva Химсвет отсоединён ケミライトを外しました - 켐라이트 분리됨 + 화학조명 떼어냄 已取下螢光棒 - 已取下萤光棒 - - - No inventory space - Kein Platz im Inventar - Sin espacio en inventario - Brak miejsca w ekwipunku - Pas de place dans l'inventaire - Nedostatek místa v inventáři - Sem espaço no inventário - Non hai più spazio - Nincs több hely - В инвентаре нет места - インベントリに空きがない - 넣을 공간이 없음 - 無可用空間 - 无可用空间 + 已取下荧光棒 + Işık Çubuğu Söküldü IR Strobe @@ -175,7 +168,8 @@ 赤外線ストロボ 적외선 스트로브 紅外線頻閃器 - 红外线频闪器 + 红外频闪器 + IR Stroboskop IR Strobe allows you to signal your position through a pulsating beacon only visible with NVGs. @@ -188,10 +182,11 @@ La Strobo IR è una luce stroboscopica che ti permette di segnalare la tua posizione grazie all'emissione di impulsi ad infrarossi visibili solo con i visori notturni. Az infravörös jeladóval megjelölheted a helyzetedet úgy, hogy annak pulzáló fénye csak éjjellátó készülékkel látható. ИК-маяк позволяет сигнализировать о своём местоположении через пульсирующий свет, видимый только через ПНВ. - 赤外線ストロボはあなたの位置を知らせますが、夜間暗視装置を介してでしか見れません。 + 赤外線ストロボを使用すると、暗視装置を介してのみ見ることが出来る点滅表示で自分の位置を知らせることができます。 적외선 스트로브는 자신의 위치를 반짝이면서 표시합니다. 이는 야간투시경으로 밖에 보지 못합니다. 紅外線閃頻器,藉由紅外線閃頻信號來辨識你的位置,僅能使用夜視系統來辨識紅外線信號 - 红外线闪频器,藉由红外线闪频信号来辨识你的位置,仅能使用夜视系统来辨识红外线信号 + 红外频闪器制造只有用夜视仪才能看到的频闪信标,发出一个位置信号。 + IR Stroboskop, yalnızca gece görüşlerinden gözükebilen titreşimli bir ışık aracılığıyla konumunuzu gösterir. Place @@ -200,14 +195,15 @@ Umieść Placer Položit - Colocar + Fixar Posiziona Elhelyez Установить - 置く - 두기 + 設置 + 놓기 放置 放置 + Yerleştir Cancel @@ -224,6 +220,7 @@ 취소 取消 取消 + Iptal Attach Failed @@ -240,6 +237,7 @@ 부착 실패 附掛失敗 附挂失败 + Bağlama başarısız %1<br/>Attached @@ -252,10 +250,11 @@ %1<br/>attaccata %1<br/>hozzácsatolva %1<br/>присоединен(-а) - %1<br/>を取り付けました + %1 を<br/>取り付けました %1<br/>부착됨 %1<br/>已附掛 %1<br/>已附挂 + %1<br/>Bağlandı %1<br/>Detached @@ -268,10 +267,11 @@ %1<br/>staccata %1<br/>lecsatolva %1<br/>отсоединен(-а) - %1<br/>を外しました - %1<br/>분리됨 + %1 を<br/>外しました + %1<br/>떼어냄 %1<br/>已取下 %1<br/>已取下 + %1<br/>Söküldü diff --git a/addons/backpacks/CfgEventHandlers.hpp b/addons/backpacks/CfgEventHandlers.hpp index 20cf8f83bf..5fedbc4606 100644 --- a/addons/backpacks/CfgEventHandlers.hpp +++ b/addons/backpacks/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/backpacks/README.md b/addons/backpacks/README.md index 64e37f337b..58bcb36dbf 100644 --- a/addons/backpacks/README.md +++ b/addons/backpacks/README.md @@ -2,11 +2,3 @@ ace_backpacks ================= Adds indication when someone else opens your backpack (sound effect and camera shake). - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/backpacks/XEH_postInit.sqf b/addons/backpacks/XEH_postInit.sqf index de5ffa4bee..3066524386 100644 --- a/addons/backpacks/XEH_postInit.sqf +++ b/addons/backpacks/XEH_postInit.sqf @@ -1,3 +1,3 @@ #include "script_component.hpp" -["ace_backpackOpened", {_this call FUNC(backpackOpened)}] call CBA_fnc_addEventHandler; +["ace_backpackOpened", LINKFUNC(backpackOpened)] call CBA_fnc_addEventHandler; diff --git a/addons/backpacks/functions/fnc_backpackOpened.sqf b/addons/backpacks/functions/fnc_backpackOpened.sqf index 92897d72f5..9b64450e38 100644 --- a/addons/backpacks/functions/fnc_backpackOpened.sqf +++ b/addons/backpacks/functions/fnc_backpackOpened.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Someone opened your backpack. Play sound and camshake. Execute locally. @@ -30,7 +30,7 @@ private _sounds = [ QUOTE(PATHTO_R(sounds\zip_out.wav)) ]; -private _position = AGLToASL (_target modelToWorldVisual (_target selectionPosition "Spine3")); +private _position = _target modelToWorldVisualWorld (_target selectionPosition "Spine3"); playSound3D [ selectRandom _sounds, diff --git a/addons/backpacks/functions/fnc_isBackpack.sqf b/addons/backpacks/functions/fnc_isBackpack.sqf index a101a514e9..3d2e10d057 100644 --- a/addons/backpacks/functions/fnc_isBackpack.sqf +++ b/addons/backpacks/functions/fnc_isBackpack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the given backpack is an actual backpack that can store items. Parachute, static weapon packs, etc. will return false. @@ -17,8 +17,8 @@ params [["_backpack", objNull, [objNull, ""]]]; -if (_backpack isEqualType objNull) then { - _backpack = typeOf _backpack; +if (_backpack isEqualType objNull) exitWith { + maxLoad _backpack > 0 && {getText (configOf _backpack >> "vehicleClass") == "backpacks"} }; private _config = configFile >> "CfgVehicles" >> _backpack; diff --git a/addons/backpacks/functions/fnc_onOpenInventory.sqf b/addons/backpacks/functions/fnc_onOpenInventory.sqf index bfb380efe2..6d72a40b66 100644 --- a/addons/backpacks/functions/fnc_onOpenInventory.sqf +++ b/addons/backpacks/functions/fnc_onOpenInventory.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle the open inventory event. Camshake and sound on target client. diff --git a/addons/backpacks/functions/script_component.hpp b/addons/backpacks/functions/script_component.hpp deleted file mode 100644 index b6bb78fff5..0000000000 --- a/addons/backpacks/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\backpacks\script_component.hpp" \ No newline at end of file diff --git a/addons/ballistics/ACE_Arsenal_Stats.hpp b/addons/ballistics/ACE_Arsenal_Stats.hpp index 34a8b561e5..52efa9702b 100644 --- a/addons/ballistics/ACE_Arsenal_Stats.hpp +++ b/addons/ballistics/ACE_Arsenal_Stats.hpp @@ -6,7 +6,7 @@ class EGVAR(arsenal,stats) { stats[] = {"ACE_barrelTwist"}; displayName= CSTRING(statBarrelTwist); showText = 1; - textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _barrelTwist = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelTwist toFixed 0, (_barrelTwist / 25.4) toFixed 1)]); + textStatement = QUOTE(params [ARR_2('_stat','_config')]; private _barrelTwist = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelTwist toFixed 0,(_barrelTwist / 25.4) toFixed 1)]); tabs[] = {{0,1}, {}}; }; class ACE_barrelLength: statBase { @@ -15,7 +15,7 @@ class EGVAR(arsenal,stats) { stats[] = {"ACE_barrelLength"}; displayName = CSTRING(statBarrelLength); showText = 1; - textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _barrelLength = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelLength toFixed 0, (_barrelLength / 25.4) toFixed 1)]); + textStatement = QUOTE(params [ARR_2('_stat','_config')]; private _barrelLength = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelLength toFixed 0,(_barrelLength / 25.4) toFixed 1)]); tabs[] = {{0,1}, {}}; }; class ACE_ammo: statBase { @@ -24,7 +24,8 @@ class EGVAR(arsenal,stats) { stats[] = {"ammo", "displayName"}; displayName = "$STR_dn_ammo"; showText = 1; - textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _ammoDisplayName = getText (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 1); [ARR_2(_ammoDisplayName, getText (_config >> _stat select 0))] select (_ammoDisplayName == '')); + condition = QUOTE(getText (_this select 1 >> _this select 0 select 0) isNotEqualTo ''); + textStatement = QUOTE(params [ARR_2('_stat','_config')]; private _ammoDisplayName = getText (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 1); [ARR_2(_ammoDisplayName,getText (_config >> _stat select 0))] select (_ammoDisplayName == '')); tabs[] = {{}, {4}}; }; class ACE_ballisticCoef: statBase { @@ -33,8 +34,8 @@ class EGVAR(arsenal,stats) { stats[] = {"ACE_dragModel","ACE_ballisticCoefficients", "ACE_standardAtmosphere"}; displayName= CSTRING(statBallisticCoef); showText= 1; - textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); private _ballisticCoef = getArray (_ammoCfg >> _stat select 1); _ballisticCoef sort false; format [ARR_4('%1 G%2 (%3)', _ballisticCoef select 0 ,getNumber (_ammoCfg >> _stat select 0), getText (_ammoCfg >> _stat select 2))]); - condition = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); !(getArray (_ammoCfg >> _stat select 1) isEqualTo [])); + textStatement = QUOTE(params[ARR_2('_stat','_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); private _ballisticCoef = getArray (_ammoCfg >> _stat select 1); _ballisticCoef sort false; format [ARR_4('%1 G%2 (%3)',_ballisticCoef select 0,getNumber (_ammoCfg >> _stat select 0),getText (_ammoCfg >> _stat select 2))]); + condition = QUOTE(params[ARR_2('_stat','_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); (getArray (_ammoCfg >> _stat select 1) isNotEqualTo [])); tabs[] ={{}, {4}}; }; class ACE_bulletMass: statBase { @@ -43,27 +44,37 @@ class EGVAR(arsenal,stats) { stats[] = {"ACE_bulletMass"}; displayName = CSTRING(statBulletMass); showText = 1; - textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoWeight = getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0); format [ARR_3('%1g (%2gr)', _ammoWeight toFixed 1, (_ammoWeight * 15.43) toFixed 1)]); - condition = QUOTE(params[ARR_2('_stat', '_config')]; getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0) > 0); + textStatement = QUOTE(params[ARR_2('_stat','_config')]; private _ammoWeight = getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0); format [ARR_3('%1g (%2gr)',_ammoWeight toFixed 1,(_ammoWeight * 15.43) toFixed 1)]); + condition = QUOTE(params[ARR_2('_stat','_config')]; getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0) > 0); tabs[] = {{}, {4}}; }; class ACE_magMuzzleVelocity: statBase { scope = 2; priority = 3; - stats[] = {"initSpeed"}; + stats[] = {"initSpeed", "ammo"}; displayName= CSTRING(statMuzzleVelocity); showText= 1; - textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_magazineMuzzleVelocity)); - condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); + textStatement = QUOTE([ARR_2(_this select 0,_this select 1)] call FUNC(statTextStatement_magazineMuzzleVelocity)); + condition = QUOTE(getText (_this select 1 >> _this select 0 select 1) isNotEqualTo '' && {getNumber (_this select 1 >> (_this select 0) select 0) > 0}); tabs[] = {{}, {4}}; }; class ACE_weaponMuzzleVelocity: statBase { scope = 2; - priority = 3; + priority = 1; stats[] = {"initSpeed"}; displayName= CSTRING(statMuzzleVelocity); showText = 1; - textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_weaponMuzzleVelocity)); + textStatement = QUOTE([ARR_2(_this select 0,_this select 1)] call FUNC(statTextStatement_weaponMuzzleVelocity)); tabs[] = {{0,1}, {}}; }; + class ACE_magazineAiUsage: statBase { + scope = 2; + priority = 0; + stats[] = {"aiAmmoUsageFlags"}; + displayName= CSTRING(ammoUsage_ai); + showText= 1; + textStatement = QUOTE(call FUNC(statTextStatement_magazineAiUsage)); + condition = QUOTE(is3DEN || {!isNull getAssignedCuratorLogic player} || {missionNamespace getVariable [ARR_2(QQGVAR(showAIMagazineUse),missionName == 'Arsenal')]}); + tabs[] = {{}, {4}}; + }; }; diff --git a/addons/ballistics/CfgAmmo.hpp b/addons/ballistics/CfgAmmo.hpp index a240840bcc..8bdb9b393c 100644 --- a/addons/ballistics/CfgAmmo.hpp +++ b/addons/ballistics/CfgAmmo.hpp @@ -6,7 +6,115 @@ class CfgAmmo { timeToLive=6; }; - class B_556x45_Ball : BulletBase { + class ShotgunBase; + + class B_12Gauge_Pellets_Submunition: BulletBase { //#00 Buckshot + //vanilla values have been left as comments for reference purposes + caliber = 0.525; //penetration of ~3mm RHA, ~9.6mm metal + //caliber = 1; //too high, ~5.7mm of RHA (380*1*15/1000=5.7), ~18.25 metal + //cost = 1; + //hit = 20; + //simulationStep = 0.0001; + //cartridge = ""; + //submunitionAmmo = "B_12Gauge_Pellets_Submunition_Deploy"; + submunitionConeType[] = {"poissondisc", 9}; //#00 Buckshot generally has 9 pellets per shell + //submunitionConeType[] = {"poissondisc", 18}; + //submunitionConeAngle = 0.8; + //triggerSpeedCoef[] = {0.85, 1}; + triggerTime = 0.008; // Shot takes ~5-15 feet to start spreading out and the vanilla triggerTime is too short to allow that + //triggerTime = 0.001; + }; + class B_12Gauge_Pellets_Submunition_Deploy: BulletBase { + airFriction = -0.0030; + //airFriction = -0.0067; + caliber = 0.525; + hit = 2.55; //vanilla hit is way too high + //hit = 6; + //indirectHit = 0; + //indirectHitRange = 0; + //typicalSpeed = 360; + //deflecting = 35; + }; + + class B_12Gauge_Pellets: ShotgunBase { //This doesn't seem to be used for anything, but I want to standardize the caliber with the other pellet classes. + caliber = 0.525; //3mm RHA, probably still too high though as RHA is hardened. + }; + + class ACE_12Gauge_Pellets_Submunition_No0_Buck: B_12Gauge_Pellets_Submunition { + caliber = 0.5; + submunitionAmmo = "ACE_12Gauge_Pellets_Submunition_No0_Buck_Deploy"; + submunitionConeType[] = {"poissondisc", 9}; + submunitionConeAngle = 0.81; + }; + class ACE_12Gauge_Pellets_Submunition_No0_Buck_Deploy: B_12Gauge_Pellets_Submunition_Deploy { + airFriction = -0.0033; + caliber = 0.5; + hit = 2.27; + }; + class ACE_12Gauge_Pellets_Submunition_No1_Buck: B_12Gauge_Pellets_Submunition { + caliber = 0.475; + submunitionAmmo = "ACE_12Gauge_Pellets_Submunition_No1_Buck_Deploy"; + submunitionConeType[] = {"poissondisc", 11}; + submunitionConeAngle = 0.83; + }; + class ACE_12Gauge_Pellets_Submunition_No1_Buck_Deploy: B_12Gauge_Pellets_Submunition_Deploy { + airFriction = -0.0038; + caliber = 0.475; + hit = 1.86; + }; + class ACE_12Gauge_Pellets_Submunition_No2_Buck: B_12Gauge_Pellets_Submunition { + caliber = 0.45; + submunitionAmmo = "ACE_12Gauge_Pellets_Submunition_No2_Buck_Deploy"; + submunitionConeType[] = {"poissondisc", 14}; + submunitionConeAngle = 0.85; + }; + class ACE_12Gauge_Pellets_Submunition_No2_Buck_Deploy: B_12Gauge_Pellets_Submunition_Deploy { + airFriction = -0.0048; + caliber = 0.45; + hit = 1.46; + }; + class ACE_12Gauge_Pellets_Submunition_No3_Buck: B_12Gauge_Pellets_Submunition { + caliber = 0.425; + submunitionAmmo = "ACE_12Gauge_Pellets_Submunition_No3_Buck_Deploy"; + submunitionConeType[] = {"poissondisc", 18}; + submunitionConeAngle = 0.87; + }; + class ACE_12Gauge_Pellets_Submunition_No3_Buck_Deploy: B_12Gauge_Pellets_Submunition_Deploy { + airFriction = -0.0067; + caliber = 0.425; + hit = 1.13; + }; + class ACE_12Gauge_Pellets_Submunition_No4_Buck: B_12Gauge_Pellets_Submunition { + caliber = 0.4; + submunitionAmmo = "ACE_12Gauge_Pellets_Submunition_No4_Buck_Deploy"; + submunitionConeType[] = {"poissondisc", 21}; + submunitionConeAngle = 0.89; + }; + class ACE_12Gauge_Pellets_Submunition_No4_Buck_Deploy: B_12Gauge_Pellets_Submunition_Deploy { + airFriction = -0.0085; + caliber = 0.4; + hit = 0.97; + }; + class ACE_12Gauge_Pellets_Submunition_No4_Bird: B_12Gauge_Pellets_Submunition { + caliber = 0.2; + hit = 3; + submunitionAmmo = "ACE_12Gauge_Pellets_Submunition_No4_Bird_Deploy"; + submunitionConeType[] = {"poissondisc", 135}; + submunitionConeAngle = 1.1; + triggerSpeedCoef[] = {0.8, 1}; + }; + class ACE_12Gauge_Pellets_Submunition_No4_Bird_Deploy: B_12Gauge_Pellets_Submunition_Deploy { + caliber = 0.2; + airFriction = -0.0800; + hit = 0.15; + }; + + class B_12Gauge_Slug: BulletBase { + //caliber = 3; //too high, ~20mm of RHA (450*3*15/1000=20), ~64mm metal + caliber = 1.037; //~7mm RHA, ~22.4mm metal, probably still too high though as RHA is hardened. + }; + + class B_556x45_Ball: BulletBase { airFriction=-0.00130094; tracerScale = 1; tracerStartTime=0.073; // M856 tracer burns out to 800m @@ -22,7 +130,15 @@ class CfgAmmo { ACE_muzzleVelocities[]={723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900}; ACE_barrelLengths[]={210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6}; }; - class ACE_556x45_Ball_Mk262 : B_556x45_Ball { + + class B_556x45_dual: B_556x45_Ball { + airFriction = -0.00055; + 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_muzzleVelocities[] = {268}; // at 21°C, at 15°C 267 m/s according with the 20Rnd_556x45_UW_mag initSpeed + ACE_barrelLengths[] = {457.2}; // according with the SDAR barrel length: https://en.wikipedia.org/wiki/Kel-Tec_RFB + }; + + class ACE_556x45_Ball_Mk262: B_556x45_Ball { airFriction=-0.00111805; ACE_caliber=5.69; ACE_bulletLength=23.012; @@ -36,7 +152,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={624, 816, 832, 838}; ACE_barrelLengths[]={190.5, 368.3, 457.2, 508.0}; }; - class ACE_556x45_Ball_Mk318 : B_556x45_Ball { + class ACE_556x45_Ball_Mk318: B_556x45_Ball { airFriction=-0.0012588; ACE_caliber=5.69; ACE_bulletLength=23.012; @@ -49,7 +165,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={780, 886, 950}; ACE_barrelLengths[]={254.0, 393.7, 508.0}; }; - class ACE_556x45_Ball_M995_AP : B_556x45_Ball { + class ACE_556x45_Ball_M995_AP: B_556x45_Ball { airFriction=-0.00126182; caliber=1.6; ACE_caliber=5.69; @@ -67,36 +183,45 @@ 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; + + class B_580x42_Ball_F: BulletBase { // DBP87 + airFriction = -0.00121087; + ACE_caliber = 6; + ACE_bulletLength = 24; + ACE_bulletMass = 4.15; + 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.156}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {790, 930, 950}; + ACE_barrelLengths[] = {369.0, 463.0, 600.0}; }; - class B_580x42_Ball_F: BulletBase { - airFriction=-0.00121087; - ACE_caliber=5.9944; - ACE_bulletLength=24.2; - ACE_bulletMass=4.15; - 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.156}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=7; - ACE_muzzleVelocities[]={790, 930, 950}; - ACE_barrelLengths[]={369.0, 463.0, 600.0}; + + class ACE_580x42_DBP88_Ball: B_580x42_Ball_F { // DBP88 https://en.wikipedia.org/wiki/5.8%C3%9742mm + airFriction = -0.000968; + typicalSpeed = 895; + ACE_bulletLength = 28; // https://files.osgnetworks.tv/2/files/2017/11/DBP87-Specs2.jpg + ACE_bulletMass = 5; + ACE_ballisticCoefficients[] = {0.21}; + ACE_muzzleVelocities[] = {903}; // at 21°C, at 15°C 895 m/s according with the ACE_10Rnd_580x42_DBP88_Mag initSpeep + ACE_barrelLengths[] = {640}; }; - class B_65x39_Caseless : BulletBase { + + class B_65x39_Caseless: BulletBase { airFriction=-0.00077363; tracerScale = 1.1; //1.0; ACE_caliber=6.706; @@ -111,11 +236,11 @@ class CfgAmmo { ACE_barrelLengths[]={254.0, 406.4, 508.0, 609.6, 660.4, 762.0}; }; class B_65x39_Case_yellow; - class ACE_65x39_Caseless_Tracer_Dim : B_65x39_Case_yellow { + class ACE_65x39_Caseless_Tracer_Dim: B_65x39_Case_yellow { nvgOnly = 1; }; class B_65x39_Caseless_green; - class ACE_65x39_Caseless_green_Tracer_Dim : B_65x39_Caseless_green { + class ACE_65x39_Caseless_green_Tracer_Dim: B_65x39_Caseless_green { nvgOnly = 1; }; class ACE_65x47_Ball_Scenar: B_65x39_Caseless { @@ -152,10 +277,10 @@ class CfgAmmo { class B_65x39_Minigun_Caseless: SubmunitionBullet { tracerScale = 1.1; //1.0; }; - class B_762x51_Ball : BulletBase { + class B_762x51_Ball: BulletBase { airFriction=-0.00103711; tracerScale = 1.2; //0.6; - tracerStartTime=0.073; // Based on the British L5A1 which burns out to 1000m + tracerStartTime=0.073; // Based on the British L5A1 which burns out to 1000m tracerEndTime=2.15957; // Time in seconds calculated with ballistics calculator ACE_caliber=7.823; ACE_bulletLength=28.956; @@ -172,7 +297,7 @@ class CfgAmmo { class ACE_B_762x51_Tracer_Dim: B_762x51_Tracer_Yellow { nvgOnly = 1; }; - class ACE_762x51_Ball_M118LR : B_762x51_Ball { + class ACE_762x51_Ball_M118LR: B_762x51_Ball { airFriction=-0.00085157; caliber=1.8; hit=16; @@ -189,7 +314,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={750, 780, 790, 794}; ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; }; - class ACE_762x51_Ball_Mk316_Mod_0 : B_762x51_Ball { + class ACE_762x51_Ball_Mk316_Mod_0: B_762x51_Ball { airFriction=-0.00084311; caliber=1.8; hit=16; @@ -206,7 +331,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={775, 790, 805, 810}; ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; }; - class ACE_762x51_Ball_Mk319_Mod_0 : B_762x51_Ball { + class ACE_762x51_Ball_Mk319_Mod_0: B_762x51_Ball { airFriction=-0.00104515; caliber=1.5; hit=14; @@ -223,7 +348,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={838, 892, 910}; ACE_barrelLengths[]={330.2, 406.4, 508.0}; }; - class ACE_762x51_Ball_M993_AP : B_762x51_Ball { + class ACE_762x51_Ball_M993_AP: B_762x51_Ball { airFriction=-0.0010939; caliber=2.2; hit=11; @@ -239,23 +364,33 @@ class CfgAmmo { ACE_muzzleVelocities[]={875, 910, 930}; ACE_barrelLengths[]={330.2, 406.4, 508.0}; }; - class ACE_762x51_Ball_Subsonic : B_762x51_Ball { - airFriction=-0.00060194; - caliber=1; - hit=6; - typicalSpeed=320; - ACE_caliber=7.823; - ACE_bulletLength=34.036; - ACE_bulletMass=12.96; - 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.235}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=7; - ACE_muzzleVelocities[]={305, 325, 335, 340}; - ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + class ACE_762x51_Ball_Subsonic: B_762x51_Ball { + airFriction = -0.00060194; + caliber = 1; + hit = 6; + typicalSpeed = 320; + visibleFire = 1; // B_762x51_Ball: 3 + audibleFire = 5; // B_762x51_Ball: 45 + dangerRadiusBulletClose = 4; // B_762x51_Ball: 8 + suppressionRadiusBulletClose = 2; // B_762x51_Ball: 6 + ACE_caliber = 7.823; + ACE_bulletLength = 34.036; + ACE_bulletMass = 12.96; + 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.235}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {305, 325, 335, 340}; + ACE_barrelLengths[] = {406.4, 508.0, 609.6, 660.4}; + class CamShakeExplode { + power = 2.2360699; // B_762x51_Ball: 2.8284299 + duration = 0.4; // B_762x51_Ball: 0.6 + frequency = 20; // B_762x51_Ball: 20 + distance = 6.7082; // B_762x51_Ball: 8.48528 + }; }; - class ACE_762x67_Ball_Mk248_Mod_0 : B_762x51_Ball { + class ACE_762x67_Ball_Mk248_Mod_0: B_762x51_Ball { airFriction=-0.00072468; caliber=1.8; hit=17; @@ -272,7 +407,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={865, 900, 924}; ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; - class ACE_762x67_Ball_Mk248_Mod_1 : B_762x51_Ball { + class ACE_762x67_Ball_Mk248_Mod_1: B_762x51_Ball { airFriction=-0.00063027; caliber=1.9; hit=18; @@ -289,8 +424,8 @@ class CfgAmmo { ACE_muzzleVelocities[]={847, 867, 877}; ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; - class ACE_762x67_Ball_Berger_Hybrid_OTM : B_762x51_Ball { - airFriction=-0.00053638; + class ACE_762x67_Ball_Berger_Hybrid_OTM: B_762x51_Ball { + airFriction=-0.000546; caliber=2.0; hit=19; typicalSpeed=853; @@ -321,7 +456,7 @@ class CfgAmmo { ACE_barrelLengths[]={406.4, 508.0, 604.5, 736.6}; }; class B_762x54_Tracer_Green; - class ACE_762x54_Ball_7T2 : B_762x54_Tracer_Green { + class ACE_762x54_Ball_7T2: B_762x54_Tracer_Green { airFriction=-0.00103739; typicalSpeed=800; tracerStartTime=0.073; // Based on the 7T2 which burns three seconds @@ -337,20 +472,20 @@ 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 { + class B_9x21_Ball: BulletBase { airFriction=-0.00211064; tracerScale = 0.5; ACE_caliber=9.042; @@ -367,7 +502,7 @@ class CfgAmmo { class B_9x21_Ball_Tracer_Green: B_9x21_Ball { tracerScale = 0.5; }; - class ACE_9x19_Ball : B_9x21_Ball { + class ACE_9x19_Ball: B_9x21_Ball { airFriction=-0.00201185; ACE_caliber=9.017; ACE_bulletLength=15.494; @@ -380,21 +515,21 @@ class CfgAmmo { ACE_muzzleVelocities[]={340, 370, 400}; ACE_barrelLengths[]={101.6, 127.0, 228.6}; }; - class B_93x64_Ball : BulletBase { - airFriction=-0.00110727; - ACE_caliber=9.296; - ACE_bulletLength=34.29; - ACE_bulletMass=14.904; - ACE_muzzleVelocityVariationSD=0.4; - 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.368}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={850, 870, 880}; - ACE_barrelLengths[]={508.0, 620.014, 660.4}; + class B_93x64_Ball: BulletBase { + airFriction = -0.000808; // According with the G1 BC 0.515 and the SVDK muzzle velocity 780 m/s https://www.kalashnikov.ru/medialibrary/bd9/72_77.pdf#page=3 + ACE_caliber = 9.28; // https://www.kalashnikov.ru/medialibrary/bd9/72_77.pdf#page=3 + ACE_bulletLength = 35.56; // Average length from bullets with similar mass and BC + ACE_bulletMass = 17; // https://www.kalashnikov.ru/medialibrary/bd9/72_77.pdf#page=3 + ACE_muzzleVelocityVariationSD = 0.4; + 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.515}; // Compromise as close as possible to these velocities and times of flight from this table (unknown measurement conditions) https://www.kalashnikov.ru/medialibrary/bd9/72_77.pdf#page=5 + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; // Better result with ICAO (15°C, 1013,25 hPa, 0%) than ASM conditions (15°C, 999,916 hPa, 78%) + ACE_dragModel = 1; // Better result than an equivalent G7 BC + ACE_muzzleVelocities[] = {768, 788, 798}; // Default values - 82 m/s at 21°C, at 15°C {760, 780, 790} according with the 10Rnd_93x64_DMR_05_Mag and the 150Rnd_93x64_Mag initSpeed + ACE_barrelLengths[] = {508.0, 620.0, 660.4}; }; - class B_408_Ball : BulletBase { + class B_408_Ball: BulletBase { timeToLive=10; airFriction=-0.00046249; tracerScale = 1.3; @@ -411,7 +546,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={867}; ACE_barrelLengths[]={736.6}; }; - class ACE_408_Ball : BulletBase { + class ACE_408_Ball: BulletBase { timeToLive=10; airFriction=-0.00065414; typicalSpeed=1067; @@ -429,7 +564,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={1067}; ACE_barrelLengths[]={736.6}; }; - class B_338_Ball : BulletBase { + class B_338_Ball: BulletBase { timeToLive=10; airFriction=-0.00060841; ACE_caliber=8.585; @@ -444,7 +579,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={880, 915, 925}; ACE_barrelLengths[]={508.0, 660.4, 711.2}; }; - class B_338_NM_Ball : BulletBase { + class B_338_NM_Ball: BulletBase { airFriction=-0.00053639; ACE_caliber=8.585; ACE_bulletLength=43.18; @@ -457,7 +592,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={790, 807, 820}; ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; - class ACE_338_Ball : B_338_Ball { + class ACE_338_Ball: B_338_Ball { timeToLive=10; airFriction=-0.00055706; typicalSpeed=826; @@ -473,7 +608,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={800, 820, 826, 830}; ACE_barrelLengths[]={508.0, 609.6, 673.1, 711.2}; }; - class ACE_338_Ball_API526 : B_338_Ball { + class ACE_338_Ball_API526: B_338_Ball { timeToLive=10; airFriction=-0.0006922; caliber=2.8; @@ -489,11 +624,12 @@ class CfgAmmo { ACE_dragModel=7; ACE_muzzleVelocities[]={880, 895, 900}; ACE_barrelLengths[]={508.0, 685.8, 711.2}; + EGVAR(vehicle_damage,incendiary) = 1.0; }; class B_127x33_Ball: BulletBase { tracerScale = 1.3; //1.2; }; - class B_127x54_Ball : BulletBase { + class B_127x54_Ball: BulletBase { airFriction=-0.00019568; tracerScale = 1.3;// ACE_caliber=12.954; @@ -507,7 +643,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={300}; ACE_barrelLengths[]={436.88}; }; - class B_127x99_Ball : BulletBase { + class B_127x99_Ball: BulletBase { timeToLive=10; airFriction=-0.00058679; tracerScale = 1.3; //1.2; @@ -523,7 +659,7 @@ class CfgAmmo { ACE_muzzleVelocities[]={900}; ACE_barrelLengths[]={736.6}; }; - class ACE_127x99_API : B_127x99_Ball { + class ACE_127x99_API: B_127x99_Ball { timeToLive=10; airFriction=-0.00058679; tracerScale = 1.3;// @@ -540,8 +676,9 @@ class CfgAmmo { ACE_dragModel=1; ACE_muzzleVelocities[]={900}; ACE_barrelLengths[]={736.6}; + EGVAR(vehicle_damage,incendiary) = 1.0; }; - class ACE_127x99_Ball_AMAX : B_127x99_Ball { + class ACE_127x99_Ball_AMAX: B_127x99_Ball { timeToLive=10; airFriction=-0.00037397; caliber=3.0; @@ -557,26 +694,36 @@ class CfgAmmo { ACE_muzzleVelocities[]={860}; ACE_barrelLengths[]={736.6}; }; - class B_127x108_Ball : BulletBase { - timeToLive=10; - airFriction=-0.00065098; - tracerScale = 1.3; //1.5; - ACE_caliber=12.979; - ACE_bulletLength=64.008; - ACE_bulletMass=48.276; - 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.63}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={820}; - ACE_barrelLengths[]={728.98}; - }; - class B_127x108_APDS: B_127x108_Ball { - typicalSpeed = 820; + class B_127x108_Ball: BulletBase { + timeToLive = 10; airFriction = -0.00065098; + tracerScale = 1.3; //1.5; + ACE_caliber = 12.979; + ACE_bulletLength = 64.008; + ACE_bulletMass = 48.276; + ACE_ammoTempMuzzleVelocityShifts[] = {-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; // Muzzle Velocity shift 0 at 70°F (21°C), -8m/s at 15°C + ACE_ballisticCoefficients[] = {0.63}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {828}; // muzzle velocity 828 m/s at 21°C (70°F: Temp vs MV chart zero), 820 m/s at 15°C (ASM: 15°C, 999,916 hPa, 78%) according to 5Rnd_127x108_Mag initSpeed + ACE_barrelLengths[] = {730}; // GM6 Lynx barrel length https://gm6lynx.com/ }; - class B_45ACP_Ball : BulletBase { + + class B_127x108_APDS: B_127x108_Ball { + ACE_caliber = 7.13; // Chinese 12.7x108mm APDS (Armour Piercing Discarding Sabot) https://i.imgur.com/8mlXD0e.png + ACE_bulletLength = 34.08; // Chinese 12.7x108mm APDS (Armour Piercing Discarding Sabot) https://i.imgur.com/8mlXD0e.png + ACE_bulletMass = 27.95; // Average value from "Norinco 2017 Weapon Systems", Type 54 12.7x108 mm Tungsten APDS https://i-com.cdn.gaijin.net/monthly_2023_03/image.png.5e6ae14e7b69a610c716872abea1061e.png + ACE_ammoTempMuzzleVelocityShifts[] = {-26.55, -25.47, -22.85, -20.12, -16.98, -12.8, -7.64, -1.53, 5.96, 15.17, 26.19}; // Muzzle Velocity shift 0 at 70°F (21°C), -8m/s at 15°C + ACE_ballisticCoefficients[] = {1.052}; // Compromise based on bullet drops, times of flight and remaining velocities according to vanilla B_127x108_APDS airFriction -0.00036 + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {1068}; // muzzle velocity 1068 m/s at 21°C (70°F: Temp vs MV chart zero), 1060 m/s at 15°C (ICAO: 15°C, 1013.25 hPa, 0%) according to 5Rnd_127x108_APDS_Mag initSpeed + ACE_barrelLengths[] = {730}; // GM6 Lynx barrel length https://gm6lynx.com/ + }; + + class B_45ACP_Ball: BulletBase { airFriction=-0.00082143; tracerScale = 0.6; ACE_caliber=11.481; @@ -590,19 +737,21 @@ class CfgAmmo { ACE_muzzleVelocities[]={230, 250, 285}; ACE_barrelLengths[]={101.6, 127.0, 228.6}; }; - class B_50BW_Ball_F : BulletBase { - airFriction=-0.00205896; - ACE_caliber=12.7; - ACE_bulletLength=24.13; - ACE_bulletMass=21.7076; - 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.21}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={510, 550, 596}; - ACE_barrelLengths[]={304.8, 406.4, 609.6}; + + class B_50BW_Ball_F: BulletBase { // http://www.alexanderarms.com/images/pdfs/beowulf_ballistics.pdf#page=2 + airFriction = -0.002098; // According with the G1 BC 0.21 and the muzzle velocity 1800 ft/s: 549 m/s + ACE_caliber = 4.55; // instead 12.7 to match with the .50BW adv. ballistics (twist rate 20") overwritten by the Katiba rifle twist 8" until a BI fix + ACE_bulletLength = 24.13; + ACE_bulletMass = 21.64; // 334 grains + 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.21}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {550}; // at 21°C, at 15°C 549 m/s according with the 10Rnd_50BW_Mag_F initSpeep + ACE_barrelLengths[] = {304.8}; // 12" }; + class B_570x28_Ball: BulletBase { 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/ diff --git a/addons/ballistics/CfgEventHandlers.hpp b/addons/ballistics/CfgEventHandlers.hpp index 93e3311cf2..865276cfba 100644 --- a/addons/ballistics/CfgEventHandlers.hpp +++ b/addons/ballistics/CfgEventHandlers.hpp @@ -1,11 +1,11 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/ballistics/CfgMagazineWells.hpp b/addons/ballistics/CfgMagazineWells.hpp index 71d553b4ba..be00c64b2f 100644 --- a/addons/ballistics/CfgMagazineWells.hpp +++ b/addons/ballistics/CfgMagazineWells.hpp @@ -1,16 +1,55 @@ class CfgMagazineWells { - - class CBA_65x39_MX { + class CBA_12g_2rnds { ADDON[] = { - "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim", - "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" + "ACE_2Rnd_12Gauge_Pellets_No0_Buck", + "ACE_2Rnd_12Gauge_Pellets_No1_Buck", + "ACE_2Rnd_12Gauge_Pellets_No2_Buck", + "ACE_2Rnd_12Gauge_Pellets_No3_Buck", + "ACE_2Rnd_12Gauge_Pellets_No4_Buck", + "ACE_2Rnd_12Gauge_Pellets_No4_Bird" }; }; - class CBA_65x39_MX_XL { + + class HunterShotgun_01_12GA { //Vanilla magwell + ADDON[] = { + "ACE_2Rnd_12Gauge_Pellets_No0_Buck", + "ACE_2Rnd_12Gauge_Pellets_No1_Buck", + "ACE_2Rnd_12Gauge_Pellets_No2_Buck", + "ACE_2Rnd_12Gauge_Pellets_No3_Buck", + "ACE_2Rnd_12Gauge_Pellets_No4_Buck", + "ACE_2Rnd_12Gauge_Pellets_No4_Bird" + }; + }; + + class UBS_12GA { //Vanilla magwell + ADDON[] = { + "ACE_6Rnd_12Gauge_Pellets_No0_Buck", + "ACE_6Rnd_12Gauge_Pellets_No1_Buck", + "ACE_6Rnd_12Gauge_Pellets_No2_Buck", + "ACE_6Rnd_12Gauge_Pellets_No3_Buck", + "ACE_6Rnd_12Gauge_Pellets_No4_Buck", + "ACE_6Rnd_12Gauge_Pellets_No4_Bird" + }; + }; + + class MX_65x39 { //Vanilla magwell + ADDON[] = { + "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" + }; + }; + + class MX_65x39_Large { //Vanilla magwell ADDON[] = { "ACE_100Rnd_65x39_caseless_mag_Tracer_Dim" }; }; + + class Katiba_65x39 { + ADDON[] = { + "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" + }; + }; + class CBA_65x39_Mk200 { ADDON[] = { "ACE_200Rnd_65x39_cased_Box_Tracer_Dim" @@ -25,12 +64,22 @@ class CfgMagazineWells { "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; }; + + class CBA_556x45_SCAR_EGLM { + ADDON[] = { + "ACE_30Rnd_556x45_Stanag_M995_AP_mag", + "ACE_30Rnd_556x45_Stanag_Mk262_mag", + "ACE_30Rnd_556x45_Stanag_Mk318_mag", + "ACE_30Rnd_556x45_Stanag_Tracer_Dim" + }; + }; + class STANAG_556x45 { //Vanilla magwell ADDON[] = { - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" + "ACE_30Rnd_556x45_Stanag_M995_AP_mag", + "ACE_30Rnd_556x45_Stanag_Mk262_mag", + "ACE_30Rnd_556x45_Stanag_Mk318_mag", + "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; }; @@ -39,6 +88,9 @@ class CfgMagazineWells { "ACE_20Rnd_762x51_Mag_Tracer", "ACE_20Rnd_762x51_Mag_Tracer_Dim", "ACE_20Rnd_762x51_Mag_SD", + "ACE_10Rnd_762x51_Mag_Tracer", + "ACE_10Rnd_762x51_Mag_Tracer_Dim", + "ACE_10Rnd_762x51_Mag_SD", "ACE_10Rnd_762x51_M118LR_Mag", "ACE_10Rnd_762x51_Mk316_Mod_0_Mag", "ACE_10Rnd_762x51_Mk319_Mod_0_Mag", @@ -49,11 +101,15 @@ class CfgMagazineWells { "ACE_20Rnd_762x51_M993_AP_Mag" }; }; + class CBA_762x51_HK417 { ADDON[] = { "ACE_20Rnd_762x51_Mag_Tracer", "ACE_20Rnd_762x51_Mag_Tracer_Dim", "ACE_20Rnd_762x51_Mag_SD", + "ACE_10Rnd_762x51_Mag_Tracer", + "ACE_10Rnd_762x51_Mag_Tracer_Dim", + "ACE_10Rnd_762x51_Mag_SD", "ACE_10Rnd_762x51_M118LR_Mag", "ACE_10Rnd_762x51_Mk316_Mod_0_Mag", "ACE_10Rnd_762x51_Mk319_Mod_0_Mag", @@ -64,11 +120,15 @@ class CfgMagazineWells { "ACE_20Rnd_762x51_M993_AP_Mag" }; }; + class CBA_762x51_SR25 { ADDON[] = { "ACE_20Rnd_762x51_Mag_Tracer", "ACE_20Rnd_762x51_Mag_Tracer_Dim", "ACE_20Rnd_762x51_Mag_SD", + "ACE_10Rnd_762x51_Mag_Tracer", + "ACE_10Rnd_762x51_Mag_Tracer_Dim", + "ACE_10Rnd_762x51_Mag_SD", "ACE_10Rnd_762x51_M118LR_Mag", "ACE_10Rnd_762x51_Mk316_Mod_0_Mag", "ACE_10Rnd_762x51_Mk319_Mod_0_Mag", @@ -79,11 +139,15 @@ class CfgMagazineWells { "ACE_20Rnd_762x51_M993_AP_Mag" }; }; + class CBA_762x51_G3 { ADDON[] = { "ACE_20Rnd_762x51_Mag_Tracer", "ACE_20Rnd_762x51_Mag_Tracer_Dim", "ACE_20Rnd_762x51_Mag_SD", + "ACE_10Rnd_762x51_Mag_Tracer", + "ACE_10Rnd_762x51_Mag_Tracer_Dim", + "ACE_10Rnd_762x51_Mag_SD", "ACE_10Rnd_762x51_M118LR_Mag", "ACE_10Rnd_762x51_Mk316_Mod_0_Mag", "ACE_10Rnd_762x51_Mk319_Mod_0_Mag", @@ -95,24 +159,23 @@ class CfgMagazineWells { }; }; -//Missing in CBA -//ACE_20Rnd_762x67_Mk248_Mod_0_Mag -//ACE_20Rnd_762x67_Mk248_Mod_1_Mag -//ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag - - class CBA_65C_AR10 { + class MAR10_338 { //Vanilla magwell ADDON[] = { - "ACE_30Rnd_65_Creedmor_mag", - "ACE_20Rnd_65_Creedmor_mag", - "ACE_30Rnd_65x47_Scenar_mag", - "ACE_20Rnd_65x47_Scenar_mag" + "ACE_10Rnd_338_300gr_HPBT_Mag", + "ACE_10Rnd_338_API526_Mag", + "ACE_20Rnd_762x67_Mk248_Mod_0_Mag", + "ACE_20Rnd_762x67_Mk248_Mod_1_Mag", + "ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag", + "ACE_10Rnd_762x67_Mk248_Mod_0_Mag", + "ACE_10Rnd_762x67_Mk248_Mod_1_Mag", + "ACE_10Rnd_762x67_Berger_Hybrid_OTM_Mag" }; }; - class CBA_338LM_AI { //338 Lapua Magnum Accuracy International + class CBA_65C_AR10 { ADDON[] = { - "ACE_10Rnd_338_300gr_HPBT_Mag", - "ACE_10Rnd_338_API526_Mag" + "ACE_20Rnd_65_Creedmor_mag", + "ACE_20Rnd_65x47_Scenar_mag" }; }; @@ -122,7 +185,7 @@ class CfgMagazineWells { }; }; - class CBA_50BMG_M107 { + class CBA_50BMG_AS50 { ADDON[] = { "ACE_5Rnd_127x99_Mag", "ACE_5Rnd_127x99_API_Mag", @@ -130,21 +193,32 @@ class CfgMagazineWells { }; }; + class CBA_50BMG_M107 { + ADDON[] = { + "ACE_10Rnd_127x99_Mag", + "ACE_10Rnd_127x99_API_Mag", + "ACE_10Rnd_127x99_AMAX_Mag" + }; + }; + class CBA_9x19_P226 { // SIG P226 ADDON[] = { "ACE_16Rnd_9x19_mag" }; }; + class CBA_9x19_P228 { // SIG P228 ADDON[] = { "ACE_16Rnd_9x19_mag" }; }; + class CBA_9x19_P239 { // SIG P239 ADDON[] = { "ACE_16Rnd_9x19_mag" }; }; + class CBA_9x19_HiPower { ADDON[] = { "ACE_16Rnd_9x19_mag" @@ -156,10 +230,10 @@ class CfgMagazineWells { "ACE_10Rnd_762x54_Tracer_mag" }; }; + class CBA_762x54R_SVD { ADDON[] = { "ACE_10Rnd_762x54_Tracer_mag" }; }; - }; diff --git a/addons/ballistics/CfgMagazines.hpp b/addons/ballistics/CfgMagazines.hpp index a89cf7022d..4a6abcca01 100644 --- a/addons/ballistics/CfgMagazines.hpp +++ b/addons/ballistics/CfgMagazines.hpp @@ -3,22 +3,145 @@ class CfgMagazines { class CA_Magazine; class VehicleMagazine; - + + class 2Rnd_12Gauge_Pellets: CA_Magazine { + displayName = CSTRING(2Rnd_12Gauge_Pellets_No00_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No00_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No00_Buck_Description); + }; + + class ACE_2Rnd_12Gauge_Pellets_No0_Buck: 2Rnd_12Gauge_Pellets { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(2Rnd_12Gauge_Pellets_No0_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No0_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No0_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No0_Buck"; + }; + + class ACE_2Rnd_12Gauge_Pellets_No1_Buck: ACE_2Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(2Rnd_12Gauge_Pellets_No1_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No1_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No1_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No1_Buck"; + }; + + class ACE_2Rnd_12Gauge_Pellets_No2_Buck: ACE_2Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(2Rnd_12Gauge_Pellets_No2_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No2_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No2_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No2_Buck"; + }; + + class ACE_2Rnd_12Gauge_Pellets_No3_Buck: ACE_2Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(2Rnd_12Gauge_Pellets_No3_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No3_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No3_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No3_Buck"; + }; + + class ACE_2Rnd_12Gauge_Pellets_No4_Buck: ACE_2Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(2Rnd_12Gauge_Pellets_No4_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No4_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No4_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No4_Buck"; + }; + + class ACE_2Rnd_12Gauge_Pellets_No4_Bird: ACE_2Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(2Rnd_12Gauge_Pellets_No4_Bird_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No4_Bird_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No4_Bird_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No4_Bird"; + }; + + class 6Rnd_12Gauge_Pellets: 2Rnd_12Gauge_Pellets { + displayName = CSTRING(6Rnd_12Gauge_Pellets_No00_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No00_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No00_Buck_Description); + }; + + class ACE_6Rnd_12Gauge_Pellets_No0_Buck: 6Rnd_12Gauge_Pellets { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(6Rnd_12Gauge_Pellets_No0_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No0_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No0_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No0_Buck"; + }; + + class ACE_6Rnd_12Gauge_Pellets_No1_Buck: ACE_6Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(6Rnd_12Gauge_Pellets_No1_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No1_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No1_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No1_Buck"; + }; + + class ACE_6Rnd_12Gauge_Pellets_No2_Buck: ACE_6Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(6Rnd_12Gauge_Pellets_No2_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No2_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No2_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No2_Buck"; + }; + + class ACE_6Rnd_12Gauge_Pellets_No3_Buck: ACE_6Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(6Rnd_12Gauge_Pellets_No3_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No3_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No3_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No3_Buck"; + }; + + class ACE_6Rnd_12Gauge_Pellets_No4_Buck: ACE_6Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(6Rnd_12Gauge_Pellets_No4_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No4_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No4_Buck_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No4_Buck"; + }; + + class ACE_6Rnd_12Gauge_Pellets_No4_Bird: ACE_6Rnd_12Gauge_Pellets_No0_Buck { + displayName = CSTRING(6Rnd_12Gauge_Pellets_No4_Bird_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No4_Bird_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No4_Bird_Description); + ammo = "ACE_12Gauge_Pellets_Submunition_No4_Bird"; + }; + + class 15Rnd_12Gauge_Pellets: 6Rnd_12Gauge_Pellets { + displayName = CSTRING(15Rnd_12Gauge_Pellets_No00_Buck_Name); + displayNameShort = CSTRING(12Gauge_Pellets_No00_Buck_NameShort); + descriptionShort = CSTRING(12Gauge_Pellets_No00_Buck_Description); + }; + class 30Rnd_580x42_Mag_F: CA_Magazine { initSpeed = 950; }; + class 20Rnd_650x39_Cased_Mag_F: CA_Magazine { initSpeed = 806; }; + + class ACE_10Rnd_580x42_DBP88_Mag: 20Rnd_650x39_Cased_Mag_F { + author = ECSTRING(common,ACETeam); + ammo = "ACE_580x42_DBP88_Ball"; + count = 10; // https://en.wikipedia.org/wiki/QBU-88 + initSpeed = 895; // according with the ACE_ammoTempMuzzleVelocityShifts at the ICAO conditions (15°C) + mass = 6; + displayName = CSTRING(10Rnd_580x42_DBP88_Mag_Name); + displayNameShort = CSTRING(10Rnd_580x42_DBP88_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_580x42_DBP88_Mag_Description); + }; + class 30Rnd_65x39_caseless_mag: CA_Magazine { initSpeed = 774; }; + class 30Rnd_65x39_caseless_black_mag; + class 30Rnd_65x39_caseless_khaki_mag; + class 30Rnd_65x39_caseless_msbs_mag; + class 30Rnd_65x39_caseless_green: 30Rnd_65x39_caseless_mag { initSpeed = 788; }; + class 100Rnd_65x39_caseless_mag: CA_Magazine { initSpeed = 774; }; + class 100Rnd_65x39_caseless_mag_Tracer; class ACE_100Rnd_65x39_caseless_mag_Tracer_Dim: 100Rnd_65x39_caseless_mag_Tracer { author = ECSTRING(common,ACETeam); @@ -28,9 +151,11 @@ class CfgMagazines { descriptionShort = CSTRING(100Rnd_65x39_caseless_mag_Tracer_DimDescription); picture = "\A3\weapons_f\data\ui\m_100rnd_65x39_yellow_ca.paa"; }; + class 200Rnd_65x39_cased_Box: 100Rnd_65x39_caseless_mag { initSpeed = 743; }; + class ACE_200Rnd_65x39_cased_Box_Tracer_Dim: 200Rnd_65x39_cased_Box { author = ECSTRING(common,ACETeam); ammo = "ACE_65x39_Caseless_Tracer_Dim"; @@ -40,6 +165,7 @@ class CfgMagazines { picture = "\A3\weapons_f\data\ui\m_200rnd_65x39_yellow_ca.paa"; initSpeed = 774; }; + class 30Rnd_65x39_caseless_mag_Tracer; class ACE_30Rnd_65x39_caseless_mag_Tracer_Dim: 30Rnd_65x39_caseless_mag_Tracer { author = ECSTRING(common,ACETeam); @@ -48,6 +174,7 @@ class CfgMagazines { displayNameShort = CSTRING(30Rnd_65x39_caseless_mag_Tracer_DimNameShort); descriptionShort = CSTRING(30Rnd_65x39_caseless_mag_Tracer_DimDescription); }; + class 30Rnd_65x39_caseless_green_mag_Tracer; class ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim: 30Rnd_65x39_caseless_green_mag_Tracer { author = ECSTRING(common,ACETeam); @@ -58,27 +185,33 @@ 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 { initSpeed = 909; }; + class 30Rnd_556x45_Stanag_green: 30Rnd_556x45_Stanag { initSpeed = 869; }; + class 30Rnd_556x45_Stanag_red: 30Rnd_556x45_Stanag { initSpeed = 869; }; + class 30Rnd_556x45_Stanag_Tracer_Red: 30Rnd_556x45_Stanag { initSpeed = 869; }; + class 30Rnd_556x45_Stanag_Tracer_Green: 30Rnd_556x45_Stanag { initSpeed = 869; }; + class 30Rnd_556x45_Stanag_Tracer_Yellow: 30Rnd_556x45_Stanag { initSpeed = 889; }; + class ACE_30Rnd_556x45_Stanag_M995_AP_mag: 30Rnd_556x45_Stanag { author = ECSTRING(common,ACETeam); ammo = "ACE_556x45_Ball_M995_AP"; @@ -87,6 +220,7 @@ class CfgMagazines { descriptionShort = CSTRING(30Rnd_556x45_Stanag_M995_AP_mag_Description); initSpeed = 875; }; + class ACE_30Rnd_556x45_Stanag_Mk262_mag: 30Rnd_556x45_Stanag { author = ECSTRING(common,ACETeam); ammo = "ACE_556x45_Ball_Mk262"; @@ -95,6 +229,7 @@ class CfgMagazines { descriptionShort = CSTRING(30Rnd_556x45_Stanag_Mk262_mag_Description); initSpeed = 832; }; + class ACE_30Rnd_556x45_Stanag_Mk318_mag: 30Rnd_556x45_Stanag { author = ECSTRING(common,ACETeam); ammo = "ACE_556x45_Ball_Mk318"; @@ -103,38 +238,45 @@ class CfgMagazines { descriptionShort = CSTRING(30Rnd_556x45_Stanag_Mk318_mag_Description); initSpeed = 923; }; + class ACE_30Rnd_556x45_Stanag_Tracer_Dim: 30Rnd_556x45_Stanag_Tracer_Red { author = ECSTRING(common,ACETeam); ammo = "ACE_B_556x45_Ball_Tracer_Dim"; displayName = CSTRING(30Rnd_556x45_mag_Tracer_DimName); displayNameShort = CSTRING(30Rnd_556x45_mag_Tracer_DimNameShort); descriptionShort = CSTRING(30Rnd_556x45_mag_Tracer_DimDescription); - picture = "\A3\weapons_f\data\ui\m_20stanag_red_ca.paa"; }; class 200Rnd_556x45_Box_F: CA_Magazine { initSpeed = 889; }; + class 200Rnd_556x45_Box_Red_F: 200Rnd_556x45_Box_F { initSpeed = 869; }; - + 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 { initSpeed = 827; }; + + class 10Rnd_Mk14_762x51_Mag; + class 10Rnd_762x51_Mag: 20Rnd_762x51_Mag { initSpeed = 833; }; + class 150Rnd_762x51_Box: CA_Magazine { initSpeed = 833; }; + class 150Rnd_762x51_Box_Tracer: 150Rnd_762x51_Box { initSpeed = 833; }; + class ACE_20Rnd_762x51_Mag_Tracer: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "B_762x51_Tracer_Red"; @@ -161,7 +303,33 @@ class CfgMagazines { initSpeed = 330; }; - class ACE_10Rnd_762x51_M118LR_Mag: 10Rnd_762x51_Mag { + class ACE_10Rnd_762x51_Mag_Tracer: 10Rnd_Mk14_762x51_Mag { + author = ECSTRING(common,ACETeam); + ammo = "B_762x51_Tracer_Red"; + displayName = CSTRING(10Rnd_762x51_mag_TracerName); + displayNameShort = CSTRING(10Rnd_762x51_mag_TracerNameShort); + descriptionShort = CSTRING(10Rnd_762x51_mag_TracerDescription); + tracersEvery = 1; + }; + + class ACE_10Rnd_762x51_Mag_Tracer_Dim: ACE_10Rnd_762x51_Mag_Tracer { + author = ECSTRING(common,ACETeam); + ammo = "ACE_B_762x51_Tracer_Dim"; + displayName = CSTRING(10Rnd_762x51_mag_Tracer_DimName); + displayNameShort = CSTRING(10Rnd_762x51_mag_Tracer_DimNameShort); + descriptionShort = CSTRING(10Rnd_762x51_mag_Tracer_DimDescription); + }; + + class ACE_10Rnd_762x51_Mag_SD: 10Rnd_Mk14_762x51_Mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_762x51_Ball_Subsonic"; + displayName = CSTRING(10Rnd_762x51_mag_SDName); + displayNameShort = CSTRING(10Rnd_762x51_mag_SDNameShort); + descriptionShort = CSTRING(10Rnd_762x51_mag_SDDescription); + initSpeed = 330; + }; + + class ACE_10Rnd_762x51_M118LR_Mag: 10Rnd_Mk14_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_M118LR"; count = 10; @@ -170,7 +338,8 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_762x51_M118LR_Mag_Description); initSpeed = 780; }; - class ACE_10Rnd_762x51_Mk316_Mod_0_Mag: 10Rnd_762x51_Mag { + + class ACE_10Rnd_762x51_Mk316_Mod_0_Mag: 10Rnd_Mk14_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_Mk316_Mod_0"; count = 10; @@ -179,7 +348,8 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_762x51_Mk316_Mod_0_Mag_Description); initSpeed = 790; }; - class ACE_10Rnd_762x51_Mk319_Mod_0_Mag: 10Rnd_762x51_Mag { + + class ACE_10Rnd_762x51_Mk319_Mod_0_Mag: 10Rnd_Mk14_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_Mk319_Mod_0"; count = 10; @@ -188,7 +358,8 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_762x51_Mk319_Mod_0_Mag_Description); initSpeed = 900; }; - class ACE_10Rnd_762x51_M993_AP_Mag: 10Rnd_762x51_Mag { + + class ACE_10Rnd_762x51_M993_AP_Mag: 10Rnd_Mk14_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_M993_AP"; count = 10; @@ -197,6 +368,7 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_762x51_M993_AP_Mag_Description); initSpeed = 920; }; + class ACE_20Rnd_762x51_M118LR_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_M118LR"; @@ -205,6 +377,7 @@ class CfgMagazines { descriptionShort = CSTRING(20Rnd_762x51_M118LR_Mag_Description); initSpeed = 785; }; + class ACE_20Rnd_762x51_Mk316_Mod_0_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_Mk316_Mod_0"; @@ -214,6 +387,7 @@ class CfgMagazines { descriptionShort = CSTRING(20Rnd_762x51_Mk316_Mod_0_Mag_Description); initSpeed = 798; }; + class ACE_20Rnd_762x51_Mk319_Mod_0_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_Mk319_Mod_0"; @@ -222,6 +396,7 @@ class CfgMagazines { descriptionShort = CSTRING(20Rnd_762x51_Mk319_Mod_0_Mag_Description); initSpeed = 910; }; + class ACE_20Rnd_762x51_M993_AP_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x51_Ball_M993_AP"; @@ -231,30 +406,7 @@ class CfgMagazines { descriptionShort = CSTRING(20Rnd_762x51_M993_AP_Mag_Description); initSpeed = 930; }; - class ACE_20Rnd_762x67_Mk248_Mod_0_Mag: 20Rnd_762x51_Mag { - author = ECSTRING(common,ACETeam); - ammo = "ACE_762x67_Ball_Mk248_Mod_0"; - displayName = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_Name); - displayNameShort = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_NameShort); - descriptionShort = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_Description); - initSpeed = 865; - }; - class ACE_20Rnd_762x67_Mk248_Mod_1_Mag: 20Rnd_762x51_Mag { - author = ECSTRING(common,ACETeam); - ammo = "ACE_762x67_Ball_Mk248_Mod_1"; - displayName = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_Name); - displayNameShort = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_NameShort); - descriptionShort = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_Description); - initSpeed = 847; - }; - class ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag: 20Rnd_762x51_Mag { - author = ECSTRING(common,ACETeam); - ammo = "ACE_762x67_Ball_Berger_Hybrid_OTM"; - displayName = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_Name); - displayNameShort = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_NameShort); - descriptionShort = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_Description); - initSpeed = 800; - }; + class ACE_30Rnd_65x47_Scenar_mag: 30Rnd_65x39_caseless_mag { author = ECSTRING(common,ACETeam); ammo = "ACE_65x47_Ball_Scenar"; @@ -263,6 +415,23 @@ class CfgMagazines { displayNameShort = CSTRING(30Rnd_65x47_Scenar_mag_NameShort); descriptionShort = CSTRING(30Rnd_65x47_Scenar_mag_Description); }; + class ACE_30Rnd_65x47_Scenar_black_mag: 30Rnd_65x39_caseless_black_mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65x47_Ball_Scenar"; + initSpeed = 826; + displayName = CSTRING(30Rnd_65x47_Scenar_black_mag_Name); + displayNameShort = CSTRING(30Rnd_65x47_Scenar_mag_NameShort); + descriptionShort = CSTRING(30Rnd_65x47_Scenar_mag_Description); + }; + class ACE_30Rnd_65x47_Scenar_khaki_mag: 30Rnd_65x39_caseless_khaki_mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65x47_Ball_Scenar"; + initSpeed = 826; + displayName = CSTRING(30Rnd_65x47_Scenar_khaki_mag_Name); + displayNameShort = CSTRING(30Rnd_65x47_Scenar_mag_NameShort); + descriptionShort = CSTRING(30Rnd_65x47_Scenar_mag_Description); + }; + class ACE_20Rnd_65x47_Scenar_mag: 20Rnd_650x39_Cased_Mag_F { author = ECSTRING(common,ACETeam); ammo = "ACE_65x47_Ball_Scenar"; @@ -271,6 +440,16 @@ class CfgMagazines { displayNameShort = CSTRING(20Rnd_65x47_Scenar_mag_NameShort); descriptionShort = CSTRING(20Rnd_65x47_Scenar_mag_Description); }; + + class ACE_30Rnd_65x47_Scenar_msbs_mag: 30Rnd_65x39_caseless_msbs_mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65x47_Ball_Scenar"; + initSpeed = 826; + displayName = CSTRING(30Rnd_65x47_Scenar_msbs_mag_Name); + displayNameShort = CSTRING(30Rnd_65x47_Scenar_mag_NameShort); + descriptionShort = CSTRING(30Rnd_65x47_Scenar_msbs_mag_Description); + }; + class ACE_30Rnd_65_Creedmor_mag: 30Rnd_65x39_caseless_mag { author = ECSTRING(common,ACETeam); ammo = "ACE_65_Creedmor_Ball"; @@ -279,6 +458,23 @@ class CfgMagazines { displayNameShort = CSTRING(30Rnd_65_Creedmor_mag_NameShort); descriptionShort = CSTRING(30Rnd_65_Creedmor_mag_Description); }; + class ACE_30Rnd_65_Creedmor_black_mag: 30Rnd_65x39_caseless_black_mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65_Creedmor_Ball"; + initSpeed = 857; + displayName = CSTRING(30Rnd_65_Creedmor_black_mag_Name); + displayNameShort = CSTRING(30Rnd_65_Creedmor_mag_NameShort); + descriptionShort = CSTRING(30Rnd_65_Creedmor_mag_Description); + }; + class ACE_30Rnd_65_Creedmor_khaki_mag: 30Rnd_65x39_caseless_khaki_mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65_Creedmor_Ball"; + initSpeed = 857; + displayName = CSTRING(30Rnd_65_Creedmor_khaki_mag_Name); + displayNameShort = CSTRING(30Rnd_65_Creedmor_mag_NameShort); + descriptionShort = CSTRING(30Rnd_65_Creedmor_mag_Description); + }; + class ACE_20Rnd_65_Creedmor_mag: 20Rnd_650x39_Cased_Mag_F { author = ECSTRING(common,ACETeam); ammo = "ACE_65_Creedmor_Ball"; @@ -287,9 +483,20 @@ class CfgMagazines { displayNameShort = CSTRING(20Rnd_65_Creedmor_mag_NameShort); descriptionShort = CSTRING(20Rnd_65_Creedmor_mag_Description); }; + + class ACE_30Rnd_65_Creedmor_msbs_mag: 30Rnd_65x39_caseless_msbs_mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65_Creedmor_Ball"; + initSpeed = 857; + displayName = CSTRING(30Rnd_65_Creedmor_msbs_mag_Name); + displayNameShort = CSTRING(30Rnd_65_Creedmor_mag_NameShort); + descriptionShort = CSTRING(30Rnd_65_Creedmor_msbs_mag_Description); + }; + class 10Rnd_338_Mag: CA_Magazine { initSpeed = 880; }; + class ACE_10Rnd_338_300gr_HPBT_Mag: 10Rnd_338_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_338_Ball"; @@ -298,6 +505,7 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_338_300gr_HPBT_Mag_Description); initSpeed = 800; }; + class ACE_10Rnd_338_API526_Mag: 10Rnd_338_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_338_Ball_API526"; @@ -306,10 +514,74 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_338_API526_Mag_Description); initSpeed = 880; }; - + + class ACE_20Rnd_762x67_Mk248_Mod_0_Mag: 10Rnd_338_Mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_762x67_Ball_Mk248_Mod_0"; + count = 20; + scope = 1; // backwards compatibility only + mass = 28; // 10Rnd_338_Mag mass * 2 + displayName = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_Name); + displayNameShort = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_NameShort); + descriptionShort = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_Description); + initSpeed = 865; + }; + + class ACE_20Rnd_762x67_Mk248_Mod_1_Mag: 10Rnd_338_Mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_762x67_Ball_Mk248_Mod_1"; + count = 20; + scope = 1; + mass = 28; + displayName = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_Name); + displayNameShort = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_NameShort); + descriptionShort = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_Description); + initSpeed = 847; + }; + + class ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag: 10Rnd_338_Mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_762x67_Ball_Berger_Hybrid_OTM"; + count = 20; + scope = 1; + mass = 28; + displayName = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_Name); + displayNameShort = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_NameShort); + descriptionShort = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_Description); + initSpeed = 800; + }; + + class ACE_10Rnd_762x67_Mk248_Mod_0_Mag: ACE_20Rnd_762x67_Mk248_Mod_0_Mag { + scope = 2; + count = 10; + mass = 14; // same as 10Rnd_338_Mag + displayName = CSTRING(10Rnd_762x67_Mk248_Mod_0_Mag_Name); + displayNameShort = CSTRING(10Rnd_762x67_Mk248_Mod_0_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_762x67_Mk248_Mod_0_Mag_Description); + }; + + class ACE_10Rnd_762x67_Mk248_Mod_1_Mag: ACE_20Rnd_762x67_Mk248_Mod_1_Mag { + scope = 2; + count = 10; + mass = 14; + displayName = CSTRING(10Rnd_762x67_Mk248_Mod_1_Mag_Name); + displayNameShort = CSTRING(10Rnd_762x67_Mk248_Mod_1_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_762x67_Mk248_Mod_1_Mag_Description); + }; + + class ACE_10Rnd_762x67_Berger_Hybrid_OTM_Mag: ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag { + scope = 2; + count = 10; + mass = 14; + displayName = CSTRING(10Rnd_762x67_Berger_Hybrid_OTM_Mag_Name); + displayNameShort = CSTRING(10Rnd_762x67_Berger_Hybrid_OTM_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_762x67_Berger_Hybrid_OTM_Mag_Description); + }; + class 7Rnd_408_Mag: CA_Magazine { initSpeed = 867; }; + class ACE_7Rnd_408_305gr_Mag: 7Rnd_408_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_408_Ball"; @@ -320,57 +592,82 @@ class CfgMagazines { }; class 5Rnd_127x108_Mag; - class 5Rnd_127x108_APDS_Mag: 5Rnd_127x108_Mag { - initSpeed = 820; - }; class ACE_5Rnd_127x99_Mag: 5Rnd_127x108_Mag { author = ECSTRING(common,ACETeam); ammo = "B_127x99_Ball"; displayName = CSTRING(5Rnd_127x99_Mag_Name); - displayNameShort = CSTRING(5Rnd_127x99_Mag_NameShort); + displayNameShort = CSTRING(127x99_Mag_NameShort); descriptionShort = CSTRING(5Rnd_127x99_Mag_Description); initSpeed = 900; }; + class ACE_5Rnd_127x99_API_Mag: 5Rnd_127x108_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_127x99_API"; displayName = CSTRING(5Rnd_127x99_API_Mag_Name); - displayNameShort = CSTRING(5Rnd_127x99_API_Mag_NameShort); + displayNameShort = CSTRING(127x99_API_Mag_NameShort); descriptionShort = CSTRING(5Rnd_127x99_API_Mag_Description); initSpeed = 900; }; + class ACE_5Rnd_127x99_AMAX_Mag: 5Rnd_127x108_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_127x99_Ball_AMAX"; displayName = CSTRING(5Rnd_127x99_AMAX_Mag_Name); - displayNameShort = CSTRING(5Rnd_127x99_AMAX_Mag_NameShort); + displayNameShort = CSTRING(127x99_AMAX_Mag_NameShort); descriptionShort = CSTRING(5Rnd_127x99_AMAX_Mag_Description); initSpeed = 860; }; + class ACE_10Rnd_127x99_Mag: ACE_5Rnd_127x99_Mag { + count = 10; + mass = 32; // 5Rnd_127x108_Mag mass * 2 + displayName = CSTRING(10Rnd_127x99_Mag_Name); + displayNameShort = CSTRING(127x99_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_127x99_Mag_Description); + }; + + class ACE_10Rnd_127x99_API_Mag: ACE_5Rnd_127x99_API_Mag { + count = 10; + mass = 32; + displayName = CSTRING(10Rnd_127x99_API_Mag_Name); + displayNameShort = CSTRING(127x99_API_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_127x99_API_Mag_Description); + }; + + class ACE_10Rnd_127x99_AMAX_Mag: ACE_5Rnd_127x99_AMAX_Mag { + count = 10; + mass = 32; + displayName = CSTRING(10Rnd_127x99_AMAX_Mag_Name); + displayNameShort = CSTRING(127x99_AMAX_Mag_NameShort); + descriptionShort = CSTRING(10Rnd_127x99_AMAX_Mag_Description); + }; class 30Rnd_9x21_Mag: CA_Magazine { initSpeed = 430; }; + class 30Rnd_9x21_Green_Mag: 30Rnd_9x21_Mag { initSpeed = 402; }; + class 30Rnd_9x21_Mag_SMG_02: 30Rnd_9x21_Mag { initSpeed = 430; }; + class 30Rnd_9x21_Mag_SMG_02_Tracer_Green: 30Rnd_9x21_Mag_SMG_02 { initSpeed = 402; }; class 10Rnd_50BW_Mag_F: CA_Magazine { - initSpeed = 552; + initSpeed = 549; // according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C) }; class 11Rnd_45ACP_Mag: CA_Magazine { initSpeed = 254; }; - class 6Rnd_45ACP_Cylinder : 11Rnd_45ACP_Mag { + class 6Rnd_45ACP_Cylinder: 11Rnd_45ACP_Mag { initSpeed = 254; }; @@ -389,9 +686,11 @@ class CfgMagazines { class 16Rnd_9x21_Mag: 30Rnd_9x21_Mag { initSpeed = 430; }; + class 10Rnd_9x21_Mag: 16Rnd_9x21_Mag { initSpeed = 430; }; + class ACE_16Rnd_9x19_mag: 16Rnd_9x21_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_9x19_Ball"; @@ -404,6 +703,7 @@ class CfgMagazines { class 10Rnd_762x54_Mag: 10Rnd_762x51_Mag { initSpeed = 836; }; + class ACE_10Rnd_762x54_Tracer_mag: 10Rnd_762x54_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_762x54_Ball_7T2"; @@ -421,27 +721,28 @@ class CfgMagazines { class 10Rnd_127x54_Mag: CA_Magazine { initSpeed = 300; }; - + class 150Rnd_556x45_Drum_Mag_F: CA_Magazine { initSpeed = 869; }; - + class 130Rnd_338_Mag: CA_Magazine { initSpeed = 807; }; - + class 200Rnd_65x39_Belt: VehicleMagazine { initSpeed = 806; }; - + class 20Rnd_556x45_UW_mag: 30Rnd_556x45_Stanag { initSpeed = 267; }; - + class 150Rnd_93x64_Mag: CA_Magazine { - initSpeed = 870; + initSpeed = 768; // according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C) }; + class 10Rnd_93x64_DMR_05_Mag: 150Rnd_93x64_Mag { - initSpeed = 870; + initSpeed = 780; // according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C) }; }; diff --git a/addons/ballistics/CfgVehicles.hpp b/addons/ballistics/CfgVehicles.hpp index c6a40301f2..5632507530 100644 --- a/addons/ballistics/CfgVehicles.hpp +++ b/addons/ballistics/CfgVehicles.hpp @@ -13,9 +13,7 @@ class CfgVehicles { class NATO_Box_Base; class Box_NATO_Wps_F: NATO_Box_Base { class TransportMagazines { - MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); }; }; @@ -37,9 +35,7 @@ class CfgVehicles { class Box_NATO_Ammo_F: NATO_Box_Base { class TransportMagazines { - MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x51_M118LR_Mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_M118LR_Mag,4); @@ -83,9 +79,7 @@ class CfgVehicles { class ReammoBox_F; class B_supplyCrate_F: ReammoBox_F { class TransportMagazines { - MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x51_M118LR_Mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_M118LR_Mag,4); @@ -102,10 +96,9 @@ class CfgVehicles { class Box_East_Wps_F: EAST_Box_Base { class TransportMagazines { MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_580x42_DBP88_Mag,4); }; }; @@ -114,30 +107,27 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_30Rnd_556x45_Stanag_Tracer_Dim,1); MACRO_ADDMAGAZINE(ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_580x42_DBP88_Mag,4); }; }; class Box_East_Ammo_F: EAST_Box_Base { class TransportMagazines { MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_580x42_DBP88_Mag,4); }; }; class Box_East_Support_F: EAST_Box_Base { class TransportMagazines { MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); - MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_580x42_DBP88_Mag,4); }; }; @@ -199,9 +189,7 @@ class CfgVehicles { class C_supplyCrate_F: ReammoBox_F { class TransportMagazines { - MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); - MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); }; }; @@ -211,6 +199,7 @@ class CfgVehicles { accuracy = 1000; displayName = CSTRING(AmmoSupplyCrate_DisplayName); model = "\A3\weapons_F\AmmoBoxes\AmmoBox_F"; + editorPreview = "\A3\EditorPreviews_F\Data\CfgVehicles\Box_NATO_Ammo_F.jpg"; author = ECSTRING(common,ACETeam); class TransportMagazines { MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_Mag_SD,4); @@ -228,6 +217,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_20Rnd_762x67_Mk248_Mod_1_Mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_580x42_DBP88_Mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_556x45_Stanag_M995_AP_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_556x45_Stanag_Mk262_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_556x45_Stanag_Mk318_mag,4); @@ -238,14 +228,19 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_200Rnd_65x39_cased_Box_Tracer_Dim,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_msbs_mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); + MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_msbs_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_300gr_HPBT_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_API526_Mag,4); MACRO_ADDMAGAZINE(ACE_7Rnd_408_305gr_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_API_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_AMAX_Mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_127x99_Mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_127x99_API_Mag,4); + MACRO_ADDMAGAZINE(ACE_10Rnd_127x99_AMAX_Mag,4); }; class AnimationSources { class Ammo_source { diff --git a/addons/ballistics/CfgWeapons.hpp b/addons/ballistics/CfgWeapons.hpp index 2616015e7d..024b6a6343 100644 --- a/addons/ballistics/CfgWeapons.hpp +++ b/addons/ballistics/CfgWeapons.hpp @@ -1,834 +1,474 @@ -class Mode_SemiAuto; -class Mode_Burst; -class Mode_FullAuto; - class CfgWeapons { - class LMG_RCWS; - class MGun; - class MGunCore; - class MMG_01_base_F; - class MMG_02_base_F; + class HMG_01; + class Pistol_Base_F; class Rifle_Base_F; class Rifle_Short_Base_F: Rifle_Base_F {}; class Rifle_Long_Base_F: Rifle_Base_F {}; + // Rifle_Long_Base_F Sniper Marksman // GM6 Lynx - class GM6_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.45); - }; + class GM6_base_F: Rifle_Long_Base_F {}; + class srifle_GM6_F: GM6_base_F { + ACE_barrelLength = 730; // GM6 Lynx barrel length https://gm6lynx.com/ + ACE_barrelTwist = 381.0; + initSpeed = -1.0; + magazineWell[] += { + "CBA_50BMG_AS50" + }; // empty in vanilla }; // M200 Intervention - class LRR_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.50); + class LRR_base_F: Rifle_Long_Base_F {}; + class srifle_LRR_F: LRR_base_F { + ACE_barrelLength = 736.6; + ACE_barrelTwist = 330.2; + initSpeed = -1.0; + magazineWell[] += { + "CBA_408CT_Inter" + }; // vanilla magazineWell[] = {"M320_408"}; + }; + + // Mk14 Mod 1 EBR + class EBR_base_F: Rifle_Long_Base_F {}; + class srifle_EBR_F: EBR_base_F { + ACE_barrelLength = 457.2; + ACE_barrelTwist = 304.8; + initSpeed = -0.979444; + }; + + // VS-121 + class DMR_01_base_F: Rifle_Long_Base_F {}; + class srifle_DMR_01_F: DMR_01_base_F { + ACE_barrelLength = 609.6; + ACE_barrelTwist = 241.3; + initSpeed = -1.00019; + }; + + // Noreen "Bad News" ULR + class DMR_02_base_F: Rifle_Long_Base_F {}; + class srifle_DMR_02_F: DMR_02_base_F { + ACE_barrelLength = 508.0; + ACE_barrelTwist = 254.0; + initSpeed = -1.0; + }; + + // SIG 556 + class DMR_03_base_F: Rifle_Long_Base_F {}; + class srifle_DMR_03_F: DMR_03_base_F { + ACE_barrelLength = 508.0; + ACE_barrelTwist = 254.0; + initSpeed = -0.991536; + magazineWell[] += { + "CBA_762x51_SR25" + }; // vanilla magazineWell[] = {"M14_762x51"}; + }; + + // ASP-1 Kir + class DMR_04_base_F: Rifle_Long_Base_F {}; + class srifle_DMR_04_F: DMR_04_base_F { + ACE_barrelLength = 450.088; + ACE_barrelTwist = 203.2; + initSpeed = -1.0; + }; + + // Cyrus + class DMR_05_base_F: Rifle_Long_Base_F {}; + class srifle_DMR_05_blk_F: DMR_05_base_F { + ACE_barrelLength = 620.0; + ACE_barrelTwist = 360.0; + initSpeed = -1.0; // 780 m/s according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C) + }; + + // M14 + class DMR_06_base_F: Rifle_Long_Base_F { + ACE_barrelLength = 558.8; + ACE_barrelTwist = 304.8; + initSpeed = -0.999395; + }; + + // QBU-88 + class DMR_07_base_F: Rifle_Long_Base_F { + ACE_barrelLength = 640.0; + ACE_barrelTwist = 206; // https://en.wikipedia.org/wiki/QBU-88 + initSpeed = -1; + magazines[] += { //No Vanilla magwell + "ACE_20Rnd_65x47_Scenar_mag", + "ACE_20Rnd_65_Creedmor_mag", + "ACE_10Rnd_580x42_DBP88_Mag" + }; + }; + + // Rifle_Long_Base_F MG + // Stoner 99 LMG + class LMG_Mk200_F: Rifle_Long_Base_F { + ACE_barrelLength = 381; + ACE_barrelTwist = 177.8; + initSpeed = -0.999327; + }; + + // Negev NG7 + class LMG_Zafir_F: Rifle_Long_Base_F { + ACE_barrelLength = 459.74; + ACE_barrelTwist = 304.8; + initSpeed = -1.00048; + }; + + // M249 SPW + class LMG_03_base_F: Rifle_Long_Base_F { + ACE_barrelLength = 414.02; + ACE_barrelTwist = 177.8; + initSpeed = -1.00051; + }; + + // HK121 + class MMG_01_base_F: Rifle_Long_Base_F {}; // https://www.heckler-koch.com/en/products/military/machine-guns/mg5/mg5/technical-data.html + class MMG_01_hex_F: MMG_01_base_F { + ACE_barrelLength = 550.0; + ACE_barrelTwist = 360.0; + initSpeed = -1.0; // 768 m/s according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C) + }; + + // LWMMG + class MMG_02_base_F: Rifle_Long_Base_F {}; + class MMG_02_camo_F: MMG_02_base_F { + ACE_barrelLength = 609.6; + ACE_barrelTwist = 234.95; + initSpeed = -1.0; + }; + + // Rifle_Base_F + // MX variants + class arifle_MX_Base_F: Rifle_Base_F {}; + + // MX LSW + class arifle_MX_SW_F: arifle_MX_Base_F { + ACE_barrelLength = 406.4; + ACE_barrelTwist = 228.6; + initSpeed = -0.981912; + }; + + // MXM + class arifle_MXM_F: arifle_MX_Base_F { + ACE_barrelLength = 457.2; + ACE_barrelTwist = 228.6; + initSpeed = -1.0; + magazines[] += { // 6.5C Rechambering, MXM only + "ACE_30Rnd_65_Creedmor_mag", + "ACE_30Rnd_65x47_Scenar_mag", + "ACE_30Rnd_65_Creedmor_black_mag", + "ACE_30Rnd_65_Creedmor_khaki_mag", + "ACE_30Rnd_65x47_Scenar_black_mag", + "ACE_30Rnd_65x47_Scenar_khaki_mag" + }; + }; + class arifle_MXM_Black_F: arifle_MXM_F { // bleh inheritance + magazines[] += { + "ACE_30Rnd_65_Creedmor_mag", + "ACE_30Rnd_65x47_Scenar_mag", + "ACE_30Rnd_65_Creedmor_black_mag", + "ACE_30Rnd_65_Creedmor_khaki_mag", + "ACE_30Rnd_65x47_Scenar_black_mag", + "ACE_30Rnd_65x47_Scenar_khaki_mag" + }; + }; + class arifle_MXM_khk_F: arifle_MXM_Black_F { + magazines[] += { + "ACE_30Rnd_65_Creedmor_mag", + "ACE_30Rnd_65x47_Scenar_mag", + "ACE_30Rnd_65_Creedmor_black_mag", + "ACE_30Rnd_65_Creedmor_khaki_mag", + "ACE_30Rnd_65x47_Scenar_black_mag", + "ACE_30Rnd_65x47_Scenar_khaki_mag" }; }; // MX - class arifle_MX_Base_F: Rifle_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; + class arifle_MX_F: arifle_MX_Base_F { + ACE_barrelLength = 368.3; + ACE_barrelTwist = 228.6; + initSpeed = -0.972222; }; + // MX 3GL + class arifle_MX_GL_F: arifle_MX_Base_F { + ACE_barrelLength = 368.3; + ACE_barrelTwist = 228.6; + initSpeed = -0.972222; + }; + + // MXC + class arifle_MXC_F: arifle_MX_Base_F { + ACE_barrelLength = 266.7; + ACE_barrelTwist = 203.2; + initSpeed = -0.946382; + }; + + // KH2002 Sama variants + class arifle_katiba_Base_F: Rifle_Base_F {}; + // KH2002 Sama - class arifle_katiba_Base_F: Rifle_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; + class arifle_Katiba_F: arifle_katiba_Base_F { + ACE_barrelLength = 508.0; + ACE_barrelTwist = 203.2; + initSpeed = -1.0; }; - // CTAR-21 - class Tavor_base_F: Rifle_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; + // KH2002C Sama + class arifle_Katiba_C_F: arifle_katiba_Base_F { + ACE_barrelLength = 393.7; + ACE_barrelTwist = 203.2; + initSpeed = -0.961294; }; + // KH2002 Sama KGL + class arifle_Katiba_GL_F: arifle_katiba_Base_F { + ACE_barrelLength = 508.0; + ACE_barrelTwist = 203.2; + initSpeed = -1.0; + }; + + // CTAR-21 variants + class Tavor_base_F: Rifle_Base_F {}; + + // CTAR-21 + class arifle_TRG20_F: Tavor_base_F { + ACE_barrelLength = 381.0; + ACE_barrelTwist = 177.8; + initSpeed = -0.961496; + }; + + // TAR-21 + class arifle_TRG21_F: Tavor_base_F { + ACE_barrelLength = 459.74; + ACE_barrelTwist = 177.8; + initSpeed = -1.0; + }; + + // TAR-21 EGLM + class arifle_TRG21_GL_F: arifle_TRG21_F { + initSpeed = -1.0; + }; + + // F2000 variants + class mk20_base_F: Rifle_Base_F {}; + // F2000 - class mk20_base_F: Rifle_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; + class arifle_Mk20_F: mk20_base_F { + ACE_barrelLength = 441.96; + ACE_barrelTwist = 177.8; + initSpeed = -0.992849; }; - // P90 (1.86) + // F2000 Tactical + class arifle_Mk20C_F: mk20_base_F { + ACE_barrelLength = 406.4; + ACE_barrelTwist = 177.8; + initSpeed = -0.974297; + }; + + // F2000 EGLM + class arifle_Mk20_GL_F: mk20_base_F { + ACE_barrelLength = 406.4; + ACE_barrelTwist = 177.8; + initSpeed = -0.974297; + }; + + // P90 (1.86) variants class SMG_03_TR_BASE: Rifle_Base_F { - ACE_barrelTwist = 228.6; // 1:9 inch twist ACE_barrelLength = 407; - ACE_twistDirection = 1; + ACE_barrelTwist = 228.6; // 1:9 inch twist 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 { ACE_barrelLength = 264; modes[] = {"Single", "FullAuto"}; }; - // Noreen "Bad News" ULR - class DMR_02_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.61); - }; - }; - - // VS-121 - class DMR_01_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.81); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.81); - }; - }; - - // Mk14 Mod 1 EBR - class EBR_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.81); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.81); - }; - }; - - // SIG 556 - class DMR_03_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.81); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.81); - }; - }; - - // ASP-1 Kir - class DMR_04_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.0); - }; - }; - - // Cyrus - class DMR_05_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.67); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.67); - }; - }; - - // M14 - class DMR_06_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.81); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.81); - }; - }; - - // MX LSW - class arifle_MX_SW_F: arifle_MX_Base_F { - magazines[] = { - "100Rnd_65x39_caseless_mag_Tracer", - "100Rnd_65x39_caseless_mag", - "30Rnd_65x39_caseless_mag", - "30Rnd_65x39_caseless_mag_Tracer", - "ACE_100Rnd_65x39_caseless_mag_Tracer_Dim", - "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" - }; - initSpeed = -0.981912; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 406.4; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; - }; - - // MXM - class arifle_MXM_F: arifle_MX_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_mag", - "30Rnd_65x39_caseless_mag_Tracer", - "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim", - "ACE_30Rnd_65x47_Scenar_mag", - "ACE_30Rnd_65_Creedmor_mag" - }; - initSpeed = -1.0; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 457.2; - class Single: Single { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; - }; - + // HK416 variants // HK416A5 11" class arifle_SPAR_01_base_F: Rifle_Base_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_green", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -0.869636; - ACE_barrelTwist = 177.8; ACE_barrelLength = 264.0; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; + ACE_barrelTwist = 177.8; + initSpeed = -0.869636; }; // HK416A5 14.5" class arifle_SPAR_02_base_F: Rifle_Base_F { - initSpeed = -0.999864; - ACE_barrelTwist = 177.8; ACE_barrelLength = 368.0; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; + ACE_barrelTwist = 177.8; + initSpeed = -0.999864; }; // HK417A2 20" class arifle_SPAR_03_base_F: Rifle_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.991536; - ACE_barrelTwist = 279.4; ACE_barrelLength = 508.0; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.81); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.81); - }; - }; - - // 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; - }; - - // Negev NG7 - class LMG_Zafir_F: Rifle_Long_Base_F { - initSpeed = -1.00048; - ACE_barrelTwist = 304.8; - ACE_barrelLength = 459.74; - }; - - // M249 SPW - class LMG_03_base_F: Rifle_Long_Base_F { - initSpeed = -1.00051; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 414.02; + ACE_barrelTwist = 279.4; + initSpeed = -0.991536; }; // RFB SDAR - class SDAR_base_F: Rifle_Base_F { - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(3.0); - }; - - class Burst: Mode_Burst { - dispersion = MOA_TO_RAD(3.0); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(3.0); - }; - }; - - class Pistol; - class Pistol_Base_F: Pistol {}; - - // P99 - class hgun_P07_F: Pistol_Base_F { - initSpeed = -0.906977; - ACE_barrelTwist = 254.0; - ACE_barrelLength = 101.6; - }; - - // MP-443 Grach - class hgun_Rook40_F: Pistol_Base_F { - initSpeed = -0.934884; - ACE_barrelTwist = 254.0; - ACE_barrelLength = 111.76; - }; - - // Custom Covert II - class hgun_ACPC2_F: Pistol_Base_F { - initSpeed = -0.984252; - ACE_barrelTwist = 406.4; - ACE_barrelLength = 127.0; - }; - - // FNX-45 Tactical - class hgun_Pistol_heavy_01_F: Pistol_Base_F { - initSpeed = -0.944882; - ACE_barrelTwist = 406.4; - ACE_barrelLength = 114.3; - }; - - // Chiappa Rhino 60DS - class hgun_Pistol_heavy_02_F: Pistol_Base_F { - initSpeed = -0.905512; - ACE_barrelTwist = 406.4; - ACE_barrelLength = 76.2; - }; - - // Makarov PM - class hgun_Pistol_01_F: Pistol_Base_F { - initSpeed = -0.883721; - ACE_barrelTwist = 254.0; - ACE_barrelLength = 93.5; - }; - - class pdw2000_base_F: Rifle_Short_Base_F {}; - - // CPW - class hgun_PDW2000_F: pdw2000_base_F { - initSpeed = -0.994186; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 177.8; + class SDAR_base_F: Rifle_Base_F {}; + class arifle_SDAR_F: SDAR_base_F { + ACE_barrelLength = 457.2; + ACE_barrelTwist = 285.75; + initSpeed = -0.998321; }; // AKS class arifle_AKS_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 160.02; - ACE_barrelLength = 206.5; + ACE_barrelLength = 210; + ACE_barrelTwist = 160; + initSpeed = -1; // 735 m/s according with the ACE_muzzleVelocities at 15°C }; // AKM class arifle_AKM_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 199.898; - ACE_barrelLength = 414.02; + ACE_barrelLength = 415; + ACE_barrelTwist = 240; + initSpeed = -1; // 715 m/s according with the ACE_muzzleVelocities at 15°C }; - // AK12 + // AK15,AK15K,RPK (AK12) class arifle_AK12_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 199.898; - ACE_barrelLength = 414.02; + ACE_barrelLength = 415; + ACE_barrelTwist = 240; + initSpeed = -1; // 715 m/s according with the ACE_muzzleVelocities at 15°C + }; + + class arifle_AK12U_base_F: arifle_AK12_base_F { + ACE_barrelLength = 314; + initSpeed = -0.937063; // 715*0.937063= 670 m/s according with the ACE_muzzleVelocities at 15°C + }; + + class arifle_RPK12_base_F: arifle_AK12_base_F { + ACE_barrelLength = 590; + initSpeed = -1.041958; // 715*1.041958= 745 m/s according with the ACE_muzzleVelocities at 15°C + }; + + // MSBS GROT (Promet) + class arifle_MSBS65_base_F: Rifle_Base_F { + ACE_barrelLength = 406.4; // 16" + ACE_barrelTwist = 228.6; + initSpeed = -0.971576; // 774*0.971576= 752 m/s according with the ACE_muzzleVelocities at 15°C + }; + + class arifle_MSBS65_Mark_base_F: arifle_MSBS65_base_F { + ACE_barrelLength = 508; // 20" + initSpeed = -1.007752; // 774*1.007752= 780 m/s according with the ACE_muzzleVelocities at 15°C + magazines[] += { // 6.5C Rechambering, only available for Grot MR + "ACE_30Rnd_65_Creedmor_msbs_mag", + "ACE_30Rnd_65x47_Scenar_msbs_mag" + }; }; // QBZ-95-1 class arifle_CTAR_base_F: Rifle_Base_F { - initSpeed = -0.978947; - ACE_barrelTwist = 244.0; ACE_barrelLength = 463.0; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; - }; - - // QBU-88 - class DMR_07_base_F: Rifle_Long_Base_F { - initSpeed = -0.99998; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 640.0; - magazines[] = { - "20Rnd_650x39_Cased_Mag_F", - "ACE_20Rnd_65x47_Scenar_mag", - "ACE_20Rnd_65_Creedmor_mag" - }; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.01); - }; + ACE_barrelTwist = 244.0; + initSpeed = -0.978947; }; // QBZ-95-1 LSW class arifle_CTARS_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 244.0; ACE_barrelLength = 600.0; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; + ACE_barrelTwist = 244.0; + initSpeed = -1.0; }; // Type 115 class arifle_ARX_base_F: Rifle_Base_F { - initSpeed = -0.984262; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 463.0; - class Single: Mode_SemiAuto { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: Mode_FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; - }; - - // KH2002 Sama - class arifle_Katiba_F: arifle_katiba_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_green", - "30Rnd_65x39_caseless_green_mag_Tracer", - "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" - }; - initSpeed = -1.0; - ACE_barrelTwist = 203.2; ACE_barrelLength = 508.0; - }; - - // KH2002C Sama - class arifle_Katiba_C_F: arifle_katiba_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_green", - "30Rnd_65x39_caseless_green_mag_Tracer", - "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" - }; - initSpeed = -0.961294; ACE_barrelTwist = 203.2; - ACE_barrelLength = 393.7; - class Single: Single { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; - }; - - // KH2002 Sama KGL - class arifle_Katiba_GL_F: arifle_katiba_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_green", - "30Rnd_65x39_caseless_green_mag_Tracer", - "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" - }; initSpeed = -1.0; - ACE_barrelTwist = 203.2; - ACE_barrelLength = 508.0; + class Secondary: Rifle_Base_F { + ACE_barrelLength = 304.8; + ACE_barrelTwist = 508.0; + initSpeed = -1.0; + }; }; - // MX - class arifle_MX_F: arifle_MX_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_mag", - "30Rnd_65x39_caseless_mag_Tracer", - "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" - }; - initSpeed = -0.972222; + // Rifle_Short_Base_F + // CPW + class pdw2000_base_F: Rifle_Short_Base_F {}; + class hgun_PDW2000_F: pdw2000_base_F { + ACE_barrelLength = 177.8; ACE_barrelTwist = 228.6; - ACE_barrelLength = 368.3; + initSpeed = -0.994186; }; - // MX 3GL - class arifle_MX_GL_F: arifle_MX_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_mag", - "30Rnd_65x39_caseless_mag_Tracer", - "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" - }; - initSpeed = -0.972222; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 368.3; + // Vector SMG + class SMG_01_Base: Rifle_Short_Base_F {}; + class SMG_01_F: SMG_01_Base { + ACE_barrelLength = 139.7; + ACE_barrelTwist = 406.4; + initSpeed = -1.00148; }; - // MXC - class arifle_MXC_F: arifle_MX_Base_F { - magazines[] = { - "30Rnd_65x39_caseless_mag", - "30Rnd_65x39_caseless_mag_Tracer", - "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" - }; - initSpeed = -0.946382; - ACE_barrelTwist = 203.2; - ACE_barrelLength = 266.7; - class Single: Single { - dispersion = MOA_TO_RAD(0.90); - }; - - class FullAuto: FullAuto { - dispersion = MOA_TO_RAD(0.90); - }; - }; - - // RFB SDAR - class arifle_SDAR_F: SDAR_base_F { - magazines[] = { - "20Rnd_556x45_UW_mag", - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -0.998321; - ACE_barrelTwist = 285.75; - ACE_barrelLength = 457.2; - }; - - class SMG_02_base_F: Rifle_Short_Base_F {}; - // Scorpion Evo 3 A1 + class SMG_02_base_F: Rifle_Short_Base_F {}; class SMG_02_F: SMG_02_base_F { - initSpeed = -1.00029; - ACE_barrelTwist = 254.0; ACE_barrelLength = 195.58; + ACE_barrelTwist = 254.0; + initSpeed = -1.00029; }; // MP5K class SMG_05_base_F: Rifle_Short_Base_F { - initSpeed = -0.943783; - ACE_barrelTwist = 254.0; ACE_barrelLength = 115.0; + ACE_barrelTwist = 254.0; + initSpeed = -0.943783; }; - // CTAR-21 - class arifle_TRG20_F: Tavor_base_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -0.961496; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 381.0; + // Pistol_Base_F + // P99 + class hgun_P07_F: Pistol_Base_F { + ACE_barrelLength = 101.6; + ACE_barrelTwist = 254.0; + initSpeed = -0.906977; }; - // TAR-21 - class arifle_TRG21_F: Tavor_base_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -1.0; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 459.74; - class Single: Single { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; + // MP-443 Grach + class hgun_Rook40_F: Pistol_Base_F { + ACE_barrelLength = 111.76; + ACE_barrelTwist = 254.0; + initSpeed = -0.934884; }; - // TAR-21 EGLM - class arifle_TRG21_GL_F: arifle_TRG21_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -1.0; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 459.74; - }; - - // F2000 - class arifle_Mk20_F: mk20_base_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -0.992849; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 441.96; - }; - - // F2000 Tactical - class arifle_Mk20C_F: mk20_base_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -0.974297; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 406.4; - class Single: Single { - dispersion = MOA_TO_RAD(1.12); - }; - - class FullAuto: FullAuto { - dispersion = MOA_TO_RAD(1.12); - }; - }; - - // F2000 EGLM - class arifle_Mk20_GL_F: mk20_base_F { - magazines[] = { - "30Rnd_556x45_Stanag", - "30Rnd_556x45_Stanag_Tracer_Red", - "30Rnd_556x45_Stanag_Tracer_Green", - "30Rnd_556x45_Stanag_Tracer_Yellow", - "30Rnd_556x45_Stanag_red", - "30Rnd_556x45_Stanag_green", - "ACE_30Rnd_556x45_Stanag_M995_AP_mag", - "ACE_30Rnd_556x45_Stanag_Mk262_mag", - "ACE_30Rnd_556x45_Stanag_Mk318_mag", - "ACE_30Rnd_556x45_Stanag_Tracer_Dim" - }; - initSpeed = -0.974297; - ACE_barrelTwist = 177.8; - ACE_barrelLength = 406.4; - }; - - class SMG_01_Base: Rifle_Short_Base_F {}; - - // Vector SMG - class SMG_01_F: SMG_01_Base { - initSpeed = -1.00148; + // Custom Covert II + class hgun_ACPC2_F: Pistol_Base_F { + ACE_barrelLength = 127.0; ACE_barrelTwist = 406.4; - ACE_barrelLength = 139.7; + initSpeed = -0.984252; }; - // VS-121 - class srifle_DMR_01_F: DMR_01_base_F { - magazines[] = { - "10Rnd_762x54_Mag", - "ACE_10Rnd_762x54_Tracer_mag" - }; - initSpeed = -1.00019; - ACE_barrelTwist = 241.3; - ACE_barrelLength = 609.6; + // FNX-45 Tactical + class hgun_Pistol_heavy_01_F: Pistol_Base_F { + ACE_barrelLength = 114.3; + ACE_barrelTwist = 406.4; + initSpeed = -0.944882; }; - // Mk14 Mod 1 EBR - class srifle_EBR_F: EBR_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.979444; - ACE_barrelTwist = 304.8; - ACE_barrelLength = 457.2; + // Chiappa Rhino 60DS + class hgun_Pistol_heavy_02_F: Pistol_Base_F { + ACE_barrelLength = 76.2; + ACE_barrelTwist = 406.4; + initSpeed = -0.905512; }; - // M200 Intervention - class srifle_LRR_F: LRR_base_F { - magazines[] = { - "7Rnd_408_Mag", - "ACE_7Rnd_408_305gr_Mag" - }; - initSpeed = -1.0; - ACE_barrelTwist = 330.2; - ACE_barrelLength = 736.6; - }; - - // GM6 Lynx - class srifle_GM6_F: GM6_base_F { - magazines[] = { - "5Rnd_127x108_Mag", - "5Rnd_127x108_APDS_Mag", - "ACE_5Rnd_127x99_Mag", - "ACE_5Rnd_127x99_API_Mag", - "ACE_5Rnd_127x99_AMAX_Mag" - }; - initSpeed = -1.0; - ACE_barrelTwist = 381.0; - ACE_barrelLength = 730; - }; - - // Noreen "Bad News" ULR - class srifle_DMR_02_F: DMR_02_base_F { - magazines[] = { - "10Rnd_338_Mag", - "ACE_10Rnd_338_300gr_HPBT_Mag", - "ACE_10Rnd_338_API526_Mag", - "ACE_20Rnd_762x67_Mk248_Mod_0_Mag", - "ACE_20Rnd_762x67_Mk248_Mod_1_Mag", - "ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag" - }; - initSpeed = -1.0; + // Makarov PM + class hgun_Pistol_01_F: Pistol_Base_F { + ACE_barrelLength = 93.5; ACE_barrelTwist = 254.0; - ACE_barrelLength = 508.0; + initSpeed = -0.883721; }; - // SIG 556 - class srifle_DMR_03_F: DMR_03_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.991536; - ACE_barrelTwist = 254.0; - ACE_barrelLength = 508.0; - }; - - // ASP-1 Kir - class srifle_DMR_04_F: DMR_04_base_F { - initSpeed = -1.0; - ACE_barrelTwist = 203.2; - ACE_barrelLength = 450.088; - }; - - // Cyrus - class srifle_DMR_05_blk_F: DMR_05_base_F { - initSpeed = -1.0; - ACE_barrelTwist = 359.918; - 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; - ACE_barrelTwist = 359.918; - ACE_barrelLength = 549.91; - }; - - // LWMMG - class MMG_02_camo_F: MMG_02_base_F { - initSpeed = -1.0; - ACE_barrelTwist = 234.95; - ACE_barrelLength = 609.6; - }; - - class HMG_127 : LMG_RCWS { - }; - class HMG_01: HMG_127 { - }; + // M2_Turret class HMG_M2: HMG_01 { - initSpeed = -1.0; - ACE_barrelTwist = 304.8; ACE_barrelLength = 1143.0; + ACE_barrelTwist = 304.8; + initSpeed = -1.0; }; /* Silencers */ diff --git a/addons/ballistics/README.md b/addons/ballistics/README.md index 18d81bceb3..54a7cf5e76 100644 --- a/addons/ballistics/README.md +++ b/addons/ballistics/README.md @@ -2,12 +2,3 @@ ace_ballistics ============== Changes to weapon, magazine and ammunition values. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/ballistics/XEH_PREP.hpp b/addons/ballistics/XEH_PREP.hpp index c370b5fe1f..03a5055fcb 100644 --- a/addons/ballistics/XEH_PREP.hpp +++ b/addons/ballistics/XEH_PREP.hpp @@ -1,2 +1,3 @@ -PREP(statTextStatement_weaponMuzzleVelocity); +PREP(statTextStatement_magazineAiUsage); PREP(statTextStatement_magazineMuzzleVelocity); +PREP(statTextStatement_weaponMuzzleVelocity); diff --git a/addons/ballistics/functions/fnc_statTextStatement_magazineAiUsage.sqf b/addons/ballistics/functions/fnc_statTextStatement_magazineAiUsage.sqf new file mode 100644 index 0000000000..c7017f648b --- /dev/null +++ b/addons/ballistics/functions/fnc_statTextStatement_magazineAiUsage.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Text statement for the magazine's AI Usage. + * + * Arguments: + * 0: not used + * 1: item config path (CONFIG) + * + * Return Value: + * String to display + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_magazineAiUsage",_config); + +private _ammo = getText (_config >> "ammo"); +private _aiAmmoUsageFlags = getNumber (configFile >> "CfgAmmo" >> _ammo >> "aiAmmoUsageFlags"); +private _cost = getNumber (configFile >> "CfgAmmo" >> _ammo >> "cost"); + +private _output = []; + +if ([_aiAmmoUsageFlags, 1] call BIS_fnc_bitflagsCheck) then { _output pushBack LLSTRING(ammoUsageShort_illumination) }; +if ([_aiAmmoUsageFlags, 4] call BIS_fnc_bitflagsCheck) then { _output pushBack LLSTRING(ammoUsageShort_concealment) }; +if ([_aiAmmoUsageFlags, 64] call BIS_fnc_bitflagsCheck) then { _output pushBack LLSTRING(ammoUsageShort_infantry) }; +if ([_aiAmmoUsageFlags, 128] call BIS_fnc_bitflagsCheck) then { _output pushBack LLSTRING(ammoUsageShort_lightVehicle) }; +if ([_aiAmmoUsageFlags, 256] call BIS_fnc_bitflagsCheck) then { _output pushBack LLSTRING(ammoUsageShort_armor) }; +if ([_aiAmmoUsageFlags, 512] call BIS_fnc_bitflagsCheck) then { _output pushBack LLSTRING(ammoUsageShort_aircraft) }; + +(_output joinString ", ") + format [" [%1 %2]", localize "str_a3_cfgvehicles_modulecuratorsetobjectcost_f_arguments_cost", _cost] diff --git a/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf b/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf index 73f671343a..a57a52bba7 100644 --- a/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf +++ b/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Text statement for the magazine ammo muzzle velocity stat. @@ -13,36 +13,47 @@ * Public: No */ -params ["", "_config"]; +params ["", "_configMagazine"]; if (EGVAR(arsenal,currentLeftPanel) == 2002) then { private _primaryMag = primaryWeaponMagazine EGVAR(arsenal,center); - - [primaryWeapon EGVAR(arsenal,center), configName _config] + [primaryWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]] } else { private _primaryMag = handgunMagazine EGVAR(arsenal,center); - - [handgunWeapon EGVAR(arsenal,center), configName _config] + [handgunWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]] } params ["_weapon", "_magazine"]; -if (_magazine isEqualTo "") then { - localize "str_empty"; -} else { - private _weaponCfg = configFile >> "CfgWeapons" >> _weapon; - private _ammoCfg = (configFile >> "CfgAmmo" >> (getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"))); - private _barrelLength = getNumber (_weaponCfg >> "ACE_barrelLength"); - private _muzzleVelocityTable = getArray (_ammoCfg >> "ACE_muzzleVelocities"); - private _barrelLengthTable = getArray (_ammoCfg >> "ACE_barrelLengths"); +// we might be looking at random mags not related to our weapon +private _magIsForCurrentWeapon = (configName _configMagazine == _magazine) && {_weapon != ""}; +private _configWeapon = configNull; - if (_barrelLength != 0 && {count _muzzleVelocityTable > 0} && {count _barrelLengthTable > 0}) then { - private _muzzleVelocity = if (["ace_advanced_ballistics"] call EFUNC(common,isModLoaded)) then { - [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); - } else { - getNumber (_config >> "initSpeed") - }; +private _muzzleVelocity = getNumber (_configMagazine >> "initSpeed"); +private _initSpeedCoef = 0; +if (_magIsForCurrentWeapon) then { + _configWeapon = configFile >> "CfgWeapons" >> _weapon; + _initSpeedCoef = getNumber (_configWeapon >> "initSpeed"); +}; +if (_initSpeedCoef < 0) then { + _muzzleVelocity = _muzzleVelocity * -_initSpeedCoef; +}; +if (_initSpeedCoef > 0) then { + _muzzleVelocity = _initSpeedCoef; +}; - format ["%1 m/s (%2 ft/s)", _muzzleVelocity toFixed 0, (_muzzleVelocity * 3.28084) toFixed 0] - } else { - localize "str_empty"; +private _abAdjustText = ""; +if ( + _magIsForCurrentWeapon && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]} && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} // this can be on while AB is off or vice-versa +) then { + private _configAmmo = (configFile >> "CfgAmmo" >> (getText (_configMagazine >> "ammo"))); + private _barrelLength = getNumber (_configWeapon >> "ACE_barrelLength"); + private _muzzleVelocityTable = getArray (_configAmmo >> "ACE_muzzleVelocities"); + private _barrelLengthTable = getArray (_configAmmo >> "ACE_barrelLengths"); + private _abShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); + if (_abShift != 0) then { + _abAdjustText = " [AB]"; + _muzzleVelocity = _abShift; }; }; +format ["%1 m/s (%2 ft/s)%3", _muzzleVelocity toFixed 0, (_muzzleVelocity * 3.28084) toFixed 0, _abAdjustText] diff --git a/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf index 227af9158d..e11c7cf5fb 100644 --- a/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf +++ b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Alganthe * Text statement for the weapon muzzle velocity stat. @@ -13,35 +13,43 @@ * Public: No */ -params ["", "_config"]; +params ["", "_configWeapon"]; if (EGVAR(arsenal,currentLeftPanel) == 2002) then { private _primaryMag = primaryWeaponMagazine EGVAR(arsenal,center); - [primaryWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]] } else { private _primaryMag = handgunMagazine EGVAR(arsenal,center); - [handgunWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]] } params ["_weapon", "_magazine"]; if (_magazine isEqualTo "") then { localize "str_empty"; } else { - private _ammoCfg = (configFile >> "CfgAmmo" >> (getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"))); - private _barrelLength = getNumber (_config >> "ACE_barrelLength"); - private _muzzleVelocityTable = getArray (_ammoCfg >> "ACE_muzzleVelocities"); - private _barrelLengthTable = getArray (_ammoCfg >> "ACE_barrelLengths"); - - if (_barrelLength != 0 && {count _muzzleVelocityTable > 0} && {count _barrelLengthTable > 0}) then { - private _muzzleVelocity = if (["ace_advanced_ballistics"] call EFUNC(common,isModLoaded)) then { - [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); - } else { - getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed") - }; - - format ["%1 m/s (%2 ft/s)", _muzzleVelocity toFixed 0, (_muzzleVelocity * 3.28084) toFixed 0] - } else { - localize "str_empty"; + private _configMagazine = configFile >> "CfgMagazines" >> _magazine; + private _muzzleVelocity = getNumber (_configMagazine >> "initSpeed"); + private _initSpeedCoef = getNumber (_configWeapon >> "initSpeed"); + if (_initSpeedCoef < 0) then { + _muzzleVelocity = _muzzleVelocity * -_initSpeedCoef; }; + if (_initSpeedCoef > 0) then { + _muzzleVelocity = _initSpeedCoef; + }; + + private _abAdjustText = ""; + if ( + missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} // this can be on while AB is off or vice-versa + ) then { + private _configAmmo = (configFile >> "CfgAmmo" >> (getText (_configMagazine >> "ammo"))); + private _barrelLength = getNumber (_configWeapon >> "ACE_barrelLength"); + private _muzzleVelocityTable = getArray (_configAmmo >> "ACE_muzzleVelocities"); + private _barrelLengthTable = getArray (_configAmmo >> "ACE_barrelLengths"); + private _abShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); + if (_abShift != 0) then { + _abAdjustText = " [AB]"; + _muzzleVelocity = _abShift; + }; + }; + format ["%1 m/s (%2 ft/s)%3", _muzzleVelocity toFixed 0, (_muzzleVelocity * 3.28084) toFixed 0, _abAdjustText] }; diff --git a/addons/ballistics/functions/script_component.hpp b/addons/ballistics/functions/script_component.hpp deleted file mode 100644 index a257e3d384..0000000000 --- a/addons/ballistics/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\ballistics\script_component.hpp" diff --git a/addons/ballistics/scripts/initTargetWall.sqf b/addons/ballistics/scripts/initTargetWall.sqf index 7f9578f09a..7297e6ba17 100644 --- a/addons/ballistics/scripts/initTargetWall.sqf +++ b/addons/ballistics/scripts/initTargetWall.sqf @@ -1,5 +1,5 @@ // by commy2 -#include "script_component.hpp" +#include "..\script_component.hpp" params ["_wall"]; diff --git a/addons/ballistics/scripts/script_component.hpp b/addons/ballistics/scripts/script_component.hpp deleted file mode 100644 index 998ced0210..0000000000 --- a/addons/ballistics/scripts/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\ballistics\script_component.hpp" \ No newline at end of file diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index 1c691d960a..a4c67c68d5 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -1,603 +1,1309 @@ + + + #00 Buckshot + Postas #00 + #00 Schrotmunition + #00 鹿彈 + #00 鹿弹 + #00 Pallettoni + #00 バックショット + Chevrotine #00 + #00 Broky velké + #00 Śrut + #00 Chumbo Grosso + #00 Irisaçma + #00 Картечь + #00 벅샷 + + + #00 Buckshot + Postas #00 + #00 Schrotmunition + #00 鹿彈(8.38 mm) + #00 鹿弹(8.38 mm) + #00 Pallettoni + #00 バックショット - 直径 8.38 mm粒弾 + Chevrotine #00 + #00 Broky velké - kalibr 8.38 mm + #00 Śrut + #00 Chumbo Grosso + #00 Irisaçma + #00 Картечь + #00 벅샷 + + + #0 Buckshot + Postas #0 + #0 Schrotmunition + #0 鹿彈 + #0 鹿弹 + #0 Pallettoni + #0 バックショット + Chevrotine #0 + #0 Broky velké + #0 Śrut + #0 Chumbo Grosso + #0 Irisaçma + #0 Картечь + #0 벅샷 + + + #0 Buckshot + Postas #0 + #0 Schrotmunition + #0 鹿彈 + #0 鹿弹(8.1 mm) + #0 Pallettoni + #0 バックショット - 直径 8.1 mm粒弾 + Chevrotine #0 + #0 Broky velké - kalibr 8.1 mm + #0 Śrut + #0 Chumbo Grosso + #0 Irisaçma + #0 Картечь + #0 벅샷 + + + #1 Buckshot + Postas #1 + #1 Schrotmunition + #1 鹿彈 + #1 鹿弹 + #1 Pallettoni + #1 バックショット + Chevrotine #1 + #1 Broky velké + #1 Śrut + #1 Chumbo Grosso + #1 Irisaçma + #1 Картечь + #1 벅샷 + + + #1 Buckshot + Postas #1 + #1 Schrotmunition + #1 鹿彈 + #1 鹿弹(7.6 mm) + #1 Pallettoni + #1 バックショット - 直径 7.6 mm粒弾 + Chevrotine #1 + #1 Broky velké - kalibr 7.6 mm + #1 Śrut + #1 Chumbo Grosso + #1 Irisaçma + #1 Картечь + #1 벅샷 + + + #2 Buckshot + Postas #2 + #2 Schrotmunition + #2 鹿彈 + #2 鹿弹 + #2 Pallettoni + #2 バックショット + Chevrotine #2 + #2 Broky velké + #2 Śrut + #2 Chumbo Grosso + #2 Irisaçma + #2 Картечь + #2 벅샷 + + + #2 Buckshot + Postas #2 + #2 Schrotmunition + #2 鹿彈 + #2 鹿弹(6.9 mm) + #2 Pallettoni + #2 バックショット - 直径 6.9 mm粒弾 + Chevrotine #2 + #2 Broky velké - kalibr 6.9 mm + #2 Śrut + #2 Chumbo Grosso + #2 Irisaçma + #2 Картечь + #2 벅샷 + + + #3 Buckshot + Postas #3 + #3 Schrotmunition + #3 鹿彈 + #3 鹿弹 + #3 Pallettoni + #3 バックショット + Chevrotine #3 + #3 Broky velké + #3 Śrut + #3 Chumbo Grosso + #3 Irisaçma + #3 Картечь + #3 벅샷 + + + #3 Buckshot + Postas #3 + #3 Schrotmunition + #3 鹿彈 + #3 鹿弹(6.4 mm) + #3 Pallettoni + #3 バックショット - 直径 6.4 mm粒弾 + Chevrotine #3 + #3 Broky velké - kalibr 6.4 mm + #3 Śrut + #3 Chumbo Grosso + #3 Irisaçma + #3 Картечь + #3 벅샷 + + + #4 Buckshot + Postas #4 + #4 Schrotmunition + #4 鹿彈 + #4 鹿弹 + #4 Pallettoni + #4 バックショット + Chevrotine #4 + #4 Broky velké + #4 Śrut + #4 Chumbo Grosso + #4 Irisaçma + #4 Картечь + #4 벅샷 + + + #4 Buckshot + Postas #4 + #4 Schrotmunition + #4 鹿彈 + #4 鹿弹(6.10 mm) + #4 Pallettoni + #4 バックショット - 直径 6.1 mm粒弾 + Chevrotine #4 + #4 Broky velké - kalibr 6.1 mm + #4 Śrut + #4 Chumbo Grosso + #4 Irisaçma + #4 Картечь + #4 벅샷 + + + #4 Birdshot + Perdigones #4 + #4 Vogelschrot + #4 鳥彈 + #4 鸟弹 + #4 Pallini + #4 バードショット + Grenaille No.4 + #4 Broky malé + #4 Śrut Drobny + #4 Küçük saçma + #4 Дробь + #4 버드샷 + #4 Chumbo Fino + + + #4 Birdshot + Perdigones #4 + #4 Vogelschrot + #4 鳥彈 + #4 鸟弹(3.30 mm) + #4 Pallini + #4 バードショット - 直径 3.3 mm粒弾 + Grenaille No.4 + #4 Broky malé - kalibr 3.3 mm + #4 Śrut Drobny (Birdshot) + #4 Küçük saçma + #4 Дробь + #4 버드샷 + #4 Chumbo Fino + + + 12 Gauge 2Rnd #00 Buckshot + 2 Cartuchos de Postas Calibre 12 #00 + 12 Gauge 2Schuss #00 Schrotmunition + 12鉛徑 2發 #00 鹿彈 + 12铅径 2发 #00 鹿弹 + Calibro 12 2cp #00 Pallettoni + 12 ゲージ 2Rnd #00 バックショット + 2 balles cal. 12 Chevrotine #00 + 2x #00 Broky velké (kalibr 8.38 mm) + 12 Gauge 2 naboje #00 Śrut + Chumbo Grosso #00 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #00 Картечь + 12 kalibre 2 mermi #00 İrisaçma + 12 게이지 2발 #00 벅샷 + + + 12 Gauge 2Rnd #0 Buckshot + 2 Cartuchos de Postas Calibre 12 #0 + 12 Gauge 2Schuss #0 Schrotmunition + 12鉛徑 2發 #0 鹿彈 + 12铅径 2发 #0 鹿弹 + Calibro 12 2cp #0 Pallettoni + 12 ゲージ 2Rnd #0 バックショット + 2 balles cal. 12 Chevrotine #0 + 2x #0 Broky velké (kalibr 8.1 mm) + 12 Gauge 2 naboje #0 Śrut + Chumbo Grosso #0 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #0 Картечь + 12 kalibre 2 mermi #0 İrisaçma + 12 게이지 2발 #00 벅샷 + + + 12 Gauge 2Rnd #1 Buckshot + 2 Cartuchos de Postas Calibre 12 #1 + 12 Gauge 2Schuss #1 Schrotmunition + 12鉛徑 2發 #1 鹿彈 + 12铅径 2发 #1 鹿弹 + Calibro 12 2cp #1 Pallettoni + 12 ゲージ 2Rnd #1 バックショット + 2 balles cal. 12 Chevrotine #1 + 2x #1 Broky velké (kalibr 7.6 mm) + 12 Gauge 2 naboje #1 Śrut + Chumbo Grosso #1 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #1 Картечь + 12 kalibre 2 mermi #1 İrisaçma + 12 게이지 2발 #1 벅샷 + + + 12 Gauge 2Rnd #2 Buckshot + 2 Cartuchos de Postas Calibre 12 #2 + 12 Gauge 2Schuss #2 Schrotmunition + 12鉛徑 2發 #2 鹿彈 + 12铅径 2发 #2 鹿弹 + Calibro 12 2cp #2 Pallettoni + 12 ゲージ 2Rnd #2 バックショット + 2 balles cal. 12 Chevrotine #2 + 2x #2 Broky velké (kalibr 6.9 mm) + 12 Gauge 2 naboje #2 Śrut + Chumbo Grosso #2 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #2 Картечь + 12 kalibre 2 mermi #2 İrisaçma + 12 게이지 2발 #2 벅샷 + + + 12 Gauge 2Rnd #3 Buckshot + 2 Cartuchos de Postas Calibre 12 #3 + 12 Gauge 2Schuss #3 Schrotmunition + 12鉛徑 2發 #3 鹿彈 + 12铅径 2发 #3 鹿弹 + Calibro 12 2cp #3 Pallettoni + 12 ゲージ 2Rnd #3 バックショット + 2 balles cal. 12 Chevrotine #3 + 2x #3 Broky velké (kalibr 6.4 mm) + 12 Gauge 2 naboje #3 Śrut + Chumbo Grosso #3 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #3 Картечь + 12 kalibre 2 mermi #3 İrisaçma + 12 게이지 2발 #3 벅샷 + + + 12 Gauge 2Rnd #4 Buckshot + 2 Cartuchos de Postas Calibre 12 #4 + 12 Gauge 2Schuss #4 Schrotmunition + 12鉛徑 2發 #4 鹿彈 + 12铅径 2发 #4 鹿弹 + Calibro 12 2cp #4 Pallettoni + 12 ゲージ 2Rnd #4 バックショット + 2 balles cal. 12 Chevrotine #4 + 2x #4 Broky velké (kalibr 6.1 mm) + 12 Gauge 2 naboje #4 Śrut + Chumbo Grosso #4 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #4 Картечь + 12 kalibre 2 mermi #4 İrisaçma + 12 게이지 2발 #4 벅샷 + + + 12 Gauge 2Rnd #4 Birdshot + 2 Cartuchos de Perdigones Calibre 12 #4 + 12 Gauge 2Schuss #4 Schrotmunition + 12鉛徑 2發 #4 鳥彈 + 12铅径 2发 #4 鸟弹 + Calibro 12 2cp #4 Pallini + 12 ゲージ 2Rnd #4 バードショット + 2 balles cal. 12 Grenaille No.4 + 2x #4 Broky malé (kalibr 3.3 mm) + 12 Gauge 2 naboje #4 Śrut + Chumbo Fino #4 Calibre Doze 2 Tiros + 12 Калибр 2 патр. #4 Дробь + 12 kalibre 2 mermi #4 İrisaçma + 12 게이지 2발 #4 버드샷 + + + 12 Gauge 6Rnd #00 Buckshot + 6 Cartuchos de Postas Calibre 12 #00 + 12 Gauge 6Schuss #00 Schrotmunition + 12鉛徑 6發 #00 鹿彈 + 12铅径 6发 #00 鹿弹 + Calibro 12 6cp #00 Pallettoni + 12 ゲージ 6Rnd #00 バックショット + 6 balles cal. 12 Chevrotine #00 + 6x #00 Broky velké (kalibr 8.38 mm) + 12 Gauge 6 naboi #00 Śrut + Chumbo Grosso #00 Calibre Doze 6 Tiros + 12 Калибр 6 патр. #00 Картечь + 12 kalibre 6 mermi #00 İrisaçma + 12 게이지 6발 #00 벅샷 + + + 12 Gauge 6Rnd #0 Buckshot + 6 Cartuchos de Postas Calibre 12 #0 + 12 Gauge 6Schuss #0 Schrotmunition + 12鉛徑 6發 #0 鹿彈 + 12铅径 6发 #0 鹿弹 + Calibro 12 6cp #0 Pallettoni + 12 ゲージ 6Rnd #0 バックショット + 6 balles cal. 12 Chevrotine #0 + 6x #0 Broky velké (kalibr 8.1 mm) + 12 Gauge 6 naboi #0 Śrut + Chumbo Grosso #0 Calibre Doze 6 Tiros + 12 Калибр 6 патр. #0 Картечь + 12 kalibre 6 mermi #0 İrisaçma + 12 게이지 6발 #0 벅샷 + + + 12 Gauge 6Rnd #1 Buckshot + 6 Cartuchos de Postas Calibre 12 #1 + 12 Gauge 6Schuss #1 Schrotmunition + 12鉛徑 6發 #1 鹿彈 + 12铅径 6发 #1 鹿弹 + Calibro 12 6cp #1 Pallettoni + 12 ゲージ 6Rnd #1 バックショット + 6 balles cal. 12 Chevrotine #1 + 6x #1 Broky velké (kalibr 7.6 mm) + 12 Gauge 6 naboi #1 Śrut + Chumbo Grosso #1 Calibre Doze 6 Tiros + 12 Калибр 6 патр. #1 Картечь + 12 kalibre 6 mermi #1 İrisaçma + 12 게이지 6발 #1 벅샷 + + + 12 Gauge 6Rnd #2 Buckshot + 6 Cartuchos de Postas Calibre 12 #2 + 12 Gauge 6Schuss #2 Schrotmunition + 12鉛徑 6發 #2 鹿彈 + 12铅径 6发 #2 鹿弹 + Calibro 12 6cp #2 Pallettoni + 12 ゲージ 6Rnd #2 バックショット + 6 balles cal. 12 Chevrotine #2 + 6x #2 Broky velké (kalibr 6.9 mm) + 12 Gauge 6 naboi #2 Śrut + Chumbo Grosso #2 Calibre Doze 6 Tiros + 12 Калибр 6 патр. #2 Картечь + 12 kalibre 6 mermi #2 İrisaçma + 12 게이지 6발 #2 벅샷 + + + 12 Gauge 6Rnd #3 Buckshot + 6 Cartuchos de Postas Calibre 12 #3 + 12 Gauge 6Schuss #3 Schrotmunition + 12鉛徑 6發 #3 鹿彈 + 12铅径 6发 #3 鹿弹 + Calibro 12 6cp #3 Pallettoni + 12 ゲージ 6Rnd #3 バックショット + 6 balles cal. 12 Chevrotine #3 + 6x #3 Broky velké (kalibr 6.4 mm) + 12 Gauge 6 naboi #3 Śrut + Chumbo Grosso #3 Calibre Doze 6 Tiros + 12 Калибр 6 патр. #3 Картечь + 12 kalibre 6 mermi #3 İrisaçma + 12 게이지 6발 #3 벅샷 + + + 12 Gauge 6Rnd #4 Buckshot + 6 Cartuchos de Postas Calibre 12 #4 + 12 Gauge 6Schuss #4 Schrotmunition + 12鉛徑 6發 #4 鹿彈 + 12铅径 6发 #4 鹿弹 + Calibro 12 6cp #4 Pallettoni + 12 ゲージ 6Rnd #4 バックショット + 6 balles cal. 12 Chevrotine #4 + 6x #4 Broky velké (kalibr 6.1 mm) + 12 Gauge 6 naboi #4 Śrut + Chumbo Grosso #4 Calibre Doze 6 Tiros + 12 Калибр 6 патр. #4 Картечь + 12 kalibre 6 mermi #4 İrisaçma + 12 게이지 6발 #4 벅샷 + + + 12 Gauge 6Rnd #4 Birdshot + 6 Cartuchos de Perdigones Calibre 12 #4 + 12 Gauge 6Schuss #4 Schrotmunition + 12鉛徑 6發 #4 鳥彈 + 12铅径 6发 #4 鸟弹 + Calibro 12 6cp #4 Pallini + 12 ゲージ 6Rnd #4 バードショット + 6 balles cal. 12 Grenaille No.4 + 6x #4 Broky malé (kalibr 3.3 mm) + 12 Gauge 6 naboi #4 Śrut + 12 Калибр 6 патр. #4 Дробь + 12 kalibre 6 mermi #4 İrisaçma + 12 게이지 6발 #4 버드샷 + Chumbo Fino #4 Calibre Doze 6 Tiros + + + 12 Gauge 15Rnd #00 Buckshot + 15 Cartuchos de Postas Calibre 12 #00 + 12 Gauge 15Schuss #00 Schrotmunition + 12鉛徑 15發 #00 鹿彈 + 12铅径 15发 #00 鹿弹 + Calibro 12 15cp #00 Pallettoni + 12 ゲージ 15Rnd #00 バックショット + 15 balles cal. 12 Chevrotine #00 + 15x #00 Broky velké (kalibr 8.38 mm) + 12 Gauge 15 naboi #00 Śrut + Chumbo Grosso #00 Calibre Doze 15 Tiros + 12 Калибр 15 патр. #00 Картечь + 12 kalibre 15 mermi #00 İrisaçma + 12 게이지 15발 #00 벅샷 + - 6.5x47mm 20Rnd Mag (HPBT Scenar) - Ch. 6,5x47mm 20Cps (HPBT Scenar) - Cargador de 20 balas de 6.5x47mm (HPBT Scenar) - Magazynek 6,5x47mm 20rd (HPBT Scenar) + 6.5x47 mm 20Rnd Mag (HPBT Scenar) + Ch. 6,5x47 mm 20Cps (HPBT Scenar) + Cargador de 20 balas de 6.5x47 mm (HPBT Scenar) + Magazynek 6,5x47 mm 20rd (HPBT Scenar) Магазин из 20-ти 6,5x47 мм (экспансивные Scenar) - 6,5x47mm 20-Patronen-Magazin (HPBT Scenar) - 6.5x47mm 20Rnd Mag (HPBT Scenar) - 6.5x47mm 20náb. Zásobník (HPBT Scenar) - Carregador 6.5x47mm com 20 cartuchos (HPBT Scenar) - 6,5x47mm 20-lövedékes tár (HPBT Scenar) - 6.5x47mm 20発入り 弾倉 (HPBT Scenar) - 20발들이 6.5x47mm (HPBT Scenar) - 6.5x47mm 20發 彈匣 (Lapua 空尖艇尾狙擊專用彈) - 6.5x47mm 20发 弹匣 (Lapua 空尖艇尾狙击专用弹) + 6,5x47 mm 20-Patronen-Magazin (HPBT Scenar) + 6.5x47 mm 20cp Car (HPBT Scenar) + 6.5x47 mm 20náb. Zásobník (HPBT Scenar) + Carregador 6.5x47 mm com 20 cartuchos (HPBT Scenar) + 6,5x47 mm 20-lövedékes tár (HPBT Scenar) + 6.5x47 mm 20Rnd マガジン (HPBT Scenar) + 20발 들이 6.5x47mm (HPBT Scenar) + 6.5x47毫米 20發 彈匣 (拉普 空尖艇尾狙擊專用彈) + 6.5x47 mm 20发 弹匣(HPBT Scenar) + 6.5x47 mm 20Rnd Mag (HPBT Scenar) - 6.5mm Lapua - 6,5mm Lapua - 6.5mm Lapua - 6,5mm Lapua + 6.5 mm Lapua + 6,5 mm Lapua + 6.5 mm Lapua + 6,5 mm Lapua 6,5 мм Lapua - 6,5mm Lapua - 6.5mm Lapua - 6.5mm Lapua - 6.5mm Lapua - 6,5mm Lapua - 6.5mm Lapua - 6.5mm Lapua - 6.5mm Lapua 空尖艇尾狙擊專用彈 - 6.5mm Lapua 空尖艇尾狙击专用弹 + 6,5 mm Lapua + 6.5 mm Lapua + 6.5 mm Lapua + 6.5 mm Lapua + 6,5 mm Lapua + 6.5 mm Lapua + 6.5mm 라푸아 + 6.5毫米 拉普 空尖艇尾狙擊專用彈 + 6.5 mm Lapua + 6.5 mm Lapua - Caliber: 6.5x47mm (HPBT Scenar)<br />Rounds: 20<br />Used in: QBU-88 - Calibre: 6,5x47mm (HPBT Scenar)<br />Cartouches: 20 - Calibre: 6.5x47mm (HPBT Scenar)<br />Balas: 20<br />Se usa en: QBU-88 - Kaliber: 6,5x47mm (HPBT Scenar)<br />Pociski: 20 + Caliber: 6.5x47 mm (HPBT Scenar)<br />Rounds: 20<br />Used in: QBU-88 + Calibre: 6,5x47 mm (HPBT Scenar)<br />Cartouches: 20<br />Utilisé avec: QBU-88 + Calibre: 6.5x47 mm (HPBT Scenar)<br />Balas: 20<br />Se usa en: QBU-88 + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Pociski: 20 Калибр: 6,5x47 мм (экспансивные Scenar)<br />Патронов: 20<br />Используются с: QBU-88 - Kaliber: 6,5x47mm (HPBT Scenar)<br />Patronen: 20<br />Eingesetzt von: QBU-88 - Calibro: 6.5x47mm (HPBT Scenar)<br />Munizioni: 20<br />In uso su: QBU-88 - Ráže: 6.5x47mm (HPBT Scenar)<br />Nábojů: 20<br />Použití u: QBU-88 - Calibre: 6.5x47mm (HPBT Scenar)<br/>Cartuchos: 20<br/>Usado em: QBU-88 - Kaliber: 6,5x47mm (HPBT Scenar)<br />Lövedékek: 20<br />Használható: QBU-88 - 口径: 6.5x47mm (HPBT Scenar)<br />装填数: 20<br />次で使用: QBU-88 - 구경: 6.5x47mm (HPBT Scenar)<br />장탄수: 20<br />사용처: QBU-88 - 口徑: 6.5x47mm (Lapua 空尖艇尾狙擊專用彈)<br />發數: 20<br />使用於: QBU-88 - 口径: 6.5x47mm (Lapua 空尖艇尾狙击专用弹)<br />发数: 20<br />使用于: QBU-88 + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Patronen: 20<br />Eingesetzt von: QBU-88 + Calibro: 6.5x47 mm (HPBT Scenar)<br />Munizioni: 20<br />In uso su: QBU-88 + Ráže: 6.5x47 mm (HPBT Scenar)<br />Nábojů: 20<br />Použití u: QBU-88 + Calibre: 6.5x47 mm (HPBT Scenar)<br/>Cartuchos: 20<br/>Usado em: QBU-88 + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Lövedékek: 20<br />Használható: QBU-88 + 口径: 6.5x47 mm (HPBT Scenar)<br />装填数: 20<br />次で使用: QBU-88 + 구경: 6.5x47mm (HPBT Scenar)<br/>장탄수: 20<br/>사용처: QBU-88 + 口徑: 6.5x47毫米 (拉普 空尖艇尾狙擊專用彈)<br />發數: 20<br />使用於: QBU-88 + 口径:6.5x47 mm(HPBT Scenar)<br />发数:20<br />使用于:QBU-88 + Kalibre: 6.5x47 mm (HPBT Scenar)<br />Mermi: 20<br />Kullanıyor: QBU-88 - 6.5mm Creedmor 20Rnd Mag - Magazynek 6,5mm Creedmor 20rd - 6.5mm Creedmor 20Rnd Mag + 6.5 mm Creedmor 20Rnd Mag + Magazynek 6,5 mm Creedmor 20rd + 6.5 mm Creedmor 20cp Car Магазин из 20-ти 6,5 мм Creedmor - 6,5mm Creedmor 20-Patronen-Magazin - Cargador de 20 balas Creedmor de 6.5mm - Ch. 6,5mm Creedmor 20Cps - 6.5mm Creedmor 20náb. Zásobník - Carregador 6.5mm com 20 cartuchos Creedmor - 6,5mm Creedmor 20-lövedékes tár - 6.5mm Creedmor 20発入り 弾倉 - 20발들이 6.5mm Creedmor 탄창 - 6.5mm 20發 彈匣 (Creedmor 狙擊專用彈) - 6.5mm 20发 弹匣 (Creedmor 狙击专用弹) + 6,5 mm Creedmor 20-Patronen-Magazin + Cargador de 20 balas Creedmor de 6.5 mm + Ch. 6,5 mm Creedmor 20Cps + 6.5 mm Creedmor 20náb. Zásobník + Carregador 6.5 mm com 20 cartuchos Creedmor + 6,5 mm Creedmor 20-lövedékes tár + 6.5 mm クリードモア 20Rnd マガジン + 20발 들이 6.5mm 크리드무어 탄창 + 6.5毫米 20發 彈匣 (克里德莫爾(CM) 狙擊專用彈) + 6.5 mm 20发 弹匣(Creedmor) + 6.5 mm Creedmor 20Rnd Mag - 6.5mm CM - 6,5mm CM - 6.5mm CM - 6,5mm CM + 6.5 mm CM + 6,5 mm CM + 6.5 mm CM + 6,5 mm CM 6,5 мм CM - 6,5mm CM - 6.5mm CM - 6.5mm CM - 6.5mm CM - 6,5mm CM - 6.5mm CM - 6.5mm CM - 6.5mm CM 狙擊專用彈 - 6.5mm CM 狙击专用弹 + 6,5 mm CM + 6.5 mm CM + 6.5 mm CM + 6.5 mm CM + 6,5 mm CM + 6.5 mm CM + 6.5mm 크리드무어 + 6.5毫米 CM 狙擊專用彈 + 6.5 mm CM + 6.5 mm CM - Caliber: 6.5x47mm Creedmor<br />Rounds: 20<br />Used in: QBU-88 - Kaliber: 6,5x47mm Creedmor<br />Pociski: 20<br />Używany w: QBU-88 - Kaliber: 6,5x47mm Creedmor<br />Patronen: 20<br />Eingesetzt von: QBU-88 - Calibre: 6,5x47mm Creedmor <br />Cartouches: 20<br />Utilisé avec: QBU-88 - Calibro: 6.5mm Creedmor<br />Munizioni: 20<br />In uso su: QBU-88 - Calibre: 6.5mm Creedmor<br />Balas: 20<br />Se usa en: QBU-88 + Caliber: 6.5x47 mm Creedmor<br />Rounds: 20<br />Used in: QBU-88 + Kaliber: 6,5x47 mm Creedmor<br />Pociski: 20<br />Używany w: QBU-88 + Kaliber: 6,5x47 mm Creedmor<br />Patronen: 20<br />Eingesetzt von: QBU-88 + Calibre: 6,5x47 mm Creedmor <br />Cartouches: 20<br />Utilisé avec: QBU-88 + Calibro: 6.5 mm Creedmor<br />Munizioni: 20<br />In uso su: QBU-88 + Calibre: 6.5 mm Creedmor<br />Balas: 20<br />Se usa en: QBU-88 Калибр: 6,5x47мм Creedmor<br />Патронов: 20<br />Используются c: QBU-88 - Ráže: 6.5x47mm Creedmor<br />Nábojů: 20<br />Použití u: QBU-88 - Calibre: 6.5x47mm Creedmor<br/>Cartuchos: 20<br/>Usado em: QBU-88 - Kaliber: 6,5x47mm Creedmor<br />Lövedékek: 20<br />Használható: QBU-88 - 口径: 6.5x47mm Creedmor<br />装填数: 20<br />次で使用: QBU-88 - 구경: 6.5x47mm Creedmor<br />장탄수: 20<br />사용처: QBU-88 - 口徑: 6.5x47mm Creedmor 狙擊專用彈<br />發數: 20<br />使用於: QBU-88 - 口径: 6.5x47mm Creedmor 狙击专用弹<br />发数: 20<br />使用于: QBU-88 + Ráže: 6.5x47 mm Creedmor<br />Nábojů: 20<br />Použití u: QBU-88 + Calibre: 6.5x47 mm Creedmor<br/>Cartuchos: 20<br/>Usado em: QBU-88 + Kaliber: 6,5x47 mm Creedmor<br />Lövedékek: 20<br />Használható: QBU-88 + 口径: 6.5x47 mm クリードモア<br />装填数: 20<br />次で使用: QBU-88 + 구경: 6.5x47mm 크리드무어<br/>장탄수: 20<br/>사용처: QBU-88 + 口徑: 6.5x47毫米 克里德莫爾 狙擊專用彈<br />發數: 20<br />使用於: QBU-88 + 口径:6.5x47 mm Creedmor 狙击专用弹<br />发数:20<br />使用于:QBU-88 + Kalibre: 6.5x47 mm Creedmor<br />Mermi: 20<br />Kullanıyor: QBU-88 + + + 5.8 mm DBP88 10Rnd Mag + Magazynek 5,8 mm DBP88 10rd + 5.8 mm DBP88 10cp Car + Магазин из 10-ти 5,8 мм DBP88 + 5,8 mm DBP88 10-Patronen-Magazin + Cargador de 10 balas DBP88 de 5.8 mm + Ch. 5,8 mm DBP88 10Cps + 5.8 mm DBP88 10náb. Zásobník + Carregador 5.8 mm com 10 cartuchos DBP88 + 5,8 mm DBP88 10-lövedékes tár + 5.8 mm DBP88 10Rnd マガジン + 10발 들이 5.8mm DBP88 탄창 + 5.8毫米 10發 彈匣 (DBP88) + 5.8 mm 10发 弹匣(DBP88) + 5.8 mm DBP88 10Rnd Mag + + + 5.8 mm DBP88 + 5,8 mm DBP88 + 5.8 mm DBP88 + 5,8 mm DBP88 + 5,8 мм DBP88 + 5,8 mm DBP88 + 5.5 mm DBP88 + 5.8 mm DBP88 + 5.8 mm DBP88 + 5,8 mm DBP88 + 5.8 mm DBP88 + 5.8mm DBP88 + 5.8毫米 DBP88 + 5.8 mm DBP88 + 5.8 mm DBP88 + + + Caliber: 5.8x42 mm DBP88<br />Rounds: 10<br />Used in: QBU-88 + Kaliber: 5,8x42 mm DBP88<br />Pociski: 10<br />Używany w: QBU-88 + Kaliber: 5,8x42 mm DBP88<br />Patronen: 10<br />Eingesetzt von: QBU-88 + Calibre: 5,8x42 mm DBP88 <br />Cartouches: 10<br />Utilisé avec: QBU-88 + Calibro: 5.8 mm DBP88<br />Munizioni: 10<br />In uso su: QBU-88 + Calibre: 5.8 mm DBP88<br />Balas: 10<br />Se usa en: QBU-88 + Калибр: 5,8x42мм DBP88<br />Патронов: 10<br />Используются c: QBU-88 + Ráže: 5.8x42 mm DBP88<br />Nábojů: 10<br />Použití u: QBU-88 + Calibre: 5.8x42 mm DBP88<br/>Cartuchos: 10<br/>Usado em: QBU-88 + Kaliber: 5,8x42 mm DBP88<br />Lövedékek: 10<br />Használható: QBU-88 + 口径: 5.8x42 mm DBP88<br />装填数: 10<br />次で使用: QBU-88 + 구경: 5.8x42mm DBP88<br/>장탄수: 10<br/>사용처: QBU-88 + 口徑: 5.8x42毫米 DBP88<br />發數: 10<br />使用於: QBU-88 + 口径:5.8x42 mm DBP88<br />发数:10<br />使用于:QBU-88 + Kalibre: 5.8x42 mm DBP88<br />Mermi: 10<br />Kullanıyor: QBU-88 - 6.5mm 30Rnd Tracer IR-DIM Mag - 6,5mm Nyomjelző IR-DIM 30-as Tár - 6,5mm 30-Patronen-Magazin Leuchtspur IR-DIM - Cargador de 30 balas trazadoras IR-DIM de 6,5mm - Ch. 6,5mm 30Cps Traçantes IR-DIM - Magazynek 6,5mm 30rd Smugacz IR-DIM - 6.5mm 30náb. Svítící IR-DIM Zásobník - Carregador de 30 projéteis traçantes IR-DIM de 6,5mm - Caricatore 6.5mm 30Rnd Traccianti IR-DIM + 6.5 mm 30Rnd Tracer IR-DIM Mag + 6,5 mm Nyomjelző IR-DIM 30-as Tár + 6,5 mm 30-Patronen-Magazin Leuchtspur IR-DIM + Cargador de 30 balas trazadoras IR-DIM de 6,5 mm + Ch. 6,5 mm 30Cps Traçantes IR-DIM + Magazynek 6,5 mm 30rd Smugacz IR-DIM + 6.5 mm 30náb. Svítící IR-DIM Zásobník + Carregador de 30 projéteis traçantes IR-DIM de 6,5 mm + Caricatore 6.5 mm 30cp Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих - 6.5mm 30発入り IR-DIM曳光弾 弾倉 - 30발들이 6.5mm IR-DIM 예광탄 탄창 - 6.5mm 30發 低視度紅外線曳光彈 彈匣 - 6.5mm 30发 低视度红外线曳光弹 弹匣 + 6.5 mm 30Rnd IR-DIM トレーサー ケースレスマガジン + 30발 들이 6.5mm IR-DIM 예광탄 탄창 + 6.5毫米 30發 低視度紅外線曳光彈 彈匣 + 6.5 mm 30发 弹匣(红外曳光) + 6.5 mm 30Rnd Tracer IR-DIM Mag - 6.5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6.5mm IR-DIM - 6,5mm IR-DIM - 6.5mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm IR-DIM + 6.5 mm IR-DIM 6,5 мм ИК-трассирующие - 6.5mm IR-DIM曳光弾 + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 - 6.5mm 低視紅外曳光彈 - 6.5mm 低视红外曳光弹 + 6.5毫米 低視紅外曳光彈 + 6.5 mm 红外曳光 + 6.5 mm IR-DIM - Caliber: 6.5x39mm Tracer IR-DIM<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL - Kaliber: 6,5x39mm Nyomjelző IR-DIM<br />Lövedékek: 30<br />Használható: MX/C/M/SW/3GL - Kaliber: 6,5x39mm Leuchtspur IR-DIM<br />Patronen: 30<br />Eingesetzt von: MX/C/M/SW/3GL - Calibre: 6,5x39mm Trazadoras IR-DIM<br />Balas: 30<br />Se usa en: MX/C/M/SW/3GL - Calibre: 6,5x39mm Traçantes IR-DIM<br />Cartouches: 30<br />Utilisé avec: MX/C/M/SW/3GL - Kaliber: 6,5x39mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL - Ráže: 6.5x39mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: MX - Calibre: 6,5x39mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL - Calibro: 6.5x39mm Traccianti IR-DIM <br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL + Caliber: 6.5x39 mm Tracer IR-DIM<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm Nyomjelző IR-DIM<br />Lövedékek: 30<br />Használható: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm Leuchtspur IR-DIM<br />Patronen: 30<br />Eingesetzt von: MX/C/M/SW/3GL + Calibre: 6,5x39 mm Trazadoras IR-DIM<br />Balas: 30<br />Se usa en: MX/C/M/SW/3GL + Calibre: 6,5x39 mm Traçantes IR-DIM<br />Cartouches: 30<br />Utilisé avec: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL + Ráže: 6.5x39 mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: MX + Calibre: 6,5x39 mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL + Calibro: 6.5x39 mm Tracciante IR-DIM <br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL - 口径: 6.5x39mm 曳光弾 IR-DIM<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL - 구경: 6.5x39mm IR-DIM 예광탄<br />장탄수: 30<br />사용처: MX/C/M/SW/3GL - 口徑: 6.5x39mm 低視度紅外線曳光彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL - 口径: 6.5x39mm 低视度红外线曳光弹<br />发数: 30<br />使用于: MX/C/M/SW/3GL + 口径: 6.5x39 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 구경: 6.5x39mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: MX/C/M/SW/3GL + 口徑: 6.5x39毫米 低視度紅外線曳光彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL + 口径:6.5x39 mm 红外曳光<br />发数:30<br />使用于:MX/C/M/SW/3GL + Kalibre: 6.5x39 mm Tracer IR-DIM<br />Mermi: 30<br />Kullanıyor: MX/C/M/SW/3GL - 6.5mm 30Rnd SD Mag - 6,5mm Halk 30-as Tár - 6,5mm 30-Patronen-Magazin SD - Cargador de 30 balas SD de 6,5mm - Ch. 6,5mm 30Cps SD - Magazynek 6,5mm 30rd SD - 6.5mm 30náb. SD Zásobník - Carregador de 30 projéteis SD de 6,5mm - Caricatore 6.5mm 30Rnd Sil. + 6.5 mm 30Rnd SD Mag + 6,5 mm Halk 30-as Tár + 6,5 mm 30-Patronen-Magazin SD + Cargador de 30 balas SD de 6,5 mm + Ch. 6,5 mm 30Cps SD + Magazynek 6,5 mm 30rd SD + 6.5 mm 30náb. SD Zásobník + Carregador de 30 projéteis SD de 6,5 mm + Caricatore 6.5 mm 30cp Sil. Магазин из 30-ти 6,5 мм дозвуковых - 6.5mm 30発入り 亜音速弾 弾倉 - 30발들이 6.5mm 아음속탄 탄창 - 6.5mm 30發 消音彈 彈匣 - 6.5mm 30发 消音弹 弹匣 + 6.5 mm 30Rnd 亜音速弾 マガジン + 30발 들이 6.5mm 아음속탄 탄창 + 6.5毫米 30發 消音彈 彈匣 + 6.5 mm 30发 弹匣(亚音速) + 6.5 mm 30Rnd SD Mag - 6.5mm SD - 6,5mm Halk - 6,5mm SD - 6,5mm SD - 6,5mm SD - 6,5mm SD - 6.5mm SD - 6,5mm SD - 6.5mm Sil. + 6.5 mm SD + 6,5 mm Halk + 6,5 mm SD + 6,5 mm SD + 6,5 mm SD + 6,5 mm SD + 6.5 mm SD + 6,5 mm SD + 6.5 mm Sil. 6,5 мм дозвуковые - 6.5mm 亜音速弾 + 6.5 mm SD 6.5mm 아음속탄 - 6.5mm 消音彈 - 6.5mm 消音弹 + 6.5毫米 消音彈 + 6.5 mm 亚音速 + 6.5 mm SD - Caliber: 6.5x39mm SD<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL - Kaliber: 6,5x39mm Halk<br />Lövedékek: 30<br />Használható: MX/C/M/SW/3GL - Kaliber: 6,5x39mm SD<br />Patronen: 30<br />Eingesetzt von: MX/C/M/SW/3GL - Calibre: 6,5x39mm SD<br />Balas: 30<br />Se usa en: MX/C/M/SW/3GL - Calibre: 6,5x39mm SD<br />Cartouches: 30<br />Utilisé avec: MX/C/M/SW/3GL - Kaliber: 6,5x39mm SD<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL - Ráže: 6.5x39mm SD<br />Nábojů: 30<br />Použití u: MX - Calibre: 6,5x39mm SD<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL - Calibro: 6.5x39mm Sil.<br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL + Caliber: 6.5x39 mm SD<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm Halk<br />Lövedékek: 30<br />Használható: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm SD<br />Patronen: 30<br />Eingesetzt von: MX/C/M/SW/3GL + Calibre: 6,5x39 mm SD<br />Balas: 30<br />Se usa en: MX/C/M/SW/3GL + Calibre: 6,5x39 mm SD<br />Cartouches: 30<br />Utilisé avec: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm SD<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL + Ráže: 6.5x39 mm SD<br />Nábojů: 30<br />Použití u: MX + Calibre: 6,5x39 mm SD<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL + Calibro: 6.5x39 mm Sil.<br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм дозвуковые<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL - 口径: 6.5x39mm 亜音速弾<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL - 구경: 6.5x39mm SD<br />장탄수: 30<br />사용처: MX/C/M/SW/3GL - 口徑: 6.5x39mm 消音彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL - 口径: 6.5x39mm 消音弹<br />发数: 30<br />使用于: MX/C/M/SW/3GL + 口径: 6.5x39 mm 亜音速弾<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 구경: 6.5x39mm 아음속탄<br/>장탄수: 30<br/>사용처: MX/C/M/SW/3GL + 口徑: 6.5x39毫米 消音彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL + 口径:6.5x39 mm 亚音速<br />发数:30<br />使用于:MX/C/M/SW/3GL + Kalibre: 6.5x39 mm SD<br />Mermi: 30<br />Kullanıyor: MX/C/M/SW/3GL - 6.5mm 30Rnd AP Mag - 6,5mm Páncéltörő 30-as Tár - 6,5mm 30-Patronen-Magazin AP - Cargador de 30 balas AP de 6,5mm - Ch. 6,5mm 30Cps AP - Magazynek 6,5mm 30rd AP - 6.5mm 30náb. AP Zásobník - Carregador de 30 projéteis AP de 6,5mm - Caricatore 6.5mm 30Rnd AP + 6.5 mm 30Rnd AP Mag + 6,5 mm Páncéltörő 30-as Tár + 6,5 mm 30-Patronen-Magazin AP + Cargador de 30 balas AP de 6,5 mm + Ch. 6,5 mm 30Cps AP + Magazynek 6,5 mm 30rd AP + 6.5 mm 30náb. AP Zásobník + Carregador de 30 projéteis AP de 6,5 mm + Caricatore 6.5 mm 30cp AP Магазин из 30-ти 6,5 мм бронебойных - 6.5mm 30 発入り徹甲弾 弾倉 - 30발들이 6.5mm 철갑탄 탄창 - 6.5mm 30發 穿甲彈 彈匣 - 6.5mm 30发 穿甲弹 弹匣 + 6.5 mm 30Rnd 徹甲弾 マガジン + 30발 들이 6.5mm 철갑탄 탄창 + 6.5毫米30發 穿甲彈 彈匣 + 6.5 mm 30发 弹匣(穿甲) + 6.5 mm 30Rnd AP Mag - 6.5mm AP - 6,5mm Páncéltörő - 6,5mm AP - 6,5mm AP - 6,5mm AP - 6,5mm AP - 6.5mm AP - 6,5mm AP - 6.5mm AP + 6.5 mm AP + 6,5 mm Páncéltörő + 6,5 mm AP + 6,5 mm AP + 6,5 mm AP + 6,5 mm AP + 6.5 mm AP + 6,5 mm AP + 6.5 mm AP 6,5 мм бронебойные - 6.5mm 徹甲弾 + 6.5 mm 徹甲弾 6.5mm 철갑탄 - 6.5mm 穿甲彈 - 6.5mm 穿甲弹 + 6.5毫米 穿甲彈 + 6.5 mm 穿甲 + 6.5 mm AP - Caliber: 6.5x39mm AP<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL - Kaliber: 6,5x39mm Páncéltörő<br />Lövedékek: 30<br />Használható: MX/C/M/SW/3GL - Kaliber: 6,5x39mm AP<br />Patronen: 30<br />Eingesetzt von: MX/C/M/SW/3GL - Calibre: 6,5x39mm AP<br />Balas: 30<br />Se usa en: MX/C/M/SW/3GL - Calibre: 6,5x39mm AP<br />Cartouches: 30<br />Utilisé avec: MX/C/M/SW/3GL - Kaliber: 6,5x39mm AP<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL - Ráže: 6.5x39mm AP<br />Nábojů: 30<br />Použití u: MX - Calibre: 6,5x39mm AP<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL - Calibro: 6.5x39mm AP<br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL + Caliber: 6.5x39 mm AP<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm Páncéltörő<br />Lövedékek: 30<br />Használható: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm AP<br />Patronen: 30<br />Eingesetzt von: MX/C/M/SW/3GL + Calibre: 6,5x39 mm AP<br />Balas: 30<br />Se usa en: MX/C/M/SW/3GL + Calibre: 6,5x39 mm AP<br />Cartouches: 30<br />Utilisé avec: MX/C/M/SW/3GL + Kaliber: 6,5x39 mm AP<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL + Ráže: 6.5x39 mm AP<br />Nábojů: 30<br />Použití u: MX + Calibre: 6,5x39 mm AP<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL + Calibro: 6.5x39 mm AP<br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм бронебойные<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL - 口径: 6.5x39mm 徹甲弾<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL - 구경: 6.5x39mm 철갑탄<br />장탄수: 30<br />사용처: MX/C/M/SW/3GL - 口徑: 6.5x39mm 穿甲彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL - 口径: 6.5x39mm 穿甲弹<br />发数: 30<br />使用于: MX/C/M/SW/3GL + 口径: 6.5x39 mm 徹甲弾<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 구경: 6.5x39mm 철갑탄<br/>장탄수: 30<br/>사용처: MX/C/M/SW/3GL + 口徑: 6.5x39毫米 穿甲彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL + 口径:6.5x39 mm 穿甲<br />发数:30<br />使用于:MX/C/M/SW/3GL + Kalibre: 6.5x39 mm AP<br />Mermi: 30<br />Kullanıyor: MX/C/M/SW/3GL - 6.5mm 30Rnd Tracer IR-DIM Mag - 6,5mm IR-DIM Nyomjelző 30-as Tár - 6,5mm 30-Patronen-Magazin Leuchtspur IR-DIM - Cargador de 30 balas trazadoras IR-DIM de 6,5mm - Ch. 6,5mm 30Cps Traçantes IR-DIM - Magazynek 6,5mm 30rd Smugacz IR-DIM - 6.5mm 30náb. Svítící IR-DIM Zásobník - Carregador de 30 projéteis traçantes IR-DIM de 6,5mm - Caricatore 6.5mm 30Rnd Traccianti IR-DIM + 6.5 mm 30Rnd Tracer IR-DIM Mag + 6,5 mm IR-DIM Nyomjelző 30-as Tár + 6,5 mm 30-Patronen-Magazin Leuchtspur IR-DIM + Cargador de 30 balas trazadoras IR-DIM de 6,5 mm + Ch. 6,5 mm 30Cps Traçantes IR-DIM + Magazynek 6,5 mm 30rd Smugacz IR-DIM + 6.5 mm 30náb. Svítící IR-DIM Zásobník + Carregador de 30 projéteis traçantes IR-DIM de 6,5 mm + Caricatore 6.5 mm 30cp Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих - 6.5mm 30発入り IR-DIM曳光弾 弾倉 - 30발들이 6.5mm IR-DIM 예광탄 탄창 - 6.5mm 30發 低視度紅外線曳光彈 彈匣 - 6.5mm 30发 低视度红外线曳光弹 弹匣 + 6.5 mm 30Rnd IR-DIM トレーサー マガジン + 30발 들이 6.5mm IR-DIM 예광탄 탄창 + 6.5毫米 30發 低視度紅外線曳光彈 彈匣 + 6.5 mm 30发 弹匣(红外曳光) + 6.5 mm 30Rnd Tracer IR-DIM Mag - 6.5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6.5mm IR-DIM - 6,5mm IR-DIM - 6.5mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm IR-DIM + 6.5 mm IR-DIM 6,5 мм ИК-трассирующие - 6.5mm IR-DIM曳光弾 + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 - 6.5mm 低視紅外曳光彈 - 6.5mm 低视红外曳光弹 + 6.5毫米 低視紅外曳光彈 + 6.5 mm 红外曳光 + 6.5 mm IR-DIM - Caliber: 6.5x39mm Tracer IR-DIM<br />Rounds: 30<br />Used in: Katiba - Kaliber: 6,5x39mm Nyomjelző IR-DIM<br />Lövedékek: 30<br />Használható: Katiba - Kaliber: 6,5x39mm Leuchtspur IR-DIM<br />Patronen: 30<br />Eingesetzt von: Katiba - Calibre: 6,5x39mm Trazadoras IR-DIM<br />Balas: 30<br />Se usa en: Katiba - Calibre: 6,5x39mm Traçantes IR-DIM<br />Cartouches: 30<br />Utilisé avec: Katiba - Kaliber: 6,5x39mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: Katiba - Ráže: 6.5x39mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: KH 2002 Sama - Calibre: 6,5x39mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: Katiba - Calibro: 6.5x39mm Tracciant IR-DIM<br />Munizioni: 30<br />In uso su: Katiba + Caliber: 6.5x39 mm Tracer IR-DIM<br />Rounds: 30<br />Used in: Katiba + Kaliber: 6,5x39 mm Nyomjelző IR-DIM<br />Lövedékek: 30<br />Használható: Katiba + Kaliber: 6,5x39 mm Leuchtspur IR-DIM<br />Patronen: 30<br />Eingesetzt von: Katiba + Calibre: 6,5x39 mm Trazadoras IR-DIM<br />Balas: 30<br />Se usa en: Katiba + Calibre: 6,5x39 mm Traçantes IR-DIM<br />Cartouches: 30<br />Utilisé avec: Katiba + Kaliber: 6,5x39 mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: Katiba + Ráže: 6.5x39 mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: KH 2002 Sama + Calibre: 6,5x39 mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: Katiba + Calibro: 6.5x39 mm Tracciant IR-DIM<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: Katiba - 口径: 6.5x39mm IR-DIM曳光弾<br />装填数: 30<br />次で使用: Katiba - 구경: 6.5x39mm IR-DIM 예광탄<br />장탄수: 30<br />사용처: Katiba - 口徑: 6.5x39mm 低視度紅外線曳光彈<br />發數: 30<br />使用於: Katiba - 口径: 6.5x39mm 低视度红外线曳光弹<br />发数: 30<br />使用于: Katiba + 口径: 6.5x39 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: Katiba + 구경: 6.5x39mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: KH-2002 + 口徑: 6.5x39毫米 低視度紅外線曳光彈<br />發數: 30<br />使用於: Katiba + 口径:6.5x39 mm 红外曳光<br />发数:30<br />使用于:Katiba + Kalibre: 6.5x39 mm Tracer IR-DIM<br />Mermi: 30<br />Kullanıyor: Katiba - 6.5mm 30Rnd SD Mag - 6,5mm Halk 30-as Tár - 6,5mm 30-Patronen-Magazin SD - Cargador de 30 balas SD de 6,5mm - Ch. 6,5mm 30Cps SD - Magazynek 6,5mm 30rd SD - 6.5mm 30náb. SD Zásobník - Carregador de 30 projéteis SD de 6,5mm - Caricatore 6.5mm 30Rnd Sil. + 6.5 mm 30Rnd SD Mag + 6,5 mm Halk 30-as Tár + 6,5 mm 30-Patronen-Magazin SD + Cargador de 30 balas SD de 6,5 mm + Ch. 6,5 mm 30Cps SD + Magazynek 6,5 mm 30rd SD + 6.5 mm 30náb. SD Zásobník + Carregador de 30 projéteis SD de 6,5 mm + Caricatore 6.5 mm 30cp Sil. Магазин из 30-ти 6,5 мм дозвуковых - 6.5mm 30発入り 亜音速弾 弾倉 - 30발들이 6.5mm 아음속탄 탄창 - 6.5mm 30發 消音彈 彈匣 - 6.5mm 30发 消音弹 弹匣 + 6.5 mm 30Rnd 亜音速弾 マガジン + 30발 들이 6.5mm 아음속탄 탄창 + 6.5毫米 30發 消音彈 彈匣 + 6.5 mm 30发 弹匣(亚音速) + 6.5 mm 30Rnd SD Mag - 6.5mm SD - 6,5mm Halk - 6,5mm SD - 6,5mm SD - 6,5mm SD - 6,5mm SD - 6.5mm SD - 6,5mm SD - 6.5mm Sil. + 6.5 mm SD + 6,5 mm Halk + 6,5 mm SD + 6,5 mm SD + 6,5 mm SD + 6,5 mm SD + 6.5 mm SD + 6,5 mm SD + 6.5 mm Sil. 6,5 мм дозвуковые - 6.5mm 亜音速弾 + 6.5 mm SD 6.5mm 아음속탄 - 6.5mm 消音彈 - 6.5mm 消音弹 + 6.5毫米 消音彈 + 6.5 mm 亚音速 + 6.5 mm SD - Caliber: 6.5x39mm SD<br />Rounds: 30<br />Used in: Katiba - Kaliber: 6,5x39mm Halk<br />Lövedékek: 30<br />Használható: Katiba - Kaliber: 6,5x39mm SD<br />Patronen: 30<br />Eingesetzt von: Katiba - Calibre: 6,5x39mm SD<br />Balas: 30<br />Se usa en: Katiba - Calibre: 6,5x39mm SD<br />Cartouches: 30<br />Utilisé avec: Katiba - Kaliber: 6,5x39mm SD<br />Naboje: 30<br />Używane w: Katiba - Ráže: 6.5x39mm SD<br />Nábojů: 30<br />Použití u: KH 2002 Sama - Calibre: 6,5x39mm SD<br />Projéteis: 30<br />Usado em: Katiba - Calibro: 6.5x39mm Sil.<br />Munizioni: 30<br />In uso su: Katiba + Caliber: 6.5x39 mm SD<br />Rounds: 30<br />Used in: Katiba + Kaliber: 6,5x39 mm Halk<br />Lövedékek: 30<br />Használható: Katiba + Kaliber: 6,5x39 mm SD<br />Patronen: 30<br />Eingesetzt von: Katiba + Calibre: 6,5x39 mm SD<br />Balas: 30<br />Se usa en: Katiba + Calibre: 6,5x39 mm SD<br />Cartouches: 30<br />Utilisé avec: Katiba + Kaliber: 6,5x39 mm SD<br />Naboje: 30<br />Używane w: Katiba + Ráže: 6.5x39 mm SD<br />Nábojů: 30<br />Použití u: KH 2002 Sama + Calibre: 6,5x39 mm SD<br />Projéteis: 30<br />Usado em: Katiba + Calibro: 6.5x39 mm Sil.<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм дозвуковые<br />Патронов: 30<br />Используются с: Katiba - 口径: 6.5x39mm 亜音速弾<br />装填数: 30<br />次で使用: Katiba - 구경: 6.5x39mm 아음속탄<br />장탄수: 30<br />사용처: Katiba - 口徑: 6.5x39mm 消音彈<br />發數: 30<br />使用於: Katiba - 口径: 6.5x39mm 消音弹<br />发数: 30<br />使用于: Katiba + 口径: 6.5x39 mm 亜音速弾<br />装填数: 30<br />次で使用: Katiba + 구경: 6.5x39mm 아음속탄<br/>장탄수: 30<br/>사용처: KH-2002 + 口徑: 6.5x39毫米 消音彈<br />發數: 30<br />使用於: Katiba + 口径:6.5x39 mm 亚音速<br />发数:30<br />使用于:Katiba + Kalibre: 6.5x39 mm SD<br />Mermi: 30<br />Kullanıyor: Katiba - 6.5mm 30Rnd AP Mag - 6,5mm Páncéltörő 30-as Tár - 6,5mm 30-Patronen-Magazin AP - Cargador de 30 balas AP de 6,5mm - Ch. 6,5mm 30Cps AP - Magazynek 6,5mm 30rd AP - 6.5mm 30náb. AP Zásobník - Carregador de 30 projéteis AP de 6,5mm - Caricatore 6.5mm 30Rnd AP + 6.5 mm 30Rnd AP Mag + 6,5 mm Páncéltörő 30-as Tár + 6,5 mm 30-Patronen-Magazin AP + Cargador de 30 balas AP de 6,5 mm + Ch. 6,5 mm 30Cps AP + Magazynek 6,5 mm 30rd AP + 6.5 mm 30náb. AP Zásobník + Carregador de 30 projéteis AP de 6,5 mm + Caricatore 6.5 mm 30cp AP Магазин из 30-ти 6,5 мм бронебойных - 6.5mm 30 発入り徹甲弾 弾倉 - 30발들이 6.5mm 철갑탄 탄창 - 6.5mm 30發 穿甲彈 彈匣 - 6.5mm 30发 穿甲弹 弹匣 + 6.5 mm 30Rnd 徹甲弾 マガジン + 30발 들이 6.5mm 철갑탄 탄창 + 6.5毫米 30發 穿甲彈 彈匣 + 6.5 mm 30发 弹匣(穿甲) + 6.5 mm 30Rnd AP Mag - 6.5mm AP - 6,5mm Páncéltörő - 6,5mm AP - 6,5mm AP - 6,5mm AP - 6,5mm AP - 6.5mm AP - 6,5mm AP - 6.5mm AP + 6.5 mm AP + 6,5 mm Páncéltörő + 6,5 mm AP + 6,5 mm AP + 6,5 mm AP + 6,5 mm AP + 6.5 mm AP + 6,5 mm AP + 6.5 mm AP 6,5 мм бронебойные - 6.5mm 徹甲弾 + 6.5 mm AP 6.5mm 철갑탄 - 6.5mm 穿甲彈 - 6.5mm 穿甲弹 + 6.5毫米 穿甲彈 + 6.5 mm 穿甲 + 6.5 mm AP - Caliber: 6.5x39mm AP<br />Rounds: 30<br />Used in: Katiba - Kaliber: 6,5x39mm Páncéltörő<br />Lövedékek: 30<br />Használható: Katiba - Kaliber: 6,5x39mm AP<br />Patronen: 30<br />Eingesetzt von: Katiba - Calibre: 6,5x39mm AP<br />Balas: 30<br />Se usa en: Katiba - Calibre: 6,5x39mm AP<br />Cartouches: 30<br />Utilisé avec: Katiba - Kaliber: 6,5x39mm AP<br />Pociski: 30<br />Używane w: Katiba - Ráže: 6.5x39mm AP<br />Nábojů: 30<br />Použití u: KH 2002 Sama - Calibre: 6,5x39mm AP<br />Projéteis: 30<br />Usado em: Katiba - Calibro: 6.5x39mm AP<br />Munizioni: 30<br />In uso su: Katiba + Caliber: 6.5x39 mm AP<br />Rounds: 30<br />Used in: Katiba + Kaliber: 6,5x39 mm Páncéltörő<br />Lövedékek: 30<br />Használható: Katiba + Kaliber: 6,5x39 mm AP<br />Patronen: 30<br />Eingesetzt von: Katiba + Calibre: 6,5x39 mm AP<br />Balas: 30<br />Se usa en: Katiba + Calibre: 6,5x39 mm AP<br />Cartouches: 30<br />Utilisé avec: Katiba + Kaliber: 6,5x39 mm AP<br />Pociski: 30<br />Używane w: Katiba + Ráže: 6.5x39 mm AP<br />Nábojů: 30<br />Použití u: KH 2002 Sama + Calibre: 6,5x39 mm AP<br />Projéteis: 30<br />Usado em: Katiba + Calibro: 6.5x39 mm AP<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм бронебойные<br />Патронов: 30<br />Используются с: Katiba - 口径: 6.5x39mm 徹甲弾<br />装填数: 30<br />次で使用: Katiba - 구경: 6.5x39mm 철갑탄<br />장탄수: 30<br />사용처: Katiba - 口徑: 6.5x39mm 穿甲彈<br />發數: 30<br />使用於: Katiba - 口径: 6.5x39mm 穿甲弹<br />发数: 30<br />使用于: Katiba + 口径: 6.5x39 mm 徹甲弾<br />装填数: 30<br />次で使用: Katiba + 구경: 6.5x39mm 철갑탄<br/>장탄수: 30<br/>사용처: KH-2002 + 口徑: 6.5x39m毫米 穿甲彈<br />發數: 30<br />使用於: Katiba + 口径:6.5x39 mm 穿甲<br />发数:30<br />使用于:Katiba + Kalibre: 6.5x39 mm AP<br />Mermi: 30<br />Kullanıyor: Katiba - + - 5.56mm 30rnd Tracer IR-DIM Mag - 5,56mm Nyomjelző IR-DIM 30-as Tár - 5,56mm 30-Patronen-Magazin Leuchtspur IR-DIM - Cargador de 30 balas trazadoras IR-DIM de 5,56mm - Ch. 5,56mm 30Cps Traçantes IR-DIM - Magazynek 5,56mm 30rd Smugacz IR-DIM - 5.56mm 30náb. Svítící IR-DIM Zásobník - Carregador de 30 projéteis traçantes IR-DIM de 5,56mm - Caricatore 5.56mm 30rnd Traccianti IR-DIM + 5.56 mm 30rnd Tracer IR-DIM Mag + 5,56 mm Nyomjelző IR-DIM 30-as Tár + 5,56 mm 30-Patronen-Magazin Leuchtspur IR-DIM + Cargador de 30 balas trazadoras IR-DIM de 5,56 mm + Ch. 5,56 mm 30Cps Traçantes IR-DIM + Magazynek 5,56 mm 30rd Smugacz IR-DIM + 5.56 mm 30náb. Svítící IR-DIM Zásobník + Carregador de 30 projéteis traçantes IR-DIM de 5,56 mm + Caricatore 5.56 mm 30cp Traccianti IR-DIM Магазин из 30-ти 5,56 мм ИК-трассирующих - 5.56mm 30発入り IR-DIM曳光弾 弾倉 + 5.56mm 30Rnd IR-DIM トレーサー マガジン 30발 들이 5.56mm IR-DIM 예광탄 탄창 - 5.56mm 30發 低視度紅外線曳光彈 彈匣 - 5.56mm 30发 低视度红外线曳光弹 弹匣 + 5.56毫米 30發 低視度紅外線曳光彈 彈匣 + 5.56 mm 30发 弹匣(红外曳光) + 5.56 mm 30rnd Tracer IR-DIM Mag - 5.56mm IR-DIM - 5,56mm IR-DIM - 5,56mm IR-DIM - 5,56mm IR-DIM - 5,56mm IR-DIM - 5,56mm IR-DIM - 5.56mm IR-DIM - 5,56mm IR-DIM - 5.56mm IR-DIM + 5.56 mm IR-DIM + 5,56 mm IR-DIM + 5,56 mm IR-DIM + 5,56 mm IR-DIM + 5,56 mm IR-DIM + 5,56 mm IR-DIM + 5.56 mm IR-DIM + 5,56 mm IR-DIM + 5.56 mm IR-DIM 5,56 мм ИК-трассирующие - 5.56mm IR-DIM曳光弾 + 5.56 mm IR-DIM 5.56mm IR-DIM 예광탄 - 5.56mm 低視紅外曳光彈 - 5.56mm 低视红外曳光弹 + 5.56毫米 低視紅外曳光彈 + 5.56 mm 红外曳光 + 5.56 mm IR-DIM - Caliber: 5.56x45mm Tracer IR-DIM<br />Rounds: 30<br />Used in: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Kaliber: 5,56x45mm Nyomjelző IR-DIM<br />Lövedékek: 30<br />Használható: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Kaliber: 5,56x45mm Leuchtspur IR-DIM<br />Patronen: 30<br />Eingesetzt von: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Calibre: 5,56x45mm Trazadoras IR-DIM<br />Balas: 30<br />Se usa en: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Calibre: 5,56x45mm Traçantes IR-DIM<br />Cartouches: 30<br />Utilisé avec: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Kaliber: 5,56x45mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Ráže: 5.56x45mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: CTAR-21, TAR-21, F2000, RFB SDAR - Calibre: 5,56x45mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Calibro: 5.56x45mm Traccianti IR-DIM<br />Munizioni: 30<br />In uso su: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Caliber: 5.56x45 mm Tracer IR-DIM<br />Rounds: 30<br />Used in: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Kaliber: 5,56x45 mm Nyomjelző IR-DIM<br />Lövedékek: 30<br />Használható: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Kaliber: 5,56x45 mm Leuchtspur IR-DIM<br />Patronen: 30<br />Eingesetzt von: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Calibre: 5,56x45 mm Trazadoras IR-DIM<br />Balas: 30<br />Se usa en: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Calibre: 5,56x45 mm Traçantes IR-DIM<br />Cartouches: 30<br />Utilisé avec: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Kaliber: 5,56x45 mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Ráže: 5.56x45 mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: CTAR-21, TAR-21, F2000, RFB SDAR + Calibre: 5,56x45 mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Calibro: 5.56x45 mm Tracciante IR-DIM<br />Munizioni: 30<br />In uso su: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR Калибр: 5,56x45 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - 口径: 5.56x45mm IR-DIM曳光弾<br />装填数: 30<br />次で使用: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - 구경: 5.56x45mm IR-DIM 예광탄<br />장탄수: 30<br />사용처: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - 口徑: 5.56x45mm 低視度紅外線曳光彈<br />發數: 30<br />使用於: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - 口径: 5.56x45mm 低视度红外线曳光弹<br />发数: 30<br />使用于: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 口径: 5.56x45 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 구경: 5.56x45 mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: CTAR-21, TAR-21/GTAR-21 EGLM, F2000/택티컬/EGLM, SDAR + 口徑: 5.56x45毫米 低視度紅外線曳光彈<br />發數: 30<br />使用於: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 口径:5.56x45 mm 红外曳光<br />发数:30<br />使用于:TRG-20,TRG-21/EGLM, Mk20/C/EGLM, SDAR + Kalibre: 5.56x45 mm Tracer IR-DIM<br />Mermi: 30<br />Kullanıyor: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - + - 7.62mm 20rnd Tracer Mag - 7,62mm Nyomjelző IR-DIM 20-as Tár - 7,62mm 20-Patronen-Magazin Leuchtspur - Cargador de 20 balas trazadores de 7,62mm - Ch. 7,62mm 20Cps Traçantes - Magazynek 7,62mm 20rd Smugacz - 7.62mm 20náb. Svítící Zásobník - Carregador de 20 projéteis traçantes de 7,62mm - Caricatore 7.62mm 20Rnd Traccianti + 7.62 mm 20Rnd Mag (Tracer) + 7,62 mm Nyomjelző IR-DIM 20-as Tár + 7,62 mm 20-Patronen-Magazin Leuchtspur + Cargador de 20 balas trazadores de 7,62 mm + Ch. 7,62 mm 20Cps Traçantes + Magazynek 7,62 mm 20rd Smugacz + 7.62 mm 20náb. Svítící Zásobník + Carregador de 20 projéteis traçantes de 7,62 mm + Caricatore 7.62 mm 20cp Traccianti Магазин из 20-ти 7,62 мм трассирующих - 7.62mm 20発入り 曳光弾 - 20발들이 7.62mm 예광탄 탄창 - 7.62mm 20發 曳光彈 彈匣 - 7.62mm 20发 曳光弹 弹匣 + 7.62mm 20Rnd マガジン (トレーサー) + 20발 들이 7.62mm 예광탄 탄창 + 7.62毫米 20發 曳光彈 彈匣 + 7.62 mm 20发 弹匣(曳光) + 7.62 mm 20Rnd Mag (Tracer) - 7.62mm Tracer - 7,62mm Nyomjelző - 7,62mm Leuchtspur - 7,62mm Trazadora - 7,62mm Traçantes - 7,62mm Smugacz - 7.62mm Svítící - 7,62mm Traçante - 7.62mm Traccianti + 7.62 mm Tracer + 7,62 mm Nyomjelző + 7,62 mm Leuchtspur + 7,62 mm Trazadora + 7,62 mm Traçante + 7,62 mm Smugacz + 7.62 mm Svítící + 7,62 mm Traçante + 7.62 mm Tracciante 7,62 мм трассирущие - 7.62mm 曳光弾 + 7.62 mm トレーサー 7.62mm 예광탄 - 7.62mm 曳光彈 - 7.62mm 曳光弹 + 7.62毫米 曳光彈 + 7.62 mm 曳光 + 7.62 mm İzli - Caliber: 7.62x51mm Tracer<br />Rounds: 20<br />Used in: Mk18 ABR - Kaliber: 7,62x51mm Nyomjelző<br />Lövedékek: 20<br />Használható: Mk18 ABR - Kaliber: 7,62x51mm Leuchtspur<br />Patronen: 20<br />Eingesetzt von: EBR - Calibre: 7,62x51mm Trazadora<br />Balas: 20<br />Se usa en: Mk18 ABR - Calibre: 7,62x51mm Traçantes<br />Cartouches: 20<br />Utilisé avec: EBR - Kaliber: 7,62x51mm Smugacz<br />Pociski: 20<br />Używane w: Mk18 ABR - Ráže: 7.62x51mm Svítící<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR - Calibre: 7,62x51mm Traçante<br />Projéteis: 20<br />Usado em: Mk18 ABR - Calibro: 7.62x51mm Traccianti<br />Munizioni: 20<br />In uso su: Mk18 ABR + Caliber: 7.62x51 mm Tracer<br />Rounds: 20<br />Used in: Mk18 ABR + Kaliber: 7,62x51 mm Nyomjelző<br />Lövedékek: 20<br />Használható: Mk18 ABR + Kaliber: 7,62x51 mm Leuchtspur<br />Patronen: 20<br />Eingesetzt von: EBR + Calibre: 7,62x51 mm Trazadora<br />Balas: 20<br />Se usa en: Mk18 ABR + Calibre: 7,62x51 mm Traçante<br />Cartouches: 20<br />Utilisé avec: Mk18 ABR + Kaliber: 7,62x51 mm Smugacz<br />Pociski: 20<br />Używane w: Mk18 ABR + Ráže: 7.62x51 mm Svítící<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR + Calibre: 7,62x51 mm Traçante<br />Projéteis: 20<br />Usado em: Mk18 ABR + Calibro: 7.62x51 mm Tracciante<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм трассирующие<br />Патронов: 20<br />Используются с: Mk18 ABR - 口径: 7.62x51mm 曳光弾<br />装填数: 20<br />次で使用: Mk18 ABR - 구경: 7.62x51mm 예광탄<br />장탄수: 20<br />사용처: Mk18 ABR - 口徑: 7.62x51mm 曳光彈<br />發數: 20<br />使用於: Mk18 ABR - 口径: 7.62x51mm 曳光弹<br />发数: 20<br />使用于: Mk18 ABR + 口径: 7.62x51 mm トレーサー<br />装填数: 20<br />次で使用: Mk18 ABR + 구경: 7.62x51mm 예광탄<br/>장탄수: 20<br/>사용처: Mk.14 Mod 1 EBR + 口徑: 7.62x51毫米 曳光彈<br />發數: 20<br />使用於: Mk18 ABR + 口径:7.62x51 mm 曳光<br />发数:20<br />使用于:Mk18 ABR + Kalibre: 7.62x51 mm Tracer<br />Mermi: 20<br />Kullanıyor: Mk18 ABR - 7.62mm 20rnd Tracer IR-DIM Mag - 7,62mm Nyomjelző IR-DIM 20-as Tár - 7,62mm 20-Patronen-Magazin Leuchtspur IR-DIM - Cargador de 20 balas trazadoras IR-DIM de 7,62mm - Ch. 7,62mm 20Cps Traçantes IR-DIM - Magazynek 7,62mm 20rd Smugacz IR-DIM - 7.62mm 20náb. Svítící IR-DIM Zásobník - Carregador de 20 projéteis IR-DIM de 7,62mm - Caricatore 7.62mm 20rnd Traccianti IR-DIM + 7.62 mm 20Rnd Mag (IR-DIM) + 7,62 mm Nyomjelző IR-DIM 20-as Tár + 7,62 mm 20-Patronen-Magazin Leuchtspur IR-DIM + Cargador de 20 balas trazadoras IR-DIM de 7,62 mm + Ch. 7,62 mm 20Cps Traçantes IR-DIM + Magazynek 7,62 mm 20rd Smugacz IR-DIM + 7.62 mm 20náb. Svítící IR-DIM Zásobník + Carregador de 20 projéteis IR-DIM de 7,62 mm + Caricatore 7.62 mm 20cp Traccianti IR-DIM Магазин из 20-ти 7,62 мм ИК-трассирующих - 7.62mm 20発入り IR-DIM曳光弾 - 20발들이 7.62mm IR-DIM 예광탄 탄창 - 7.62mm 20發 低視度紅外線曳光彈 彈匣 - 7.62mm 20发 低视度红外线曳光弹 弹匣 + 7.62mm 20Rnd マガジン (IR-DIM) + 20발 들이 7.62mm IR-DIM 예광탄 탄창 + 7.62毫米 20發 低視度紅外線曳光彈 彈匣 + 7.62 mm 20发 弹匣(红外曳光) + 7.62 mm 20Rnd Mag (IR-DIM) - 7.62mm IR-DIM - 7,62mm IR-DIM - 7,62mm IR-DIM - 7,62mm IR-DIM - 7,62mm IR-DIM - 7,62mm IR-DIM - 7.62mm IR-DIM - 7,62mm IR-DIM - 7.62mm IR-DIM + 7.62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7.62 mm IR-DIM + 7,62 mm IR-DIM + 7.62 mm IR-DIM 7,62 мм ИК-трассирующие - 7.62mm IR-DIM曳光弾 + 7.62 mm IR-DIM 7.62mm IR-DIM 예광탄 - 7.62mm 低視紅外曳光彈 - 7.62mm 低视红外曳光弹 + 7.62毫米 低視紅外曳光彈 + 7.62 mm 红外曳光 + 7.62 mm IR-DIM - Caliber: 7.62x51mm Tracer IR-DIM<br />Rounds: 20<br />Used in: Mk18 ABR - Kaliber: 7,62x51mm Nyomjelző IR-DIM<br />Lövedékek: 20<br />Használható: Mk18 ABR - Kaliber: 7,62x51mm Leuchtspur IR-DIM<br />Patronen: 20<br />Eingesetzt von: EBR - Calibre: 7,62x51mm Trazadoras IR-DIM<br />Balas: 20<br />Se usa en: Mk18 ABR - Calibre: 7,62x51mm Traçantes IR-DIM<br />Cartouches: 20<br />Utilisé avec: EBR - Kaliber: 7,62x51mm Smugacz IR-DIM<br />Pociski: 20<br />Używane w: Mk18 ABR - Ráže: 7.62x51mm Svítící IR-DIM<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR - Calibre: 7,62x51mm Traçante IR-DIM<br />Projéteis: 20<br />Usado em: Mk18 ABR - Calibro: 7.62x51mm Traccianti IR-DIM<br />Munizioni: 20<br />In uso su: Mk18 ABR + Caliber: 7.62x51 mm Tracer IR-DIM<br />Rounds: 20<br />Used in: Mk18 ABR + Kaliber: 7,62x51 mm Nyomjelző IR-DIM<br />Lövedékek: 20<br />Használható: Mk18 ABR + Kaliber: 7,62x51 mm Leuchtspur IR-DIM<br />Patronen: 20<br />Eingesetzt von: EBR + Calibre: 7,62x51 mm Trazadoras IR-DIM<br />Balas: 20<br />Se usa en: Mk18 ABR + Calibre: 7,62x51 mm Traçante IR-DIM<br />Cartouches: 20<br />Utilisé avec: Mk18 ABR + Kaliber: 7,62x51 mm Smugacz IR-DIM<br />Pociski: 20<br />Używane w: Mk18 ABR + Ráže: 7.62x51 mm Svítící IR-DIM<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR + Calibre: 7,62x51 mm Traçante IR-DIM<br />Projéteis: 20<br />Usado em: Mk18 ABR + Calibro: 7.62x51 mm Traccianti IR-DIM<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм ИК-трассирующие<br />Патронов: 20<br />Используются с: Mk18 ABR - 口径: 7.62x51mm IR-DIM曳光弾<br />装填数: 20<br />次で使用: Mk18 ABR - 구경: 7.62x51mm IR-DIM 예광탄<br />장탄수: 20<br />사용처: Mk18 ABR - 口徑: 7.62x51mm 低視度紅外線曳光彈<br />發數: 20<br />使用於: Mk18 ABR - 口径: 7.62x51mm 低视度红外线曳光弹<br />发数: 20<br />使用于: Mk18 ABR + 口径: 7.62x51 mm IR-DIM トレーサー<br />装填数: 20<br />次で使用: Mk18 ABR + 구경: 7.62x51mm IR-DIM 예광탄<br/>장탄수: 20<br/>사용처: Mk.14 Mod 1 EBR + 口徑: 7.62x51毫米 低視度紅外線曳光彈<br />發數: 20<br />使用於: Mk18 ABR + 口径:7.62x51 mm 红外曳光<br />发数:20<br />使用于:Mk18 ABR + Kalibre: 7.62x51 mm Tracer IR-DIM<br />Mermi: 20<br />Kullanıyor: Mk18 ABR - 7.62mm 20Rnd SD Mag - 7,62mm Halk 20-as Tár - 7,62mm 20-Patronen-Magazin SD - Cargador de 20 balas SD de 7,62mm - Ch. 7,62mm 20Cps SD - Magazynek 7,62mm 20rd SD - 7.62mm 20náb. SD Zásobník - Carregador de 20 projéteis SD de 7,62mm - Caricatore 7.62mm 20Rnd Sil. + 7.62 mm 20Rnd Mag (SD) + 7,62 mm Halk 20-as Tár + 7,62 mm 20-Patronen-Magazin SD + Cargador de 20 balas SD de 7,62 mm + Ch. 7,62 mm 20Cps SD + Magazynek 7,62 mm 20rd SD + 7.62 mm 20náb. SD Zásobník + Carregador de 20 projéteis SD de 7,62 mm + Caricatore 7.62 mm 20cp Sil. Магазин из 20-ти 7,62 мм дозвуковых - 7.62mm 20発入り 亜音速弾 弾倉 - 20발들이 7.62mm 아음속탄 탄창 - 7.62mm 20發 消音彈 彈匣 - 7.62mm 20发 消音弹 弹匣 + 7.62mm 20Rnd マガジン (亜音速弾) + 20발 들이 7.62mm 아음속탄 탄창 + 7.62毫米 20發 消音彈 彈匣 + 7.62 mm 20发 弹匣(亚音速) + 7.62 mm 20Rnd Mag (SD) - 7.62mm SD - 7,62mm Halk - 7,62mm SD - 7,62mm SD - 7,62mm SD - 7,62mm SD - 7.62mm SD - 7,62mm SD - 7.62mm Sil. + 7.62 mm SD + 7,62 mm Halk + 7,62 mm SD + 7,62 mm SD + 7,62 mm SD + 7,62 mm SD + 7.62 mm SD + 7,62 mm SD + 7.62 mm Sil. 7,62 мм дозвуковые - 7.62mm 亜音速弾 + 7.62 mm SD 7.62mm 아음속탄 - 7.62mm 消音彈 - 7.62mm 消音弹 + 7.62毫米 消音彈 + 7.62 mm 亚音速 + 7.62 mm SD - Caliber: 7.62x51mm SD<br />Rounds: 20<br />Used in: Mk18 ABR - Kaliber: 7,62x51mm Halk<br />Lövedékek: 20<br />Használható: Mk18 ABR - Kaliber: 7,62x51mm SD<br />Patronen: 20<br />Eingesetzt von: EBR - Calibre: 7,62x51mm SD<br />Balas: 20<br />Se usa en: Mk18 ABR - Calibre: 7,62x51mm SD<br />Cartouches: 20<br />Utilisé avec: EBR - Kaliber: 7,62x51mm SD<br />Pociski: 20<br />Używane w: Mk18 ABR - Ráže: 7.62x51mm SD<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR - Calibre: 7,62x51mm SD<br />Projéteis: 20<br />Usado em: Mk18 ABR - Calibro: 7.62x51mm Sil.<br />Munizioni: 20<br />In uso su: Mk18 ABR + Caliber: 7.62x51 mm SD<br />Rounds: 20<br />Used in: Mk18 ABR + Kaliber: 7,62x51 mm Halk<br />Lövedékek: 20<br />Használható: Mk18 ABR + Kaliber: 7,62x51 mm SD<br />Patronen: 20<br />Eingesetzt von: EBR + Calibre: 7,62x51 mm SD<br />Balas: 20<br />Se usa en: Mk18 ABR + Calibre: 7,62x51 mm SD<br />Cartouches: 20<br />Utilisé avec: Mk18 ABR + Kaliber: 7,62x51 mm SD<br />Pociski: 20<br />Używane w: Mk18 ABR + Ráže: 7.62x51 mm SD<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR + Calibre: 7,62x51 mm SD<br />Projéteis: 20<br />Usado em: Mk18 ABR + Calibro: 7.62x51 mm Sil.<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм дозвуковые<br />Патронов: 20<br />Используются с: Mk18 ABR - 口径: 7.62x51mm 亜音速弾<br />装填数: 20<br />次で使用: Mk18 ABR - 구경: 7.62x51mm SD<br />장탄수: 20<br />사용처: Mk18 ABR - 口徑: 7.62x51mm 消音彈<br />發數: 20<br />使用於: Mk18 ABR - 口径: 7.62x51mm 消音弹<br />发数: 20<br />使用于: Mk18 ABR + 口径: 7.62x51 mm 亜音速弾<br />装填数: 20<br />次で使用: Mk18 ABR + 구경: 7.62x51mm 아음속탄<br/>장탄수: 20<br/>사용처: Mk.14 Mod 1 EBR + 口徑: 7.62x51毫米 消音彈<br />發數: 20<br />使用於: Mk18 ABR + 口径:7.62x51 mm 亚音速<br />发数:20<br />使用于:Mk18 ABR + Kalibre: 7.62x51 mm SD<br />Mermi: 20<br />Kullanıyor: Mk18 ABR + + + 7.62 mm 10Rnd Mag (Tracer) + 7,62 mm Nyomjelző IR-DIM 10-as Tár + 7,62 mm 10-Patronen-Magazin Leuchtspur + Cargador de 10 balas trazadores de 7,62 mm + Ch. 7,62 mm 10Cps Traçantes + Magazynek 7,62 mm 10rd Smugacz + 7.62 mm 10náb. Svítící Zásobník + Carregador de 10 projéteis traçantes de 7,62 mm + Caricatore 7.62 mm 10cp Traccianti + Магазин из 10-ти 7,62 мм трассирующих + 7.62mm 10Rnd マガジン (トレーサー) + 10발 들이 7.62mm 예광탄 탄창 + 7.62毫米 10發 曳光彈 彈匣 + 7.62 mm 10发 弹匣(曳光) + 7.62 mm 10Rnd Mag (Tracer) + + + 7.62 mm Tracer + 7,62 mm Nyomjelző + 7,62 mm Leuchtspur + 7,62 mm Trazadora + 7,62 mm Traçante + 7,62 mm Smugacz + 7.62 mm Svítící + 7,62 mm Traçante + 7.62 mm Tracciante + 7,62 мм трассирущие + 7.62 mm トレーサー + 7.62mm 예광탄 + 7.62毫米 曳光彈 + 7.62 mm 曳光 + 7.62 mm İzli + + + Caliber: 7.62x51 mm Tracer<br />Rounds: 10<br />Used in: Mk18 ABR + Kaliber: 7,62x51 mm Nyomjelző<br />Lövedékek: 10<br />Használható: Mk18 ABR + Kaliber: 7,62x51 mm Leuchtspur<br />Patronen: 10<br />Eingesetzt von: EBR + Calibre: 7,62x51 mm Trazadora<br />Balas: 10<br />Se usa en: Mk18 ABR + Calibre: 7,62x51 mm Traçante<br />Cartouches: 10<br />Utilisé avec: Mk18 ABR + Kaliber: 7,62x51 mm Smugacz<br />Pociski: 10<br />Używane w: Mk18 ABR + Ráže: 7.62x51 mm Svítící<br />Nábojů: 10<br />Použití u: Mk14 Mod 1 EBR + Calibre: 7,62x51 mm Traçante<br />Projéteis: 10<br />Usado em: Mk18 ABR + Calibro: 7.62x51 mm Tracciante<br />Munizioni: 10<br />In uso su: Mk18 ABR + Калибр: 7,62x51 мм трассирующие<br />Патронов: 10<br />Используются с: Mk18 ABR + 口径: 7.62x51 mm トレーサー<br />装填数: 10<br />次で使用: Mk18 ABR + 구경: 7.62x51mm 예광탄<br/>장탄수: 10<br/>사용처: Mk.14 Mod 1 EBR + 口徑: 7.62x51毫米 曳光彈<br />發數: 10<br />使用於: Mk18 ABR + 口径:7.62x51 mm 曳光<br />发数:10<br />使用于:Mk18 ABR + Kalibre: 7.62x51 mm Tracer<br />Mermi: 10<br />Kullanıyor: Mk18 ABR + + + 7.62 mm 10Rnd Mag (IR-DIM) + 7,62 mm Nyomjelző IR-DIM 10-as Tár + 7,62 mm 10-Patronen-Magazin Leuchtspur IR-DIM + Cargador de 10 balas trazadoras IR-DIM de 7,62 mm + Ch. 7,62 mm 10Cps Traçantes IR-DIM + Magazynek 7,62 mm 10rd Smugacz IR-DIM + 7.62 mm 10náb. Svítící IR-DIM Zásobník + Carregador de 10 projéteis IR-DIM de 7,62 mm + Caricatore 7.62 mm 10cp Traccianti IR-DIM + Магазин из 10-ти 7,62 мм ИК-трассирующих + 7.62mm 10Rnd マガジン (IR-DIM) + 10발 들이 7.62mm IR-DIM 예광탄 탄창 + 7.62毫米 10發 低視度紅外線曳光彈 彈匣 + 7.62 mm 10发 弹匣(红外曳光) + 7.62 mm 10Rnd Mag (IR-DIM) + + + 7.62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7,62 mm IR-DIM + 7.62 mm IR-DIM + 7,62 mm IR-DIM + 7.62 mm IR-DIM + 7,62 мм ИК-трассирующие + 7.62 mm IR-DIM + 7.62mm IR-DIM 예광탄 + 7.62毫米 低視紅外曳光彈 + 7.62 mm 红外曳光 + 7.62 mm IR-DIM + + + Caliber: 7.62x51 mm Tracer IR-DIM<br />Rounds: 10<br />Used in: Mk18 ABR + Kaliber: 7,62x51 mm Nyomjelző IR-DIM<br />Lövedékek: 10<br />Használható: Mk18 ABR + Kaliber: 7,62x51 mm Leuchtspur IR-DIM<br />Patronen: 10<br />Eingesetzt von: EBR + Calibre: 7,62x51 mm Trazadoras IR-DIM<br />Balas: 10<br />Se usa en: Mk18 ABR + Calibre: 7,62x51 mm Traçante IR-DIM<br />Cartouches: 10<br />Utilisé avec: Mk18 ABR + Kaliber: 7,62x51 mm Smugacz IR-DIM<br />Pociski: 10<br />Używane w: Mk18 ABR + Ráže: 7.62x51 mm Svítící IR-DIM<br />Nábojů: 10<br />Použití u: Mk14 Mod 1 EBR + Calibre: 7,62x51 mm Traçante IR-DIM<br />Projéteis: 10<br />Usado em: Mk18 ABR + Calibro: 7.62x51 mm Tracciante IR-DIM<br />Munizioni: 10<br />In uso su: Mk18 ABR + Калибр: 7,62x51 мм ИК-трассирующие<br />Патронов: 10<br />Используются с: Mk18 ABR + 口径: 7.62x51 mm IR-DIM トレーサー<br />装填数: 10<br />次で使用: Mk18 ABR + 구경: 7.62x51mm IR-DIM 예광탄<br/>장탄수: 10<br/>사용처: Mk.14 Mod 1 EBR + 口徑: 7.62x51毫米 低視度紅外線曳光彈<br />發數: 10<br />使用於: Mk18 ABR + 口径:7.62x51 mm 红外曳光<br />发数:10<br />使用于:Mk18 ABR + Kalibre: 7.62x51 mm Tracer IR-DIM<br />Mermi: 10<br />Kullanıyor: Mk18 ABR + + + 7.62 mm 10Rnd Mag (SD) + 7,62 mm Halk 10-as Tár + 7,62 mm 10-Patronen-Magazin SD + Cargador de 10 balas SD de 7,62 mm + Ch. 7,62 mm 10Cps SD + Magazynek 7,62 mm 10rd SD + 7.62 mm 10náb. SD Zásobník + Carregador de 10 projéteis SD de 7,62 mm + Caricatore 7.62 mm 10cp Sil. + Магазин из 10-ти 7,62 мм дозвуковых + 7.62mm 10Rnd マガジン (亜音速弾) + 10발 들이 7.62mm 아음속탄 탄창 + 7.62毫米 10發 消音彈 彈匣 + 7.62 mm 10发 弹匣(亚音速) + 7.62 mm 10Rnd Mag (SD) + + + 7.62 mm SD + 7,62 mm Halk + 7,62 mm SD + 7,62 mm SD + 7,62 mm SD + 7,62 mm SD + 7.62 mm SD + 7,62 mm SD + 7.62 mm Sil. + 7,62 мм дозвуковые + 7.62 mm SD + 7.62mm 아음속탄 + 7.62毫米 消音彈 + 7.62 mm 亚音速 + 7.62 mm SD + + + Caliber: 7.62x51 mm SD<br />Rounds: 10<br />Used in: Mk18 ABR + Kaliber: 7,62x51 mm Halk<br />Lövedékek: 10<br />Használható: Mk18 ABR + Kaliber: 7,62x51 mm SD<br />Patronen: 10<br />Eingesetzt von: EBR + Calibre: 7,62x51 mm SD<br />Balas: 10<br />Se usa en: Mk18 ABR + Calibre: 7,62x51 mm SD<br />Cartouches: 10<br />Utilisé avec: Mk18 ABR + Kaliber: 7,62x51 mm SD<br />Pociski: 10<br />Używane w: Mk18 ABR + Ráže: 7.62x51 mm SD<br />Nábojů: 10<br />Použití u: Mk14 Mod 1 EBR + Calibre: 7,62x51 mm SD<br />Projéteis: 10<br />Usado em: Mk18 ABR + Calibro: 7.62x51 mm Sil.<br />Munizioni: 10<br />In uso su: Mk18 ABR + Калибр: 7,62x51 мм дозвуковые<br />Патронов: 10<br />Используются с: Mk18 ABR + 口径: 7.62x51 mm 亜音速弾<br />装填数: 10<br />次で使用: Mk18 ABR + 구경: 7.62x51 mm 아음속탄<br/>장탄수: 10<br/>사용처: Mk.14 Mod 1 EBR + 口徑: 7.62x51毫米 消音彈<br />發數: 10<br />使用於: Mk18 ABR + 口径:7.62x51 mm 亚音速<br />发数:10<br />使用于:Mk18 ABR + Kalibre: 7.62x51 mm SD<br />Mermi: 10<br />Kullanıyor: Mk18 ABR .338 NM 130Rnd Tracer Belt .338 NM 130-Patronen-Gurt Leuchtspur Taśma .338 NM 130rd Smugacz - Bande .338 NM 130Cps Traçante + Bande .338 NM 130Cps Traçantes Cinta de 130 balas trazadoras de .338 NM Лента из 130-ти .338 NM трассирующих - .338 NM 130Rnd Tracciante Belt + .338 NM 130cp Nastro Tracciante .338 NM 130náb. Svítící Pás Cinto de munição .338 NM com 130 cartuchos .338 NM 130-lövedékes nyomkövető heveder - .338 NM 130発入り 曳光弾ベルト - 130발들이 .338 NM 예광탄 벨트 - .338 NM 130發 曳光彈 彈鏈 - .338 NM 130发 曳光弹 弹链 + .338 NM 130Rnd トレーサー ベルト + 130발 들이 .338구경 노르마 매그넘 예광탄 벨트 + .338 拉普麥格農(NM) 130發 曳光彈 彈鏈 + .338 NM 130发 弹链(曳光) + .338 NM 130Rnd Tracer Belt .338 NM Tracer @@ -607,13 +1313,14 @@ .338 NM Traçante .338 NM Trazadora .338 NM трассирующие - .338 NM 130Rnd Tracciante + .338 NM 130cp Traccianti .338 NM Traçante .338 NM nyomkövető - .338 NM 曳光弾 - .338 NM 예광탄 + .338 NM トレーサー + .338구경 노르마 매그넘 예광탄 .338 NM 曳光彈 - .338 NM 曳光弹 + .338 NM 曳光 + .338 NM İzli Caliber: .338 Norma Magnum Tracer<br />Rounds: 130<br />Used in: SPMG @@ -623,13 +1330,14 @@ Calibre: .338 Norma Magnum trazadora<br />Balas: 130<br />Se usa en: SPMG Калибр: .338 Norma Magnum трассирующие<br />Патронов: 130<br />Используются в: SPMG Calibro: .338 Norma Magnum Tracciante<br />Munizioni: 130<br />In uso su: SPMG - Ráže: .338 Noma Magnum Svítící<br />Nábojů: 130<br />Použití u: LWMMG + Ráže: .338 Norma Magnum Svítící<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum Traçante<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum nyomkövető<br />Lövedékek: 130<br />Használható: SPMG - 口径: .338 Norma Magnum 曳光弾<br />装填数: 130<br />次で使用: SPMG - 구경: .338 Norma 매그넘 예광탄<br />장탄수: 130<br />사용처: SPMG - 口徑: .338 Norma Magnum 曳光彈<br />發數: 130<br />使用於: SPMG - 口径: .338 Norma Magnum 曳光弹<br />发数: 130<br />使用于: SPMG + 口径: .338 Norma Magnum トレーサー<br />装填数: 130<br />次で使用: SPMG + 구경: .338구경 노르마 매그넘 예광탄<br/>장탄수: 130<br/>사용처: LWMMG + 口徑: .338 拉普麥格農 曳光彈<br />發數: 130<br />使用於: SPMG + 口径:.338 Norma Magnum 曳光<br />发数:130<br />使用于:SPMG + Kalibre: .338 Norma Magnum Tracer<br />Mermi: 130<br />Kullanıyor: SPMG .338 NM 130Rnd IR-DIM Belt @@ -638,18 +1346,19 @@ Bande .338 NM 130Cps IR-DIM Cinta de 130 balas IR-DIM de .338 NM Лента из 130-ти .338 NM ИК-трассирующих - .338 NM 130Rnd IR-DIM Belt + .338 NM 130cp Nastro IR-DIM .338 NM 130náb. IR-DIM Pás Cinto de munição traçante .338 NM IR-DIM com 130 cartuchos .338 NM 130-lövedékes infravörös nyomkövető heveder - .338 NM 130発入り IR-DIM曳光弾ベルト - 130발들이 .338 NM IR-DIM 예광탄 벨트 - .338 NM 130發 低視度紅外線曳光彈 彈鏈 - .338 NM 130发 低视度红外线曳光弹 弹链 + .338 NM 130Rnd IR-DIM ベルト + 130발 들이 .338rnrud 노르마 매그넘 IR-DIM 예광탄 벨트 + .338 拉普麥格農(NM) 130發 低視度紅外線曳光彈 彈鏈 + .338 NM 130发 弹链(红外曳光) + .338 NM 130Rnd IR-DIM Belt .338 NM IR-DIM - .338 LM IR-DIM + .338 NM IR-DIM .338 NM IR-DIM .338 NM IR-DIM .338 NM IR-DIM @@ -658,10 +1367,11 @@ .338 NM IR-DIM .338 NM IR-DIM .338 NM infravörös nyomkövető - .338 NM IR-DIM曳光弾 - .338 NM IR-DIM 예광탄 + .338 NM IR-DIM + .338구경 노르마 매그넘 IR-DIM 예광탄 .338 NM 低視紅外曳光彈 - .338 NM 低视红外曳光弹 + .338 NM 红外曳光 + .338 NM IR-DIM Caliber: .338 Norma Magnum Tracer IR-DIM<br />Rounds: 130<br />Used in: SPMG @@ -674,10 +1384,11 @@ Ráže: .338 Noma Magnum Svítící IR-DIM<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum Traçante IR-DIM<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum infravörös nyomkövető<br />Lövedékek: 130<br />Használható: SPMG - 口径: .338 Norma Magnum IR-DIM曳光弾<br />装填数: 130<br />次で使用: SPMG - 구경: .338 Norma 매그넘 IR-DIM 예광탄<br />장탄수: 130<br />사용처: SPMG - 口徑: .338 Norma Magnum 低視度紅外線曳光彈<br />發數: 130<br />使用於: SPMG - 口径: .338 Norma Magnum 低视度红外线曳光弹<br />发数: 130<br />使用于: SPMG + 口径: .338 Norma Magnum IR-DIM トレーサー<br />装填数: 130<br />次で使用: SPMG + 구경: .338구경 노르마 매그넘 IR-DIM 예광탄<br/>장탄수: 130<br/>사용처: LWMMG + 口徑: .338 拉普麥格農 低視度紅外線曳光彈<br />發數: 130<br />使用於: SPMG + 口径:.338 Norma Magnum 红外曳光<br />发数:130<br />使用于:SPMG + Kalibre: .338 Norma Magnum Tracer IR-DIM<br />Mermi: 130<br />Kullanıyor: SPMG .338 NM 130Rnd AP Belt @@ -686,14 +1397,15 @@ Bande .338 NM 130Cps AP Cinta de 130 balas AP de .338 NM Лента из 130-ти .338 NM бронебойных - .338 NM 130Rnd AP Belt + .338 NM 130cp Nastro AP .338 NM 130náb. AP Pás Cinto de munição .338 NM com 130 cartuchos AP .338 NM 130-lövedékes páncéltörő heveder - .338 NM 130発入り 徹甲弾ベルト - 130발들이 .338 NM 철갑탄 벨트 - .338 NM 130發 穿甲彈 彈鏈 - .338 NM 130发 穿甲弹 弹链 + .338 NM 130Rnd 徹甲弾 ベルト + 130발 들이 .338구경 노르마 매그넘 철갑탄 벨트 + .338 拉普麥格農(NM) 130發 穿甲彈 彈鏈 + .338 NM 130发 弹链(穿甲) + .338 NM 130Rnd AP Belt .338 NM AP @@ -706,10 +1418,11 @@ .338 NM AP .338 NM AP .338 NM páncéltörő - .338 NM 徹甲弾 - .338 NM 철갑탄 + .338 NM AP + .338구경 노르마 매그넘 철갑탄 .338 NM 穿甲彈 - .338 NM 穿甲弹 + .338 NM 穿甲 + .338 NM AP Caliber: .338 Norma Magnum AP<br />Rounds: 130<br />Used in: SPMG @@ -723,1275 +1436,1612 @@ Calibre: .338 Norma Magnum AP<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum páncéltörő<br />Lövedékek: 130<br />Használható: SPMG 口径: .338 Norma Magnum 徹甲弾<br />装填数: 130<br />次で使用: SPMG - 구경: .338 Norma 매그넘 철갑탄<br />장탄수: 130<br />사용처: SPMG - 口徑: .338 Norma Magnum 穿甲彈<br />發數: 130<br />使用於: SPMG - 口径: .338 Norma Magnum 穿甲弹<br />发数: 130<br />使用于: SPMG + 구경: .338구경 노르마 매그넘 철갑탄<br/>장탄수: 130<br/>사용처: LWMMG + 口徑: .338 拉普麥格農 穿甲彈<br />發數: 130<br />使用於: SPMG + 口径:.338 Norma Magnum 穿甲<br />发数:130<br />使用于:SPMG + Kalibre: .338 Norma Magnum AP<br />Mermi: 130<br />Kullanıyor: SPMG - + - 9.3mm 10Rnd Tracer Mag - 9,3mm 10-Patronen-Magazin Leuchtspur - Magazynek 9.3mm 10rd Smugacz - Ch. 9,3mm 10Cps Traçante - Cargador de 10 balas trazadoras de 9.3mm + 9.3 mm 10Rnd Tracer Mag + 9,3 mm 10-Patronen-Magazin Leuchtspur + Magazynek 9.3 mm 10rd Smugacz + Ch. 9,3 mm 10Cps Traçantes + Cargador de 10 balas trazadoras de 9.3 mm Магазин из 10-ти 9,3 мм трассирующих - 9.3mm 10Rnd Tracer Mag - 9.3mm 10náb. Svítící Zásobník - Carregador de 10 cartuchos 9.3mm traçantes - 9,3mm 10-lövedékes nyomkövető tár - 9.3mm 10発入り 曳光弾 弾倉 - 10발들이 9.3mm 예광탄 탄창 - 9.3mm 10發 曳光彈 彈匣 - 9.3mm 10发 曳光弹 弹匣 + 9.3 mm 10cp Traccianti + 9.3 mm 10náb. Svítící Zásobník + Carregador de 10 cartuchos 9.3 mm traçantes + 9,3 mm 10-lövedékes nyomkövető tár + 9.3mm 10Rnd トレーサー マガジン + 10발 들이 9.3 mm 예광탄 탄창 + 9.3毫米 10發 曳光彈 彈匣 + 9.3 mm 10发 弹匣(曳光) + 9.3 mm 10Rnd Tracer Mag - 9.3mm Tracer - 9,3mm Leuchtspur - 9,3mm Smugacz - 9.3mm Svítící - 9,3mm Traçante - 9.3mm Trazadora + 9.3 mm Tracer + 9,3 mm Leuchtspur + 9,3 mm Smugacz + 9.3 mm Svítící + 9,3 mm Traçante + 9.3 mm Trazadora 9,3 мм трассирующие - 9.3mm Tracer - 9.3mm Traçante - 9,3mm nyomkövető - 9.3mm 曳光弾 + 9.3 mm Tracciante + 9.3 mm Traçante + 9,3 mm nyomkövető + 9.3 mm トレーサー 9.3mm 예광탄 - 9.3mm 曳光彈 - 9.3mm 曳光弹 + 9.3毫米 曳光彈 + 9.3 mm 曳光 + 9.3 mm Tracer - Caliber: 9.3x64mm Tracer<br />Rounds: 10<br />Used in: Cyrus - Kaliber: 9,3x64mm Leuchtspur<br />Patronen: 10<br />Eingesetzt von: Cyrus - Kaliber: 9,3x64mm Smugacz<br />Pociski: 10<br />Używany w: Cyrus - Calibre: 9,3x64mm Traçante<br />Cartouches: 10<br />Utilisé avec: Cyrus - Calibre: 9.3x64mm trazadora<br />Balas: 10<br />Se usa en: Cyrus + Caliber: 9.3x64 mm Tracer<br />Rounds: 10<br />Used in: Cyrus + Kaliber: 9,3x64 mm Leuchtspur<br />Patronen: 10<br />Eingesetzt von: Cyrus + Kaliber: 9,3x64 mm Smugacz<br />Pociski: 10<br />Używany w: Cyrus + Calibre: 9,3x64 mm Traçante<br />Cartouches: 10<br />Utilisé avec: Cyrus + Calibre: 9.3x64 mm trazadora<br />Balas: 10<br />Se usa en: Cyrus Калибр: 9,3x64 мм трассирующие<br />Патронов: 10<br />Используются с: Cyrus - Calibro: 9.3x64mm Tracer<br />Munizioni: 10<br />In uso su: Cyrus - Ráže: 9.3x64mm Svítící<br />Nábojů: 10<br />Použití u: Cyrus - Calibre: 9.3x64mm Traçante<br />Cartuchos: 10<br />Usado em: Cyrus - Kaliber: 9,3x64mm nyomkövető<br />Lövedékek: 10<br />Használható: Cyrus - 口径: 9.3x64mm 曳光弾<br />装填数: 10<br />次で使用: Cyrus - 구경: 9.3x64mm 예광탄<br />장탄수: 10<br />사용처: Cyrus - 口徑: 9.3x64mm 曳光彈<br />發數: 10<br />使用於: Cyrus - 口径: 9.3x64mm 曳光弹<br />发数: 10<br />使用于: Cyrus + Calibro: 9.3x64 mm Tracciante<br />Munizioni: 10<br />In uso su: Cyrus + Ráže: 9.3x64 mm Svítící<br />Nábojů: 10<br />Použití u: Cyrus + Calibre: 9.3x64 mm Traçante<br />Cartuchos: 10<br />Usado em: Cyrus + Kaliber: 9,3x64 mm nyomkövető<br />Lövedékek: 10<br />Használható: Cyrus + 口径: 9.3x64 mm トレーサー<br />装填数: 10<br />次で使用: Cyrus + 구경: 9.3x64mm 예광탄<br/>장탄수: 10<br/>사용처: 사이러스 + 口徑: 9.3x64毫米 曳光彈<br />發數: 10<br />使用於: Cyrus + 口径:9.3x64 mm 曳光<br />发数:10<br />使用于:"居鲁士" + Kalibre: 9.3x64 mm Tracer<br />Mermi: 10<br />Kullanıyor: Cyrus - 9.3mm 10Rnd Tracer IR-DIM Mag - 9,3mm 10-Patronen-Magazin Leuchtspur IR-DIM - Magazynek 9,3mm 10rd Smugacz IR-DIM - Ch. 9,3mm 10Cps Traçante IR-DIM - Cargador de 10 balas trazadoras IR-DIM de 9.3mm + 9.3 mm 10Rnd Tracer IR-DIM Mag + 9,3 mm 10-Patronen-Magazin Leuchtspur IR-DIM + Magazynek 9,3 mm 10rd Smugacz IR-DIM + Ch. 9,3 mm 10Cps Traçantes IR-DIM + Cargador de 10 balas trazadoras IR-DIM de 9.3 mm Магазин из 10-ти 9,3 мм ИК-трассирующих - 9.3mm 10Rnd Tracciante IR-DIM Mag - 9.3mm 10náb. Svítící IR-DIM Zásobník - Carregador de 10 cartuchos 9.3mm traçantes IR-DIM - 9,3mm 10-lövedékes infravörös nyomkövető tár - 9.3mm 10発入り IR-DIM曳光弾 弾倉 + 9.3 mm 10cp Traccianti IR-DIM + 9.3 mm 10náb. Svítící IR-DIM Zásobník + Carregador de 10 cartuchos 9.3 mm traçantes IR-DIM + 9,3 mm 10-lövedékes infravörös nyomkövető tár + 9.3mm 10Rnd IR-DIM トレーサー マガジン 10발들이 9.3mm IR-DIM 예광탄 탄창 - 9.3mm 10發 低視度紅外線曳光彈 彈匣 - 9.3mm 10发 低视度红外线曳光弹 弹匣 + 9.3毫米 10發 低視度紅外線曳光彈 彈匣 + 9.3 mm 10发 弹匣(红外曳光) + 9.3 mm 10Rnd Tracer IR-DIM Mag - 9.3mm IR-DIM - 9,3mm IR-DIM - 9,3mm IR-DIM - 9.3mm IR-DIM - 9,3mm IR-DIM - 9.3mm IR-DIM + 9.3 mm IR-DIM + 9,3 mm IR-DIM + 9,3 mm IR-DIM + 9.3 mm IR-DIM + 9,3 mm IR-DIM + 9.3 mm IR-DIM 9,3 мм ИК-трассирующие - 9.3mm IR-DIM - 9.3mm IR-DIM - 9,3mm infravörös nyomkövető - 9.3mm IR-DIM曳光弾 + 9.3 mm IR-DIM + 9.3 mm IR-DIM + 9,3 mm infravörös nyomkövető + 9.3 mm IR-DIM 9.3mm IR-DIM 예광탄 - 9.3mm 低視紅外曳光彈 - 9.3mm 低视红外曳光弹 + 9.3毫米 低視紅外曳光彈 + 9.3 mm 红外曳光 + 9.3 mm IR-DIM - Caliber: 9.3x64mm Tracer IR-DIM<br />Rounds: 10<br />Used in: Cyrus - Kaliber: 9,3x64mm Leuchtspur IR-DIM<br />Patronen: 10<br />Eingesetzt von: Cyrus - Kaliber: 9,3x64mm Smugacz IR-DIM<br />Pociski: 10<br />Używany w: Cyrus - Calibre: 9,3x64mm Traçante IR-DIM<br />Cartouches: 10<br />Utilisé avec: Cyrus - Calibre: 9.3x64mm trazadora IR-DIM<br />Balas: 10<br />Se usa en: Cyrus + Caliber: 9.3x64 mm Tracer IR-DIM<br />Rounds: 10<br />Used in: Cyrus + Kaliber: 9,3x64 mm Leuchtspur IR-DIM<br />Patronen: 10<br />Eingesetzt von: Cyrus + Kaliber: 9,3x64 mm Smugacz IR-DIM<br />Pociski: 10<br />Używany w: Cyrus + Calibre: 9,3x64 mm Traçante IR-DIM<br />Cartouches: 10<br />Utilisé avec: Cyrus + Calibre: 9.3x64 mm trazadora IR-DIM<br />Balas: 10<br />Se usa en: Cyrus Калибр: 9,3x64 мм ИК-трассирующие<br />Патронов: 10<br />Используются с: Cyrus - Calibro: 9.3x64mm Tracciante IR-DIM<br />Munizioni: 10<br />In uso su: Cyrus - Ráže: 9.3x64mm Svítící IR-DIM<br />Nábojů: 10<br />Použití u: Cyrus - Calibre: 9.3x64mm Traçante IR-DIM<br />Cartuchos: 10<br />Usado em: Cyrus - Kaliber: 9,3x64mm infravörös nyomkövető<br />Lövedékek: 10<br /> Használható: Cyrus - 口径: 9.3x64mm IR-DIM曳光弾<br />装填数: 10<br />次で使用: Cyrus - 구경: 9.3x64mm IR-DIM 예광탄<br />장탄수: 10<br />사용처: Cyrus - 口徑: 9.3x64mm 低視度紅外線曳光彈<br />發數: 10<br />使用於: Cyrus - 口径: 9.3x64mm 低视度红外线曳光弹<br />发数: 10<br />使用于: Cyrus + Calibro: 9.3x64 mm Tracciante IR-DIM<br />Munizioni: 10<br />In uso su: Cyrus + Ráže: 9.3x64 mm Svítící IR-DIM<br />Nábojů: 10<br />Použití u: Cyrus + Calibre: 9.3x64 mm Traçante IR-DIM<br />Cartuchos: 10<br />Usado em: Cyrus + Kaliber: 9,3x64 mm infravörös nyomkövető<br />Lövedékek: 10<br /> Használható: Cyrus + 口径: 9.3x64 mm IR-DIM トレーサー<br />装填数: 10<br />次で使用: Cyrus + 구경: 9.3x64mm IR-DIM 예광탄<br/>장탄수: 10<br/>사용처: 사이러스 + 口徑: 9.3x64毫米 低視度紅外線曳光彈<br />發數: 10<br />使用於: Cyrus + 口径:9.3x64 mm 红外曳光<br />发数:10<br />使用于:"居鲁士" + Kalibre: 9.3x64 mm Tracer IR-DIM<br />Mermi: 10<br />Kullanıyor: Cyrus - + - 9.3mm 150Rnd Tracer Belt - 9,3mm 150-Patronen-Gurt Leuchtspur - Taśma 9,3mm 150rd Smugacz - Bande 9,3mm 150Cps Traçante - Cinta de 150 balas trazadoras de 9.3mm + 9.3 mm 150Rnd Tracer Belt + 9,3 mm 150-Patronen-Gurt Leuchtspur + Taśma 9,3 mm 150rd Smugacz + Bande 9,3 mm 150Cps Traçantes + Cinta de 150 balas trazadoras de 9.3 mm Лента из 150-ти 9,3 мм трассирующих - 9.3mm 150Rnd Tracer Belt - 9.3mm 150náb. Svítící Pás - Cinto de munição traçante 9.3mm com 150 cartuchos - 9,3mm 150-lövedékes nyomkövető heveder - 9.3mm 150発入り 曳光弾ベルト - 150발들이 9.3mm 예광탄 벨트 - 9.3mm 150發 曳光彈 彈鏈 - 9.3mm 150发 曳光弹 弹链 + 9.3 mm 150cp Nastro Tracciante + 9.3 mm 150náb. Svítící Pás + Cinto de munição traçante 9.3 mm com 150 cartuchos + 9,3 mm 150-lövedékes nyomkövető heveder + 9.3mm 150Rnd トレーサー ベルト + 150발 들이 9.3mm 예광탄 벨트 + 9.3毫米 150發 曳光彈 彈鏈 + 9.3 mm 150发 弹链(曳光) + 9.3 mm 150Rnd Tracer Belt - 9.3mm Tracer - 9,3mm Leuchtspur - 9,3mm Smugacz - 9.3mm Svítící - 9,3mm Traçante - 9.3mm Trazadora + 9.3 mm Tracer + 9,3 mm Leuchtspur + 9,3 mm Smugacz + 9.3 mm Svítící + 9,3 mm Traçante + 9.3 mm Trazadora 9,3 мм трассирующие - 9.3mm Tracciante - 9.3mm Traçante - 9,3mm nyomkövető - 9.3mm 曳光弾 + 9.3 mm Tracciante + 9.3 mm Traçante + 9,3 mm nyomkövető + 9.3 mm トレーサー 9.3mm 예광탄 - 9.3mm 曳光彈 - 9.3mm 曳光弹 + 9.3毫米 曳光彈 + 9.3 mm 曳光 + 9.3 mm Tracer - Caliber: 9.3x64mm Tracer<br />Rounds: 150<br />Used in: Navid - Kaliber: 9,3x64mm Leuchtspur<br />Patronen: 150<br />Eingesetzt von: Navid - Kaliber: 9,3x64mm Smugacz<br />Pociski: 150<br />Używane w: Navid - Calibre: 9,3x64mm Traçante<br />Cartouches: 150<br />Utilisé avec: Navid - Calibre: 9.3x64mm trazadora<br />Balas: 150<br />Se usa en: Navid + Caliber: 9.3x64 mm Tracer<br />Rounds: 150<br />Used in: Navid + Kaliber: 9,3x64 mm Leuchtspur<br />Patronen: 150<br />Eingesetzt von: Navid + Kaliber: 9,3x64 mm Smugacz<br />Pociski: 150<br />Używane w: Navid + Calibre: 9,3x64 mm Traçantes<br />Cartouches: 150<br />Utilisé avec: Navid + Calibre: 9.3x64 mm trazadora<br />Balas: 150<br />Se usa en: Navid Калибр: 9,3x64 мм трассирующие<br />Патронов: 150<br />Используются с: Навид - Calibro: 9.3x64mm Tracciante<br />Munizioni: 150<br />In uso su: Navid - Ráže: 9.3x64mm Svítící<br />Nábojů: 150<br />Použití u: HK121 - Calibre: 9.3x64mm Traçante<br />Cartuchos: 150<br />Usado em: Navid - Kaliber: 9,3x64mm nyomkövető<br />Lövedékek: 150<br />Használható: Navid - 口径: 9.3x64mm 曳光弾<br />装填数: 150<br />次で使用: Navid - 구경: 9.3x64mm 예광탄<br />장탄수: 150<br />사용처: Navid - 口徑: 9.3x64mm 曳光彈<br />發數: 150<br />使用於: Navid - 口径: 9.3x64mm 曳光弹<br />发数: 150<br />使用于: Navid + Calibro: 9.3x64 mm Tracciante<br />Munizioni: 150<br />In uso su: Navid + Ráže: 9.3x64 mm Svítící<br />Nábojů: 150<br />Použití u: HK121 + Calibre: 9.3x64 mm Traçante<br />Cartuchos: 150<br />Usado em: Navid + Kaliber: 9,3x64 mm nyomkövető<br />Lövedékek: 150<br />Használható: Navid + 口径: 9.3x64 mm トレーサー<br />装填数: 150<br />次で使用: Navid + 구경: 9.3x64mm 예광탄<br/>장탄수: 150<br/>사용처: HK121 + 口徑: 9.3x64m毫米 曳光彈<br />發數: 150<br />使用於: Navid + 口径:9.3x64 mm 曳光<br />发数:150<br />使用于:Navid + Kalibre: 9.3x64 mm Tracer<br />Mermi: 150<br />Kullanıyor: Navid - 9.3mm 150Rnd Tracer IR-DIM Belt - 9,3mm 150-Patronen-Gurt Leuchtspur IR-DIM - Taśma 9,3mm 150rd Smugacz IR-DIM - Bande 9,3mm 150Cps Traçante IR-DIM - Cinta de 150 balas trazadoras IR-DIM de 9.3mm + 9.3 mm 150Rnd Tracer IR-DIM Belt + 9,3 mm 150-Patronen-Gurt Leuchtspur IR-DIM + Taśma 9,3 mm 150rd Smugacz IR-DIM + Bande 9,3 mm 150Cps Traçantes IR-DIM + Cinta de 150 balas trazadoras IR-DIM de 9.3 mm Лента из 150-ти 9,3 мм ИК-трассирующих - 9.3mm 150Rnd Tracciante IR-DIM Belt - 9.3mm 150náb. Svítící IR-DIM Pás - Cinto de munição traçante 9.3mm IR-DIM com 150 cartuchos - 9,3mm 150-lövedékes infravörös nyomkövető heveder - 9.3mm 150発入り IR-DIM曳光弾ベルト + 9.3 mm 150cp Nastro Tracciante IR-DIM + 9.3 mm 150náb. Svítící IR-DIM Pás + Cinto de munição traçante 9.3 mm IR-DIM com 150 cartuchos + 9,3 mm 150-lövedékes infravörös nyomkövető heveder + 9.3mm 150Rnd IR-DIM トレーサー ベルト 150발들이 9.3mm IR-DIM 예광탄 벨트 - 9.3mm 150發 低視度紅外線曳光彈 彈鏈 - 9.3mm 150发 低视度红外线曳光弹 弹链 + 9.3毫米 150發 低視度紅外線曳光彈 彈鏈 + 9.3 mm 150发 弹链(红外曳光) + 9.3 mm 150Rnd Tracer IR-DIM Belt - 9.3mm IR-DIM - 9,3mm IR-DIM - 9,3mm IR-DIM - 9.3mm IR-DIM - 9,3mm IR-DIM - 9.3mm IR-DIM + 9.3 mm IR-DIM + 9,3 mm IR-DIM + 9,3 mm IR-DIM + 9.3 mm IR-DIM + 9,3 mm IR-DIM + 9.3 mm IR-DIM 9,3 мм ИК-трассирующие - 9.3mm IR-DIM - 9.3mm IR-DIM - 9,3mm infravörös nyomkövető - 9.3mm IR-DIM曳光弾 + 9.3 mm IR-DIM + 9.3 mm IR-DIM + 9,3 mm infravörös nyomkövető + 9.3 mm IR-DIM 9.3mm IR-DIM 예광탄 - 9.3mm 低視紅外曳光彈 - 9.3mm 低视红外曳光弹 + 9.3毫米 低視紅外曳光彈 + 9.3 mm 红外曳光 + 9.3 mm IR-DIM - Caliber: 9.3x64mm Tracer IR-DIM<br />Rounds: 150<br />Used in: Navid - Kaliber: 9,3x64mm Leuchtspur IR-DIM<br />Patronen: 150<br />Eingesetzt von: Navid - Kaliber: 9,3x64mm Smugacz IR-DIM<br />Pociski: 150<br />Używane w: Navid - Calibre: 9,3x64mm Traçante IR-DIM<br />Cartouches: 150<br />Utilisé avec: Navid - Calibre: 9.3x64mm trazadora IR-DIM<br />Balas: 150<br />Se usa en: Navid + Caliber: 9.3x64 mm Tracer IR-DIM<br />Rounds: 150<br />Used in: Navid + Kaliber: 9,3x64 mm Leuchtspur IR-DIM<br />Patronen: 150<br />Eingesetzt von: Navid + Kaliber: 9,3x64 mm Smugacz IR-DIM<br />Pociski: 150<br />Używane w: Navid + Calibre: 9,3x64 mm Traçante IR-DIM<br />Cartouches: 150<br />Utilisé avec: Navid + Calibre: 9.3x64 mm trazadora IR-DIM<br />Balas: 150<br />Se usa en: Navid Калибр: 9,3x64 мм ИК-трассирующие<br />Патронов: 150<br />Используются с: Навид - Calibro: 9.3x64mm Tracciante IR-DIM<br />Munizioni: 150<br />In uso su: Navid - Ráže: 9.3x64mm Svítící IR-DIM<br />Nábojů: 150<br />Použití u: HK121 - Calibre: 9.3x64mm Traçante IR-DIM<br />Cartuchos: 150<br />Usado em: Navid - Kaliber: 9,3x64mm infravörös nyomkövető<br />Lövedékek: 150<br />Használható: Navid - 口径: 9.3x64mm IR-DIM曳光弾<br />装填数: 150<br />次で使用: Navid - 구경: 9.3x64mm IR-DIM 예광탄<br />장탄수: 150<br />사용처: Navid - 口徑: 9.3x64mm 低視度紅外線曳光彈<br />發數: 150<br />使用於: Navid - 口径: 9.3x64mm 低视度红外线曳光弹<br />发数: 150<br />使用于: Navid + Calibro: 9.3x64 mm Tracciante IR-DIM<br />Munizioni: 150<br />In uso su: Navid + Ráže: 9.3x64 mm Svítící IR-DIM<br />Nábojů: 150<br />Použití u: HK121 + Calibre: 9.3x64 mm Traçante IR-DIM<br />Cartuchos: 150<br />Usado em: Navid + Kaliber: 9,3x64 mm infravörös nyomkövető<br />Lövedékek: 150<br />Használható: Navid + 口径: 9.3x64 mm IR-DIM トレーサー<br />装填数: 150<br />次で使用: Navid + 구경: 9.3x64mm IR-DIM 예광탄<br/>장탄수: 150<br/>사용처: HK121 + 口徑: 9.3x64毫米 低視度紅外線曳光彈<br />發數: 150<br />使用於: Navid + 口径:9.3x64 mm 红外曳光<br />发数:150<br />使用于:Navid + Kalibre: 9.3x64 mm Tracer IR-DIM<br />Mermi: 150<br />Kullanıyor: Navid - 9.3mm 150Rnd AP Belt - 9,3mm 150-Patronen-Gurt Hartkern - Taśma 9,3mm 150rd AP - Bande 9,3mm 150Cps AP - Cinta de 150 balas AP de 9.3mm + 9.3 mm 150Rnd AP Belt + 9,3 mm 150-Patronen-Gurt Hartkern + Taśma 9,3 mm 150rd AP + Bande 9,3 mm 150Cps AP + Cinta de 150 balas AP de 9.3 mm Лента из 150-ти 9,3 мм бронебойных - 9.3mm 150Rnd AP Belt - 9.3mm 150náb. AP Pás - Cinto de munição 9.3mm AP com 150 cartuchos - 9,3mm 150-lövedékes páncéltörő heveder - 9.3mm 150発入り 徹甲弾ベルト + 9.3 mm 150cp Nastro AP + 9.3 mm 150náb. AP Pás + Cinto de munição 9.3 mm AP com 150 cartuchos + 9,3 mm 150-lövedékes páncéltörő heveder + 9.3mm 150Rnd 徹甲弾 ベルト 150발들이 9.3mm 철갑탄 벨트 - 9.3mm 150發 穿甲彈 彈鏈 - 9.3mm 150发 穿甲弹 弹链 + 9.3毫米 150發 穿甲彈 彈鏈 + 9.3 mm 150发 弹链(穿甲) + 9.3 mm 150Rnd AP Belt - 9.3mm AP - 9,3mm AP - 9,3mm AP - 9.3mm AP - 9,3mm AP - 9.3mm AP + 9.3 mm AP + 9,3 mm AP + 9,3 mm AP + 9.3 mm AP + 9,3 mm AP + 9.3 mm AP 9,3 мм бронебойные - 9.3mm AP - 9.3mm AP - 9,3mm páncéltörő - 9.3mm 徹甲弾 + 9.3 mm AP + 9.3 mm AP + 9,3 mm páncéltörő + 9.3 mm AP 9.3mm 철갑탄 - 9.3mm 穿甲彈 - 9.3mm 穿甲弹 + 9.3毫米 穿甲彈 + 9.3 mm 穿甲 + 9.3 mm AP - Caliber: 9.3x64mm AP<br />Rounds: 150<br />Used in: Navid - Kaliber: 9,3x64mm Hartkern<br />Patronen: 150<br />Eingesetzt von: Navid - Kaliber: 9,3x64mm AP<br />Pociski: 150<br />Używane w: Navid - Calibre: 9,3x64mm AP<br />Cartouches: 150<br />Utilisé avec: Navid - Calibre: 9.3x64mm AP<br />Balas: 150<br />Se usa en: Navid + Caliber: 9.3x64 mm AP<br />Rounds: 150<br />Used in: Navid + Kaliber: 9,3x64 mm Hartkern<br />Patronen: 150<br />Eingesetzt von: Navid + Kaliber: 9,3x64 mm AP<br />Pociski: 150<br />Używane w: Navid + Calibre: 9,3x64 mm AP<br />Cartouches: 150<br />Utilisé avec: Navid + Calibre: 9.3x64 mm AP<br />Balas: 150<br />Se usa en: Navid Калибр: 9,3x64 мм бронебойные<br />Патронов: 150<br />Используются с: Навид - Calibro: 9.3x64mm AP<br />Munizioni: 150<br />In uso su: Navid - Ráže: 9.3x64mm AP<br />Nábojů: 150<br />Použití u: HK121 - Calibre: 9.3x64mm AP<br />Cartuchos: 150<br />Usado em: Navid - Kaliber: 9,3x64mm páncéltörő<br />Lövedékek: 150<br />Használható: Navid - 口径: 9.3x64mm 徹甲弾<br />装填数: 150<br />次で使用: Navid - 구경: 9.3x64mm 철갑탄<br />장탄수: 150<br />사용처: Navid - 口徑: 9.3x64mm 穿甲彈<br />發數: 150<br />使用於: Navid - 口径: 9.3x64mm 穿甲弹<br />发数: 150<br />使用于: Navid + Calibro: 9.3x64 mm AP<br />Munizioni: 150<br />In uso su: Navid + Ráže: 9.3x64 mm AP<br />Nábojů: 150<br />Použití u: HK121 + Calibre: 9.3x64 mm AP<br />Cartuchos: 150<br />Usado em: Navid + Kaliber: 9,3x64 mm páncéltörő<br />Lövedékek: 150<br />Használható: Navid + 口径: 9.3x64 mm 徹甲弾<br />装填数: 150<br />次で使用: Navid + 구경: 9.3x64mm 철갑탄<br/>장탄수: 150<br/>사용처: HK121 + 口徑: 9.3x64毫米 穿甲彈<br />發數: 150<br />使用於: Navid + 口径:9.3x64 mm 穿甲<br />发数:150<br />使用于:Navid + Kalibre: 9.3x64 mm AP<br />Mermi: 150<br />Kullanıyor: Navid - 9x19mm 16Rnd Mag - Magazynek 9x19mm 16rd - Ch. 9x19mm 16Cps - Cargador de 16 balas de 9x19mm + 9x19 mm 16Rnd Mag + Magazynek 9x19 mm 16rd + Ch. 9x19 mm 16Cps + Cargador de 16 balas de 9x19 mm Магазин из 16-ти 9х19 мм - 9x19mm 20-Patronen-Magazin - 9x19mm 16Rnd Mag - 9x19mm 16náb. Zásobník - Carregador de 16 cartuchos 9x19mm - 9x19mm 16-lövedékes tár - 9x19mm 16発入り 弾倉 - 16발들이 9x19mm 탄창 - 9x19mm 16發 彈匣 - 9x19mm 16发 弹匣 + 9x19 mm 20-Patronen-Magazin + 9x19 mm 16cp Car + 9x19 mm 16náb. Zásobník + Carregador de 16 cartuchos 9x19 mm + 9x19 mm 16-lövedékes tár + 9x19 mm 16Rnd マガジン + 17발들이 9x19mm 탄창 + 9x19毫米 16發 彈匣 + 9x19 mm 16发 弹匣 + 9x19 mm 16Rnd Mag - 9x19mm - 9x19mm - 9x19mm - 9x19mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm 9х19 мм - 9x19mm - 9x19mm - 9x19mm - 9x19mm - 9x19mm - 9x19mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm 9x19mm - 9x19mm - 9x19mm + 9x19毫米 + 9x19 mm + 9x19 mm - 9x19mm 30Rnd Mag - Magazynek 9x19mm 16rd - Ch. 9x19mm 30Cps - Cargador de 16 balas de 9x19mm + 9x19 mm 30Rnd Mag + Magazynek 9x19 mm 16rd + Ch. 9x19 mm 30Cps + Cargador de 16 balas de 9x19 mm Магазин из 16-ти 9х19 мм - 9x19mm 30-Patronen-Magazin - 9x19mm 30Rnd Mag - 9x19mm 30náb. Zásobník - Carregador de 16 cartuchos 9x19mm - 9x19mm 16-lövedékes tár - 9x19mm 30発入り 弾倉 - 30발들이 9x19mm 탄창 - 9x19mm 30發 彈匣 - 9x19mm 30发 弹匣 + 9x19 mm 30-Patronen-Magazin + 9x19 mm 30cp Car + 9x19 mm 30náb. Zásobník + Carregador de 16 cartuchos 9x19 mm + 9x19 mm 16-lövedékes tár + 9x19 mm 30Rnd マガジン + 30발 들이 9x19mm 탄창 + 9x19毫米 30發 彈匣 + 9x19 mm 30发 弹匣 + 9x19 mm 30Rnd Mag - 9x19mm 30Rnd Mag - Magazynek 9x19mm 30rd - Ch. 9x19mm 30Cps - Cargador de 30 balas de 9x19mm + 9x19 mm 30Rnd Mag + Magazynek 9x19 mm 30rd + Ch. 9x19 mm 30Cps + Cargador de 30 balas de 9x19 mm Магазин из 30-ти 9х19 мм - 9x19mm 30-Patronen-Magazin - 9x19mm 30Rnd Mag - 9x19mm 30náb. Zásobník - Carregador de 30 cartuchos 9x19mm - 9x19mm 30-lövedékes tár - 9x19mm 30発入り 弾倉 - 30발들이 9x19mm 탄창 - 9x19mm 30發 彈匣 - 9x19mm 30发 弹匣 + 9x19 mm 30-Patronen-Magazin + 9x19 mm 30cp Car + 9x19 mm 30náb. Zásobník + Carregador de 30 cartuchos 9x19 mm + 9x19 mm 30-lövedékes tár + 9x19 mm 30Rnd マガジン + 30발 들이 9x19mm 탄창 + 9x19毫米 30發 彈匣 + 9x19 mm 30发 弹匣 + 9x19 mm 30Rnd Mag - 9x19mm - 9x19mm - 9x19mm - 9x19mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm 9х19 мм - 9x19mm - 9x19mm - 9x19mm - 9x19mm - 9x19mm - 9x19mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm + 9x19 mm 9x19mm - 9x19mm - 9x19mm + 9x19毫米 + 9x19 mm + 9x19 mm - 9x19mm 30Rnd Mag - Magazynek 9x19mm 30rd - Ch. 9x19mm 30Cps - Cargador de 30 balas de 9x19mm + 9x19 mm 30Rnd Mag + Magazynek 9x19 mm 30rd + Ch. 9x19 mm 30Cps + Cargador de 30 balas de 9x19 mm Магазин из 30-ти 9х19 мм - 9x19mm 30-Patronen-Magazin - 9x19mm 30Rnd Mag - 9x19mm 30náb. Zásobník - Carregador de 30 cartuchos 9x19mm - 9x19mm 30-lövedékes tár - 9x19mm 30発入り 弾倉 - 30발들이 9x19mm 탄창 - 9x19mm 30發 彈匣 - 9x19mm 30发 弹匣 + 9x19 mm 30-Patronen-Magazin + 9x19 mm 30cp Car + 9x19 mm 30náb. Zásobník + Carregador de 30 cartuchos 9x19 mm + 9x19 mm 30-lövedékes tár + 9x19 mm 30Rnd マガジン + 30발 들이 9x19mm 탄창 + 9x19毫米 30發 彈匣 + 9x19 mm 30发 弹匣 + 9x19 mm 30Rnd Mag - 7.62x54mm 10Rnd Tracer Mag - Magazynek 7,62x54mm 10rd Smugacz - Ch. 7,62x54mm 10Cps Traçante - Cargador de 10 balas trazadoras de 7.62x54mm - Магазин из 10-ти 7,62 мм ИК-трассирующих - 7,62x54mm 10-Patronen-Magazin Leuchtspur - 7.62x54mm 10Munizioni Traccianti IR-DIM Mag - 7.62x54mm 10náb. Svítící Zásobník - Carregador com 10 cartuchos 7.62x54mm Traçante - 7,62x54mm 10-lövedékes nyomkövető tár - 7.62x54mm 10発入り 曳光弾 弾倉 - 10발들이 7.62x54mm 예광탄 탄창 - 7.62x54mm 10發 曳光彈 彈匣 - 7.62x54mm 10发 曳光弹 弹匣 + 7.62x54 mm 10Rnd Tracer Mag + Magazynek 7,62x54 mm 10rd Smugacz + Ch. 7,62x54 mm 10Cps Traçantes + Cargador de 10 balas trazadoras de 7.62x54 mm + Магазин из 10-ти 7,62 мм трассирующих + 7,62x54 mm 10-Patronen-Magazin Leuchtspur + 7.62x54 mm 10cp Traccianti + 7.62x54 mm 10náb. Svítící Zásobník + Carregador com 10 cartuchos 7.62x54 mm Traçante + 7,62x54 mm 10-lövedékes nyomkövető tár + 7.62mm 10Rnd マガジン (トレーサー) + 10발 들이 7.62x54mm 예광탄 탄창 + 7.62x54毫米 10發 曳光彈 彈匣 + 7.62x54 mm 10发 弹匣(曳光) + 7.62x54 mm 10Rnd Tracer Mag - 7.62mm - 7,62mm - 7,62mm - 7.62mm - 7,62 мм - 7,62mm - 7.62mm - 7.62mm - 7.62mm - 7,62mm - 7.62mm - 7.62mm - 7.62mm - 7.62mm + Tracer + Smugacz + Traçantes + trazadoras + трассирующих + Leuchtspur + Tracciante + Svítící + Traçante + nyomkövető + トレーサー + 예광탄 + 曳光 + 曳光 + Tracer - 7.62x54mm 10Rnd Tracer Mag - Magazynek 7,62x54mm 10rd Smugacz - Ch. 7,62x54mm 10Cps Traçante - Cargador de 10 balas trazadoras de 7.62x54mm - Магазин из 10-ти 7,62 мм ИК-трассирующих - 7,62x54mm 10-Patronen-Magazin Leuchtspur - 7.62x54mm 10Munizioni Traccianti IR-DIM Mag - 7.62x54mm 10náb. Svítící Zásobník - Carregador com 10 cartuchos 7.62x54mm Traçante - 7,62x54mm 10-lövedékes nyomkövető tár - 7.62x54mm 10発入り 曳光弾 弾倉 - 10발들이 7.62x54mm 예광탄 탄창 - 7.62x54mm 10發 曳光彈 彈匣 - 7.62x54mm 10发 曳光弹 弹匣 + 7.62x54 mm 10Rnd Tracer Mag + Magazynek 7,62x54 mm 10rd Smugacz + Ch. 7,62x54 mm 10Cps Traçantes + Cargador de 10 balas trazadoras de 7.62x54 mm + Магазин из 10-ти 7,62 мм трассирующих + 7,62x54 mm 10-Patronen-Magazin Leuchtspur + 7.62x54 mm 10cp Traccianti + 7.62x54 mm 10náb. Svítící Zásobník + Carregador com 10 cartuchos 7.62x54 mm Traçante + 7,62x54 mm 10-lövedékes nyomkövető tár + 口径: 7.62x54 mm トレーサー<br />弾薬: 10<br />使用: ラヒム + 10발 들이 7.62x54mm 예광탄 탄창 + 7.62x54毫米 10發 曳光彈 彈匣 + 7.62x54 mm 10发 弹匣(曳光) + 7.62x54 mm 10Rnd Tracer Mag - 6.5mm 100Rnd Tracer IR-DIM Mag - Magazynek 6,5mm 100rd Smugacz IR-DIM - Ch. 6,5mm 100Cps Traçante IR-DIM - Cargador de 100 balas trazadoras IR-DIM de 6.5mm + 6.5 mm 100Rnd Tracer IR-DIM Mag + Magazynek 6,5 mm 100rd Smugacz IR-DIM + Ch. 6,5 mm 100Cps Traçantes IR-DIM + Cargador de 100 balas trazadoras IR-DIM de 6.5 mm Магазин из 100 6,5 мм ИК-трассирующих - 6,5mm 100-Patronen-Magazin IR-DIM Leuchtspur - 6.5mm 100Munizioni Traccianti IR-DIM Mag - 6.5mm 100náb. Svítící IR-DIM Zásobník - Carregador com 100 cartuchos 6.5mm IR-DIM Traçante - 6,5mm 100-lövedékes infravörös nyomkövető tár - 6.5mm 100発入り IR-DIM曳光弾 弾倉 - 100발들이 6.5mm IR-DIM 예광탄 탄창 - 6.5mm 100發 低視度紅外線曳光彈 彈匣 - 6.5mm 100发 低视度红外线曳光弹 弹匣 + 6,5 mm 100-Patronen-Magazin IR-DIM Leuchtspur + 6.5 mm 100cp Traccianti IR-DIM + 6.5 mm 100náb. Svítící IR-DIM Zásobník + Carregador com 100 cartuchos 6.5 mm IR-DIM Traçante + 6,5 mm 100-lövedékes infravörös nyomkövető tár + 6.5mm 100Rnd IR-DIM トレーサー マガジン + 100발 들이 6.5mm IR-DIM 예광탄 탄창 + 6.5毫米 100發 低視度紅外線曳光彈 彈匣 + 6.5 mm 100发 弹匣(红外曳光) + 6.5 mm 100Rnd Tracer IR-DIM Mag - 6.5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6.5mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6.5 mm IR-DIM 6,5 мм ИК-трассирующие - 6,5mm IR-DIM - 6.5mm IR-DIM - 6.5mm IR-DIM - 6.5mm IR-DIM - 6,5mm infravörös nyomkövető - 6.5mm IR-DIM曳光弾 + 6,5 mm IR-DIM + 6.5 mm IR-DIM + 6.5 mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm infravörös nyomkövető + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 - 6.5mm 低視紅外曳光彈 - 6.5mm 低视红外曳光弹 + 6.5毫米 低視紅外曳光彈 + 6.5 mm 红外曳光 + 6.5 mm IR-DIM - 6.5mm 100Rnd Tracer IR-DIM Mag<br />Rounds: 100<br />Used in: MX LSW - Magazynek 6,5mm 100rd Smugacz IR-DIM - Ch. 6,5mm 100Cps Traçante IR-DIM<br />Cartouches: 100<br />Utilisé avec: MX LSW - Cargador de 100 balas trazadoras IR-DIM de 6.5mm + 6.5 mm 100Rnd Tracer IR-DIM Mag<br />Rounds: 100<br />Used in: MX LSW + Magazynek 6,5 mm 100rd Smugacz IR-DIM + Ch. 6,5 mm 100Cps Traçantes IR-DIM<br />Cartouches: 100<br />Utilisé avec: MX LSW + Cargador de 100 balas trazadoras IR-DIM de 6.5 mm Магазин из 100 6,5 мм ИК-трассирующих - 6,5mm 100-Patronen-Magazin IR-DIM Leuchtspur<br />Patronen: 100<br />Eingesetzt von: MXLSW - 6.5mm 100Rnd Tracer IR-DIM Mag<br />Munizioni: 100<br />In uso su: MX LSW - 6.5mm 100náb. Svítící IR-DIM Zásobník<br />Nábojů: 100<br />Použití u: MX LSW - Carregador 6.5mm 100 Cartuchos Traçantes IR-DIM<br />Cartuchos: 100<br />Usado em: MX LSW - 6.5mm 100-lövedékes infravörös nyomkövető tár<br />Lövedékek: 100<br />Használható: MX LSW - 6.5mm 100発入り IR-DIM曳光弾 弾倉<br />装填数: 100<br />次で使用: MX LSW - 100발들이 6.5mm IR-DIM 예광탄 탄창<br />장탄수: 100<br />사용처: MX LSW - 6.5mm 100發 低視度紅外線曳光彈<br />發數: 100<br />使用於: MX LSW - 6.5mm 100发 低视度红外线曳光弹<br />发数: 100<br />使用于: MX LSW + 6,5 mm 100-Patronen-Magazin IR-DIM Leuchtspur<br />Patronen: 100<br />Eingesetzt von: MXLSW + 6.5 mm 100cp Traccianti IR-DIM Car<br />Munizioni: 100<br />In uso su: MX LSW + 6.5 mm 100náb. Svítící IR-DIM Zásobník<br />Nábojů: 100<br />Použití u: MX LSW + Carregador 6.5 mm 100 Cartuchos Traçantes IR-DIM<br />Cartuchos: 100<br />Usado em: MX LSW + 6.5 mm 100-lövedékes infravörös nyomkövető tár<br />Lövedékek: 100<br />Használható: MX LSW + 6.5 mm 100Rnd IR-DIM トレーサー マガジン<br />装填数: 100<br />次で使用: MX LSW + 6.5mm IR-DIM 예광탄<br/>장탄수: 100<br/>사용처: MX LSW + 6.5毫米 100發 低視度紅外線曳光彈<br />發數: 100<br />使用於: MX LSW + 口径:6.5 mm 100发 红外曳光<br />发数:100<br />使用于:MX LSW + 6.5 mm 100Rnd Tracer IR-DIM Mag<br />Mermi: 100<br />Kullanıyor: MX LSW - 6.5mm 200Rnd Tracer IR-DIM Belt - Magazynek 6,5mm 200rd Smugacz IR-DIM - Bande 6,5mm 200Cps Traçante IR-DIM - Cinta de 200 balas trazadoras IR-DIM de 6.5mm + 6.5 mm 200Rnd Belt Tracer (IR-DIM) + Magazynek 6,5 mm 200rd Smugacz IR-DIM + Bande 6,5 mm 200Cps Traçantes IR-DIM + Cinta de 200 balas trazadoras IR-DIM de 6.5 mm Магазин из 200-т 6,5 мм ИК-трассирующих - 6,5mm 200-Patronen-Gurt IR-DIM Leuchtspur - 6.5mm 200Rnd Tracer IR-DIM Belt - 6.5mm 200náb. Svítící IR-DIM Pás - Cinto de munição traçante 6.5mm IR-DIM com 200 cartuchos - 6,5mm 200-lövedékes infravörös nyomkövető heveder - 6.5mm 200発入り IR-DIM曳光弾ベルト - 200발들이 6.5mm IR-DIM 예광탄 탄창 - 6.5mm 200發 低視度紅外線曳光彈 彈鏈 - 6.5mm 200发 低视度红外线曳光弹 弹链 + 6,5 mm 200-Patronen-Gurt IR-DIM Leuchtspur + 6.5 mm 200cp Nastro Tracciante (IR-DIM) + 6.5 mm 200náb. Svítící IR-DIM Pás + Cinto de munição traçante 6.5 mm IR-DIM com 200 cartuchos + 6,5 mm 200-lövedékes infravörös nyomkövető heveder + 6.5mm 200Rnd ベルト トレーサー(IR-DIM) + 200발 들이 6.5mm IR-DIM 예광탄 탄창 + 6.5毫米 200發 低視度紅外線曳光彈 彈鏈 + 6.5 mm 200发 弹链(红外曳光) + 6.5 mm 200Rnd Belt Tracer (IR-DIM) - 6.5mm IR-DIM - 6,5mm IR-DIM - 6,5mm IR-DIM - 6.5mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm IR-DIM + 6,5 mm IR-DIM + 6.5 mm IR-DIM 6,5 мм ИК-трассирующие - 6,5mm IR-DIM - 6.5mm IR-DIM - 6.5mm IR-DIM - 6.5mm IR-DIM - 6,5mm infravörös nyomkövető - 6.5mm IR-DIM曳光弾 + 6,5 mm IR-DIM + 6.5 mm IR-DIM + 6.5 mm IR-DIM + 6.5 mm IR-DIM + 6,5 mm infravörös nyomkövető + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 - 6.5mm 低視紅外曳光彈 - 6.5mm 低视红外曳光弹 + 6.5毫米 低視紅外曳光彈 + 6.5 mm 红外曳光 + 6.5 mm IR-DIM - 6.5mm 200Rnd Tracer IR-DIM Belt<br />Rounds: 200<br />Used in: Stoner 99 LMG - Magazynek 6,5mm 200rd Smugacz IR-DIM - Bande 6.5mm 200Cps Traçante IR-DIM<br />Cartouches: 200<br />Utilisé avec: Stoner 99 LMG - Cinta de 200 balas trazadoras IR-DIM de 6.5mm + 6.5 mm 200Rnd Belt Tracer (IR-DIM)<br />Rounds: 200<br />Used in: Stoner 99 LMG + Magazynek 6,5 mm 200rd Smugacz IR-DIM + Bande 6,5 mm 200Cps Traçantes IR-DIM<br />Cartouches: 200<br />Utilisé avec: Stoner 99 LMG + Cinta de 200 balas trazadoras IR-DIM de 6.5 mm Магазин из 200-т 6,5 мм ИК-трассирующих - 6,5mm 200-Patronen-Gurt IR-DIM Leuchtspur<br />Patronen: 200<br />Eingesetzt von: Stoner 99 LMG - 6.5mm 200Rnd Tracer IR-DIM Belt<br />Munizioni: 200<br />In uso su: Stoner 99 LMG - 6.5mm 200náb. Svítící IR-DIM Pás<br />Nábojů: 200<br />Použití u: Stoner 99 LMG - Cinto de munição traçante 6.5mm IR-DIM com 200 cartuchos<br />Cartuchos: 200<br />Usado em: Stoner 99 LMG - 6.5mm 200-lövedékes infravörös nyomkövető heveder<br />Lövedékek: 200<br />Használható: Stoner 99 LMG - 6.5mm 200発入り IR-DIM曳光弾ベルト<br />装填数: 200<br />次で使用: Stoner 99 LMG - 200발들이 6.5mm IR-DIM 예광탄 벨트<br />장탄수: 200<br />사용처: Stoner 99 LMG - 6.5mm 200發 低視度紅外線曳光彈<br />發數: 200<br />使用於: Stoner 99 LMG - 6.5mm 200发 低视度红外线曳光弹<br />发数: 200<br />使用于: Stoner 99 LMG + 6,5 mm 200-Patronen-Gurt IR-DIM Leuchtspur<br />Patronen: 200<br />Eingesetzt von: Stoner 99 LMG + 6.5 mm 200cp Nastro Tracciante (IR-DIM)<br />Munizioni: 200<br />In uso su: Stoner 99 LMG + 6.5 mm 200náb. Svítící IR-DIM Pás<br />Nábojů: 200<br />Použití u: Stoner 99 LMG + Cinto de munição traçante 6.5 mm IR-DIM com 200 cartuchos<br />Cartuchos: 200<br />Usado em: Stoner 99 LMG + 6.5 mm 200-lövedékes infravörös nyomkövető heveder<br />Lövedékek: 200<br />Használható: Stoner 99 LMG + 6.5 mm 200Rnd ベルト トレーサー (IR-DIM)<br />装填数: 200<br />次で使用: Stoner 99 LMG + 200발 들이 6.5mm IR-DIM 예광탄 벨트<br/>장탄수: 200<br/>사용처: 스토너 99 LMG + 6.5毫米 200發 低視度紅外線曳光彈<br />發數: 200<br />使用於: Stoner 99 重機槍 + 口径:6.5 mm 200发 红外曳光<br />发数:200<br />使用于:Stoner 99 LMG + 6.5 mm 200Rnd Belt Tracer (IR-DIM)<br />Mermi: 200<br />Kullanıyor: Stoner 99 LMG - 5.56mm 30Rnd Mag (Mk262) - Magazynek 5,56mm 30rd Mk262 - 5,56mm 30Cps (Mk262) - Cargador de 30 balas de 5.56mm (Mk262) + 5.56 mm 30Rnd Mag (Mk262) + Magazynek 5,56 mm 30rd Mk262 + 5,56 mm 30Cps (Mk262) + Cargador de 30 balas de 5.56 mm (Mk262) Магазин из 30-ти 5.56 мм Mk262 - 5,56mm 30-Patronen-Magazin (Mk262) - 5.56mm 30Rnd Mag (Mk262) - 5.56mm 30náb. Zásobník (Mk262) - Carregador 5.56mm com 30 cartuchos (Mk262) - 5,56mm 30-lövedékes tár (Mk262) - 5.56mm 30発入り 弾倉 (Mk262) - 30발들이 5.56mm 탄창 (Mk262) - 5.56mm 30發 彈匣 (Mk262 狙擊專用彈) - 5.56mm 30发 弹匣 (Mk262 狙击专用弹) + 5,56 mm 30-Patronen-Magazin (Mk262) + 5.56 mm 30cp Car (Mk262) + 5.56 mm 30náb. Zásobník (Mk262) + Carregador 5.56 mm com 30 cartuchos (Mk262) + 5,56 mm 30-lövedékes tár (Mk262) + 5.56mm 30Rnd マガジン (Mk262) + 30발 들이 5.56mm 탄창 (Mk.262) + 5.56毫米 30發 彈匣 (Mk262 狙擊專用彈) + 5.56 mm 30发 弹匣(Mk262) + 5.56 mm 30Rnd Mag (Mk262) - 5.56mm Mk262 - 5,56mm Mk262 - 5,56mm Mk262 - 5.56mm Mk262 + 5.56 mm Mk262 + 5,56 mm Mk262 + 5,56 mm Mk262 + 5.56 mm Mk262 5,56 мм Mk262 - 5,56mm Mk262 - 5.56mm Mk262 - 5.56mm Mk262 - 5.56mm Mk262 - 5,56mm Mk262 - 5.56mm Mk262 - 5.56mm Mk262 - 5.56mm Mk262 狙擊專用彈 - 5.56mm Mk262 狙击专用弹 + 5,56 mm Mk262 + 5.56 mm Mk262 + 5.56 mm Mk262 + 5.56 mm Mk262 + 5,56 mm Mk262 + 5.56 mm Mk262 + 5.56mm Mk.262 + 5.56毫米 Mk262 狙擊專用彈 + 5.56 mm Mk262 + 5.56 mm Mk262 - Caliber: 5.56x45mm NATO (Mk262)<br />Rounds: 30 - Kaliber: 5,56x45mm NATO (Mk262)<br />Pociski: 30 - Calibre: 5,56x45mm NATO (Mk262)<br />Cartouches: 30 - Calibre: 5.56x45mm NATO (Mk262)<br />Balas: 30 + Caliber: 5.56x45 mm NATO (Mk262)<br />Rounds: 30 + Kaliber: 5,56x45 mm NATO (Mk262)<br />Pociski: 30 + Calibre: 5,56x45 mm NATO (Mk262)<br />Cartouches: 30 + Calibre: 5.56x45 mm NATO (Mk262)<br />Balas: 30 Калибр: 5,56x45 мм NATO (Mk262)<br />Патронов: 30 - Kaliber: 5,56x45mm NATO (Mk262)<br />Patronen: 30 + Kaliber: 5,56x45 mm NATO (Mk262)<br />Patronen: 30 Calibro: 5.56x45 mm NATO (Mk262)<br />Munizioni: 30 - Ráže: 5.56x45mm NATO (Mk262)<br />Nábojů: 30 - Calibre: 5.56x45mm NATO (Mk262)<br/>Cartuchos: 30 - Kaliber: 5,56x45mm NATO (Mk262)<br />Lövedékek: 30 - 口径: 5.56x45mm NATO (Mk262)<br />装填数: 30 - 구경: 5.56x45mm NATO (Mk262)<br />장탄수: 30 - 口徑: 5.56x45mm NATO標準 (Mk262 狙擊專用彈)<br />發數: 30 - 口径: 5.56x45mm NATO标准 (Mk262 狙击专用弹)<br />发数: 30 + Ráže: 5.56x45 mm NATO (Mk262)<br />Nábojů: 30 + Calibre: 5.56x45 mm NATO (Mk262)<br/>Cartuchos: 30 + Kaliber: 5,56x45 mm NATO (Mk262)<br />Lövedékek: 30 + 口径: 5.56x45 mm NATO (Mk262)<br />装填数: 30 + 구경: 5.56x45mm NATO (Mk.262)<br/>장탄수: 30 + 口徑: 5.56x45毫米 NATO標準 (Mk262 狙擊專用彈)<br />發數: 30 + 口径:5.56x45 mm 北约(Mk262 狙击专用弹)<br />发数:30 + Kalibre: 5.56x45 mm NATO (Mk262)<br />Mermi: 30 - 5.56mm 30Rnd Mag (Mk318) - Magazynek 5,56mm 30rd (Mk318) - Ch. 5,56mm 30Cps (Mk318) - Cargador de 30 balas de 5.56mm (Mk318) + 5.56 mm 30Rnd Mag (Mk318) + Magazynek 5,56 mm 30rd (Mk318) + Ch. 5,56 mm 30Cps (Mk318) + Cargador de 30 balas de 5.56 mm (Mk318) Магазин из 30-ти 5.56 мм (Mk318) - 5,56mm 30-Patronen-Magazin (Mk318) - 5.56mm 30Rnd Mag (Mk318) - 5.56mm 30Rnd Zásobník (Mk318) - Carregador 5.56mm com 30 cartuchos (Mk318) - 5,56mm 30-lövedékes tár (Mk318) - 5.56mm 30発入り 弾倉 (Mk318) - 30발들이 5.56mm 탄창 (Mk318) - 5.56mm 30發 彈匣 (Mk318 特戰專用彈) - 5.56mm 30发 弹匣 (Mk318 特战专用弹) + 5,56 mm 30-Patronen-Magazin (Mk318) + 5.56 mm 30cp Car (Mk318) + 5.56 mm 30Rnd Zásobník (Mk318) + Carregador 5.56 mm com 30 cartuchos (Mk318) + 5,56 mm 30-lövedékes tár (Mk318) + 5.56mm 30Rnd マガジン (Mk318) + 30발들이 5.56mm 탄창 (Mk.318) + 5.56毫米 30發 彈匣 (Mk318 特戰專用彈) + 5.56 mm 30发 弹匣(Mk318) + 5.56 mm 30Rnd Mag (Mk318) - 5.56mm Mk318 - 5,56mm Mk318 - 5,56mm Mk318 - 5.56mm Mk318 + 5.56 mm Mk318 + 5,56 mm Mk318 + 5,56 mm Mk318 + 5.56 mm Mk318 5.56 мм Mk318 - 5,56mm Mk318 - 5.56mm Mk318 - 5.56mm Mk318 - 5.56mm Mk318 - 5,56mm Mk318 - 5.56mm Mk318 - 5.56mm Mk318 - 5.56mm Mk318 特戰專用彈 - 5.56mm Mk318 特战专用弹 + 5,56 mm Mk318 + 5.56 mm Mk318 + 5.56 mm Mk318 + 5.56 mm Mk318 + 5,56 mm Mk318 + 5.56 mm Mk318 + 5.56mm Mk.318 + 5.56毫米 Mk318 特戰專用彈 + 5.56 mm Mk318 + 5.56 mm Mk318 - Caliber: 5.56x45mm NATO (Mk318)<br />Rounds: 30 - Kaliber: 5,56x45mm NATO (Mk318)<br />Pociski: 30 - Calibre: 5,56x45mm NATO (Mk318)<br />Cartouches: 30 - Calibre: 5.56x45mm NATO (Mk318)<br />Balas: 30 + Caliber: 5.56x45 mm NATO (Mk318)<br />Rounds: 30 + Kaliber: 5,56x45 mm NATO (Mk318)<br />Pociski: 30 + Calibre: 5,56x45 mm NATO (Mk318)<br />Cartouches: 30 + Calibre: 5.56x45 mm NATO (Mk318)<br />Balas: 30 Калибр: 5,56x45 мм NATO (Mk318)<br />Патронов: 30 - Kaliber: 5,56x45mm NATO (Mk318)<br />Patronen: 30 + Kaliber: 5,56x45 mm NATO (Mk318)<br />Patronen: 30 Calibro: 5.56x45 mm NATO (Mk318)<br />Munizioni: 30 - Ráže: 5.56x45mm NATO (Mk318)<br />Nábojů: 30 - Calibre: 5.56x45mm NATO (Mk318)<br/>Cartuchos: 30 - Kaliber: 5,56x45mm NATO (Mk318)<br />Lövedékek: 30 - 口径: 5.56x45mm NATO (Mk318)<br />装填数: 30 - 구경: 5.56x45mm NATO (Mk318)<br />장탄수: 30 - 口徑: 5.56x45mm NATO標準 (Mk318 特戰專用彈)<br />發數: 30 - 口径: 5.56x45mm NATO标准 (Mk318 特战专用弹)<br />发数: 30 + Ráže: 5.56x45 mm NATO (Mk318)<br />Nábojů: 30 + Calibre: 5.56x45 mm NATO (Mk318)<br/>Cartuchos: 30 + Kaliber: 5,56x45 mm NATO (Mk318)<br />Lövedékek: 30 + 口径: 5.56x45 mm NATO (Mk318)<br />装填数: 30 + 구경: 5.56x45mm NATO (Mk.318)<br/>장탄수: 30 + 口徑: 5.56x45毫米 NATO標準 (Mk318 特戰專用彈)<br />發數: 30 + 口径:5.56x45 mm 北约(Mk318 特战专用弹)<br />发数:30 + Kalibre: 5.56x45 mm NATO (Mk318)<br />Mermi: 30 - 5.56mm 30Rnd Mag (M995 AP) - Magazynek 5,56mm 30rd (M995 AP) - Ch. 5,56mm 30Cps (M995 AP) - Cargador de 30 balas de 5.56mm (M995 AP) + 5.56 mm 30Rnd Mag (M995 AP) + Magazynek 5,56 mm 30rd (M995 AP) + Ch. 5,56 mm 30Cps (M995 AP) + Cargador de 30 balas de 5.56 mm (M995 AP) Магазин из 30-ти 5.56 мм (M995 бронебойные) - 5,56mm 30-Patronen-Magazin (M995AP) - 5.56mm 30Rnd Mag (M995 AP) - 5.56mm 30náb. Zásobník (M995 AP) - Carregador 5.56mm com 30 cartuchos (M995 AP) - 5,56mm 30-lövedékes tár (M995 páncéltörő) - 5.56mm 30発入り 弾倉 (M995 徹甲弾) - 30발들이 5.56mm 탄창 (Mk995 철갑탄) - 5.56mm 30發 彈匣 (M995 穿甲彈) - 5.56mm 30发 弹匣 (M995 穿甲弹) + 5,56 mm 30-Patronen-Magazin (M995AP) + 5.56 mm 30cp Car (M995 AP) + 5.56 mm 30náb. Zásobník (M995 AP) + Carregador 5.56 mm com 30 cartuchos (M995 AP) + 5,56 mm 30-lövedékes tár (M995 páncéltörő) + 5.56mm 30Rnd マガジン (M995 徹甲弾) + 30발 들이 5.56mm 탄창 (M995 철갑탄) + 5.56毫米 30發 彈匣 (M995 穿甲彈) + 5.56 mm 30发 弹匣(M995 穿甲) + 5.56 mm 30Rnd Mag (M995 AP) - 5.56mm AP - 5,56mm AP - 5,56mm AP - 5.56mm AP + 5.56 mm AP + 5,56 mm AP + 5,56 mm AP + 5.56 mm AP 5.56 мм бронебойные - 5,56mm AP - 5.56mm AP - 5.56mm AP - 5.56mm M995 AP - 5,56mm páncéltörő - 5.56mm 徹甲弾 + 5,56 mm AP + 5.56 mm AP + 5.56 mm AP + 5.56 mm M995 AP + 5,56 mm páncéltörő + 5.56 mm AP 5.56mm 철갑탄 - 5.56mm M995 穿甲彈 - 5.56mm M995 穿甲弹 + 5.56毫米 M995 穿甲彈 + 5.56 mm 穿甲 + 5.56 mm AP - Caliber: 5.56x45mm NATO (M995 AP)<br />Rounds: 30 - Kaliber: 5,56x45mm NATO (M995 AP)<br />Pociski: 30 - Calibre: 5,56x45mm NATO (M995 AP)<br />Cartouches: 30 - Calibre: 5.56x45mm NATO (M995 AP)<br />Balas: 30 + Caliber: 5.56x45 mm NATO (M995 AP)<br />Rounds: 30 + Kaliber: 5,56x45 mm NATO (M995 AP)<br />Pociski: 30 + Calibre: 5,56x45 mm NATO (M995 AP)<br />Cartouches: 30 + Calibre: 5.56x45 mm NATO (M995 AP)<br />Balas: 30 Калибр: 5,56x45 мм NATO (M995 бронебойные)<br />Патронов: 30 - Kaliber: 5,56x45mm NATO (M995 AP)<br />Patronen: 30 + Kaliber: 5,56x45 mm NATO (M995 AP)<br />Patronen: 30 Calibro: 5.56x45 mm NATO (M995 AP)<br />Munizioni: 30 - Ráže: 5.56x45mm NATO (M995 AP)<br />Nábojů: 30 - Calibre: 5.56x45mm NATO (M995 AP)<br/>Cartuchos: 30 - Kaliber: 5,56x45mm NATO (M995 páncéltörő)<br />Lövedékek: 30 - 口径: 5.56x45mm NATO (M995 徹甲弾)<br />装填数: 30 - 구경: 5.56x45mm NATO (Mk995 철갑탄)<br />장탄수: 30 - 口徑: 5.56x45mm NATO標準 (M995 穿甲彈)<br />發數: 30 - 口径: 5.56x45mm NATO标准 (M995 穿甲弹)<br />发数: 30 + Ráže: 5.56x45 mm NATO (M995 AP)<br />Nábojů: 30 + Calibre: 5.56x45 mm NATO (M995 AP)<br/>Cartuchos: 30 + Kaliber: 5,56x45 mm NATO (M995 páncéltörő)<br />Lövedékek: 30 + 口径: 5.56x45 mm NATO (M995 徹甲弾)<br />装填数: 30 + 구경: 5.56x45mm NATO (M995 철갑탄)<br/>장탄수: 30 + 口徑: 5.56x45毫米 NATO標準 (M995 穿甲彈)<br />發數: 30 + 口径:5.56x45 mm 北约(M995 穿甲)<br />发数:30 + Kalibre: 5.56x45 mm NATO (M995 AP)<br />Mermi: 30 - 7.62mm 10Rnd Mag (M118LR) - Magazynek 7,62mm 10rd (M118LR) - Ch. 7,62mm 10Cps (M118LR) - Cargador de 10 balas de 7.62mm (M118LR) + 7.62 mm 10Rnd Mag (M118LR) + Magazynek 7,62 mm 10rd (M118LR) + Ch. 7,62 mm 10Cps (M118LR) + Cargador de 10 balas de 7.62 mm (M118LR) Магазин из 10-ти 7,62 мм (M118LR) - 7,62mm 10-Patronen-Magazin (M118LR) - 7.62mm 10Rnd Mag (M118LR) - 7.62mm 10náb. Zásobník (M118LR) - Carregador 7.62mm com 10 cartuchos (M118LR) - 7,62mm 10-lövedékes tár (M118LR) - 7.62mm 10発入り 弾倉 (M118LR) - 10발들이 7.62mm 탄창 (M118LR) - 7.62mm 10發 彈匣 (M118LR 狙擊專用彈) - 7.62mm 10发 弹匣 (M118LR 狙击专用弹) + 7,62 mm 10-Patronen-Magazin (M118LR) + 7.62 mm 10cp Car (M118LR) + 7.62 mm 10náb. Zásobník (M118LR) + Carregador 7.62 mm com 10 cartuchos (M118LR) + 7,62 mm 10-lövedékes tár (M118LR) + 7.62mm 10Rnd マガジン (M118LR) + 10발 들이 7.62mm 탄창 (M118LR) + 7.62毫米 10發 彈匣 (M118LR 狙擊專用彈) + 7.62 mm 10发 弹匣(M118LR) + 7.62 mm 10Rnd Mag (M118LR) - 7.62mm M118LR - 7,62mm M118LR - 7,62mm M118LR - 7.62mm M118LR + 7.62 mm M118LR + 7,62 mm M118LR + 7,62 mm M118LR + 7.62 mm M118LR 7,62 мм M118LR - 7,62mm M118LR - 7.62mm M118LR - 7.62mm M118LR - 7.62mm M118LR - 7,62mm M118LR - 7.62mm M118LR + 7,62 mm M118LR + 7.62 mm M118LR + 7.62 mm M118LR + 7.62 mm M118LR + 7,62 mm M118LR + 7.62 mm M118LR 7.62mm M118LR - 7.62mm M118LR 狙擊專用彈 - 7.62mm M118LR 狙击专用弹 + 7.62m毫米 M118LR 狙擊專用彈 + 7.62 mm M118LR + 7.62 mm M118LR - Caliber: 7.62x51mm NATO (M118LR)<br />Rounds: 10 - Kaliber: 7,62x51mm NATO (M118LR)<br />Pociski: 10 - Calibre: 7,62x51mm NATO (M118LR)<br />Cartouches: 10 - Calibre: 7.62x51mm NATO (M118LR)<br />Balas: 10 + Caliber: 7.62x51 mm NATO (M118LR)<br />Rounds: 10 + Kaliber: 7,62x51 mm NATO (M118LR)<br />Pociski: 10 + Calibre: 7,62x51 mm NATO (M118LR)<br />Cartouches: 10 + Calibre: 7.62x51 mm NATO (M118LR)<br />Balas: 10 Калибр: 7,62x51 мм NATO (M118LR)<br />Патронов: 10 - Kaliber: 7,62x51mm NATO (M118LR)<br />Patronen: 10 + Kaliber: 7,62x51 mm NATO (M118LR)<br />Patronen: 10 Calibro: 7.62x51 mm NATO (M118LR)<br />Munizioni: 10 - Ráže: 7.62x51mm NATO (M118LR)<br />Nábojů: 10 - Calibre: 7.26x51mm NATO (M118LR)<br/>Cartuchos: 10 - Kaliber: 7,62x51mm NATO (M118LR)<br />Lövedékek: 10 - 口径: 7.62x51mm NATO (M118LR)<br />装填数: 10 - 구경: 7.62x51mm NATO (M118LR)<br />장탄수: 10 - 口徑: 7.62x51mm NATO標準 (M118LR 狙擊專用彈)<br />發數: 10 - 口径: 7.62x51mm NATO标准 (M118LR 狙击专用弹)<br />发数: 10 + Ráže: 7.62x51 mm NATO (M118LR)<br />Nábojů: 10 + Calibre: 7.26x51 mm NATO (M118LR)<br/>Cartuchos: 10 + Kaliber: 7,62x51 mm NATO (M118LR)<br />Lövedékek: 10 + 口径: 7.62x51 mm NATO (M118LR)<br />装填数: 10 + 구경: 7.62x51mm NATO (M118LR)<br/>장탄수: 10 + 口徑: 7.62x51毫米 NATO標準 (M118LR 狙擊專用彈)<br />發數: 10 + 口径:7.62x51 mm 北约(M118LR 狙击专用弹)<br />发数:10 + Kalibre: 7.62x51 mm NATO (M118LR)<br />Mermi: 10 - 7.62mm 20Rnd Mag (M118LR) - Magazynek 7,62mm 20rd (M118LR) - Ch. 7,62mm 20Cps (M118LR) - Cargador de 20 balas de 7.62mm (M118LR) + 7.62 mm 20Rnd Mag (M118LR) + Magazynek 7,62 mm 20rd (M118LR) + Ch. 7,62 mm 20Cps (M118LR) + Cargador de 20 balas de 7.62 mm (M118LR) Магазин из 20-ти 7,62 мм (M118LR) - 7,62mm 20-Patronen-Magazin (M118LR) - 7.62mm 20Rnd Mag (M118LR) - 7.62mm 20náb. Zásobník (M118LR) - Carregador 7.62mm com 20 cartuchos (M118LR) - 7,62mm 20-lövedékes tár (M118LR) - 7.62mm 20発入り 弾倉 (M118LR) - 20발들이 7.62mm 탄창 (M118LR) - 7.62mm 20發 彈匣 (M118LR 狙擊專用彈) - 7.62mm 20发 弹匣 (M118LR 狙击专用弹) + 7,62 mm 20-Patronen-Magazin (M118LR) + 7.62 mm 20cp Car (M118LR) + 7.62 mm 20náb. Zásobník (M118LR) + Carregador 7.62 mm com 20 cartuchos (M118LR) + 7,62 mm 20-lövedékes tár (M118LR) + 7.62mm 20Rnd マガジン (M118LR) + 20발 들이 7.62mm 탄창 (M118LR) + 7.62毫米 20發 彈匣 (M118LR 狙擊專用彈) + 7.62 mm 20发 弹匣(M118LR) + 7.62 mm 20Rnd Mag (M118LR) - 7.62mm M118LR - 7,62mm M118LR - 7,62mm M118LR - 7.62mm M118LR + 7.62 mm M118LR + 7,62 mm M118LR + 7,62 mm M118LR + 7.62 mm M118LR 7,62 мм M118LR - 7,62mm M118LR - 7.62mm M118LR - 7.62mm M118LR - 7.62mm M118LR - 7,62mm M118LR - 7.62mm M118LR + 7,62 mm M118LR + 7.62 mm M118LR + 7.62 mm M118LR + 7.62 mm M118LR + 7,62 mm M118LR + 7.62 mm M118LR 7.62mm M118LR - 7.62mm M118LR 狙擊專用彈 - 7.62mm M118LR 狙击专用弹 + 7.62毫米 M118LR 狙擊專用彈 + 7.62 mm M118LR + 7.62 mm M118LR - Caliber: 7.62x51mm NATO (M118LR)<br />Rounds: 20 - Kaliber: 7,62x51mm NATO (M118LR)<br />Pociski: 20 - Calibre: 7.62x51mm NATO (M118LR)<br />Cartouches: 20 - Calibre: 7.62x51mm NATO (M118LR)<br />Balas: 20 + Caliber: 7.62x51 mm NATO (M118LR)<br />Rounds: 20 + Kaliber: 7,62x51 mm NATO (M118LR)<br />Pociski: 20 + Calibre: 7,62x51 mm NATO (M118LR)<br />Cartouches: 20 + Calibre: 7.62x51 mm NATO (M118LR)<br />Balas: 20 Калибр: 7,62x51 мм NATO (M118LR)<br />Патронов: 20 - Kaliber: 7,62x51mm NATO (M118LR)<br />Patronen: 20 + Kaliber: 7,62x51 mm NATO (M118LR)<br />Patronen: 20 Calibro: 7.62x51 mm NATO (M118LR)<br />Munizioni: 20 - Ráže: 7.62x51mm NATO (M118LR)<br />Nábojů: 20 - Calibre: 7.26x51mm NATO (M118LR)<br/>Cartuchos: 20 - Kaliber: 7,62x51mm NATO (M118LR)<br />Lövedékek: 20 - 口径: 7.62x51mm NATO (M118LR)<br />装填数: 20 - 구경: 7.62x51mm NATO (M118LR)<br />장탄수: 20 - 口徑: 7.62x51mm NATO標準 (M118LR 狙擊專用彈)<br />發數: 20 - 口径: 7.62x51mm NATO标准 (M118LR 狙击专用弹)<br />发数: 20 + Ráže: 7.62x51 mm NATO (M118LR)<br />Nábojů: 20 + Calibre: 7.26x51 mm NATO (M118LR)<br/>Cartuchos: 20 + Kaliber: 7,62x51 mm NATO (M118LR)<br />Lövedékek: 20 + 口径: 7.62x51 mm NATO (M118LR)<br />装填数: 20 + 구경: 7.62x51mm NATO (M118LR)<br/>장탄수: 20 + 口徑: 7.62x51毫米 NATO標準 (M118LR 狙擊專用彈)<br />發數: 20 + 口径:7.62x51 mm 北约(M118LR 狙击专用弹)<br />发数:20 + Kalibre: 7.62x51 mm NATO (M118LR)<br />Mermi: 20 - 7.62mm 10Rnd Mag (Mk316 Mod 0) - Magazynek 7,62mm 10rd (Mk316 Mod 0) - Ch. 7,62mm 10Cps (Mk316 Mod 0) - Cargador de 10 balas de 7.62mm (Mk316 Mod 0) + 7.62 mm 10Rnd Mag (Mk316 Mod 0) + Magazynek 7,62 mm 10rd (Mk316 Mod 0) + Ch. 7,62 mm 10Cps (Mk316 Mod 0) + Cargador de 10 balas de 7.62 mm (Mk316 Mod 0) Магазин из 10-ти 7,62 мм (Mk316 Mod 0) - 7,62mm 10-Patronen-Magazin (Mk316 Mod 0) - 7.62mm 10Rnd Mag (Mk316 Mod 0) - 7.62mm 10náb. Zásobník (Mk316 Mod 0) - Carregador 7.62mm com 10 cartuchos (Mk316 Mod 0) - 7,62mm 10-lövedékes tár (Mk316 Mod 0) - 7.62mm 10発入り 弾倉 (Mk316 Mod 0) - 10발들이 7.62mm 탄창 (Mk316 Mod 0) - 7.62mm 10發 彈匣 (Mk316 Mod 0 狙擊專用彈) - 7.62mm 10发 弹匣 (Mk316 Mod 0 狙击专用弹) + 7,62 mm 10-Patronen-Magazin (Mk316 Mod 0) + 7.62 mm 10cp Car (Mk316 Mod 0) + 7.62 mm 10náb. Zásobník (Mk316 Mod 0) + Carregador 7.62 mm com 10 cartuchos (Mk316 Mod 0) + 7,62 mm 10-lövedékes tár (Mk316 Mod 0) + 7.62mm 10Rnd マガジン (Mk316 Mod 0) + 10발 들이 7.62mm 탄창 (Mk.316 Mod 0) + 7.62毫米 10發 彈匣 (Mk316 Mod 0 狙擊專用彈) + 7.62 mm 10发 弹匣(Mk316 Mod 0) + 7.62 mm 10Rnd Mag (Mk316 Mod 0) - 7.62mm Mk316 - 7,62mm Mk316 - 7,62mm Mk316 - 7.62mm Mk316 + 7.62 mm Mk316 + 7,62 mm Mk316 + 7,62 mm Mk316 + 7.62 mm Mk316 7,62 мм Mk316 - 7,62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 - 7,62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 狙擊專用彈 - 7.62mm Mk316 狙击专用弹 + 7,62 mm Mk316 + 7.62 mm Mk316 + 7.62 mm Mk316 + 7.62 mm Mk316 + 7,62 mm Mk316 + 7.62 mm Mk316 + 7.62mm Mk.316 + 7.62毫米 Mk316 狙擊專用彈 + 7.62 mm Mk316 + 7.62 mm Mk316 - Caliber: 7.62x51mm NATO (Mk316 Mod 0)<br />Rounds: 10 - Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Pociski: 10 - Calibre: 7,62x51mm NATO (Mk316 Mod 0)<br />Cartouches: 10 - Calibre: 7.62x51mm NATO (Mk316 Mod 0)<br />Balas: 10 + Caliber: 7.62x51 mm NATO (Mk316 Mod 0)<br />Rounds: 10 + Kaliber: 7,62x51 mm NATO (Mk316 Mod 0)<br />Pociski: 10 + Calibre: 7,62x51 mm NATO (Mk316 Mod 0)<br />Cartouches: 10 + Calibre: 7.62x51 mm NATO (Mk316 Mod 0)<br />Balas: 10 Калибр: 7,62x51 мм NATO (Mk316 Mod 0)<br />Патронов: 10 - Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Patronen: 10 + Kaliber: 7,62x51 mm NATO (Mk316 Mod 0)<br />Patronen: 10 Calibro: 7.62x51 mm NATO (Mk316 Mod 0)<br />Munizioni: 10 - Ráže: 7.62x51mm NATO (Mk316 Mod 0)<br />Nábojů: 10 - Calibre: 7.26x51mm NATO (Mk316 Mod 0)<br/>Cartuchos: 10 - Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Lövedékek: 10 - 口径: 7.62x51mm NATO (Mk316 Mod 0)<br />装填数: 10 - 구경: 7.62x51mm NATO (Mk316 Mod 0)<br />장탄수: 10 - 口徑: 7.62x51mm NATO標準 (Mk316 Mod 0 狙擊專用彈)<br />發數: 10 - 口径: 7.62x51mm NATO标准 (Mk316 Mod 0 狙击专用弹)<br />发数: 10 + Ráže: 7.62x51 mm NATO (Mk316 Mod 0)<br />Nábojů: 10 + Calibre: 7.26x51 mm NATO (Mk316 Mod 0)<br/>Cartuchos: 10 + Kaliber: 7,62x51 mm NATO (Mk316 Mod 0)<br />Lövedékek: 10 + 口径: 7.62x51 mm NATO (Mk316 Mod 0)<br />装填数: 10 + 구경: 7.62x51mm NATO (Mk.316 Mod 0)<br/>장탄수: 10 + 口徑: 7.62x51毫米 NATO標準 (Mk316 Mod 0 狙擊專用彈)<br />發數: 10 + 口径:7.62x51 mm 北约(Mk316 Mod 0 狙击专用弹)<br />发数:10 + Kalibre: 7.62x51 mm NATO (Mk316 Mod 0)<br />Mermi: 10 - 7.62mm 20Rnd Mag (Mk316 Mod 0) - Magazynek 7,62mm 20rd (Mk316 Mod 0) - Ch. 7,62mm 20Cps (Mk316 Mod 0) - Cargador de 20 balas de 7.62mm (Mk316 Mod 0) + 7.62 mm 20Rnd Mag (Mk316 Mod 0) + Magazynek 7,62 mm 20rd (Mk316 Mod 0) + Ch. 7,62 mm 20Cps (Mk316 Mod 0) + Cargador de 20 balas de 7.62 mm (Mk316 Mod 0) Магазин из 20-ти 7,62 мм (Mk316 Mod 0) - 7,62mm 20-Patronen-Magazin (Mk316 Mod 0) - 7.62mm 20Rnd Mag (Mk316 Mod 0) - 7.62mm 20náb. Zásobník (Mk316 Mod 0) - Carregador 7.62mm com 20 cartuchos (Mk316 Mod 0) - 7,62mm 20-lövedékes tár (Mk316 Mod 0) - 7.62mm 20発入り 弾倉 (Mk316 Mod 0) - 20발들이 7.62mm 탄창 (Mk316 Mod 0) - 7.62mm 20發 彈匣 (Mk316 Mod 0 狙擊專用彈) - 7.62mm 20发 弹匣 (Mk316 Mod 0 狙击专用弹) + 7,62 mm 20-Patronen-Magazin (Mk316 Mod 0) + 7.62 mm 20cp Car (Mk316 Mod 0) + 7.62 mm 20náb. Zásobník (Mk316 Mod 0) + Carregador 7.62 mm com 20 cartuchos (Mk316 Mod 0) + 7,62 mm 20-lövedékes tár (Mk316 Mod 0) + 7.62mm 20Rnd マガジン (Mk316 Mod 0) + 20발 들이 7.62mm 탄창 (Mk.316 Mod 0) + 7.62毫米 20發 彈匣 (Mk316 Mod 0 狙擊專用彈) + 7.62 mm 20发 弹匣(Mk316 Mod 0) + 7.62 mm 20Rnd Mag (Mk316 Mod 0) - 7.62mm Mk316 - 7,62mm Mk316 - 7,62mm Mk316 - 7.62mm Mk316 + 7.62 mm Mk316 + 7,62 mm Mk316 + 7,62 mm Mk316 + 7.62 mm Mk316 7,62 мм Mk316 - 7,62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 - 7,62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 - 7.62mm Mk316 狙擊專用彈 - 7.62mm Mk316 狙击专用弹 + 7,62 mm Mk316 + 7.62 mm Mk316 + 7.62 mm Mk316 + 7.62 mm Mk316 + 7,62 mm Mk316 + 7.62 mm Mk316 + 7.62mm Mk.316 + 7.62毫米 Mk316 狙擊專用彈 + 7.62 mm Mk316 + 7.62 mm Mk316 - Caliber: 7.62x51mm NATO (Mk316 Mod 0)<br />Rounds: 20 - Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Pociski: 20 - Calibre: 7,62x51mm NATO (Mk316 Mod 0)<br />Cartouches: 20 - Calibre: 7.62x51mm NATO (Mk316 Mod 0)<br />Balas: 20 + Caliber: 7.62x51 mm NATO (Mk316 Mod 0)<br />Rounds: 20 + Kaliber: 7,62x51 mm NATO (Mk316 Mod 0)<br />Pociski: 20 + Calibre: 7,62x51 mm NATO (Mk316 Mod 0)<br />Cartouches: 20 + Calibre: 7.62x51 mm NATO (Mk316 Mod 0)<br />Balas: 20 Калибр: 7,62x51 мм NATO (Mk316 Mod 0)<br />Патронов: 20 - Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Patronen: 20 + Kaliber: 7,62x51 mm NATO (Mk316 Mod 0)<br />Patronen: 20 Calibro: 7.62x51 mm NATO (Mk316 Mod 0)<br />Munizioni: 20 - Ráže: 7.62x51mm NATO (Mk316 Mod 0)<br />Nábojů: 20 - Calibre: 7.26x51mm NATO (Mk316 Mod 0)<br/>Cartuchos: 20 - Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Lövedékek: 20 - 口径: 7.62x51mm NATO (Mk316 Mod 0)<br />装填数: 20 - 구경: 7.62x51mm NATO (Mk316 Mod 0)<br />장탄수: 20 - 口徑: 7.62x51mm NATO標準 (Mk316 Mod 0 狙擊專用彈)<br />發數: 20 - 口径: 7.62x51mm NATO标准 (Mk316 Mod 0 狙击专用弹)<br />发数: 20 + Ráže: 7.62x51 mm NATO (Mk316 Mod 0)<br />Nábojů: 20 + Calibre: 7.26x51 mm NATO (Mk316 Mod 0)<br/>Cartuchos: 20 + Kaliber: 7,62x51 mm NATO (Mk316 Mod 0)<br />Lövedékek: 20 + 口径: 7.62x51 mm NATO (Mk316 Mod 0)<br />装填数: 20 + 구경: 7.62x51mm NATO (Mk.316 Mod 0)<br/>장탄수: 20 + 口徑: 7.62x51毫米 NATO標準 (Mk316 Mod 0 狙擊專用彈)<br />發數: 20 + 口径:7.62x51 mm 北约(Mk316 Mod 0 狙击专用弹)<br />发数:20 + Kalibre: 7.62x51 mm NATO (Mk316 Mod 0)<br />Mermi: 20 - 7.62mm 10Rnd Mag (Mk319 Mod 0) - Magazynek 7,62mm 10rd (Mk319 Mod 0) - Ch. 7,62mm 10Cps (Mk319 Mod 0) - Cargador de 10 balas de 7.62mm (Mk319 Mod 0) + 7.62 mm 10Rnd Mag (Mk319 Mod 0) + Magazynek 7,62 mm 10rd (Mk319 Mod 0) + Ch. 7,62 mm 10Cps (Mk319 Mod 0) + Cargador de 10 balas de 7.62 mm (Mk319 Mod 0) Магазин из 10-ти 7,62 мм (Mk319 Mod 0) - 7,62mm 10-Patronen-Magazin (Mk319 Mod 0) - 7.62mm 10Rnd Mag (Mk319 Mod 0) - 7.62mm 10náb. Zásobník (Mk319 Mod 0) - Carregador 7.62mm com 10 cartuchos (Mk319 Mod 0) - 7,62mm 10-lövedékes tár (Mk319 Mod 0) - 7.62mm 10発入り 弾倉 (Mk319 Mod 0) - 10발들이 7.62mm 탄창 (Mk319 Mod 0) - 7.62mm 10發 彈匣 (Mk319 Mod 0 特戰專用彈) - 7.62mm 10发 弹匣 (Mk319 Mod 0 特战专用弹) + 7,62 mm 10-Patronen-Magazin (Mk319 Mod 0) + 7.62 mm 10cp Car (Mk319 Mod 0) + 7.62 mm 10náb. Zásobník (Mk319 Mod 0) + Carregador 7.62 mm com 10 cartuchos (Mk319 Mod 0) + 7,62 mm 10-lövedékes tár (Mk319 Mod 0) + 7.62mm 10Rnd マガジン (Mk319 Mod 0) + 10발들이 7.62mm 탄창 (Mk.319 Mod 0) + 7.62毫米 10發 彈匣 (Mk319 Mod 0 特戰專用彈) + 7.62 mm 10发 弹匣(Mk319 Mod 0) + 7.62 mm 10Rnd Mag (Mk319 Mod 0) - 7.62mm Mk319 - 7,62mm Mk319 - 7,62mm Mk319 - 7.62mm Mk319 + 7.62 mm Mk319 + 7,62 mm Mk319 + 7,62 mm Mk319 + 7.62 mm Mk319 7,62 мм Mk319 - 7,62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 - 7,62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 特戰專用彈 - 7.62mm Mk319 特战专用弹 + 7,62 mm Mk319 + 7.62 mm Mk319 + 7.62 mm Mk319 + 7.62 mm Mk319 + 7,62 mm Mk319 + 7.62 mm Mk319 + 7.62mm Mk.319 + 7.62毫米 Mk319 特戰專用彈 + 7.62 mm Mk319 + 7.62 mm Mk319 - Caliber: 7.62x51mm NATO (Mk319 Mod 0)<br />Rounds: 10 - Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Pociski: 10 - Calibre: 7,62x51mm NATO (Mk319 Mod 0)<br />Cartouches: 10 - Calibre: 7.62x51mm NATO (Mk319 Mod 0)<br />Balas: 10 + Caliber: 7.62x51 mm NATO (Mk319 Mod 0)<br />Rounds: 10 + Kaliber: 7,62x51 mm NATO (Mk319 Mod 0)<br />Pociski: 10 + Calibre: 7,62x51 mm NATO (Mk319 Mod 0)<br />Cartouches: 10 + Calibre: 7.62x51 mm NATO (Mk319 Mod 0)<br />Balas: 10 Калибр: 7,62x51 мм NATO (Mk319 Mod 0)<br />Патронов: 10 - Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Patronen: 10 + Kaliber: 7,62x51 mm NATO (Mk319 Mod 0)<br />Patronen: 10 Calibro: 7.62x51 mm NATO (Mk319 Mod 0)<br />Munizioni: 10 - Ráže: 7.62x51mm NATO (Mk319 Mod 0)<br />Nábojů: 10 - Calibre: 7.26x51mm NATO (Mk319 Mod 0)<br/>Cartuchos: 10 - Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Lövedékek: 10 - 口径: 7.62x51mm NATO (Mk319 Mod 0)<br />装填数: 10 - 구경: 7.62x51mm NATO (Mk319 Mod 0)<br />장탄수: 10 - 口徑: 7.62x51mm NATO標準 (Mk319 Mod 0 特戰專用彈)<br />發數: 10 - 口径: 7.62x51mm NATO标准 (Mk319 Mod 0 特战专用弹)<br />发数: 10 + Ráže: 7.62x51 mm NATO (Mk319 Mod 0)<br />Nábojů: 10 + Calibre: 7.26x51 mm NATO (Mk319 Mod 0)<br/>Cartuchos: 10 + Kaliber: 7,62x51 mm NATO (Mk319 Mod 0)<br />Lövedékek: 10 + 口径: 7.62x51 mm NATO (Mk319 Mod 0)<br />装填数: 10 + 구경: 7.62x51mm NATO (Mk.319 Mod 0)<br/>장탄수: 10 + 口徑: 7.62x51毫米 NATO標準 (Mk319 Mod 0 特戰專用彈)<br />發數: 10 + 口径:7.62x51 mm 北约(Mk319 Mod 0 特战专用弹)<br />发数:10 + Kalibre: 7.62x51 mm NATO (Mk319 Mod 0)<br />Mermi: 20 - 7.62mm 20Rnd Mag (Mk319 Mod 0) - Magazynek 7,62mm 20rd (Mk319 Mod 0) - Ch. 7,62mm 20Cps (Mk319 Mod 0) - Cargador de 20 balas de 7.62mm (Mk319 Mod 0) + 7.62 mm 20Rnd Mag (Mk319 Mod 0) + Magazynek 7,62 mm 20rd (Mk319 Mod 0) + Ch. 7,62 mm 20Cps (Mk319 Mod 0) + Cargador de 20 balas de 7.62 mm (Mk319 Mod 0) Магазин из 20-ти 7,62 мм (Mk319 Mod 0) - 7,62mm 20-Patronen-Magazin (Mk319 Mod 0) - 7.62mm 20Rnd Mag (Mk319 Mod 0) - 7.62mm 20náb. Zásobník (Mk319 Mod 0) - Carregador 7.62mm com 20 cartuchos (Mk319 Mod 0) - 7,62mm 20-lövedékes tár (Mk319 Mod 0) - 7.62mm 20発入り 弾倉 (Mk319 Mod 0) - 20발들이 7.62mm 탄창 (Mk319 Mod 0) - 7.62mm 20發 彈匣 (Mk319 Mod 0 特戰專用彈) - 7.62mm 20发 弹匣 (Mk319 Mod 0 特战专用弹) + 7,62 mm 20-Patronen-Magazin (Mk319 Mod 0) + 7.62 mm 20cp Car (Mk319 Mod 0) + 7.62 mm 20náb. Zásobník (Mk319 Mod 0) + Carregador 7.62 mm com 20 cartuchos (Mk319 Mod 0) + 7,62 mm 20-lövedékes tár (Mk319 Mod 0) + 7.62mm 20Rnd マガジン (Mk319 Mod 0) + 20들이 7.62mm 탄창 (Mk.319 Mod 0) + 7.62毫米 20發 彈匣 (Mk319 Mod 0 特戰專用彈) + 7.62 mm 20发 弹匣(Mk319 Mod 0) + 7.62 mm 20Rnd Mag (Mk319 Mod 0) - 7.62mm Mk319 - 7,62mm Mk319 - 7,62mm Mk319 - 7.62mm Mk319 + 7.62 mm Mk319 + 7,62 mm Mk319 + 7,62 mm Mk319 + 7.62 mm Mk319 7,62 мм Mk319 - 7,62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 - 7,62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 - 7.62mm Mk319 特戰專用彈 - 7.62mm Mk319 特战专用弹 + 7,62 mm Mk319 + 7.62 mm Mk319 + 7.62 mm Mk319 + 7.62 mm Mk319 + 7,62 mm Mk319 + 7.62 mm Mk319 + 7.62mm Mk.319 + 7.62毫米 Mk319 特戰專用彈 + 7.62 mm Mk319 + 7.62 mm Mk319 - Caliber: 7.62x51mm NATO (Mk319 Mod 0)<br />Rounds: 20 - Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Pociski: 20 - Calibre: 7,62x51mm NATO (Mk319 Mod 0)<br />Cartouches: 20 - Calibre: 7.62x51mm NATO (Mk319 Mod 0)<br />Balas: 20 + Caliber: 7.62x51 mm NATO (Mk319 Mod 0)<br />Rounds: 20 + Kaliber: 7,62x51 mm NATO (Mk319 Mod 0)<br />Pociski: 20 + Calibre: 7,62x51 mm NATO (Mk319 Mod 0)<br />Cartouches: 20 + Calibre: 7.62x51 mm NATO (Mk319 Mod 0)<br />Balas: 20 Калибр: 7,62x51 мм NATO (Mk319 Mod 0)<br />Патронов: 20 - Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Patronen: 20 + Kaliber: 7,62x51 mm NATO (Mk319 Mod 0)<br />Patronen: 20 Calibro: 7.62x51 mm NATO (Mk319 Mod 0)<br />Munizioni: 20 - Ráže: 7.62x51mm NATO (Mk319 Mod 0)<br />Nábojů: 20 - Calibre: 7.26x51mm NATO (Mk319 Mod 0)<br/>Cartuchos: 20 - Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Lövedékek: 20 - 口径: 7.62x51mm NATO (Mk319 Mod 0)<br />装填数: 20 - 구경: 7.62x51mm NATO (Mk319 Mod 0)<br />장탄수: 20 - 口徑: 7.62x51mm NATO標準 (Mk319 Mod 0 特戰專用彈)<br />發數: 20 - 口径: 7.62x51mm NATO标准 (Mk319 Mod 0 特战专用弹)<br />发数: 20 + Ráže: 7.62x51 mm NATO (Mk319 Mod 0)<br />Nábojů: 20 + Calibre: 7.26x51 mm NATO (Mk319 Mod 0)<br/>Cartuchos: 20 + Kaliber: 7,62x51 mm NATO (Mk319 Mod 0)<br />Lövedékek: 20 + 口径: 7.62x51 mm NATO (Mk319 Mod 0)<br />装填数: 20 + 구경: 7.62x51mm NATO (Mk.319 Mod 0)<br/>장탄수: 20 + 口徑: 7.62x51毫米 NATO標準 (Mk319 Mod 0 特戰專用彈)<br />發數: 20 + 口径:7.62x51 mm 北约(Mk319 Mod 0)<br />发数:20 + Kalibre: 7.62x51 mm NATO (Mk319 Mod 0)<br />Mermi: 20 - 7.62mm 10Rnd Mag (M993 AP) - Magazynek 7,62mm 10rd (M993 AP) - Ch. 7,62mm 10Cps (M993 AP) - Cargador de 10 balas de 7.62mm (M993 AP) + 7.62 mm 10Rnd Mag (M993 AP) + Magazynek 7,62 mm 10rd (M993 AP) + Ch. 7,62 mm 10Cps (M993 AP) + Cargador de 10 balas de 7.62 mm (M993 AP) Магазин из 10-ти 7,62 мм (M993 бронебойные) - 7,62mm 10-Patronen-Magazin (M993 AP) - 7.62mm 10Rnd Mag (M993 AP) + 7,62 mm 10-Patronen-Magazin (M993 AP) + 7.62 mm 10cp Car (M993 AP) 7.62 10náb. Zásobník (M993 AP) - Carregador 7.62mm com 10 cartuchos (M993 AP) - 7,62mm 10-lövedékes tár (M993 páncéltörő) - 7.62mm 10発入り 弾倉 (M993 徹甲弾) - 10발들이 7.62mm 탄창 (M993 철갑탄) - 7.62mm 10發 彈匣 (M993 穿甲專用彈) - 7.62mm 10发 弹匣 (M993 穿甲专用弹) + Carregador 7.62 mm com 10 cartuchos (M993 AP) + 7,62 mm 10-lövedékes tár (M993 páncéltörő) + 7.62mm 10Rnd マガジン (M993 徹甲弾) + 10발 들이 7.62mm 탄창 (M993 철갑탄) + 7.62毫米 10發 彈匣 (M993 穿甲專用彈) + 7.62 mm 10发 弹匣(M993 穿甲) + 7.62 mm 10Rnd Mag (M993 AP) - 7.62mm AP - 7,62mm AP - 7,62mm AP - 7.62mm AP - 7,62mm бронебойные - 7,62mm AP - 7.62mm AP - 7.62mm AP - 7.62mm AP - 7,62mm páncéltörő - 7.62mm 徹甲弾 + 7.62 mm AP + 7,62 mm AP + 7,62 mm AP + 7.62 mm AP + 7,62 mm бронебойные + 7,62 mm AP + 7.62 mm AP + 7.62 mm AP + 7.62 mm AP + 7,62 mm páncéltörő + 7.62 mm AP 7.62mm 철갑탄 - 7.62mm M993 穿甲專用彈 - 7.62mm M993 穿甲专用弹 + 7.62毫米 M993 穿甲專用彈 + 7.62 mm M993 + 7.62 mm AP - Caliber: 7.62x51mm NATO (M993 AP)<br />Rounds: 10 - Kaliber: 7,62x51mm NATO (M993 AP)<br />Pociski: 10 - Calibre: 7,62x51mm NATO (M993 AP)<br />Cartouches: 10 - Calibre: 7.62x51mm NATO (M993 AP)<br />Balas: 10 + Caliber: 7.62x51 mm NATO (M993 AP)<br />Rounds: 10 + Kaliber: 7,62x51 mm NATO (M993 AP)<br />Pociski: 10 + Calibre: 7,62x51 mm NATO (M993 AP)<br />Cartouches: 10 + Calibre: 7.62x51 mm NATO (M993 AP)<br />Balas: 10 Калибр: 7,62x51 мм NATO (M993 бронебойные)<br />Патронов: 10 - Kaliber: 7,62x51mm NATO (M993 AP)<br />Patronen: 10 + Kaliber: 7,62x51 mm NATO (M993 AP)<br />Patronen: 10 Calibro: 7.62x51 mm NATO (M993 AP)<br />Munizioni: 10 - Ráže: 7.62x51mm NATO (M993 AP)<br />Nábojů: 10 - Calibre: 7.26x51mm NATO (M993 AP)<br/>Cartuchos: 10 - Kaliber: 7,62x51mm NATO (M993 páncéltörő)<br />Lövedékek: 10 - 口径: 7.62x51mm NATO (Mk319 Mod 0)<br />装填数: 10 - 구경: 7.62x51mm NATO (M993 철갑탄)<br />장탄수: 10 - 口徑: 7.62x51mm NATO標準 (M993 穿甲專用彈)<br />發數: 10 - 口径: 7.62x51mm NATO标准 (M993 穿甲专用弹)<br />发数: 10 + Ráže: 7.62x51 mm NATO (M993 AP)<br />Nábojů: 10 + Calibre: 7.26x51 mm NATO (M993 AP)<br/>Cartuchos: 10 + Kaliber: 7,62x51 mm NATO (M993 páncéltörő)<br />Lövedékek: 10 + 口径: 7.62x51 mm NATO (Mk319 Mod 0)<br />装填数: 10 + 구경: 7.62x51mm NATO (M993 철갑탄)<br/>장탄수: 10 + 口徑: 7.62x51毫米 NATO標準 (M993 穿甲專用彈)<br />發數: 10 + 口径:7.62x51 mm 北约(M993 穿甲)<br />发数:10 + Kalibre: 7.62x51 mm NATO (M993 AP)<br />Mermi: 10 - 7.62mm 20Rnd Mag (M993 AP) - Magazynek 7,62mm 20rd (M993 AP) - Ch. 7,62mm 20Cps (M993 AP) - Cargador de 20 balas de 7.62mm (M993 AP) + 7.62 mm 20Rnd Mag (M993 AP) + Magazynek 7,62 mm 20rd (M993 AP) + Ch. 7,62 mm 20Cps (M993 AP) + Cargador de 20 balas de 7.62 mm (M993 AP) Магазин из 20-ти 7,62 мм (M993 бронебойные) - 7,62mm 20-Patronen-Magazin (M993 AP) - 7.62mm 20Rnd Mag (M993 AP) - 7.62mm 20náb. Zásobník (M993 AP) - Carregador 7.62mm com 20 cartuchos (M993 AP) - 7,62mm 20-lövedékes tár (M993 páncéltörő) - 7.62mm 20発入り 弾倉 (M993 徹甲弾) - 20발들이 7.62mm 탄창 (M993 철갑탄) - 7.62mm 20發 彈匣 (M993 穿甲專用彈) - 7.62mm 20发 弹匣 (M993 穿甲专用弹) + 7,62 mm 20-Patronen-Magazin (M993 AP) + 7.62 mm 20cp Car (M993 AP) + 7.62 mm 20náb. Zásobník (M993 AP) + Carregador 7.62 mm com 20 cartuchos (M993 AP) + 7,62 mm 20-lövedékes tár (M993 páncéltörő) + 7.62mm 20Rnd マガジン (M993 徹甲弾) + 20발 들이 7.62mm 탄창 (M993 철갑탄) + 7.62毫米 20發 彈匣 (M993 穿甲專用彈) + 7.62 mm 20发 弹匣(M993 穿甲) + 7.62 mm 20Rnd Mag (M993 AP) - 7.62mm AP - 7,62mm AP - 7,62mm AP - 7.62mm AP + 7.62 mm AP + 7,62 mm AP + 7,62 mm AP + 7.62 mm AP 7,62 мм бронебойные - 7,62mm AP - 7.62mm AP - 7.62mm AP - 7.62mm AP - 7,62mm páncéltörő - 7.62mm 徹甲弾 + 7,62 mm AP + 7.62 mm AP + 7.62 mm AP + 7.62 mm AP + 7,62 mm páncéltörő + 7.62 mm AP 7.62mm 철갑탄 - 7.62mm M993 穿甲專用彈 - 7.62mm M993 穿甲专用弹 + 7.62毫米 M993 穿甲專用彈 + 7.62 mm M993 + 7.62 mm AP - Caliber: 7.62x51mm NATO (M993 AP)<br />Rounds: 20 - Kaliber: 7,62x51mm NATO (M993 AP)<br />Pociski: 20 - Calibre: 7,62x51mm NATO (M993 AP)<br />Cartouches: 20 + Caliber: 7.62x51 mm NATO (M993 AP)<br />Rounds: 20 + Kaliber: 7,62x51 mm NATO (M993 AP)<br />Pociski: 20 + Calibre: 7,62x51 mm NATO (M993 AP)<br />Cartouches: 20 Калибр: 7,62x51 мм NATO (M993 бронебойные)<br />Патронов: 20 - Kaliber: 7,62x51mm NATO (M993 AP)<br />Patronen: 20 + Kaliber: 7,62x51 mm NATO (M993 AP)<br />Patronen: 20 Calibro: 7.62x51 mm NATO (M993 AP)<br />Munizioni: 20 Calibre: 7.62x51 mm NATO (M993 AP)<br />Balas: 20 - Ráže: 7.62x51mm NATO (M993 AP)<br />Nábojů: 20 - Calibre: 7.26x51mm NATO (M993 AP)<br/>Cartuchos: 20 - Kaliber: 7,62x51mm NATO (M993 páncéltörő)<br />Lövedékek: 20 - 口径: 7.62x51mm NATO (M993 徹甲弾)<br />装填数: 20 - 구경: 7.62x51mm NATO (M993 철갑탄)<br />장탄수: 20 - 口徑: 7.62x51mm NATO標準 (M993 穿甲專用彈)<br />發數: 20 - 口径: 7.62x51mm NATO标准 (M993 穿甲专用弹)<br />发数: 20 + Ráže: 7.62x51 mm NATO (M993 AP)<br />Nábojů: 20 + Calibre: 7.26x51 mm NATO (M993 AP)<br/>Cartuchos: 20 + Kaliber: 7,62x51 mm NATO (M993 páncéltörő)<br />Lövedékek: 20 + 口径: 7.62x51 mm NATO (M993 徹甲弾)<br />装填数: 20 + 구경: 7.62x51mm NATO (M993 철갑탄)<br/>장탄수: 20 + 口徑: 7.62x51毫米 NATO標準 (M993 穿甲專用彈)<br />發數: 20 + 口径:7.62x51 mm 北约(M993 穿甲)<br />发数:20 + Kalibre: 7.62x51 mm NATO (M993 AP)<br />Mermi: 20 - 7.62mm 20Rnd Mag (Mk248 Mod 0) - Magazynek 7,62mm 20rd (Mk248 Mod 0) - Ch. 7,62mm 20Cps (Mk248 Mod 0) - Cargador de 20 balas de 7.62mm (Mk248 Mod 0) - Магазин из 20-ти 7,62 мм (Mk248 Mod 0) - 7,62mm 20-Patronen-Magazin (Mk248 Mod 0) - 7.62mm 20Rnd Mag (Mk248 Mod 0) - 7.62mm 20náb. Zásobník (Mk248 Mod 0) - Carregador 7.62mm com 20 cartuchos (Mk248 Mod 0) - 7,62mm 20-lövedékes tár (Mk248 Mod 0) - 7.62mm 20発入り 弾倉 (Mk248 Mod 0) - 20발들이 7.62mm 탄창 (Mk248 Mod 0) - 7.62mm 20發 彈匣 (Mk248 Mod 0 狙擊專用彈) - 7.62mm 20发 弹匣 (Mk248 Mod 0 狙击专用弹) + .300 WM 20Rnd Mag (Mk248 Mod 0) + Magazynek .300 WM 20rd (Mk248 Mod 0) + Ch. .300 WM 20Cps (Mk248 Mod 0) + Cargador de 20 balas de .300 WM (Mk248 Mod 0) + Магазин из 20-ти .300 WM (Mk248 Mod 0) + .300 WM 20-Patronen-Magazin (Mk248 Mod 0) + .300 WM 20cp Car (Mk248 Mod 0) + .300 WM 20náb. Zásobník (Mk248 Mod 0) + Carregador .300 WM com 20 cartuchos (Mk248 Mod 0) + .300 WM 20-lövedékes tár (Mk248 Mod 0) + .300 WM 20Rnd マガジン (Mk248 Mod 0) + 20발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 0) + .300 萬能(WM) 20發 彈匣 (Mk248 Mod 0 狙擊專用彈) + .300 WM 20发 弹匣(Mk248 Mod 0) + .300 WM 20Rnd Mag (Mk248 Mod 0) - 7.62mm Mk248 - 7,62mm Mk248 - 7,62mm Mk248 - 7.62mm Mk248 - 7,62 мм Mk248 - 7,62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 - 7,62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 狙擊專用彈 - 7.62mm Mk248 狙击专用弹 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300구경 윈체스터 매그넘 Mk.248 + .300 西米 Mk248 狙擊專用彈 + .300 WM Mk248 + .300 WM Mk248 - Caliber: 7.62x67mm NATO (Mk248 Mod 0)<br />Rounds: 20 - Kaliber: 7,62x67mm NATO (Mk248 Mod 0)<br />Pociski: 20 - Calibre: 7,62x67mm NATO (Mk248 Mod 0)<br />Cartouches: 20 - Calibre: 7.62x67mm NATO (Mk248 Mod 0)<br />Balas: 20 - Калибр: 7,62x67 мм NATO (Mk248 Mod 0)<br />Патронов: 20 - Kaliber: 7,62x51mm NATO (Mk248 Mod 0)<br />Patronen: 20 - Calibro: 7.62x67 mm NATO (Mk248 Mod 0)<br />Munizioni: 20 - Ráže: 7.62x67mm NATO (Mk248 Mod 0)<br />Nábojů: 20 - Calibre: 7.26x67mm NATO (Mk248 Mod 0)<br/>Cartuchos: 20 - Kaliber: 7,62x51mm NATO (Mk248 Mod 0)<br />Lövedékek: 20 - 口径: 7.62x67mm NATO (Mk248 Mod 0)<br />装填数: 20 - 구경: 7.62x51mm NATO (Mk248 Mod 0)<br />장탄수: 20 - 口徑: 7.62x67mm NATO標準 (Mk248 Mod 0 狙擊專用彈)<br />發數: 20 - 口径: 7.62x67mm NATO标准 (Mk248 Mod 0 狙击专用弹)<br />发数: 20 + Caliber: .300 WM NATO (Mk248 Mod 0)<br />Rounds: 20 + Kaliber: .300 WM NATO (Mk248 Mod 0)<br />Pociski: 20 + Calibre: .300 WM NATO (Mk248 Mod 0)<br />Cartouches: 20 + Calibre: .300 WM NATO (Mk248 Mod 0)<br />Balas: 20 + Калибр: .300 WM NATO (Mk248 Mod 0)<br />Патронов: 20 + Kaliber: .300 WM NATO (Mk248 Mod 0)<br />Patronen: 20 + Calibro: .300 WM NATO (Mk248 Mod 0)<br />Munizioni: 20 + Ráže: .300 WM (Mk248 Mod 0)<br />Nábojů: 20 + Calibre: .300 WM NATO (Mk248 Mod 0)<br/>Cartuchos: 20 + Kaliber: .300 WM NATO (Mk248 Mod 0)<br />Lövedékek: 20 + 口径: .300 WM NATO (Mk248 Mod 0)<br />装填数: 20 + 구경: .300 윈체스터 매그넘 (Mk.248 Mod 0)<br/>장탄수: 20 + 口徑: .300 西米 NATO標準 (Mk248 Mod 0 狙擊專用彈)<br />發數: 20 + 口径:.300 WM 北约(Mk248 Mod 0 狙击专用弹)<br />发数:20 + Kalibre: .300 WM NATO (Mk248 Mod 0)<br />Mermi: 20 - 7.62mm 20Rnd Mag (Mk248 Mod 1) - Magazynek 7,62mm 20rd (Mk248 Mod 1) - Ch. 7,62mm 20Cps (Mk248 Mod 1) - Cargador de 20 balas de 7.62mm (Mk248 Mod 1) - Магазин из 20-ти 7,62 мм (Mk248 Mod 1) - 7,62mm 20-Patronen-Magazin (Mk248 Mod 1) - 7.62mm 20Rnd Mag (Mk248 Mod 1) - 7.62mm 20náb. Zásobník (Mk248 Mod 1) - Carregador 7.62mm com 20 cartuchos (Mk248 Mod 1) - 7,62mm 20-lövedékes tár (Mk248 Mod 1) - 7.62mm 20発入り 弾倉 (Mk248 Mod 1) - 20발들이 7.62mm 탄창 (Mk248 Mod 1) - 7.62mm 20發 彈匣 (Mk248 Mod 1 狙擊專用彈) - 7.62mm 20发 弹匣 (Mk248 Mod 1 狙击专用弹) + .300 WM 20Rnd Mag (Mk248 Mod 1) + Magazynek .300 WM 20rd (Mk248 Mod 1) + Ch. .300 WM 20Cps (Mk248 Mod 1) + Cargador de 20 balas de .300 WM (Mk248 Mod 1) + Магазин из 20-ти .300 WM (Mk248 Mod 1) + .300 WM 20-Patronen-Magazin (Mk248 Mod 1) + .300 WM 20cp Car (Mk248 Mod 1) + .300 WM 20náb. Zásobník (Mk248 Mod 1) + Carregador .300 WM com 20 cartuchos (Mk248 Mod 1) + .300 WM 20-lövedékes tár (Mk248 Mod 1) + .300 WM 20Rnd マガジン (Mk248 Mod 1) + 20발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 1) + .300 西米 20發 彈匣 (Mk248 Mod 1 狙擊專用彈) + .300 WM 20发 弹匣(Mk248 Mod 1) + .300 WM 20Rnd Mag (Mk248 Mod 1) - 7.62mm Mk248 - 7,62mm Mk248 - 7,62mm Mk248 - 7.62mm Mk248 - 7,62 мм Mk248 - 7,62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 - 7,62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 - 7.62mm Mk248 狙擊專用彈 - 7.62mm Mk248 狙击专用弹 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300구경 윈체스터 매그넘 Mk.248 + .300 西米 Mk248 狙擊專用彈 + .300 WM Mk248 + .300 WM Mk248 - Caliber: 7.62x67mm NATO (Mk248 Mod 1)<br />Rounds: 20 - Kaliber: 7,62x67mm NATO (Mk248 Mod 1)<br />Pociski: 20 - Calibre: 7,62x67mm NATO (Mk248 Mod 1)<br />Cartouches: 20 - Calibre: 7.62x67mm NATO (Mk248 Mod 1)<br />Balas: 20 - Калибр: 7,62x67 мм NATO (Mk248 Mod 1)<br />Патронов: 20 - Kaliber: 7,62x51mm NATO (Mk248 Mod 1)<br />Patronen: 20 - Calibro: 7.62x67 mm NATO (Mk248 Mod 1)<br />Munizioni: 20 - Ráže: 7.62x67mm NATO (Mk248 Mod 1)<br />Nábojů: 20 - Calibre: 7.26x67mm NATO (Mk248 Mod 1)<br/>Cartuchos: 20 - Kaliber: 7,62x51mm NATO (Mk248 Mod 1)<br />Lövedékek: 20 - 口径: 7.62x67mm NATO (Mk248 Mod 1)<br />装填数: 20 - 구경: 7.62x51mm NATO (Mk248 Mod 1)<br />장탄수: 20 - 口徑: 7.62x67mm NATO標準 (Mk248 Mod 1 狙擊專用彈)<br />發數: 20 - 口径: 7.62x67mm NATO标准 (Mk248 Mod 1 狙击专用弹)<br />发数: 20 + Caliber: .300 WM NATO (Mk248 Mod 1)<br />Rounds: 20 + Kaliber: .300 WM NATO (Mk248 Mod 1)<br />Pociski: 20 + Calibre: .300 WM NATO (Mk248 Mod 1)<br />Cartouches: 20 + Calibre: .300 WM NATO (Mk248 Mod 1)<br />Balas: 20 + Калибр: .300 WM NATO (Mk248 Mod 1)<br />Патронов: 20 + Kaliber: .300 WM NATO (Mk248 Mod 1)<br />Patronen: 20 + Calibro: .300 WM NATO (Mk248 Mod 1)<br />Munizioni: 20 + Ráže: .300 WM NATO (Mk248 Mod 1)<br />Nábojů: 20 + Calibre: .300 WM NATO (Mk248 Mod 1)<br/>Cartuchos: 20 + Kaliber: .300 WM NATO (Mk248 Mod 1)<br />Lövedékek: 20 + 口径: .300 WM NATO (Mk248 Mod 1)<br />装填数: 20 + 구경: .300구경 윈체스터 매그넘 (Mk.248 Mod 1)<br/>장탄수: 20 + 口徑: .300 西米 NATO標準 (Mk248 Mod 1 狙擊專用彈)<br />發數: 20 + 口径:.300 WM 北约(Mk248 Mod 1 狙击专用弹)<br />发数:20 + Kalibre: .300 WM NATO (Mk248 Mod 1)<br />Mermi: 20 - 7.62mm 20Rnd Mag (Berger Hybrid OTM) - Magazynek 7,62mm 20rd (Berger Hybrid OTM) - Ch. 7,62 20Cps (Berger Hybrid OTM) - Cargador de 20 balas de 7.62mm (Berger Hybrid OTM) - Магазин из 20-ти 7,62 мм (Berger Hybrid OTM) - 7,62mm 20-Patronen-Magazin (Berger Hybrid OTM) - 7.62mm 20Rnd Mag (Berger Hybrid OTM) - 7.62mm 20náb. Zásobník (Berger Hybrid OTM) - Carregador 7.62mm com 20 cartuchos (Berger Hybrid OTM) - 7,62mm 20-lövedékes tár (Berger Hybrid OTM) - 7.62mm 20発入り 弾倉 (Berger Hybrid OTM) - 20발들이 7.62mm 탄창 (Berger Hybrid OTM) - 7.62mm 20發 彈匣 (Berger Hybrid 空尖比賽專用彈) - 7.62mm 20发 弹匣 (Berger Hybrid 空尖比赛专用弹) + .300 WM 20Rnd Mag (Berger Hybrid OTM) + Magazynek .300 WM 20rd (Berger Hybrid OTM) + Ch. .300 WM 20Cps (Berger Hybrid OTM) + Cargador de 20 balas de .300 WM (Berger Hybrid OTM) + Магазин из 20-ти .300 WM (Berger Hybrid OTM) + .300 WM 20-Patronen-Magazin (Berger Hybrid OTM) + .300 WM 20cp Car (Berger Hybrid OTM) + .300 WM 20náb. Zásobník (Berger Hybrid OTM) + Carregador .300 WM com 20 cartuchos (Berger Hybrid OTM) + .300 WM 20-lövedékes tár (Berger Hybrid OTM) + .300 WM 20Rnd マガジン (Berger Hybrid OTM) + 20발 들이 .300구경 윈체스터 매그넘 탄창 (Berger Hybrid OTM) + .300 西米 20發 彈匣 (Berger Hybrid 空尖比賽專用彈) + .300 WM 20发 弹匣(Berger Hybrid 空尖) + .300 WM 20Rnd Mag (Berger Hybrid OTM) - 7.62mm OTM - 7,62mm OTM - 7,62mm OTM - 7.62mm OTM - 7,62 мм OTM - 7,62mm OTM - 7.62mm OTM - 7.62mm OTM - 7.62mm OTM - 7,62mm OTM - 7.62mm OTM - 7.62mm OTM - 7.62mm 空尖比賽專用彈 - 7.62mm 空尖比赛专用弹 + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300구경 윈체스터 매그넘 OTM + .300 西米 空尖比賽專用彈 + .300 WM 空尖 + .300 WM OTM - Caliber: 7.62x67mm NATO (Berger Hybrid OTM)<br />Rounds: 20 - Kaliber: 7,62x67mm NATO (Berger Hybrid OTM)<br />Pociski: 20 - Calibre: 7,62x67mm NATO (Berger Hybrid OTM)<br />Cartouches: 20 - Calibre: 7.62x67mm NATO (Berger Hybrid OTM)<br />Balas: 20 - Калибр: 7,62x67 мм NATO (Berger Hybrid OTM)<br />Патронов: 20 - Kaliber: 7,62x67mm NATO (Berger Hybrid OTM)<br />Patronen: 20 - Calibro: 7.62x67 mm NATO (Berger Hybrid OTM)<br />Munizioni: 20 - Ráže: 7.62x67mm NATO (Berger Hybrid OTM)<br />Nábojů: 20 - Calibre: 7.26x67mm NATO (Berger Hybrid OTM)<br/>Cartuchos: 20 - Kaliber: 7,62x67mm NATO (Berger Hybrid OTM)<br />Lövedékek: 20 - 口径: 7.62x67mm NATO (Berger Hybrid OTM)<br />装填数: 20 - 구경: 7.62x51mm NATO (Berger Hybrid OTM)<br />장탄수: 20 - 口徑: 7.62x67mm NATO標準 (Berger Hybrid 空尖比賽專用彈)<br />發數: 20 - 口径: 7.62x67mm NATO标准 (Berger Hybrid 空尖比赛专用弹)<br />发数: 20 + Caliber: .300 WM NATO (Berger Hybrid OTM)<br />Rounds: 20 + Kaliber: .300 WM NATO (Berger Hybrid OTM)<br />Pociski: 20 + Calibre: .300 WM NATO (Berger Hybrid OTM)<br />Cartouches: 20 + Calibre: .300 WM NATO (Berger Hybrid OTM)<br />Balas: 20 + Калибр: .300 WM NATO (Berger Hybrid OTM)<br />Патронов: 20 + Kaliber: .300 WM NATO (Berger Hybrid OTM)<br />Patronen: 20 + Calibro: .300 WM NATO (Berger Hybrid OTM)<br />Munizioni: 20 + Ráže: .300 WM NATO (Berger Hybrid OTM)<br />Nábojů: 20 + Calibre: .300 WM OTM NATO (Berger Hybrid OTM)<br/>Cartuchos: 20 + Kaliber: .300 WM NATO (Berger Hybrid OTM)<br />Lövedékek: 20 + 口径: .300 WM NATO (Berger Hybrid OTM)<br />装填数: 20 + 구경: .300구경 윈체스터 매그넘 (Berger Hybrid OTM)<br/>장탄수: 20 + 口徑: .300 西米 NATO標準 (Berger Hybrid 空尖比賽專用彈)<br />發數: 20 + 口径:.300 WM 北约(Berger Hybrid 空尖)<br />发数:20 + Kalibre: .300 WM NATO (Berger Hybrid OTM)<br />Mermi: 20 + + + .300 WM 10Rnd Mag (Mk248 Mod 0) + Magazynek .300 WM 10rd (Mk248 Mod 0) + Ch. .300 WM 10Cps (Mk248 Mod 0) + Cargador de 10 balas de .300 WM (Mk248 Mod 0) + Магазин из 10-ти .300 WM (Mk248 Mod 0) + .300 WM 10-Patronen-Magazin (Mk248 Mod 0) + .300 WM 10cp Car (Mk248 Mod 0) + .300 WM 10náb. Zásobník (Mk248 Mod 0) + Carregador .300 WM com 10 cartuchos (Mk248 Mod 0) + .300 WM 10-lövedékes tár (Mk248 Mod 0) + .300 WM 10Rnd マガジン (Mk248 Mod 0) + 10발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 0) + .300 萬能(WM) 10發 彈匣 (Mk248 Mod 0 狙擊專用彈) + .300 WM 10发 弹匣(Mk248 Mod 0) + .300 WM 10Rnd Mag (Mk248 Mod 0) + + + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300구경 윈체스터 매그넘 Mk.248 + .300 西米 Mk248 狙擊專用彈 + .300 WM Mk248 + .300 WM Mk248 + + + Caliber: .300 WM NATO (Mk248 Mod 0)<br />Rounds: 10 + Kaliber: .300 WM NATO (Mk248 Mod 0)<br />Pociski: 10 + Calibre: .300 WM NATO (Mk248 Mod 0)<br />Cartouches: 10 + Calibre: .300 WM NATO (Mk248 Mod 0)<br />Balas: 10 + Калибр: .300 WM NATO (Mk248 Mod 0)<br />Патронов: 10 + Kaliber: .300 WM NATO (Mk248 Mod 0)<br />Patronen: 10 + Calibro: .300 WM NATO (Mk248 Mod 0)<br />Munizioni: 10 + Ráže: .300 WM (Mk248 Mod 0)<br />Nábojů: 10 + Calibre: .300 WM NATO (Mk248 Mod 0)<br/>Cartuchos: 10 + Kaliber: .300 WM NATO (Mk248 Mod 0)<br />Lövedékek: 10 + 口径: .300 WM NATO (Mk248 Mod 0)<br />装填数: 10 + 구경: .300구경 윈체스터 매그넘 (Mk.248 Mod 0)<br/>장탄수: 10 + 口徑: .300 西米 NATO標準 (Mk248 Mod 0 狙擊專用彈)<br />發數: 10 + 口径:.300 WM 北约(Mk248 Mod 0 狙击专用弹)<br />发数:10 + Kalibre: .300 WM NATO (Mk248 Mod 0)<br />Mermi: 10 + + + .300 WM 10Rnd Mag (Mk248 Mod 1) + Magazynek .300 WM 10rd (Mk248 Mod 1) + Ch. .300 WM 10Cps (Mk248 Mod 1) + Cargador de 10 balas de .300 WM (Mk248 Mod 1) + Магазин из 10-ти .300 WM (Mk248 Mod 1) + .300 WM 10-Patronen-Magazin (Mk248 Mod 1) + .300 WM 10cp Car (Mk248 Mod 1) + .300 WM 10náb. Zásobník (Mk248 Mod 1) + Carregador .300 WM com 10 cartuchos (Mk248 Mod 1) + .300 WM 10-lövedékes tár (Mk248 Mod 1) + .300 WM 10Rnd マガジン (Mk248 Mod 1) + 10발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 1) + .300 西米 10發 彈匣 (Mk248 Mod 1 狙擊專用彈) + .300 WM 10发 弹匣(Mk248 Mod 1) + .300 WM 10Rnd Mag (Mk248 Mod 1) + + + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300 WM Mk248 + .300구경 윈체스터 매그넘 Mk.248 + .300 西米 Mk248 狙擊專用彈 + .300 WM Mk248 + .300 WM Mk248 + + + Caliber: .300 WM NATO (Mk248 Mod 1)<br />Rounds: 10 + Kaliber: .300 WM NATO (Mk248 Mod 1)<br />Pociski: 10 + Calibre: .300 WM NATO (Mk248 Mod 1)<br />Cartouches: 10 + Calibre: .300 WM NATO (Mk248 Mod 1)<br />Balas: 10 + Калибр: .300 WM NATO (Mk248 Mod 1)<br />Патронов: 10 + Kaliber: .300 WM NATO (Mk248 Mod 1)<br />Patronen: 10 + Calibro: .300 WM NATO (Mk248 Mod 1)<br />Munizioni: 10 + Ráže: .300 WM NATO (Mk248 Mod 1)<br />Nábojů: 10 + Calibre: .300 WM NATO (Mk248 Mod 1)<br/>Cartuchos: 10 + Kaliber: .300 WM NATO (Mk248 Mod 1)<br />Lövedékek: 10 + 口径: .300 WM NATO (Mk248 Mod 1)<br />装填数: 10 + 구경: .300구경 윈체스터 매그넘 (Mk.248 Mod 1)<br/>장탄수: 10 + 口徑: .300 西米 NATO標準 (Mk248 Mod 1 狙擊專用彈)<br />發數: 10 + 口径:.300 WM 北约(Mk248 Mod 1 狙击专用弹)<br />发数:10 + Kalibre: .300 WM NATO (Mk248 Mod 1)<br />Mermi: 10 + + + .300 WM 10Rnd Mag (Berger Hybrid OTM) + Magazynek .300 WM 10rd (Berger Hybrid OTM) + Ch. .300 WM 10Cps (Berger Hybrid OTM) + Cargador de 10 balas de .300 WM (Berger Hybrid OTM) + Магазин из 10-ти .300 WM (Berger Hybrid OTM) + .300 WM 10-Patronen-Magazin (Berger Hybrid OTM) + .300 WM 10cp Car (Berger Hybrid OTM) + .300 WM 10náb. Zásobník (Berger Hybrid OTM) + Carregador .300 WM com 10 cartuchos (Berger Hybrid OTM) + .300 WM 10-lövedékes tár (Berger Hybrid OTM) + .300 WM 10Rnd マガジン (Berger Hybrid OTM) + 10발 들이 .300구경 윈체스터 매그넘 탄창 (Berger Hybrid OTM) + .300 西米 10發 彈匣 (Berger Hybrid 空尖比賽專用彈) + .300 WM 10发 弹匣(Berger Hybrid 空尖) + .300 WM 10Rnd Mag (Berger Hybrid OTM) + + + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300 WM OTM + .300구경 윈체스터 매그넘 OTM + .300 西米 空尖比賽專用彈 + .300 WM 空尖 + .300 WM OTM + + + Caliber: .300 WM NATO (Berger Hybrid OTM)<br />Rounds: 10 + Kaliber: .300 WM NATO (Berger Hybrid OTM)<br />Pociski: 10 + Calibre: .300 WM NATO (Berger Hybrid OTM)<br />Cartouches: 10 + Calibre: .300 WM NATO (Berger Hybrid OTM)<br />Balas: 10 + Калибр: .300 WM NATO (Berger Hybrid OTM)<br />Патронов: 10 + Kaliber: .300 WM NATO (Berger Hybrid OTM)<br />Patronen: 10 + Calibro: .300 WM NATO (Berger Hybrid OTM)<br />Munizioni: 10 + Ráže: .300 WM NATO (Berger Hybrid OTM)<br />Nábojů: 10 + Calibre: .300 WM OTM NATO (Berger Hybrid OTM)<br/>Cartuchos: 10 + Kaliber: .300 WM NATO (Berger Hybrid OTM)<br />Lövedékek: 10 + 口径: .300 WM NATO (Berger Hybrid OTM)<br />装填数: 10 + 구경: .300구경 윈체스터 매그넘 (Berger Hybrid OTM)<br/>장탄수: 10 + 口徑: .300 西米 NATO標準 (Berger Hybrid 空尖比賽專用彈)<br />發數: 10 + 口径:.300 WM 北约(Berger Hybrid 空尖)<br />发数:10 + Kalibre: .300 WM NATO (Berger Hybrid OTM)<br />Mermi: 10 - 6.5x47mm 30Rnd Mag (HPBT Scenar) - Ch. 6,5x47mm 30Cps (HPBT Scenar) - Cargador de 30 balas de 6.5x47mm (HPBT Scenar) - Magazynek 6,5x47mm 30rd (HPBT Scenar) - Магазин из 30-ти 6,5x47 мм (экспансивные Scenar) - 6,5x47mm 30-Patronen-Magazin (HPBT Scenar) - 6.5x47mm 30Rnd Mag (HPBT Scenar) - 6.5x47mm 30náb. Zásobník (HPBT Scenar) - Carregador 6.5x47mm com 30 cartuchos (HPBT Scenar) - 6,5x47mm 30-lövedékes tár (HPBT Scenar) - 6.5x47mm 30発入り 弾倉 (HPBT Scenar) - 30발들이 6.5x47mm 탄창 (HPBT Scenar) - 6.5x47mm 30發 彈匣 (Lapua 空尖艇尾狙擊專用彈) - 6.5x47mm 30发 弹匣 (Lapua 空尖艇尾狙击专用弹) + 6.5x47 mm 30Rnd Sand Mag (HPBT Scenar) + 6.5x47mm 30Rnd(砂色)マガジン (HPBT Scenar) + Ch. 6,5x47 mm 30Cps Sable (HPBT Scenar) + 6.5x47 mm 30-Patronen-Magazin Sandfarben (HPBT Scenar) + 6.5x47 mm 30cp Sabbia (HPBT Scenar) + Magazynek 6.5x47 mm 30rd Piaskowy (HPBT Scenar) + 6.5x47 mm 30发 沙色弹匣(HPBT Scenar) + 6.5x47mm 30발 사막 탄창 (HPBT Scenar) + Магазин из 30-ти 6.5x47 мм Песочный (HPBT Scenar) + Cargador de 30 balas de 6.5x47mm Arena (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Areia (HPBT Scenar) + + + 6.5x47 mm 30Rnd Promet Mag (HPBT Scenar) + 6.5x47 mm 30Rnd Promet マガジン (HPBT Scenar) + Ch. 6,5x47 mm 30Cps Promet (HPBT Scenar) + 6.5x47 mm 30-Patronen-Magazin für Promet (HPBT Scenar) + 6.5x47 mm 30cp Car Promet (HPBT Scenar) + Magazynek 6.5x47 mm 30rd Promet (HPBT Scenar) + 6.5x47 mm 30发 Promet 弹匣(HPBT Scenar) + 6.5x47mm 30발 그롯 탄창 (HPBT Scenar) + Магазин из 30-ти 6.5x47 мм Promet (HPBT Scenar) + Cargador de 30 balas de 6.5x47mm Promet (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Promet (HPBT Scenar) + + + 6.5x47 mm 30Rnd Black Mag (HPBT Scenar) + 6.5x47mm 30Rnd(黒)マガジン (HPBT Scenar) + Ch. 6,5x47 mm 30Cps Noir (HPBT Scenar) + 6.5x47 mm 30-Patronen-Magazin Schwarz (HPBT Scenar) + 6.5x47 mm 30cp Car Nero (HPBT Scenar) + Magazynek 6.5x47 mm 30rd Czarny (HPBT Scenar) + 6.5x47 mm 30发 黑色弹匣(HPBT Scenar) + 6.5x47mm 30발 검정 탄창 (HPBT Scenar) + Магазин из 30-ти 6.5x47 мм Чёрный (HPBT Scenar) + Cargador de 30 balas de 6.5x47mm Negro (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Preto (HPBT Scenar) + + + 6.5x47 mm 30Rnd Khaki Mag (HPBT Scenar) + 6.5x47mm 30Rnd(カーキ)マガジン (HPBT Scenar) + Ch. 6,5x47 mm 30Cps Kaki (HPBT Scenar) + 6.5x47 mm 30-Patronen-Magazin Khaki (HPBT Scenar) + 6.5x47 mm 30cp Car Cachi (HPBT Scenar) + Magazynek 6.5x47 mm 30rd Khaki (HPBT Scenar) + 6.5x47 mm 30发 卡其色弹匣(HPBT Scenar) + 6.5x47mm 30발 카키 탄창 (HPBT Scenar) + Магазин из 30-ти 6.5x47 мм Хаки (HPBT Scenar) + Cargador de 30 balas de 6.5x47mm Caqui (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Caqui (HPBT Scenar) - 6.5mm Lapua - 6,5mm Lapua - 6.5mm Lapua - 6,5mm Lapua + 6.5 mm Lapua + 6,5 mm Lapua + 6.5 mm Lapua + 6,5 mm Lapua 6,5 мм Lapua - 6,5mm Lapua - 6.5mm Lapua - 6.5mm Lapua - 6.5mm Lapua - 6,5mm Lapua - 6.5mm Lapua - 6.5mm Lapua - 6.5mm Lapua 空尖艇尾狙擊專用彈 - 6.5mm Lapua 空尖艇尾狙击专用弹 + 6,5 mm Lapua + 6.5 mm Lapua + 6.5 mm Lapua + 6.5 mm Lapua + 6,5 mm Lapua + 6.5 mm Lapua + 6.5mm 라푸아 + 6.5毫米 拉普 空尖艇尾狙擊專用彈 + 6.5 mm Lapua + 6.5 mm Lapua - Caliber: 6.5x47mm (HPBT Scenar)<br />Rounds: 30<br />Used in: MXM - Calibre: 6,5x47mm (HPBT Scenar)<br />Cartouches: 30 - Calibre: 6.5x47mm (HPBT Scenar)<br />Balas: 30<br />Se usa en: MXM - Kaliber: 6,5x47mm (HPBT Scenar)<br />Pociski: 30 + Caliber: 6.5x47 mm (HPBT Scenar)<br />Rounds: 30<br />Used in: MXM + Calibre: 6,5x47 mm (HPBT Scenar)<br />Cartouches: 30<br />Utilisé avec: MXM + Calibre: 6.5x47 mm (HPBT Scenar)<br />Balas: 30<br />Se usa en: MXM + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Pociski: 30 Калибр: 6,5x47 мм (экспансивные Scenar)<br />Патронов: 30<br />Используются с: MXM - Kaliber: 6,5x47mm (HPBT Scenar)<br />Patronen: 30<br />Eingesetzt von: MXM - Calibro: 6.5x47mm (HPBT Scenar)<br />Munizioni: 30<br />In uso su: MXM - Ráže: 6.5x47mm (HPBT Scenar)<br />Nábojů: 30<br />Použití u: MXM - Calibre: 6.5x47mm (HPBT Scenar)<br/>Cartuchos: 30<br/>Usado em: MXM - Kaliber: 6,5x47mm (HPBT Scenar)<br />Lövedékek: 30<br />Használható: MXM - 口径: 6.5x47mm (HPBT Scenar)<br />装填数: 30<br />次で使用: MXM - 구경: 6.5x47mm (HPBT Scenar)<br />장탄수: 30<br />사용처: MXM - 口徑: 6.5x47mm (Lapua 空尖艇尾狙擊專用彈)<br />發數: 30<br />使用於: MXM - 口径: 6.5x47mm (Lapua 空尖艇尾狙击专用弹)<br />发数: 30<br />使用于: MXM + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Patronen: 30<br />Eingesetzt von: MXM + Calibro: 6.5x47 mm (HPBT Scenar)<br />Munizioni: 30<br />In uso su: MXM + Ráže: 6.5x47 mm (HPBT Scenar)<br />Nábojů: 30<br />Použití u: MXM + Calibre: 6.5x47 mm (HPBT Scenar)<br/>Cartuchos: 30<br/>Usado em: MXM + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Lövedékek: 30<br />Használható: MXM + 口径: 6.5x47 mm (HPBT Scenar)<br />装填数: 30<br />次で使用: MXM + 구경: 6.5x47mm (HPBT Scenar)<br/>장탄수: 30<br/>사용처: MXM + 口徑: 6.5x47毫米 (拉普 空尖艇尾狙擊專用彈)<br />發數: 30<br />使用於: MXM + 口径:6.5x47 mm(HPBT Scenar 狙击专用弹)<br />发数:30<br />使用于:MXM + Kalibre: 6.5x47 mm (HPBT Scenar)<br />Mermi: 30<br />Kullanıyor: MXM + + + Caliber: 6.5x47 mm (HPBT Scenar)<br />Rounds: 30<br />Used in: Promet MR + Calibre: 6,5x47 mm (HPBT Scenar)<br />Cartouches: 30<br />Utilisé avec: Promet MR + Calibre: 6.5x47 mm (HPBT Scenar)<br />Balas: 30<br />Se usa en: Promet MR + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Pociski: 30 + Калибр: 6,5x47 мм (экспансивные Scenar)<br />Патронов: 30<br />Используются с: Promet MR + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Patronen: 30<br />Eingesetzt von: Promet MR + Calibro: 6.5x47 mm (HPBT Scenar)<br />Munizioni: 30<br />In uso su: Promet MR + Ráže: 6.5x47 mm (HPBT Scenar)<br />Nábojů: 30<br />Použití u: Promet MR + Calibre: 6.5x47 mm (HPBT Scenar)<br/>Cartuchos: 30<br/>Usado em: Promet MR + Kaliber: 6,5x47 mm (HPBT Scenar)<br />Lövedékek: 30<br />Használható: Promet MR + 口径: 6.5x47 mm (HPBT Scenar)<br />装填数: 30<br />次で使用: Promet MR + 구경: 6.5x47mm (HPBT Scenar)<br/>장탄수: 30<br/>사용처: MSBS 그롯/GL/MR/SG + 口徑: 6.5x47毫米 (拉普 空尖艇尾狙擊專用彈)<br />發數: 30<br />使用於: Promet MR + 口径:6.5x47 mm(HPBT Scenar 狙击专用弹)<br />发数:30<br />使用于:Promet MR + Kalibre: 6.5x47 mm (HPBT Scenar)<br />Mermi: 30<br />Kullanıyor: Promet MR - 6.5mm Creedmor 30Rnd Mag - Magazynek 6,5mm Creedmor 30rd - 6.5mm Creedmor 30Rnd Mag - Магазин из 30-ти 6,5 мм Creedmor - 6,5mm Creedmor 30-Patronen-Magazin - Cargador de 30 balas Creedmor de 6.5mm - Ch. 6,5mm Creedmor 30Cps - 6.5mm Creedmor 30náb. Zásobník - Carregador 6.5mm com 30 cartuchos Creedmor - 6,5mm Creedmor 30-lövedékes tár - 6.5mm Creedmor 30発入り 弾倉 - 30발들이 6.5mm Creedmor 탄창 - 6.5mm 30發 彈匣 (Creedmor 狙擊專用彈) - 6.5mm 30发 弹匣 (Creedmor 狙击专用弹) + 6.5 mm Creedmor 30Rnd Sand Mag + 6.5mm 30Rnd クリードモア(砂色)マガジン + Ch. 6,5 mm Creedmor 30Cps Sable + 6.5 mm Creedmor 30-Patronen-Magazin Sandfarben + 6.5 mm Creedmor 30cp Car Sabbia + Magazynek 6.5 mm Creedmor 30Rnd Piaskowy + 6.5 mm 30发 沙色弹匣(Creedmor) + 6.5mm 크리드무어 30발 사막 탄창 + Магазин из 30-ти 6.5 мм Creedmor Песочный + Cargador de 30 balas de 6.5mm Creedmor Arena + Carregador 6.5 mm com 30 cartuchos Creedmor Areia + + + 6.5 mm Creedmor 30Rnd Promet Mag + 6.5 mm 30Rnd Promet クリードモア・マガジン + Ch. 6,5 mm Creedmor 30Cps Promet + 6.5 mm Creedmor 30-Patronen-Magazin für Promet + 6.5 mm Creedmor 30cp Car Promet + Magazynek 6.5 mm Creedmor 30Rnd Promet + 6.5 mm 30发 Promet 弹匣(Creedmor) + 6.5mm 크리드무어 30발 프로멧 탄창 + Магазин из 30-ти 6.5 мм Creedmor Promet + Cargador de 30 balas de 6.5mm Creedmor Promet + Carregador 6.5 mm com 30 cartuchos Creedmor Promet + + + 6.5 mm Creedmor 30Rnd Black Mag + 6.5mm 30Rnd クリードモア(黒)マガジン + Ch. 6,5 mm Creedmor 30Cps Noir + 6.5 mm Creedmor 30-Patronen-Magazin Schwarz + 6.5 mm Creedmor 30cp Car Nero + Magazynek 6.5 mm Creedmor 30Rnd Czarny + 6.5 mm 30发 黑色弹匣(Creedmor) + 6.5mm 크리드무어 30발 검정 탄창 + Магазин из 30-ти 6.5 мм Creedmor Чёрный + Cargador de 30 balas de 6.5mm Creedmor Negro + Carregador 6.5 mm com 30 cartuchos Creedmor Preto + + + 6.5 mm Creedmor 30Rnd Khaki Mag + 6.5mm 30Rnd クリードモア(カーキ)マガジン + Ch. 6,5 mm Creedmor 30Cps Kaki + 6.5 mm Creedmor 30-Patronen-Magazin Khaki + 6.5 mm Creedmor 30cp Car Cachi + Magazynek 6.5 mm Creedmor 30Rnd Khaki + 6.5 mm 30发 卡其色弹匣(Creedmor) + 6.5mm 크리드무어 30발 카키 탄창 + Магазин из 30-ти 6.5 мм Creedmor Хаки + Cargador de 30 balas de 6.5mm Creedmor Caqui + Carregador 6.5 mm com 30 cartuchos Creedmor Caqui - 6.5mm CM - 6,5mm CM - 6.5mm CM - 6,5mm CM + 6.5 mm CM + 6,5 mm CM + 6.5 mm CM + 6,5 mm CM 6,5 мм CM - 6,5mm CM - 6.5mm CM - 6.5mm CM - 6.5mm CM - 6,5mm CM - 6.5mm CM - 6.5mm CM - 6.5mm CM 狙擊專用彈 - 6.5mm CM 狙击专用弹 + 6,5 mm CM + 6.5 mm CM + 6.5 mm CM + 6.5 mm CM + 6,5 mm CM + 6.5 mm CM + 6.5mm 크리드무어 + 6.5毫米 CM狙擊專用彈 + 6.5 mm CM + 6.5 mm CM - Caliber: 6.5x47mm Creedmor<br />Rounds: 30<br />Used in: MXM - Kaliber: 6,5x47mm Creedmor<br />Pociski: 30<br />Używany w: MXM - Kaliber: 6,5x47mm Creedmor<br />Patronen: 30<br />Eingesetzt von: MXM - Calibre: 6,5x47mm Creedmor <br />Cartouches: 30<br />Utilisé avec: MXM - Calibro: 6.5mm Creedmor<br />Munizioni: 30<br />In uso su: MXM - Calibre: 6.5mm Creedmor<br />Balas: 30<br />Se usa en: MXM + Caliber: 6.5x47 mm Creedmor<br />Rounds: 30<br />Used in: MXM + Kaliber: 6,5x47 mm Creedmor<br />Pociski: 30<br />Używany w: MXM + Kaliber: 6,5x47 mm Creedmor<br />Patronen: 30<br />Eingesetzt von: MXM + Calibre: 6,5x47 mm Creedmor <br />Cartouches: 30<br />Utilisé avec: MXM + Calibro: 6.5 mm Creedmor<br />Munizioni: 30<br />In uso su: MXM + Calibre: 6.5 mm Creedmor<br />Balas: 30<br />Se usa en: MXM Калибр: 6,5x47мм Creedmor<br />Патронов: 30<br />Используются c: MXM - Ráže: 6.5x47mm Creedmor<br />Nábojů: 30<br />Použití u: MXM - Calibre: 6.5x47mm Creedmor<br/>Cartuchos: 30<br/>Usado em: MXM - Kaliber: 6,5x47mm Creedmor<br />Lövedékek: 30<br />Használható: MXM - 口径: 6.5x47mm Creedmor<br />装填数: 30<br />次で使用: MXM - 구경: 6.5x47mm Creedmor<br />장탄수: 30<br />사용처: MXM - 口徑: 6.5x47mm Creedmor 狙擊專用彈<br />發數: 30<br />使用於: MXM - 口径: 6.5x47mm Creedmor 狙击专用弹<br />发数: 30<br />使用于: MXM + Ráže: 6.5x47 mm Creedmor<br />Nábojů: 30<br />Použití u: MXM + Calibre: 6.5x47 mm Creedmor<br/>Cartuchos: 30<br/>Usado em: MXM + Kaliber: 6,5x47 mm Creedmor<br />Lövedékek: 30<br />Használható: MXM + 口径: 6.5x47 mm クリードモア<br />装填数: 30<br />次で使用: MXM + 구경: 6.5x47mm 크리드무어<br/>장탄수: 30<br/>사용처: MXM + 口徑: 6.5x47毫米 克里德莫爾 狙擊專用彈<br />發數: 30<br />使用於: MXM + 口径:6.5x47 mm Creedmor 狙击专用弹<br />发数:30<br />使用于:MXM + Kalibre: 6.5x47 mm Creedmor<br />Mermi: 30<br />Kullanıyor: MXM + + + Caliber: 6.5x47 mm Creedmor<br />Rounds: 30<br />Used in: Promet MR + Kaliber: 6,5x47 mm Creedmor<br />Pociski: 30<br />Używany w: Promet MR + Kaliber: 6,5x47 mm Creedmor<br />Patronen: 30<br />Eingesetzt von: Promet MR + Calibre: 6,5x47 mm Creedmor <br />Cartouches: 30<br />Utilisé avec: Promet MR + Calibro: 6.5 mm Creedmor<br />Munizioni: 30<br />In uso su: Promet MR + Calibre: 6.5 mm Creedmor<br />Balas: 30<br />Se usa en: Promet MR + Калибр: 6,5x47мм Creedmor<br />Патронов: 30<br />Используются c: Promet MR + Ráže: 6.5x47 mm Creedmor<br />Nábojů: 30<br />Použití u: Promet MR + Calibre: 6.5x47 mm Creedmor<br/>Cartuchos: 30<br/>Usado em: Promet MR + Kaliber: 6,5x47 mm Creedmor<br />Lövedékek: 30<br />Használható: Promet MR + 口径: 6.5x47 mm クリードモア<br />装填数: 30<br />次で使用: Promet MR + 구경: 6.5x47mm 크리드무어<br/>장탄수: 30<br/>사용처: MSBS 그롯/GL/MR/SG + 口徑: 6.5x47毫米 克里德莫爾 狙擊專用彈<br />發數: 30<br />使用於: Promet MR + 口径:6.5x47 mm Creedmor 狙击专用弹<br />发数:30<br />使用于:Promet MR + Kalibre: 6.5x47 mm Creedmor<br />Mermi: 30<br />Kullanıyor: Promet MR - .338 10Rnd Mag (300gr Lapua Scenar) - Ch. .338 10 Cps (300gr Lapua Scenar) + .338 LM 10Rnd Mag (300gr Lapua Scenar) + Ch. .338 LM 10 Cps (300gr Lapua Scenar) Cargador de 10 balas de 8.6x70mm (300gr Lapua Scenar) - Magazynek .338 10rd (300gr Lapua Scenar) - Магазин из 10-ти .338 (300 гран Lapua Scenar) - .338 10-Patronen-Magazin (300gr Lapua Scenar) - .338 10Munizioni Mag (300gr Lapua Scenar) - .338 10náb. Zásobník (300gr Lapua Scenar) - Carregador .338 (300gr Lapua Scenar) com 10 cartuchos - .338 10-lövedékes tár (300gr Lapua Scenar) - .338 10発入り 弾倉 (300gr Lapua Scenar) - 10발들이 .338 탄창 (300gr Lapua Scenar) + Magazynek .338 LM 10rd (300gr Lapua Scenar) + Магазин из 10-ти .338 LM (300 гран Lapua Scenar) + .338 LM 10-Patronen-Magazin (300gr Lapua Scenar) + .338 LM 10cp Car (300gr Lapua Scenar) + .338 LM 10náb. Zásobník (300gr Lapua Scenar) + Carregador .338 LM (300gr Lapua Scenar) com 10 cartuchos + .338 LM 10-lövedékes tár (300gr Lapua Scenar) + .338 LM 10Rnd マガジン (300gr Lapua Scenar) + 10발 들이 .338구경 라푸아 매그넘 탄창 (300그레인 Scenar) .338 10發 彈匣 (300公克 Lapua Scenar) - .338 10发 弹匣 (300公克 Lapua Scenar) + .338 LM 10发 弹匣(300gr Lapua Scenar) + .338 LM 10Rnd Mag (300gr Lapua Scenar) .338 Scenar @@ -2005,9 +3055,10 @@ .338 Scenar .338 Scenar 338 Scenar - .338 Scenar + .338구경 라푸아 매그넘 Scenar .338 Scenar .338 Scenar + .338 Scenar Caliber: 8.6x70mm (300gr Lapua Scenar)<br />Rounds: 10 @@ -2021,25 +3072,27 @@ Calibre: 8.6x70mm (300gr Lapua Scenar)<br/>Cartuchos: 10 Kaliber: 8,6x70mm (300gr Lapua Scenar)<br />Lövedékek: 10 口径: 8.6x70mm (300gr Lapua Scenar)<br />装填数: 10 - 구경: 8.6x70mm (300gr Lapua Scenar)<br />장탄수: 10 - 口徑: 8.6x70mm (300公克 Lapua Scenar)<br />發數: 10 - 口径: 8.6x70mm (300公克 Lapua Scenar)<br />发数: 10 + 구경: 8.6x70mm 라푸아 매그넘 (300그레인 Scenar)<br/>장탄수: 10 + 口徑: 8.6x70毫米 (300公克 Lapua Scenar)<br />發數: 10 + 口径:8.6x70 mm(300gr Lapua Scenar)<br />发数:10 + Kalibre: 8.6x70mm (300gr Lapua Scenar)<br />Mermi: 10 - .338 10Rnd Mag (API526) - Ch. .338 10Cps (API526) - Cargador de 10 balas de .338 (API526) - Magazynek .338 10rd (API526) - Магазин из 10-ти .338 (API526) - .338 10-Patronen-Magazin (API526) - .338 10Rnd Mag (API526) - .338 10náb. Zásobník (API526) - Carregador .338 (API526) com 10 cartuchos - .338 10-lövedékes tár (API526) - .338 10発入り 弾倉 (API526) - 10발들이 .338 탄창 (API526) + .338 LM 10Rnd Mag (API526) + Ch. .338 LM 10Cps (API526) + Cargador de 10 balas de .338 LM (API526) + Magazynek .338 LM 10rd (API526) + Магазин из 10-ти .338 LM (API526) + .338 LM 10-Patronen-Magazin (API526) + .338 LM 10cp Car (API526) + .338 LM 10náb. Zásobník (API526) + Carregador .338 LM (API526) com 10 cartuchos + .338 LM 10-lövedékes tár (API526) + .338 LM 10Rnd マガジン (API526) + 10발 들이 .338구경 라푸아 매그넘 탄창 (API526) .338 10發 彈匣 (API526 穿甲燃燒彈) - .338 10发 弹匣 (API526 穿甲燃烧弹) + .338 LM 10发 弹匣(API526 穿燃) + .338 LM 10Rnd Mag (API526) .338 AP @@ -2052,10 +3105,11 @@ .338 AP .338 AP .338 páncéltörő - .338 徹甲弾 - .338 철갑탄 + .338 AP + .338구경 라푸아 매그넘 철갑탄 .338 API526 穿甲燃燒彈 - .338 API526 穿甲燃烧弹 + .338 穿燃 + .338 AP Caliber: 8.6x70mm (API526)<br />Rounds: 10 @@ -2069,9 +3123,10 @@ Calibre: 8.6x70mm (API526)<br/>Cartuchos: 10 Kaliber: 8,6x70mm (API526)<br />Lövedékek: 10 口径: 8.6x70mm (API526)<br />装填数: 10 - 구경: 8.6x70mm (API526)<br />장탄수: 10 - 口徑: 8.6x70mm (API526 穿甲燃燒彈)<br />發數: 10 - 口径: 8.6x70mm (API526 穿甲燃烧弹)<br />发数: 10 + 구경: 8.6x70mm 라푸아 매그넘 (API526)<br/>장탄수: 10 + 口徑: 8.6x70毫米 (API526 穿甲燃燒彈)<br />發數: 10 + 口径:8.6x70 mm(API526 穿燃)<br />发数:10 + Kalibre: 8.6x70mm (API526)<br />Mermi: 10 .408 7Rnd Mag (305gr) @@ -2080,14 +3135,15 @@ Magazynek .408 7rd (305gr) Магазин из 7-ти .408 (305gr) .408 7-Patronen-Magazin (305gr) - .408 7Rnd Mag (305gr) + .408 7cp Car (305gr) .408 7náb. Zásobník (305gr) Carregador .408 (305gr) com 7 cartuchos .408 7-lövedékes tár (305gr) - .408 7発入り 弾倉 (305gr) - 7발들이 .408 탄창 (305gr) + .408 7Rnd マガジン (305gr) + 7발 들이 .408구경 샤이택 탄창 (305그레인) .408 7發 彈匣 (305公克) - .408 7发 弹匣 (305公克) + .408 7发 弹匣(305gr) + .408 7Rnd Mag (305gr) .408 @@ -2101,9 +3157,10 @@ .408 .408 .408 - .408 + .408구경 샤이택 .408 .408 + .408 Caliber: .408 CheyTac (305gr)<br />Rounds: 7 @@ -2117,153 +3174,265 @@ Calibre: .408 CheyTac (305gr)<br/>Cartuchos: 7 Kaliber: .408 CheyTac (305gr)<br />Lövedékek: 7 口径: .408 CheyTac (305gr)<br />装填数: 7 - 구경: .408 CheyTac (305gr)<br />장탄수: 7 + 구경: .408구경 샤이택(305그레인)<br/>장탄수: 7 口徑: .408 夏伊戰術狙擊彈 (305公克)<br />發數: 7 - 口径: .408 夏伊战术狙击弹 (305公克)<br />发数: 7 + 口径:.408 夏伊(305gr)<br />发数:7 + Kalibre: .408 CheyTac (305gr)<br />Mermi: 7 - 12.7x99mm 5Rnd Mag - Ch. 12,7x99mm 5Cps - Cargador de 5 balas de 12.7x99mm - Magazynek 12,7x99mm 5rd + 12.7x99 mm 5Rnd Mag + Ch. 12,7x99 mm 5Cps + Cargador de 5 balas de 12.7x99 mm + Magazynek 12,7x99 mm 5rd Магазин из 5-ти 12,7x99 мм - 12,7x99mm 5-Patronen-Magazin - 12.7x99mm 5Rnd Mag - 12.7x99mm 5náb. Zásobník - Carregador 12.7x99mm com 5 cartuchos - 12,7x99mm 5-lövedékes tár - 12.7x99mm 5発入り 弾倉 - 5발들이 12.7x99mm 탄창 - 12.7x99mm 5發 彈匣 - 12.7x99mm 5发 弹匣 - - - 12.7mm - 12,7mm - 12.7mm - 12,7mm - 12,7 мм - 12,7mm - 12.7mm - 12.7mm - 12.7mm - 12,7mm - 12.7mm - 12.7mm - 12.7mm - 12.7mm + 12,7x99 mm 5-Patronen-Magazin + 12.7x99 mm 5cp Car + 12.7x99 mm 5náb. Zásobník + Carregador 12.7x99 mm com 5 cartuchos + 12,7x99 mm 5-lövedékes tár + 12.7x99mm 5Rnd マガジン + 5발 들이 12.7x99mm 탄창 + 12.7x99毫米 5發 彈匣 + 12.7x99 mm 5发 弹匣 + 12.7x99 mm 5Rnd Mag - Caliber: 12.7x99mm<br />Rounds: 5 - Calibre: 12.7x99mm<br />Cartouches: 5 - Calibre: 12.7x99mm<br />Balas: 5 - Kaliber: 12,7x99mm<br />Pociski: 5 + Caliber: 12.7x99 mm<br />Rounds: 5 + Calibre: 12,7x99 mm<br />Cartouches: 5 + Calibre: 12.7x99 mm<br />Balas: 5 + Kaliber: 12,7x99 mm<br />Pociski: 5 Калибр: 12,7x99 мм<br />Патронов: 5 - Kaliber: 12,7x99mm<br />Patronen: 5 - Calibro: 12.7x99mm<br />Munizioni: 5 - Ráže: 12.7x99mm<br />Nábojů: 5 - Calibre: 12.7x99mm<br/>Cartuchos: 5 - Kaliber: 12,7x99mm<br />Lövedékek: 5 - 口径: 12.7x99mm<br />装填数: 5 - 구경: 12.7x99mm<br />장탄수: 5 - 口徑: 12.7x99mm<br />發數: 5 - 口径: 12.7x99mm<br />发数: 5 + Kaliber: 12,7x99 mm<br />Patronen: 5 + Calibro: 12.7x99 mm<br />Munizioni: 5 + Ráže: 12.7x99 mm<br />Nábojů: 5 + Calibre: 12.7x99 mm<br/>Cartuchos: 5 + Kaliber: 12,7x99 mm<br />Lövedékek: 5 + 口径: 12.7x99 mm<br />装填数: 5 + 구경: 12.7x99mm<br/>장탄수: 5 + 口徑: 12.7x99毫米<br />發數: 5 + 口径:12.7x99 mm<br />发数:5 + Kalibre: 12.7x99 mm<br />Mermi: 5 + + + 12.7x99 mm 10Rnd Mag + Ch. 12,7x99 mm 10Cps + Cargador de 10 balas de 12.7x99 mm + Magazynek 12,7x99 mm 10rd + Магазин из 10-ти 12,7x99 мм + 12,7x99 mm 10-Patronen-Magazin + 12.7x99 mm 10cp Car + 12.7x99 mm 10náb. Zásobník + Carregador 12.7x99 mm com 10 cartuchos + 12,7x99 mm 10-lövedékes tár + 12.7x99mm 10Rnd マガジン + 10발 들이 12.7x99mm 탄창 + 12.7x99毫米 10發 彈匣 + 12.7x99 mm 10发 弹匣 + 12.7x99 mm 10Rnd Mag + + + Caliber: 12.7x99 mm<br />Rounds: 10 + Calibre: 12,7x99 mm<br />Cartouches: 10 + Calibre: 12.7x99 mm<br />Balas: 10 + Kaliber: 12,7x99 mm<br />Pociski: 10 + Калибр: 12,7x99 мм<br />Патронов: 10 + Kaliber: 12,7x99 mm<br />Patronen: 10 + Calibro: 12.7x99 mm<br />Munizioni: 10 + Ráže: 12.7x99 mm<br />Nábojů: 10 + Calibre: 12.7x99 mm<br/>Cartuchos: 10 + Kaliber: 12,7x99 mm<br />Lövedékek: 10 + 口径: 12.7x99 mm<br />装填数: 10 + 구경: 12.7x99 mm<br/>장탄수: 10 + 口徑: 12.7x99毫米<br />發數: 10 + 口径:12.7x99 mm<br />发数:10 + Kalibre: 12.7x99 mm<br />Mermi: 10 + + + 12.7 mm + 12,7 mm + 12.7 mm + 12,7 mm + 12,7 мм + 12,7 mm + 12.7 mm + 12.7 mm + 12.7 mm + 12,7 mm + 12.7 mm + 12.7mm + 12.7毫米 + 12.7 mm + 12.7 mm - 12.7x99mm API 5Rnd Mag - Ch. 12,7x99mm API 5Cps - Cargador de 5 balas de 12.7x99mm API - Magazynek 12,7x99mm API 5rd - 12.7x99mm API 5Rnd Mag + 12.7x99 mm API 5Rnd Mag + Ch. 12,7x99 mm API 5Cps + Cargador de 5 balas de 12.7x99 mm API + Magazynek 12,7x99 mm API 5rd + 12.7x99 mm API 5cp Car Магазин из 5-ти 12,7x99 мм (бронебойно-зажигательные) - 12,7x99mm 5-Patronen-Magazin (API) - 12.7x99mm API 5náb. Zásobník - Carregador 12.7x99mm API com 5 cartuchos - 12,7x99mm 5-lövedékes tár (páncéltörő-gyújtó) - 12.7x99mm 5発入り焼夷徹甲弾 弾倉 - 5발들이 12.7x99mm 철갑소이탄 탄창 - 12.7x99mm 穿甲燃燒彈 5發 彈匣 - 12.7x99mm 穿甲燃烧弹 5发 弹匣 - - - 12.7mm API - 12,7mm API - 12.7mm API - 12,7mm API - 12.7mm API - 12.7 мм бронебойно-зажигательные - 12,7mm API - 12.7mm API - 12.7mm API - 12,7mm páncéltörő-gyújtó - 12.7mm 焼夷徹甲弾 - 12.7mm 철갑소이탄 - 12.7mm 穿甲燃燒彈 - 12.7mm 穿甲燃烧弹 + 12,7x99 mm 5-Patronen-Magazin (API) + 12.7x99 mm API 5náb. Zásobník + Carregador 12.7x99 mm API com 5 cartuchos + 12,7x99 mm 5-lövedékes tár (páncéltörő-gyújtó) + 12.7x99mm 5Rnd 焼夷徹甲弾 マガジン + 5발 들이 12.7x99mm 철갑소이탄 탄창 + 12.7x99毫米 穿甲燃燒彈 5發 彈匣 + 12.7x99 mm 穿燃 5发 弹匣 + 12.7x99 mm API 5Rnd Mag - Caliber: 12.7x99mm API<br />Rounds: 5 - Calibre: 12,7x99mm API<br />Cartouches: 5 - Calibre: 12.7x99mm API<br />Balas: 5 - Kaliber: 12,7x99mm API<br />Pociski: 5 + Caliber: 12.7x99 mm API<br />Rounds: 5 + Calibre: 12,7x99 mm API<br />Cartouches: 5 + Calibre: 12.7x99 mm API<br />Balas: 5 + Kaliber: 12,7x99 mm API<br />Pociski: 5 Калибр: 12,7x99 мм бронебойно-зажигательные<br />Патронов: 5 - Kaliber:12,7x99mm API<br />Patronen: 5 - Calibro: 12.7x99mm API<br />Munizioni: 5 - Ráže: 12.7x99mm API<br />Nábojů: 5 - Calibre: 12.7x99mm API<br/>Cartuchos: 5 - Kaliber: 12,7x99mm API<br />Lövedékek: 5 - 口径: 12.7x99mm 焼夷徹甲弾<br />装填数: 5 - 구경: 12.7x99mm 철갑소이탄<br />장탄수: 5 - 口徑: 12.7x99mm 穿甲燃燒彈<br />發數: 5 - 口径: 12.7x99mm 穿甲燃烧弹<br />发数: 5 + Kaliber:12,7x99 mm API<br />Patronen: 5 + Calibro: 12.7x99 mm API<br />Munizioni: 5 + Ráže: 12.7x99 mm API<br />Nábojů: 5 + Calibre: 12.7x99 mm API<br/>Cartuchos: 5 + Kaliber: 12,7x99 mm API<br />Lövedékek: 5 + 口径: 12.7x99 mm 焼夷徹甲弾<br />装填数: 5 + 구경: 12.7x99mm 철갑소이탄<br/>장탄수: 5 + 口徑: 12.7x99毫米 穿甲燃燒彈<br />發數: 5 + 口径:12.7x99 mm 穿燃<br />发数:5 + Kalibre: 12.7x99 mm API<br />Mermi: 5 + + + 12.7x99 mm API 10Rnd Mag + Ch. 12,7x99 mm API 10Cps + Cargador de 10 balas de 12.7x99 mm API + Magazynek 12,7x99 mm API 10rd + 12.7x99 mm API 10cp Car + Магазин из 10-ти 12,7x99 мм (бронебойно-зажигательные) + 12,7x99 mm 10-Patronen-Magazin (API) + 12.7x99 mm API 10náb. Zásobník + Carregador 12.7x99 mm API com 10 cartuchos + 12,7x99 mm 10-lövedékes tár (páncéltörő-gyújtó) + 12.7x99mm 10Rnd 焼夷徹甲弾 マガジン + 10발 들이 12.7x99mm 철갑소이탄 탄창 + 12.7x99毫米 穿甲燃燒彈 10發 彈匣 + 12.7x99 mm 穿燃 10发 弹匣 + 12.7x99 mm API 10Rnd Mag + + + Caliber: 12.7x99 mm API<br />Rounds: 10 + Calibre: 12,7x99 mm API<br />Cartouches: 10 + Calibre: 12.7x99 mm API<br />Balas: 10 + Kaliber: 12,7x99 mm API<br />Pociski: 10 + Калибр: 12,7x99 мм бронебойно-зажигательные<br />Патронов: 10 + Kaliber:12,7x99 mm API<br />Patronen: 10 + Calibro: 12.7x99 mm API<br />Munizioni: 10 + Ráže: 12.7x99 mm API<br />Nábojů: 10 + Calibre: 12.7x99 mm API<br/>Cartuchos: 10 + Kaliber: 12,7x99 mm API<br />Lövedékek: 10 + 口径: 12.7x99 mm 焼夷徹甲弾<br />装填数: 10 + 구경: 12.7x99mm 철갑소이탄<br/>장탄수: 10 + 口徑: 12.7x99毫米 穿甲燃燒彈<br />發數: 10 + 口径:12.7x99 mm 穿燃<br />发数:10 + Kalibre: 12.7x99 mm API<br />Mermi: 10 - 12.7x99mm 5Rnd Mag (AMAX) - Ch. 12,7x99mm 5Cps (AMAX) - Cargador de 5 balas de 12.7x99mm (AMAX) - Magazynek 12,7x99mm 5rd (AMAX) + 12.7x99 mm 5Rnd Mag (AMAX) + Ch. 12,7x99 mm 5Cps (AMAX) + Cargador de 5 balas de 12.7x99 mm (AMAX) + Magazynek 12,7x99 mm 5rd (AMAX) Магазин из 5-ти 12,7x99 мм (A-MAX) - 12,7x99mm 5-Patronen-Magazin (AMAX) - 12.7x99mm 5Rnd Mag (AMAX) - 12.7x99mm 5náb. Zásobník (AMAX) - Carregador 12.7x99mm (AMAX) com 5 cartuchos - 12,7x99mm 5-lövedékes tár (AMAX) - 12.7x99mm 5発入り 弾倉 (AMAX) + 12,7x99 mm 5-Patronen-Magazin (AMAX) + 12.7x99 mm 5cp Car (AMAX) + 12.7x99 mm 5náb. Zásobník (AMAX) + Carregador 12.7x99 mm (AMAX) com 5 cartuchos + 12,7x99 mm 5-lövedékes tár (AMAX) + 12.7x99mm 5Rnd マガジン (AMAX) 5발들이 12.7x99mm 탄창 (AMAX) - 12.7x99mm 5發 彈匣 (AMAX 比賽專用彈) - 12.7x99mm 5发 弹匣 (AMAX 比赛专用弹) - - - 12.7mm - 12,7mm - 12.7mm - 12,7mm - 12,7 мм - 12,7mm - 12.7mm - 12.7mm - 12.7mm - 12,7mm - 12.7mm - 12.7mm - 12.7mm AMAX 比賽專用彈 - 12.7mm AMAX 比赛专用弹 + 12.7x99毫米 5發 彈匣 (AMAX 比賽專用彈) + 12.7x99 mm 5发 弹匣(AMAX) + 12.7x99 mm 5Rnd Şarjör (AMAX) - Caliber: 12.7x99mm (AMAX)<br />Rounds: 5 - Calibre: 12,7x99mm (AMAX)<br />Cartouches: 5 - Calibre: 12.7x99mm (AMAX)<br />Balas: 5 - Kaliber: 12,7x99mm (AMAX)<br />Pociski: 5 + Caliber: 12.7x99 mm (AMAX)<br />Rounds: 5 + Calibre: 12,7x99 mm (AMAX)<br />Cartouches: 5 + Calibre: 12.7x99 mm (AMAX)<br />Balas: 5 + Kaliber: 12,7x99 mm (AMAX)<br />Pociski: 5 Калибр: 12,7x99 мм (A-MAX)<br />Патронов: 5 - Calibro: 12.7x99mm (AMAX)<br />Munizioni: 5 - Kaliber:12,7x99mm (AMAX)<br />Patronen: 5 - Ráže: 12.7x99mm (AMAX)<br />Nábojů: 5 - Calibre: 12.7x99mm (AMAX)<br/>Cartuchos: 5 - Kaliber: 12,7x99mm (AMAX)<br />Lövedékek: 5 - 口径: 12.7x99mm (AMAX)<br />装填数: 5 - 구경: 12.7x99mm (AMAX)<br />장탄수: 5 - 口徑: 12.7x99mm (AMAX 比賽專用彈)<br />發數: 5 - 口径: 12.7x99mm (AMAX 比赛专用弹)<br />发数: 5 + Calibro: 12.7x99 mm (AMAX)<br />Munizioni: 5 + Kaliber:12,7x99 mm (AMAX)<br />Patronen: 5 + Ráže: 12.7x99 mm (AMAX)<br />Nábojů: 5 + Calibre: 12.7x99 mm (AMAX)<br/>Cartuchos: 5 + Kaliber: 12,7x99 mm (AMAX)<br />Lövedékek: 5 + 口径: 12.7x99 mm (AMAX)<br />装填数: 5 + 구경: 12.7x99mm (AMAX)<br/>장탄수: 5 + 口徑: 12.7x99毫米 (AMAX 比賽專用彈)<br />發數: 5 + 口径:12.7x99 mm(AMAX)<br />发数:5 + Kalibre: 12.7x99 mm (AMAX)<br />Mermi: 5 + + + 12.7x99 mm 10Rnd Mag (AMAX) + Ch. 12,7x99 mm 10Cps (AMAX) + Cargador de 10 balas de 12.7x99 mm (AMAX) + Magazynek 12,7x99 mm 10rd (AMAX) + Магазин из 10-ти 12,7x99 мм (A-MAX) + 12,7x99 mm 10-Patronen-Magazin (AMAX) + 12.7x99 mm 10cp Car (AMAX) + 12.7x99 mm 10náb. Zásobník (AMAX) + Carregador 12.7x99 mm (AMAX) com 10 cartuchos + 12,7x99 mm 10-lövedékes tár (AMAX) + 12.7x99mm 10Rnd マガジン (AMAX) + 10발들이 12.7x99mm 탄창 (AMAX) + 12.7x99毫米 10發 彈匣 (AMAX 比賽專用彈) + 12.7x99 mm 10发 弹匣(AMAX) + 12.7x99 mm 10Rnd Şarjör (AMAX) + + + Caliber: 12.7x99 mm (AMAX)<br />Rounds: 10 + Calibre: 12,7x99 mm (AMAX)<br />Cartouches: 10 + Calibre: 12.7x99 mm (AMAX)<br />Balas: 10 + Kaliber: 12,7x99 mm (AMAX)<br />Pociski: 10 + Калибр: 12,7x99 мм (A-MAX)<br />Патронов: 10 + Calibro: 12.7x99 mm (AMAX)<br />Munizioni: 10 + Kaliber:12,7x99 mm (AMAX)<br />Patronen: 10 + Ráže: 12.7x99 mm (AMAX)<br />Nábojů: 10 + Calibre: 12.7x99 mm (AMAX)<br/>Cartuchos: 10 + Kaliber: 12,7x99 mm (AMAX)<br />Lövedékek: 10 + 口径: 12.7x99 mm (AMAX)<br />装填数: 10 + 구경: 12.7x99mm (AMAX)<br/>장탄수: 10 + 口徑: 12.7x99毫米 (AMAX 比賽專用彈)<br />發數: 10 + 口径:12.7x99 mm(AMAX)<br />发数:10 + Kalibre: 12.7x99 mm (AMAX)<br />Mermi: 10 + + + 12.7 mm AMAX + 12,7 mm AMAX + 12.7 mm AMAX + 12,7 mm AMAX + 12,7 мм AMAX + 12,7 mm AMAX + 12.7 mm AMAX + 12.7 mm AMAX + 12.7 mm AMAX + 12,7 mm AMAX + 12.7 mm AMAX + 12.7mm AMAX + 12.7毫米 AMAX 比賽專用彈 + 12.7 mm AMAX + 12.7 mm AMAX + + + 12.7 mm API + 12,7 mm API + 12.7 mm API + 12,7 mm API + 12.7 mm API + 12.7 мм бронебойно-зажигательные + 12,7 mm API + 12.7 mm API + 12.7 mm API + 12,7 mm páncéltörő-gyújtó + 12.7 mm API + 12.7mm 철갑소이탄 + 12.7毫米 穿甲燃燒彈 + 12.7 mm 穿燃 + 12.7 mm API [ACE] Ammo Supply Crate @@ -2275,43 +3444,59 @@ [ACE] Caisse de munitions [ACE] Lőszeres láda [ACE] Ящик с боеприпасами - [ACE] Cassa munizioni + [ACE] Cassa Munizioni [ACE] 弾薬物資箱 - [ACE] 탄약 보급 상자 + [ACE] 탄약 보급상자 [ACE] 彈藥補給箱 [ACE] 弹药补给箱 + [ACE] Cephane Ikmal Kutusu Barrel twist Dralllänge - 銃身の転度 + 銃身転度 膛线缠距 膛線扭度 Rigatura della canna Gwintowanie lufy Нарезы ствола + Barrel Twist + Pas du canon + Stoupání vývrtu hlavně + Estriado del cañón + 강선 회전율 Barrel length Lauflänge Longueur du canon 銃身長 - 身管长度 + 枪管长度 槍管長度 Lunghezza della canna Długość lufy Длина ствола + Comprimento do cano + Délka hlavně + Longitud del cañón + Namlu Uzunluğu + 총열 길이 Ballistic coefficient Ballistischer Koeffizient - Coefficient ballistique + Coefficient balistique 弾道係数 弹道系数 彈道係數 - Coefficente balistico + Coefficiente balistico Współczynnik balistyczny Баллистический коэффициент + Coeficiente balístico + Balistický koeficient + Coheficiente de balística + Balistik Katsayısı + 탄도 계수 Bullet mass @@ -2323,17 +3508,111 @@ Massa del proiettile Masa pocisku Масса пули + Massa do projétil + Váha projektilu + Masa de la bala + Mermi Ağırlığı + 탄두 질량 Muzzle velocity Mündungsgeschwindigkeit - Vitesse à la bouche + Vitesse initiale 銃口初速 枪口初速 槍口初速 - Velocità iniziale + Velocità alla volata Prędkość wylotowa Начальная скорость + Velocidade de Saída + Úsťová rychlost + Velocidad inicial + Namlu çıkış hızı + 총구 속도 + + + AI Usage + AIの使用 + Wykorzystanie przez AI + KI Verwendet + Utilizzo IA + 인공지능 사용 + Utilisation de l'IA + Utilização por IA + Использование ИИ + Uso de la IA + + + Illum + 照明弾 + Flary + Leuchtmittel + Illuminante + 조명탄 + Fusées éclairantes + Sinalizadoras + Осветители + Iluminación + + + Smoke + 発煙弾 + Granaty dymne + Rauch + Fumogeno + 연막탄 + Fumigènes + Fumígenas + Дым + Humo + + + Inf + 歩兵 + Piechota + Infanterie + Fanti + 보병 + Infanterie + Infantaria + Пехота + Infantería + + + Veh + 車両 + Pojazdy + Fahrzeug + Veicoli + 차량 + Véhicule + Veículo + Техника + Vehículo + + + Armor + 機甲 + Pojazdy opancerzone + Panzerung + Blidati + 기갑 + Blindage + Blindagem + Бронетехника + Blindados + + + Air + 航空 + Lotnictwo + Luft + Velivoli + 항공 + Aviation + Aeronaves + Авиация + Aeronaves diff --git a/addons/captives/ACE_Settings.hpp b/addons/captives/ACE_Settings.hpp index 50d4c17aa7..f229d2385c 100644 --- a/addons/captives/ACE_Settings.hpp +++ b/addons/captives/ACE_Settings.hpp @@ -1,31 +1,14 @@ class ACE_Settings { class GVAR(allowHandcuffOwnSide) { - category = CSTRING(DisplayName); - displayName = CSTRING(ModuleSettings_handcuffSide_name); - description = CSTRING(ModuleSettings_handcuffSide_description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(requireSurrender) { - category = CSTRING(DisplayName); - displayName = CSTRING(ModuleSettings_requireSurrender_name); - description = CSTRING(ModuleSettings_requireSurrender_description); - typeName = "SCALAR"; - values[] = {ECSTRING(common,Disabled), CSTRING(SurrenderOnly), CSTRING(SurrenderOrNoWeapon)}; - value = 1; + movedToSQF = 1; }; class GVAR(allowSurrender) { - category = CSTRING(DisplayName); - displayName = CSTRING(ModuleSettings_allowSurrender_name); - description = CSTRING(ModuleSettings_allowSurrender_description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(requireSurrenderAi) { - category = CSTRING(DisplayName); - displayName = CSTRING(ModuleSettings_requireSurrenderAi_name); - description = CSTRING(ModuleSettings_requireSurrenderAi_description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; }; diff --git a/addons/captives/CfgEventHandlers.hpp b/addons/captives/CfgEventHandlers.hpp index 95453fe5d1..5e0d148c94 100644 --- a/addons/captives/CfgEventHandlers.hpp +++ b/addons/captives/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/captives/CfgGlasses.hpp b/addons/captives/CfgGlasses.hpp new file mode 100644 index 0000000000..5bebfb830c --- /dev/null +++ b/addons/captives/CfgGlasses.hpp @@ -0,0 +1,6 @@ +class CfgGlasses { + class None; + class G_Blindfold_01_base_F: None { + GVAR(blindfold) = 1; + }; +}; diff --git a/addons/captives/CfgVehicles.hpp b/addons/captives/CfgVehicles.hpp index d000ad6083..ca1194e614 100644 --- a/addons/captives/CfgVehicles.hpp +++ b/addons/captives/CfgVehicles.hpp @@ -5,9 +5,9 @@ class CfgVehicles { class ACE_ApplyHandcuffs { displayName = CSTRING(SetCaptive); selection = "righthand"; - distance = 2; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canApplyHandcuffs)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(doApplyHandcuffs)); + distance = HANDCUFFS_DISTANCE; + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canApplyHandcuffs)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(doApplyHandcuffs)); exceptions[] = {"isNotSwimming", "isNotInside"}; icon = QPATHTOF(UI\handcuff_ca.paa); }; @@ -16,17 +16,17 @@ class CfgVehicles { class ACE_RemoveHandcuffs { displayName = CSTRING(ReleaseCaptive); selection = "righthand"; - distance = 2; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRemoveHandcuffs)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(doRemoveHandcuffs)); + distance = HANDCUFFS_DISTANCE; + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canRemoveHandcuffs)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(doRemoveHandcuffs)); exceptions[] = {"isNotSwimming", "isNotInside"}; icon = QPATHTOF(UI\handcuff_ca.paa); }; class ACE_EscortCaptive { displayName = CSTRING(EscortCaptive); distance = 4; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canEscortCaptive)); - statement = QUOTE([ARR_3(_player, _target, true)] call FUNC(doEscortCaptive)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canEscortCaptive)); + statement = QUOTE([ARR_3(_player,_target,true)] call FUNC(doEscortCaptive)); exceptions[] = {"isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); @@ -34,8 +34,8 @@ class CfgVehicles { class ACE_StopEscorting { displayName = CSTRING(StopEscorting); distance = 4; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canStopEscorting)); - statement = QUOTE([ARR_3(_player,_target, false)] call FUNC(doEscortCaptive)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canStopEscorting)); + statement = QUOTE([ARR_3(_player,_target,false)] call FUNC(doEscortCaptive)); exceptions[] = {"isNotEscorting", "isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); @@ -43,8 +43,8 @@ class CfgVehicles { class ACE_LoadCaptive { displayName = CSTRING(LoadCaptive); distance = 4; - condition = QUOTE([ARR_3(_player, _target, objNull)] call FUNC(canLoadCaptive)); - statement = QUOTE([ARR_3(_player, _target, objNull)] call FUNC(doLoadCaptive)); + condition = QUOTE([ARR_3(_player,_target,objNull)] call FUNC(canLoadCaptive)); + statement = QUOTE([ARR_3(_player,_target,objNull)] call FUNC(doLoadCaptive)); exceptions[] = {"isNotEscorting", "isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); @@ -53,33 +53,49 @@ class CfgVehicles { class GVAR(UnloadCaptive) { displayName = CSTRING(UnloadCaptive); distance = 4; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canUnloadCaptive)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(doUnloadCaptive)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canUnloadCaptive)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(doUnloadCaptive)); exceptions[] = {"isNotSwimming"}; }; + class GVAR(BlindfoldCaptive) { + displayName = CSTRING(BlindfoldCaptive); + distance = 4; + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canBlindfoldCaptive)); + statement = QUOTE([ARR_3(_player,_target,true)] call FUNC(doBlindfoldCaptive)); + exceptions[] = {"isNotSwimming"}; + showDisabled = 0; + }; + class GVAR(RemoveBlindfoldCaptive) { + displayName = CSTRING(RemoveBlindfoldCaptive); + distance = 4; + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canRemoveBlindfoldCaptive)); + statement = QUOTE([ARR_3(_player,_target,false)] call FUNC(doBlindfoldCaptive)); + exceptions[] = {"isNotSwimming"}; + showDisabled = 0; + }; }; }; class ACE_SelfActions { class ACE_StopEscortingSelf { displayName = CSTRING(StopEscorting); - condition = QUOTE([ARR_2(_player, objNull)] call FUNC(canStopEscorting)); - statement = QUOTE([ARR_3(_player,objNull, false)] call FUNC(doEscortCaptive)); + condition = QUOTE([ARR_2(_player,objNull)] call FUNC(canStopEscorting)); + statement = QUOTE([ARR_3(_player,objNull,false)] call FUNC(doEscortCaptive)); exceptions[] = {"isNotEscorting", "isNotSwimming"}; showDisabled = 0; }; class ACE_StartSurrenderingSelf { displayName = CSTRING(StartSurrendering); - condition = QUOTE([ARR_2(_player, true)] call FUNC(canSurrender)); - statement = QUOTE([ARR_2(_player, true)] call FUNC(setSurrendered)); + condition = QUOTE([ARR_2(_player,true)] call FUNC(canSurrender)); + statement = QUOTE([ARR_2(_player,true)] call FUNC(setSurrendered)); exceptions[] = {"isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\Surrender_ca.paa); }; class ACE_StopSurrenderingSelf { displayName = CSTRING(StopSurrendering); - condition = QUOTE([ARR_2(_player, false)] call FUNC(canSurrender)); - statement = QUOTE([ARR_2(_player, false)] call FUNC(setSurrendered)); + condition = QUOTE([ARR_2(_player,false)] call FUNC(canSurrender)); + statement = QUOTE([ARR_2(_player,false)] call FUNC(setSurrendered)); exceptions[] = {"isNotSurrendering", "isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\Surrender_ca.paa); @@ -93,8 +109,8 @@ class CfgVehicles { class GVAR(LoadCaptive) { \ displayName = CSTRING(LoadCaptive); \ distance = 4; \ - condition = QUOTE([ARR_3(_player, objNull, _target)] call FUNC(canLoadCaptive)); \ - statement = QUOTE([ARR_3(_player, objNull, _target)] call FUNC(doLoadCaptive)); \ + condition = QUOTE([ARR_3(_player,objNull,_target)] call FUNC(canLoadCaptive)); \ + statement = QUOTE([ARR_3(_player,objNull,_target)] call FUNC(doLoadCaptive)); \ exceptions[] = {"isNotEscorting", "isNotSwimming"}; \ }; \ }; \ diff --git a/addons/captives/CfgWeapons.hpp b/addons/captives/CfgWeapons.hpp index 34f7b59e10..ce3c989ee5 100644 --- a/addons/captives/CfgWeapons.hpp +++ b/addons/captives/CfgWeapons.hpp @@ -4,13 +4,14 @@ class CfgWeapons { class ACE_CableTie: ACE_ItemCore { author = ECSTRING(common,ACETeam); + GVAR(restraint) = 1; displayName = CSTRING(CableTie); descriptionShort = CSTRING(CableTieDescription); model = QPATHTOF(models\ace_cabletie.p3d); picture = QPATHTOF(UI\ace_cabletie_ca.paa); scope = 2; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.3; }; }; }; diff --git a/addons/captives/README.md b/addons/captives/README.md index 37c26db159..eed1408c72 100644 --- a/addons/captives/README.md +++ b/addons/captives/README.md @@ -5,10 +5,3 @@ Adds ability to handcuff and surrender. #### Items Added: `ACE_CableTie` - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/captives/XEH_PREP.hpp b/addons/captives/XEH_PREP.hpp index 6157a1e33e..9769fe7855 100644 --- a/addons/captives/XEH_PREP.hpp +++ b/addons/captives/XEH_PREP.hpp @@ -1,12 +1,15 @@ PREP(addLoadCaptiveActions); PREP(canApplyHandcuffs); +PREP(canBlindfoldCaptive); PREP(canEscortCaptive); PREP(canLoadCaptive); +PREP(canRemoveBlindfoldCaptive); PREP(canRemoveHandcuffs); PREP(canStopEscorting); PREP(canSurrender); PREP(canUnloadCaptive); PREP(doApplyHandcuffs); +PREP(doBlindfoldCaptive); PREP(doEscortCaptive); PREP(doLoadCaptive); PREP(doRemoveHandcuffs); diff --git a/addons/captives/XEH_postInit.sqf b/addons/captives/XEH_postInit.sqf index 6adfef9dea..2580e72463 100644 --- a/addons/captives/XEH_postInit.sqf +++ b/addons/captives/XEH_postInit.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" -["ace_settingsInitialized", { +["CBA_settingsInitialized", { // Hold on a little bit longer to ensure anims will work [{ GVAR(captivityEnabled) = true; @@ -24,15 +24,15 @@ if (isServer) then { }]; }; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -[QGVAR(moveInCaptive), FUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; -[QGVAR(moveOutCaptive), FUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +[QGVAR(moveInCaptive), LINKFUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; +[QGVAR(moveOutCaptive), LINKFUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; -[QGVAR(setHandcuffed), FUNC(setHandcuffed)] call CBA_fnc_addEventHandler; -[QGVAR(setSurrendered), FUNC(setSurrendered)] call CBA_fnc_addEventHandler; +[QGVAR(setHandcuffed), LINKFUNC(setHandcuffed)] call CBA_fnc_addEventHandler; +[QGVAR(setSurrendered), LINKFUNC(setSurrendered)] call CBA_fnc_addEventHandler; //Medical Integration Events -["ace_unconscious", FUNC(handleOnUnconscious)] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleOnUnconscious)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; @@ -41,7 +41,7 @@ if (!hasInterface) exitWith {}; private _target = cursorObject; if !([ACE_player, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; if !(_target isKindOf "CAManBase") exitWith {false}; - if ((_target distance ACE_player) > getNumber (configFile >> "CfgVehicles" >> "CAManBase" >> "ACE_Actions" >> "ACE_ApplyHandcuffs" >> "distance")) exitWith {false}; + if ((_target distance ACE_player) > getNumber (configOf ACE_player >> "ACE_Actions" >> "ACE_ApplyHandcuffs" >> "distance")) exitWith {false}; if ([ACE_player, _target] call FUNC(canApplyHandcuffs)) exitWith { [ACE_player, _target] call FUNC(doApplyHandcuffs); diff --git a/addons/captives/XEH_preInit.sqf b/addons/captives/XEH_preInit.sqf index 641da1f5c8..8104e55b39 100644 --- a/addons/captives/XEH_preInit.sqf +++ b/addons/captives/XEH_preInit.sqf @@ -8,4 +8,9 @@ PREP_RECOMPILE_END; GVAR(captivityEnabled) = false; +GVAR(restraints) = keys (uiNamespace getVariable QGVAR(restraints)); +GVAR(blindfolds) = keys (uiNamespace getVariable QGVAR(blindfolds)); + +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/captives/XEH_preStart.sqf b/addons/captives/XEH_preStart.sqf index 022888575e..f1101979c6 100644 --- a/addons/captives/XEH_preStart.sqf +++ b/addons/captives/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +private _restraints = (QUOTE(getNumber (_x >> QQGVAR(restraint)) > 0) configClasses (configFile >> "CfgWeapons") apply {configName _x}); +uiNamespace setVariable [QGVAR(restraints), compileFinal (_restraints createHashMapFromArray [])]; + +private _blindfolds = (QUOTE(getNumber (_x >> QQGVAR(blindfold)) > 0) configClasses (configFile >> "CfgGlasses") apply {configName _x}); +uiNamespace setVariable [QGVAR(blindfolds), compileFinal (_blindfolds createHashMapFromArray [])]; diff --git a/addons/captives/config.cpp b/addons/captives/config.cpp index 0b8dae014a..c28a88559d 100644 --- a/addons/captives/config.cpp +++ b/addons/captives/config.cpp @@ -16,6 +16,7 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" +#include "CfgGlasses.hpp" #include "CfgMoves.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf index 81710f161d..d3f771be8d 100644 --- a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf +++ b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Adds child actions to the "load captive" action for near vehicles. @@ -10,7 +10,7 @@ * Child actions * * Example: - * [kevin] call ace_medical_fnc_addLoadCaptiveActions + * [kevin] call ace_captives_fnc_addLoadCaptiveActions * * Public: No */ @@ -22,4 +22,4 @@ private _statement = { [_player, _target, _vehicle] call FUNC(doLoadCaptive); }; -[_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) +[[_target, nil, true] call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/captives/functions/fnc_canApplyHandcuffs.sqf b/addons/captives/functions/fnc_canApplyHandcuffs.sqf index 72ac745517..9d91e2f517 100644 --- a/addons/captives/functions/fnc_canApplyHandcuffs.sqf +++ b/addons/captives/functions/fnc_canApplyHandcuffs.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able to apply handcuffs @@ -20,7 +20,7 @@ params ["_unit", "_target"]; //Check sides, Player has cableTie, target is alive and not already handcuffed (GVAR(allowHandcuffOwnSide) || {(side _unit) != (side _target)}) && -{"ACE_CableTie" in (_unit call EFUNC(common,uniqueItems))} && +{((_unit call EFUNC(common,uniqueItems)) findAny GVAR(restraints)) != -1} && {alive _target} && {!(_target getVariable [QGVAR(isHandcuffed), false])} && { diff --git a/addons/captives/functions/fnc_canBlindfoldCaptive.sqf b/addons/captives/functions/fnc_canBlindfoldCaptive.sqf new file mode 100644 index 0000000000..7020b1a9a6 --- /dev/null +++ b/addons/captives/functions/fnc_canBlindfoldCaptive.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: mrschick + * Checks if caller can blindfold the captive. + * + * Arguments: + * 0: Caller (player) + * 1: Target + * + * Return Value: + * Can blindfold + * + * Example: + * [player, cursorTarget] call ace_captives_fnc_canBlindfoldCaptive + * + * Public: No + */ + +params ["_unit", "_target"]; +// Alive, handcuffed, not being escorted, caller has a blindfold in their inventory and target isn't already wearing a blindfold + +(_target getVariable [QGVAR(isHandcuffed), false]) && +{isNull (attachedTo _target)} && +{alive _target} && +{(GVAR(blindfolds) findAny (_unit call EFUNC(common,uniqueItems))) != -1} && +{!((goggles _target) in GVAR(blindfolds))} diff --git a/addons/captives/functions/fnc_canEscortCaptive.sqf b/addons/captives/functions/fnc_canEscortCaptive.sqf index cb5fdd4972..f39ff2ac5f 100644 --- a/addons/captives/functions/fnc_canEscortCaptive.sqf +++ b/addons/captives/functions/fnc_canEscortCaptive.sqf @@ -1,14 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Tests if can escort target (attach) * * Arguments: - * 0: caller (player) - * 1: target + * 0: Caller (player) + * 1: Target * * Return Value: - * The return value + * Can escort * * Example: * [player, bob] call ACE_captives_fnc_canEscortCaptive @@ -17,7 +17,7 @@ */ params ["_unit", "_target"]; -//Alive, handcuffed, not being escored, and not unconscious +// Alive, handcuffed, not being escorted, and not unconscious (_target getVariable [QGVAR(isHandcuffed), false]) && {isNull (attachedTo _target)} && diff --git a/addons/captives/functions/fnc_canLoadCaptive.sqf b/addons/captives/functions/fnc_canLoadCaptive.sqf index 2129b36f5a..982e4025a2 100644 --- a/addons/captives/functions/fnc_canLoadCaptive.sqf +++ b/addons/captives/functions/fnc_canLoadCaptive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit can load the target object into a vehicle. @@ -34,7 +34,7 @@ if (isNull _target || {(vehicle _target) != _target} || {!(_target getVariable [ if (isNull _vehicle) then { // Looking at a captive unit, get nearest vehicle with valid seat: - _vehicle = (_target call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; + _vehicle = ([_target, nil, true] call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; } else { // We have a vehicle picked, make sure it has empty seats: if (_vehicle emptyPositions "cargo" == 0 && {_vehicle emptyPositions "gunner" == 0}) then { diff --git a/addons/captives/functions/fnc_canRemoveBlindfoldCaptive.sqf b/addons/captives/functions/fnc_canRemoveBlindfoldCaptive.sqf new file mode 100644 index 0000000000..b01f62e26c --- /dev/null +++ b/addons/captives/functions/fnc_canRemoveBlindfoldCaptive.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Checks if caller can remove blindfold from the captive. + * + * Arguments: + * 0: Caller (player) + * 1: Target + * + * Return Value: + * Can remove blindfold + * + * Example: + * [player, cursorTarget] call ace_captives_fnc_canRemoveBlindfoldCaptive + * + * Public: No + */ + +params ["_unit", "_target"]; +// Alive, handcuffed, not being escorted, and target is wearing a blindfold + +(_target getVariable [QGVAR(isHandcuffed), false]) && +{isNull (attachedTo _target)} && +{alive _target} && +{(goggles _target) in GVAR(blindfolds)} diff --git a/addons/captives/functions/fnc_canRemoveHandcuffs.sqf b/addons/captives/functions/fnc_canRemoveHandcuffs.sqf index 37dc156bf0..0ff4ab0f5d 100644 --- a/addons/captives/functions/fnc_canRemoveHandcuffs.sqf +++ b/addons/captives/functions/fnc_canRemoveHandcuffs.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able to remove handcuffs diff --git a/addons/captives/functions/fnc_canStopEscorting.sqf b/addons/captives/functions/fnc_canStopEscorting.sqf index 01010c8f97..7519904abd 100644 --- a/addons/captives/functions/fnc_canStopEscorting.sqf +++ b/addons/captives/functions/fnc_canStopEscorting.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Tests if player can stop escorting. diff --git a/addons/captives/functions/fnc_canSurrender.sqf b/addons/captives/functions/fnc_canSurrender.sqf index bec8edca04..80e1d26fb5 100644 --- a/addons/captives/functions/fnc_canSurrender.sqf +++ b/addons/captives/functions/fnc_canSurrender.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able switch surrender states diff --git a/addons/captives/functions/fnc_canUnloadCaptive.sqf b/addons/captives/functions/fnc_canUnloadCaptive.sqf index 3c5b302529..58899f088d 100644 --- a/addons/captives/functions/fnc_canUnloadCaptive.sqf +++ b/addons/captives/functions/fnc_canUnloadCaptive.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, LinkIsGrim * Check if the unit can unload a captive from the vehicle. * * Arguments: @@ -19,4 +19,6 @@ params ["_player", "_unit"]; // Don't show "Unload Captive" if unit is unconscious (already has "Unload Patient") -(vehicle _unit != _unit) && {vehicle _player == _player} && {_unit getVariable [QGVAR(isHandcuffed), false]} && {!(_unit getVariable ["ACE_isUnconscious", false])} +!isNull objectParent _unit && +{_unit getVariable [QGVAR(isHandcuffed), false]} && +{lifeState _unit in ["HEALTHY", "INJURED"]} diff --git a/addons/captives/functions/fnc_doApplyHandcuffs.sqf b/addons/captives/functions/fnc_doApplyHandcuffs.sqf index 1731151ead..c6a9be8e2a 100644 --- a/addons/captives/functions/fnc_doApplyHandcuffs.sqf +++ b/addons/captives/functions/fnc_doApplyHandcuffs.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able to apply handcuffs @@ -21,6 +21,8 @@ params ["_unit", "_target"]; playSound3D [QUOTE(PATHTO_R(sounds\cable_tie_zipping.ogg)), objNull, false, (getPosASL _target), 1, 1, 10]; -[QGVAR(setHandcuffed), [_target, true], [_target]] call CBA_fnc_targetEvent; +[QGVAR(setHandcuffed), [_target, true, _unit], [_target]] call CBA_fnc_targetEvent; -_unit removeItem "ACE_CableTie"; +private _cuffs = (_unit call EFUNC(common,uniqueItems)) arrayIntersect GVAR(restraints); + +_unit removeItem (_cuffs#0); diff --git a/addons/captives/functions/fnc_doBlindfoldCaptive.sqf b/addons/captives/functions/fnc_doBlindfoldCaptive.sqf new file mode 100644 index 0000000000..e4463909e6 --- /dev/null +++ b/addons/captives/functions/fnc_doBlindfoldCaptive.sqf @@ -0,0 +1,83 @@ +#include "..\script_component.hpp" +/* + * Author: mrschick, johnb43 + * Puts a blindfold on a captive unit if the player has a blindfold in their inventory. + * + * Arguments: + * 0: Unit + * 1: Target + * 2: Put on (true) or take off (false) + * + * Return Value: + * None + * + * Example: + * [player, cursorTarget, true] call ace_captives_fnc_doBlindfoldCaptive + * + * Public: No + */ + +params ["_unit", "_target", "_state"]; + +private _dropGoggles = false; +private _previousGoggles = ""; + +if (_state) then { // Blindfold target + // Check if _unit has a blindfold in its inventory, abort otherwise. + private _carriedBlindfoldIdx = GVAR(blindfolds) findAny (_unit call EFUNC(common,uniqueItems)); + if (_carriedBlindfoldIdx == -1) exitWith { ERROR("no blindfold"); }; + + private _blindfold = GVAR(blindfolds) select _carriedBlindfoldIdx; + _unit removeItem _blindfold; + + // Remove target's goggles if it is wearing any and move them to unit's or target's inventory (if they can hold them) + _previousGoggles = goggles _target; + if (_previousGoggles != "") then { + if ([_unit, _previousGoggles] call CBA_fnc_canAddItem) exitWith { + removeGoggles _target; + _unit addItem _previousGoggles; + }; + if ([_target, _previousGoggles] call CBA_fnc_canAddItem) exitWith { + removeGoggles _target; + _target addItem _previousGoggles; + }; + // If the target's goggles can fit in neither unit's nor target's inventory, drop them on the ground + _dropGoggles = true; + }; + + _target addGoggles _blindfold; +} else { // Remove blindfold from target + _previousGoggles = goggles _target; + + // Abort if already not wearing a blindfold + if !(_previousGoggles in GVAR(blindfolds)) exitWith { ERROR("no blindfold"); }; + + if ([_unit, _previousGoggles] call CBA_fnc_canAddItem) exitWith { + removeGoggles _target; + _unit addItem _previousGoggles; + }; + if ([_target, _previousGoggles] call CBA_fnc_canAddItem) exitWith { + removeGoggles _target; + _target addItem _previousGoggles; + }; + // If the target's blindfold can fit in neither unit's nor target's inventory, drop it on the ground + _dropGoggles = true; + + removeGoggles _target; +}; + +// Handle for things that need to be dropped to the ground or in a vehicle inventory +if (_dropGoggles) then { + private _weaponHolder = nearestObject [_target, "WeaponHolder"]; + // if _target is in a vehicle, use vehicle inventory as container + private _inVehicle = !isNull objectParent _target; + if (_inVehicle) then { + _weaponHolder = objectParent _target; + }; + + if (!_inVehicle && {isNull _weaponHolder || {_target distance _weaponHolder > 2}}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; + _weaponHolder setPosASL getPosASL _target; + }; + _weaponHolder addItemCargoGlobal [_previousGoggles, 1]; +}; diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index 86d597aabe..7eb25ccc4c 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nic547 * Attaches a Captive to the _unit @@ -12,7 +12,7 @@ * The return value * * Example: - * [player, bob, true] call ACE_captives_fnc_doEscorteCaptive; + * [player, bob, true] call ACE_captives_fnc_doEscortCaptive; * * Public: No */ @@ -44,15 +44,20 @@ if (_state) then { }; }; - if (!(_unit getVariable [QGVAR(isEscorting), false])) then { + if !(_unit getVariable [QGVAR(isEscorting), false]) then { [(_this select 1)] call CBA_fnc_removePerFrameHandler; [objNull, _target, false] call EFUNC(common,claim); detach _target; _unit removeAction _actionID; _unit setVariable [QGVAR(escortedUnit), objNull, true]; + + // Public event + [QGVAR(escortingCaptive), [_target, false, _unit]] call CBA_fnc_localEvent; }; }, 0, [_unit, _target, _actionID]] call CBA_fnc_addPerFrameHandler; + // Public event + [QGVAR(escortingCaptive), [_target, true, _unit]] call CBA_fnc_localEvent; } else { _unit setVariable [QGVAR(isEscorting), false, true]; _unit setVariable [QGVAR(escortedUnit), objNull, true]; diff --git a/addons/captives/functions/fnc_doLoadCaptive.sqf b/addons/captives/functions/fnc_doLoadCaptive.sqf index e4e3b5f45b..34bc46b1f5 100644 --- a/addons/captives/functions/fnc_doLoadCaptive.sqf +++ b/addons/captives/functions/fnc_doLoadCaptive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Unit loads the target object into a vehicle. (logic same as canLoadCaptive) @@ -31,7 +31,7 @@ if (isNull _target || {(vehicle _target) != _target} || {!(_target getVariable [ if (isNull _vehicle) then { // Looking at a captive unit, get nearest vehicle with valid seat: - _vehicle = (_target call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; + _vehicle = ([_target, nil, true] call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; } else { // We have a vehicle picked, make sure it has empty seats: if (_vehicle emptyPositions "cargo" == 0 && {_vehicle emptyPositions "gunner" == 0}) then { diff --git a/addons/captives/functions/fnc_doRemoveHandcuffs.sqf b/addons/captives/functions/fnc_doRemoveHandcuffs.sqf index a5623535d2..a9a35cd607 100644 --- a/addons/captives/functions/fnc_doRemoveHandcuffs.sqf +++ b/addons/captives/functions/fnc_doRemoveHandcuffs.sqf @@ -1,20 +1,21 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Remove handcuffs from a target * * Arguments: - * 0: target + * 0: Caller + * 1: Target * * Return Value: * The return value * * Example: - * [bob, false] call ACE_captives_fnc_doRemoveHandcuffs + * [bob, bill] call ACE_captives_fnc_doRemoveHandcuffs * * Public: No */ params ["_unit", "_target"]; -[QGVAR(setHandcuffed), [_target, false], [_target]] call CBA_fnc_targetEvent; +[QGVAR(setHandcuffed), [_target, false, _unit], [_target]] call CBA_fnc_targetEvent; diff --git a/addons/captives/functions/fnc_doUnloadCaptive.sqf b/addons/captives/functions/fnc_doUnloadCaptive.sqf index 8f78b7b323..c278e48363 100644 --- a/addons/captives/functions/fnc_doUnloadCaptive.sqf +++ b/addons/captives/functions/fnc_doUnloadCaptive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Unit unloads a captive from a vehicle. diff --git a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf index 7c9daf1080..2e07a353df 100644 --- a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf +++ b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Finds a free cargo seat, searching non FFV first @@ -16,22 +16,25 @@ */ params ["_vehicle"]; -TRACE_1("params", _vehicle); +TRACE_1("params",_vehicle); scopeName "main"; +private _seats = fullCrew [_vehicle, "", true]; +reverse _seats; + { _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; if (isNull _unit && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then { [_cargoIndex, false] breakOut "main"; }; -} forEach (fullCrew [_vehicle, "", true]); +} forEach _seats; { _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; if (isNull _unit && {_cargoIndex > -1}) then { [_cargoIndex, true] breakOut "main"; }; -} forEach (fullCrew [_vehicle, "", true]); +} forEach _seats; [-1, false] diff --git a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf index bdd61f6686..3363ca923e 100644 --- a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nic547, commy2 * Restart the handcuffing animation if it got interrupted. Called from a AnimChanged EH. diff --git a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf index 08d6369ed6..b9164ddbe5 100644 --- a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nic547, commy2 * Restart the surrendering animation if it got interrupted. Called from a AnimChanged EH. diff --git a/addons/captives/functions/fnc_handleGetIn.sqf b/addons/captives/functions/fnc_handleGetIn.sqf index 96a32031af..00a090a6bb 100644 --- a/addons/captives/functions/fnc_handleGetIn.sqf +++ b/addons/captives/functions/fnc_handleGetIn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles when a unit gets in to a vehicle. Release escorted captive when entering a vehicle @@ -36,7 +36,7 @@ if (local _unit) then { _x params ["_xUnit", "", "", "_xTurretPath"]; if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath}; } forEach (fullCrew (vehicle _unit)); - if (!(_turretPath isEqualTo [])) then { + if (_turretPath isNotEqualTo []) then { TRACE_1("Setting FFV Handcuffed Animation",_turretPath); [_unit, "ACE_HandcuffedFFV", 2] call EFUNC(common,doAnimation); [_unit, "ACE_HandcuffedFFV", 1] call EFUNC(common,doAnimation); diff --git a/addons/captives/functions/fnc_handleGetOut.sqf b/addons/captives/functions/fnc_handleGetOut.sqf index 7f5de6f330..610ec719f6 100644 --- a/addons/captives/functions/fnc_handleGetOut.sqf +++ b/addons/captives/functions/fnc_handleGetOut.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles when a captive unit gets out of a vehicle. diff --git a/addons/captives/functions/fnc_handleKilled.sqf b/addons/captives/functions/fnc_handleKilled.sqf index 39158ae662..3b8139e9fa 100644 --- a/addons/captives/functions/fnc_handleKilled.sqf +++ b/addons/captives/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Called when a unit dies. diff --git a/addons/captives/functions/fnc_handleLocal.sqf b/addons/captives/functions/fnc_handleLocal.sqf index be92b1c7dc..e6f9a11e3d 100644 --- a/addons/captives/functions/fnc_handleLocal.sqf +++ b/addons/captives/functions/fnc_handleLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Called when a unit switched locality diff --git a/addons/captives/functions/fnc_handleOnUnconscious.sqf b/addons/captives/functions/fnc_handleOnUnconscious.sqf index 745b651a0d..a43207fc84 100644 --- a/addons/captives/functions/fnc_handleOnUnconscious.sqf +++ b/addons/captives/functions/fnc_handleOnUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, PabstMirror * Handles the "ace_unconscious" event @@ -27,7 +27,7 @@ if (_isUnconc) then { }; } else { //Woke up: if handcuffed, goto animation - if (_unit getVariable [QGVAR(isHandcuffed), false] && {vehicle _unit == _unit}) then { + if (_unit getVariable [QGVAR(isHandcuffed), false] && {isNull objectParent _unit}) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); [_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_handlePlayerChanged.sqf b/addons/captives/functions/fnc_handlePlayerChanged.sqf index c6adce4f84..bafe93bef9 100644 --- a/addons/captives/functions/fnc_handlePlayerChanged.sqf +++ b/addons/captives/functions/fnc_handlePlayerChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles playerChanged. Resets "showHUD" based on handcuff status @@ -11,7 +11,7 @@ * The return value * * Example: - * [bob1, bob2] call ACE_captives_fnc_handlePlayerChange + * [bob1, bob2] call ACE_captives_fnc_handlePlayerChanged * * Public: No */ diff --git a/addons/captives/functions/fnc_handleRespawn.sqf b/addons/captives/functions/fnc_handleRespawn.sqf index 3643eb4393..1dc6ca7bfa 100644 --- a/addons/captives/functions/fnc_handleRespawn.sqf +++ b/addons/captives/functions/fnc_handleRespawn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 PabstMirror * Fix, because captiveNum doesn't reset properly on respawn diff --git a/addons/captives/functions/fnc_handleUnitInitPost.sqf b/addons/captives/functions/fnc_handleUnitInitPost.sqf index 2f189e2ffb..1045046b2a 100644 --- a/addons/captives/functions/fnc_handleUnitInitPost.sqf +++ b/addons/captives/functions/fnc_handleUnitInitPost.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * handle captive and unconsciousness state and prevent grenades diff --git a/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf b/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf index df78c9773f..9bc5fc18aa 100644 --- a/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf +++ b/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles ZeusDisplayChanged event diff --git a/addons/captives/functions/fnc_moduleHandcuffed.sqf b/addons/captives/functions/fnc_moduleHandcuffed.sqf index 1cd50dd4ce..32438643d7 100644 --- a/addons/captives/functions/fnc_moduleHandcuffed.sqf +++ b/addons/captives/functions/fnc_moduleHandcuffed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Module Function to make a unit handcuffed (can be called from editor) diff --git a/addons/captives/functions/fnc_moduleSettings.sqf b/addons/captives/functions/fnc_moduleSettings.sqf index d31a57a43d..5f44de695c 100644 --- a/addons/captives/functions/fnc_moduleSettings.sqf +++ b/addons/captives/functions/fnc_moduleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Module for captivity settings diff --git a/addons/captives/functions/fnc_moduleSurrender.sqf b/addons/captives/functions/fnc_moduleSurrender.sqf index ab31ea6bc9..8f59d913d8 100644 --- a/addons/captives/functions/fnc_moduleSurrender.sqf +++ b/addons/captives/functions/fnc_moduleSurrender.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Module Function to make a unit surrender (can be called from editor) diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index 5e0b634544..0c54d9a70a 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nic547, commy2 * Handcuffs a unit. @@ -6,18 +6,19 @@ * Arguments: * 0: Unit * 1: True to take captive, false to release captive + * 2: Caller * * Return Value: * None * * Example: - * [bob, true] call ACE_captives_fnc_setHandcuffed; + * [bob, true, dave] call ACE_captives_fnc_setHandcuffed; * * Public: No */ -params ["_unit","_state"]; -TRACE_2("params",_unit,_state); +params ["_unit", "_state", ["_caller", objNull]]; +TRACE_3("params",_unit,_state,_caller); if (!local _unit) exitWith { WARNING("running setHandcuffed on remote unit"); @@ -41,6 +42,7 @@ if ((_unit getVariable [QGVAR(isHandcuffed), false]) isEqualTo _state) exitWith if (_state) then { _unit setVariable [QGVAR(isHandcuffed), true, true]; [_unit, "setCaptive", QGVAR(Handcuffed), true] call EFUNC(common,statusEffect_set); + [_unit, "blockRadio", QGVAR(Handcuffed), true] call EFUNC(common,statusEffect_set); if (_unit getVariable [QGVAR(isSurrendering), false]) then { //If surrendering, stop [_unit, false] call FUNC(setSurrendered); @@ -56,7 +58,7 @@ if (_state) then { // fix anim on mission start (should work on dedicated servers) [{ params ["_unit"]; - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {}; + if !(_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {}; if ((vehicle _unit) == _unit) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); @@ -81,6 +83,7 @@ if (_state) then { } else { _unit setVariable [QGVAR(isHandcuffed), false, true]; [_unit, "setCaptive", QGVAR(Handcuffed), false] call EFUNC(common,statusEffect_set); + [_unit, "blockRadio", QGVAR(Handcuffed), false] call EFUNC(common,statusEffect_set); //remove AnimChanged EH private _animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1]; @@ -103,4 +106,4 @@ if (_state) then { }; //Global Event after changes: -["ace_captiveStatusChanged", [_unit, _state, "SetHandcuffed"]] call CBA_fnc_globalEvent; +["ace_captiveStatusChanged", [_unit, _state, "SetHandcuffed", _caller]] call CBA_fnc_globalEvent; diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index a9b4ef85a7..4acc8529bb 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 PabstMirror * Lets a unit surrender @@ -45,6 +45,7 @@ if (_state) then { _unit setVariable [QGVAR(isSurrendering), true, true]; [_unit, "setCaptive", QGVAR(Surrendered), true] call EFUNC(common,statusEffect_set); + [_unit, "blockRadio", QGVAR(Surrendered), true] call EFUNC(common,statusEffect_set); if (_unit == ACE_player) then { ["captive", [false, false, false, false, false, false, false, false, false, true]] call EFUNC(common,showHud); @@ -71,6 +72,7 @@ if (_state) then { } else { _unit setVariable [QGVAR(isSurrendering), false, true]; [_unit, "setCaptive", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set); + [_unit, "blockRadio", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set); //remove AnimChanged EH private _animChangedEHID = _unit getVariable [QGVAR(surrenderAnimEHID), -1]; @@ -79,7 +81,7 @@ if (_state) then { if (_unit == ACE_player) then { //only re-enable HUD if not handcuffed - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then { + if !(_unit getVariable [QGVAR(isHandcuffed), false]) then { ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; diff --git a/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf b/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf index 6089625961..95a7f43f84 100644 --- a/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf +++ b/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Loads a captive into a vehicle diff --git a/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf b/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf index f26ff45370..f2c2762f95 100644 --- a/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf +++ b/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Unloads a captive from a vehicle. diff --git a/addons/captives/functions/script_component.hpp b/addons/captives/functions/script_component.hpp deleted file mode 100644 index e91d5c843b..0000000000 --- a/addons/captives/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\captives\script_component.hpp" \ No newline at end of file diff --git a/addons/captives/initSettings.inc.sqf b/addons/captives/initSettings.inc.sqf new file mode 100644 index 0000000000..3a1fbfa6ed --- /dev/null +++ b/addons/captives/initSettings.inc.sqf @@ -0,0 +1,33 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(allowHandcuffOwnSide), "CHECKBOX", + [LSTRING(ModuleSettings_handcuffSide_name), LSTRING(ModuleSettings_handcuffSide_description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(requireSurrender), "LIST", + [LSTRING(ModuleSettings_requireSurrender_name), LSTRING(ModuleSettings_requireSurrender_description)], + _category, + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(SurrenderOnly), LSTRING(SurrenderOrNoWeapon)], 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(allowSurrender), "CHECKBOX", + [LSTRING(ModuleSettings_allowSurrender_name), LSTRING(ModuleSettings_allowSurrender_description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(requireSurrenderAi), "CHECKBOX", + [LSTRING(ModuleSettings_requireSurrenderAi_name), LSTRING(ModuleSettings_requireSurrenderAi_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/captives/script_component.hpp b/addons/captives/script_component.hpp index c0cbefe5b2..76094f990d 100644 --- a/addons/captives/script_component.hpp +++ b/addons/captives/script_component.hpp @@ -15,3 +15,5 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define HANDCUFFS_DISTANCE 2 diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 89911305e0..4fc86ec58f 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -8,15 +8,20 @@ 俘虜 俘虏 捕虜 - 포로설정 + 포로 Jeńcy Пленные + Prisioneiros + Prisonniers + Zajatci + Tutsaklar + Prisioneros Take Prisoner Gefangen nehmen Tomar prisionero - Prendre le prisonnier + Capturer le prisonnier Aresztuj Zajmout osobu Arresta il prigioniero @@ -26,7 +31,8 @@ 捕虜にする 포박하기 逮捕俘虜 - 逮捕俘虏 + 俘获 + Kelepçele Free Prisoner @@ -43,6 +49,7 @@ 풀어주기 釋放俘虜 释放俘虏 + Serbest bırak Escort Prisoner @@ -55,26 +62,28 @@ Escoltar Prisioneiro Fogoly kísérése Конвоировать пленного - 捕虜を移動させる + 捕虜を移送する 포로 호송하기 護送俘虜 护送俘虏 + Tutsağı Taşı Release Prisoner Gefangenen loslassen Soltar prisionero Anuluj eskortowanie - Relâcher le prisonnier + Lâcher le prisonnier Uvolnit zajatce Rilascia il Prigioniero Largar Prisioneiro Fogoly elengedése Прекратить конвоирование - 捕虜を解放する + 捕虜を手放す 포로 풀어주기 停止護送俘虜 停止护送俘虏 + Taşımayı bırak You need to take him as prisoner first! @@ -87,10 +96,11 @@ Você deve tomá-lo como prisioneiro primeiro! Először foglyul kell ejtened őt! Вы должны сначала арестовать его! - 捕虜を取っている必要があります! + 先に対象を捕虜にする必要があります! 먼저 포로로 만들어야합니다! 你必須先逮捕他! - 你必须先逮捕他! + 你必须先俘获他! + Önce onu tutuklamalısın! Load Captive @@ -107,6 +117,7 @@ 포로 태우기 將俘虜放入載具 将俘虏放入载具 + Tutukluyu bindir Unload Captive @@ -123,6 +134,30 @@ 포로 내리기 將俘虜帶出載具 将俘虏带出载具 + Tutukluyu indir + + + Blindfold Captive + Augen verbinden + Bandeau sur les yeux du captif + Vendar prisioneiro + Benda gli occhi + Załóż opaskę na oczy + 포로 눈 가리기 + 目隠しをする + Завязать глаза пленному + Vendar ojos al prisionero + + + Remove blindfold + Augenbinde entfernen + Enlever bandeau sur les yeux + Rimuovi la benda per gli occhi + Zdejmij opaskę z oczu + 눈가리개 풀기 + 目隠しを外す + Снять повязку с глаз + Quitar vendas de los ojos Cable Tie @@ -132,13 +167,14 @@ Serflex Stahovací pásek Algema Plástica - Fascietta + Fascetta Gyorskötöző Кабельная стяжка ケーブル タイ 케이블 타이 束線帶 束线带 + Kelepçe Cable ties that allow you to restrain prisoners. @@ -151,10 +187,11 @@ Fascetta per arrestare i prigionieri Gyorskötöző, emberek foglyulejtéséhez használható. Кабельные стяжки используются для связывания рук при аресте - ケーブル タイは捕虜を制圧できます。 + ケーブル タイによって捕虜を拘束することが出来る。 케이블 타이는 포로를 구류시킬때 씁니다. 束線帶可以綁住俘虜 束线带可以绑住俘虏 + Kişilerin ellerini bağlamanız için kablo sağlar. Surrender @@ -171,6 +208,7 @@ 투항 投降 投降 + Teslim ol Stop Surrendering @@ -187,6 +225,7 @@ 투항하는것을 멈춤 停止投降 停止投降 + Teslim olmayı durdur Make Unit Surrender @@ -195,7 +234,7 @@ Einheit kapitulieren lassen Vzdávající se jednotka Fazer unidade se render - Faire capituler l'unité + Se rend Egység kapitulálása Заставить юнита сдаться Fai arrendere l'unità @@ -203,6 +242,7 @@ 투항시키기 使單位投降 使单位投降 + Teslim olmaya zorla Sync a unit to make them surrender. @@ -211,10 +251,10 @@ Einheit synchronisieren, um sie kapitulieren zu lassen. Synchronizuj s jednotkou, která se má vzdát. Sincroniza uma unidade para fazer com que ela se renda. - Synchronise une unité pour la rendre captive. + Synchronise l'unité pour qu'elle se rende. Egység szinkronizálása, hogy kapituláljon. Синхронизируйте с юнитами, чтобы заставить их сдаться. - Sincronizza una unità per farla arrendere. + Sincronizza un'unità per farla arrendere. 同期されたユニットを投降させます。 투항시키기 위해 동기화합니다. 同步此模塊到一個單位,使該單位投降 @@ -229,11 +269,12 @@ Spoutat jednotku Metti manette all'unità Hacer que la unidad esté esposada - Rendre une unité captive - ユニットを拘束する + Est menottée + ユニットを拘束させる 포박하기 使單位戴上手銬 使单位戴上手铐 + Birimi Kelepçele Sync a unit to make them handcuffed. @@ -244,11 +285,12 @@ Synchronizovat s jednotkou, která má být v poutech. Sincronizza un'unità per metterle le manette. Sincroniza una unidad para hacer que esté esposada. - Synchronisez une unité pour la rendre captive. + Synchronise l'unité pour qu'elle soit menottée. 同期されたユニットを拘束させます。 수갑을 채우기 위해 동기화합니다. 使單位戴上手銬 使单位戴上手铐 + Birim kelepçelendi Captives Settings @@ -265,6 +307,7 @@ 포박 설정 俘虜設定 俘虏设定 + Tutsak Ayarları Controls settings for surrender and cable ties @@ -273,7 +316,7 @@ Toto kontroluje nastavení kapitulace a pout Einstellungen zur Kapitulation und Kabelbindern Controla as configurações de rendição e abraçadeiras - Contrôle les paramètres de la reddition et des Serflex + 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 @@ -289,11 +332,11 @@ Může spoutat spolubojovníky Kann Kameraden fesseln Pode algemar o próprio lado - Peut capturer sa propre faction + Permission de capturer son propre camp Saját oldal megbilincselhető Можно связывать руки союзникам Puoi ammanettare unità alleate - 拘束ユニットを自陣営へ + 自陣営を拘束可能に 자기편을 포박 할 수 있습니다. 可以銬住同陣營隊友 可以铐住同阵营队友 @@ -305,47 +348,15 @@ Mohou hráči spoutat jednotky na své straně Spieler können eigene Einheiten fesseln Os jogadores podem algemar unidades do seu lado - Les joueurs peuvent utiliser les Serflex sur leur propre camp + Les joueurs peuvent menotter les unités de leur propre camp. A játékosok megkötözhetik-e a saját oldalukon lévő egységeket Разрешить игрокам арестовывать юнитов своей стороны - I giocatori possono ammanettare unità alleate - プレイヤーが拘束したユニットの陣営を自陣営に変更させます。 - 자기편에게 케이블타이를 사용할 수 있게합니다 + I giocatori possono ammanettare unità della tua fazione + プレーヤーが自陣営のユニットをケーブルタイで拘束ができるようにします + 자기 편에게 케이블 타이를 사용할 수 있게 합니다 玩家可以使用束線帶銬住同陣營隊友 玩家可以使用束线带铐住同阵营队友 - - Allow surrendering - Pozwól kapitulować - Permitir rendición - Povolit vzdávání - Kapitulation erlauben - Permite rendição - Permettre la reddition - Kapituláció engedélyezése - Разрешить сдаваться - Permetti Resa - 投降を許可 - 투항 활성화 - 允許投降 - 允许投降 - - - Players can surrender after holstering their weapon - Gracze mogą skapitulować po schowaniu swojej broni do kabury - Los jugadores pueden rendirse después de enfundar su arma - Hráč se může vzdát poté, co si skryje zbraň - Spieler können kapitulieren, nachdem sie ihre Waffe geholstert haben. - 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 - プレイヤーは武器を収めたあと投降できるようにします。 - 비무장한 플레이어가 투항할 수 있게 합니다 - 玩家能在收起自己武器後投降 - 玩家能在收起自己武器后投降 - Require surrendering Benötigt Kapitulation @@ -370,11 +381,11 @@ 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 - Requiert la capitulation des joueurs avant qu'ils ne puissent être arrêtés - プレイヤーは拘束される前に、投降する必要があります。 + Définit si les joueurs doivent d'abord s'être rendus avant qu'on ne puisse les arrêter. + プレイヤーを拘束する前に、投降を必要とさせます 체포하기 전에 먼저 플레이어가 투항을 해야만 합니다 玩家須先要求目標投降,才可以進行逮捕 - 玩家须先要求目标投降,才可以进行逮捕 + 玩家须先要求目标投降,才可以进行俘获 Surrendering only @@ -400,44 +411,88 @@ Rendición o desarme Vzdávání nebo beze zbraně Resa o senza armi - Capitulation ou desarmé + Reddition ou désarmé 投降中か非武装時 투항 중 혹은 비무장 投降或無武器狀態 投降或无武器状态 - - Sets the unit under the cursor captive. - Nimmt die Einheit unter dem Cursor fest. - カーソル先のユニットを拘束 - Imposta l'unità nello stato di prigioniero. - 設置在游標下的單位成俘虜狀態 - 设置在游标下的单位成俘虏状态。 - 커서의 병력을 포박합니다. - Ustawia jednostkę pod kursorem jako jeniec. - Арестовывает указанный курсором юнит + + Allow surrendering + Pozwól kapitulować + Permitir rendición + Povolit vzdávání + Kapitulation erlauben + Permitir Rendição + Permettre la reddition + Kapituláció engedélyezése + Разрешить сдаваться + Permetti Resa + 投降を許可 + 투항 활성화 + 允許投降 + 允许投降 + + + Players can surrender after holstering their weapon + Gracze mogą skapitulować po schowaniu swojej broni do kabury + Los jugadores pueden rendirse después de enfundar su arma + Hráč se může vzdát poté, co si skryje zbraň + Spieler können kapitulieren, nachdem sie ihre Waffe geholstert haben. + Jogadores podem se render depois de guardar sua arma + Les joueurs peuvent se rendre après avoir rengainé 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 + プレイヤーが武器を収めたあとに投降できるようにします + 비무장한 플레이어가 투항할 수 있게 합니다 + 玩家能在收起自己武器後投降 + 玩家能在收起自己武器后投降 Require AI surrendering Benötigt für KI Kapitulation - Necessita arresa AI - AI の投降を必要とする + Necessita arresa IA + AIの投降を必要とする 需要AI先行投降 - 需要AI先行投降 + 需要 AI 先行投降 AI 항복 필요 Wymaga poddania się przez SI Требовать ИИ сдаться для ареста + Requer rendição da IA + Requiert la reddition de l'IA + Vyžadovat, aby se AI prvně vzdala + Requiere la rendición de la IA Require AI to surrender before they can be arrested KI muss sich erst ergeben, bevor sie gefangen genommen werden kann - Necessita che le AI si arrendano prima di essere arrestate - AI の拘束は AI が投降している場合に限り可能にします。 + Necessita che le IA si arrendano prima di poter essere arrestate + AIを拘束する前に、投降を必要とさせます 在逮捕AI之前該AI必須先進入投降狀態 - 在逮捕AI之前该AI必须先进入投降状态。 + 在俘获 AI 之前该 AI 必须先进入投降状态。 포박하기 전에 먼저 AI가 투항해야만 합니다. Wymaga poddania się przez SI zanim aresztowanie będzie możliwe Требовать для ареста, чтобы ИИ вначале сдавались + Requer que a IA se renda antes que seja presa + Requiert la capitulation des unités IA avant qu'elles ne puissent être arrêtées. + Vyžadovat, aby se AI prvně vzdala před umožněním zajetí + Requiere la rendición de la IA antes de poder arrestarlas + + + Sets the unit under the cursor captive. + Nimmt die Einheit unter dem Cursor fest. + カーソル先のユニットを拘束 + Imposta l'unità puntata come prigioniero. + 設置在游標下的單位成俘虜狀態 + 设置在光标下的单位成俘虏状态。 + 커서의 병력을 포박합니다. + Ustawia jednostkę pod kursorem jako jeniec. + Арестовывает указанный курсором юнит. + Torna a unidade sob o cursor um prisioneiro + Capture l'unité sous le curseur. + Nastaví jednotku pod kurzorem jako zajatce. + Establece a la unidad bajo el cursor como prisionera diff --git a/addons/cargo/CfgEden.hpp b/addons/cargo/CfgEden.hpp index 9144ba458b..0a4cc7ba1b 100644 --- a/addons/cargo/CfgEden.hpp +++ b/addons/cargo/CfgEden.hpp @@ -3,14 +3,26 @@ class Cfg3DEN { class AttributeCategories { class ace_attributes { class Attributes { + class GVAR(customName) { + displayName = CSTRING(customName_edenName); + tooltip = CSTRING(customName_edenDesc); + property = QGVAR(customName); + control = "Edit"; + + expression = QUOTE(_this setVariable [ARR_3(QQGVAR(customName),_value,true)]); + defaultValue = "''"; + + condition = "objectHasInventoryCargo - objectVehicle"; + typeName = "STRING"; + }; class GVAR(space) { displayName = CSTRING(space_edenName); tooltip = CSTRING(space_edenDesc); property = QGVAR(space); control = "Edit"; - expression = QUOTE([ARR_2(_this,_value)] call DFUNC(setSpace);); - defaultValue = QUOTE(GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(space),0)); + expression = QUOTE([ARR_2(_this,_value)] call DFUNC(setSpace)); + defaultValue = QUOTE(GET_NUMBER(configOf _this >> QQGVAR(space),0)); validate = "number"; condition = "objectHasInventoryCargo"; @@ -23,8 +35,8 @@ class Cfg3DEN { control = "Edit"; // Expression only runs on the server, must handle actions for all machines and future JIPs (Why BI?!) - expression = QUOTE([ARR_2(_this,_value)] call DFUNC(setSize);); - defaultValue = QUOTE(GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(size),-1)); + expression = QUOTE([ARR_2(_this,_value)] call DFUNC(setSize)); + defaultValue = QUOTE(GET_NUMBER(configOf _this >> QQGVAR(size),-1)); validate = "number"; condition = "1-objectBrain"; diff --git a/addons/cargo/CfgEventHandlers.hpp b/addons/cargo/CfgEventHandlers.hpp index 823dc87470..29a0c6b277 100644 --- a/addons/cargo/CfgEventHandlers.hpp +++ b/addons/cargo/CfgEventHandlers.hpp @@ -1,26 +1,31 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_Killed_EventHandlers { - class All { + class CAManBase { class ADDON { - serverKilled = QUOTE(call FUNC(handleDestroyed)); + killed = QUOTE((_this select 0) call FUNC(handleDeployInterrupt)); }; }; }; + +class Extended_DisplayLoad_EventHandlers { + class RscDisplayMission { + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); + }; +}; diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index ab41cac4db..66fa98159e 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -48,15 +48,7 @@ class CfgVehicles { class Car: LandVehicle { GVAR(space) = 4; GVAR(hasCargo) = 1; - class ACE_Cargo { - /* - class Cargo { - class ACE_medicalSupplyCrate { - type = "ACE_medicalSupplyCrate"; - amount = 1; - }; - };*/ - }; + class ADDON {}; }; class Tank: LandVehicle { @@ -75,96 +67,105 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - // hemets + // HEMTTs - Default at 30, some variants are altered based on model size and/or expected level of free space inside. class Truck_01_base_F: Truck_F { - GVAR(space) = 8; + GVAR(space) = 30; }; class B_Truck_01_transport_F: Truck_01_base_F { - GVAR(space) = 20; + GVAR(space) = 30; }; class B_Truck_01_covered_F: B_Truck_01_transport_F { - GVAR(space) = 20; + GVAR(space) = 30; }; class B_Truck_01_mover_F: B_Truck_01_transport_F { GVAR(space) = 4; }; class B_Truck_01_box_F: B_Truck_01_mover_F { - GVAR(space) = 40; + GVAR(space) = 50; }; class B_Truck_01_Repair_F: B_Truck_01_mover_F { - GVAR(space) = 20; + GVAR(space) = 4; }; class B_Truck_01_ammo_F: B_Truck_01_mover_F { - GVAR(space) = 8; + GVAR(space) = 10; }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { GVAR(space) = 4; }; class B_Truck_01_medical_F: B_Truck_01_transport_F { - GVAR(space) = 8; + GVAR(space) = 30; }; - // kamaz' - class Truck_02_base_F: Truck_F { //covers "covered" variants - GVAR(space) = 20; + // Kamaz' + class Truck_02_base_F: Truck_F { // Covers "transport" variants. + GVAR(space) = 25; }; class Truck_02_transport_base_F: Truck_02_base_F { - GVAR(space) = 20; + GVAR(space) = 25; }; - class Truck_02_box_base_F: Truck_02_base_F { // repair variant, not actually cargo box like hemet - GVAR(space) = 12; + class Truck_02_box_base_F: Truck_02_base_F { // Repair variant, smaller than HEMTT. + GVAR(space) = 4; }; class Truck_02_medical_base_F: Truck_02_box_base_F { - GVAR(space) = 8; + GVAR(space) = 25; }; class Truck_02_Ammo_base_F: Truck_02_base_F { - GVAR(space) = 12; + GVAR(space) = 4; }; class Truck_02_fuel_base_F: Truck_02_base_F { GVAR(space) = 4; }; - // typhoon + // Typhoon - Roughly the same size if not slightly larger than HEMTT. class Truck_03_base_F: Truck_F { GVAR(space) = 8; }; class O_Truck_03_transport_F: Truck_03_base_F { - GVAR(space) = 20; + GVAR(space) = 30; }; class O_Truck_03_covered_F: Truck_03_base_F { - GVAR(space) = 20; + GVAR(space) = 30; }; class O_Truck_03_repair_F: Truck_03_base_F { - GVAR(space) = 12; + GVAR(space) = 4; }; class O_Truck_03_ammo_F: Truck_03_base_F { - GVAR(space) = 8; + GVAR(space) = 4; }; class O_Truck_03_fuel_F: Truck_03_base_F { GVAR(space) = 4; }; class O_Truck_03_medical_F: Truck_03_base_F { - GVAR(space) = 8; + GVAR(space) = 30; }; class O_Truck_03_device_F: Truck_03_base_F { GVAR(space) = 4; }; - // civ trucks + // Civilian Trucks class Van_01_base_F: Truck_F { GVAR(space) = 8; }; class Van_01_transport_base_F: Van_01_base_F { GVAR(space) = 8; }; - class Van_01_box_base_F: Van_01_base_F { // repair variant, not actually cargo box like hemet - GVAR(space) = 12; + class Van_01_box_base_F: Van_01_base_F { + GVAR(space) = 15; }; class Van_01_fuel_base_F: Van_01_base_F { - GVAR(space) = 4; + GVAR(space) = 2; }; - // misc. vehicles + // Laws of War Vans + class Van_02_base_F: Truck_F { // Transport + GVAR(space) = 10; + }; + class Van_02_vehicle_base_F: Van_02_base_F { // Cargo + GVAR(space) = 20; + }; + + + // Misc. vehicles class Quadbike_01_base_F: Car_F { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -175,7 +176,7 @@ class CfgVehicles { GVAR(hasCargo) = 0; }; - // helicopters + // Helicopters class Air; class Helicopter: Air { GVAR(space) = 8; @@ -194,12 +195,12 @@ class CfgVehicles { }; class Heli_Light_02_base_F: Helicopter_Base_H { - GVAR(space) = 4; + GVAR(space) = 8; }; class Helicopter_Base_F; class Heli_light_03_base_F: Helicopter_Base_F { - GVAR(space) = 4; + GVAR(space) = 6; }; class Heli_Transport_01_base_F: Helicopter_Base_H { @@ -215,7 +216,7 @@ class CfgVehicles { }; class Heli_Transport_04_base_F: Helicopter_Base_H { - // note the double brackets are because loadmasterTurrets is an array of arrays / turret paths + // Note the double brackets are because loadmasterTurrets is an array of arrays / turret paths GVAR(loadmasterTurrets)[] = {{1}}; GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -227,19 +228,19 @@ class CfgVehicles { }; class O_Heli_Transport_04_repair_F: Heli_Transport_04_base_F { - GVAR(space) = 12; + GVAR(space) = 2; GVAR(hasCargo) = 1; }; class O_Heli_Transport_04_ammo_F: Heli_Transport_04_base_F { - GVAR(space) = 8; + GVAR(space) = 2; GVAR(hasCargo) = 1; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F {}; class O_Heli_Transport_04_medevac_F: Heli_Transport_04_base_F { - GVAR(space) = 8; + GVAR(space) = 10; GVAR(hasCargo) = 1; }; @@ -252,7 +253,7 @@ class CfgVehicles { GVAR(space) = 4; }; - // planes (off by default as most are attack jets) + // Planes, does not apply to attack jets. class Plane: Air { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -265,15 +266,15 @@ class CfgVehicles { }; class VTOL_Base_F; class VTOL_01_base_F: VTOL_Base_F { - GVAR(space) = 4; + GVAR(space) = 30; GVAR(hasCargo) = 1; }; class VTOL_02_base_F: VTOL_Base_F { - GVAR(space) = 4; + GVAR(space) = 15; GVAR(hasCargo) = 1; }; - // autonomous + // Drones class UAV_01_base_F: Helicopter_Base_F { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -287,7 +288,7 @@ class CfgVehicles { GVAR(hasCargo) = 0; }; - // boats + // Boats class Ship; class Ship_F: Ship { GVAR(space) = 4; @@ -295,7 +296,7 @@ class CfgVehicles { }; class Boat_Civil_01_base_F: Ship_F { - GVAR(space) = 4; + GVAR(space) = 2; GVAR(hasCargo) = 1; }; @@ -306,11 +307,11 @@ class CfgVehicles { }; class Boat_Armed_01_base_F: Boat_F { - GVAR(space) = 8; + GVAR(space) = 4; GVAR(hasCargo) = 1; }; - // submarines + // Submarines class SDV_01_base_F: Boat_F { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -322,6 +323,11 @@ class CfgVehicles { GVAR(canLoad) = 1; }; + // Invisible Target Soldier + class TargetSoldierBase: StaticWeapon { + GVAR(canLoad) = 0; + }; + class StaticMortar; class Mortar_01_base_F: StaticMortar { GVAR(size) = 2; // 1 = small, 2 = large @@ -335,10 +341,10 @@ class CfgVehicles { GVAR(size) = 2; // 1 = small, 2 = large GVAR(canLoad) = 1; }; - class Land_RepairDepot_01_base_F: ReammoBox_F { // TanksDLC - Repair Depo Thing (probably too big to safely unload) + class Land_RepairDepot_01_base_F: ReammoBox_F { // Tanks DLC - Repair Depot, too big to safely unload. GVAR(canLoad) = 0; }; - //"Supply Box" - Small Pallets + // "Supply Box" - Small Pallets class B_supplyCrate_F: ReammoBox_F { GVAR(size) = 6; }; @@ -349,30 +355,31 @@ class CfgVehicles { GVAR(size) = 6; }; + // Slingload pallets class Slingload_base_F: ReammoBox_F {}; - class CargoNet_01_base_F: Slingload_base_F { //Slingload pallets + class CargoNet_01_base_F: Slingload_base_F { GVAR(size) = 6; }; - //Huron 20ft containers + // Huron 20ft containers class Slingload_01_Base_F: Slingload_base_F { - GVAR(canLoad) = 0; - GVAR(size) = -1; + GVAR(canLoad) = 1; + GVAR(size) = 50; // Use same size value from 20ft containers for consistancy }; class B_Slingload_01_Cargo_F: Slingload_01_Base_F { // Huron Cargo GVAR(space) = 20; GVAR(hasCargo) = 1; }; class B_Slingload_01_Ammo_F: Slingload_01_Base_F { // Huron Ammo - GVAR(space) = 8; + GVAR(space) = 0; GVAR(hasCargo) = 1; }; class B_Slingload_01_Medevac_F: Slingload_01_Base_F { // Huron Medevac - GVAR(space) = 8; + GVAR(space) = 10; GVAR(hasCargo) = 1; }; class B_Slingload_01_Repair_F: Slingload_01_Base_F { // Huron Repair - GVAR(space) = 12; + GVAR(space) = 0; GVAR(hasCargo) = 1; }; @@ -382,15 +389,15 @@ class CfgVehicles { GVAR(size) = -1; }; class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F { - GVAR(space) = 8; + GVAR(space) = 0; GVAR(hasCargo) = 1; }; - class Land_Pod_Heli_Transport_04_box_F: Pod_Heli_Transport_04_base_F { - GVAR(space) = 20; + class Land_Pod_Heli_Transport_04_box_F: Pod_Heli_Transport_04_base_F { // Smaller than Huron Cargo + GVAR(space) = 15; GVAR(hasCargo) = 1; }; class Land_Pod_Heli_Transport_04_repair_F: Pod_Heli_Transport_04_base_F { - GVAR(space) = 12; + GVAR(space) = 0; GVAR(hasCargo) = 1; }; class Pod_Heli_Transport_04_crewed_base_F: StaticWeapon { @@ -406,7 +413,7 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - //Plastic and metal case + // Plastic and metal case class PlasticCase_01_base_F: Items_base_F { GVAR(size) = 1; // 1 = small, 2 = large GVAR(canLoad) = 1; @@ -426,30 +433,43 @@ class CfgVehicles { class Land_CanisterFuel_F: Items_base_F { GVAR(size) = 1; GVAR(canLoad) = 1; + GVAR(noRename) = 1; }; - // objects + // Flexible Fuel tanks, 300L + class FlexibleTank_base_F: ThingX { + GVAR(size) = 3; + GVAR(canLoad) = 1; + GVAR(noRename) = 1; + }; + + // Objects class RoadCone_F: ThingX { GVAR(size) = 1; GVAR(canLoad) = 1; + GVAR(noRename) = 1; }; class RoadBarrier_F: RoadCone_F { GVAR(size) = 2; + GVAR(noRename) = 1; }; class Lamps_base_F; class Land_PortableLight_single_F: Lamps_base_F { GVAR(size) = 2; GVAR(canLoad) = 1; + GVAR(noRename) = 1; }; class FloatingStructure_F; class Land_Camping_Light_F: FloatingStructure_F { GVAR(size) = 0.2; GVAR(canLoad) = 1; + GVAR(noRename) = 1; }; class Land_Camping_Light_off_F: ThingX { GVAR(size) = 0.2; GVAR(canLoad) = 1; + GVAR(noRename) = 1; }; @@ -482,7 +502,7 @@ class CfgVehicles { }; GVAR(space) = 2; - GVAR(hasCargo) = 2; + GVAR(hasCargo) = 1; GVAR(size) = 3; GVAR(canLoad) = 1; @@ -495,8 +515,9 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + GVAR(space) = 3; - GVAR(hasCargo) = 3; + GVAR(hasCargo) = 1; GVAR(size) = 3; GVAR(canLoad) = 1; @@ -636,6 +657,15 @@ class CfgVehicles { GVAR(space) = 49; GVAR(size) = 50; }; + class Cargo_IDAP_base_F: Cargo_base_F {}; + class Land_Cargo20_IDAP_F: Cargo_IDAP_base_F { + class EventHandlers { + class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; + }; + + GVAR(space) = 49; + GVAR(size) = 50; + }; class Land_Cargo40_blue_F: Cargo_base_F { class EventHandlers { diff --git a/addons/cargo/README.md b/addons/cargo/README.md index eda7079b7b..e506eda71f 100644 --- a/addons/cargo/README.md +++ b/addons/cargo/README.md @@ -2,11 +2,3 @@ ace_cargo ============ Adds cargo menu to vehicles and allows loading and unloading of cargo items. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [Glowbal](https://github.com/Glowbal) diff --git a/addons/cargo/XEH_PREP.hpp b/addons/cargo/XEH_PREP.hpp index 154956c74a..10281e2967 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -2,9 +2,15 @@ PREP(addCargoItem); PREP(addCargoVehiclesActions); PREP(canLoadItemIn); PREP(canUnloadItem); +PREP(deployCancel); +PREP(deployConfirm); PREP(getCargoSpaceLeft); +PREP(getNameItem); +PREP(getSelectedItem); PREP(getSizeItem); PREP(handleDestroyed); +PREP(handleDeployInterrupt); +PREP(handleScrollWheel); PREP(initObject); PREP(initVehicle); PREP(loadItem); @@ -12,9 +18,11 @@ PREP(moduleSettings); PREP(onMenuOpen); PREP(paradropItem); PREP(removeCargoItem); +PREP(renameObject); PREP(setSize); PREP(setSpace); +PREP(startDeploy); PREP(startLoadIn); PREP(startUnload); +PREP(unloadCarryItem); PREP(unloadItem); -PREP(validateCargoSpace); diff --git a/addons/cargo/XEH_missionDisplayLoad.sqf b/addons/cargo/XEH_missionDisplayLoad.sqf new file mode 100644 index 0000000000..7bdea7571f --- /dev/null +++ b/addons/cargo/XEH_missionDisplayLoad.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +params ["_display"]; + +_display displayAddEventHandler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}]; +_display displayAddEventHandler ["MouseButtonDown", { + // Right clicking cancels deployment + if (_this select 1 == 1) then { + ACE_player call FUNC(handleDeployInterrupt); + }; +}]; diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index 1df7733aea..f48849b50b 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -1,69 +1,80 @@ #include "script_component.hpp" -["ace_addCargo", {_this call FUNC(addCargoItem)}] call CBA_fnc_addEventHandler; -[QGVAR(paradropItem), {_this call FUNC(paradropItem)}] call CBA_fnc_addEventHandler; +["ace_addCargo", LINKFUNC(addCargoItem)] call CBA_fnc_addEventHandler; ["ace_loadCargo", { params ["_item", "_vehicle"]; TRACE_2("LoadCargo EH",_item,_vehicle); - private _loaded = [_item, _vehicle] call FUNC(loadItem); + private _loaded = [_item, _vehicle] call FUNC(loadItem); // returns true if successful // Show hint as feedback - private _hint = [LSTRING(LoadingFailed), LSTRING(LoadedItem)] select _loaded; - private _itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName"); - private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + private _hint = [LSTRING(loadingFailed), LSTRING(loadedItem)] select _loaded; + private _itemName = [_item, true] call FUNC(getNameItem); + private _vehicleName = getText (configOf _vehicle >> "displayName"); - [[_hint, _itemName, _vehicleName], 3.0] call EFUNC(common,displayTextStructured); - - if (_loaded) then { - // Invoke listenable event - ["ace_cargoLoaded", [_item, _vehicle]] call CBA_fnc_globalEvent; - }; + [[_hint, _itemName, _vehicleName], 3] call EFUNC(common,displayTextStructured); }] call CBA_fnc_addEventHandler; ["ace_unloadCargo", { - params ["_item", "_vehicle", ["_unloader", objNull]]; - TRACE_3("UnloadCargo EH",_item,_vehicle,_unloader); + params ["_item", "_vehicle", ["_unloader", objNull], ["_place", []]]; + TRACE_4("UnloadCargo EH",_item,_vehicle,_unloader,_place); - private _unloaded = [_item, _vehicle, _unloader] call FUNC(unloadItem); //returns true if sucessful - - private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item}; + private _unloaded = [_item, _vehicle, _unloader, _place] call FUNC(unloadItem); // returns true if successful // Show hint as feedback - private _hint = [LSTRING(UnloadingFailed), LSTRING(UnloadedItem)] select _unloaded; - private _itemName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName"); - private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + private _hint = [LSTRING(unloadingFailed), LSTRING(unloadedItem)] select _unloaded; + private _itemName = [_item, true] call FUNC(getNameItem); + private _vehicleName = getText (configOf _vehicle >> "displayName"); - [[_hint, _itemName, _vehicleName], 3.0] call EFUNC(common,displayTextStructured); + [[_hint, _itemName, _vehicleName], 3] call EFUNC(common,displayTextStructured); - if (_unloaded) then { - // Invoke listenable event - ["ace_cargoUnloaded", [_item, _vehicle]] call CBA_fnc_globalEvent; + if (_unloaded && {GVAR(openAfterUnload) in [1, 3]}) then { + GVAR(interactionVehicle) = _vehicle; + GVAR(interactionParadrop) = false; + createDialog QGVAR(menu); }; - - // TOOO maybe drag/carry the unloaded item? }] call CBA_fnc_addEventHandler; +// Direction must be set before setting position according to wiki +[QGVAR(setDirAndUnload), { + params ["_item", "_emptyPosAGL", "_direction"]; + + _item setDir _direction; + + [QGVAR(serverUnload), [_item, _emptyPosAGL]] call CBA_fnc_serverEvent; +}] call CBA_fnc_addEventHandler; + +// hideObjectGlobal must be executed before setPos to ensure light objects are rendered correctly +// Do both on server to ensure they are executed in the correct order [QGVAR(serverUnload), { params ["_item", "_emptyPosAGL"]; _item hideObjectGlobal false; _item setPosASL (AGLtoASL _emptyPosAGL); - if ((getText (configFile >> "CfgVehicles" >> (typeOf _item) >> "simulation")) == "carx") then { - TRACE_1("re-enabling car damage",_item); - [_item, "blockDamage", "ACE_cargo", false] call EFUNC(common,statusEffect_set); + // Let objects remain invulernable for a short while after placement + [EFUNC(common,statusEffect_set), [_item, "blockDamage", QUOTE(ADDON), false], 2] call CBA_fnc_waitAndExecute; +}] call CBA_fnc_addEventHandler; + +[QGVAR(paradropItem), { + params ["_item", "_vehicle", ["_showHint", true]]; + + private _unloaded = [_item, _vehicle, _showHint] call FUNC(paradropItem); + + if (_unloaded && {GVAR(openAfterUnload) in [2, 3]}) then { + GVAR(interactionVehicle) = _vehicle; + GVAR(interactionParadrop) = true; + createDialog QGVAR(menu); }; }] call CBA_fnc_addEventHandler; // Private events to handle adding actions globally via public functions -[QGVAR(initObject), DFUNC(initObject)] call CBA_fnc_addEventHandler; -[QGVAR(initVehicle), DFUNC(initVehicle)] call CBA_fnc_addEventHandler; - +[QGVAR(initObject), LINKFUNC(initObject)] call CBA_fnc_addEventHandler; +[QGVAR(initVehicle), LINKFUNC(initVehicle)] call CBA_fnc_addEventHandler; GVAR(vehicleAction) = [ - QGVAR(openMenu), localize LSTRING(openMenu), "", + QGVAR(openMenu), LLSTRING(openMenu), "", { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(interactionVehicle) = _target; @@ -73,56 +84,132 @@ GVAR(vehicleAction) = [ { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(enable) && - {(_target getVariable [QGVAR(hasCargo), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(hasCargo)) == 1])} && - {locked _target < 2} && - {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} && {alive _target} && - {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} + {locked _target < 2} && + {_target getVariable [QGVAR(hasCargo), getNumber (configOf _target >> QGVAR(hasCargo)) == 1]} && + {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && + {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && + {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} } ] call EFUNC(interact_menu,createAction); -GVAR(objectAction) = [ - QGVAR(load), localize LSTRING(loadObject), "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa", - { - params ["_target", "_player"]; - [_player, _target] call FUNC(startLoadIn); - }, - { - //IGNORE_PRIVATE_WARNING ["_target", "_player"]; - GVAR(enable) && - {(_target getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(canLoad))]) in [true, 1]} && - {locked _target < 2} && - {alive _target} && - {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && - {((nearestObjects [_target, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]) findIf { - private _hasCargoConfig = 1 == getNumber (configFile >> "CfgVehicles" >> typeOf _x >> QGVAR(hasCargo)); - private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; - (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} && {alive _x} && {locked _x < 2} && - {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} - }) > -1} - }, - LINKFUNC(addCargoVehiclesActions) -] call EFUNC(interact_menu,createAction); +GVAR(objectActions) = [ + [QGVAR(renameObject), LELSTRING(common,rename), "\a3\Modules_F_Curator\Data\iconMissionName_ca.paa", + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + GVAR(interactionVehicle) = _target; + createDialog QGVAR(renameMenu); + }, + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + GVAR(enable) && + {GVAR(enableRename)} && + {alive _target} && + {_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} && + {!(_target getVariable [QGVAR(noRename), getNumber (configOf _target >> QGVAR(noRename)) == 1])} && + {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && + {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} + } + ] call EFUNC(interact_menu,createAction), + [QGVAR(load), LLSTRING(loadObject), "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa", + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + [_player, _target] call FUNC(startLoadIn); + }, + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + GVAR(enable) && + {alive _target} && + {locked _target < 2} && + {_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} && + {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && + {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && + {((nearestObjects [_target, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) findIf { + _x != _target && + {alive _x} && + {locked _x < 2} && + {_x getVariable [QGVAR(hasCargo), getNumber (configOf _x >> QGVAR(hasCargo)) == 1]} && + {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} + }) != -1} + }, + LINKFUNC(addCargoVehiclesActions) + ] call EFUNC(interact_menu,createAction) +]; -// find all remaining configured classes and init them, see XEH_preStart.sqf +// Find all remaining configured classes and init them, see XEH_preStart.sqf private _vehicleClassesAddAction = call (uiNamespace getVariable [QGVAR(initializedVehicleClasses), {[]}]); + { [_x, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToClass); } forEach _vehicleClassesAddAction; + GVAR(initializedVehicleClasses) append _vehicleClassesAddAction; private _objectClassesAddAction = call (uiNamespace getVariable [QGVAR(initializedItemClasses), {[]}]); + { - [_x, 0, ["ACE_MainActions"], GVAR(objectAction)] call EFUNC(interact_menu,addActionToClass); + private _objectClass = _x; + + { + [_objectClass, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(objectActions); } forEach _objectClassesAddAction; + GVAR(initializedItemClasses) append _objectClassesAddAction; private _vehicleClassesAddClassEH = call (uiNamespace getVariable [QGVAR(vehicleClasses_classEH), {[]}]); + { [_x, "initPost", DFUNC(initVehicle), nil, nil, true] call CBA_fnc_addClassEventHandler; } forEach _vehicleClassesAddClassEH; private _objectClassesAddClassEH = call (uiNamespace getVariable [QGVAR(objectClasses_classEH), {[]}]); + { [_x, "initPost", DFUNC(initObject), nil, nil, true] call CBA_fnc_addClassEventHandler; } forEach _objectClassesAddClassEH; + +if (isServer) then { + ["ace_placedInBodyBag", { + params ["_target", "_bodyBag", "_isGrave"]; + + if (_isGrave) exitWith {}; // assume graves aren't cargo + + _bodyBag setVariable [QGVAR(customName), [_target, false, true] call EFUNC(common,getName), true]; + }] call CBA_fnc_addEventHandler; +}; + +// Set variables, even on machines without interfaces, just to be safe +GVAR(selectedItem) = objNull; +GVAR(itemPreviewObject) = objNull; +GVAR(deployPFH) = -1; +GVAR(deployDistance) = -1; +GVAR(deployDirection) = 0; +GVAR(deployHeight) = 0; +GVAR(canDeploy) = false; + +if (!hasInterface) exitWith {}; + +// Cancel object deployment if interact menu opened +["ace_interactMenuOpened", {ACE_player call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; + +// Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting +["unit", LINKFUNC(handleDeployInterrupt)] call CBA_fnc_addPlayerEventHandler; +["vehicle", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; +["weapon", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; + +// When changing feature cameras, stop deployment +["featureCamera", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; + +// Handle falling unconscious while trying to deploy +["ace_unconscious", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; + +// Handle surrendering and handcuffing +["ace_captiveStatusChanged", { + params ["_unit", "_state"]; + + // If surrendered or handcuffed, stop deployment + if (_state) then { + _unit call FUNC(handleDeployInterrupt); + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/cargo/XEH_preInit.sqf b/addons/cargo/XEH_preInit.sqf index 1b0894b77e..35f2d78e45 100644 --- a/addons/cargo/XEH_preInit.sqf +++ b/addons/cargo/XEH_preInit.sqf @@ -6,11 +6,17 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(initializedItemClasses) = []; GVAR(initializedVehicleClasses) = []; -GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"]; -GVAR(disableParadropEffectsClasstypes) = ["Car_F"]; +GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"] apply {_x call EFUNC(common,getConfigName)}; // make sure they are config case +GVAR(disableParadropEffectsClasstypes) = ["Car_F"] apply {_x call EFUNC(common,getConfigName)}; + +if (isServer) then { + ["All", "Deleted", LINKFUNC(handleDestroyed)] call CBA_fnc_addClassEventHandler; +}; + +["All", "Killed", LINKFUNC(handleDestroyed)] call CBA_fnc_addClassEventHandler; ADDON = true; diff --git a/addons/cargo/XEH_preStart.sqf b/addons/cargo/XEH_preStart.sqf index e7b3f5c59b..e5ef507556 100644 --- a/addons/cargo/XEH_preStart.sqf +++ b/addons/cargo/XEH_preStart.sqf @@ -2,36 +2,38 @@ #include "XEH_PREP.hpp" - -//See XEH_postInit.sqf +// See XEH_postInit.sqf private _vehicleClasses_addClassEH = ["ThingX", "LandVehicle", "Air", "Ship_F"]; private _objectClasses_addClassEH = ["ThingX", "StaticWeapon"]; private _vehicleClasses_addAction = []; private _itemClasses_addAction = []; +private _class = ""; -// find all remaining configured classes and init them +// Find all remaining configured classes and init them { - private _class = configName _x; - // init vehicle + _class = configName _x; + + // Init vehicle if ( - 1 == getNumber (_x >> QGVAR(hasCargo)) - && {-1 == _vehicleClasses_addClassEH findIf {_class isKindOf _x}} + getNumber (_x >> QGVAR(hasCargo)) == 1 && + {_vehicleClasses_addClassEH findIf {_class isKindOf _x} == -1} ) then { if (_class isKindOf "Static") then { - if (2 == getNumber (_x >> "scope")) then { + if (getNumber (_x >> "scope") == 2) then { _vehicleClasses_addAction pushBackUnique _class; }; } else { _vehicleClasses_addClassEH pushBackUnique _class; }; }; - // init object + + // Init object if ( - 1 == getNumber (_x >> QGVAR(canLoad)) - && {-1 == _objectClasses_addClassEH findIf {_class isKindOf _x}} + getNumber (_x >> QGVAR(canLoad)) == 1 && + {_objectClasses_addClassEH findIf {_class isKindOf _x} == -1} ) then { if (_class isKindOf "Static") then { - if (2 == getNumber (_x >> "scope")) then { + if (getNumber (_x >> "scope") == 2) then { _itemClasses_addAction pushBackUnique _class; }; } else { @@ -40,7 +42,6 @@ private _itemClasses_addAction = []; }; } forEach ("true" configClasses (configFile >> "CfgVehicles")); - uiNamespace setVariable [QGVAR(vehicleClasses_classEH), compileFinal str _vehicleClasses_addClassEH]; uiNamespace setVariable [QGVAR(objectClasses_classEH), compileFinal str _objectClasses_addClassEH]; uiNamespace setVariable [QGVAR(initializedVehicleClasses), compileFinal str _vehicleClasses_addAction]; diff --git a/addons/cargo/config.cpp b/addons/cargo/config.cpp index 31f01ffd72..2bdb3c7e65 100644 --- a/addons/cargo/config.cpp +++ b/addons/cargo/config.cpp @@ -19,3 +19,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "menu.hpp" +#include "renameMenu.hpp" diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index 8be00818c6..d5c7925a6f 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -1,29 +1,48 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Jonpas * Adds a cargo item to the vehicle. * * Arguments: - * 0: Item Classname - * 1: Vehicle + * 0: Item to be loaded or + * 1: Holder object (vehicle) * 2: Amount (default: 1) - * 3: Show Hint (default: false) + * 3: Ignore interaction distance and stability checks (default: false) * * Return Value: - * None + * Objects loaded * * Example: - * ["item", vehicle] call ace_cargo_fnc_addCargoItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_addCargoItem * * Public: No */ -params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]]]; -TRACE_3("params",_itemClass,_vehicle,_amount); +params ["_item", "_vehicle", ["_amount", 1], ["_ignoreInteraction", false]]; +TRACE_4("params",_item,_vehicle,_amount,_ignoreInteraction); -for "_i" from 1 to _amount do { - [_itemClass, _vehicle] call FUNC(loadItem); +private _loaded = 0; + +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); + + for "_i" from 1 to _amount do { + if !([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)) exitWith {}; + + _loaded = _loaded + 1; + }; +} else { + _loaded = parseNumber ([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)); + + _item = typeOf _item; }; +TRACE_1("loaded",_loaded); + // Invoke listenable event -["ace_cargoAdded", [_itemClass, _vehicle, _amount]] call CBA_fnc_globalEvent; +if (_loaded > 0) then { + ["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent; +}; + +_loaded // return diff --git a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf index d3a66794db..4aa18867d6 100644 --- a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf +++ b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf @@ -1,32 +1,34 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian - * Create actions for nearest vehicles with cargo. + * Creates actions for nearest vehicles with cargo. * * Arguments: - * 0: Target + * 0: Holder object (vehicle) * * Return Value: * Child actions * * Example: - * [cursorObject] call ace_cargo_fnc_addCargoVehiclesActions + * cursorObject call ace_cargo_fnc_addCargoVehiclesActions * * Public: No */ -params ["_target"]; +params ["_vehicle"]; private _statement = { - params ["_target", "_player", "_vehicle"]; - [_player, _target, _vehicle] call FUNC(startLoadIn); + params ["_item", "_loader", "_vehicle"]; + + [_loader, _item, _vehicle] call FUNC(startLoadIn); }; -private _vehicles = (nearestObjects [_target, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]) select { - private _hasCargoConfig = 1 == getNumber (configFile >> "CfgVehicles" >> typeOf _x >> QGVAR(hasCargo)); - private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; - (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} && {alive _x} && {locked _x < 2} && - {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} +private _vehicles = (nearestObjects [_vehicle, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) select { + _x != _vehicle && + {alive _x} && + {locked _x < 2} && + {_x getVariable [QGVAR(hasCargo), getNumber (configOf _x >> QGVAR(hasCargo)) == 1]} && + {([_vehicle, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} }; -[_vehicles, _statement, _target] call EFUNC(interact_menu,createVehiclesActions) +[_vehicles, _statement, _vehicle] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/cargo/functions/fnc_canLoadItemIn.sqf b/addons/cargo/functions/fnc_canLoadItemIn.sqf index f7bc696d35..6a45593297 100644 --- a/addons/cargo/functions/fnc_canLoadItemIn.sqf +++ b/addons/cargo/functions/fnc_canLoadItemIn.sqf @@ -1,45 +1,57 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal - * Check if item can be loaded into other Object. + * Checks if the item can be loaded into another object. * * Arguments: - * 0: Item - * 1: Holder Object (Vehicle) - * 2: Ignore interaction distance and stability checks + * 0: Item to be loaded or + * 1: Holder object (vehicle) + * 2: Ignore interaction distance and stability checks (default: false) * * Return Value: - * Can load in + * Can be loaded * * Example: - * [item, holder] call ace_cargo_fnc_canLoadItemIn + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_canLoadItemIn * * Public: No */ -params [["_item", "", [objNull,""]], "_vehicle", ["_ignoreInteraction", false]]; +params ["_item", "_vehicle", ["_ignoreInteraction", false]]; -if ((!_ignoreInteraction) && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith {TRACE_1("vehicle not stable",_vehicle); false}; +// Check if vehicle is stable +if (!_ignoreInteraction && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith { + TRACE_1("vehicle not stable",_vehicle); -if (_item isEqualType objNull && {{alive _x && {getText (configFile >> "CfgVehicles" >> typeOf _x >> "simulation") != "UAVPilot"}} count crew _item > 0}) exitWith { - TRACE_1("item is occupied",_item); - false + false // return }; -private _itemSize = [_item] call FUNC(getSizeItem); -private _validItem = false; -if (_item isEqualType "") then { - _validItem = - isClass (configFile >> "CfgVehicles" >> _item) && - {getNumber (configFile >> "CfgVehicles" >> _item >> QGVAR(canLoad)) == 1}; +// If there is crew that isn't UAV crew, exit +if (_item isEqualType objNull && {(crew _item) findIf {alive _x && {!unitIsUAV _x}} != -1}) exitWith { + TRACE_1("item is occupied",_item); + + false // return +}; + +private _itemSize = _item call FUNC(getSizeItem); + +private _validItem = if (_item isEqualType "") then { + private _config = configFile >> "CfgVehicles" >> _item; + + isClass _config && + {getNumber (_config >> QGVAR(canLoad)) == 1} } else { - _validItem = - (alive _item) && - {_ignoreInteraction || {([_item, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}}; + alive _item && + {_item getVariable [QGVAR(canLoad), getNumber (configOf _item >> QGVAR(canLoad)) == 1]} && + {_ignoreInteraction || {([_item, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} && + {!(_item getVariable [QEGVAR(cookoff,isCookingOff), false])} && // do not load items that are cooking off + {isNull (_item getVariable [QEGVAR(refuel,nozzle), objNull])} && // objects which have a refueling nozzle connected to them cannot be loaded + {isNull (_item getVariable [QEGVAR(refuel,ownedNozzle), objNull])} // fuel sources which have their nozzle out cannot be loaded }; _validItem && -{_itemSize > 0} && {alive _vehicle} && -{_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))} && -{locked _vehicle < 2} +{locked _vehicle < 2} && +{_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]} && +{_itemSize >= 0} && +{_itemSize <= (_vehicle call FUNC(getCargoSpaceLeft)) max 0} diff --git a/addons/cargo/functions/fnc_canUnloadItem.sqf b/addons/cargo/functions/fnc_canUnloadItem.sqf index 311f3cb36d..357ba78f21 100644 --- a/addons/cargo/functions/fnc_canUnloadItem.sqf +++ b/addons/cargo/functions/fnc_canUnloadItem.sqf @@ -1,30 +1,44 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, ViperMaul - * Check if item can be unloaded. + * Checks if the item can be unloaded from another object. * * Arguments: - * 0: loaded Object - * 1: Object - * 2: Unloader (player) (default: objNull) + * 0: Item to be unloaded or + * 1: Holder object (vehicle) + * 2: Unit doing the unloading (default: objNull) + * 3: Ignore interaction distance and stability checks (default: false) + * 4: Ignore finding a suitable position (default: false) * * Return Value: * Can be unloaded * * Example: - * [item, holder] call ace_cargo_fnc_canUnloadItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_canUnloadItem * * Public: No */ -params ["_item", "_vehicle", ["_unloader", objNull]]; +params ["_item", "_vehicle", ["_unloader", objNull], ["_ignoreInteraction", false], ["_ignoreFindPosition", false]]; TRACE_2("params",_item,_vehicle); -private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if !(_item in _loaded) exitWith {false}; +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; -private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item}; +if !(_item in (_vehicle getVariable [QGVAR(loaded), []])) exitWith {false}; -private _emptyPos = [_vehicle, _itemClass, _unloader] call EFUNC(common,findUnloadPosition); +private _validItem = if (_item isEqualType objNull) then { + alive _item +} else { + true +}; -(count _emptyPos) == 3 +_validItem && +{alive _vehicle} && +{locked _vehicle < 2} && +{_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]} && +{_item call FUNC(getSizeItem) >= 0} && +{_ignoreInteraction || {([_unloader, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} && +{_ignoreFindPosition || {([_vehicle, _item, _unloader, MAX_LOAD_DISTANCE, !_ignoreInteraction] call EFUNC(common,findUnloadPosition)) isNotEqualTo []}} diff --git a/addons/cargo/functions/fnc_deployCancel.sqf b/addons/cargo/functions/fnc_deployCancel.sqf new file mode 100644 index 0000000000..50ee62c457 --- /dev/null +++ b/addons/cargo/functions/fnc_deployCancel.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith + * Cancels unloading when deploying. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_deployCancel + * + * Public: No + */ + +if (GVAR(deployPFH) == -1) exitWith {}; + +// Remove deployment pfh +GVAR(deployPFH) call CBA_fnc_removePerFrameHandler; +GVAR(deployPFH) = -1; + +params ["_unit"]; + +// Enable running again +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + +// Delete placement dummy +deleteVehicle GVAR(itemPreviewObject); + +// Remove mouse button actions +call EFUNC(interaction,hideMouseHint); + +[_unit, "DefaultAction", _unit getVariable [QGVAR(deploy), -1]] call EFUNC(common,removeActionEventHandler); +_unit setVariable [QGVAR(deploy), -1]; + +_unit setVariable [QGVAR(isDeploying), false, true]; diff --git a/addons/cargo/functions/fnc_deployConfirm.sqf b/addons/cargo/functions/fnc_deployConfirm.sqf new file mode 100644 index 0000000000..27674b0515 --- /dev/null +++ b/addons/cargo/functions/fnc_deployConfirm.sqf @@ -0,0 +1,56 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith + * Confirms unloading when deploying. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_deployConfirm + * + * Public: No + */ + +if (GVAR(deployPFH) == -1) exitWith {}; + +params ["_unit"]; + +// Delete placement dummy and unload real item from cargo at dummy position +if (!isNull GVAR(itemPreviewObject) && {[GVAR(selectedItem), GVAR(interactionVehicle), _unit, false, true] call FUNC(canUnloadItem)}) then { + // Position is AGL for unloading event + private _position = ASLToAGL getPosASL GVAR(itemPreviewObject); + private _direction = getDir GVAR(itemPreviewObject); + private _duration = GVAR(loadTimeCoefficient) * (GVAR(selectedItem) call FUNC(getSizeItem)); + + // If unload time is 0, don't show a progress bar + if (_duration <= 0) exitWith { + ["ace_unloadCargo", [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]]] call CBA_fnc_localEvent; + }; + + [ + _duration, + [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]], + { + TRACE_1("deploy finish",_this); + + ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent; + }, + { + TRACE_1("deploy fail",_this); + }, + format [LLSTRING(unloadingItem), [GVAR(selectedItem), true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], + { + (_this select 0) params ["_item", "_vehicle", "_unit"]; + + [_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem) // don't check for a suitable unloading position when deploying + }, + ["isNotSwimming"] + ] call EFUNC(common,progressBar); +}; + +// Cleanup EHs and preview object +_unit call FUNC(deployCancel); diff --git a/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf b/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf index d9452d4b01..e797b0820d 100644 --- a/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf +++ b/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf @@ -1,21 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal - * Get the cargo space left on object. + * Gets the object's remaining cargo space. * * Arguments: - * 0: Object + * 0: Holder object (vehicle) * * Return Value: * Cargo space left * * Example: - * [object] call ace_cargo_fnc_getCargoSpaceLeft + * cursorObject call ace_cargo_fnc_getCargoSpaceLeft * * Public: No */ -params ["_object"]; -// TRACE_1("params",_object); +params ["_vehicle"]; -(_object getVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeOf _object >> QGVAR(space))]) max 0 +_vehicle getVariable [QGVAR(space), getNumber (configOf _vehicle >> QGVAR(space))] diff --git a/addons/cargo/functions/fnc_getNameItem.sqf b/addons/cargo/functions/fnc_getNameItem.sqf new file mode 100644 index 0000000000..b71ae073cb --- /dev/null +++ b/addons/cargo/functions/fnc_getNameItem.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: JasperRab + * Gets the name of the item, and alternatively the custom name if requested and available. + * + * Arguments: + * 0: Item or (default: "") + * 1: Add custom name (default: false) + * + * Return Value: + * Item name + * + * Example: + * cursorObject call ace_cargo_fnc_getNameItem + * + * Public: Yes + */ + +params [["_item", "", [objNull, ""]], ["_addCustomName", false, [false]]]; + +private _displayName = if (_item isEqualType "") then { + getText (configFile >> "CfgVehicles" >> _item >> "displayName") +} else { + getText (configOf _item >> "displayName") +}; + +if (_addCustomName && {_item isEqualType objNull}) then { + private _customName = _item getVariable [QGVAR(customName), ""]; + + if (_customName isNotEqualTo "") then { + _displayName = _displayName + " [" + _customName + "]"; + }; +}; + +_displayName diff --git a/addons/cargo/functions/fnc_getSelectedItem.sqf b/addons/cargo/functions/fnc_getSelectedItem.sqf new file mode 100644 index 0000000000..a6f9141ae1 --- /dev/null +++ b/addons/cargo/functions/fnc_getSelectedItem.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, Smith + * Get selected item from cargo menu. + * + * Arguments: + * None + * + * Return Value: + * Classname of selected item or selected object or (default: nil) + * + * Example: + * call ace_cargo_fnc_getSelectedItem + * + * Public: No + */ + +disableSerialization; + +private _display = uiNamespace getVariable QGVAR(menuDisplay); + +if (isNil "_display") exitWith {}; + +private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; + +if (_loaded isEqualTo []) exitWith {}; + +// This can be an object or a classname string +_loaded param [lbCurSel (_display displayCtrl 100), nil] diff --git a/addons/cargo/functions/fnc_getSizeItem.sqf b/addons/cargo/functions/fnc_getSizeItem.sqf index 5d66e59b72..bf049b71b3 100644 --- a/addons/cargo/functions/fnc_getSizeItem.sqf +++ b/addons/cargo/functions/fnc_getSizeItem.sqf @@ -1,29 +1,25 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal, SilentSpike - * Get the cargo size of an object. + * Author: Glowbal, kymckay + * Gets the cargo size of an object. * * Arguments: - * 0: Item + * 0: Item or * * Return Value: * Cargo size (default: -1) * * Example: - * [object] call ace_cargo_fnc_getSizeItem + * cursorObject call ace_cargo_fnc_getSizeItem * * Public: No */ params ["_item"]; -// Virtual items are much easier to deal with +// Default cargo size is -1 as 0 is a valid size if (_item isEqualType "") then { - CARGO_SIZE(_item) + GET_NUMBER(configFile >> "CfgVehicles" >> _item >> QGVAR(size),-1) } else { - if (isNil {_item getVariable QGVAR(size)}) then { - CARGO_SIZE(typeOf _item) - } else { - _item getVariable QGVAR(size) - }; + _item getVariable [QGVAR(size), GET_NUMBER(configOf _item >> QGVAR(size),-1)] }; diff --git a/addons/cargo/functions/fnc_handleDeployInterrupt.sqf b/addons/cargo/functions/fnc_handleDeployInterrupt.sqf new file mode 100644 index 0000000000..2cb712b5e0 --- /dev/null +++ b/addons/cargo/functions/fnc_handleDeployInterrupt.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, Smith + * Handle various interruption types. + * + * Arguments: + * 0: (New) unit + * 1: Old unit (for player change) (default: objNull) + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_handleDeployInterrupt + * + * Public: No +*/ + +params ["_newPlayer", ["_oldPlayer", objNull]]; +TRACE_2("params",_newPlayer,_oldPlayer); + +if (!local _newPlayer) exitWith {}; + +if (_newPlayer getVariable [QGVAR(isDeploying), false]) then { + _newPlayer call FUNC(deployCancel); +}; + +if (_oldPlayer getVariable [QGVAR(isDeploying), false]) then { + _oldPlayer call FUNC(deployCancel); +}; diff --git a/addons/cargo/functions/fnc_handleDestroyed.sqf b/addons/cargo/functions/fnc_handleDestroyed.sqf index 2818e71e07..cc5777723d 100644 --- a/addons/cargo/functions/fnc_handleDestroyed.sqf +++ b/addons/cargo/functions/fnc_handleDestroyed.sqf @@ -1,7 +1,9 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal - * Handle object being destroyed. Only runs on server. + * Author: mharis001, Glowbal + * Handles an object being destroyed/deleted. + * If object contained loaded cargo, the cargo is deleted. + * If object was loaded cargo, it's removed from loaded cargo list. * * Arguments: * 0: Object @@ -10,23 +12,34 @@ * None * * Example: - * [object] call ace_cargo_fnc_handleDestroyed + * cursorObject call ace_cargo_fnc_handleDestroyed * * Public: No */ -params ["_vehicle"]; -TRACE_1("params",_vehicle); +params ["_object"]; -private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if (_loaded isEqualTo []) exitWith {}; +private _loaded = _object getVariable [QGVAR(loaded), []]; -{ - // TODO Do we want to be able to recover destroyed equipment? - if (_x isEqualType objNull) then { - deleteVehicle _x; - }; - nil -} count _loaded; +if (_loaded isNotEqualTo []) then { + // Delete all cargo + { + if (_x isEqualType objNull) then { + detach _x; + deleteVehicle _x; + }; + } forEach _loaded; -[_vehicle] call FUNC(validateCargoSpace); + // In case vehicle is killed, but not deleted, reset loaded list + _object setVariable [QGVAR(loaded), [], true]; +}; + +// Update remaining cargo space, if loaded as cargo in a vehicle +private _vehicle = attachedTo _object; + +if (!isNull _vehicle && {_object in (_vehicle getVariable [QGVAR(loaded), []])}) then { + private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); + private _itemSize = (_object call FUNC(getSizeItem)) max 0; // don't let negative size items increase space + + _vehicle setVariable [QGVAR(space), _cargoSpace + _itemSize, true]; +}; diff --git a/addons/cargo/functions/fnc_handleScrollWheel.sqf b/addons/cargo/functions/fnc_handleScrollWheel.sqf new file mode 100644 index 0000000000..9ec2c498e6 --- /dev/null +++ b/addons/cargo/functions/fnc_handleScrollWheel.sqf @@ -0,0 +1,58 @@ +#include "..\script_component.hpp" +/* + * Author: L-H, commy2, Smith + * Handles rotation of object to unload. + * + * Arguments: + * 0: Scroll amount + * + * Return Value: + * If the scroll was handled + * + * Example: + * 1.2 call ace_cargo_fnc_handleScrollWheel + * + * Public: No + */ + +if (GVAR(deployPFH) == -1) exitWith {false}; + +params ["_scrollAmount"]; + +private _deployedItem = GVAR(itemPreviewObject); + +if (!CBA_events_control) then { + private _unit = ACE_player; + + // Raise/lower + // Move deployed item 15 cm per scroll interval + _scrollAmount = _scrollAmount * 0.15; + + private _position = getPosASL _deployedItem; + private _maxHeight = (_unit modelToWorldVisualWorld [0, 0, 0]) select 2; + + _position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) max _maxHeight]; + + // Move up/down object and reattach at current position + detach _deployedItem; + + // Uses this method of selecting position because setPosATL did not have immediate effect + private _positionChange = _position vectorDiff (getPosASL _deployedItem); + private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _deployedItem); + _selectionPosition = _selectionPosition vectorAdd _positionChange; + _deployedItem attachTo [_unit, _selectionPosition]; + + // Reset the deploy direction + private _direction = _deployedItem getVariable [QGVAR(deployDirection_temp), 0]; + _deployedItem setDir _direction; +} else { + // Rotate + private _direction = _deployedItem getVariable [QGVAR(deployDirection_temp), 0]; + _scrollAmount = _scrollAmount * 10; + _direction = _direction + _scrollAmount; + + _deployedItem setDir _direction; + _deployedItem setVariable [QGVAR(deployDirection_temp), _direction]; +}; + +true diff --git a/addons/cargo/functions/fnc_initObject.sqf b/addons/cargo/functions/fnc_initObject.sqf index 611e3e6391..734fe99c39 100644 --- a/addons/cargo/functions/fnc_initObject.sqf +++ b/addons/cargo/functions/fnc_initObject.sqf @@ -1,49 +1,60 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal, SilentSpike + * Author: Glowbal, kymckay * Initializes variables for loadable objects. Called from init EH. * * Arguments: - * 0: Object + * 0: Item * * Return Value: * None * * Example: - * [object] call ace_cargo_fnc_initObject + * cursorObject call ace_cargo_fnc_initObject * * Public: No */ -params ["_object"]; -private _type = typeOf _object; -TRACE_2("params",_object,_type); +// Dedicated servers and HCs do not require action menus +if (!hasInterface) exitWith {}; -// If object had size given to it via eden/public then override config canLoad setting -private _canLoadPublic = _object getVariable [QGVAR(canLoad), false]; -if (!(_canLoadPublic isEqualType false)) then { - WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_object,_type,QGVAR(canLoad),_canLoadPublic); +params ["_item"]; +private _type = typeOf _item; +TRACE_2("params",_item,_type); + +// If object had size given to it via eden/public, then override config canLoad setting +private _canLoadPublic = _item getVariable QGVAR(canLoad); +private _canLoadPublicDefined = !isNil "_canLoadPublic"; + +if (_canLoadPublicDefined && {!(_canLoadPublic isEqualType false)}) then { + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_item,_type,QGVAR(canLoad),_canLoadPublic); }; -private _canLoadConfig = getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(canLoad)) == 1; + +private _canLoadConfig = getNumber (configOf _item >> QGVAR(canLoad)) == 1; // Nothing to do here if object can't be loaded -if !(_canLoadConfig || {_canLoadPublic in [true, 1]}) exitWith {}; - -// Servers and HCs do not require action menus (beyond this point) -if !(hasInterface) exitWith {}; +if !((_canLoadPublicDefined && {_canLoadPublic in [true, 1]}) || {!_canLoadPublicDefined && {_canLoadConfig}}) exitWith {}; // Unnecessary to add actions to an object class that's already got them if (_type in GVAR(initializedItemClasses)) exitWith {}; -if (_object getVariable [QGVAR(initObject),false]) exitWith {}; +if (_item getVariable [QGVAR(initObject),false]) exitWith {}; // Objects given size via eden have their actions added to the object // So this function may run for multiple of the same class in that case if (_canLoadConfig) then { GVAR(initializedItemClasses) pushBack _type; - TRACE_1("Adding load cargo action to class", _type); - [_type, 0, ["ACE_MainActions"], GVAR(objectAction)] call EFUNC(interact_menu,addActionToClass); + + TRACE_1("Adding load cargo action to class",_type); + + { + [_type, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(objectActions); } else { - _object setVariable [QGVAR(initObject),true]; - TRACE_1("Adding load cargo action to object", _object); - [_object, 0, ["ACE_MainActions"], GVAR(objectAction)] call EFUNC(interact_menu,addActionToObject); + _item setVariable [QGVAR(initObject), true]; + + TRACE_1("Adding load cargo action to object",_item); + + { + [_item, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToObject); + } forEach GVAR(objectActions); }; diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index 60f204cb75..25cebe5b13 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Initializes vehicle, adds open cargo menu action if available. @@ -10,61 +10,85 @@ * None * * Example: - * [vehicle] call ace_cargo_fnc_initVehicle + * cursorObject call ace_cargo_fnc_initVehicle * * Public: No */ params ["_vehicle"]; -TRACE_1("params", _vehicle); +TRACE_1("params",_vehicle); private _type = typeOf _vehicle; +private _config = configOf _vehicle; -// If vehicle had space given to it via eden/public then override config hasCargo setting -private _hasCargoPublic = _vehicle getVariable [QGVAR(hasCargo), false]; -private _hasCargoConfig = getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(hasCargo)) == 1; +// If vehicle had space given to it via eden/public, then override config hasCargo setting +private _hasCargoPublic = _vehicle getVariable QGVAR(hasCargo); +private _hasCargoPublicDefined = !isNil "_hasCargoPublic"; + +if (_hasCargoPublicDefined && {!(_hasCargoPublic isEqualType false)}) then { + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_vehicle,_type,QGVAR(hasCargo),_hasCargoPublic); +}; + +private _hasCargoConfig = getNumber (_config >> QGVAR(hasCargo)) == 1; // Nothing to do here if vehicle has no cargo space -if !(_hasCargoConfig || _hasCargoPublic) exitWith {}; +if !((_hasCargoPublicDefined && {_hasCargoPublic in [true, 1]}) || {!_hasCargoPublicDefined && {_hasCargoConfig}}) exitWith {}; // Check if cargo is in cargo holder types (checked when trying to search for loadable objects) -private _addCargoType = true; -{ - if (_type isKindOf _x) exitWith {_addCargoType = false}; -} forEach GVAR(cargoHolderTypes); +private _addCargoType = GVAR(cargoHolderTypes) findIf {_type isKindOf _x} == -1; + TRACE_2("",_addCargoType,_type); + if (_addCargoType) then { GVAR(cargoHolderTypes) pushBack _type; }; -// Vehicle can have default ace cargo in its config +// If already initialised (both actions and cargo), then skip +if (_vehicle getVariable [QGVAR(initVehicle), false]) exitWith {}; + +// Vehicles can have default ace cargo in their config if (isServer) then { + _vehicle setVariable [QGVAR(initVehicle), true]; + + private _cargoClassname = ""; + private _cargoCount = 0; + private _loaded = 0; + { - if (isClass _x) then { - private _cargoClassname = getText (_x >> "type"); - private _cargoCount = getNumber (_x >> "amount"); - TRACE_3("adding ACE_Cargo", (configName _x), _cargoClassname, _cargoCount); - ["ace_addCargo", [_cargoClassname, _vehicle, _cargoCount]] call CBA_fnc_localEvent; + _cargoClassname = getText (_x >> "type"); + _cargoCount = getNumber (_x >> "amount"); + + TRACE_3("adding ace_cargo",configName _x,_cargoClassname,_cargoCount); + + // Ignore stability check (distance check is also ignored with this, but it's ignored by default if item is a string) + _loaded = [_cargoClassname, _vehicle, _cargoCount, true] call FUNC(addCargoItem); + + // Let loop continue until the end, so that it prints everything into the rpt (there might be smaller items that could still fit in cargo) + if (_loaded != _cargoCount) then { + WARNING_5("%1 (%2) could not fit %3 %4 inside its cargo, only %5 were loaded.",_vehicle,_type,_cargoCount,_cargoClassname,_loaded); }; - } count ("true" configClasses (configFile >> "CfgVehicles" >> _type >> "ACE_Cargo" >> "Cargo")); + } forEach ("true" configClasses (_config >> QUOTE(ADDON) >> "cargo")); }; // Servers and HCs do not require action menus (beyond this point) -if !(hasInterface) exitWith {}; +if (!hasInterface) exitWith {}; // Unnecessary to add actions to a vehicle class that's already got them if (_type in GVAR(initializedVehicleClasses)) exitWith {}; -if (_vehicle getVariable [QGVAR(initVehicle),false]) exitWith {}; // Vehicles given cargo via eden have their actions added to the object // So this function may run for multiple of the same class in that case if (_hasCargoConfig) then { GVAR(initializedVehicleClasses) pushBack _type; - TRACE_1("Adding unload cargo action to class", _type); + + TRACE_1("Adding unload cargo action to class",_type); + [_type, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToClass); } else { - _vehicle setVariable [QGVAR(initVehicle),true]; - TRACE_1("Adding unload cargo action to object", _vehicle); + _vehicle setVariable [QGVAR(initVehicle), true]; + + TRACE_1("Adding unload cargo action to object",_vehicle); + [_vehicle, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToObject); }; @@ -72,24 +96,31 @@ if (_hasCargoConfig) then { if (_vehicle isKindOf "Air") then { private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; - GVAR(enable) && {[_player, _target, []] call EFUNC(common,canInteractWith)} && { - private _turretPath = _player call CBA_fnc_turretPath; - (_player == (driver _target)) || // pilot - {(getNumber (([_target, _turretPath] call CBA_fnc_getTurret) >> "isCopilot")) == 1} || // coPilot - {_turretPath in (getArray (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(loadmasterTurrets)))}} // loadMaster turret from config + GVAR(enable) && + {[_player, _target, []] call EFUNC(common,canInteractWith)} && { + private _turretPath = _target unitTurret _player; + + (_player == currentPilot _target) || // Pilot/Co-pilot + {(getNumber ([_target, _turretPath] call CBA_fnc_getTurret >> "isCopilot")) == 1} || // Co-pilot + {_turretPath in (getArray (configOf _target >> QGVAR(loadmasterTurrets)))} + } }; + private _statement = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(interactionVehicle) = _target; GVAR(interactionParadrop) = true; createDialog QGVAR(menu); }; - private _text = localize LSTRING(openMenu); + + private _text = LLSTRING(openMenu); private _icon = ""; private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction); + + // Self action on the vehicle if (_hasCargoConfig) then { - [_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); // self action on the vehicle + [_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); } else { [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); }; diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index 73056ef43f..21ebc0d52a 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -1,27 +1,36 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal - * Load object into vehicle. + * Loads an object into a vehicle. * Objects loaded via classname remain virtual until unloaded. * * Arguments: - * 0: Item - * 1: Vehicle - * 2: Ignore interaction distance and stability checks + * 0: Item to be loaded or (default: "") + * 1: Holder object (vehicle) (default: objNull) + * 2: Ignore interaction distance and stability checks (default: false) * * Return Value: * Object loaded * * Example: - * [object, vehicle] call ace_cargo_fnc_loadItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_loadItem * * Public: Yes */ -params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]], ["_ignoreInteraction", false]]; -TRACE_2("params",_item,_vehicle); +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_ignoreInteraction", false, [false]]]; +TRACE_3("params",_item,_vehicle,_ignoreInteraction); -if !([_item, _vehicle, _ignoreInteraction] call FUNC(canLoadItemIn)) exitWith {TRACE_2("cannot load",_item,_vehicle); false}; +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; + +if !([_item, _vehicle, _ignoreInteraction] call FUNC(canLoadItemIn)) exitWith { + TRACE_3("cannot load",_item,_vehicle,_ignoreInteraction); + + false // return +}; private _loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded pushBack _item; @@ -29,20 +38,33 @@ _vehicle setVariable [QGVAR(loaded), _loaded, true]; TRACE_1("added to loaded array",_loaded); -private _space = [_vehicle] call FUNC(getCargoSpaceLeft); -private _itemSize = [_item] call FUNC(getSizeItem); -_vehicle setVariable [QGVAR(space), _space - _itemSize, true]; +// Update cargo space remaining +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +private _itemSize = (_item call FUNC(getSizeItem)) max 0; // don't let negative size items increase space +_vehicle setVariable [QGVAR(space), _cargoSpace - _itemSize, true]; +// Attach object 100m below vehicle if (_item isEqualType objNull) then { detach _item; - _item attachTo [_vehicle,[0,0,-100]]; + _item attachTo [_vehicle, [0, 0, -100]]; [QEGVAR(common,hideObjectGlobal), [_item, true]] call CBA_fnc_serverEvent; - - // Cars below water will take engine damage over time and eventualy become "water logged" and unfixable (because of negative z attach) - if ((getText (configFile >> "CfgVehicles" >> (typeOf _item) >> "simulation")) == "carx") then { - TRACE_1("disabling car damage",_item); - [_item, "blockDamage", "ACE_cargo", true] call EFUNC(common,statusEffect_set); + + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + private _objectCurators = objectCurators _item; + + // Save which curators had this object as editable + _item setVariable [QGVAR(objectCurators), _objectCurators, true]; + + if (_objectCurators isEqualTo []) exitWith {}; + + [QEGVAR(zeus,removeObjects), [[_item], _objectCurators]] call CBA_fnc_serverEvent; }; + + // Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach) + [_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; -true +// Invoke listenable event +["ace_cargoLoaded", [_item, _vehicle]] call CBA_fnc_globalEvent; + +true // return diff --git a/addons/cargo/functions/fnc_moduleSettings.sqf b/addons/cargo/functions/fnc_moduleSettings.sqf index ce73678e9e..9c337364b1 100644 --- a/addons/cargo/functions/fnc_moduleSettings.sqf +++ b/addons/cargo/functions/fnc_moduleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Module for adjusting the cargo settings @@ -12,7 +12,7 @@ * None * * Example: - * function = "ace_cargo_fnc_loadItem" + * [] call ace_cargo_fnc_moduleSettings * * Public: No */ diff --git a/addons/cargo/functions/fnc_onMenuOpen.sqf b/addons/cargo/functions/fnc_onMenuOpen.sqf index d611d18ff2..f99999aabf 100644 --- a/addons/cargo/functions/fnc_onMenuOpen.sqf +++ b/addons/cargo/functions/fnc_onMenuOpen.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal - * Handle the UI data display. + * Handles the UI data display. * * Arguments: * 0: Display @@ -10,7 +10,7 @@ * None * * Example: - * [display] call ace_cargo_fnc_onMenuOpen + * display call ace_cargo_fnc_onMenuOpen * * Public: No */ @@ -22,37 +22,81 @@ params ["_display"]; uiNamespace setVariable [QGVAR(menuDisplay), _display]; if (GVAR(interactionParadrop)) then { - (_display displayCtrl 12) ctrlSetText (localize LSTRING(paradropButton)); + (_display displayCtrl 12) ctrlSetText LLSTRING(paradropButton); }; +// Disable deploy option if paradropping or in Zeus +(_display displayCtrl 13) ctrlEnable (GVAR(enableDeploy) && !GVAR(interactionParadrop) && {isNull curatorCamera}); + [{ + params ["_vehicle", "_pfhID"]; + disableSerialization; + private _display = uiNamespace getVariable QGVAR(menuDisplay); - if (isnil "_display") exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + + if (isNil "_display") exitWith { + GVAR(interactionParadrop) = nil; + + _pfhID call CBA_fnc_removePerFrameHandler; }; - if (isNull GVAR(interactionVehicle) || {(([ACE_player, GVAR(interactionVehicle)] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE) && {(vehicle ACE_player) != GVAR(interactionVehicle)}}) exitWith { + // Close menu if in invalid state + if ( + !alive ACE_player || + {!alive _vehicle} || + {locked _vehicle >= 2} || + {!(_vehicle getVariable [QGVAR(hasCargo), true])} || // if the cargo menu could be opened, the vehicle has QGVAR(hasCargo) in its config or the variable is set using FUNC(setSpace) + { + isNull curatorCamera && // if in Zeus, ignore the checks that follow + {([ACE_player, _vehicle] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE} && + {(vehicle ACE_player) != _vehicle} + } + ) exitWith { closeDialog 0; - [_this select 1] call CBA_fnc_removePerFrameHandler; + + GVAR(interactionParadrop) = nil; + + _pfhID call CBA_fnc_removePerFrameHandler; }; - private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; private _ctrl = _display displayCtrl 100; private _label = _display displayCtrl 2; + // Remove previous entries lbClear _ctrl; + + // Display item names + private _displayName = ""; + private _itemSize = 0; + private _index = -1; + private _damageStr = "0%"; + private _damage = 0; + { - private _class = if (_x isEqualType "") then {_x} else {typeOf _x}; - private _displayName = getText (configfile >> "CfgVehicles" >> _class >> "displayName"); - if (GVAR(interactionParadrop)) then { - _ctrl lbAdd format ["%1 (%2s)", _displayName, GVAR(paradropTimeCoefficent) * ([_class] call FUNC(getSizeItem))]; + _displayName = [_x, true] call FUNC(getNameItem); + _itemSize = _x call FUNC(getSizeItem); + _damage = if (_x isEqualType "") then {0} else {damage _x}; + _damageStr = ((_damage * 100) toFixed 0) + "%"; + + if (_itemSize >= 0) then { + _index = if (GVAR(interactionParadrop)) then { + _ctrl lbAdd format ["%1. %2 (%3s)", _forEachIndex + 1, _displayName, GVAR(paradropTimeCoefficent) * _itemSize] + } else { + _ctrl lbAdd format ["%1. %2", _forEachIndex + 1, _displayName] + }; + + private _tooltip = format ["%1\n%2", format [LLSTRING(sizeMenu), _itemSize], format ["%1: %2", localize "str_a3_normaldamage1", _damageStr]]; + _ctrl lbSetTooltip [_index, _tooltip]; } else { - _ctrl lbAdd _displayName; + // If item has a size < 0, it means it's not loadable + _index = _ctrl lbAdd _displayName; + + _ctrl lbSetTooltip [_index, LLSTRING(unloadingImpossible)]; + _ctrl lbSetColor [_index, [1, 0, 0, 1]]; // set text to red + _ctrl lbSetSelectColor [_index, [1, 0, 0, 1]]; }; + } forEach (_vehicle getVariable [QGVAR(loaded), []]); - true - } count _loaded; - - _label ctrlSetText format[localize LSTRING(labelSpace), [GVAR(interactionVehicle)] call DFUNC(getCargoSpaceLeft)]; -}, 0, []] call CBA_fnc_addPerFrameHandler; + _label ctrlSetText format [LLSTRING(labelSpace), (_vehicle call FUNC(getCargoSpaceLeft)) max 0]; +}, 0, GVAR(interactionVehicle)] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index 4c873d189e..acd780f463 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -1,18 +1,18 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: marc_book, commy2, CAA-Picard - * Unload and paradrop object from plane or helicopter. + * Unloads and paradrops an object from a plane or helicopter. * * Arguments: - * 0: Object - * 1: Vehicle + * 0: Item or + * 1: Holder object (vehicle) * 2: Show Hint (default: true) * * Return Value: * Object unloaded * * Example: - * [object, vehicle] call ace_cargo_fnc_paradropItem + * ["ACE_Wheel", vehicle player] call ace_cargo_fnc_paradropItem * * Public: No */ @@ -20,93 +20,114 @@ params ["_item", "_vehicle", ["_showHint", true]]; TRACE_2("params",_item,_vehicle); +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; + +// Check if item is actually part of cargo private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if !(_item in _loaded) exitWith {false}; +if !(_item in _loaded) exitWith { + false // return +}; -// unload item from cargo +// Check if item can be unloaded +private _itemSize = _item call FUNC(getSizeItem); + +if (_itemSize < 0) exitWith { + false // return +}; + +// Unload item from cargo _loaded deleteAt (_loaded find _item); _vehicle setVariable [QGVAR(loaded), _loaded, true]; -private _cargoSpace = [_vehicle] call FUNC(getCargoSpaceLeft); -private _itemSize = [_item] call FUNC(getSizeItem); -_vehicle setVariable [QGVAR(space), (_cargoSpace + _itemSize), true]; +// Update cargo space remaining +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _cargoSpace + _itemSize, true]; (boundingBoxReal _vehicle) params ["_bb1", "_bb2"]; private _distBehind = ((_bb1 select 1) min (_bb2 select 1)) - 4; // 4 meters behind max bounding box -TRACE_1("",_distBehind); private _posBehindVehicleAGL = _vehicle modelToWorld [0, _distBehind, -2]; +TRACE_1("",_distBehind); + +private _object = _item; + +if (_item isEqualType objNull) then { + detach _object; -private _itemObject = if (_item isEqualType objNull) then { - detach _item; // hideObjectGlobal must be executed before setPos to ensure light objects are rendered correctly - // do both on server to ensure they are executed in the correct order - [QGVAR(serverUnload), [_item, _posBehindVehicleAGL]] call CBA_fnc_serverEvent; - _item + // Do both on server to ensure they are executed in the correct order + [QGVAR(serverUnload), [_object, _posBehindVehicleAGL]] call CBA_fnc_serverEvent; } else { - private _newItem = createVehicle [_item, _posBehindVehicleAGL, [], 0, "NONE"]; - _newItem setPosASL (AGLtoASL _posBehindVehicleAGL); - _newItem + _object = createVehicle [_item, _posBehindVehicleAGL, [], 0, "NONE"]; + _object setPosASL (AGLtoASL _posBehindVehicleAGL); }; -_itemObject setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply -5)); +[QEGVAR(common,setVelocity), [_object, (velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply -5)], _object] call CBA_fnc_targetEvent; -// open parachute and ir light effect +// Open parachute and IR light effect [{ - params ["_item"]; + params ["_object"]; - if (isNull _item || {getPos _item select 2 < 1}) exitWith {}; + if (isNull _object || {getPos _object select 2 < 1}) exitWith {}; - private _parachute = createVehicle ["B_Parachute_02_F", [0,0,0], [], 0, "CAN_COLLIDE"]; + private _parachute = createVehicle ["B_Parachute_02_F", [0, 0, 0], [], 0, "CAN_COLLIDE"]; - // cannot use setPos on parachutes without them closing down - _parachute attachTo [_item, [0,0,0]]; + // Prevent collision damage + [QEGVAR(common,fixCollision), _parachute] call CBA_fnc_localEvent; + [QEGVAR(common,fixCollision), _object, _object] call CBA_fnc_targetEvent; + + // Cannot use setPos on parachutes without them closing down + _parachute attachTo [_object, [0, 0, 0]]; detach _parachute; - private _velocity = velocity _item; + private _velocity = velocity _object; - _item attachTo [_parachute, [0,0,1]]; + // Attach to the middle of the object + (2 boundingBoxReal _object) params ["_bb1", "_bb2"]; + + _object attachTo [_parachute, [0, 0, ((_bb2 select 2) - (_bb1 select 2)) / 2]]; _parachute setVelocity _velocity; - if ((GVAR(disableParadropEffectsClasstypes) findIf {_item isKindOf _x}) == -1) then { - private _light = "Chemlight_yellow" createVehicle [0,0,0]; - _light attachTo [_item, [0,0,0]]; + if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then { + private _light = "Chemlight_yellow" createVehicle [0, 0, 0]; + _light attachTo [_object, [0, 0, 0]]; }; +}, _object, 0.7] call CBA_fnc_waitAndExecute; -}, [_itemObject], 0.7] call CBA_fnc_waitAndExecute; - -// smoke effect when crate landed +// Create smoke effect when crate landed [{ - (_this select 0) params ["_item"]; + (_this select 0) params ["_object"]; - if (isNull _item) exitWith { + if (isNull _object) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - if (getPos _item select 2 < 1) then { - if ((GVAR(disableParadropEffectsClasstypes) findIf {_item isKindOf _x}) == -1) then { - private _smoke = "SmokeshellYellow" createVehicle [0,0,0]; - _smoke attachTo [_item, [0,0,0]]; + if (getPos _object select 2 < 1) exitWith { + [_this select 1] call CBA_fnc_removePerFrameHandler; + + if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then { + private _smoke = "SmokeshellYellow" createVehicle [0, 0, 0]; + _smoke attachTo [_object, [0, 0, 0]]; }; - - [_this select 1] call CBA_fnc_removePerFrameHandler; }; - -}, 1, [_itemObject]] call CBA_fnc_addPerFrameHandler; +}, 1, _object] call CBA_fnc_addPerFrameHandler; if (_showHint) then { [ [ - LSTRING(UnloadedItem), - getText (configFile >> "CfgVehicles" >> typeOf _itemObject >> "displayName"), - getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName") + LSTRING(unloadedItem), + [_object, true] call FUNC(getNameItem), + getText (configOf _vehicle >> "displayName") ], 3 ] call EFUNC(common,displayTextStructured); }; // Invoke listenable event -["ace_cargoUnloaded", [_item, _vehicle, "paradrop"]] call CBA_fnc_globalEvent; +["ace_cargoUnloaded", [_object, _vehicle, "paradrop"]] call CBA_fnc_globalEvent; -true +true // return diff --git a/addons/cargo/functions/fnc_removeCargoItem.sqf b/addons/cargo/functions/fnc_removeCargoItem.sqf index ede9c68c94..6e95893992 100644 --- a/addons/cargo/functions/fnc_removeCargoItem.sqf +++ b/addons/cargo/functions/fnc_removeCargoItem.sqf @@ -1,26 +1,31 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Removes a cargo item from the vehicle. * * Arguments: - * 0: Item or - * 1: Vehicle + * 0: Item to be removed or (default: "") + * 1: Holder object (vehicle) (default: objNull) * 2: Amount (default: 1) * * Return Value: * Number of items removed * * Example: - * ["ACE_Wheel", vehicle, 2] call ace_cargo_fnc_removeCargoItem + * ["ACE_Wheel", cursorObject, 2] call ace_cargo_fnc_removeCargoItem * [crate_7, truck] call ace_cargo_fnc_removeCargoItem * * Public: Yes */ -params ["_item", "_vehicle", ["_amount", 1]]; +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_amount", 1, [0]]]; TRACE_3("params",_item,_vehicle,_amount); +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; + private _loaded = _vehicle getVariable [QGVAR(loaded), []]; private _addedSpace = 0; @@ -29,31 +34,40 @@ private _itemsRemoved = 0; private _continue = if (_item isEqualType objNull) then { if !(_item in _loaded) exitWith {false}; - _addedSpace = [_item] call FUNC(getSizeItem); + + _addedSpace = (_item call FUNC(getSizeItem)) max 0; // don't let negative size items increase space _loaded deleteAt (_loaded find _item); + _itemClass = typeOf _item; + + // Delete item deleteVehicle _item; + _itemsRemoved = 1; + true } else { { if (_itemsRemoved == _amount) exitWith {}; if ( - (_x isEqualType "" && {_x == _item}) || // Check for classname, case-insensitive - {_x isEqualType objNull && {typeOf _x isEqualTo _item}} + (_x isEqualType "" && {_x == _item}) || + {_x isEqualType objNull && {typeOf _x == _item}} ) then { INC(_itemsRemoved); - ADD(_addedSpace,[_x] call FUNC(getSizeItem)); + _addedSpace = _addedSpace + ((_x call FUNC(getSizeItem)) max 0); // don't let negative size items increase space + // Delete item if (_x isEqualType objNull) then { deleteVehicle _x; }; + _loaded set [_forEachIndex, nil]; }; } forEach _loaded; - FILTER(_loaded,_x != nil); + FILTER(_loaded,!isNil "_x"); + true }; @@ -61,8 +75,9 @@ if (!_continue) exitWith {0}; _vehicle setVariable [QGVAR(loaded), _loaded, true]; -private _space = [_vehicle] call FUNC(getCargoSpaceLeft); -_vehicle setVariable [QGVAR(space), _space + _addedSpace, true]; +// Update remaining cargo space +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _cargoSpace + _addedSpace, true]; // Invoke listenable event ["ace_cargoRemoved", [_itemClass, _vehicle, _amount, _itemsRemoved]] call CBA_fnc_globalEvent; diff --git a/addons/cargo/functions/fnc_renameObject.sqf b/addons/cargo/functions/fnc_renameObject.sqf new file mode 100644 index 0000000000..a10d54df7e --- /dev/null +++ b/addons/cargo/functions/fnc_renameObject.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: JasperRab + * Renames an object. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_cargo_fnc_renameObject + * + * Public: No + */ + +private _display = uiNamespace getVariable QGVAR(menuDisplay); + +if (isNil "_display") exitWith {}; + +private _ctrlEditText = ctrlText 100; +_ctrlEditText = _ctrlEditText select [0, 32]; + +// Check if custom name has been removed +if (_ctrlEditText isEqualTo "") then { + [LSTRING(clearedCustomName), 3] call EFUNC(common,displayTextStructured); +} else { + [[LSTRING(renamedObject), _ctrlEditText], 3] call EFUNC(common,displayTextStructured); +}; + +GVAR(interactionVehicle) setVariable [QGVAR(customName), _ctrlEditText, true]; diff --git a/addons/cargo/functions/fnc_setSize.sqf b/addons/cargo/functions/fnc_setSize.sqf index 9c9cc34f39..8804c81266 100644 --- a/addons/cargo/functions/fnc_setSize.sqf +++ b/addons/cargo/functions/fnc_setSize.sqf @@ -1,57 +1,55 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike - * Set the cargo size of any object. Has global effect. + * Author: kymckay + * Sets the cargo size of any object. Has global effect. * Adds the load action menu if necessary. - * Negative size makes unloadable. + * A negative size disables the object's cargo interactions. * * Arguments: - * 0: Object - * 1: Cargo size + * 0: Object (default: objNull) + * 1: Cargo size (default: nil) * * Return Value: * None * * Example: - * [cursorTarget, 3] call ace_cargo_fnc_setSize + * [cursorObject, 3] call ace_cargo_fnc_setSize * * Public: Yes */ -// Only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSize), _this]; -}; - params [ - ["_object",objNull,[objNull]], - ["_size",nil,[0]] // Default can't be a number since all are valid + ["_object", objNull, [objNull]], + ["_size", nil, [0]] // default can't be a number since all are valid ]; TRACE_2("setSize",_object,_size); +private _oldSize = _object call FUNC(getSizeItem); + // Nothing to do here -if ( - (isNil "_size") || - {isNull _object} || - {_size == _object getVariable [QGVAR(size), CARGO_SIZE(typeOf _object)]} -) exitWith {}; +if (isNil "_size" || {isNull _object} || {_size == _oldSize}) exitWith {}; // Apply new size globally -// Necessary to update value, even if unloadable, as API could be used again +// Necessary to update value, even if disabled, as API could be used again _object setVariable [QGVAR(canLoad), _size >= 0, true]; _object setVariable [QGVAR(size), _size, true]; -// If no size no need for load action -if (_size < 0) exitWith {}; +// Update remaining cargo space, if loaded as cargo in a vehicle +private _vehicle = attachedTo _object; -// If an existing ID is present, load action has already been added globally -private _jipID = _object getVariable QGVAR(setSize_jipID); +if (!isNull _vehicle && {_object in (_vehicle getVariable [QGVAR(loaded), []])}) then { + private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); -// Actions should be added to all future JIP players too -if (isNil "_jipID") then { - _jipID = [QGVAR(initObject), [_object]] call CBA_fnc_globalEventJIP; + _vehicle setVariable [QGVAR(space), _cargoSpace + (_oldSize max 0) - (_size max 0), true]; // don't let negative size items increase space +}; + +// Actions should be added for all future JIP players too, regardless of size +private _jipID = format [QGVAR(sizeJipID_%1), hashValue _object]; +[QGVAR(initObject), _object, _jipID] call CBA_fnc_globalEventJIP; + +// Remove from JIP queue if object is deleted +if !(_object getVariable [QGVAR(setSizeRemoveJip), false]) then { [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; - // Store the ID for any future calls to this function - _object setVariable [QGVAR(setSize_jipID), _jipID, true]; + _object setVariable [QGVAR(setSizeRemoveJip), true, true]; }; diff --git a/addons/cargo/functions/fnc_setSpace.sqf b/addons/cargo/functions/fnc_setSpace.sqf index 1b3743cf9f..01c078496c 100644 --- a/addons/cargo/functions/fnc_setSpace.sqf +++ b/addons/cargo/functions/fnc_setSpace.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike - * Set the cargo space of any object. Has global effect. + * Author: kymckay + * Sets the cargo space of any object. Has global effect. * Adds the cargo action menu if necessary. * * Arguments: - * 0: Object - * 1: Cargo space + * 0: Vehicle (default: objNull) + * 1: Cargo space (default: nil) * * Return Value: * None @@ -17,40 +17,38 @@ * Public: Yes */ -// Only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSpace), _this]; -}; - params [ - ["_vehicle",objNull,[objNull]], - ["_space",nil,[0]] // Default can't be a number since all are valid + ["_vehicle", objNull, [objNull]], + ["_space", nil, [0]] // default can't be a number since all are valid ]; -TRACE_2("setSpace",_vehicle,_size); +TRACE_2("setSpace",_vehicle,_space); // Nothing to do here -if ( - (isNil "_space") || - {isNull _vehicle} || - {_space == _vehicle getVariable [QGVAR(space), CARGO_SPACE(typeOf _vehicle)]} -) exitWith {}; +if (isNil "_space" || {isNull _vehicle}) exitWith {}; + +// Account for cargo already in the vehicle +private _loaded = _vehicle getVariable [QGVAR(loaded), []]; +private _cargoSpace = _space; + +{ + _cargoSpace = _cargoSpace - ((_x call FUNC(getSizeItem)) max 0); +} forEach _loaded; + +// If the new value is the same as the old, do nothing +if (_cargoSpace == (_vehicle call FUNC(getCargoSpaceLeft))) exitwith {}; // Apply new space globally // Necessary to update value, even if no space, as API could be used again _vehicle setVariable [QGVAR(hasCargo), _space > 0, true]; -_vehicle setVariable [QGVAR(space), _space, true]; +_vehicle setVariable [QGVAR(space), _cargoSpace, true]; -// If no cargo space no need for cargo menu -if (_space <= 0) exitWith {}; +// Space should be added for all future JIP players too, regardless of space +private _jipID = format [QGVAR(spaceJipID_%1), hashValue _vehicle]; +[QGVAR(initVehicle), _vehicle, _jipID] call CBA_fnc_globalEventJIP; -// If an existing ID is present, cargo menu has already been added globally -private _jipID = _vehicle getVariable QGVAR(setSpace_jipID); - -// Cargo menu should be added to all future JIP players too -if (isNil "_jipID") then { - _jipID = [QGVAR(initVehicle), [_vehicle]] call CBA_fnc_globalEventJIP; +// Remove from JIP queue if vehicle is deleted +if !(_vehicle getVariable [QGVAR(setSpaceRemoveJip), false]) then { [_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; - // Store the ID for any future calls to this function - _vehicle setVariable [QGVAR(setSpace_jipID), _jipID, true]; + _vehicle setVariable [QGVAR(setSpaceRemoveJip), true, true]; }; diff --git a/addons/cargo/functions/fnc_startDeploy.sqf b/addons/cargo/functions/fnc_startDeploy.sqf new file mode 100644 index 0000000000..185f71c712 --- /dev/null +++ b/addons/cargo/functions/fnc_startDeploy.sqf @@ -0,0 +1,86 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith + * Starts the deploy process for unloading an object. + * + * Arguments: + * 0: Unit deploying + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_startDeploy + * + * Public: No + */ + +// Deny creating preview item as it will destroy player vehicle instantly by collision +if (GVAR(interactionParadrop)) exitWith {}; + +params ["_unit"]; + +// Don't allow deploying if already deploying +if (_unit getVariable [QGVAR(isDeploying), false]) exitWith {}; + +// This can be an object or a classname string +private _item = call FUNC(getSelectedItem); + +if (isNil "_item") exitWith {}; + +// Close opened cargo menu +closeDialog 0; + +GVAR(selectedItem) = _item; + +private _classname = _item; + +if (_classname isEqualType objNull) then { + _classname = typeOf _classname; +}; + +// Prevent the placing unit from running +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// Create a local preview object +private _itemPreviewObject = createVehicleLocal [_classname, [0, 0, 0], [], 0, "CAN_COLLIDE"]; + +GVAR(itemPreviewObject) = _itemPreviewObject; + +// Prevent collisions with object +_itemPreviewObject disableCollisionWith _unit; +_itemPreviewObject enableSimulation false; +_itemPreviewObject setMass 1e-12; + +// Detect radius of zone where collision can damage the player +private _itemPreviewObjectRadius = 1 max ((boundingBoxReal [_itemPreviewObject, "FireGeometry"]) select 2); + +// Add height offset of model +private _offset = ((_itemPreviewObject modelToWorldVisual [0, 0, 0]) select 2) - ((_unit modelToWorldVisual [0, 0, 0]) select 2) + 1; + +// Attach object +_itemPreviewObject attachTo [_unit, [0, 1.5 * _itemPreviewObjectRadius, _offset]]; + +// PFH that runs while the deployment is in progress +GVAR(deployPFH) = [{ + (_this select 0) params ["_unit", "_vehicle", "_item", "_itemPreviewObject"]; + + if !( + !isNull _itemPreviewObject && + {[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem)} // don't check for a suitable unloading position when deploying + ) exitWith { + _unit call FUNC(deployCancel); + }; +}, 0.5, [_unit, GVAR(interactionVehicle), _item, _itemPreviewObject]] call CBA_fnc_addPerFrameHandler; + +// Add mouse button action and hint +[LLSTRING(unloadObject), localize "STR_DISP_CANCEL", LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint); + +_unit setVariable [QGVAR(deploy), [ + _unit, "DefaultAction", + {GVAR(deployPFH) != -1}, + {[_this select 0] call FUNC(deployConfirm)} +] call EFUNC(common,addActionEventHandler)]; + +_unit setVariable [QGVAR(isDeploying), true, true]; diff --git a/addons/cargo/functions/fnc_startLoadIn.sqf b/addons/cargo/functions/fnc_startLoadIn.sqf index 7cc7923696..7212d89c22 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -1,68 +1,108 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal - * Start load item. + * Starts loading item. * * Arguments: - * 0: Player - * 1: Object - * 2: Vehicle (Optional) + * 0: Unit doing the loading + * 1: Item to be loaded + * 2: Holder object (vehicle) (default: objNull) * * Return Value: * Load ProgressBar Started * * Example: - * [player, cursorTarget] call ace_cargo_fnc_startLoadIn + * [player, cursorObject] call ace_cargo_fnc_startLoadIn * * Public: No */ -params ["_player", "_object", ["_cargoVehicle", objNull]]; -TRACE_3("params",_player,_object,_cargoVehicle); +params ["_loader", "_item", ["_vehicle", objNull]]; +TRACE_3("params",_loader,_item,_vehicle); -private _vehicle = _cargoVehicle; if (isNull _vehicle) then { { - if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_vehicle = _x}; - } forEach (nearestObjects [_player, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]); + if ([_item, _x] call FUNC(canLoadItemIn)) exitWith { + _vehicle = _x; + }; + } forEach (nearestObjects [_loader, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]); }; if (isNull _vehicle) exitWith { - TRACE_3("Could not find vehicle",_player,_object,_vehicle); - false + TRACE_3("Could not find vehicle",_loader,_item,_vehicle); + + false // return }; -private _return = false; // Start progress bar -if ([_object, _vehicle] call FUNC(canLoadItemIn)) then { - [_player, _object, true] call EFUNC(common,claim); - private _size = [_object] call FUNC(getSizeItem); +if ([_item, _vehicle] call FUNC(canLoadItemIn)) then { + private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); + + // If load time is 0, don't show a progress bar + if (_duration <= 0) exitWith { + ["ace_loadCargo", [_item, _vehicle]] call CBA_fnc_localEvent; + + true // return + }; + + // Claim so nobody else can interact with it + [_loader, _item, true] call EFUNC(common,claim); [ - GVAR(loadTimeCoefficient) * _size, - [_object, _vehicle], + _duration, + [_item, _vehicle], { - TRACE_1("load finish",_this); + TRACE_1("load finish",_this); + [objNull, _this select 0 select 0, true] call EFUNC(common,claim); + ["ace_loadCargo", _this select 0] call CBA_fnc_localEvent; }, { TRACE_1("load fail",_this); - [objNull, _this select 0 select 0, true] call EFUNC(common,claim) + (_this select 0) params ["_item", "_vehicle"]; + + [objNull, _item, true] call EFUNC(common,claim); + + [[LSTRING(loadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); + + // Fix cancelling loading a carried item + if (!isNull attachedTo _item) then { + detach _item; + + // Prevent coliisions between item and vehicle + [QEGVAR(common,fixCollision), _vehicle, _vehicle] call CBA_fnc_targetEvent; + [QEGVAR(common,fixCollision), _item, _item] call CBA_fnc_targetEvent; + + [QEGVAR(common,fixPosition), _item, _item] call CBA_fnc_targetEvent; + [QEGVAR(common,fixFloating), _item, _item] call CBA_fnc_targetEvent; + }; }, - localize LSTRING(LoadingItem), + format [LLSTRING(loadingItem), [_item, true] call FUNC(getNameItem), getText (configOf _vehicle >> "displayName")], { - (_this select 0) params ["_item", "_target"]; - (alive _target) && {locked _target < 2} && {alive _item} - && {([_item, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} + (_this select 0) call FUNC(canLoadItemIn) }, ["isNotSwimming"] ] call EFUNC(common,progressBar); - _return = true; + + true // return } else { - private _displayName = getText (configFile >> "CfgVehicles" >> typeOf _object >> "displayName"); + // Unlock the object + [objNull, _item, true] call EFUNC(common,claim); - [[LSTRING(LoadingFailed), _displayName], 3] call EFUNC(common,displayTextStructured); + [[LSTRING(loadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); + + // Fix cancelling loading a carried item + if (!isNull attachedTo _item) then { + detach _item; + + // Prevent coliisions between item and vehicle + [QEGVAR(common,fixCollision), _vehicle, _vehicle] call CBA_fnc_targetEvent; + [QEGVAR(common,fixCollision), _item, _item] call CBA_fnc_targetEvent; + + [QEGVAR(common,fixPosition), _item, _item] call CBA_fnc_targetEvent; + [QEGVAR(common,fixFloating), _item, _item] call CBA_fnc_targetEvent; + }; + + false // return }; - -_return diff --git a/addons/cargo/functions/fnc_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index 5e7ada82c5..39dbf59f48 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -1,93 +1,112 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal - * Start unload action. + * Starts unloading item selected in the cargo menu. * * Arguments: - * None + * 0: Unit doing the unloading * * Return Value: * None * * Example: - * [] call ace_cargo_fnc_startUnload + * player call ace_cargo_fnc_startUnload * * Public: No */ -disableSerialization; +// This can be an object or a classname string +private _item = call FUNC(getSelectedItem); -private _display = uiNamespace getVariable QGVAR(menuDisplay); -if (isNil "_display") exitWith {}; +if (isNil "_item") exitWith {}; -private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; -if (_loaded isEqualTo []) exitWith {}; - -private _ctrl = _display displayCtrl 100; - -private _selected = (lbCurSel _ctrl) max 0; - -if (count _loaded <= _selected) exitWith {}; -private _item = _loaded select _selected; // This can be an object or a classname string +params ["_unit"]; if (GVAR(interactionParadrop)) exitWith { - // If drop time is 0 don't show a progress bar - if (GVAR(paradropTimeCoefficent) == 0) exitWith { + // Close the cargo menu + closeDialog 0; + + private _duration = GVAR(paradropTimeCoefficent) * (_item call FUNC(getSizeItem)); + + // If drop time is 0, don't show a progress bar + if (_duration <= 0) exitWith { [QGVAR(paradropItem), [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent; }; // Start progress bar - paradrop - private _size = [_item] call FUNC(getSizeItem); - [ - GVAR(paradropTimeCoefficent) * _size, - [_item, GVAR(interactionVehicle), ACE_player], + // Delay execution by a frame, to avoid progress bar stopping prematurely because of the cargo menu still being open + [EFUNC(common,progressBar), [ + _duration, + [_item, GVAR(interactionVehicle)], { - (_this select 0) params ["_item", "_target", "_player"]; - [QGVAR(paradropItem), [_item, _target]] call CBA_fnc_localEvent; + [QGVAR(paradropItem), _this select 0] call CBA_fnc_localEvent; }, { - params ["_args", "", "", "_errorCode"]; // show warning if we failed because of flight conditions - if (_errorCode == 3) then { - _args params ["_item", "_target", "_player"]; - [localize LSTRING(unlevelFlightWarning)] call EFUNC(common,displayTextStructured); + params ["", "", "", "_errorCode"]; + + if (_errorCode == 3) then { // show warning if we failed because of flight conditions + [LSTRING(unlevelFlightWarning)] call EFUNC(common,displayTextStructured); }; }, - localize LSTRING(UnloadingItem), + format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], { - (_this select 0) params ["_item", "_target", "_player"]; - if ((acos ((vectorUp _target) select 2)) > 30) exitWith {false}; // check flight level - if (((getPos _target) select 2) < 25) exitWith {false}; // check height - if ((speed _target) < -5) exitWith {false}; // check reverse + (_this select 0) params ["", "_vehicle"]; + + if ((acos ((vectorUp _vehicle) select 2)) > 30) exitWith {false}; // check flight level + if (((getPos _vehicle) select 2) < 25) exitWith {false}; // check height + if ((speed _vehicle) < -5) exitWith {false}; // check reverse + true }, - ["isNotSwimming", "isNotInside"] - ] call EFUNC(common,progressBar); + ["isNotSwimming", "isNotInside"], + false + ]] call CBA_fnc_execNextFrame; }; +// If in zeus +if (!isNull curatorCamera) exitWith { + // Do not check distance to unit, but do check for valid position + if !([_item, GVAR(interactionVehicle), objNull, true] call FUNC(canUnloadItem)) exitWith { + [[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); + }; + + // Close the cargo menu + closeDialog 1; + + ["ace_unloadCargo", [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent; +}; // Start progress bar - normal ground unload -if ([_item, GVAR(interactionVehicle), ACE_player] call FUNC(canUnloadItem)) then { - private _size = [_item] call FUNC(getSizeItem); +if ([_item, GVAR(interactionVehicle), _unit] call FUNC(canUnloadItem)) then { + // Close the cargo menu + closeDialog 0; + + private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); + + // If unload time is 0, don't show a progress bar + if (_duration <= 0) exitWith { + ["ace_unloadCargo", [_item, GVAR(interactionVehicle), _unit]] call CBA_fnc_localEvent; + }; [ - GVAR(loadTimeCoefficient) * _size, - [_item, GVAR(interactionVehicle), ACE_player], - {TRACE_1("unload finish",_this); ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent}, - {TRACE_1("unload fail",_this);}, - localize LSTRING(UnloadingItem), + _duration, + [_item, GVAR(interactionVehicle), _unit], { - (_this select 0) params ["_item", "_target", "_player"]; - - (alive _target) - && {locked _target < 2} - && {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} - && {_item in (_target getVariable [QGVAR(loaded), []])} + TRACE_1("unload finish",_this); + + ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent; + }, + { + TRACE_1("unload fail",_this); + }, + format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], + { + (_this select 0) params ["_item", "_vehicle", "_unit"]; + + [_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem) // don't check for a suitable unloading position every frame }, ["isNotSwimming"] ] call EFUNC(common,progressBar); } else { - private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item}; - private _displayName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName"); - - [[LSTRING(UnloadingFailed), _displayName], 3] call EFUNC(common,displayTextStructured); + [[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); }; diff --git a/addons/cargo/functions/fnc_unloadCarryItem.sqf b/addons/cargo/functions/fnc_unloadCarryItem.sqf new file mode 100644 index 0000000000..7baac21b73 --- /dev/null +++ b/addons/cargo/functions/fnc_unloadCarryItem.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: Grim + * Dragging integration. Unloader starts carrying unloaded object. + * + * Arguments: + * 0: Unit doing the unloading + * 1: Unloaded item + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_cargo_fnc_unloadCarryItem + * + * Public: No + */ + +params ["_unloader", "_object"]; +TRACE_2("unloadCarryItem-start",_unloader,_object); + +if !(["ace_dragging"] call EFUNC(common,isModLoaded)) exitWith {}; +if (!GVAR(carryAfterUnload) || {getNumber (configOf _object >> QGVAR(blockUnloadCarry)) > 0}) exitWith {}; + +// When unloading attached objects, this code will run before server has finished moving object to the safe position +[{ + params ["_unloader", "_object"]; + + (_unloader distance _object) < 10 +}, { + params ["_unloader", "_object"]; + + TRACE_2("unloadCarryItem-unloaded",_unloader,_object); + + if ([_unloader, _object] call EFUNC(dragging,canCarry)) exitWith { + [_unloader, _object] call EFUNC(dragging,startCarry); + }; + + if ([_unloader, _object] call EFUNC(dragging,canDrag)) exitWith { + [_unloader, _object] call EFUNC(dragging,startDrag); + }; +}, _this, 1, { // Delay is based on how long it will take server event to trigger and take effect + // Not a hard error if this fails, could have just unloaded to other side of vehicle because of findSafePos + TRACE_1("unloadCarryItem-failed to unload nearby player",_this); +}] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index 6f0f97cb43..f32215fdd7 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -1,60 +1,121 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, ViperMaul - * Unload object from vehicle. + * Unloads an object from a vehicle. * * Arguments: - * 0: Item - * 1: Vehicle + * 0: Item to be unloaded or (default: "") + * 1: Holder object (vehicle) (default: objNull) * 2: Unloader (default: objNull) + * 3: Deploy parameters (default: []) + * - 0: Position AGL + * - 1: Direction * * Return Value: - * Object was unloaded + * Object unloaded * * Example: - * [object, vehicle] call ace_cargo_fnc_unloadItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_unloadItem * * Public: Yes */ -params ["_item", "_vehicle", ["_unloader", objNull]]; -TRACE_3("params",_item,_vehicle,_unloader); +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]], ["_deploy", []]]; +_deploy params ["_emptyPosAGL", "_direction"]; -//This covers testing vehicle stability and finding a safe position -private _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); -TRACE_1("findUnloadPosition",_emptyPosAGL); +TRACE_4("params",_item,_vehicle,_unloader,_deploy); -if ((count _emptyPosAGL) != 3) exitWith { - TRACE_4("Could not find unload pos",_vehicle,getPosASL _vehicle,isTouchingGround _vehicle,speed _vehicle); - if ((!isNull _unloader) && {_unloader == ACE_player}) then { - //display text saying there are no safe places to exit the vehicle - [localize ELSTRING(common,NoRoomToUnload)] call EFUNC(common,displayTextStructured); - }; - false +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); }; +// Check if item is actually part of cargo private _loaded = _vehicle getVariable [QGVAR(loaded), []]; if !(_item in _loaded) exitWith { - ERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]", _item, _vehicle, _loaded); - false + ERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]",_item,_vehicle,_loaded); + + false // return }; +// Check if item can be unloaded +private _itemSize = _item call FUNC(getSizeItem); + +if (_itemSize < 0) exitWith { + false // return +}; + +private _deployed = _deploy isNotEqualTo []; + +if (!_deployed) then { + // This covers testing vehicle stability and finding a safe position + for "_i" from 1 to 3 do { + _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); + + if (_emptyPosAGL isNotEqualTo []) exitWith {}; + }; + + TRACE_1("findUnloadPosition",_emptyPosAGL); +}; + +if (_emptyPosAGL isEqualTo []) exitWith { + // Display text saying there are no safe places to exit the vehicle + if (!isNull _unloader && {_unloader == ACE_player}) then { + [ELSTRING(common,NoRoomToUnload)] call EFUNC(common,displayTextStructured); + }; + + false // return +}; + +// Unload item from cargo _loaded deleteAt (_loaded find _item); _vehicle setVariable [QGVAR(loaded), _loaded, true]; -private _space = [_vehicle] call FUNC(getCargoSpaceLeft); -private _itemSize = [_item] call FUNC(getSizeItem); -_vehicle setVariable [QGVAR(space), (_space + _itemSize), true]; +// Update cargo space remaining +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _cargoSpace + _itemSize, true]; -if (_item isEqualType objNull) then { - detach _item; - // hideObjectGlobal must be executed before setPos to ensure light objects are rendered correctly - // do both on server to ensure they are executed in the correct order - [QGVAR(serverUnload), [_item, _emptyPosAGL]] call CBA_fnc_serverEvent; +private _object = _item; + +if (_object isEqualType objNull) then { + detach _object; + + // If player unloads via deployment, set direction first, then unload + if (_deployed) then { + [QGVAR(setDirAndUnload), [_object, _emptyPosAGL, _direction], _object] call CBA_fnc_targetEvent; + } else { + [QGVAR(serverUnload), [_object, _emptyPosAGL]] call CBA_fnc_serverEvent; + }; + + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + // Get which curators had this object as editable + private _objectCurators = _object getVariable [QGVAR(objectCurators), []]; + + if (_objectCurators isEqualTo []) exitWith {}; + + [QEGVAR(zeus,addObjects), [[_object], _objectCurators]] call CBA_fnc_serverEvent; + }; } else { - private _newItem = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"]; - _newItem setPosASL (AGLtoASL _emptyPosAGL); + _object = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"]; + + // If player unloads via deployment, set direction. Must happen before setPosASL command according to wiki + if (_deployed) then { + _object setDir _direction; + }; + + _object setPosASL (AGLtoASL _emptyPosAGL); + + [QEGVAR(common,fixCollision), _object] call CBA_fnc_localEvent; + [QEGVAR(common,fixPosition), _object] call CBA_fnc_localEvent; }; -true +// Dragging integration +if (!_deployed) then { + [_unloader, _object] call FUNC(unloadCarryItem); +}; + +// Invoke listenable event +["ace_cargoUnloaded", [_object, _vehicle, "unload"]] call CBA_fnc_globalEvent; + +true // return diff --git a/addons/cargo/functions/fnc_validateCargoSpace.sqf b/addons/cargo/functions/fnc_validateCargoSpace.sqf deleted file mode 100644 index b83ccfe93a..0000000000 --- a/addons/cargo/functions/fnc_validateCargoSpace.sqf +++ /dev/null @@ -1,37 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Validate the vehicle cargo space. - * - * Arguments: - * 0: Object - * - * Return Value: - * None - * - * Example: - * [object] call ace_cargo_fnc_validateCargoSpace - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -private _loaded = _vehicle getVariable [QGVAR(loaded), []]; - -private _newLoaded = []; -private _totalSpaceOccupied = 0; -{ - if ((_x isEqualType "") || {!isNull _x}) then { - _newLoaded pushback _x; - _totalSpaceOccupied = _totalSpaceOccupied + ([_x] call FUNC(getSizeItem)); - }; - true -} count _loaded; - -if (count _loaded != count _newLoaded) then { - _vehicle setVariable [QGVAR(loaded), _newLoaded, true]; -}; - -_vehicle setVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(space)) - _totalSpaceOccupied, true]; diff --git a/addons/cargo/functions/script_component.hpp b/addons/cargo/functions/script_component.hpp deleted file mode 100644 index cc6204b83b..0000000000 --- a/addons/cargo/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\cargo\script_component.hpp" diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf new file mode 100644 index 0000000000..4f92934d46 --- /dev/null +++ b/addons/cargo/initSettings.inc.sqf @@ -0,0 +1,61 @@ +private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; + +[ + QGVAR(enable), + "CHECKBOX", + [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(loadTimeCoefficient), + "SLIDER", + [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], + _category, + [0, 10, 5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(paradropTimeCoefficent), + "SLIDER", + [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], + _category, + [0, 10, 2.5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(openAfterUnload), + "LIST", + [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], + _category, + [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0] +] call CBA_fnc_addSetting; + +[ + QGVAR(carryAfterUnload), + "CHECKBOX", + [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], + _category, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(enableDeploy), + "CHECKBOX", + [LSTRING(enableDeploy), LSTRING(enableDeploy_description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableRename), + "CHECKBOX", + [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], + _category, + true +] call CBA_fnc_addSetting; diff --git a/addons/cargo/initSettings.sqf b/addons/cargo/initSettings.sqf deleted file mode 100644 index cbf0a121e5..0000000000 --- a/addons/cargo/initSettings.sqf +++ /dev/null @@ -1,26 +0,0 @@ -[ - QGVAR(enable), "CHECKBOX", - [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - true, - true, - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(loadTimeCoefficient), "SLIDER", - [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - [0, 10, 5, 1], - true, - {[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(paradropTimeCoefficent), "SLIDER", - [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - [0, 10, 2.5, 1], - true, - {[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; diff --git a/addons/cargo/menu.hpp b/addons/cargo/menu.hpp index 7496298371..1811369d7d 100644 --- a/addons/cargo/menu.hpp +++ b/addons/cargo/menu.hpp @@ -2,11 +2,11 @@ class GVAR(menu) { idd = 314614; - movingEnable = true; + movingEnable = 1; onLoad = QUOTE([_this select 0] call FUNC(onMenuOpen)); - onUnload = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(menuDisplay)),nil)];); + onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),nil)]); class controlsBackground { - class HeaderBackground: ACE_gui_backgroundBase{ + class HeaderBackground: ACE_gui_backgroundBase { idc = -1; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; x = "13 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; @@ -17,10 +17,10 @@ class GVAR(menu) { }; class CenterBackground: HeaderBackground { y = "2.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - h = "13.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + h = "14.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; text = "#(argb,8,8,3)color(0,0,0,0.8)"; colorText[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; - colorBackground[] = {0,0,0,"(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; + colorBackground[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; }; }; @@ -32,7 +32,7 @@ class GVAR(menu) { y = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; w = "13 * (((safezoneW / safezoneH) min 1.2) / 40)"; h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - style = ST_LEFT + ST_SHADOW; + style = QUOTE(ST_LEFT + ST_SHADOW); font = "RobotoCondensed"; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; colorText[] = {0.95, 0.95, 0.95, 0.75}; @@ -46,8 +46,8 @@ class GVAR(menu) { w = "13 * (((safezoneW / safezoneH) min 1.2) / 40)"; h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; style = ST_CENTER; - colorText[] = {1, 1, 1.0, 0.9}; - colorBackground[] = {0,0,0,0}; + colorText[] = {1, 1, 1, 0.9}; + colorBackground[] = {0, 0, 0, 0}; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1.2)"; text = ""; }; @@ -72,7 +72,7 @@ class GVAR(menu) { idc = 11; x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; y = "14.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - w = "5 * (((safezoneW / safezoneH) min 1.2) / 40)"; + w = "6 * (((safezoneW / safezoneH) min 1.2) / 40)"; h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; size = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.7)"; @@ -83,12 +83,12 @@ class GVAR(menu) { animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; color[] = {1, 1, 1, 1}; - color2[] = {0,0,0, 1}; - colorBackgroundFocused[] = {1,1,1,1}; - colorBackground[] = {1,1,1,1}; - colorbackground2[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,1}; - colorFocused[] = {0,0,0,1}; + color2[] = {0, 0, 0, 1}; + colorBackgroundFocused[] = {1, 1, 1, 1}; + colorBackground[] = {1, 1, 1, 1}; + colorbackground2[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 1}; + colorFocused[] = {0, 0, 0, 1}; periodFocus = 1; periodOver = 1; action = QUOTE(closeDialog 0); @@ -96,8 +96,15 @@ class GVAR(menu) { class btnUnload: btnCancel { text = CSTRING(unloadObject); idc = 12; - x = "20.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - action = QUOTE([] call FUNC(startUnload);); + x = "19.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + action = QUOTE(ACE_player call FUNC(startUnload)); + }; + class btnPlace: btnUnload { + text = CSTRING(deployObject); + idc = 13; + y = "15.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + action = QUOTE(ACE_player call FUNC(startDeploy)); + colorDisabled[] = {0.25, 0.25, 0.25, 1}; }; }; }; diff --git a/addons/cargo/renameMenu.hpp b/addons/cargo/renameMenu.hpp new file mode 100644 index 0000000000..b6acc9ad4e --- /dev/null +++ b/addons/cargo/renameMenu.hpp @@ -0,0 +1,85 @@ +#include "\z\ace\addons\common\define.hpp" + +class GVAR(renameMenu) { + idd = 314615; + movingEnable = 0; + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),_this select 0)]); + onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),nil)]); + class controlsBackground { + class HeaderBackground: ACE_gui_backgroundBase { + idc = -1; + SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + x = "13 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + y = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + w = "13 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + text = "#(argb,8,8,3)color(0,0,0,0)"; + }; + class CenterBackground: HeaderBackground { + y = "2.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + h = "2.9 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + text = "#(argb,8,8,3)color(0,0,0,0.8)"; + colorText[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; + colorBackground[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; + }; + }; + + class controls { + class HeaderName { + idc = 1; + type = CT_STATIC; + x = "13 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + y = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + w = "13 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + style = QUOTE(ST_LEFT + ST_SHADOW); + font = "RobotoCondensed"; + SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + colorText[] = {0.95, 0.95, 0.95, 0.75}; + colorBackground[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])", "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])", "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; + text = CSTRING(renameObjectUI); + }; + class edit: ACE_gui_editBase { + onLoad = QUOTE((_this select 0) ctrlSetText (GVAR(interactionVehicle) getVariable [ARR_2(QQGVAR(customName),'')])); + idc = 100; + canModify = 1; + x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + y = "2.3 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + w = "12.8 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + SizeEx = "1.5 * (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.7)"; + }; + class btnCancel: ACE_gui_buttonBase { + text = "$STR_DISP_CANCEL"; + idc = 11; + x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + y = "3.9 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + w = "5 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + size = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; + SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.7)"; + animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; + animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; + animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; + animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; + animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; + animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; + color[] = {1, 1, 1, 1}; + color2[] = {0, 0, 0, 1}; + colorBackgroundFocused[] = {1, 1, 1, 1}; + colorBackground[] = {1, 1, 1, 1}; + colorbackground2[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 1}; + colorFocused[] = {0, 0, 0, 1}; + periodFocus = 1; + periodOver = 1; + action = QUOTE(closeDialog 0); + }; + class btnSave: btnCancel { + text = ECSTRING(Common,Save); + idc = 12; + x = "20.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + action = QUOTE(closeDialog 1; call FUNC(renameObject)); + }; + }; +}; diff --git a/addons/cargo/script_component.hpp b/addons/cargo/script_component.hpp index d5cee60c39..00629c73d2 100644 --- a/addons/cargo/script_component.hpp +++ b/addons/cargo/script_component.hpp @@ -19,7 +19,3 @@ #define MAX_LOAD_DISTANCE 5 #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) - -// Default cargo size is -1 as 0 is a valid size -#define CARGO_SIZE(classname) GET_NUMBER(configFile >> "CfgVehicles" >> (classname) >> QGVAR(size),-1) -#define CARGO_SPACE(classname) GET_NUMBER(configFile >> "CfgVehicles" >> (classname) >> QGVAR(space),0) diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index ed7b135e8f..8e16f50090 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -15,6 +15,7 @@ 싣기 裝載 装载 + Yükle Unload @@ -26,10 +27,117 @@ Descargar Scarica Décharger - 下ろす + 降ろす 내리기 卸載 卸载 + Boşalt + + + Deploy + Piazza + Разместить + 配置する + 배치하기 + Déployer + Aufstellen + Desplegar + + + Raise/Lower | (Ctrl + Scroll) Rotate + Heben/Senken | (Strg + Scrollen) Drehen + Alza/Abbassa | (Ctrl + Rotellina) Ruota + Lever/Baisser | (Ctrl + Scroll) Rotation + 上げる/下げる | (Ctrl + スクロール) 回転 + Zvednout/Snížit | (Ctrl + Kolečko myši) Otáčet + Поднять/опустить | (Ctrl + Скролл) Крутить + Wyżej/niżej | (Ctrl + Kółko myszy) obracanie + Yükselt/Alçalt | (Ctrl + Tekerlek) Döndür + Subir/Bajar | (Ctrl + Scroll) Rotar + 抬起/放低 |(Ctrl + 鼠标滚轮)旋转 + 높이기/내리기 | (컨트롤 + 스크롤) 회전 + Subir/Abaixar | (Ctrl + Scroll) Rotacionar + + + Blocked + Obstruido + Bloqueado + Заблокировано + Blokováno + Zablokowany + Bloccato + Blockiert + Bloqué + 配置不可 + 막힘 + 断开 + 斷開 + Bloke Edilmiş + + + Renamed to:<br/>%1 + 名前を次に変更:<br/>%1 + Renommé en :<br/>%1 + Переименовано в:<br/>%1 + Neu umbenannt zu: <br/>%1 + Rinominato in: <br/>%1 + Nazwa zmieniona na:<br/>%1 + 重命名为:<br/>%1 + %1(으)로 명칭을 바꿈 + Renombrado a:<br/>%1 + Renomeado para: <br/>%1 + + + Custom name has been cleared. + カスタム名が削除されました。 + Le nom personnalisé a été supprimé. + Пользовательское название удалено. + Eigener Name wurde gelöscht. + Nome personalizzato cancellato. + Własna nazwa została usunięta + 自定义名称已被清除。 + 임의로 지은 명칭을 지웠습니다. + El nombre personalizado ha sido borrado. + O nome personalizado foi apagado. + + + Set New Name: + 新しい名前: + Définir un nouveau nom : + Задать новое название: + Neuen Namen setzen: + Imposta nome personalizzato: + Ustaw nową nazwę: + 设定新名称: + 새로운 명칭 설정: + Establecer nuevo nombre: + Definir novo nome: + + + Enable Rename Action + 名前変更を有効化 + Possibilité de renommage + Вкл. возможность переименования + Aktiviere Umbenennungs-Aktion + Attiva azione di rinomina + Włącz możliwość zmiany nazwy + 启用重命名动作 + 새로 명칭 짓기 행동 활성화 + Habilitar renombrado + Habilitar ação de renomear + + + Enables the rename action for renamable objects. + 名前変更が可能なオブジェクトに対して、名前変更アクションを有効化します。 + Active la possibilité de donner un nom personnalisé aux objets transportables (si renommables). + Включает переименование для объектов, допускающих переименование. + Aktiviert die Umbenennungs-Aktion für neu benennbare Objekte. + Attiva la funzione di rinomina per nuovi oggetti rinominabili. + Włącza akcję zmiany nazwy dla obiektów z możliwością zmiany nazwy. + 启用可重命名物体的重命名动作。 + 개체의 명칭을 새로 짓는 것을 허가합니다. + Habilitar renombrado para los objetos renombrables. + Habilita a ação de renomear para objetos renomeáveis. Cargo @@ -39,12 +147,13 @@ Грузовой отсек Náklad Carga - Cargo + Carico Cargaison - カーゴ + 貨物 화물 貨物 货物 + Kargo Cargo Menu @@ -54,12 +163,13 @@ Грузовой отсек Menu nákladu Menu de carga - Menù Cargo + Menù del Carico Menu de cargaison - カーゴ メニュー + 貨物メニュー 화물 메뉴 貨物選單 - 货物选单 + 货物菜单 + Kargo Menüsü Cargo space left: %1 @@ -69,27 +179,29 @@ Осталось мест: %1 Zbývající prostor: %1 Espacio de carga restante: %1 - Spazio cargo rimanente: %1 - Espace de cargaison restant : %1 - カーゴの空き容量: %1 + Spazio di carico rimanente: %1 + Espace de chargement restant : %1 + 貨物室の空き容量: %1 선적 공간 남음: %1 貨物剩餘空間: %1 - 货物剩余空间: %1 + 货物剩余空间:%1 + Kargo Alanı Kaldı: %1 Enable Cargo Aktiviere Fracht Aktywuj cargo Ativar carga - Включить модуль перевозки грузов + Вкл. модуль перевозки грузов Povolit náklad Habilitar carga - Abilita Cargo - Activer la mise en cargaison - カーゴを有効化 + Abilita Carico + Activer la cargaison + 貨物を有効化 화물 활성화 啟用貨物裝載 启用货物装载 + Kargoyu Etkinleştir Enable the load in cargo module @@ -99,10 +211,10 @@ Включает модуль погрузки и перевозки грузов Habilitar la carga en el módulo de carga Umožňuje naložit předměty do nákladového prostoru vozidla - Abilita il modulo di caricamento in cargo - Active le chargement de cargaison dans un vehicule - カーゴ モジュールで積み込みを有効化 - 화물 모듈에 싣기를 활성화합니다 + Abilita il modulo di caricamento nel carico + Active la possibilité de charger du matériel dans un module de fret (véhicule/container). + 貨物積載モジュールを有効化 + 화물 모듈을 활성화합니다 啟用貨物裝載功能 启用货物装载功能 @@ -114,12 +226,13 @@ Перевозка грузов Nastavení nákladu Ajustes de carga - Impostazioni Cargo + Impostazioni Carico Paramètres de cargaison - カーゴ設定 + 貨物設定 화물 설정 貨物設定 货物设定 + Kargo Ayarları Configure the cargo module settings @@ -129,9 +242,9 @@ Конфигурирует настройки модуля перевозки грузов Configure los ajustes del módulo de carga Konfigurace nákladního modulu - Configura le impostazioni del modulo cargo - Configure les paramètres du module de cargaison - カーゴ モジュールの設定を構成 + Configura le impostazioni del modulo carico + Configure les paramètres du module de cargaison. + 貨物モジュールの設定を変更します 화물 모듈의 환경 설정을 바꿉니다 配置貨物模塊設定 配置货物模块设定 @@ -147,8 +260,8 @@ %1<br/>caricato su<br/>%2 %1<br/>berakodva ide:<br/>%2 %1<br/>загружен в<br/>%2 - %1<br/>は<br/>%2へ積み込まれました - %1<br/>는<br/>%2 에 실림 + %1 を<br/>%2 に<br/>積み込みました + %1은(는)<br/>%2 에 실림 %1<br/>裝載至<br/>%2 %1<br/>装载至<br/>%2 @@ -156,47 +269,37 @@ 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/>déchargé 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 에서 내려짐 + %1 を<br/>%2 から<br/>降ろしました + %1은(는)<br/>%2에서 내려짐 從<br/>%2卸載<br/>%1 从<br/>%2卸载<br/>%1 - Loading Cargo - Belade - Carregando carga - Ładowanie cargo - Nakládám - Погрузка - Caricando - Cargando - Chargement de la cargaison - カーゴへ積み込んでいます - 화물 싣기 - 裝載貨物中 - 装载货物中 + Loading %1 into %2... + Cargando %1 en %2... + Caricando %1 in %2... + %1 を %2 に積み込んでいます・・・ + Загружаем %1 в %2... + %1을(를) %2에 싣는 중... + Chargement %1 dans %2... + %1 wird in %2 geladen... - Unloading Cargo - Entlade - Descarregando carga - Rozładowywanie cargo - Vykládám - Выгрузка - Scaricando - Descargando - Déchargement de la cargaison - カーゴから降ろしています - 화물 내리기 - 卸載貨物中 - 卸载货物中 + Unloading %1 from %2... + Descargando %1 de %2... + Scaricando %1 da %2... + %1 を %2 から降ろしています・・・ + Выгружаем %1 из %2... + %1을(를) %2(으)로부터 내리는 중... + Déchargement %1 de %2... + %1 wird von %2 entladen... %1<br/>could not be loaded @@ -207,11 +310,12 @@ %1<br/>не может быть погружен %1<br/>non può essere caricato %1<br/>no pudo ser cargado - %1<br /> n'a pas pu être chargé - %1<br/>は積み込めませんでした - %1<br/>이 실릴 수가 없습니다 + %1<br />n'a pas pu être chargé + %1 は<br/>積み込めませんでした + %1을(를) 싣을 수가 없습니다 %1<br/>無法被裝載 %1<br/>无法被装载 + %1<br/> kargo yüklenemedi %1<br/>could not be unloaded @@ -222,55 +326,120 @@ %1<br/>не может быть выгружен %1<br/>non può essere scaricato %1<br/>no pudo ser descargado - %1<br /> n'a pas pu être déchargé - %1<br/>は降ろせませんでした - %1<br/>이 내려질 수가 없습니다 + %1<br />n'a pas pu être déchargé + %1 は<br/>降ろせませんでした + %1을(를) 하역할 수가 없습니다 %1<br/>無法被卸載 %1<br/>无法被卸载 + %1<br/> kargo boşaltılamadı + + + Can't be unloaded + Kann nicht entladen werden + Impossibile da scaricare + Ne peut pas être déchargé + 荷降ろし不可能です + 하역할 수가 없습니다 + Не может быть выгружен + No puede ser descargado + + + Cargo Size: %1 + Frachtgröße: %1 + Dimensione Carico: %1 + Encombrement fret: %1 + 貨物のサイズ: %1 + 화물 크기: %1 + Размер груза: %1 + Tamaño de carga: %1 + + + Custom Name + カスタム名 + Nom personnalisé + Eigener Name + Nome Personalizzato + Własna nazwa + 自定义名称 + 임의 명칭 + Собственное название + Nombre personalizado + Nome personalizado + + + Set a custom cargo name used in the cargo interface. + 貨物インターフェイスで使用されるカスタム名を設定します。 + Définit un nom de fret personnalisé qui sera visible dans le menu de cargaison. + Установить пользовательское имя груза, используемое в интерфейсе погрузки. + Definiere eigenen Frachtnamen, welcher im Frachtraum genutzt wird. + Definisce nome personalizzato, verrà mostrato nel menù del carico. + Ustaw własną nazwę ładunku, używaną w menu ładunku. + 设置货物界面中使用的一个自定义货物名称。 + 화물 인터페이스에 쓰일 화물의 명칭을 설정합니다. + Establecer un nombre personalizado de carga en la interfaz de carga. + Defina um nome de carga personalizado usado na interface de carga. Cargo Space Frachtraum - Spazio Cargo - カーゴ スペース + Spazio di Carico + 貨物室の容量 貨物空間 货物空间 Przestrzeń ładunkowa 화물 공간 Грузовое пространство + Espaço de Carga + Espace de stockage + Nákladový prostor + Espacio de carga + Kargo Alanı The cargo space available in this vehicle/container Verfügbarer Frachtraum in diesem Fahrzeug/Container Lo spazio disponibile in questo veicolo/container - この車両/コンテナでカーゴ スペースを使えるようにします + この車両/コンテナで使用可能な貨物室の容量 設定此載具/集裝箱可裝載多少貨物 设定此载具/集装箱可装载多少货物 Dostępna przestrzeń ładunkowa w tym pojeździe/kontenerze 이 차량/컨테이너에서 사용가능한 화물 공간 Грузовое пространство, доступное в этом транспортном средстве / контейнере + O espaço de carga disponível nesse veículo/contâiner + L'espace de stockage disponible dans ce véhicule/container. + Nákladový prostor dostupný v tomto vozidle/kontejneru + El espacio de carga disponible en este vehículo/contenedor Cargo Size Frachtgröße - Dimensioni Cargo - カーゴ サイズ + Dimensioni nel Carico + 貨物のサイズ 貨物的大小 货物的大小 Wielkość ładunku 화물 크기 Размер груза + Tamanho da Carga + Encombrement fret + Velikost nákladu + Tamaño de carga + Kargo Boyutu - The cargo space required to hold this object (-1 for unloadable) + The cargo space required to hold this object (-1 for not loadable) Frachtraumgröße, welche zum Einladen dieses Objektes benötigt wird (-1 nicht einladbar) - Lo spazio del cargo necessita di mantenere questo oggetto (-1 per scaricabile) - オブジェクトを積載するのに必要なカーゴ スペース (-1 で積載不可) + Lo spazio di carico necessario per contenere questo oggetto (-1 per non caricabile) + このオブジェクトの積載に必要な貨物室の容量 (-1 で積載不可に) 此貨物會佔掉多少空間(設定-1的話此貨物就不能被裝載) - 此货物会占掉多少空间(设定-1的话此货物就不能被装载) + 此货物会占掉多少空间(设定 -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) + Définit l'espace de stockage nécessaire à l'embarquement de cet objet (-1 pour le rendre non transportable). + Nákladový prostor požadovný pro naložení tohoto objektu (-1 pro nenaložitelné) + Espacio de carga requerido para guardar este objeto (-1 para no descargable) Airdrop @@ -278,11 +447,14 @@ 空中投下 Zrzut zaopatrzenia 공중 투하 - Largage aérien + Largage Lancio Aereo 空投 空投 Десантирование груза + Lançamento Aéreo + Výsadek + Lanzamiento aéreo Unlevel Flight @@ -290,51 +462,146 @@ 機体が水平ではありません Nierówny lot 기체가 수평이 아닙니다 - Rétablir l'assiette + Vol en dénivelé Volo non Livellato 此架飛機並無保持水平飛行 此架飞机并无保持水平飞行 Неподходящее положение + Desnivelar Vôo + Let není vyrovnaný + Vuelo no nivelado Paradrop Time Coefficient Türlast Zeitfaktor - 空中投下までの時間係数 - Coefficente Tempo Lancio Paracadute - Coefficient Temps de largage de cargaison + 空中投下の所要時間係数 + Coefficiente Tempo Lancio Aereo + Coefficient du temps de paralargage 空投時間係數 空投时间系数 Współczynnik czasu zrzutu 공중 투하 시간 계수 - Коэффициент времени десантирования + Коэф. времени десантирования + Fator de Tempo para soltar a carga + Koeficient času nákladního výsadku + Coeficiente de tiempo para lanzamiento Modifier for how long it takes to paradrop a cargo item. Beeinflusst die zusätzliche Zeit für Türlastabwürfe. - カーゴ アイテムを空中投下するまでの時間を変更します。 - Modificato per quanto tempo ci impiega a paracadutare un oggetto cargo. - Modifier le temps qu'il faut pour larguer la cargaison. + 貨物の空中投下に掛かる時間を変更します。 + Modifica quanto tempo viene impiegato per paracadutare oggetti dal carico. + Modifie le temps nécessaire au paralargage d'une cargaison. 設定空投所需消耗的時間 - 设定空投所需消耗的时间. + 设定空投所需消耗的时间。 Modyfikator wskazujący jak dużo czasu potrzeba by zrzucić przedmiot na spadochronie. - 화물을 공중 투하 하는데 얼마나 걸리는 시간 설정 + 화물을 공중 투하 하는데 걸리는 시간을 설정합니다 Модификатор времени, необходимого для десантирования груза + Coeficiente de quanto tempo leva para soltar uma carga de paraquedas + Upravuje jak dlouho výsadek trvá pro náklad. + Modificador de tiempo de lanzamiento en paracaídas de un objeto cargado Load Time Coefficient Ladezeitmultiplikator - 積載時間の係数 + 積載の所要時間係数 Współczynnik czasu załadowania - Coefficente Tempo Caricamento - Коэффициент времени погрузки + Coefficiente Tempo Caricamento + Коэф. времени погрузки + Fator de tempo para carregar + Coefficient du temps de chargement + 裝載時間係數 + Koeficient času nákládání + Coeficiente de tiempo para cargar + 装载时间系数 + 적재 시간 계수 Modifies how long it takes to load/unload items.\nTime, in seconds, is the size of the item multiplied by this value. Gibt an, wie lange das Laden / Entladen von Gegenständen dauern soll.\nZeit in Sekunden, die mit der Größe des Gegenstandes multipliziert wird. - アイテムの積み下ろし作業にかかる時間を編集できます。\nアイテムの大きさにこの値が乗法され、時間 (秒) を変更できます。 + 貨物の積み込み/積み下ろしに掛かる時間を変更します。\n時間 (秒単位) は、貨物のサイズにこの値を掛けたものです。 Modyfikuje, jak długo zajmuje załadowywanie/wyładowywanie przedmiotów. \nCzasem, w sekundach, jest wielkość przedmiotu razy jego wartość. - Modifica quanto tempo ci impiega a caricare o scaricare gli oggetti.\n Tempo, in secondi, è la dimensione dell'oggetto moltiplicata per questo valore - Изменяет время для загрузки/выгрузки предметов. \n Время (сек) - это размер предмета, умноженный на это значение. + Modifica il tempo impiegato per caricare o scaricare gli oggetti.\nIl tempo, in secondi, equivale alla dimensione dell'oggetto moltiplicata per questo valore + Изменяет время для загрузки/выгрузки предметов. \nВремя (сек) - это размер предмета, умноженный на это значение. + Coeficiente de quanto tempo leva para carregar/descarregar itens.\nTempo, em segundos, é o tamanho do objeto multiplicado por esse valor. + Modifie le temps nécessaire pour charger/décharger des objets.\nLe temps, en secondes, est calculé en multipliant la taille de l'élément par ce coefficient. + 修改要花多長時間來裝載/卸載物品。\n時間,以秒為單位,而物品的大小數值與這個係數成比。 + Upravuje jak dlouho nakládají/vykládání trvá.\nVýsledkem je čas v sekundách - velikost objektu vynásobená touto hodnotou. + Modifica el tiempo de carga/descarga de objetos.\n El Tiempo en segundos, es el tamño del objeto multiplicado por este valor. + 修改装载/卸载物体所需的时间。\n时间,单位:秒,物体的大小乘以该系数值。 + 화물의 적재/하역 시 걸리는 시간을 설정합니다.\n초 단위로 물건의 크기에 곱셈하여 계산합니다. + + + Reopen Cargo Menu + Kargo Menüsünü Tekrar Aç + 貨物メニューを再度開く + Rouvrir le menu de cargaison + Переоткрыть меню погрузки + Frachtmenü erneut öffnen + Riapri Menù del Carico + Ponownie otwórz menu załadunku + 重新打开货物菜单 + 화물 메뉴 다시 열기 + Reabrir menú de carga + Reabrir menu de carga + + + Reopen the Cargo Menu after successful unload. + Başarılı bir yük indirmeden sonra Kargo Menüsünü tekrar göster. + 貨物を降ろした後に再び貨物メニューを開きます。 + Réouvre le menu de cargaison après un déchargement réussi. + Переоткрыть меню погрузки после успешной выгрузки. + Frachtmenü erneut öffnen, nach erfolgreichen Entladen. + Riapri il Menù del Carico dopo aver scaricato un oggetto con successo. + Ponownie otwórz menu załadunku po udanym wyładowaniu. + 成功卸货后,重新打开货物菜单。 + 화물을 성공적으로 내리고 난 다음 화물 메뉴를 열지 결정합니다. + Reabrir menú de carga despues de una descarga satisfactoria. + Reabre o menu de carga após uma descarga bem sucedida. + + + Carry After Unload + 화물 내린 후 운반 + Нести после выгрузки + Llevar encima tras la descarga + 荷降ろし後に持ち運ぶ + Niesienie Po Rozładowaniu + Nach dem Entladen tragen + Trasporta dopo aver Scaricato + Porter après déchargement + Transporte após descarregar + + + Controls whether cargo items are carried or dragged after unloading. + 화물 아이템을 내린 후 들거나 끌지 여부를 결정합니다. + Нужно ли переносить или тащить предметы после их выгрузки. + Controla si los objetos de carga son llevados encima o arrastrados despues de la descarga. + 荷降ろし後、貨物を運ぶか引きずるかを制御する。 + Kontroluje, czy przedmioty z ładunku są przenoszone lub ciągnięte po ich wyładowaniu. + Steuert, ob Objekte nach dem Entladen getragen oder gezogen werden. + Determina se un oggetto verrà subito trasportato o trascinato dopo essere stato scaricato. + Active si les éléments de cargaison sont portés ou traînés après le déchargement. + Controla se os itens de carga são carregados ou arrastados após a descarga. + + + Enable deploy + Abilita Piazzamento + Включить размещение + 配置機能を有効化 + 배치 활성화 + Permettre le placement + Aktiviere Aufbauen + Habilitar despliegue + + + Controls whether cargo items can be unloaded via the deploy method. + Determina se oggetti in carico possono essere scaricati e piazzati direttamente. + Определяет, можно ли выгружать грузы с помощью метода размещения. + 配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。 + 배치 방법을 통해 화물 아이템을 내릴 수 있는지 여부를 제어합니다. + Contrôler si les éléments de cargaison peuvent être déchargés via la méthode de déploiement. + Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können. + Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue. diff --git a/addons/casings/$PBOPREFIX$ b/addons/casings/$PBOPREFIX$ new file mode 100644 index 0000000000..622c48c2bb --- /dev/null +++ b/addons/casings/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\casings diff --git a/addons/casings/CfgEventHandlers.hpp b/addons/casings/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/casings/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/casings/CfgVehicles.hpp b/addons/casings/CfgVehicles.hpp new file mode 100644 index 0000000000..73d06bc0ac --- /dev/null +++ b/addons/casings/CfgVehicles.hpp @@ -0,0 +1,6 @@ +class CfgVehicles { + class FxCartridge; + class FxCartridge_65_caseless: FxCartridge { + GVAR(model) = ""; // note: the vanilla 6.5 caseless don't actually use this, just being safe + }; +}; diff --git a/addons/casings/README.md b/addons/casings/README.md new file mode 100644 index 0000000000..7c1ac9b2a0 --- /dev/null +++ b/addons/casings/README.md @@ -0,0 +1,4 @@ +ace_casings +=============== + +Create persistent empty casing when bullets are fired by infantry weapons. diff --git a/addons/casings/XEH_PREP.hpp b/addons/casings/XEH_PREP.hpp new file mode 100644 index 0000000000..8a0738b272 --- /dev/null +++ b/addons/casings/XEH_PREP.hpp @@ -0,0 +1 @@ +PREP(createCasing); diff --git a/addons/casings/XEH_postInit.sqf b/addons/casings/XEH_postInit.sqf new file mode 100644 index 0000000000..c1baad68e9 --- /dev/null +++ b/addons/casings/XEH_postInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +if (!hasInterface || !GVAR(enabled)) exitWith {}; + +GVAR(cachedCasings) = createHashMap; +GVAR(casings) = []; +["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler; diff --git a/addons/casings/XEH_preInit.sqf b/addons/casings/XEH_preInit.sqf new file mode 100644 index 0000000000..894773534a --- /dev/null +++ b/addons/casings/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/optionals/compat_rhs_usf3/XEH_preStart.sqf b/addons/casings/XEH_preStart.sqf similarity index 100% rename from optionals/compat_rhs_usf3/XEH_preStart.sqf rename to addons/casings/XEH_preStart.sqf diff --git a/addons/casings/config.cpp b/addons/casings/config.cpp new file mode 100644 index 0000000000..29d0b7cb89 --- /dev/null +++ b/addons/casings/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"esteldunedain","Cyruz","diwako"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/casings/functions/fnc_createCasing.sqf b/addons/casings/functions/fnc_createCasing.sqf new file mode 100644 index 0000000000..fe35ad5945 --- /dev/null +++ b/addons/casings/functions/fnc_createCasing.sqf @@ -0,0 +1,76 @@ +#include "..\script_component.hpp" +/* + * Author: esteldunedain / Cyruz / diwako + * Produces a casing matching the fired weapons caliber on the ground around the unit + * + * Arguments: + * 0: unit - Object the event handler is assigned to + * 1: ammo - Ammo used + * + * Return Value: + * None + * + * Example: + * [player, "", "","", "B_556x45_Ball"] call ace_casings_fnc_createCasing + * + * Public: No + */ + +params ["_unit", "", "", "", "_ammo"]; + +if (!isNull objectParent _unit) exitWith {}; + + +private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { + private _cartridge = getText (configFile >> "CfgAmmo" >> _ammo >> "cartridge"); + if (_cartridge == "") then { // return (note: can't use exitWith) + "" + } else { + private _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; + + // if explicitly defined, use ACE's config + if (isText (_cartridgeConfig >> QGVAR(model))) exitWith { + getText (_cartridgeConfig >> QGVAR(model)) + }; + // use casing's default model + private _model = getText (_cartridgeConfig >> "model"); + if ("a3\weapons_f\empty" in toLowerANSI _model) exitWith { "" }; + + // Add file extension if missing (fileExists needs file extension) + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d"; + }; + + ["", _model] select (fileExists _model) + }; +}, true]; + +if (_modelPath isEqualTo "") exitWith {}; + +private _unitPos = getposASL _unit; +// Distant shooters don't produce as many cases +if ((AGLToASL positionCameraToWorld [0,0,0]) vectorDistance _unitPos > 100 && {random 1 < 0.9}) exitWith {}; + +private _weapDir = _unit weaponDirection currentWeapon _unit; +private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; +private _pos = _unitPos + vectorAdd (_weapDir vectorMultiply (-0.5 + random 2)) + vectorAdd (_ejectDir vectorMultiply (0.2 + random 2)); + +[ + { + params ["_modelPath", "_pos"]; + + private _lisPos = (lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-1e11], objNull, objNull, true, 1, "ROADWAY", "FIRE"]) #0; + private _casing = createSimpleObject [_modelPath, (_lisPos #0 vectorAdd [0,0,0.005]), true]; + _casing setDir (random 360); + _casing setVectorUp _lisPos #1; + private _idx = GVAR(casings) pushBack _casing; + + for "_" from 0 to (_idx - GVAR(maxCasings)) do { + deleteVehicle (GVAR(casings) deleteAt 0); + }; + }, + [_modelPath,_pos], + 0.4 +] call CBA_fnc_waitAndExecute; diff --git a/addons/casings/initSettings.inc.sqf b/addons/casings/initSettings.inc.sqf new file mode 100644 index 0000000000..3dea180e2d --- /dev/null +++ b/addons/casings/initSettings.inc.sqf @@ -0,0 +1,17 @@ +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(displayName), LSTRING(description)], + LSTRING(Settings_DisplayName), + true, + false, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(maxCasings), "SLIDER", + [LSTRING(maxCasings_displayName), LSTRING(maxCasings_description)], + LSTRING(Settings_DisplayName), + [100, 500, 250, -1], + false +] call CBA_fnc_addSetting; diff --git a/addons/casings/script_component.hpp b/addons/casings/script_component.hpp new file mode 100644 index 0000000000..c734aca4e3 --- /dev/null +++ b/addons/casings/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT casings +#define COMPONENT_BEAUTIFIED Casings +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_CASINGS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_CASINGS + #define DEBUG_SETTINGS DEBUG_SETTINGS_CASINGS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/casings/stringtable.xml b/addons/casings/stringtable.xml new file mode 100644 index 0000000000..bf30ac36d9 --- /dev/null +++ b/addons/casings/stringtable.xml @@ -0,0 +1,70 @@ + + + + + ACE Casings + ACE 薬莢 + ACE Łuski + ACE 탄피 + ACE Bossoli + ACE 弹壳 + ACE Гильзы + ACE Casquillos + ACE Patronenhülsen + ACE Douilles + ACE Cartuchos + + + Casings Enabled + 薬莢の有効化 + Łuski włączone + Abilita Bossoli + 탄피 활성화 + 开启弹壳生成 + Гильзы включены + Habilitar Casquillos + Patronenhülsen aktiviert + Douilles activées + Cartuchos habilitados + + + Enable persistent casings (POTENTIAL performance impact on old/weak systems) + 永続的な薬莢を有効にする (古い/弱いシステムに対する潜在的なパフォーマンスの影響) + Włącz pozostawanie łusek (MOŻLIWY wpływ na wydajność na starych/słabych komputerach) + 영구적으로 남는 탄피를 활성화합니다(오래되거나 저사양에 잠재적인 성능 영향을 줄 수 있음) + 开启生成持续存在的弹壳(可能对较老和性能不行的系统有影响) + Включить постоянные гильзы (ПОТЕНЦИАЛЬНО может повлиять на производительность на старых/слабых системах) + Habilitar persistencia de casquillos (POTENCIAL impacto en el rendimiento de ordenadores antiguos o no potentes) + Persistente Patronenhülsen aktivieren (POTENZIELLE Leistungseinbußen bei alten/schwachen Systemen) + Abilita bossoli persistenti (POTENZIALE impatto sulla perfomance su sistemi vecchi/deboli) + Active la persistance des douilles (POTENTIEL impact sur les performances sur les anciens/faibles systèmes) + Habilitar persistência de cartuchos (POTENCIAL impacto no desempenho de sistemas antigos/fracos) + + + Maximum casings + 薬莢の最大量 + Maksymalna liczba łusek + 탄피 최대 갯수 + 最大弹壳量 + Макс. кол-во гильз + Casquillos máximos + Maximale Patronenhülsen + Numero massimo di bossoli + Nombre maximum de douilles + Máxima de cartuchos + + + Maximum amount of casings to display + 表示される薬莢の最大の数 + Maksymalna liczba wyświetlanych łusek + 표시할 최대 탄피 갯수 + 显示的最大弹壳数量 + Максимальное количество гильз для отображения + Máxima cantidad de casquillos para mostrar + Maximale Anzahl an Patronenhülsen, die angezeigt werden + Numero massimo di bossoli renderizzati + Nombre maximum de douilles à afficher + Quantidade máxima de cartuchos para exibir + + + diff --git a/addons/chemlights/CfgAmmo.hpp b/addons/chemlights/CfgAmmo.hpp index 696c39e724..8c2b9a43ae 100644 --- a/addons/chemlights/CfgAmmo.hpp +++ b/addons/chemlights/CfgAmmo.hpp @@ -2,57 +2,57 @@ class CfgAmmo { class Chemlight_base; - + class Chemlight_Blue: Chemlight_base { timeToLive = 28800; // 8h as per cyalume website }; - + class Chemlight_Red: Chemlight_base { timeToLive = 43200; // 12h as per cyalume website }; - + class Chemlight_Green: Chemlight_base { timeToLive = 43200; }; - + class Chemlight_Yellow: Chemlight_base { timeToLive = 43200; }; - + class ACE_G_Chemlight_Orange: Chemlight_base { timeToLive = 43200; effectsSmoke = "ACE_ChemlightEffect_Orange"; model = "\A3\Weapons_f\chemlight\chemlight_yellow_lit"; }; - + class ACE_G_Chemlight_Orange_Infinite: ACE_G_Chemlight_Orange { timeToLive = 1e10; }; - + class ACE_G_Chemlight_White: Chemlight_base { timeToLive = 28800; effectsSmoke = "ACE_ChemlightEffect_White"; model = "\A3\Weapons_f\chemlight\chemlight_yellow_lit"; }; - + class ACE_G_Chemlight_White_Infinite: ACE_G_Chemlight_White { timeToLive = 1e10; }; - - class ACE_G_Chemlight_HiRed: Chemlight_Red { + + class ACE_G_Chemlight_HiRed: Chemlight_Red { effectsSmoke = "ACE_ChemlightEffect_HiRed"; timeToLive = 1800; }; - + class ACE_G_Chemlight_HiRed_Infinite: ACE_G_Chemlight_HiRed { timeToLive = 1e10; }; - + class ACE_G_Chemlight_HiYellow: Chemlight_Yellow { effectsSmoke = "ACE_ChemlightEffect_HiYellow"; timeToLive = 1800; }; - + class ACE_G_Chemlight_HiYellow_Infinite: ACE_G_Chemlight_HiYellow { timeToLive = 1e10; }; @@ -88,7 +88,7 @@ class CfgAmmo { effectsSmoke = "ACE_ChemlightEffect_UltraHiOrange"; timeToLive = 300; }; - + class ACE_G_Chemlight_UltraHiOrange_Infinite: ACE_G_Chemlight_UltraHiOrange { timeToLive = 1e10; }; diff --git a/addons/chemlights/CfgEventHandlers.hpp b/addons/chemlights/CfgEventHandlers.hpp index 4a25dcc26e..9f522ca135 100644 --- a/addons/chemlights/CfgEventHandlers.hpp +++ b/addons/chemlights/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/chemlights/CfgLights.hpp b/addons/chemlights/CfgLights.hpp index 1b9d445f30..005cc26460 100644 --- a/addons/chemlights/CfgLights.hpp +++ b/addons/chemlights/CfgLights.hpp @@ -99,7 +99,7 @@ class CfgLights { class ACE_ChemlightLight_UltraHiOrange: ACE_ChemlightLight_Orange { intensity = 12000; - + ULTRA_HI_ATTENUATION }; diff --git a/addons/chemlights/CfgMagazines.hpp b/addons/chemlights/CfgMagazines.hpp index a905f4efd1..cb88f28dc2 100644 --- a/addons/chemlights/CfgMagazines.hpp +++ b/addons/chemlights/CfgMagazines.hpp @@ -2,7 +2,7 @@ class CfgMagazines { class SmokeShell; - class Chemlight_Green: Smokeshell { + class Chemlight_Green: SmokeShell { ACE_Chemlight_Shield = "ACE_Chemlight_Shield_Green"; }; diff --git a/addons/chemlights/CfgVehicles.hpp b/addons/chemlights/CfgVehicles.hpp index f22b03a7fe..e01fb79b87 100644 --- a/addons/chemlights/CfgVehicles.hpp +++ b/addons/chemlights/CfgVehicles.hpp @@ -9,11 +9,8 @@ class CfgVehicles { class ACE_Chemlights { displayName = CSTRING(Action_Chemlights); icon = "\a3\ui_f\data\gui\cfg\Hints\chemlights_ca.paa"; - condition = QUOTE(count ([ACE_player] call FUNC(getShieldComponents)) > 0); - statement = "true"; exceptions[] = {"isNotDragging", "isNotSwimming", "notOnMap", "isNotInside", "isNotSitting"}; - insertChildren = QUOTE(_this call DFUNC(compileChemlightMenu)); - showDisabled = 0; + insertChildren = QUOTE(call DFUNC(compileChemlightMenu)); }; }; }; @@ -246,6 +243,7 @@ class CfgVehicles { transportMaxItems = 9002; maximumload = 9002; model = "\A3\weapons_F\AmmoBoxes\WpnsBox_large_F"; + editorPreview = "\A3\EditorPreviews_F\Data\CfgVehicles\Box_NATO_WpsSpecial_F.jpg"; class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,20); diff --git a/addons/chemlights/CfgWeapons.hpp b/addons/chemlights/CfgWeapons.hpp index 8ed9d73583..a3d5ab5afe 100644 --- a/addons/chemlights/CfgWeapons.hpp +++ b/addons/chemlights/CfgWeapons.hpp @@ -54,6 +54,7 @@ class CfgWeapons { model = "\A3\weapons_F\ammo\mag_univ.p3d"; picture = QPATHTOF(UI\ace_chemlight_shield_x_ca.paa); scope = 2; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; diff --git a/addons/chemlights/README.md b/addons/chemlights/README.md index a4b734b0d6..e35737f00c 100644 --- a/addons/chemlights/README.md +++ b/addons/chemlights/README.md @@ -2,10 +2,3 @@ ace_chemlights ============ Enhances chemlights and makes them more realistic. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [voiper](https://github.com/voiperr) diff --git a/addons/chemlights/XEH_postInit.sqf b/addons/chemlights/XEH_postInit.sqf index 6b22de4a3c..b40ffb764e 100644 --- a/addons/chemlights/XEH_postInit.sqf +++ b/addons/chemlights/XEH_postInit.sqf @@ -2,6 +2,6 @@ if (!hasInterface) exitWith {}; -["ace_firedPlayer", DFUNC(throwEH)] call CBA_fnc_addEventHandler; -// ["ace_firedPlayerNonLocal", DFUNC(throwEH)] call CBA_fnc_addEventHandler; -// ["ace_firedNonPlayer", DFUNC(throwEH)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwEH)] call CBA_fnc_addEventHandler; +// ["ace_firedPlayerNonLocal", LINKFUNC(throwEH)] call CBA_fnc_addEventHandler; +// ["ace_firedNonPlayer", LINKFUNC(throwEH)] call CBA_fnc_addEventHandler; diff --git a/addons/chemlights/functions/fnc_compileChemlightMenu.sqf b/addons/chemlights/functions/fnc_compileChemlightMenu.sqf index c8cccb88bd..4deade18e6 100644 --- a/addons/chemlights/functions/fnc_compileChemlightMenu.sqf +++ b/addons/chemlights/functions/fnc_compileChemlightMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Compile list of chemlight classnames and add to the "Chemlight shield" parent menu. diff --git a/addons/chemlights/functions/fnc_getShieldComponents.sqf b/addons/chemlights/functions/fnc_getShieldComponents.sqf index f372241599..f942480146 100644 --- a/addons/chemlights/functions/fnc_getShieldComponents.sqf +++ b/addons/chemlights/functions/fnc_getShieldComponents.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Check a unit for whether they're carrying a chemlight shield and a chemlight. diff --git a/addons/chemlights/functions/fnc_initIR.sqf b/addons/chemlights/functions/fnc_initIR.sqf index 29532f41f1..a49cf96447 100644 --- a/addons/chemlights/functions/fnc_initIR.sqf +++ b/addons/chemlights/functions/fnc_initIR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Spawn IR marker for dummy IR physX object. @@ -17,7 +17,7 @@ params ["_dummy"]; -private _chemlightClass = getText (configFile >> "CfgVehicles" >> typeOf _dummy >> "ACE_Attachable"); +private _chemlightClass = getText (configOf _dummy >> "ACE_Attachable"); private _config = configFile >> "CfgAmmo" >> _chemlightClass; private _delay = getNumber (_config >> "explosionTime"); private _lifeTime = getNumber (_config >> "timeToLive"); diff --git a/addons/chemlights/functions/fnc_isIRClass.sqf b/addons/chemlights/functions/fnc_isIRClass.sqf index 3d2021749e..7d43bc731c 100644 --- a/addons/chemlights/functions/fnc_isIRClass.sqf +++ b/addons/chemlights/functions/fnc_isIRClass.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Check if an ammo classname is an IR chemlight. diff --git a/addons/chemlights/functions/fnc_prepShield.sqf b/addons/chemlights/functions/fnc_prepShield.sqf index 3f4f09d430..46c567a6b3 100644 --- a/addons/chemlights/functions/fnc_prepShield.sqf +++ b/addons/chemlights/functions/fnc_prepShield.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Combine a chemlight shield item and a chemlight item into a light. diff --git a/addons/chemlights/functions/fnc_removeIR.sqf b/addons/chemlights/functions/fnc_removeIR.sqf index 1c40a5b126..e6c186c3f1 100644 --- a/addons/chemlights/functions/fnc_removeIR.sqf +++ b/addons/chemlights/functions/fnc_removeIR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Kill chemlight and any dummy objects attached to it. diff --git a/addons/chemlights/functions/fnc_throwEH.sqf b/addons/chemlights/functions/fnc_throwEH.sqf index 2bedff7cb7..49ec199db1 100644 --- a/addons/chemlights/functions/fnc_throwEH.sqf +++ b/addons/chemlights/functions/fnc_throwEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, voiper * Fired EH, for handling chemlight ThrowMuzzles. diff --git a/addons/chemlights/functions/fnc_throwIR.sqf b/addons/chemlights/functions/fnc_throwIR.sqf index b507c8e5b1..da581a90b0 100644 --- a/addons/chemlights/functions/fnc_throwIR.sqf +++ b/addons/chemlights/functions/fnc_throwIR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Create and throw IR chemlight. diff --git a/addons/chemlights/functions/script_component.hpp b/addons/chemlights/functions/script_component.hpp deleted file mode 100644 index 961201c26c..0000000000 --- a/addons/chemlights/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\chemlights\script_component.hpp" diff --git a/addons/chemlights/stringtable.xml b/addons/chemlights/stringtable.xml index ec638f64ec..76f937df61 100644 --- a/addons/chemlights/stringtable.xml +++ b/addons/chemlights/stringtable.xml @@ -6,12 +6,16 @@ ケミライト Świetliki Knicklichter - 켐라이트 + 화학조명 Cyalumes Luce chimica 螢光棒 - 萤光棒 + 荧光棒 Химсвет + Bastões de Luz + Chemická světla + Luces químicas + Işık Çubukları Prepare %1 @@ -19,67 +23,67 @@ Przygotuj %1 %1 vorbereiten %1 준비 - Prépare %1 + Préparer un %1 Prepara %1 使用%1 使用%1 Приготовить %1 + Preparar %1 + Připravit %1 + Preparar %1 + Hazırlanıyor %1 %1<br/>Prepared - %1<br/>を使った + %1 を<br/>使った %1<br/>Przygotowany %1<br/>vorbereitet %1<br/>준비됨 %1<br/>prêt - %1 <br/> Preparata + %1 <br/>Preparata %1<br/>已使用 %1<br/>已使用 %1<br/>Приготовлен - - - No inventory space - Kein Platz im Inventar - Sin espacio en inventario - Brak miejsca w ekwipunku - Pas de place - Nedostatek místa v inventáři - Sem espaço no inventário - Nessuno spazio nell'inventario - Nincs több hely - В инвентаре нет места - インベントリに空きがありません - 소지품 공간이 없음 - 已無存放空間 - 已无存放空间 + %1<br/>Preparado + %1<br/>Připraveno + %1<br/>Preparado + %1<br/> Hazırlandı [ACE] Chemlights - [ACE] ケミライト + [ACE] ケミカルライト [ACE] Świetliki [ACE] Knicklichter - [ACE] 켐라이트 - [ACE] Cyalume - [ACE] Luci chimiche + [ACE] 화학조명 + [ACE] Cyalumes + [ACE] Luci Chimiche [ACE] 螢光棒 - [ACE] 萤光棒 + [ACE] 荧光棒 [ACE] Химсвет + [ACE] Bastões de Luz + [ACE] Chemická světla + [ACE] Luces químicas + [ACE] Işık Çubukları Chemlight (Orange) - ケミライト (オレンジ) + ケミカルライト(橙) Świetlik (pomarańczowy) Knicklicht (orange) - 켐라이트 (주황) + 화학조명 (주황) Cyalume (orange) Luce chimica (Arancione) 螢光棒 (橘色) - 萤光棒 (橘色) - Химсвет (Оранжевый) + 荧光棒(橘色) + Химсвет (оранжевый) + Bastão de Luz (Laranja) + Chemické světlo (Oranžové) + Luz química (naranja) + Işık Çubuğu (Turuncu) Orange Light - オレンジ色 + 橙ライト Pomarańczowe światło Oranges Knicklicht 주황색 @@ -88,34 +92,46 @@ 橘色光 橘色光 Оранжевый свет + Luz Laranja + Oranžové světlo + Luz naranja + Turuncu Işık Type: Light - Orange<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - オレンジ<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 橙<br />弾薬: 1<br />使用: 手 Typ: Światło - pomarańczowe<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - orange<br />Anzahl: 1<br />Benutzt in: Hand - 종류:밝은 오렌지<br />수량: 1<br />사용처: 손 - Type: Lumière - orange<br />Nbre: 1<br /> À main + 종류: 밝은 오렌지<br />수량: 1<br />사용처: 손 + Type : lumière - Orange<br />Munitions : 1<br />Application : main Tipo: Luce - Arancione<br/>Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 橘色<br />發數: 1<br />使用於: 手 - 类型: 光 - 橘色<br />发数: 1<br />使用于: 手 - Тип: Свет - Оранжевый<br />1 штука<br />В руках + 类型:光—橘色<br />发数:1<br />使用于:手 + Тип: Свет - оранжевый<br />1 штука<br />В руках + Tipo: Luz - Laranja<br/>Usos: 1<br/>Usado em: Mão + Typ: Světlo - Oranžové<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Naranja<br />Cantidad: 1<br />Usado en: Mano + Type: Light - Orange<br />Rounds: 1<br />Used in: Hand Chemlight (White) - ケミライト (白) + ケミカルライト(白) Świetlik (biały) Knicklicht (weiß) - 켐라이트 (하양) + 화학조명 (하양) Cyalume (blanc) Luce chimica (Bianca) 螢光棒 (白色) - 萤光棒 (白色) - Химсвет (Белый) + 荧光棒(白色) + Химсвет (белый) + Bastão de Luz (Branco) + Chemické světlo (Bílé) + Luz química (Blanca) + Işık Çubuğu (Beyaz) White Light - 白色 + 白ライト Białe światło Weißes Knicklicht 하얀색 @@ -124,402 +140,586 @@ 白色光 白色光 Белый свет + Luz Branca + Bílé světlo + Luz blanca + Beyaz Işık Type: Light - White<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 白<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 白<br />弾薬: 1<br />使用: 手 Typ: Światło - białe<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - weiß<br />Anzahl: 1<br />Benutzt in: Hand - 종류:하얀색<br />수량: 1<br />사용처: 손 - Type: Lumière - blanche<br />Nbre: 1<br /> À main + 종류: 하얀색<br />수량: 1<br />사용처: 손 + Type : lumière - Blanche<br />Munitions : 1<br />Application : main Tipo: Luce - Bianca<br/>Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 白色<br />發數: 1<br />使用於: 手 - 类型: 光 - 白色<br />发数: 1<br />使用于: 手 - Тип: Свет - Белый<br />1 штука<br />В руках + 类型:光—白色<br />发数:1<br />使用于:手 + Тип: Свет - белый<br />1 штука<br />В руках + Tipo: Luz - Branco<br/>Usos: 1<br/>Usado em: Mão + Typ: Světlo - Bílé<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Blanca<br />Cantidad: 1<br />Usado en: Mano + Type: Light - White<br />Rounds: 1<br />Used in: Hand Chemlight (Hi Red) - ケミライト (高輝度 赤) + ケミカルライト(高輝度 赤) Świetlik (jaskrawy czerwony) Knicklicht (rot, hell) - 켐라이트 (밝은 빨간색) - Cyalume (Hi rouge) - Luce chimica (Hi Rossa) + 화학조명 (밝은 빨간색) + Cyalume HL (rouge) + Luce chimica (Rossa Intensa) 螢光棒 (超亮紅色) - 萤光棒 (超亮红色) - Химсвет (Ярко-Красный) + 荧光棒(高亮红色) + Химсвет (ярко-красный) + Bastão de Luz (Vermelho Forte) + Chemické světlo (Červené jasné) + Luz química (Roja Hi) + Işık Çubuğu (Kırmızı) Red Hi Light - 高輝度の赤色 + 赤ライト 高輝度 Jaskrawe czerwone światło Helles, rotes Knicklicht 밝은 빨간색 - Lum. rouge haute intensité - Luce Hi Rossa + Lum. rouge HL + Luce Rossa Intensa 超亮紅色光 - 超亮红色光 - Яркий Красный свет + 高亮红色光 + Яркий красный свет + Luz forte vermelha + Červené jasné světlo + Luz roja Hi + Kırmızı Işık Type: Light - Red Hi (30 minute)<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 高輝度 赤 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 赤 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe czerwone (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - rot, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 종류: 밝은 빨간색 (30분)<br />수량: 1<br />사용처: 손 - Type: Lumière - rouge Hi (30 minutes)<br />Nbre: 1<br /> À main - Tipo: Luce - Rossa Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + Type : lumière HL (30 minutes) - Rouge<br />Munitions : 1<br />Application : main + Tipo: Luce - Rossa Intensa (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮紅色 (30分鐘)<br />發數: 1<br />使用於: 手 - 类型: 光 - 超亮红色 (30分钟)<br />发数: 1<br />使用于: 手 - Тип: Свет - Ярко-Красный (30 минут)<br />1 штука<br />В руках + 类型:光—高亮红色(30分钟)<br />发数:1<br />使用于:手 + Тип: Свет - ярко-красный (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Vermelho Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão + Typ: Světlo - Červené jasné<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Roja Hi (30 minutos)<br />Cantidad: 1<br />Usado en: Mano + Type: Light - Red Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Chemlight (Hi Yellow) - ケミライト (高輝度 黄) + ケミカルライト(高輝度 黄) Świetlik (jaskrawy żółty) Knicklicht (gelb, hell) - 켐라이트 (밝은 노란색) - Cyalume (Hi jaune) - Luce chimica (Hi Gialla) + 화학조명 (밝은 노란색) + Cyalume HL (jaune) + Luce chimica (Gialla Intensa) 螢光棒 (超亮黃色) - 萤光棒 (超亮黄色) - Химсвет (Ярко-Желтый) + 荧光棒(高亮黄色) + Химсвет (ярко-жёлтый) + Bastão de Luz (Amarelo Forte) + Chemické světlo (Žluté jasné) + Luz química (Amarilla Hi) + Işık Çubuğu (Sarı) Yellow Hi Light - 高輝度の黄色 + 黄ライト 高輝度 Jaskrawe żółte światło Helles, gelbes Knicklicht 밝은 노란색 - Lum. jaune haute intensité - Luce Hi Gialla + Lum. jaune HL + Luce Gialla Intensa 超亮黃色光 - 超亮黄色光 - Яркий Желтый свет + 高亮黄色光 + Яркий жёлтый свет + Luz forte amarela + Žluté jasné světlo + Luz amarilla Hi + Sarı Işık Type: Light - Yellow Hi (30 minute)<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 高輝度 黄 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 黄 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe żółte (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - gelb, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand - 종류:밝은 노란색 (30분)<br />수량: 1<br />사용처: Hand - Type: Lumière - Jaune Hi (30 minutes)Nbre: 1<br /> À main - Tipo: Luce - Gialla Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + 종류: 밝은 노란색 (30분)<br />수량: 1<br />사용처: Hand + Type : lumière HL (30 minutes) - Jaune<br />Munitions : 1<br />Application : main + Tipo: Luce - Gialla Intensa (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮黃色 (30分鐘)<br />發數: 1<br />使用於: 手 - 类型: 光 - 超亮黄色 (30分钟)<br />发数: 1<br />使用于: 手 - Тип: Свет - Ярко-Желтый (30 минут)<br />1 штука<br />В руках + 类型:光—高亮黄色(30分钟)<br />发数:1<br />使用于:手 + Тип: Свет - ярко-жёлтый (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Amarelo Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão + Typ: Světlo - Žluté jasné<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Amarilla Hi (30 minutos)<br />Cantidad: 1<br />Usado en: Mano + Type: Light - Yellow Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Chemlight (Hi White) - ケミライト (高輝度 白) + ケミカルライト(高輝度 白) Świetlik (jaskrawy biały) Knicklicht (weiß, hell) - 켐라이트 (밝은 하얀색) - Cyalume (Hi blanc) - Luce chimica (Hi Bianca) + 화학조명 (밝은 하얀색) + Cyalume HL (blanc) + Luce chimica (Bianca Intensa) 螢光棒 (超亮白色) - 萤光棒 (超亮白色) - Химсвет (Ярко-Белый) + 荧光棒(高亮白色) + Химсвет (ярко-белый) + Bastão de Luz (Branco Forte) + Chemické světlo (Bílé jasné) + Luz química (Blanca Hi) + Işık Çubuğu (Beyaz) White Hi Light - 高輝度の白色 + 白ライト 高輝度 Jaskrawe białe światło Helles, weißes Knicklicht 밝은 하얀색 - Lum. blanche haute intensité - Luce Hi Bianca + Lum. blanche HL + Luce Bianca Intensa 超亮白色光 - 超亮白色光 - Яркий Белый свет + 高亮白色光 + Яркий белый свет + Luz forte branca + Bílé jasné světlo + Luz blanca Hi + Beyaz Yüksek Işık Type: Light - White Hi (30 minute)<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 高輝度 白 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 白 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe białe (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - weiß, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 종류: 밝은 하얀색 (30분)<br />수량: 1<br />사용처: 손 - Type: Lumière - blanche Hi (30 minutes)<br />Nbre: 1<br /> À main - Tipo: Luce - Bianca Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + Type : lumière HL (30 minutes) - Blanche<br />Munitions : 1<br />Application : main + Tipo: Luce - Bianca Intensa (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮白色 (30分鐘)<br />發數: 1<br />使用於: 手 - 类型: 光 - 超亮白色 (30分钟)<br />发数: 1<br />使用于: 手 - Тип: Свет - Ярко-Белый (30 минут)<br />1 штука<br />В руках + 类型:光—高亮白色(30分钟)<br />发数:1<br />使用于:手 + Тип: Свет - ярко-белый (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Branco Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão + Typ: Světlo - Bílé jasné<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Blanca Hi (30 minutos)<br />Cantidad: 1<br />Usado en: Mano + Type: Light - White Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Chemlight (Hi Blue) - Cyalume (Hi Bleu) - ケミライト (高輝度 青) + Cyalume HL (bleu) + ケミカルライト(高輝度 青) Świetlik (jaskrawy niebieski) - Luce chimica (Hi Blu) - Химсвет (Ярко-Синий) + Knicklicht (Blau, Hell) + Luce chimica (Blu Intensa) + Химсвет (ярко-синий) + Bastão de Luz (Azul Forte) + 螢光棒(超亮藍色) + 荧光棒(高亮蓝色) + Chemické světlo (Modré jasné) + Luz química (Azul Hi) + Işık Çubuğu (Mavi) + 화학조명 (밝은 파란색) Blue Hi Light - Lum. bleue haute intensité - 高輝度の青色 + Lum. bleue HL + Helles, blaues Knicklicht + 青ライト 高輝度 Jaskrawe niebieskie światło - Luce Hi Blu - Яркий Синий свет + Luce Blu Intensa + Яркий синий свет + Luz forte azul + 超亮藍色光 + 高亮蓝色光 + Modré jasné světlo + Luz azul Hi + Mavi Yüksek Işık + 밝은 파란색 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 - 種類: 照明 - 高輝度 青 (30分間)<br />装填数: 1<br />次で使用: 携帯 + Type : lumière HL (30 minutes) - Bleue<br />Munitions : 1<br />Application : main + Typ: Licht - blau, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + タイプ: ライト - 高輝度 青 (30分間)<br />弾薬: 1<br />使用: 手 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: Luce - Blu Intensa (30 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano + Тип: Свет - ярко-синий (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Azul Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão + 類型: 光 - 超亮藍色 (30分鐘)<br />發數: 1<br />使用於: 手 + 类型:光—高亮蓝色(30分钟)<br />发数:1<br />使用于:手 + Typ: Světlo - Modré jasné<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Azul Hi (30 minutos)<br />Cantidad: 1<br />Usado en: Mano + Type: Light - Blue Hi (30 minute)<br />Rounds: 1<br />Used in: Hand + 종류: 밝은 파란색 (30분)<br />수량: 1<br />사용처: 손 Chemlight (Hi Green) - Cyalume (Hi Vert) - ケミライト (高輝度 緑) + Cyalume HL (Vert) + Knicklicht (Grün, Hell) + ケミカルライト(高輝度 緑) Świetlik (jaskrawy zielony) - Luce chimica (Hi Verde) - Химсвет (Ярко-Зеленый) + Luce chimica (Verde Intensa) + Химсвет (ярко-зелёный) + Bastão de Luz (Verde Forte) + 螢光棒(超亮綠色) + 荧光棒(高亮绿色) + Chemické světlo (Zelené jasné) + Luz química (Verde Hi) + Işık Çubuğu (Yeşil) + 화학조명 (밝은 초록색) Green Hi Light - Lum. verte haute intensité - 高輝度の青色 + Lum. verte HL + Helles, grünes Knicklicht + 緑ライト 高輝度 Jaskrawe zielone światło - Luce Hi Verde - Яркий Зеленый свет + Luce Verde Intensa + Яркий зелёный свет + Luz forte verde + 超亮綠色光 + 高亮绿色光 + Zelené jasné světlo + Luz verde Hi + Yeşil Yüksek Işık + 밝은 초록색 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 - 種類: 照明 - 高輝度 緑 (30分間)<br />装填数: 1<br />次で使用: 携帯 + Type : lumière HL (30 minutes) - Verte<br />Munitions : 1<br />Application : main + Typ: Licht - grün, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + タイプ: ライト - 高輝度 緑 (30分間)<br />弾薬: 1<br />使用: 手 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: Luce - Verde Intensa (30 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano + Тип: Свет - ярко-зелёный (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Verde Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão + 類型: 光 - 超亮綠色 (30分鐘)<br />發數: 1<br />使用於: 手 + 类型:光—高亮绿色(30分钟)<br />发数:1<br />使用于:手 + Typ: Světlo - Zelené jasné<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Verde Hi (30 minutos)<br />Cantidad: 1<br />Usado en: Mano + Type: Light - Green Hi (30 minute)<br />Rounds: 1<br />Used in: Hand + 종류: 밝은 초록색 (30분)<br />수량: 1<br />사용처: 손 Chemlight (Ultra-Hi Orange) - Cyalume (Ultra-Hi orange) - ケミライト (高輝度 オレンジ) + Cyalume UHL (orange) + Knicklicht (Orange, Hell) + ケミカルライト(超高輝度 橙) Świetlik (ultra-jaskrawy pomarańczowy) - Luce chimica (Ultra-Hi Arancione) - Химсвет (Ультраяркий Оранжевый) + Luce chimica (Ultra-Intensa Arancione) + Химсвет (ультраяркий оранжевый) + Bastão de Luz (Laranja Ultra Forte) + 螢光棒(極亮橘色) + 荧光棒(高亮橘色) + Chemické světlo (Oranžové velmi jasné) + Luz química (Naranja Ultra-Hi) + Işık Çubuğu (Turuncu) + 화학조명 (밝은 주황색) Orange Ultra-Hi Light - Lum. orange ultra haute intensité - ウルトラ高輝度のオレンジ色 + Lum. orange UHL + Helles, orangenes Knicklicht + 橙ライト 超高輝度 Ultra-jaskrawe pomarańczowe światło - Luce Ultra-Hi Arancione - Ультраяркий Оранжевый свет + Luce Ultra-Intensa Arancione + Ультраяркий оранжевый свет + Luz ultra forte laranja + 極亮橘色光 + 高亮橘色光 + Oranžové velmi jasné světlo + Luz naranja Ultra-Hi + Turuncu Yüksek Işık + 밝은 주황색 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 - 種類: 照明 - ウルトラ高輝度 オレンジ (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 />В руках + Type : lumière UHL (5 minutes) - Orange<br />Munitions : 1<br />Application : main + Typ: Licht - orange, hell (5 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + タイプ: ライト - 超高輝度 橙 (5分間)<br />弾薬: 1<br />使用: 手 + Typ: Światło - ultra-jaskrawe pomarańczowe (5 minut)<br/>Pociski: 1<br/>Używany w: ręce + Tipo: Luce - Ultra-Intensa (5 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano + Тип: Свет - ультраяркий оранжевый (5 минут)<br />1 штука<br />В руках + Tipo: Luz - Laranja Ultra Forte (5 minutos)<br/>Usos: 1<br/>Usado em: Mão + 類型: 光 - 極亮橘色 (5分鐘)<br />發數: 1<br />使用於: 手 + 类型:光—高亮橘色(5分钟)<br />发数:1<br />使用于:手 + Typ: Světlo - Oranžové velmi jasné<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz - Naranja Ultra-Hi (5 minutos)<br />Cantidad: 1<br />Usado en: Mano + Type: Light - Orange Ultra-Hi (5 minute)<br />Rounds: 1<br />Used in: Hand + 종류: 밝은 주황색 (5분)<br />수량: 1<br />사용처: 손 Chemlight (IR) - ケミライト (IR) + ケミカルライト(IR) Świetlik (podczerwony) Knicklicht (IR) - 켐라이트 (적외선) + 화학조명 (적외선) Cyalume (IR) Luce chimica (IR) 螢光棒 (紅外線) - 萤光棒 (红外线) - Химсвет (Инфракрасный) + 荧光棒(红外线) + Химсвет (инфракрасный) + Bastão de Luz (IV) + Chemické světlo (Infračervené) + Luz química (IR) + Işık çubuğu (IR) IR Light - 赤外線光 + 赤外線ライト Światło podczerwone IR-Knicklicht - 적외선 켐라이트 - Lumière IR + 적외선 화학조명 + Lum. IR Luce IR 紅外線光 红外线光 Инфракрасный свет + Bastão de luz infravermelho + Infračervené světlo + Luz IR + IR Işığı Type: Light - Infrared<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 赤外線<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 赤外線<br />弾薬: 1<br />使用: 手 Typ: Światło - podczerwone<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - infrarot<br />Anzahl: 1<br />Benutzt in: Hand 종류: 적외선<br />수량: 1<br />사용처: 손 - Type: Lumière - infrarouge<br />Nbre: 1<br /> À main + Type: lumière - Infrarouge<br />Munitions : 1<br />Application : main Tipo: Luce - Infrarossi<br />Usata in: Mano 類型: 光 - 紅外線<br />發數: 1<br />使用於: 手 - 类型: 光 - 红外线<br />发数: 1<br />使用于: 手 - Тип: Свет - Инфракрасный<br />1 штука<br />В руках + 类型:光—红外线<br />发数:1<br />使用于:手 + Тип: Свет - инфракрасный<br />1 штука<br />В руках + Tipo: Luz - Infravermelho<br/>Usos: 1<br/>Usado em: Mão + Typ: Světlo - Infračervené<br/>Počet použití: 1<br/>Použít v ruce + Tipo: Luz infra-roja<br />Cantidad: 1<br />Usado en: Mano + Tip: Işık <br /> Mermi: 1<br />Kullanılma alanı: El Chemlight Shield (Empty) - ケミライト シールド (空) + ケミカルライト シールド(空) Osłona na świetlik (pusta) Knicklicht-Abschirmung (leer) - 켐라이트 쉴드 (비어있음) - Étui cyalume (vide) + 화학조명 가림막 (비어있음) + Etui cyalume (vide) Scudo Luce chimica (Vuoto) 螢光棒保護殼 (空) - 萤光棒保护壳 (空) - Контейнер для Химсвета (Пуст) + 荧光棒保护壳(空) + Контейнер для химсвета (пустой) + Protetor de Bastão de Luz (Vazio) + Clona na chemické světlo + Protector de luz química (Vacía) + Işık çubuğu koruması (Boş) Shield for chemlights. Combine with chemlight to prepare reading light. - ケミライトを入れられます。シールドとケミライトを組み合わせることで、照明にもなりえます。 + ケミカルライトのためのシールド。ケミカルライトと組み合わせることで、読書灯に出来る。 Osłona na świetliki. Połącz ją ze świetlikiem by stworzyć lampkę do czytania. Abschirmung für Knicklichter. Mit Knicklicht kombinieren, um Leselicht zu erhalten. - 켐라이트를 위한 가림막입니다. 켐라이트와 같이 사용하여 읽을 때 씁니다. - Étui pour cyalume. Combiné avec un cyalume pour obtennir un lampe de lecture. - Scudo per luci chimiche. Combina con una luce chimica per una luce da lettura. + 화학조명을 위한 가림막입니다. 화학조명과 같이 사용하여 읽을 때 씁니다. + Étui pour cyalume. Le combiner avec un cyalume pour obtenir une lampe de lecture. + Scudo per luci chimiche. Combina con una luce chimica per creare una luce da lettura. 螢光棒的保護殼. 與螢光棒結合後可充當閱讀燈 - 萤光棒的保护壳. 与萤光棒结合后可充当阅读灯. - Защитный контейнер для Химсвета. Объедините с Химсветом, чтобы подготовить Свет для чтения + 荧光棒的保护壳。与萤光棒结合后可充当阅读灯。 + Защитный контейнер для химсвета. Объедините с химсветом, чтобы подготовить ночник. + Estojo para os bastões de luz. Combine com o bastão de luz para preparar luz de leitura. + Clona na chemické světlo. Při vložení chemického světla vznikne praktické světlo na čtení. + Protector para luz química. Combina con luz química para preparar una luz de lectura + Işık çubuğu için kalkan. Okuma ışığını hazırlamak için ışık çubuğu ile birleştirin. Chemlight Shield (Green) - ケミライト シールド (緑) + ケミカルライト シールド(緑) Osłona na świetlik (zielona) - Knicklicht-Abschirmung (grün) - 켐라이트 쉴드 (초록) - Étui cyalume (vert) + Knicklicht-Abschirmung (Grün) + 화학조명 가림막 (초록) + Etui avec cyalume (Vert) Scudo Luce Chimica (Verde) 螢光棒保護殼 (綠色) - 萤光棒保护壳 (绿色) - Контейнер для Химсвета (Зел) + 荧光棒保护壳(绿色) + Контейнер для химсвета (зелёный) + Protetor de Bastão de Luz (Verde) + Clona s vloženým chemickým světlem (Zelené) + Protector de luz química (Verde) + Işık çubuğu koruması (Yeşil) Green reading light. - 緑色の照明。 + 緑色の読書灯。 Zielona lampka. Grünes Leselicht. 초록빛 조명 - Lampe d'orientation verte. + Lampe de lecture verte. Luce da lettura Verde. 綠色閱讀燈 绿色阅读灯。 - Ночник из Химсвета (Зеленый) + Ночник из зелёного химсвета. + Luz de leitura verde. + Zelené světlo na čtení. + Luz de lectura verde + Yeşil okuma ışığı. Chemlight Shield (Red) - ケミライト シールド (赤) + ケミカルライト シールド(赤) Osłona na świetlik (czerwona) Knicklicht-Abschirmung (rot) - 켐라이트 쉴드 (빨강) - Étui cyalume (rouge) + 화학조명 가림막 (빨강) + Etui avec cyalume (rouge) Scudo Luce Chimica (Rossa) 螢光棒保護殼 (紅色) - 萤光棒保护壳 (红色) - Контейнер для Химсвета (Красн) + 荧光棒保护壳(红色) + Контейнер для химсвета (красный) + Protetor de Bastão de Luz (Vermelho) + Clona s vloženým chemickým světlem (Červené) + Protector de luz química (Roja) + Işık çubuğu koruması (Kırmızıl) Red reading light. - 赤色の照明。 + 赤色の読書灯。 Czerwona lampka. Rotes Leselicht. 빨간색 조명 - Lampe d'orientation rouge. + Lampe de lecture rouge. Luce da lettura Rossa. 紅色閱讀燈 红色阅读灯。 - Ночник из Химсвета (Красный) + Ночник из красного химсвета. + Luz de leitura vermelha. + Červené světlo na čtení. + Luz de lectura roja + Kırmızı okuma ışığı. Chemlight Shield (Blue) - ケミライト シールド (青) + ケミカルライト シールド(青) Osłona na świetlik (niebieska) Knicklicht-Abschirmung (blau) - 켐라이트 쉴드 (파랑) - Étui cyalume (bleu) + 화학조명 가림막 (파랑) + Etui avec cyalume (bleu) Scudo Luce Chimica (Blu) 螢光棒保護殼 (藍色) - 萤光棒保护壳 (蓝色) - Контейнер для Химсвета (Син) + 荧光棒保护壳(蓝色) + Контейнер для химсвета (синий) + Protetor de Bastão de Luz (Azul) + Clona s vloženým chemickým světlem (Modré) + Protector de luz química (Azul) + Işık çubuğu koruması (Mavi) Blue reading light. - 青色の照明。 + 青色の読書灯。 Niebieska lampka. Blaues Leselicht. 파란색 조명 - Lampe d'orientation bleue. + Lampe de lecture bleue. Luce da lettura Blu. 藍色閱讀燈 蓝色阅读灯。 - Ночник из Химсвета (Синий) + Ночник из синего химсвета. + Luz de leitura azul. + Modré světlo na čtení. + Luz de lectura azul + Mavi okuma ışığı. Chemlight Shield (Yellow) - ケミライト シールド (黄) + ケミカルライト シールド(黄) Osłona na świetlik (żółta) Knicklicht-Abschirmung (gelb) - 켐라이트 쉴드 (노랑) - Étui cyalume (jaune) + 화학조명 가림막 (노랑) + Etui avec cyalume (jaune) Scudo Luce Chimica (Gialla) 螢光棒保護殼 (黃色) - 萤光棒保护壳 (黄色) - Контейнер для Химсвета (Желт) + 荧光棒保护壳(黄色) + Контейнер для химсвета (жёлтый) + Protetor de Bastão de Luz (Amarelo) + Clona s vloženým chemickým světlem (Žluté) + Protector de luz química (Amarilla) + Işık çubuğu koruması (Sarı) Yellow reading light. - 黄色の照明。 + 黄色の読書灯。 Żółta lampka. Gelbes Leselicht. 노란색 조명 - Lampe d'orientation jaune. + Lampe de lecture jaune. Luce da lettura Gialla. 黃色閱讀燈 黄色阅读灯。 - Ночник из Химсвета (Желтый) + Ночник из жёлтого химсвета. + Luz de leitura amarela. + Žluté světlo na čtení. + Luz de lectura amarilla + Sarı okuma ışığı. Chemlight Shield (Orange) - ケミライト シールド (オレンジ) + ケミカルライト シールド(橙) Osłona na świetlik (pomarańczowa) Knicklicht-Abschirmung (orange) - 켐라이트 쉴드 (주황) - Étui cyalume (orange) + 화학조명 가림막 (주황) + Etui avec cyalume (orange) Scudo Luce Chimica (Arancione) 螢光棒保護殼 (橘色) - 萤光棒保护壳 (橘色) - Контейнер для Химсвета (Оранж) + 荧光棒保护壳(橘色) + Контейнер для химсвета (оранжевый) + Protetor de Bastão de Luz (Laranja) + Clona s vloženým chemickým světlem (Oranžové) + Protector de luz química (Naranja) + Işık çubuğu koruması (Turuncu) Orange reading light. - オレンジの照明。 + 橙色の読書灯。 Pomarańczowa lampka. Oranges Leselicht. 주황색 조명 - Lampe d'orientation orange. + Lampe de lecture orange. Luce da lettura Arancione. 橘色閱讀燈 橘色阅读灯。 - Ночник из Химсвета (Оранжевый) + Ночник из оранжевого химсвета. + Luz de leitura laranja. + Oranžové světlo na čtení. + Luz de lectura naranja + Turuncu okuma ışığı. Chemlight Shield (White) - ケミライト シールド (白) + ケミカルライト シールド(白) Osłona na świetlik (biała) Knicklicht-Abschirmung (weiß) - 켐라이트 쉴드 (하양) - Étui cyalume (blanc) + 화학조명 가림막 (하양) + Etui avec cyalume (blanc) Scudo Luce Chimica (Bianca) 螢光棒保護殼 (白色) - 萤光棒保护壳 (白色) - Контейнер для Химсвета (Белый) + 荧光棒保护壳(白色) + Контейнер для химсвета (белый) + Protetor de Bastão de Luz (Branco) + Clona s vloženým chemickým světlem (Bílé) + Protector de luz química (Blanca) + Işık çubuğu koruması (Beyazl) White reading light. - 白色の照明。 + 白色の読書灯。 Biała lampka. Weißes Leselicht. 주황색 조명 - Lampe d'orientation blanche. + Lampe de lecture blanche. Luce da lettura Bianca. 白色閱讀燈 白色阅读灯。 - Ночник из Химсвета (Белый) + Ночник из белого химсвета. + Luz de leitura branca. + Bílé světlo na čtení. + Luz de lectura blanca + Beyaz okuma ışığı. diff --git a/addons/common/ACE_Settings.hpp b/addons/common/ACE_Settings.hpp index f7ab86e227..bc607e357e 100644 --- a/addons/common/ACE_Settings.hpp +++ b/addons/common/ACE_Settings.hpp @@ -17,26 +17,13 @@ class ACE_Settings { * }; */ class GVAR(checkPBOsAction) { - category = CSTRING(DisplayName); - value = 0; - typeName = "SCALAR"; - isClientSettable = 0; - displayName = CSTRING(CheckPBOsAction); - values[] = {CSTRING(CheckPBO_Action_WarnOnce), CSTRING(CheckPBO_Action_WarnPerm), CSTRING(CheckPBO_Action_Kick)}; + movedToSQF = 1; }; class GVAR(checkPBOsCheckAll) { - category = CSTRING(DisplayName); - value = 0; - typeName = "BOOL"; - isClientSettable = 0; - displayName = CSTRING(CheckPBOsCheckAll); + movedToSQF = 1; }; class GVAR(checkPBOsWhitelist) { - category = CSTRING(DisplayName); - value = "[]"; - typeName = "STRING"; - isClientSettable = 0; - displayName = CSTRING(CheckPBOsWhitelist); + movedToSQF = 1; }; /*class GVAR(enableNumberHotkeys) { value = 1; @@ -45,39 +32,15 @@ class ACE_Settings { displayName = CSTRING(EnableNumberHotkeys); };*/ class GVAR(settingFeedbackIcons) { - category = CSTRING(DisplayName); - value = 1; - typeName = "SCALAR"; - force = 0; - isClientSettable = 1; - displayName = CSTRING(SettingFeedbackIconsName); - description = CSTRING(SettingFeedbackIconsDesc); - values[] = {ECSTRING(optionsmenu,Hide), ECSTRING(optionsmenu,TopRightDown), ECSTRING(optionsmenu,TopRightLeft), ECSTRING(optionsmenu,TopLeftDown), ECSTRING(optionsmenu,TopLeftRight)}; + movedToSQF = 1; }; class GVAR(settingProgressBarLocation) { - category = CSTRING(DisplayName); - value = 0; - typeName = "SCALAR"; - force = 0; - isClientSettable = 1; - displayName = CSTRING(SettingProgressbarLocationName); - description = CSTRING(SettingProgressbarLocationDesc); - values[] = {ECSTRING(optionsmenu,Top), ECSTRING(optionsmenu,Bottom)}; + movedToSQF = 1; }; class GVAR(displayTextColor) { - category = CSTRING(DisplayName); - value[] = {0,0,0,0.1}; - typeName = "COLOR"; - isClientSettable = 1; - displayName = CSTRING(SettingDisplayTextColorName); - description = CSTRING(SettingDisplayTextColorDesc); + movedToSQF = 1; }; class GVAR(displayTextFontColor) { - category = CSTRING(DisplayName); - value[] = {1,1,1,1}; - typeName = "COLOR"; - isClientSettable = 1; - displayName = CSTRING(SettingDisplayTextFontColorName); - description = CSTRING(SettingDisplayTextFontColorDesc); + movedToSQF = 1; }; }; diff --git a/addons/common/CfgEventHandlers.hpp b/addons/common/CfgEventHandlers.hpp index fa4f3dcacd..70f35357c4 100644 --- a/addons/common/CfgEventHandlers.hpp +++ b/addons/common/CfgEventHandlers.hpp @@ -1,30 +1,28 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); - disableModuload = true; + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - disableModuload = true; + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_DisplayLoad_EventHandlers { class RscDisplayMission { - ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); }; class RscUnitInfo { - ADDON = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + ADDON = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; }; diff --git a/addons/common/CfgGesturesMale.hpp b/addons/common/CfgGesturesMale.hpp new file mode 100644 index 0000000000..0d3737cb62 --- /dev/null +++ b/addons/common/CfgGesturesMale.hpp @@ -0,0 +1,14 @@ +// From ACRE +class CfgGesturesMale { + skeletonName = "OFP2_ManSkeleton"; + class States { + class GestureNod; + class GVAR(stop): GestureNod { + file = "a3\anims_f\data\anim\sdr\gst\gestureEmpty.rtm"; + disableWeapons = 0; + disableWeaponsLong = 0; + enableOptics = 1; + mask = "empty"; + }; + }; +}; diff --git a/addons/common/CfgMoves.hpp b/addons/common/CfgMoves.hpp index b0df9a4466..da83153b15 100644 --- a/addons/common/CfgMoves.hpp +++ b/addons/common/CfgMoves.hpp @@ -1,9 +1,16 @@ - class CfgMovesBasic { class Default; + + // From ACRE + class ManActions { + GVAR(stop) = QGVAR(stop); + }; class Actions { + class NoActions: ManActions { + GVAR(stop)[] = {QGVAR(stop), "Gesture"}; + }; + // fixes grab animation with equipped pistol - class NoActions; class PistolStandActions: NoActions { grabDrag = "AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_2"; }; @@ -62,8 +69,12 @@ class CfgMovesMaleSdr: CfgMovesBasic { // fix falling back to unconsciousness animation and disable rotating in that state class Unconscious: Default { - ConnectTo[] = {}; + // Prevents AI from moving torso and head when unconscious + aiming = "aimingNo"; + aimingBody = "aimingUpNo"; head = "headNo"; + + ConnectTo[] = {}; forceAim = 1; static = 1; }; @@ -72,5 +83,14 @@ class CfgMovesMaleSdr: CfgMovesBasic { class AinvPknlMstpSnonWnonDnon_medic0: HealBase { variantsPlayer[] = {}; }; + + // Idle affects legs when weapon switching - fixes units sliding when holstering weapons + class AmovPercMstpSnonWnonDnon: StandBase { + idle = ""; + }; + // Need to reset idle, as it breaks animations otherwise + class CutSceneAnimationBase: AmovPercMstpSnonWnonDnon { + idle = "idleDefault"; + }; }; }; diff --git a/addons/common/CfgSounds.hpp b/addons/common/CfgSounds.hpp index d564f6717d..5681d1a194 100644 --- a/addons/common/CfgSounds.hpp +++ b/addons/common/CfgSounds.hpp @@ -1,7 +1,7 @@ class CfgSounds { class ACE_Sound_Click { - sound[] = {PATHTOF(sounds\ACE_click.wav), 1, 1, 200}; + sound[] = {QPATHTOF(sounds\ACE_click.wav), 1, 1, 200}; titles[] = {}; }; }; diff --git a/addons/common/CfgUIGrids.hpp b/addons/common/CfgUIGrids.hpp index 295a9098eb..1e8963e03e 100644 --- a/addons/common/CfgUIGrids.hpp +++ b/addons/common/CfgUIGrids.hpp @@ -3,7 +3,16 @@ class CfgUIGrids { class Presets { class Arma3 { class Variables { - grid_ACE_displayText[] = {{((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40)),safeZoneY + 0.175 * safezoneH, (10 *(((safezoneW / safezoneH) min 1.2) / 40)), (3 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))}, "(((safezoneW / safezoneH) min 1.2) / 40)","((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"}; + grid_ACE_displayText[] = { + { + "((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40))", + "safeZoneY + 0.175 * safezoneH", + "(10 *(((safezoneW / safezoneH) min 1.2) / 40))", + "(3 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))" + }, + "(((safezoneW / safezoneH) min 1.2) / 40)", + "((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)" + }; }; }; }; diff --git a/addons/common/CfgVehicles.hpp b/addons/common/CfgVehicles.hpp index 396d80b5c1..2e3a81d161 100644 --- a/addons/common/CfgVehicles.hpp +++ b/addons/common/CfgVehicles.hpp @@ -121,6 +121,7 @@ class CfgVehicles { class Land_HelipadEmpty_F; class ACE_LogicDummy: Land_HelipadEmpty_F { scope = 1; + scopeCurator = 0; SLX_XEH_DISABLED = 1; author = CSTRING(ACETeam); class EventHandlers { diff --git a/addons/common/CfgWeapons.hpp b/addons/common/CfgWeapons.hpp index 09a828e475..8662df8d82 100644 --- a/addons/common/CfgWeapons.hpp +++ b/addons/common/CfgWeapons.hpp @@ -39,4 +39,3 @@ class CfgWeapons { }; }; }; - diff --git a/addons/common/CfgWrapperUI.hpp b/addons/common/CfgWrapperUI.hpp new file mode 100644 index 0000000000..fd2282bcf5 --- /dev/null +++ b/addons/common/CfgWrapperUI.hpp @@ -0,0 +1,10 @@ +class CfgWrapperUI { + class Cursors { + class Arrow; + class GVAR(blank): Arrow { + // This texture has a single 99% transparent pixel and is otherwise blank + // The single pixel is necessary, otherwise appears as a black 32 px square + texture = QPATHTOF(data\blank_cursor_ca.paa); + }; + }; +}; diff --git a/addons/common/CompassControl.hpp b/addons/common/CompassControl.hpp index 899c609161..627e18d2f8 100644 --- a/addons/common/CompassControl.hpp +++ b/addons/common/CompassControl.hpp @@ -19,6 +19,7 @@ class RscPicture; class RscControlsGroupNoScrollbars; class GVAR(CompassControl): RscControlsGroupNoScrollbars { + #pragma hemtt suppress pw3_padded_arg onLoad = QUOTE(\ params ['_control'];\ private _display = ctrlParent _control;\ @@ -37,27 +38,28 @@ class GVAR(CompassControl): RscControlsGroupNoScrollbars { _display displayAddEventHandler [ARR_2('MouseMoving',_fnc_update)];\ _display displayAddEventHandler [ARR_2('MouseHolding',_fnc_update)];\ ); - x = LEFT; - y = TOP; - w = WIDTH; - h = HEIGHT; + x = QUOTE(LEFT); + y = QUOTE(TOP); + w = QUOTE(WIDTH); + h = QUOTE(HEIGHT); class controls { class Background: RscText { colorBackground[] = BACKGROUND_COLOR; x = 0; y = 0; - w = WIDTH; - h = HEIGHT; + w = QUOTE(WIDTH); + h = QUOTE(HEIGHT); }; class Pointer: RscText { colorBackground[] = POINTER_COLOR; - x = WIDTH/2 - WIDTH*POINTER_WIDTH_FACTOR/2; + x = QUOTE(WIDTH/2 - WIDTH*POINTER_WIDTH_FACTOR/2); y = 0; - w = WIDTH*POINTER_WIDTH_FACTOR; - h = HEIGHT; + w = QUOTE(WIDTH*POINTER_WIDTH_FACTOR); + h = QUOTE(HEIGHT); }; class CompassGroup: RscControlsGroupNoScrollbars { + #pragma hemtt suppress pw3_padded_arg onLoad = QUOTE(\ params ['_control'];\ private _display = ctrlParent _control;\ @@ -65,44 +67,44 @@ class GVAR(CompassControl): RscControlsGroupNoScrollbars { ); x = 0; y = 0; - w = 2*WIDTH; - h = 2*HEIGHT; + w = QUOTE(2*WIDTH); + h = QUOTE(2*HEIGHT); class controls { class Compass0: RscPicture { text = TEXTURE_0; - x = 0 * (WIDTH / 4); + x = QUOTE(0 * (WIDTH / 4)); y = 0; - w = WIDTH/4; - h = HEIGHT; + w = QUOTE(WIDTH/4); + h = QUOTE(HEIGHT); }; class Compass1: Compass0 { text = TEXTURE_1; - x = 1 * (WIDTH / 4); + x = QUOTE(1 * (WIDTH / 4)); }; class Compass2: Compass0 { text = TEXTURE_2; - x = 2 * (WIDTH / 4); + x = QUOTE(2 * (WIDTH / 4)); }; class Compass3: Compass0 { text = TEXTURE_3; - x = 3 * (WIDTH / 4); + x = QUOTE(3 * (WIDTH / 4)); }; class Compass4: Compass0 { text = TEXTURE_0; - x = 4 * (WIDTH / 4); + x = QUOTE(4 * (WIDTH / 4)); }; class Compass5: Compass0 { text = TEXTURE_1; - x = 5 * (WIDTH / 4); + x = QUOTE(5 * (WIDTH / 4)); }; class Compass6: Compass0 { text = TEXTURE_2; - x = 6 * (WIDTH / 4); + x = QUOTE(6 * (WIDTH / 4)); }; class Compass7: Compass0 { text = TEXTURE_3; - x = 7 * (WIDTH / 4); + x = QUOTE(7 * (WIDTH / 4)); }; }; }; diff --git a/addons/common/DisableMouseDialog.hpp b/addons/common/DisableMouseDialog.hpp new file mode 100644 index 0000000000..75689cf652 --- /dev/null +++ b/addons/common/DisableMouseDialog.hpp @@ -0,0 +1,17 @@ +class GVAR(DisableMouse_Dialog) { + idd = -1; + movingEnable = 0; + onLoad = QUOTE(with uiNameSpace do { GVAR(dlgDisableMouse) = _this # 0; };); + objects[] = {}; + class controlsBackground { + // Transparent map allows setting custom cursor + class Background: ctrlMapEmpty { + idc = 101; + fade = 1; + x = "safezoneXAbs"; + y = "safezoneY"; + w = "safezoneWAbs"; + h = "safezoneH"; + }; + }; +}; diff --git a/addons/common/HintConfig.hpp b/addons/common/HintConfig.hpp index e3912e56f3..c299bee8df 100644 --- a/addons/common/HintConfig.hpp +++ b/addons/common/HintConfig.hpp @@ -10,6 +10,11 @@ class GVAR(debug_structuredText): ctrlStructuredText { }; class RscTitles { + class GVAR(ProgressBar_Display): GVAR(ProgressBar_Dialog) { + duration = 1e11; // forever, essentially + fadeIn = 0; + fadeOut = 0; + }; class GVAR(watchVariableUI) { idd = -1; onLoad = QUOTE(with uiNameSpace do {GVAR(watchVariableUI) = _this select 0};); @@ -23,7 +28,7 @@ class RscTitles { class ACE_RscHint { idd = -1; onLoad = "uiNamespace setVariable ['ACE_ctrlHint', (_this select 0) displayCtrl 1];"; - movingEnable = false; + movingEnable = 0; duration = 4; fadeIn = 0.2; fadeOut = 0.2; @@ -37,10 +42,10 @@ class RscTitles { SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; colorText[] = {1, 1, 1, 1}; colorBackground[] = {0, 0, 0, 0.5}; - x = safeZoneW + safeZoneX - 0 * safezoneW; //safeZoneW + safeZoneX - 0.2 * safezoneW; - y = safeZoneY + 0.2 * safezoneH; - w = 0.2 * safeZoneW; - h = 0.1 * SafeZoneH; + x = "safeZoneW + safeZoneX - 0 * safezoneW"; //safeZoneW + safeZoneX - 0.2 * safezoneW; + y = "safeZoneY + 0.2 * safezoneH"; + w = "0.2 * safeZoneW"; + h = "0.1 * SafeZoneH"; font = "RobotoCondensed"; }; }; @@ -48,7 +53,7 @@ class RscTitles { class ACE_RscErrorHint { idd = -1; onLoad = "uiNamespace setVariable ['ACE_ctrlErrorHint', (_this select 0) displayCtrl 1];"; - movingEnable = false; + movingEnable = 0; duration = 999999; fadeIn = 0.2; fadeOut = 0.2; @@ -61,10 +66,10 @@ class RscTitles { SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; colorText[] = {1, 1, 1, 1}; colorBackground[] = {0.8, 0, 0, 0.5}; - x = 0.3 * safeZoneW + safeZoneX; - y = 0.4 * safezoneH + safeZoneY; - w = 0.4 * safeZoneW; - h = 0.2 * SafeZoneH; + x = "0.3 * safeZoneW + safeZoneX"; + y = "0.4 * safezoneH + safeZoneY"; + w = "0.4 * safeZoneW"; + h = "0.2 * SafeZoneH"; }; }; }; diff --git a/addons/common/ProgressScreen.hpp b/addons/common/ProgressScreen.hpp index 9b55ae33a3..bef2994e7d 100644 --- a/addons/common/ProgressScreen.hpp +++ b/addons/common/ProgressScreen.hpp @@ -1,19 +1,20 @@ class GVAR(ProgressBar_Dialog) { idd = -1; - movingEnable = false; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBG)),(_this select 0) displayCtrl 1)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBar)),(_this select 0) displayCtrl 2)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBarTitle)),(_this select 0) displayCtrl 3)];); + movingEnable = 0; + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(dlgProgress)),_this select 0)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBG)),(_this select 0) displayCtrl 1)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBar)),(_this select 0) displayCtrl 2)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBarTitle)),(_this select 0) displayCtrl 3)];); objects[] = {}; class controlsBackground { - class Background { - idc = -1; + class Background: ctrlMapEmpty { + idc = 101; moving = 0; + fade = 1; font = "TahomaB"; text = ""; sizeEx = 0; lineSpacing = 0; - type = 0; - style = 0; + style = 48; + type = 101; size = 1; colorBackground[] = {0, 0, 0, 0.0}; colorText[] = {0, 0, 0, 0}; @@ -49,29 +50,3 @@ class GVAR(ProgressBar_Dialog) { }; }; }; - -class GVAR(DisableMouse_Dialog) { - idd = -1; - movingEnable = false; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(dlgDisableMouse)),_this select 0)];); - objects[] = {}; - class controlsBackground { - class Background { - idc = -1; - moving = 0; - font = "TahomaB"; - text = ""; - sizeEx = 0; - lineSpacing = 0; - type = 0; - style = 0; - size = 1; - colorBackground[] = {0, 0, 0, 0};//0.5 - colorText[] = {0, 0, 0, 0}; - x = "safezoneX"; - y = "safezoneY"; - w = "safezoneW"; - h = "safezoneH"; - }; - }; -}; diff --git a/addons/common/README.md b/addons/common/README.md index 04f0eb04c4..c340967821 100644 --- a/addons/common/README.md +++ b/addons/common/README.md @@ -2,13 +2,3 @@ ace_common ========== Common functions and systems used by other components. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [NouberNou](https://github.com/NouberNou) -- [commy2](https://github.com/commy2) -- [walterpearce](https://github.com/walterpearce) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/common/RscInfoType.hpp b/addons/common/RscInfoType.hpp index 0eadb83617..672d043276 100644 --- a/addons/common/RscInfoType.hpp +++ b/addons/common/RscInfoType.hpp @@ -2,107 +2,107 @@ class RscInGameUI { class RscUnitInfo; class RscUnitInfoNoHUD { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscUnitInfoSoldier: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSoldier', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Soldier')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSoldier',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Soldier')])] call CBA_fnc_localEvent;); }; class RscUnitInfoTank: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgVehicle', _this select 0)];); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgVehicle',_this select 0)];); }; class RscUnitInfoAirNoWeapon: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)];); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft',_this select 0)];); }; class RscUnitInfoAir: RscUnitInfoAirNoWeapon { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)];); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft',_this select 0)];); }; class RscUnitInfo_AH64D_gunner { - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Aircraft')])] call CBA_fnc_localEvent;); + onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgAircraft',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Aircraft')])] call CBA_fnc_localEvent;); }; class RscUnitInfoUAV { - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgUAV', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'UAV')])] call CBA_fnc_localEvent;); + onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgUAV',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'UAV')])] call CBA_fnc_localEvent;); }; class RscUnitInfoSubmarine: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSubmarine', _this select 0)];); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSubmarine',_this select 0)];); }; class RscUnitInfoShip: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgShip', _this select 0)];); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgShip',_this select 0)];); }; class RscWeaponEmpty { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeFinder { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeArtillery { - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgArtillery', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Artillery')])] call CBA_fnc_localEvent;); + onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgArtillery',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Artillery')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeArtilleryAuto { - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgArtillery', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Artillery')])] call CBA_fnc_localEvent;); + onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_dlgArtillery',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Artillery')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeFinderPAS13 { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscOptics_LaserDesignator { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeFinderMAAWS { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeFinderAbramsCom { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeFinderAbramsGun { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscWeaponRangeFinderStrykerMGSGun { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscOptics_strider_commander { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscOptics_titan { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscOptics_punisher { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscOptics_SDV_periscope { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscUnitInfoParachute: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgParachute', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Parachute')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgParachute',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Parachute')])] call CBA_fnc_localEvent;); }; class RscUnitVehicle { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscOptics_LaserDesignator_02 { - onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Any')])] call CBA_fnc_localEvent;); }; class RscStaminaBar { @@ -110,6 +110,6 @@ class RscInGameUI { }; class RscStanceInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscStanceInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Stance')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscStanceInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Stance')])] call CBA_fnc_localEvent;); }; }; diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index a331837fb2..3a5838a230 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -10,7 +10,10 @@ PREP(readSettingsFromParamsArray); PREP(actionKeysNamesConverted); PREP(addCanInteractWithCondition); PREP(addLineToDebugDraw); +PREP(addSwayFactor); PREP(addToInventory); +PREP(addWeapon); +PREP(adjustMagazineAmmo); PREP(assignedItemFix); PREP(assignObjectsInList); PREP(ambientBrightness); @@ -25,8 +28,11 @@ PREP(canGetInPosition); PREP(canInteractWith); PREP(changeProjectileDirection); PREP(checkFiles); +PREP(checkFiles_diagnoseACE); PREP(checkPBOs); +PREP(checkVersionNumber); PREP(claim); +PREP(claimSafeServer); PREP(codeToString); PREP(createOrthonormalReference); PREP(currentChannel); @@ -49,20 +55,24 @@ PREP(dropBackpack); PREP(endRadioTransmission); PREP(eraseCache); PREP(errorMessage); +PREP(escapeRegex); PREP(findUnloadPosition); PREP(firedEH); PREP(fixCollision); PREP(fixFloating); PREP(fixLoweredRifleAnimation); PREP(fixPosition); +PREP(getAddon); PREP(getAllDefinedSetVariables); PREP(getAwakeAnim); +PREP(getConfigName); PREP(getCountOfItem); PREP(getDeathAnim); PREP(getDefaultAnim); PREP(getDefinedVariable); PREP(getDefinedVariableDefault); PREP(getDefinedVariableInfo); +PREP(getFiremodeIndex); PREP(getFirstObjectIntersection); PREP(getFirstTerrainIntersection); PREP(getGunner); @@ -94,6 +104,7 @@ PREP(getWeaponAzimuthAndInclination); PREP(getWeaponIndex); PREP(getWeaponState); PREP(getWeight); +PREP(getWheelHitPointsWithSelections); PREP(getWindDirection); PREP(getZoom); PREP(goKneeling); @@ -103,6 +114,7 @@ PREP(handleModifierKey); PREP(handleModifierKeyUp); PREP(hasItem); PREP(hasMagazine); +PREP(hasZeusAccess); PREP(headBugFix); PREP(hideUnit); PREP(interpolateFromArray); @@ -110,7 +122,6 @@ PREP(inTransitionAnim); PREP(isAwake); PREP(isEngineer); PREP(isEOD); -PREP(isFeatureCameraActive); PREP(isInBuilding); PREP(isMedic); PREP(isModLoaded); @@ -126,7 +137,6 @@ PREP(muteUnitHandleInitPost); PREP(muteUnitHandleRespawn); PREP(nearestVehiclesFreeSeat); PREP(numberToDigits); -PREP(numberToDigitsString); PREP(numberToString); PREP(onAnswerRequest); PREP(owned); @@ -138,11 +148,14 @@ PREP(positionToASL); PREP(progressBar); PREP(readSettingFromModule); PREP(receiveRequest); +PREP(registerItemReplacement); PREP(removeCanInteractWithCondition); PREP(removeSpecificMagazine); +PREP(replaceRegisteredItems); PREP(requestCallback); PREP(resetAllDefaults); PREP(restoreVariablesJIP); +PREP(rscObjectHelper); PREP(runAfterSettingsInit); PREP(runTests); PREP(sanitizeString); @@ -150,6 +163,7 @@ PREP(sendRequest); PREP(serverLog); PREP(setAimCoef); PREP(setApproximateVariablePublic); +PREP(setDead); PREP(setDefinedVariable); PREP(setDisableUserInputStatus); PREP(setHearingCapability); @@ -171,8 +185,10 @@ PREP(statusEffect_resetVariables); PREP(statusEffect_respawnEH); PREP(statusEffect_sendEffects); PREP(statusEffect_set); +PREP(stopGesture); PREP(stringCompare); PREP(stringToColoredText); +PREP(swayLoop); PREP(switchPersistentLaser); PREP(switchToGroupSide); PREP(throttledPublicVariable); @@ -180,11 +196,14 @@ PREP(toBin); PREP(toBitmask); PREP(toHex); PREP(toNumber); +PREP(throwWeapon); PREP(unhideUnit); PREP(uniqueElements); PREP(uniqueItems); +PREP(uniqueUnitItems); PREP(unloadPerson); PREP(unloadPersonLocal); +PREP(unloadUnitWeapon); PREP(unmuteUnit); PREP(useItem); PREP(useMagazine); @@ -248,6 +267,7 @@ PREP(_handleRequestAllSyncedEvents); PREP(addActionEventHandler); PREP(addActionMenuEventHandler); PREP(addMapMarkerCreatedEventHandler); +PREP(addPlayerEH); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 6a7f1a61e2..b569a4608e 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -18,14 +18,18 @@ ////////////////////////////////////////////////// //Status Effect EHs: -[QGVAR(setStatusEffect), {_this call FUNC(statusEffect_set)}] call CBA_fnc_addEventHandler; -["forceWalk", false, ["ace_advanced_fatigue", "ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches"]] call FUNC(statusEffect_addType); -["blockSprint", false, ["ace_advanced_fatigue", "ace_medical_fracture"]] call FUNC(statusEffect_addType); +[QGVAR(setStatusEffect), LINKFUNC(statusEffect_set)] call CBA_fnc_addEventHandler; +["forceWalk", false, ["ace_advanced_fatigue", "ACE_SwitchUnits", "ACE_Attach", "ace_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches", "ace_medical_fracture"]] call FUNC(statusEffect_addType); +["blockSprint", false, ["ace_advanced_fatigue", "ace_dragging", "ace_medical_fracture"]] call FUNC(statusEffect_addType); ["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered)]] call FUNC(statusEffect_addType); ["blockDamage", false, ["fixCollision", "ACE_cargo"]] call FUNC(statusEffect_addType); ["blockEngine", false, ["ACE_Refuel"]] call FUNC(statusEffect_addType); -["blockThrow", false, ["ACE_Attach", "ACE_concertina_wire", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_rearm", "ACE_refuel", "ACE_Sandbag", "ACE_Trenches", "ACE_tripod"]] call FUNC(statusEffect_addType); +["blockThrow", false, ["ACE_Attach", "ACE_concertina_wire", "ace_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_rearm", "ACE_refuel", "ACE_Sandbag", "ACE_Trenches", "ACE_tripod"]] call FUNC(statusEffect_addType); ["setHidden", true, ["ace_unconscious"]] call FUNC(statusEffect_addType); +["blockRadio", false, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered), "ace_unconscious"]] call FUNC(statusEffect_addType); +["blockSpeaking", false, ["ace_unconscious"]] call FUNC(statusEffect_addType); +["disableWeaponAssembly", false, ["ace_common", "ace_common_lockVehicle", "ace_csw"]] call FUNC(statusEffect_addType); +["lockInventory", true, [], true] call FUNC(statusEffect_addType); [QGVAR(forceWalk), { params ["_object", "_set"]; @@ -71,6 +75,31 @@ }; }] call CBA_fnc_addEventHandler; +[QGVAR(blockRadio), { + params ["_object", "_set"]; + TRACE_2("blockRadio EH",_object,_set); + if (_object isEqualTo ACE_Player && {_set > 0}) then { + call FUNC(endRadioTransmission); + }; + if (["task_force_radio"] call FUNC(isModLoaded)) then { + _object setVariable ["tf_unable_to_use_radio", _set > 0, true]; + }; + if (["acre_main"] call FUNC(isModLoaded)) then { + _object setVariable ["acre_sys_core_isDisabledRadio", _set > 0, true]; + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(blockSpeaking), { + params ["_object", "_set"]; + TRACE_2("blockSpeaking EH",_object,_set); + if (["acre_main"] call FUNC(isModLoaded)) then { + _object setVariable ["acre_sys_core_isDisabled", _set > 0, true]; + }; + if (["task_force_radio"] call FUNC(isModLoaded)) then { + _object setVariable ["tf_voiceVolume", parseNumber (_set == 0), true]; + }; +}] call CBA_fnc_addEventHandler; + [QGVAR(blockDamage), { //Name reversed from `allowDamage` because we want NOR logic params ["_object", "_set"]; if ((_object isKindOf "CAManBase") && {(["ace_medical"] call FUNC(isModLoaded))}) then { @@ -93,6 +122,17 @@ _object setMass _mass; }] call CBA_fnc_addEventHandler; +[QGVAR(disableWeaponAssembly), { + params ["_object", "_set"]; + _object enableWeaponDisassembly (_set < 1); +}] call CBA_fnc_addEventHandler; + +[QGVAR(lockInventory), { + params ["_object", "_set"]; + TRACE_2("lockInventory EH",_object,_set); + _object lockInventory (_set > 0); +}] call CBA_fnc_addEventHandler; + //Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit //This variable is used for isPlayer checks if (isServer) then { @@ -102,11 +142,10 @@ if (isServer) then { if ((!isNil "_zeusLogic") && {!isNull _zeusLogic}) then { { if ((_x getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]) isEqualTo _dcPlayer) exitWith { - INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`", [_x] call FUNC(getName), _dcPlayer, _x); + INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`",[_x] call FUNC(getName),_dcPlayer,_x); _x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true]; }; - nil - } count (curatorEditableObjects _zeusLogic); + } forEach (curatorEditableObjects _zeusLogic); }; }]; }; @@ -117,20 +156,26 @@ if (isServer) then { INFO_2("Headbug Used: Name: %1, Animation: %2",_profileName,_animation); }] call CBA_fnc_addEventHandler; -[QGVAR(fixCollision), FUNC(fixCollision)] call CBA_fnc_addEventHandler; -[QGVAR(fixFloating), FUNC(fixFloating)] call CBA_fnc_addEventHandler; -[QGVAR(fixPosition), FUNC(fixPosition)] call CBA_fnc_addEventHandler; +[QGVAR(fixCollision), LINKFUNC(fixCollision)] call CBA_fnc_addEventHandler; +[QGVAR(fixFloating), LINKFUNC(fixFloating)] call CBA_fnc_addEventHandler; +[QGVAR(fixPosition), LINKFUNC(fixPosition)] call CBA_fnc_addEventHandler; -["ace_loadPersonEvent", 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]; _this lock 2; + if ([] isNotEqualTo getArray (configOf _this >> "assembleInfo" >> "dissasembleTo")) then { + [_this, "disableWeaponAssembly", QGVAR(lockVehicle), true] call FUNC(statusEffect_set); + }; }] call CBA_fnc_addEventHandler; [QGVAR(unlockVehicle), { _this lock (_this getVariable [QGVAR(lockStatus), locked _this]); + if ([] isNotEqualTo getArray (configOf _target >> "assembleInfo" >> "dissasembleTo")) then { + [_this, "disableWeaponAssembly", QGVAR(lockVehicle), false] call FUNC(statusEffect_set); + }; }] call CBA_fnc_addEventHandler; [QGVAR(setDir), {(_this select 0) setDir (_this select 1)}] call CBA_fnc_addEventHandler; @@ -146,6 +191,7 @@ if (isServer) then { [QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler; +[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; [QGVAR(setVanillaHitPointDamage), { params ["_object", "_hitPointAnddamage"]; @@ -163,8 +209,8 @@ if (isServer) then { }] call CBA_fnc_addEventHandler; // Request framework -[QGVAR(requestCallback), FUNC(requestCallback)] call CBA_fnc_addEventHandler; -[QGVAR(receiveRequest), FUNC(receiveRequest)] call CBA_fnc_addEventHandler; +[QGVAR(requestCallback), LINKFUNC(requestCallback)] call CBA_fnc_addEventHandler; +[QGVAR(receiveRequest), LINKFUNC(receiveRequest)] call CBA_fnc_addEventHandler; [QGVAR(systemChatGlobal), {systemChat _this}] call CBA_fnc_addEventHandler; @@ -173,9 +219,13 @@ if (isServer) then { [QGVAR(enableSimulationGlobal), {(_this select 0) enableSimulationGlobal (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setShotParents), {(_this select 0) setShotParents [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; ["ace_setOwner", {(_this select 0) setOwner (_this select 1)}] call CBA_fnc_addEventHandler; - [QGVAR(serverLog), FUNC(serverLog)] call CBA_fnc_addEventHandler; + [QGVAR(serverLog), LINKFUNC(serverLog)] call CBA_fnc_addEventHandler; + [QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler; }; +["CBA_SettingChanged", { + ["ace_settingChanged", _this] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// // Set up remote execution @@ -189,14 +239,14 @@ if (!isServer) then { ["ACEa", [player]] call CBA_fnc_serverEvent; }] call CBA_fnc_addEventHandler; } else { - ["ACEa", FUNC(_handleRequestAllSyncedEvents)] call CBA_fnc_addEventHandler; + ["ACEa", LINKFUNC(_handleRequestAllSyncedEvents)] call CBA_fnc_addEventHandler; }; -["ACEe", FUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; -["ACEs", FUNC(_handleRequestSyncedEvent)] call CBA_fnc_addEventHandler; +["ACEe", LINKFUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; +["ACEs", LINKFUNC(_handleRequestSyncedEvent)] call CBA_fnc_addEventHandler; if (isServer) then { - [FUNC(syncedEventPFH), 0.5, []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(syncedEventPFH), 0.5, []] call CBA_fnc_addPerFrameHandler; }; @@ -204,7 +254,7 @@ if (isServer) then { // Check files, previous installed version etc. ////////////////////////////////////////////////// -private _currentVersion = getText (configFile >> "CfgPatches" >> QUOTE(ADDON) >> "version"); +private _currentVersion = getText (configFile >> "CfgPatches" >> QUOTE(ADDON) >> "versionStr"); private _previousVersion = profileNamespace getVariable ["ACE_VersionNumberString", ""]; // check previous version number from profile @@ -221,7 +271,7 @@ call FUNC(checkFiles); // Set up ace_settingsInitialized eventhandler ////////////////////////////////////////////////// -["ace_settingsInitialized", { +["CBA_settingsInitialized", { [ GVAR(checkPBOsAction), GVAR(checkPBOsCheckAll), @@ -251,8 +301,7 @@ enableCamShake true; //FUNC(showHud) needs to be refreshed if it was set during mission init ["ace_infoDisplayChanged", { - GVAR(showHudHash) params ["", "", "_masks"]; - if !(_masks isEqualTo []) then { + if (GVAR(showHudHash) isNotEqualTo createHashMap) then { [] call FUNC(showHud); }; }] call CBA_fnc_addEventHandler; @@ -273,7 +322,7 @@ enableCamShake true; if (alive _oldPlayer) then { [FUNC(setName), [_oldPlayer]] call CBA_fnc_execNextFrame; }; -}] call CBA_fnc_addPlayerEventHandler; +}, true] call CBA_fnc_addPlayerEventHandler; ////////////////////////////////////////////////// @@ -312,10 +361,10 @@ 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 { + switch (toLowerANSI _position) do { case (""): { _UAV = objNull; // set to objNull if not actively controlling }; @@ -346,8 +395,8 @@ addMissionEventHandler ["PlayerViewChanged", { // Eventhandlers for player controlled machines ////////////////////////////////////////////////// -[QGVAR(displayTextStructured), {_this call FUNC(displayTextStructured)}] call CBA_fnc_addEventHandler; -[QGVAR(displayTextPicture), {_this call FUNC(displayTextPicture)}] call CBA_fnc_addEventHandler; +[QGVAR(displayTextStructured), LINKFUNC(displayTextStructured)] call CBA_fnc_addEventHandler; +[QGVAR(displayTextPicture), LINKFUNC(displayTextPicture)] call CBA_fnc_addEventHandler; ["ace_unconscious", { params ["_unit", "_isUnconscious"]; @@ -357,7 +406,7 @@ addMissionEventHandler ["PlayerViewChanged", { }; }] call CBA_fnc_addEventHandler; -["ace_useItem", DFUNC(useItem)] call CBA_fnc_addEventHandler; +["ace_useItem", LINKFUNC(useItem)] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// @@ -375,61 +424,110 @@ addMissionEventHandler ["PlayerViewChanged", { params ["_unit", "_target"]; // Players can always interact with himself if not boarded - vehicle _unit == _unit || + isNull objectParent _unit || // Players can always interact with his vehicle - {vehicle _unit == _target} || + {objectParent _unit isEqualTo _target} || // Players can always interact with passengers of the same vehicle - {_unit != _target && {vehicle _unit == vehicle _target}} || + {_unit isNotEqualTo _target && {!isNull objectParent _target} && {objectParent _unit isEqualTo objectParent _target}} || // Players can always interact with connected UAV {!(isNull (ACE_controlledUAV select 0))} }] call FUNC(addCanInteractWithCondition); ["isNotInZeus", {isNull curatorCamera}] call FUNC(addCanInteractWithCondition); +["isNotUnconscious", { + params ["_unit"]; + lifeState _unit isNotEqualTo "INCAPACITATED" +}] call FUNC(addCanInteractWithCondition); + ////////////////////////////////////////////////// // Set up reload mutex ////////////////////////////////////////////////// GVAR(isReloading) = false; +GVAR(reloadMutex_lastMagazines) = []; +// When reloading, the new magazine is removed from inventory, an animation plays and then the old magazine is added +// If the animation is interrupted, the new magazine will be lost +["loadout", { + params ["_unit", "_newLoadout"]; + private _mags = magazines _unit; + // if our magazine count dropped by 1, we might be reloading + if ((count GVAR(reloadMutex_lastMagazines)) - (count _mags) == 1) then { + private _weapon = currentWeapon _unit; + private _muzzle = currentMuzzle _unit; + if (_weapon == "") exitWith {}; + private _wpnMzlConfig = configFile >> "CfgWeapons" >> _weapon; + if (_muzzle != _weapon) then { _wpnMzlConfig = _wpnMzlConfig >> _muzzle; }; -["keyDown", { - if ((_this select 1) in actionKeys "ReloadMagazine" && {alive ACE_player}) then { - //Ignore mounted (except ffv) - if (!(player call CBA_fnc_canUseWeapon)) exitWith {}; - private _weapon = currentWeapon ACE_player; + private _compatMags = [_wpnMzlConfig] call CBA_fnc_compatibleMagazines; + private _lastCompatMagCount = {_x in _compatMags} count GVAR(reloadMutex_lastMagazines); + private _curCompatMagCount = {_x in _compatMags} count _mags; + TRACE_3("",_wpnMzlConfig,_lastCompatMagCount,_curCompatMagCount); + if (_lastCompatMagCount - _curCompatMagCount != 1) exitWith {}; // check if magazines for our specific muzzle dropped by 1 - if (_weapon != "") then { - private _muzzle = currentMuzzle ACE_player; - private _wpnConfig = configFile >> "CfgWeapons" >> _weapon; - private _gesture = getText ([_wpnConfig >> _muzzle, _wpnConfig] select (_weapon isEqualTo _muzzle) >> "reloadAction"); - if (_gesture == "") exitWith {}; //Ignore weapons with no reload gesture (binoculars) - private _isLauncher = _weapon isKindOf ["Launcher", configFile >> "CfgWeapons"]; - private _config = ["CfgGesturesMale", "CfgMovesMaleSdr"] select _isLauncher; - private _duration = getNumber (configfile >> _config >> "States" >> _gesture >> "speed"); + private _gesture = getText (_wpnMzlConfig >> "reloadAction"); + if (_gesture == "") exitWith {}; //Ignore weapons with no reload gesture (binoculars) + private _isLauncher = _weapon isKindOf ["Launcher", configFile >> "CfgWeapons"]; + private _duration = 0; + if (_isLauncher) then { + _duration = getNumber (configfile >> "CfgMovesMaleSdr" >> "States" >> _gesture >> "speed"); + }; + if (_duration == 0) then { + _duration = getNumber (configfile >> "CfgGesturesMale" >> "States" >> _gesture >> "speed"); + }; - if (_duration != 0) then { - _duration = if (_duration < 0) then { abs _duration } else { 1 / _duration }; - } else { - _duration = 3; - }; + if (_duration != 0) then { + _duration = if (_duration < 0) then { abs _duration } else { 1 / _duration }; + } else { + _duration = 6; + }; - TRACE_2("Reloading, blocking gestures",_weapon,_duration); - GVAR(reloadingETA) = CBA_missionTime + _duration; + TRACE_2("Reloading, blocking gestures",_weapon,_duration); + GVAR(reloadingETA) = CBA_missionTime + _duration; - if (!GVAR(isReloading)) then { - GVAR(isReloading) = true; + if (!GVAR(isReloading)) then { + GVAR(isReloading) = true; - [{ - CBA_missionTime > GVAR(reloadingETA) - },{ - GVAR(isReloading) = false; - }] call CBA_fnc_waitUntilAndExecute; - }; + [{ + CBA_missionTime > GVAR(reloadingETA) + },{ + GVAR(isReloading) = false; + }] call CBA_fnc_waitUntilAndExecute; }; }; + GVAR(reloadMutex_lastMagazines) = _mags; +}, true] call CBA_fnc_addPlayerEventHandler; - false -}] call CBA_fnc_addDisplayHandler; +////////////////////////////////////////////////// +// Start the sway loop +////////////////////////////////////////////////// +["CBA_settingsInitialized", { + ["multiplier", { + switch (true) do { + case (isWeaponRested ACE_player): { + GVAR(swayFactor) * GVAR(restedSwayFactor) + }; + case (isWeaponDeployed ACE_player): { + GVAR(swayFactor) * GVAR(deployedSwayFactor) + }; + default { + GVAR(swayFactor) + }; + }; + }, QUOTE(ADDON)] call FUNC(addSwayFactor); + + [{ + // frame after settingsInitialized to ensure all other addons have added their factors + if (GVAR(enableSway)) then { + call FUNC(swayLoop); + }; + // check for pre-3.16 sway factors being added + if (!isNil {missionNamespace getVariable "ACE_setCustomAimCoef"}) then { + WARNING("ACE_setCustomAimCoef no longer supported - use ace_common_fnc_addSwayFactor"); + WARNING_1("source: %1",(missionNamespace getVariable "ACE_setCustomAimCoef") apply {_x}); + }; + }] call CBA_fnc_execNextFrame; +}] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// // Set up PlayerJIP eventhandler @@ -458,14 +556,14 @@ GVAR(deviceKeyHandlingArray) = []; GVAR(deviceKeyCurrentIndex) = -1; // Register localizations for the Keybinding categories -["ACE3 Equipment", localize LSTRING(ACEKeybindCategoryEquipment)] call CBA_fnc_registerKeybindModPrettyName; -["ACE3 Common", localize LSTRING(ACEKeybindCategoryCommon)] call CBA_fnc_registerKeybindModPrettyName; -["ACE3 Weapons", localize LSTRING(ACEKeybindCategoryWeapons)] call CBA_fnc_registerKeybindModPrettyName; -["ACE3 Movement", localize LSTRING(ACEKeybindCategoryMovement)] call CBA_fnc_registerKeybindModPrettyName; -["ACE3 Scope Adjustment", localize LSTRING(ACEKeybindCategoryScopeAdjustment)] call CBA_fnc_registerKeybindModPrettyName; -["ACE3 Vehicles", localize LSTRING(ACEKeybindCategoryVehicles)] call CBA_fnc_registerKeybindModPrettyName; +["ACE3 Equipment", LLSTRING(ACEKeybindCategoryEquipment)] call CBA_fnc_registerKeybindModPrettyName; +["ACE3 Common", LLSTRING(ACEKeybindCategoryCommon)] call CBA_fnc_registerKeybindModPrettyName; +["ACE3 Weapons", LLSTRING(ACEKeybindCategoryWeapons)] call CBA_fnc_registerKeybindModPrettyName; +["ACE3 Movement", LLSTRING(ACEKeybindCategoryMovement)] call CBA_fnc_registerKeybindModPrettyName; +["ACE3 Scope Adjustment", LLSTRING(ACEKeybindCategoryScopeAdjustment)] call CBA_fnc_registerKeybindModPrettyName; +["ACE3 Vehicles", LLSTRING(ACEKeybindCategoryVehicles)] call CBA_fnc_registerKeybindModPrettyName; -["ACE3 Equipment", QGVAR(openDevice), (localize "STR_ACE_Common_toggleHandheldDevice"), { +["ACE3 Equipment", QGVAR(openDevice), LLSTRING(toggleHandheldDevice), { [] call FUNC(deviceKeyFindValidIndex); if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false}; [] call ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 3); @@ -474,7 +572,7 @@ GVAR(deviceKeyCurrentIndex) = -1; {false}, [0xC7, [false, false, false]], false] call CBA_fnc_addKeybind; //Home Key -["ACE3 Equipment", QGVAR(closeDevice), (localize "STR_ACE_Common_closeHandheldDevice"), { +["ACE3 Equipment", QGVAR(closeDevice), LLSTRING(closeHandheldDevice), { [] call FUNC(deviceKeyFindValidIndex); if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false}; [] call ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 4); @@ -483,7 +581,7 @@ GVAR(deviceKeyCurrentIndex) = -1; {false}, [0xC7, [false, true, false]], false] call CBA_fnc_addKeybind; //CTRL + Home Key -["ACE3 Equipment", QGVAR(cycleDevice), (localize "STR_ACE_Common_cycleHandheldDevices"), { +["ACE3 Equipment", QGVAR(cycleDevice), LLSTRING(cycleHandheldDevices), { [1] call FUNC(deviceKeyFindValidIndex); if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false}; private _displayName = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 0); @@ -494,4 +592,40 @@ GVAR(deviceKeyCurrentIndex) = -1; {false}, [0xC7, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + Home Key + +["ACE3 Weapons", QGVAR(unloadWeapon), LSTRING(unloadWeapon), { + private _unit = ACE_player; + + // Conditions + if !([_unit, objNull, ["isNotInside"]] call FUNC(canInteractWith)) exitWith {false}; + + if !(_unit call CBA_fnc_canUseWeapon) exitWith {false}; + + (weaponState _unit) params ["_weapon", "_muzzle", "", "_magazine", "_ammo"]; + + // Check if there is any ammo + if (_ammo < 1) exitWith {false}; + + // Check if the unit has a weapon + if (_weapon == "") exitWith {false}; + + // Check if the unit has a weapon selected + if !(_weapon in [primaryWeapon _unit, handgunWeapon _unit, secondaryWeapon _unit]) exitWith {false}; + + // Statement + [_unit, _weapon, _muzzle, _magazine, _ammo, false] call FUNC(unloadUnitWeapon); + + true +}, {false}, [19, [false, false, true]], false] call CBA_fnc_addKeybind; // Alt + R + +["CBA_loadoutSet", { + params ["_unit", "_loadout"]; + _loadout params ["_primaryWeaponArray"]; + + if ((_primaryWeaponArray param [0, ""]) == "ACE_FakePrimaryWeapon") then { + TRACE_1("Ignoring fake gun",_primaryWeaponArray); + _loadout set [0, []]; + }; +}] call CBA_fnc_addEventHandler; + GVAR(commonPostInited) = true; diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 7713ce07ee..b559cb5dd9 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -7,13 +7,22 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(syncedEvents) = [] call CBA_fnc_hashCreate; -GVAR(showHudHash) = [] call CBA_fnc_hashCreate; -GVAR(vehicleIconCache) = call CBA_fnc_createNamespace; // for getVehicleIcon +GVAR(syncedEvents) = createHashMap; +GVAR(showHudHash) = createHashMap; +GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon +GVAR(wheelSelections) = createHashMap; + +GVAR(blockItemReplacement) = false; + +// Cache for FUNC(isModLoaded) +GVAR(isModLoadedCache) = createHashMap; GVAR(settingsInitFinished) = false; GVAR(runAtSettingsInitialized) = []; +GVAR(swayFactorsBaseline) = []; +GVAR(swayFactorsMultiplier) = []; + // @todo: Generic local-managed global-synced objects (createVehicleLocal) //Debug @@ -24,6 +33,7 @@ ACE_COUNTERS = []; GVAR(statusEffect_Names) = []; GVAR(statusEffect_isGlobal) = []; +GVAR(statusEffect_sendJIP) = []; GVAR(setHearingCapabilityMap) = []; @@ -56,10 +66,20 @@ GVAR(hexArray) = [ "F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF" ]; +GVAR(canDigSurfaces) = createHashMapFromArray [ + ["int_concrete",false],["int_pavement_exp",false],["int_solidwood_exp",false],["tiling",false],["roof_tiles",false],["stony",false], + ["wavymetal",false],["int_wood",false],["int_tiles",false],["softwood_exp",false],["int_concrete_exp",false],["tiles_int",false], + ["metalplate_exp",false],["int_metalplate_exp",false],["steel_exp",false],["metal",false],["int_lino_exp",false],["metal_int",false], + ["wavymetal_exp",false],["int_metal",false],["asphalt_exp",false],["pavement_exp",false],["gridmetal_exp",false], + ["rooftiles_exp",false],["rock",false],["int_mat_exp",false],["wood_int",false],["concrete_int",false],["tarmac",false],["wood",false], + ["roof_tin",false],["lino_exp",false],["concrete",false],["int_softwood_exp",false], ["concrete_exp",false],["stones_exp",false], + ["forest_exp",true],["snow",true],["grasstall_exp",true],["grass",true] +]; + isHC = !hasInterface && !isDedicated; // deprecated because no tag missionNamespace setVariable ["ACE_isHC", ACE_isHC]; uiNamespace setVariable ["ACE_isHC", ACE_isHC]; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/common/XEH_preStart.sqf b/addons/common/XEH_preStart.sqf index 022888575e..208adea7b1 100644 --- a/addons/common/XEH_preStart.sqf +++ b/addons/common/XEH_preStart.sqf @@ -1,3 +1,17 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +if (isFilePatchingEnabled) then { + private _notLoaded = configProperties [configfile >> "ace_notLoaded", "isText _x"]; + { + INFO_2("%1 not loaded because %2",configName _x,getText _x); + } forEach _notLoaded; +}; + +// These functions are used for the ace arsenal, one of which are called in preStart (ace_arsenal_fnc_scanConfig) +// Cache for FUNC(getAddon) +uiNamespace setVariable [QGVAR(addonCache), createHashMap]; + +// Cache for FUNC(getConfigName) +uiNamespace setVariable [QGVAR(configNames), createHashMap]; diff --git a/addons/common/config.cpp b/addons/common/config.cpp index 44af1ee7ce..144e7d96c6 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -4,28 +4,28 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {"ACE_Box_Misc", "ACE_bananaItem", "ACE_Flag_Black", "ACE_Flag_White"}; - weapons[] = {"ACE_ItemCore","ACE_FakePrimaryWeapon", "ACE_Banana"}; + weapons[] = {"ACE_ItemCore", "ACE_FakePrimaryWeapon", "ACE_Banana"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_main","ace_modules"}; author = CSTRING(ACETeam); authors[] = {"KoffeinFlummi"}; url = ECSTRING(main,URL); - VERSION_CONFIG_COMMON; + VERSION_CONFIG; }; }; -#include "CfgEventHandlers.hpp" - -#include "CfgLocationTypes.hpp" -#include "CfgSounds.hpp" -#include "CfgVehicles.hpp" -#include "CfgWeapons.hpp" -#include "CfgMagazines.hpp" - -#include "CfgMoves.hpp" -#include "CfgVoice.hpp" -#include "CfgUnitInsignia.hpp" #include "CfgEden.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgLocationTypes.hpp" +#include "CfgGesturesMale.hpp" +#include "CfgMagazines.hpp" +#include "CfgMoves.hpp" +#include "CfgSounds.hpp" +#include "CfgUnitInsignia.hpp" +#include "CfgVehicles.hpp" +#include "CfgVoice.hpp" +#include "CfgWeapons.hpp" +#include "CfgWrapperUI.hpp" class ACE_Rsc_Display_Base { idd = -1; @@ -59,19 +59,21 @@ class ACE_Rsc_Control_Base { h = 0; }; +class ctrlMapEmpty; + #include "ACE_Settings.hpp" #include "define.hpp" -#include -#include -#include +#include "ProgressScreen.hpp" +#include "DisableMouseDialog.hpp" +#include "HintConfig.hpp" +#include "RscInfoType.hpp" #include "CompassControl.hpp" #include "CfgUIGrids.hpp" -class ACE_Extensions { - extensions[] = {}; -}; +class ACE_Extensions {}; class ACE_Tests { vehicleTransportInventory = QPATHTOF(dev\test_vehicleInventory.sqf); mapConfigs = QPATHTOF(dev\test_mapConfigs.sqf); + cfgPatches = QPATHTOF(dev\test_cfgPatches.sqf); }; diff --git a/addons/common/data/blank_cursor_ca.paa b/addons/common/data/blank_cursor_ca.paa new file mode 100644 index 0000000000..8af652c087 Binary files /dev/null and b/addons/common/data/blank_cursor_ca.paa differ diff --git a/addons/common/define.hpp b/addons/common/define.hpp index f25892b6d7..ce8765ec9f 100644 --- a/addons/common/define.hpp +++ b/addons/common/define.hpp @@ -1,125 +1,106 @@ - #ifndef ACE_DEFINE_H #define ACE_DEFINE_H // define.hpp -#define true 1 -#define false 0 +#define true 1 +#define false 0 -#define CT_STATIC 0 -#define CT_BUTTON 1 -#define CT_EDIT 2 -#define CT_SLIDER 3 -#define CT_COMBO 4 -#define CT_LISTBOX 5 -#define CT_TOOLBOX 6 -#define CT_CHECKBOXES 7 -#define CT_PROGRESS 8 -#define CT_HTML 9 -#define CT_STATIC_SKEW 10 -#define CT_ACTIVETEXT 11 -#define CT_TREE 12 +#define CT_STATIC 0 +#define CT_BUTTON 1 +#define CT_EDIT 2 +#define CT_SLIDER 3 +#define CT_COMBO 4 +#define CT_LISTBOX 5 +#define CT_TOOLBOX 6 +#define CT_CHECKBOXES 7 +#define CT_PROGRESS 8 +#define CT_HTML 9 +#define CT_STATIC_SKEW 10 +#define CT_ACTIVETEXT 11 +#define CT_TREE 12 #define CT_STRUCTURED_TEXT 13 -#define CT_CONTEXT_MENU 14 -#define CT_CONTROLS_GROUP 15 -#define CT_SHORTCUTBUTTON 16 -#define CT_XKEYDESC 40 -#define CT_XBUTTON 41 -#define CT_XLISTBOX 42 -#define CT_XSLIDER 43 -#define CT_XCOMBO 44 +#define CT_CONTEXT_MENU 14 +#define CT_CONTROLS_GROUP 15 +#define CT_SHORTCUTBUTTON 16 +#define CT_XKEYDESC 40 +#define CT_XBUTTON 41 +#define CT_XLISTBOX 42 +#define CT_XSLIDER 43 +#define CT_XCOMBO 44 #define CT_ANIMATED_TEXTURE 45 -#define CT_OBJECT 80 -#define CT_OBJECT_ZOOM 81 +#define CT_OBJECT 80 +#define CT_OBJECT_ZOOM 81 #define CT_OBJECT_CONTAINER 82 #define CT_OBJECT_CONT_ANIM 83 -#define CT_LINEBREAK 98 -#define CT_ANIMATED_USER 99 -#define CT_MAP 100 -#define CT_MAP_MAIN 101 -#define CT_LISTNBOX 102 +#define CT_LINEBREAK 98 +#define CT_ANIMATED_USER 99 +#define CT_MAP 100 +#define CT_MAP_MAIN 101 +#define CT_LISTNBOX 102 // Static styles -#define ST_POS 0x0F -#define ST_HPOS 0x03 -#define ST_VPOS 0x0C -#define ST_LEFT 0x00 -#define ST_RIGHT 0x01 -#define ST_CENTER 0x02 -#define ST_DOWN 0x04 -#define ST_UP 0x08 -#define ST_VCENTER 0x0c +#define ST_POS 0x0F +#define ST_HPOS 0x03 +#define ST_VPOS 0x0C +#define ST_LEFT 0x00 +#define ST_RIGHT 0x01 +#define ST_CENTER 0x02 +#define ST_DOWN 0x04 +#define ST_UP 0x08 +#define ST_VCENTER 0x0C -#define ST_TYPE 0xF0 -#define ST_SINGLE 0 -#define ST_MULTI 16 -#define ST_TITLE_BAR 32 -#define ST_PICTURE 48 -#define ST_FRAME 64 -#define ST_BACKGROUND 80 -#define ST_GROUP_BOX 96 -#define ST_GROUP_BOX2 112 -#define ST_HUD_BACKGROUND 128 -#define ST_TILE_PICTURE 144 -#define ST_WITH_RECT 160 -#define ST_LINE 176 +#define ST_TYPE 0xF0 +#define ST_SINGLE 0 +#define ST_MULTI 16 +#define ST_TITLE_BAR 32 +#define ST_PICTURE 48 +#define ST_FRAME 64 +#define ST_BACKGROUND 80 +#define ST_GROUP_BOX 96 +#define ST_GROUP_BOX2 112 +#define ST_HUD_BACKGROUND 128 +#define ST_TILE_PICTURE 144 +#define ST_WITH_RECT 160 +#define ST_LINE 176 -#define ST_SHADOW 0x100 -#define ST_NO_RECT 0x200 // this style works for CT_STATIC in conjunction with ST_MULTI -#define ST_KEEP_ASPECT_RATIO 0x800 +#define ST_SHADOW 0x100 +#define ST_NO_RECT 0x200 // this style works for CT_STATIC in conjunction with ST_MULTI +#define ST_KEEP_ASPECT_RATIO 0x800 -#define ST_TITLE ST_TITLE_BAR + ST_CENTER +#define ST_TITLE ST_TITLE_BAR + ST_CENTER // Slider styles -#define SL_DIR 0x400 -#define SL_VERT 0 -#define SL_HORZ 0x400 +#define SL_DIR 0x400 +#define SL_VERT 0 +#define SL_HORZ 0x400 -#define SL_TEXTURES 0x10 +#define SL_TEXTURES 0x10 // Listbox styles -#define LB_TEXTURES 0x10 -#define LB_MULTI 0x20 -#define FONT_ACE "RobotoCondensed" +#define LB_TEXTURES 0x10 +#define LB_MULTI 0x20 +#define FONT_ACE "RobotoCondensed" class ACE_gui_backgroundBase { - type = CT_STATIC; - idc = -1; - style = ST_PICTURE; - colorBackground[] = {0,0,0,0}; - colorText[] = {1, 1, 1, 1}; - font = FONT_ACE; - text = ""; - sizeEx = 0.032; + type = CT_STATIC; + idc = -1; + style = ST_PICTURE; + colorBackground[] = {0, 0, 0, 0}; + colorText[] = {1, 1, 1, 1}; + font = FONT_ACE; + text = ""; + sizeEx = 0.032; }; -class ACE_gui_editBase -{ + +class ACE_gui_editBase { type = 2; x = 0; y = 0; h = 0.04; w = 0.2; - colorBackground[] = - { - 0, - 0, - 0, - 1 - }; - colorText[] = - { - 0.95, - 0.95, - 0.95, - 1 - }; - colorSelection[] = - { - "(profilenamespace getVariable ['GUI_BCG_RGB_R',0.3843])", - "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.7019])", - "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.8862])", - 1 - }; + colorBackground[] = {0, 0, 0, 1}; + colorText[] = {0.95, 0.95, 0.95, 1}; + colorSelection[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.8862])", 1}; autocomplete = ""; text = ""; size = 0.2; @@ -127,662 +108,621 @@ class ACE_gui_editBase font = "RobotoCondensed"; shadow = 2; sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; - colorDisabled[] = - { - 1, - 1, - 1, - 0.25 + colorDisabled[] = {1, 1, 1, 0.25}; +}; + +class ACE_gui_buttonBase { + idc = -1; + type = 16; + style = ST_LEFT; + text = ""; + action = ""; + x = 0; + y = 0; + w = 0.25; + h = 0.04; + size = 0.03921; + sizeEx = 0.03921; + color[] = {1, 1, 1, 1}; + color2[] = {1, 1, 1, 1}; + colorBackground[] = {1, 1, 1, 0.95}; + colorbackground2[] = {1, 1, 1, 0.95}; + colorDisabled[] = {1, 1, 1, 0.6}; + colorFocused[] = {1, 1, 1, 1}; + colorBackgroundFocused[] = {1, 1, 1, 1}; + periodFocus = 1.2; + periodOver = 0.8; + default = 0; + + class HitZone { + left = 0; + top = 0; + right = 0; + bottom = 0; + }; + class ShortcutPos { + left = 0; + top = 0; + w = 0; + h = 0; + }; + class TextPos { + left = 0.002; + top = 0.0004; + right = 0; + bottom = 0; + }; + + textureNoShortcut = ""; + animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; + animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; + animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; + animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; + animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; + animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; + period = 0.5; + font = FONT_ACE; + soundClick[] = {"\A3\ui_f\data\sound\RscButton\soundClick", 0.09, 1}; + soundPush[] = {"\A3\ui_f\data\sound\RscButton\soundPush", 0, 0}; + soundEnter[] = {"\A3\ui_f\data\sound\RscButton\soundEnter", 0.07, 1}; + soundEscape[] = {"\A3\ui_f\data\sound\RscButton\soundEscape", 0.09, 1}; + + class Attributes { + font = FONT_ACE; + color = "#E5E5E5"; + align = "center"; + shadow = "true"; + }; + class AttributesImage { + font = FONT_ACE; + color = "#E5E5E5"; + align = "left"; + shadow = "true"; }; }; - - -class ACE_gui_buttonBase { - idc = -1; - type = 16; - style = ST_LEFT; - text = ""; - action = ""; - x = 0.0; - y = 0.0; - w = 0.25; - h = 0.04; - size = 0.03921; - sizeEx = 0.03921; - color[] = {1.0, 1.0, 1.0, 1}; - color2[] = {1.0, 1.0, 1.0, 1}; - colorBackground[] = {1,1,1,0.95}; - colorbackground2[] = {1,1,1,0.95}; - colorDisabled[] = {1,1,1,0.6}; - colorFocused[] = {1,1,1,1}; - colorBackgroundFocused[] = {1,1,1,1}; - periodFocus = 1.2; - periodOver = 0.8; - default = false; - class HitZone { - left = 0.00; - top = 0.00; - right = 0.00; - bottom = 0.00; - }; - - class ShortcutPos { - left = 0.00; - top = 0.00; - w = 0.00; - h = 0.00; - }; - - class TextPos { - left = 0.002; - top = 0.0004; - right = 0.0; - bottom = 0.00; - }; - textureNoShortcut = ""; - animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; - animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; - animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; - animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; - period = 0.5; - font = FONT_ACE; - soundClick[] = {"\A3\ui_f\data\sound\RscButton\soundClick",0.09,1}; - soundPush[] = {"\A3\ui_f\data\sound\RscButton\soundPush",0.0,0}; - soundEnter[] = {"\A3\ui_f\data\sound\RscButton\soundEnter",0.07,1}; - soundEscape[] = {"\A3\ui_f\data\sound\RscButton\soundEscape",0.09,1}; - class Attributes { - font = FONT_ACE; - color = "#E5E5E5"; - align = "center"; - shadow = "true"; - }; - class AttributesImage { - font = FONT_ACE; - color = "#E5E5E5"; - align = "left"; - shadow = "true"; - }; -}; - class ACE_gui_RscProgress { - type = 8; - style = 0; - colorFrame[] = {1,1,1,0.7}; - colorBar[] = {1,1,1,0.7}; - texture = "#(argb,8,8,3)color(1,1,1,0.7)"; - x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - y = "10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - w = "38 * (((safezoneW / safezoneH) min 1.2) / 40)"; - h = "0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + type = 8; + style = 0; + colorFrame[] = {1, 1, 1, 0.7}; + colorBar[] = {1, 1, 1, 0.7}; + texture = "#(argb,8,8,3)color(1,1,1,0.7)"; + x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + y = "10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + w = "38 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; }; - class ACE_gui_staticBase { - idc = -1; - type = CT_STATIC; - x = 0.0; - y = 0.0; - w = 0.183825; - h = 0.104575; - style = ST_LEFT; - font = FONT_ACE; - sizeEx = 0.03921; - colorText[] = {0.95, 0.95, 0.95, 1.0}; - colorBackground[] = {0, 0, 0, 0}; - text = ""; + idc = -1; + type = CT_STATIC; + x = 0; + y = 0; + w = 0.183825; + h = 0.104575; + style = ST_LEFT; + font = FONT_ACE; + sizeEx = 0.03921; + colorText[] = {0.95, 0.95, 0.95, 1}; + colorBackground[] = {0, 0, 0, 0}; + text = ""; }; class RscListBox; -class ACE_gui_listBoxBase : RscListBox{ - type = CT_LISTBOX; - style = ST_MULTI; - font = FONT_ACE; - sizeEx = 0.03921; - color[] = {1, 1, 1, 1}; - colorText[] = {0.543, 0.5742, 0.4102, 1.0}; - colorScrollbar[] = {0.95, 0.95, 0.95, 1}; - colorSelect[] = {0.95, 0.95, 0.95, 1}; - colorSelect2[] = {0.95, 0.95, 0.95, 1}; - colorSelectBackground[] = {0, 0, 0, 1}; - colorSelectBackground2[] = {0.543, 0.5742, 0.4102, 1.0}; - colorDisabled[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])","(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])","(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", 0.25}; - period = 1.2; - rowHeight = 0.03; - colorBackground[] = {0, 0, 0, 1}; - maxHistoryDelay = 1.0; - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - soundSelect[] = {"",0.1,1}; - soundExpand[] = {"",0.1,1}; - soundCollapse[] = {"",0.1,1}; - class ListScrollBar { - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - autoScrollDelay = 5; - autoScrollEnabled = 0; - autoScrollRewind = 0; +class ACE_gui_listBoxBase: RscListBox { + type = CT_LISTBOX; + style = ST_MULTI; + font = FONT_ACE; + sizeEx = 0.03921; + color[] = {1, 1, 1, 1}; + colorText[] = {0.543, 0.5742, 0.4102, 1}; + colorScrollbar[] = {0.95, 0.95, 0.95, 1}; + colorSelect[] = {0.95, 0.95, 0.95, 1}; + colorSelect2[] = {0.95, 0.95, 0.95, 1}; + colorSelectBackground[] = {0, 0, 0, 1}; + colorSelectBackground2[] = {0.543, 0.5742, 0.4102, 1}; + colorDisabled[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])", "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])", "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", 0.25}; + period = 1.2; + rowHeight = 0.03; + colorBackground[] = {0, 0, 0, 1}; + maxHistoryDelay = 1; autoScrollSpeed = -1; - border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.3}; - height = 0; - scrollSpeed = 0.06; - shadow = 0; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - width = 0; - }; - class ScrollBar { - color[] = {1, 1, 1, 0.6}; - colorActive[] = {1, 1, 1, 1}; - colorDisabled[] = {1, 1, 1, 0.3}; - thumb = ""; - arrowFull = ""; - arrowEmpty = ""; - border = ""; - }; -}; + autoScrollDelay = 5; + autoScrollRewind = 0; + soundSelect[] = {"", 0.1, 1}; + soundExpand[] = {"", 0.1, 1}; + soundCollapse[] = {"", 0.1, 1}; + class ListScrollBar { + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + autoScrollDelay = 5; + autoScrollEnabled = 0; + autoScrollRewind = 0; + autoScrollSpeed = -1; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + height = 0; + scrollSpeed = 0.06; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + width = 0; + }; + class ScrollBar { + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + thumb = ""; + arrowFull = ""; + arrowEmpty = ""; + border = ""; + }; +}; class ACE_gui_listNBox { - type = CT_LISTNBOX;// 102; - style =ST_MULTI; - w = 0.4; - h = 0.4; - font = FONT_ACE; - sizeEx = 0.031; + type = CT_LISTNBOX; // 102; + style = ST_MULTI; + w = 0.4; + h = 0.4; + font = FONT_ACE; + sizeEx = 0.031; - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; - arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; - columns[] = {0.0}; - color[] = {1, 1, 1, 1}; - - rowHeight = 0.03; - colorBackground[] = {0, 0, 0, 0.2}; - colorText[] = {1,1, 1, 1.0}; - colorScrollbar[] = {0.95, 0.95, 0.95, 1}; - colorSelect[] = {0.95, 0.95, 0.95, 1}; - colorSelect2[] = {0.95, 0.95, 0.95, 1}; - colorSelectBackground[] = {0, 0, 0, 0.0}; - colorSelectBackground2[] = {0.0, 0.0, 0.0, 0.5}; - colorActive[] = {0,0,0,1}; - colorDisabled[] = {0,0,0,0.3}; - rows = 1; - - drawSideArrows = 0; - idcLeft = -1; - idcRight = -1; - maxHistoryDelay = 1; - soundSelect[] = {"", 0.1, 1}; - period = 1; - shadow = 2; - class ScrollBar { - arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; - arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; - border = "#(argb,8,8,3)color(1,1,1,1)"; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.3}; - thumb = "#(argb,8,8,3)color(1,1,1,1)"; - }; - class ListScrollBar { - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - autoScrollDelay = 5; - autoScrollEnabled = 0; - autoScrollRewind = 0; autoScrollSpeed = -1; - border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.3}; - height = 0; - scrollSpeed = 0.06; - shadow = 0; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - width = 0; - }; -}; + autoScrollDelay = 5; + autoScrollRewind = 0; + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + columns[] = {0}; + color[] = {1, 1, 1, 1}; + rowHeight = 0.03; + colorBackground[] = {0, 0, 0, 0.2}; + colorText[] = {1, 1, 1, 1}; + colorScrollbar[] = {0.95, 0.95, 0.95, 1}; + colorSelect[] = {0.95, 0.95, 0.95, 1}; + colorSelect2[] = {0.95, 0.95, 0.95, 1}; + colorSelectBackground[] = {0, 0, 0, 0}; + colorSelectBackground2[] = {0, 0, 0, 0.5}; + colorActive[] = {0, 0, 0, 1}; + colorDisabled[] = {0, 0, 0, 0.3}; + rows = 1; + + drawSideArrows = 0; + idcLeft = -1; + idcRight = -1; + maxHistoryDelay = 1; + soundSelect[] = {"", 0.1, 1}; + period = 1; + shadow = 2; + + class ScrollBar { + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + border = "#(argb,8,8,3)color(1,1,1,1)"; + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + thumb = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class ListScrollBar { + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + autoScrollDelay = 5; + autoScrollEnabled = 0; + autoScrollRewind = 0; + autoScrollSpeed = -1; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + height = 0; + scrollSpeed = 0.06; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + width = 0; + }; +}; class RscCombo; class ACE_gui_comboBoxBase: RscCombo { - idc = -1; - type = 4; - style = "0x10 + 0x200"; - x = 0; - y = 0; - w = 0.3; - h = 0.035; - color[] = {0,0,0,0.6}; - colorActive[] = {1,0,0,1}; - colorBackground[] = {0,0,0,1}; - colorDisabled[] = {1,1,1,0.25}; - colorScrollbar[] = {1,0,0,1}; - colorSelect[] = {0,0,0,1}; - colorSelectBackground[] = {1,1,1,0.7}; - colorText[] = {1,1,1,1}; + idc = -1; + type = 4; + style = "0x10 + 0x200"; + x = 0; + y = 0; + w = 0.3; + h = 0.035; + color[] = {0, 0, 0, 0.6}; + colorActive[] = {1, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 1}; + colorDisabled[] = {1, 1, 1, 0.25}; + colorScrollbar[] = {1, 0, 0, 1}; + colorSelect[] = {0, 0, 0, 1}; + colorSelectBackground[] = {1, 1, 1, 0.7}; + colorText[] = {1, 1, 1, 1}; - arrowEmpty = ""; - arrowFull = ""; - wholeHeight = 0.45; - font = FONT_ACE; - sizeEx = 0.031; - soundSelect[] = {"\A3\ui_f\data\sound\RscCombo\soundSelect",0.1,1}; - soundExpand[] = {"\A3\ui_f\data\sound\RscCombo\soundExpand",0.1,1}; - soundCollapse[] = {"\A3\ui_f\data\sound\RscCombo\soundCollapse",0.1,1}; - maxHistoryDelay = 1.0; - class ScrollBar - { - color[] = {0.3,0.3,0.3,0.6}; - colorActive[] = {0.3,0.3,0.3,1}; - colorDisabled[] = {0.3,0.3,0.3,0.3}; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - border = ""; - }; - class ComboScrollBar { - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - autoScrollDelay = 5; - autoScrollEnabled = 0; - autoScrollRewind = 0; - autoScrollSpeed = -1; - border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; - color[] = {0.3,0.3,0.3,0.6}; - colorActive[] = {0.3,0.3,0.3,1}; - colorDisabled[] = {0.3,0.3,0.3,0.3}; - height = 0; - scrollSpeed = 0.06; - shadow = 0; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - width = 0; - }; + arrowEmpty = ""; + arrowFull = ""; + wholeHeight = 0.45; + font = FONT_ACE; + sizeEx = 0.031; + soundSelect[] = {"\A3\ui_f\data\sound\RscCombo\soundSelect", 0.1, 1}; + soundExpand[] = {"\A3\ui_f\data\sound\RscCombo\soundExpand", 0.1, 1}; + soundCollapse[] = {"\A3\ui_f\data\sound\RscCombo\soundCollapse", 0.1, 1}; + maxHistoryDelay = 1; + + class ScrollBar { + color[] = {0.3, 0.3, 0.3, 0.6}; + colorActive[] = {0.3, 0.3, 0.3, 1}; + colorDisabled[] = {0.3, 0.3, 0.3, 0.3}; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + border = ""; + }; + class ComboScrollBar { + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + autoScrollDelay = 5; + autoScrollEnabled = 0; + autoScrollRewind = 0; + autoScrollSpeed = -1; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + color[] = {0.3, 0.3, 0.3, 0.6}; + colorActive[] = {0.3, 0.3, 0.3, 1}; + colorDisabled[] = {0.3, 0.3, 0.3, 0.3}; + height = 0; + scrollSpeed = 0.06; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + width = 0; + }; }; - - class ACE_gui_mapBase { - moveOnEdges = 1; - x = "SafeZoneXAbs"; - y = "SafeZoneY + 1.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - w = "SafeZoneWAbs"; - h = "SafeZoneH - 1.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - type = 100; // Use 100 to hide markers - style = 48; - shadow = 0; + moveOnEdges = 1; + x = "SafeZoneXAbs"; + y = "SafeZoneY + 1.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "SafeZoneWAbs"; + h = "SafeZoneH - 1.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + type = 100; // Use 100 to hide markers + style = 48; + shadow = 0; - ptsPerSquareSea = 5; - ptsPerSquareTxt = 3; - ptsPerSquareCLn = 10; - ptsPerSquareExp = 10; - ptsPerSquareCost = 10; - ptsPerSquareFor = 9; - ptsPerSquareForEdge = 9; - ptsPerSquareRoad = 6; - ptsPerSquareObj = 9; - showCountourInterval = 0; - scaleMin = 0.001; - scaleMax = 1.0; - scaleDefault = 0.16; - maxSatelliteAlpha = 0.85; - alphaFadeStartScale = 0.35; - alphaFadeEndScale = 0.4; - colorBackground[] = {0.969,0.957,0.949,1.0}; - colorSea[] = {0.467,0.631,0.851,0.5}; - colorForest[] = {0.624,0.78,0.388,0.5}; - colorForestBorder[] = {0.0,0.0,0.0,0.0}; - colorRocks[] = {0.0,0.0,0.0,0.3}; - colorRocksBorder[] = {0.0,0.0,0.0,0.0}; - colorLevels[] = {0.286,0.177,0.094,0.5}; - colorMainCountlines[] = {0.572,0.354,0.188,0.5}; - colorCountlines[] = {0.572,0.354,0.188,0.25}; - colorMainCountlinesWater[] = {0.491,0.577,0.702,0.6}; - colorCountlinesWater[] = {0.491,0.577,0.702,0.3}; - colorPowerLines[] = {0.1,0.1,0.1,1.0}; - colorRailWay[] = {0.8,0.2,0.0,1.0}; - colorNames[] = {0.1,0.1,0.1,0.9}; - colorInactive[] = {1.0,1.0,1.0,0.5}; - colorOutside[] = {0.0,0.0,0.0,1.0}; - colorTracks[] = {0.84,0.76,0.65,0.15}; - colorTracksFill[] = {0.84,0.76,0.65,1.0}; - colorRoads[] = {0.7,0.7,0.7,1.0}; - colorRoadsFill[] = {1.0,1.0,1.0,1.0}; - colorMainRoads[] = {0.9,0.5,0.3,1.0}; - colorMainRoadsFill[] = {1.0,0.6,0.4,1.0}; - colorGrid[] = {0.1,0.1,0.1,0.6}; - colorGridMap[] = {0.1,0.1,0.1,0.6}; - colorText[] = {1, 1, 1, 0.85}; -font = "RobotoCondensed"; -sizeEx = 0.0270000; -stickX[] = {0.20, {"Gamma", 1.00, 1.50} }; -stickY[] = {0.20, {"Gamma", 1.00, 1.50} }; -onMouseButtonClick = ""; -onMouseButtonDblClick = ""; + ptsPerSquareSea = 5; + ptsPerSquareTxt = 3; + ptsPerSquareCLn = 10; + ptsPerSquareExp = 10; + ptsPerSquareCost = 10; + ptsPerSquareFor = 9; + ptsPerSquareForEdge = 9; + ptsPerSquareRoad = 6; + ptsPerSquareObj = 9; + showCountourInterval = 0; + scaleMin = 0.001; + scaleMax = 1; + scaleDefault = 0.16; + maxSatelliteAlpha = 0.85; + alphaFadeStartScale = 0.35; + alphaFadeEndScale = 0.4; + colorBackground[] = {0.969, 0.957, 0.949, 1}; + colorSea[] = {0.467, 0.631, 0.851, 0.5}; + colorForest[] = {0.624, 0.78, 0.388, 0.5}; + colorForestBorder[] = {0, 0, 0, 0}; + colorRocks[] = {0, 0, 0, 0.3}; + colorRocksBorder[] = {0, 0, 0, 0}; + colorLevels[] = {0.286, 0.177, 0.094, 0.5}; + colorMainCountlines[] = {0.572, 0.354, 0.188, 0.5}; + colorCountlines[] = {0.572, 0.354, 0.188, 0.25}; + colorMainCountlinesWater[] = {0.491, 0.577, 0.702, 0.6}; + colorCountlinesWater[] = {0.491, 0.577, 0.702, 0.3}; + colorPowerLines[] = {0.1, 0.1, 0.1, 1}; + colorRailWay[] = {0.8, 0.2, 0, 1}; + colorNames[] = {0.1, 0.1, 0.1, 0.9}; + colorInactive[] = {1, 1, 1, 0.5}; + colorOutside[] = {0, 0, 0, 1}; + colorTracks[] = {0.84, 0.76, 0.65, 0.15}; + colorTracksFill[] = {0.84, 0.76, 0.65, 1}; + colorRoads[] = {0.7, 0.7, 0.7, 1}; + colorRoadsFill[] = {1, 1, 1, 1}; + colorMainRoads[] = {0.9, 0.5, 0.3, 1}; + colorMainRoadsFill[] = {1, 0.6, 0.4, 1}; + colorGrid[] = {0.1, 0.1, 0.1, 0.6}; + colorGridMap[] = {0.1, 0.1, 0.1, 0.6}; + colorText[] = {1, 1, 1, 0.85}; + font = "RobotoCondensed"; + sizeEx = 0.027; + stickX[] = {0.2, {"Gamma", 1, 1.5}}; + stickY[] = {0.2, {"Gamma", 1, 1.5}}; + onMouseButtonClick = ""; + onMouseButtonDblClick = ""; - fontLabel = "RobotoCondensed"; - sizeExLabel = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - fontGrid = "TahomaB"; - sizeExGrid = 0.02; - fontUnits = "TahomaB"; - sizeExUnits = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - fontNames = "RobotoCondensed"; - sizeExNames = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8) * 2"; - fontInfo = "RobotoCondensed"; - sizeExInfo = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - fontLevel = "TahomaB"; - sizeExLevel = 0.02; - text = "#(argb,8,8,3)color(1,1,1,1)"; - class ActiveMarker { - color[] = {0.30, 0.10, 0.90, 1.00}; - size = 50; - }; - class Legend - { - x = "SafeZoneX + ( ((safezoneW / safezoneH) min 1.2) / 40)"; - y = "SafeZoneY + safezoneH - 4.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - w = "10 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; - h = "3.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - font = "RobotoCondensed"; - sizeEx = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - colorBackground[] = {1,1,1,0.5}; - color[] = {0,0,0,1}; - }; - class Task - { - icon = "\A3\ui_f\data\map\mapcontrol\taskIcon_CA.paa"; - iconCreated = "\A3\ui_f\data\map\mapcontrol\taskIconCreated_CA.paa"; - iconCanceled = "\A3\ui_f\data\map\mapcontrol\taskIconCanceled_CA.paa"; - iconDone = "\A3\ui_f\data\map\mapcontrol\taskIconDone_CA.paa"; - iconFailed = "\A3\ui_f\data\map\mapcontrol\taskIconFailed_CA.paa"; - color[] = {"(profilenamespace getVariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getVariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getVariable ['IGUI_TEXT_RGB_B',1])","(profilenamespace getVariable ['IGUI_TEXT_RGB_A',0.8])"}; - colorCreated[] = {1,1,1,1}; - colorCanceled[] = {0.7,0.7,0.7,1}; - colorDone[] = {0.7,1,0.3,1}; - colorFailed[] = {1,0.3,0.2,1}; - size = 27; - importance = 1; - coefMin = 1; - coefMax = 1; - }; - class Waypoint - { - icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; - color[] = {0,0,0,1}; - size = 20; - importance = "1.2 * 16 * 0.05"; - coefMin = 0.900000; - coefMax = 4; - }; - class WaypointCompleted - { - icon = "\A3\ui_f\data\map\mapcontrol\waypointCompleted_ca.paa"; - color[] = {0,0,0,1}; - size = 20; - importance = "1.2 * 16 * 0.05"; - coefMin = 0.900000; - coefMax = 4; - }; - class CustomMark - { - icon = "\A3\ui_f\data\map\mapcontrol\custommark_ca.paa"; - size = 24; - importance = 1; - coefMin = 1; - coefMax = 1; - color[] = {0,0,0,1}; - }; - class Command - { - icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; - size = 18; - importance = 1; - coefMin = 1; - coefMax = 1; - color[] = {1,1,1,1}; - }; - class Bush - { - icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; - color[] = {0.45,0.64,0.33,0.4}; - size = "14/2"; - importance = "0.2 * 14 * 0.05 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class Rock - { - icon = "\A3\ui_f\data\map\mapcontrol\rock_ca.paa"; - color[] = {0.1,0.1,0.1,0.8}; - size = 12; - importance = "0.5 * 12 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class SmallTree - { - icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; - color[] = {0.45,0.64,0.33,0.4}; - size = 12; - importance = "0.6 * 12 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class Tree - { - icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; - color[] = {0.45,0.64,0.33,0.4}; - size = 12; - importance = "0.9 * 16 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class busstop - { - icon = "\A3\ui_f\data\map\mapcontrol\busstop_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class fuelstation - { - icon = "\A3\ui_f\data\map\mapcontrol\fuelstation_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class hospital - { - icon = "\A3\ui_f\data\map\mapcontrol\hospital_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class church - { - icon = "\A3\ui_f\data\map\mapcontrol\church_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class lighthouse - { - icon = "\A3\ui_f\data\map\mapcontrol\lighthouse_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class power - { - icon = "\A3\ui_f\data\map\mapcontrol\power_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class powersolar - { - icon = "\A3\ui_f\data\map\mapcontrol\powersolar_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class powerwave - { - icon = "\A3\ui_f\data\map\mapcontrol\powerwave_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class powerwind - { - icon = "\A3\ui_f\data\map\mapcontrol\powerwind_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class quay - { - icon = "\A3\ui_f\data\map\mapcontrol\quay_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class shipwreck - { - icon = "\A3\ui_f\data\map\mapcontrol\shipwreck_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class transmitter - { - icon = "\A3\ui_f\data\map\mapcontrol\transmitter_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class watertower - { - icon = "\A3\ui_f\data\map\mapcontrol\watertower_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class Cross - { - icon = "\A3\ui_f\data\map\mapcontrol\Cross_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {0,0,0,1}; - }; - class Chapel - { - icon = "\A3\ui_f\data\map\mapcontrol\Chapel_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {0,0,0,1}; - }; - class Bunker - { - icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; - size = 14; - importance = "1.5 * 14 * 0.05"; - coefMin = 0.25; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Fortress - { - icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; - size = 16; - importance = "2 * 16 * 0.05"; - coefMin = 0.25; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Fountain - { - icon = "\A3\ui_f\data\map\mapcontrol\fountain_ca.paa"; - size = 11; - importance = "1 * 12 * 0.05"; - coefMin = 0.25; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Ruin - { - icon = "\A3\ui_f\data\map\mapcontrol\ruin_ca.paa"; - size = 16; - importance = "1.2 * 16 * 0.05"; - coefMin = 1; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Stack - { - icon = "\A3\ui_f\data\map\mapcontrol\stack_ca.paa"; - size = 20; - importance = "2 * 16 * 0.05"; - coefMin = 0.9; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Tourism - { - icon = "\A3\ui_f\data\map\mapcontrol\tourism_ca.paa"; - size = 16; - importance = "1 * 16 * 0.05"; - coefMin = 0.7; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class ViewTower - { - icon = "\A3\ui_f\data\map\mapcontrol\viewtower_ca.paa"; - size = 16; - importance = "2.5 * 16 * 0.05"; - coefMin = 0.5; - coefMax = 4; - color[] = {0,0,0,1}; - }; + fontLabel = "RobotoCondensed"; + sizeExLabel = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontGrid = "TahomaB"; + sizeExGrid = 0.02; + fontUnits = "TahomaB"; + sizeExUnits = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontNames = "RobotoCondensed"; + sizeExNames = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8) * 2"; + fontInfo = "RobotoCondensed"; + sizeExInfo = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontLevel = "TahomaB"; + sizeExLevel = 0.02; + text = "#(argb,8,8,3)color(1,1,1,1)"; + + class ActiveMarker { + color[] = {0.3, 0.1, 0.9, 1}; + size = 50; + }; + class Legend { + x = "SafeZoneX + (((safezoneW / safezoneH) min 1.2) / 40)"; + y = "SafeZoneY + safezoneH - 4.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "3.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + font = "RobotoCondensed"; + sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + colorBackground[] = {1, 1, 1, 0.5}; + color[] = {0, 0, 0, 1}; + }; + class Task { + icon = "\A3\ui_f\data\map\mapcontrol\taskIcon_CA.paa"; + iconCreated = "\A3\ui_f\data\map\mapcontrol\taskIconCreated_CA.paa"; + iconCanceled = "\A3\ui_f\data\map\mapcontrol\taskIconCanceled_CA.paa"; + iconDone = "\A3\ui_f\data\map\mapcontrol\taskIconDone_CA.paa"; + iconFailed = "\A3\ui_f\data\map\mapcontrol\taskIconFailed_CA.paa"; + color[] = {"(profilenamespace getVariable ['IGUI_TEXT_RGB_R',0])", "(profilenamespace getVariable ['IGUI_TEXT_RGB_G',1])", "(profilenamespace getVariable ['IGUI_TEXT_RGB_B',1])", "(profilenamespace getVariable ['IGUI_TEXT_RGB_A',0.8])"}; + colorCreated[] = {1, 1, 1, 1}; + colorCanceled[] = {0.7, 0.7, 0.7, 1}; + colorDone[] = {0.7, 1, 0.3, 1}; + colorFailed[] = {1, 0.3, 0.2, 1}; + size = 27; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Waypoint { + icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 20; + importance = "1.2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + }; + class WaypointCompleted { + icon = "\A3\ui_f\data\map\mapcontrol\waypointCompleted_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 20; + importance = "1.2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + }; + class CustomMark { + icon = "\A3\ui_f\data\map\mapcontrol\custommark_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 24; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Command { + icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; + color[] = {1, 1, 1, 1}; + size = 18; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Bush { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45, 0.64, 0.33, 0.4}; + size = "14/2"; + importance = "0.2 * 14 * 0.05 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Rock { + icon = "\A3\ui_f\data\map\mapcontrol\rock_ca.paa"; + color[] = {0.1, 0.1, 0.1, 0.8}; + size = 12; + importance = "0.5 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class SmallTree { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45, 0.64, 0.33, 0.4}; + size = 12; + importance = "0.6 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Tree { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45, 0.64, 0.33, 0.4}; + size = 12; + importance = "0.9 * 16 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class busstop { + icon = "\A3\ui_f\data\map\mapcontrol\busstop_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class fuelstation { + icon = "\A3\ui_f\data\map\mapcontrol\fuelstation_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class hospital { + icon = "\A3\ui_f\data\map\mapcontrol\hospital_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class church { + icon = "\A3\ui_f\data\map\mapcontrol\church_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class lighthouse { + icon = "\A3\ui_f\data\map\mapcontrol\lighthouse_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class power { + icon = "\A3\ui_f\data\map\mapcontrol\power_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class powersolar { + icon = "\A3\ui_f\data\map\mapcontrol\powersolar_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class powerwave { + icon = "\A3\ui_f\data\map\mapcontrol\powerwave_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class powerwind { + icon = "\A3\ui_f\data\map\mapcontrol\powerwind_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class quay { + icon = "\A3\ui_f\data\map\mapcontrol\quay_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class shipwreck { + icon = "\A3\ui_f\data\map\mapcontrol\shipwreck_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class transmitter { + icon = "\A3\ui_f\data\map\mapcontrol\transmitter_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class watertower { + icon = "\A3\ui_f\data\map\mapcontrol\watertower_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class Cross { + icon = "\A3\ui_f\data\map\mapcontrol\Cross_CA.paa"; + color[] = {0, 0, 0, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class Chapel { + icon = "\A3\ui_f\data\map\mapcontrol\Chapel_CA.paa"; + color[] = {0, 0, 0, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class Bunker { + icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 14; + importance = "1.5 * 14 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Fortress { + icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "2 * 16 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Fountain { + icon = "\A3\ui_f\data\map\mapcontrol\fountain_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 11; + importance = "1 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Ruin { + icon = "\A3\ui_f\data\map\mapcontrol\ruin_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "1.2 * 16 * 0.05"; + coefMin = 1; + coefMax = 4; + }; + class Stack { + icon = "\A3\ui_f\data\map\mapcontrol\stack_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 20; + importance = "2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + }; + class Tourism { + icon = "\A3\ui_f\data\map\mapcontrol\tourism_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "1 * 16 * 0.05"; + coefMin = 0.7; + coefMax = 4; + }; + class ViewTower { + icon = "\A3\ui_f\data\map\mapcontrol\viewtower_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "2.5 * 16 * 0.05"; + coefMin = 0.5; + coefMax = 4; + }; }; #endif diff --git a/addons/common/dev/test_cfgPatches.sqf b/addons/common/dev/test_cfgPatches.sqf new file mode 100644 index 0000000000..c5f3c81ef5 --- /dev/null +++ b/addons/common/dev/test_cfgPatches.sqf @@ -0,0 +1,72 @@ +#include "..\script_component.hpp" + +// PabstMirror +// ["cfgPatches"] call ace_common_fnc_runTests; + +diag_log text format ["--- Checking CfgPatches --- "]; + +private _testPass = true; + +// All ace cfgPatches +private _allPatches = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgPatches"); + +// Get all units[] +private _allUnits = []; +{ + _allUnits append ((getArray (_x >> "units")) apply { toLowerANSI _x }); +} forEach _allPatches; +{ + private _class = configFile >> "CfgVehicles" >> _x; + if (isNull _class) then { + WARNING_1("in units[] but null - %1",_x); + _testPass = false; + } else { + // if (((getNumber (_class >> "scope")) != 2) && {((getNumber (_class >> "scopeCurator")) != 2)}) then { + // WARNING_2("in units[] but not public - %1 from %2",configName _class,configSourceMod _class); + // _testPass = false; + // }; + }; +} forEach _allUnits; + +// Get all weapons[] +private _allWeapons = []; +{ + _allWeapons append ((getArray (_x >> "weapons")) apply { toLowerANSI _x }); +} forEach _allPatches; +{ + private _class = configFile >> "CfgWeapons" >> _x; + if (isNull _class) then { + WARNING_1("in weapons[] but null - %1",_x); + _testPass = false; + } else { + // if (((getNumber (_class >> "scope")) != 2) && {((getNumber (_class >> "scopeCurator")) != 2)}) then { + // WARNING_2("in weapons[] but not public - %1 from %2",configName _class,configSourceMod _class); + // _testPass = false; + // }; + }; +} forEach _allWeapons; + +// Check if all public vics are defined in a cfgPatch +private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgVehicles"); +{ + if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { + if !((toLowerANSI configName _x) in _allUnits) then { + WARNING_2("Not in any units[] - %1 from %2",configName _x,configSourceMod _x); + _testPass = false; + }; + }; +} forEach _vics; + +// Check if all public weapons are defined in a cfgPatch +private _weapons = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgWeapons"); +{ + private _type = toLowerANSI configName _x; + if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { + if !((toLowerANSI configName _x) in _allWeapons) then { + WARNING_2("Not in any weapons[] - %1 from %2",configName _x,configSourceMod _x); + _testPass = false; + }; + }; +} forEach _weapons; + +_testPass diff --git a/addons/common/dev/test_mapConfigs.sqf b/addons/common/dev/test_mapConfigs.sqf index 1b114d79e3..369b2b1808 100644 --- a/addons/common/dev/test_mapConfigs.sqf +++ b/addons/common/dev/test_mapConfigs.sqf @@ -2,7 +2,7 @@ // ["mapConfigs"] call ace_common_fnc_runTests; // execVM "z\ace\addons\common\dev\test_mapConfigs.sqf"; -#include "\z\ace\addons\common\script_component.hpp" +#include "..\script_component.hpp" diag_log text format ["--- Checking Map Configs ---"]; @@ -22,7 +22,7 @@ private _maps = configProperties [configFile >> "CfgWorldList", "(isClass _x)", }; // Test MGRS grid step size (from ace_common_fnc_getMapGridData) - private _zoomMax = 1e99; + private _zoomMax = 1e38; private _formatX = ""; private _formatY = ""; private _stepX = 1e10; diff --git a/addons/common/dev/test_vehicleInventory.sqf b/addons/common/dev/test_vehicleInventory.sqf index fced35a987..9fb24fc1d6 100644 --- a/addons/common/dev/test_vehicleInventory.sqf +++ b/addons/common/dev/test_vehicleInventory.sqf @@ -14,7 +14,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _glassesConfig = configFile >> "CfgGlasses" >> _name; if (((!isClass _weaponConfig) || {(getNumber (_weaponConfig >> "type")) in [1,2,4]}) && {!isClass _glassesConfig}) then { diag_log text format ["%1 -> TransportItems -> %2 = Bad", _vehType, _name]; - _testPass = false; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; }; } forEach (configProperties [_x >> "TransportItems", "isClass _x", true]); @@ -23,7 +23,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _weaponConfig = configFile >> "CfgWeapons" >> _name; if ((!isClass _weaponConfig) || {!((getNumber (_weaponConfig >> "type")) in [1,2,4])}) then { diag_log text format ["%1 -> TransportWeapons -> %2 = Bad", _vehType, _name]; - _testPass = false; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportWeapons", "isClass _x", true]); { @@ -31,7 +31,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _magConfig = configFile >> "CfgMagazines" >> _name; if ((!isClass _magConfig)) then { diag_log text format ["%1 -> TransportMagazines -> %2 = Bad", _vehType, _name]; - _testPass = false; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportMagazines", "isClass _x", true]); { @@ -39,7 +39,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _vehConfig = configFile >> "CfgVehicles" >> _name; if ((!isClass _vehConfig)) then { diag_log text format ["%1 -> TransportBackpacks -> %2 = Bad", _vehType, _name]; - _testPass = false; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportBackpacks", "isClass _x", true]); } forEach _vehicles; diff --git a/addons/common/functions/fnc_ASLToPosition.sqf b/addons/common/functions/fnc_ASLToPosition.sqf index 81e99ef8c3..b99e9fb88a 100644 --- a/addons/common/functions/fnc_ASLToPosition.sqf +++ b/addons/common/functions/fnc_ASLToPosition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Converts ASL to Arma "Position" diff --git a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf index dfdbe4db54..2d8f8be259 100644 --- a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf +++ b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Handles a server-side request for synchronization ALL events on JIP to a client. @@ -17,12 +17,11 @@ params ["_client"]; -[GVAR(syncedEvents), { - //IGNORE_PRIVATE_WARNING ["_key", "_value"]; - _value params ["", "_eventLog"]; - - ["ACEs", [_key, _eventLog], _client] call CBA_fnc_targetEvent; +{ + //IGNORE_PRIVATE_WARNING ["_x", "_y"]; + _y params ["", "_eventlog"]; + ["ACEs", [_x, _eventLog], _client] call CBA_fnc_targetEvent; false -}] call CBA_fnc_hashEachPair; +} forEach GVAR(syncedEvents); true diff --git a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf index 1e038c40bc..1924ed22ff 100644 --- a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Receives either requests for synchronization from clients, or the synchronization data from the server. @@ -26,12 +26,12 @@ if (isServer) then { // Find the event name, and shovel out the events to the client params ["_eventName", "_client"]; - if !([GVAR(syncedEvents), _eventName] call CBA_fnc_hashHasKey) exitWith { - ERROR_1("Request for synced event - key [%1] not found.", _eventName); + if !(_eventName in GVAR(syncedEvents)) exitWith { + ERROR_1("Request for synced event - key [%1] not found.",_eventName); false }; - private _eventEntry = [GVAR(syncedEvents), _eventName] call CBA_fnc_hashGet; + private _eventEntry = GVAR(syncedEvents) get _eventName; _eventEntry params ["", "_eventLog"]; ["ACEs", [_eventName, _eventLog], _client] call CBA_fnc_targetEvent; @@ -43,8 +43,7 @@ if (isServer) then { { _x params ["", "_eventArgs","_ttl"]; [_eventName, _eventArgs, _ttl] call FUNC(_handleSyncedEvent); - false - } count _eventLog; + } forEach _eventLog; INFO_1("[%1] synchronized",_eventName); }; diff --git a/addons/common/functions/fnc__handleSyncedEvent.sqf b/addons/common/functions/fnc__handleSyncedEvent.sqf index a7fa657a5f..aac8ac873e 100644 --- a/addons/common/functions/fnc__handleSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleSyncedEvent.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Handles synced events being received. Server will log them, and server/client will execute them. @@ -19,12 +19,12 @@ params ["_name", "_args", "_ttl"]; -if !([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ERROR_1("Synced event key [%1] not found (_handleSyncedEvent).", _name); +if !(_name in GVAR(syncedEvents)) exitWith { + ERROR_1("Synced event key [%1] not found (_handleSyncedEvent).",_name); false }; -private _internalData = [GVAR(syncedEvents), _name] call CBA_fnc_hashGet; +private _internalData = GVAR(syncedEvents) get _name; _internalData params ["_eventCode", "_eventLog"]; if (isServer) then { diff --git a/addons/common/functions/fnc_actionKeysNamesConverted.sqf b/addons/common/functions/fnc_actionKeysNamesConverted.sqf index 53ebba0cd6..27c3597a9b 100644 --- a/addons/common/functions/fnc_actionKeysNamesConverted.sqf +++ b/addons/common/functions/fnc_actionKeysNamesConverted.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Reports same as actionKeysNames(Array) but in a format processable by "keyDown". @@ -43,10 +43,10 @@ if (isNil "_keyTable") then { }; }; -private _keyCache = uiNamespace getVariable [QGVAR(keyNameCache), locationNull]; +private _keyCache = uiNamespace getVariable QGVAR(keyNameCache); // @TODO: Move cache creation to preStart/somewhere else -if (isNull _keyCache) then { - _keyCache = call CBA_fnc_createNamespace; +if (isNil "_keyCache") then { + _keyCache = createHashMap; uiNamespace setVariable [QGVAR(keyNameCache), _keyCache]; }; @@ -54,7 +54,7 @@ params [["_action", "", [""]]]; private _keybinds = actionKeysNamesArray _action apply { private _keyName = _x; - private _keybind = _keyCache getVariable _keyName; + private _keybind = _keyCache get _keyName; if (isNil "_keybind") then { private _key = -1; @@ -101,7 +101,7 @@ private _keybinds = actionKeysNamesArray _action apply { // cache _keybind = [_key, _shift, _ctrl, _alt]; - _keyCache setVariable [_keyName, _keybind]; + _keyCache set [_keyName, _keybind]; }; _keybind diff --git a/addons/common/functions/fnc_addActionEventHandler.sqf b/addons/common/functions/fnc_addActionEventHandler.sqf index 8fafef07cf..49846756a2 100644 --- a/addons/common/functions/fnc_addActionEventHandler.sqf +++ b/addons/common/functions/fnc_addActionEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Add an addAction event to a unit. Used to handle multiple addAction events. Global arguments, local effects. Does only work for player controlled units. diff --git a/addons/common/functions/fnc_addActionMenuEventHandler.sqf b/addons/common/functions/fnc_addActionMenuEventHandler.sqf index 67d531c22e..02d61b141b 100644 --- a/addons/common/functions/fnc_addActionMenuEventHandler.sqf +++ b/addons/common/functions/fnc_addActionMenuEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Add an addAction event to a unit. Used to handle multiple addAction events and add a action to the mouse wheel menu. Global arguments, local effects. Does only work for player controlled units. diff --git a/addons/common/functions/fnc_addCanInteractWithCondition.sqf b/addons/common/functions/fnc_addCanInteractWithCondition.sqf index 5db1a79a3d..3dce27cf55 100644 --- a/addons/common/functions/fnc_addCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_addCanInteractWithCondition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Add a condition that gets checked by ace_common_fnc_canInteractWith. @@ -18,7 +18,7 @@ params ["_conditionName", "_conditionFunc"]; -_conditionName = toLower _conditionName; +_conditionName = toLowerANSI _conditionName; private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; _conditions params ["_conditionNames", "_conditionFuncs"]; diff --git a/addons/common/functions/fnc_addLineToDebugDraw.sqf b/addons/common/functions/fnc_addLineToDebugDraw.sqf index 3056d750d6..016c99ddf4 100644 --- a/addons/common/functions/fnc_addLineToDebugDraw.sqf +++ b/addons/common/functions/fnc_addLineToDebugDraw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Add line to draw on debug diff --git a/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf b/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf index c698d30272..3fe674afcc 100644 --- a/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf +++ b/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Add a map marker creation event handler. diff --git a/addons/common/functions/fnc_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf new file mode 100644 index 0000000000..c20fde9da1 --- /dev/null +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -0,0 +1,63 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds event handler just to ACE_player + * Can be removed after cba 3.18 is released for CBA_fnc_addBISPlayerEventHandler + * This never was public in a release + * + * Arguments: + * 0: Key + * 1: Event Type + * 2: Event Code + * 3: Ignore Virtual Units (spectators, virtual zeus, uav RC) (default: true) + * + * Return Value: + * None + * + * Example: + * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH + * + * Public: No +*/ +params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]], ["_ignoreVirtual", true, [true]]]; +TRACE_3("addPlayerEH",_key,_type,_ignoreVirtual); + +if (isNil QGVAR(playerEventsHash)) then { // first-run init + GVAR(playerEventsHash) = createHashMap; + ["unit", { + params ["_newPlayer", "_oldPlayer"]; + // uav check only applies to direct controlling UAVs from zeus, no effect on normal UAV operation + private _isVirutal = (unitIsUAV _newPlayer) || {getNumber (configOf _newPlayer >> "isPlayableLogic") == 1}; + + TRACE_4("",_newPlayer,_oldPlayer,_isVirutal,count GVAR(playerEventsHash)); + { + _y params ["_type", "_code", "_ignoreVirtual"]; + + private _oldEH = _oldPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { + _oldPlayer removeEventHandler [_type, _oldEH]; + _oldPlayer setVariable [_x, nil]; + }; + + _oldEH = _newPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { continue }; // if respawned then var and EH already exists + if (_ignoreVirtual && _isVirutal) then { continue }; + + private _newEH = _newPlayer addEventHandler [_type, _code]; + _newPlayer setVariable [_x, _newEH]; + } forEach GVAR(playerEventsHash); + }, false] call CBA_fnc_addPlayerEventHandler; +}; + + +_key = format [QGVAR(playerEvents_%1), toLower _key]; +if (_key in GVAR(playerEventsHash)) exitWith { ERROR_1("bad key %1",_this); }; + +GVAR(playerEventsHash) set [_key, [_type, _code, _ignoreVirtual]]; + +if (isNull ACE_player) exitWith {}; +if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player >> "isPlayableLogic") == 1}}) exitWith {}; + +// Add event now +private _newEH = ACE_player addEventHandler [_type, _code]; +ACE_player setVariable [_key, _newEH]; diff --git a/addons/common/functions/fnc_addSwayFactor.sqf b/addons/common/functions/fnc_addSwayFactor.sqf new file mode 100644 index 0000000000..1cdc6fb721 --- /dev/null +++ b/addons/common/functions/fnc_addSwayFactor.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Adds a factor to player sway calculation + * + * Arguments: + * 0: Type of factor, "baseline" or "multiplier" + * 1: Factor function, must return number + * 2: Factor ID, unique to type + * + * Return Value: + * Factor added + * + * Example: + * ["baseline", {1}, "ace_common"] call ace_common_fnc_addSwayFactor + * + * Public: Yes +*/ +params ["_type", "_code", "_id"]; + +_type = toLowerANSI _type; + +if !(_type in ["baseline", "multiplier"]) exitWith { ERROR_2("%1-%2 type unsupported",_type,_id); false }; + +if !((call _code) isEqualType 0) exitWith { ERROR_2("%1-%2 bad return type",_type,_id); false }; + +[missionNamespace, format ["ACE_setCustomAimCoef_%1", _type], _id, _code] call FUNC(arithmeticSetSource); + +if (_type isEqualTo "baseline") then { + GVAR(swayFactorsBaseline) pushBackUnique [_id]; +} else { + GVAR(swayFactorsMultiplier) pushBackUnique [_id]; +}; + +true diff --git a/addons/common/functions/fnc_addSyncedEventHandler.sqf b/addons/common/functions/fnc_addSyncedEventHandler.sqf index 3dd4f03152..616897842b 100644 --- a/addons/common/functions/fnc_addSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_addSyncedEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Register an event handler for an ACE synced event @@ -19,12 +19,12 @@ params ["_name", "_handler", ["_ttl", 0]]; -if ([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { +if (_name in GVAR(syncedEvents)) exitWith { ERROR_1("Duplicate synced event [%1] creation.",_name); false }; -private _eventId = [_name, FUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; +private _eventId = [_name, LINKFUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; private _data = [_handler, [], _ttl, _eventId]; -[GVAR(syncedEvents), _name, _data] call CBA_fnc_hashSet; +GVAR(syncedEvents) set [_name, _data]; diff --git a/addons/common/functions/fnc_addToInventory.sqf b/addons/common/functions/fnc_addToInventory.sqf index b8b5f93635..38476ad5fc 100644 --- a/addons/common/functions/fnc_addToInventory.sqf +++ b/addons/common/functions/fnc_addToInventory.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet - * Adds an item, weapon, or magazine to the unit's inventory or places it in a weaponHolder if no space. + * Adds an item, weapon, or magazine to the unit's inventory or places it in a weapon holder if no space. * * Arguments: * 0: Unit @@ -11,10 +11,10 @@ * * Return Value: * 0: Added to player - * 1: weaponholder + * 1: Weapon holder item was placed in * * Example: - * [bob, "classname", "", 5] call ace_common_fnc_addToInventory + * [player, "30Rnd_65x39_caseless_mag", "", 5] call ace_common_fnc_addToInventory * * Public: Yes */ @@ -24,26 +24,59 @@ params ["_unit", "_classname", ["_container", ""], ["_ammoCount", -1]]; private _type = _classname call FUNC(getItemType); private _canAdd = false; +private _canFitWeaponSlot = false; private _addedToUnit = false; +private _weaponHolder = _unit; switch (_container) do { case "vest": { - _canAdd = _unit canAddItemToVest _classname; + _canAdd = [_unit, _classname, 1, false, true, false] call CBA_fnc_canAddItem; }; case "backpack": { - _canAdd = _unit canAddItemToBackpack _classname; + _canAdd = [_unit, _classname, 1, false, false, true] call CBA_fnc_canAddItem; }; case "uniform": { - _canAdd = _unit canAddItemToUniform _classname; + _canAdd = [_unit, _classname, 1, true, false, false] call CBA_fnc_canAddItem; }; default { - _canAdd = _unit canAdd _classname; + _canAdd = [_unit, _classname] call CBA_fnc_canAddItem; + if (_canAdd) then { + switch (_type select 1) do { + case "primary": { + _canFitWeaponSlot = primaryWeapon _unit == ""; + }; + case "secondary": { + _canFitWeaponSlot = secondaryWeapon _unit == ""; + }; + case "handgun": { + _canFitWeaponSlot = handgunWeapon _unit == ""; + }; + case "binocular": { + _canFitWeaponSlot = binocular _unit == ""; + }; + }; + }; + }; +}; + +if (_type select 0 == "magazine") then { + private _configAmmoCount = getNumber (configFile >> "CfgMagazines" >> _classname >> "count"); + + // https://feedback.bistudio.com/T74244 + // When adding throwables with the addXXXCargo(Global) commands, they don't show up in the throwables list + // If a throwable has more than 1 ammo count, adding it with addItem(XXX) commands also renders the throwable unusable + if (_configAmmoCount == 1 && {_ammoCount in [-1, 1]} && {_classname call BIS_fnc_isThrowable}) then { // TODO: replace with https://community.bistudio.com/wiki/isThrowable in 2.18 + _type set [0, "item"]; + }; + + if (_ammoCount == -1) then { + _ammoCount = _configAmmoCount; }; }; switch (_type select 0) do { case "weapon": { - if (_canAdd) then { + if (_canAdd || {_canFitWeaponSlot}) then { _addedToUnit = true; switch (_container) do { @@ -57,37 +90,49 @@ switch (_type select 0) do { (uniformContainer _unit) addWeaponCargoGlobal [_classname, 1]; }; default { - _unit addWeaponGlobal _classname; + if (_canFitWeaponSlot) then { + _unit addWeaponGlobal _classname; + } else { + { + _x params ["_parameters", "_container"]; + + if (_parameters call CBA_fnc_canAddItem) exitWith { + _container addWeaponCargoGlobal [_classname, 1]; // addWeaponGlobal will replace the weapon currently in a slot + }; + } forEach [ + [[_unit, _classname, 1, false, false, true], backpackContainer _unit], + [[_unit, _classname, 1, false, true, false], vestContainer _unit], + [[_unit, _classname, 1, true, false, false], uniformContainer _unit] + ]; + }; }; }; } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addWeaponCargoGlobal [_classname, 1]; - _unit setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addWeaponCargoGlobal [_classname, 1]; }; }; case "magazine": { - if (_ammoCount == -1) then { - _ammoCount = getNumber (configFile >> "CfgMagazines" >> _classname >> "count"); - }; - if (_canAdd) then { _addedToUnit = true; switch (_container) do { case "vest": { - (vestContainer _unit) addMagazineCargoGlobal [_classname, 1/*_ammoCount*/]; //@todo Bug! This isn't really the ammo, but magazine count. No such command. + (vestContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; case "backpack": { - (backpackContainer _unit) addMagazineCargoGlobal [_classname, 1/*_ammoCount*/]; //@todo Bug! This isn't really the ammo, but magazine count. No such command. + (backpackContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; case "uniform": { - (uniformContainer _unit) addMagazineCargoGlobal [_classname, 1/*_ammoCount*/]; //@todo Bug! This isn't really the ammo, but magazine count. No such command. + (uniformContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; default { _unit addMagazine [_classname, _ammoCount]; @@ -96,11 +141,13 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addMagazineCargoGlobal [_classname, 1/*_ammoCount*/]; //@todo Bug! This isn't really the ammo, but magazine count. No such command. - _unit setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; }; @@ -125,11 +172,13 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addItemCargoGlobal [_classname, 1]; - _unit setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addItemCargoGlobal [_classname, 1]; }; }; @@ -139,4 +188,4 @@ switch (_type select 0) do { }; }; -[_addedToUnit, _unit] +[_addedToUnit, _weaponHolder] diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf new file mode 100644 index 0000000000..787c9fb24a --- /dev/null +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -0,0 +1,99 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Adds weapon to unit without taking a magazine. + * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default. + * + * Arguments: + * 0: Unit to add the weapon to + * 1: Weapon to add + * 2: If linked items should be removed or not (default: false) + * 3: Magazines that should be added to the weapon (default: []) + * - 0: Magazine classname + * - 1: Ammo count + * + * Return Value: + * None + * + * Example: + * [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon + * + * Public: Yes +*/ + +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_removeLinkedItems", false, [false]], + ["_magazines", [], [[]]] +]; + +if (isNull _unit || {_weapon == ""}) exitWith {}; + +// Config case +private _compatibleMagazines = compatibleMagazines _weapon; + +private _uniform = uniformContainer _unit; +private _uniformMagazines = (magazinesAmmoCargo _uniform) select { + (_x select 0) in _compatibleMagazines // Also config case +}; + +private _vest = vestContainer _unit; +private _vestMagazines = (magazinesAmmoCargo _vest) select { + (_x select 0) in _compatibleMagazines +}; + +private _backpack = backpackContainer _unit; +private _backpackMagazines = (magazinesAmmoCargo _backpack) select { + (_x select 0) in _compatibleMagazines +}; + +// Remove all compatible magazines +{ + _unit removeMagazines _x; +} forEach _compatibleMagazines; + +// Add weapon +_unit addWeapon _weapon; + +// This doesn't remove magazines, but linked items can't be magazines, so it's fine +if (_removeLinkedItems) then { + switch (_weapon call FUNC(getConfigName)) do { + case (primaryWeapon _unit): { + removeAllPrimaryWeaponItems _unit; + }; + case (secondaryWeapon _unit): { + removeAllSecondaryWeaponItems _unit; + }; + case (handgunWeapon _unit): { + removeAllHandgunItems _unit; + }; + case (binocular _unit): { + removeAllBinocularItems _unit; + }; + }; +}; + +// Add magazines directly now, so that AI don't reload +if (_magazines isNotEqualTo []) then { + { + _x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]]; + + if (_magazine != "" && {_ammoCount > -1}) then { + _unit addWeaponItem [_weapon, [_magazine, _ammoCount], true]; + }; + } forEach _magazines; +}; + +// Add all magazines back +{ + _uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1]; +} forEach _uniformMagazines; + +{ + _vest addMagazineAmmoCargo [_x select 0, 1, _x select 1]; +} forEach _vestMagazines; + +{ + _backpack addMagazineAmmoCargo [_x select 0, 1, _x select 1]; +} forEach _backpackMagazines; diff --git a/addons/common/functions/fnc_adjustMagazineAmmo.sqf b/addons/common/functions/fnc_adjustMagazineAmmo.sqf new file mode 100644 index 0000000000..87d5b9e899 --- /dev/null +++ b/addons/common/functions/fnc_adjustMagazineAmmo.sqf @@ -0,0 +1,107 @@ +#include "..\script_component.hpp" +/* + * Author: Katalam, Blue, Brett Mayson, johnb43 + * Handle adjusting a magazine's ammo + * + * Arguments: + * 0: Vehicle or Unit + * 1: Item + * 2: Ammo to adjust by (default: -1) + * + * Return Value: + * How much the ammo was adjusted by + * + * Example: + * [player, "30Rnd_556x45_Stanag", 1] call ace_common_fnc_adjustMagazineAmmo; + * + * Public: No + */ + +params ["_unit", "_magazine", ["_count", -1]]; + +if (_count == 0) exitWith {0}; + +private _containers = if (_unit isKindOf "CAManBase") then { + [uniformContainer _unit, vestContainer _unit, backpackContainer _unit] +} else { + [_unit] +}; + +scopeName "main"; + +private _originalCount = _count; +private _container = objNull; +private _magazinesContainer = []; +private _newAmmoCount = 0; +private _removeAmmo = _count < 0; +private _maxMagazineAmmo = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); + +{ + _container = _x; + + // Get all magazines of _magazine type + _magazinesContainer = (magazinesAmmoCargo _container) select {_x select 0 == _magazine}; + + // Get the ammo count, filter out magazines with 0 ammo + _magazinesContainer = (_magazinesContainer apply {_x select 1}) select {_x != 0}; + + // If there are none, skip to next container + if (_magazinesContainer isEqualTo []) then { + continue; + }; + + // Sort, smallest first when removing, largest first when adding + _magazinesContainer sort _removeAmmo; + + if (_removeAmmo) then { + { + _count = _x + _count; + + _container addMagazineAmmoCargo [_magazine, -1, _x]; + + if (_count >= 0) then { + // Only add magazine back if it's not empty + if (_count != 0) then { + _container addMagazineAmmoCargo [_magazine, 1, _count]; + }; + + _originalCount breakOut "main"; + }; + } forEach _magazinesContainer; + } else { + // This loop only fills up partially filled magazines + { + // Fill the magazine to either its max or until all ammo has been added + _newAmmoCount = (_x + _count) min _maxMagazineAmmo; + + if (_newAmmoCount <= _maxMagazineAmmo) then { + _container addMagazineAmmoCargo [_magazine, -1, _x]; + _container addMagazineAmmoCargo [_magazine, 1, _newAmmoCount]; + }; + + // Remove the ammo that was added + _count = _count - (_newAmmoCount - _x); + + if (_count <= 0) then { + _originalCount breakOut "main"; + }; + } forEach (_magazinesContainer select {_x < _maxMagazineAmmo}); + }; +} forEach _containers; + +// If there is still remaining ammo to add, try add it after having iterated through all containers +if (!_removeAmmo && _count > 0) then { + { + while {_count > 0 && {_x canAdd [_magazine, 1/* 2.18 , true*/]}} do { + _x addMagazineAmmoCargo [_magazine, 1, _count]; + + _count = _count - _maxMagazineAmmo; + }; + } forEach _containers; + + if (_count <= 0) then { + _originalCount breakOut "main"; + }; +}; + +_originalCount - _count diff --git a/addons/common/functions/fnc_ambientBrightness.sqf b/addons/common/functions/fnc_ambientBrightness.sqf index 608c35dfef..2b1e172cc0 100644 --- a/addons/common/functions/fnc_ambientBrightness.sqf +++ b/addons/common/functions/fnc_ambientBrightness.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, idea by Falke * Returns a brightness value depending on the sun and moon state. Ranges from 0 to 1 (dark ... bright). diff --git a/addons/common/functions/fnc_arithmeticGetResult.sqf b/addons/common/functions/fnc_arithmeticGetResult.sqf index e54f44fd27..e64fed6eb4 100644 --- a/addons/common/functions/fnc_arithmeticGetResult.sqf +++ b/addons/common/functions/fnc_arithmeticGetResult.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#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) (Case Sensitive) + * 2: Operation (max, min, sum, product, avg) (Case Sensitive) * * Return Value: * Value @@ -18,51 +18,45 @@ * Public: Yes */ -params ["_namespace", "_setID", "_op"]; -TRACE_3("arithmeticGetResult",_namespace,_setID,_op); +params ["_namespace", "_setID", "_operation"]; +TRACE_3("arithmeticGetResult",_namespace,_setID,_operation); -private _data = (_namespace getVariable _setID) param [2, []]; +private _hash = _namespace getVariable [_setID, createHashMapFromArray [["empty", {0}]]]; +private _data = values _hash; -switch (_op) do { - case ("max"): { - private _result = -1e99; - { - _result = _result max (call _x); - nil - } count _data; - _result // return +switch (_operation) do { + case "max": { + selectMax (_data apply {call _x}) }; - case ("sum"): { + case "min": { + selectMin (_data apply {call _x}) + }; + case "sum": { private _result = 0; + { - _result = _result + (call _x); - nil - } count _data; - _result // return + _result = _result + call _x; + } forEach _data; + + _result }; - case ("product"): { + 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 ("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..2645e87c28 100644 --- a/addons/common/functions/fnc_arithmeticSetSource.sqf +++ b/addons/common/functions/fnc_arithmeticSetSource.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * 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,19 +20,21 @@ */ 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; + _hash = createHashMap; _namespace setVariable [_setID, _hash]; }; + if (_variable isEqualTo {}) then { TRACE_1("removing",_source); - [_hash, _source] call CBA_fnc_hashRem; + _hash deleteAt _source; } else { TRACE_2("adding",_source,_variable); - [_hash, _source, _variable] call CBA_fnc_hashSet; + _hash set [_source, _variable]; }; nil diff --git a/addons/common/functions/fnc_assignObjectsInList.sqf b/addons/common/functions/fnc_assignObjectsInList.sqf index 764675fa5f..0928812cd4 100644 --- a/addons/common/functions/fnc_assignObjectsInList.sqf +++ b/addons/common/functions/fnc_assignObjectsInList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Loops through a string and filters out object names/variables to assign a value for given variable. @@ -28,18 +28,13 @@ if (_list isEqualType "") then { }; { - if (!isNil "_x") then { - if (_x isEqualType objNull) then { - if (local _x) then { - if (_vehicle) then { - (vehicle _x) setVariable [_variable, _setting, _global]; - TRACE_6("Set variable vehicle",_x,vehicle _x,typeOf (vehicle _x),_variable,_setting,_global); - } else { - _x setVariable [_variable, _setting, _global]; - TRACE_5("Set variable",_x,typeOf _x,_variable,_setting,_global); - }; - }; + if (!isNil "_x" && {_x isEqualType objNull} && {local _x}) then { + if (_vehicle) then { + (vehicle _x) setVariable [_variable, _setting, _global]; + TRACE_6("Set variable vehicle",_x,vehicle _x,typeOf (vehicle _x),_variable,_setting,_global); + } else { + _x setVariable [_variable, _setting, _global]; + TRACE_5("Set variable",_x,typeOf _x,_variable,_setting,_global); }; }; - false -} count _list; +} forEach _list; diff --git a/addons/common/functions/fnc_assignedItemFix.sqf b/addons/common/functions/fnc_assignedItemFix.sqf index 3f523f4a59..942d170fea 100644 --- a/addons/common/functions/fnc_assignedItemFix.sqf +++ b/addons/common/functions/fnc_assignedItemFix.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Initialized the assigned item fix. @@ -37,11 +37,11 @@ GVAR(AssignedItemsShownItems) = [ private _assignedItems = getUnitLoadout _unit param [9, ["","","","","",""]]; // ["ItemMap","ItemGPS","ItemRadio","ItemCompass","ItemWatch","NVGoggles"] GVAR(AssignedItemsShownItems) = [ - !((_assignedItems select 0) isEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 0 >> "ACE_hideItemType") != "map"}, - !((_assignedItems select 3) isEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 3 >> "ACE_hideItemType") != "compass"}, - !((_assignedItems select 4) isEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 4 >> "ACE_hideItemType") != "watch"}, - !((_assignedItems select 2) isEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 2 >> "ACE_hideItemType") != "radio"}, - !((_assignedItems select 1) isEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 1 >> "ACE_hideItemType") != "gps"} + ((_assignedItems select 0) isNotEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 0 >> "ACE_hideItemType") != "map"}, + ((_assignedItems select 3) isNotEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 3 >> "ACE_hideItemType") != "compass"}, + ((_assignedItems select 4) isNotEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 4 >> "ACE_hideItemType") != "watch"}, + ((_assignedItems select 2) isNotEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 2 >> "ACE_hideItemType") != "radio"}, + ((_assignedItems select 1) isNotEqualTo "") && {getText (configFile >> "CfgWeapons" >> _assignedItems select 1 >> "ACE_hideItemType") != "gps"} ]; GVAR(AssignedItemsShownItems) params ["_showMap", "_showCompass", "_showWatch", "_showRadio", "_showGPS"]; diff --git a/addons/common/functions/fnc_binarizeNumber.sqf b/addons/common/functions/fnc_binarizeNumber.sqf index 780551756c..830417477a 100644 --- a/addons/common/functions/fnc_binarizeNumber.sqf +++ b/addons/common/functions/fnc_binarizeNumber.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get a binary equivalent of a decimal number. diff --git a/addons/common/functions/fnc_blurScreen.sqf b/addons/common/functions/fnc_blurScreen.sqf index 339a1138e6..bbc57d43a8 100644 --- a/addons/common/functions/fnc_blurScreen.sqf +++ b/addons/common/functions/fnc_blurScreen.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Blurs screen. diff --git a/addons/common/functions/fnc_cachedCall.sqf b/addons/common/functions/fnc_cachedCall.sqf index 728303d6cd..dbf81b7676 100644 --- a/addons/common/functions/fnc_cachedCall.sqf +++ b/addons/common/functions/fnc_cachedCall.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain, Jaynus * Returns the result of the function and caches it up to a given time or event @@ -9,7 +9,7 @@ * 2: Namespace to store the cache on * 3: Cache uid * 4: Max duration of the cache - * 5: Event that clears the cache (default: nil) + * 5: Events that clear the cache (default: nil) * * Return Value: * Result of the function @@ -20,41 +20,46 @@ * Public: No */ -params ["_params", "_function", "_namespace", "_uid", "_duration", "_event"]; +params ["_params", "_function", "_namespace", "_uid", "_duration", "_events"]; if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then { _namespace setVariable [_uid, [diag_tickTime + _duration, _params call _function]]; // Does the cache need to be cleared on an event? - if (!isNil "_event") then { - private _varName = format [QGVAR(clearCache_%1), _event]; - private _cacheList = missionNamespace getVariable _varName; - - // If there was no EH to clear these caches, add one - if (isNil "_cacheList") then { - _cacheList = []; - missionNamespace setVariable [_varName, _cacheList]; - - [_event, { - #ifdef DEBUG_MODE_FULL - INFO_1("Clear cached variables on event: %1",_eventName); - #endif - // Get the list of caches to clear - //IGNORE_PRIVATE_WARNING ["_eventName"]; - // _eventName is defined on the function that calls the event - private _varName = format [QGVAR(clearCache_%1), _eventName]; - private _cacheList = missionNamespace getVariable [_varName, []]; - // Erase all the cached results - { - _x call FUNC(eraseCache); - } forEach _cacheList; - // Empty the list - missionNamespace setVariable [_varName, []]; - }] call CBA_fnc_addEventHandler; + if (!isNil "_events") then { + if (_events isEqualType "") then { + _events = [_events]; }; + { + private _event = _x; + private _varName = format [QGVAR(clearCache_%1), _event]; + private _cacheList = missionNamespace getVariable _varName; - // Add this cache to the list of the event - _cacheList pushBack [_namespace, _uid]; + // If there was no EH to clear these caches, add one + if (isNil "_cacheList") then { + _cacheList = []; + missionNamespace setVariable [_varName, _cacheList]; + + [_event, { + #ifdef DEBUG_MODE_FULL + INFO_1("Clear cached variables on event: %1",_eventName); + #endif + // Get the list of caches to clear + //IGNORE_PRIVATE_WARNING ["_eventName"]; + // _eventName is defined on the function that calls the event + private _varName = format [QGVAR(clearCache_%1), _eventName]; + private _cacheList = missionNamespace getVariable [_varName, []]; + // Erase all the cached results + { + _x call FUNC(eraseCache); + } forEach _cacheList; + // Empty the list + missionNamespace setVariable [_varName, []]; + }] call CBA_fnc_addEventHandler; + }; + // Add this cache to the list of the event + _cacheList pushBack [_namespace, _uid]; + } forEach _events; }; #ifdef DEBUG_MODE_FULL diff --git a/addons/common/functions/fnc_canDig.sqf b/addons/common/functions/fnc_canDig.sqf index e96b44a478..bd620d313a 100644 --- a/addons/common/functions/fnc_canDig.sqf +++ b/addons/common/functions/fnc_canDig.sqf @@ -1,37 +1,39 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg, commy2 * Checks if the player can dig on the surface below (enough dust). * * Arguments: - * 0: Unit + * 0: Unit or Position (2d/3d) * * Return Value: * Can Dig * * Example: * [ACE_player] call ace_common_fnc_canDig + * [[1000,2000]] call ace_common_fnc_canDig * * Public: No */ -params ["_unit"]; +params ["_input"]; -private _posASL = getPosASL _unit; +private _posASL = _input; -if ((getPosATL _unit) select 2 > 0.05 || // Walking on objects, such as buildings, pavements, etc. - {surfaceIsWater _posASL} // posATL in low water (not as low to allow awalking) is negative -) exitWith {false}; +if ((_input isEqualType objNull) && { + _posASL = getPosASL _input; + (getPosATL _input) select 2 > 0.05 || // Walking on objects, such as buildings, pavements, etc. + {surfaceIsWater _posASL} // posATL in low water (not as low to allow walking) is negative +}) exitWith {false}; private _surfaceClass = (surfaceType _posASL) select [1]; private _config = configFile >> "CfgSurfaces" >> _surfaceClass; -private _surfaceType = getText (_config >> "soundEnviron"); -private _surfaceDust = getNumber (_config >> "dust"); -TRACE_2("Surface",_surfaceType,_surfaceDust); +TRACE_3("",_surfaceClass,getText (_config >> "soundEnviron"),getNumber (_config >> "dust")); if (isNumber (_config >> "ACE_canDig")) then { - getNumber (_config >> "ACE_canDig") // return + (getNumber (_config >> "ACE_canDig")) == 1 // return } else { - !(_surfaceType in DIG_SURFACE_BLACKLIST) && {(_surfaceDust >= 0.1) || {_surfaceType in DIG_SURFACE_WHITELIST}} // return + private _surfaceType = getText (_config >> "soundEnviron"); + GVAR(canDigSurfaces) getOrDefault [_surfaceType, getNumber (_config >> "dust") >= 0.1, true] // return }; diff --git a/addons/common/functions/fnc_canGetInPosition.sqf b/addons/common/functions/fnc_canGetInPosition.sqf index 22d885b38c..777f3103a5 100644 --- a/addons/common/functions/fnc_canGetInPosition.sqf +++ b/addons/common/functions/fnc_canGetInPosition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Is the unit able to enter the vehicle in the given position? @@ -24,14 +24,14 @@ params ["_unit", "_vehicle", "_position", ["_checkDistance", false], ["_index", -1]]; -_position = toLower _position; +_position = toLowerANSI _position; // general if (!alive _vehicle || {locked _vehicle > 1}) exitWith {false}; private ["_selectionPosition", "_selectionPosition2"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _turret = []; private _radius = 0; diff --git a/addons/common/functions/fnc_canInteractWith.sqf b/addons/common/functions/fnc_canInteractWith.sqf index b67e57964f..dd684d0619 100644 --- a/addons/common/functions/fnc_canInteractWith.sqf +++ b/addons/common/functions/fnc_canInteractWith.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit can interact. @@ -19,7 +19,7 @@ params ["_unit", "_target", ["_exceptions", []]]; -_exceptions = _exceptions apply {toLower _x}; +_exceptions = _exceptions apply {toLowerANSI _x}; private _owner = _target getVariable [QGVAR(owner), objNull]; diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf index 273c72323e..29e4d532b1 100644 --- a/addons/common/functions/fnc_cbaSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Called at pre-init: Loads all ace_settings and converts them to CBA Settings. @@ -66,8 +66,7 @@ GVAR(settingsMovedToSQF) = []; INFO_1("%1 delayed functions running.",count GVAR(runAtSettingsInitialized)); { (_x select 1) call (_x select 0); - false - } count GVAR(runAtSettingsInitialized); + } forEach GVAR(runAtSettingsInitialized); GVAR(runAtSettingsInitialized) = nil; //cleanup #ifdef DEBUG_MODE_FULL @@ -104,7 +103,7 @@ TRACE_1("Reading settings from missionConfigFile",_countOptions); for "_index" from 0 to (_countOptions - 1) do { private _optionEntry = _missionSettingsConfig select _index; private _settingName = configName _optionEntry; - if ((toLower _settingName) in GVAR(cbaSettings_forcedSettings)) then { + if ((toLowerANSI _settingName) in GVAR(cbaSettings_forcedSettings)) then { WARNING_1("Setting [%1] - Already Forced - ignoring missionConfig",_varName); } else { if ((isNil _settingName) && {(getNumber (_settingsConfig >> _settingName >> "movedToSQF")) == 0}) then { diff --git a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf index 8c892bcf13..02fdfa0193 100644 --- a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf +++ b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf @@ -1,5 +1,5 @@ #define DEBUG_MODE_FULL -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Dev function: Converts ace_settings to code, outputs to clipboard @@ -22,7 +22,7 @@ private _output = [format ["// CBA Settings [ADDON: %1]:", _addon]]; private _addonSearch = _addon + "_"; private _addonSearchCount = count _addonSearch; -TRACE_2("",_addonSearch, _addonSearchCount); +TRACE_2("",_addonSearch,_addonSearchCount); private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x) && {((configName _x) select [0, _addonSearchCount]) == _addonSearch}"]; @@ -44,7 +44,7 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x private _cbaIsGlobal = (!_isClientSettable) || _isForced; private _warnIfChangedMidMission = _cbaIsGlobal && {(getNumber (_config >> "canBeChanged")) == 0}; - if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; + if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLowerANSI _varName);}; // Basic handling of setting types CBA doesn't support: if (_typeName == "ARRAY") exitWith { @@ -55,7 +55,7 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x private _cbaSettingType = ""; private _cbaValueInfo = []; - _cbaValueInfoHint = "default value"; + private _cbaValueInfoHint = "default value"; switch (_typeName) do { case ("SCALAR"): { // ACE's Scalar can be a float or an index for a list if (!isNumber (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing number",_varName,_typeName);}; @@ -110,7 +110,6 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x private _gvarName = _varName select [_addonSearchCount]; - _output pushBack ""; _output pushBack format ["["]; _output pushBack format [" QGVAR(%1), ""%2"",", _gvarName, _cbaSettingType]; _output pushBack format [" [LSTRING(), LSTRING()], // %1, %2", _localizedName, _localizedDescription]; //IGNORE_STRING_WARNING(str_ace_common_); @@ -123,7 +122,8 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x _output pushBack format [" {[""%1"", _this] call ace_common_fnc_cbaSettings_settingChanged},", _varName]; }; _output pushBack format [" %1 // Needs mission restart", _warnIfChangedMidMission]; - _output pushBack "] call CBA_settings_fnc_init;"; + _output pushBack "] call CBA_fnc_addSetting;"; + _output pushBack ""; } forEach _settings; copyToClipboard (_output joinString endl); diff --git a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf index 7f6637f622..57b93c9963 100644 --- a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf +++ b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Converts a ace_setting config into a cba setting @@ -18,6 +18,7 @@ params ["_config"]; private _varName = configName _config; +INFO_1("Loading ace_setting from config [%1] - consider updating to native cba_settings",_varName); private _typeName = toUpper getText (_config >> "typeName"); if (_typeName == "") then { WARNING_1("Setting [%1] Has no typeName",_varName); @@ -33,7 +34,7 @@ private _category = getText (_config >> "category"); private _cbaIsGlobal = (!_isClientSettable) || _isForced; private _warnIfChangedMidMission = _cbaIsGlobal && {(getNumber (_config >> "canBeChanged")) == 0}; -if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; +if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLowerANSI _varName);}; // Basic handling of setting types CBA doesn't support: if (_typeName == "ARRAY") exitWith { @@ -98,8 +99,7 @@ private _code = compile format ['["%1", _this] call FUNC(cbaSettings_settingChan TRACE_2("setting",_cbaSettingType,_cbaValueInfo); TRACE_4("",_isForced,_cbaIsGlobal,_category,_cbaValueInfo); -private _return = [_varName, _cbaSettingType, [_localizedName, _localizedDescription], _category, _cbaValueInfo, _cbaIsGlobal, _code, _warnIfChangedMidMission] call CBA_settings_fnc_init; +private _return = [_varName, _cbaSettingType, [_localizedName, _localizedDescription], _category, _cbaValueInfo, _cbaIsGlobal, _code, _warnIfChangedMidMission] call CBA_fnc_addSetting; TRACE_1("returned",_return); -if ((isNil "_return") || {_return != 0}) then {ERROR_1("Setting [%1] - CBA Error",_varName);}; +if ((isNil "_return") || {!_return}) then {ERROR_1("Setting [%1] - CBA Error",_varName);}; _return - diff --git a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf index 055e9b9da6..cf9f18166a 100644 --- a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Function for handeling a cba setting being changed. - * Adds warning if global setting is changed after ace_settingsInitialized + * Function for handling a cba setting being changed. + * Adds warning if global setting is changed after ace_settingsInitialized. * * Arguments: * 0: Setting Name @@ -21,9 +21,7 @@ params ["_settingName", "_newValue", ["_canBeChanged", false]]; TRACE_2("",_settingName,_newValue); -["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent; - -if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {}; +if !((toLower _settingName) in CBA_settings_needRestart) exitWith {}; if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);}; if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized diff --git a/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf index 703e0263dc..8b6e62cbf6 100644 --- a/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Transfers a client's old ace settings to cba @@ -31,10 +31,10 @@ private _aceSettings = configProperties [configFile >> "ACE_Settings", "isClass if (!isNil "_profileVar") then { private _currentValue = [_settingName, "client"] call CBA_settings_fnc_get; - if (_isClientSettable && {!(_currentValue isEqualTo _profileVar)}) then { + if (_isClientSettable && {_currentValue isNotEqualTo _profileVar}) then { // CBA_settings_fnc_set will do type checking for the old profile var private _ret = [_settingName, _profileVar, 0, "client", true] call CBA_settings_fnc_set; - INFO_3("Transfering setting [%1: %2] returned %3", _settingName, _profileVar, _ret); + INFO_3("Transfering setting [%1: %2] returned %3",_settingName,_profileVar,_ret); }; }; } forEach _aceSettings; diff --git a/addons/common/functions/fnc_changeProjectileDirection.sqf b/addons/common/functions/fnc_changeProjectileDirection.sqf index f355662598..85f84d1fe9 100644 --- a/addons/common/functions/fnc_changeProjectileDirection.sqf +++ b/addons/common/functions/fnc_changeProjectileDirection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Adjust a projectiles velocity and dir + up vector. diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index dee144c40e..7b90a1b0a8 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Compares version numbers of PBOs and DLLs. @@ -15,134 +15,191 @@ * Public: No */ -/////////////// -// check addons -/////////////// -private _version = getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr"); +// Don't execute in scheduled environment +if (canSuspend) exitWith { + [FUNC(checkFiles), nil] call CBA_fnc_directCall; +}; -INFO_1("ACE is version %1.",_version); +/////////////// +// Check addons +/////////////// +private _cfgPatches = configFile >> "CfgPatches"; +private _mainVersion = getText (_cfgPatches >> "ace_main" >> "versionStr"); +private _mainSource = configSourceMod (_cfgPatches >> "ace_main"); -//CBA Versioning check - close main display if using incompatible version -private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr"); +// CBA Versioning check - close main display if using incompatible version +private _cbaVersionAr = getArray (_cfgPatches >> "cba_main" >> "versionAr"); private _cbaRequiredAr = getArray (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> "ACE" >> "dependencies" >> "CBA") select 1; private _cbaVersionStr = _cbaVersionAr joinString "."; private _cbaRequiredStr = _cbaRequiredAr joinString "."; -INFO_2("CBA is version %1 (min required %2)",_cbaVersionStr,_cbaRequiredStr); +INFO_3("ACE is version %1 - CBA is version %2 (min required %3)",_mainVersion,_cbaVersionStr,_cbaRequiredStr); -if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) then { +if ([_cbaRequiredAr, _cbaVersionAr] call CBA_versioning_fnc_version_compare) then { private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr]; ERROR(_errorMsg); + if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; -//private _addons = activatedAddons; // broken with High-Command module, see #2134 -private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLower _x}; +//private _addons = activatedAddons; // Broken with High-Command module, see #2134 +private _addons = (CBA_common_addons select {(_x select [0, 4]) == "ace_"}) apply {toLowerANSI _x}; +private _oldAddons = []; +private _oldSources = []; private _oldCompats = []; + { - if (getText (configFile >> "CfgPatches" >> _x >> "versionStr") != _version) then { - private _errorMsg = format ["File %1.pbo is outdated.", _x]; + private _addonCfg = configFile >> "CfgPatches" >> _x; + private _addonVersion = getText (_addonCfg >> "versionStr"); - ERROR(_errorMsg); + if (_addonVersion != _mainVersion) then { + private _addonSource = configSourceMod _addonCfg; + _oldSources pushBackUnique _addonSource; + + // Check ACE install + call FUNC(checkFiles_diagnoseACE); + + // Don't block game if it's just an old compat pbo if ((_x select [0, 10]) != "ace_compat") then { - if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); - }; + _oldAddons pushBack _x; } else { - _oldCompats pushBack _x; // Don't block game if it's just an old compat pbo + _oldCompats pushBack [_x, _addonVersion]; }; }; - false -} count _addons; -if (!(_oldCompats isEqualTo [])) then { +} forEach _addons; + +if (_oldAddons isNotEqualTo []) then { + _oldAddons = _oldAddons apply {format ["%1.pbo", _x]}; + + private _errorMsg = if (count _oldAddons > 3) then { + format ["The following files are outdated: %1, and %2 more.
ACE Main version is %3 from %4.
Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) - 3, _mainVersion, _mainSource, _oldSources joinString ", "]; + } else { + format ["The following files are outdated: %1.
ACE Main version is %2 from %3.
Loaded mods with outdated ACE files: %4", _oldAddons joinString ", ", _mainVersion, _mainSource, _oldSources joinString ", "]; + }; + + if (hasInterface) then { + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); + }; + + ERROR(_errorMsg); +}; + +if (_oldCompats isNotEqualTo []) then { + _oldCompats = _oldCompats apply {format ["%1 (%2)", _x select 0, _x select 1]}; + [{ // Lasts for ~10 seconds - ERROR_WITH_TITLE_1("The following ACE compatiblity PBOs are outdated", "%1", _this); - }, _oldCompats, 1] call CBA_fnc_waitAndExecute; + ERROR_WITH_TITLE_3("The following ACE compatiblity PBOs are outdated","%1. ACE Main version is %2 from %3.",_this select 0,_this select 1,_this select 2); + }, [_oldCompats, _mainVersion, _mainSource], 1] call CBA_fnc_waitAndExecute; }; /////////////// -// check dlls +// Check extensions /////////////// -if (toLower (productVersion select 6) in ["linux", "osx"]) then { - INFO("Operating system does not support DLL file format"); +private _platform = toLowerANSI (productVersion select 6); + +if (!isServer && {_platform in ["linux", "osx"]}) then { + // Linux and OSX client ports do not support extensions at all + INFO("Operating system does not support extensions"); } 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 (productVersion select 7 == "x64") then { - _extension = "_x64.dll"; + if (_versionEx == "") then { + private _extensionFile = _extension; + + if (productVersion select 7 == "x64") then { + _extensionFile = format ["%1_x64", _extensionFile]; + }; + + 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] 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")); +}; + +if (isArray (configFile >> "ACE_Extensions" >> "extensions")) then { + WARNING("extensions[] array no longer supported"); }; /////////////// -// check server version/addons +// Check server version/addons /////////////// if (isMultiplayer) then { - // don't check optional addons - _addons = _addons select {getNumber (configFile >> "CfgPatches" >> _x >> "ACE_isOptional") != 1}; + // Don't check optional addons + _addons = _addons select {getNumber (_cfgPatches >> _x >> "ACE_isOptional") != 1}; if (isServer) then { - // send servers version of ACE to all clients - GVAR(ServerVersion) = _version; - GVAR(ServerAddons) = _addons; - publicVariable QGVAR(ServerVersion); - publicVariable QGVAR(ServerAddons); + // Send server's version of ACE to all clients + GVAR(serverVersion) = _mainVersion; + GVAR(serverAddons) = _addons; + GVAR(serverSource) = _mainSource; + + publicVariable QGVAR(serverVersion); + publicVariable QGVAR(serverAddons); + publicVariable QGVAR(serverSource); } else { - // clients have to wait for the variables - [{ - if (isNil QGVAR(ServerVersion) || isNil QGVAR(ServerAddons)) exitWith {}; + GVAR(clientVersion) = _version; + GVAR(clientAddons) = _addons; - (_this select 0) params ["_version", "_addons"]; + private _fnc_check = { + if (GVAR(clientVersion) != GVAR(serverVersion)) then { + private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2. Server modDir: %3", GVAR(serverVersion), GVAR(clientVersion), GVAR(serverSource)]; - if (_version != GVAR(ServerVersion)) then { - private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _version]; + // Check ACE install + call FUNC(checkFiles_diagnoseACE); ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; - _addons = _addons - GVAR(ServerAddons); - if !(_addons isEqualTo []) then { - private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons]; + private _addons = GVAR(clientAddons) - GVAR(serverAddons); + + if (_addons isNotEqualTo []) then { + private _errorMsg = format ["Client/Server Addon Mismatch. Client has additional addons: %1. Server modDir: %2", _addons, GVAR(serverSource)]; + + // Check ACE install + call FUNC(checkFiles_diagnoseACE); ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; + }; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }, 1, [_version,_addons]] call CBA_fnc_addPerFrameHandler; + // Clients have to wait for the variables + if (isNil QGVAR(serverVersion) || isNil QGVAR(serverAddons)) then { + GVAR(serverVersion) addPublicVariableEventHandler _fnc_check; + } else { + call _fnc_check; + }; }; }; diff --git a/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf new file mode 100644 index 0000000000..f9271ca213 --- /dev/null +++ b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf @@ -0,0 +1,74 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Diagnoses ACE install problems, this will only be called if there is a known problem. + * + * Arguments: + * None + * + * Return Value: + * ACE addons' WS IDs + * + * Example: + * [] call ace_common_fnc_checkFiles_diagnoseACE + * + * Public: No + */ + +// Only run once +if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith { + createHashMap // return +}; + +GVAR(checkFiles_diagnoseACE) = true; + +private _addons = CBA_common_addons select {(_x select [0, 4]) == "ace_"}; +private _cfgPatches = configFile >> "CfgPatches"; +private _allMods = createHashMap; +private _getLoadedModsInfo = getLoadedModsInfo; + +// Check if ACE_ADDONs are in expected mod DIR +{ + private _cfg = _cfgPatches >> _x; + private _actualModDir = configSourceMod _cfg; + private _expectedModDir = getText (_cfg >> "ACE_expectedModDir"); + + if (_expectedModDir == "") then { + _expectedModDir = "@ace"; + }; + + private _expectedSteamID = getText (_cfg >> "ACE_expectedSteamID"); + + if (_expectedSteamID == "") then { + _expectedSteamID = "463939057" + }; + + (_allMods getOrDefault [_actualModDir, [], true]) pushBackUnique _expectedSteamID; + + if (_actualModDir != _expectedModDir) then { + private _errorMsg = format ["%1 loading from unexpected modDir [%2]", _x, _actualModDir]; + systemChat _errorMsg; + WARNING_1("%1",_errorMsg); + }; +} forEach _addons; + +// Check if all ACE ModDirs have expected steam WS ID +{ + private _modDir = _x; + + if (count _y != 1) then { + ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y); + }; + + private _expectedSteamID = _y select 0; + private _index = _getLoadedModsInfo findIf {_x select 1 == _modDir}; + (_getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]]; + + if (_actualID != _expectedSteamID) then { + private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]", _modDir, _modName, _actualID]; + systemChat _errorMsg; + WARNING_1("%1",_errorMsg); + }; +} forEach _allMods; + +_allMods // return diff --git a/addons/common/functions/fnc_checkPBOs.sqf b/addons/common/functions/fnc_checkPBOs.sqf index b45fae45d6..4f2e3f4fa6 100644 --- a/addons/common/functions/fnc_checkPBOs.sqf +++ b/addons/common/functions/fnc_checkPBOs.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Used to execute the checkPBOs module without placing the module. Don't use this together with the module. * Checks PBO versions and compares to the one running on server. * @@ -9,8 +9,8 @@ * 0 = Warn once * 1 = Warn permanently * 2 = Kick - * 1: Check all PBOs? (default: false) - * 2: Whitelist (default: "") + * 1: Check all PBOs? (default: false) + * 2: Whitelist (default: "") * * Return Value: * None @@ -24,83 +24,75 @@ params ["_mode", ["_checkAll", false], ["_whitelist", "", [""]]]; TRACE_3("params",_mode,_checkAll,_whitelist); -//lowercase and convert whiteList String into array of strings: -_whitelist = toLower _whitelist; +// Lowercase and convert whiteList string into array of strings +_whitelist = toLowerANSI _whitelist; _whitelist = _whitelist splitString "[,""']"; TRACE_1("Array",_whitelist); ACE_Version_CheckAll = _checkAll; ACE_Version_Whitelist = _whitelist; -if (!_checkAll) exitWith {}; //ACE is checked by FUNC(checkFiles) +// ACE is checked by FUNC(checkFiles) +if (!_checkAll) exitWith {}; if (!isServer) then { - [{ - if (isNil "ACE_Version_ClientErrors") exitWith {}; + ["ace_versioning_clientCheckDone", { + // Don't let this event get triggered again + [_thisType, _thisId] call CBA_fnc_removeEventHandler; - ACE_Version_ClientErrors params ["_missingAddon", "_missingAddonServer", "_oldVersionClient", "_oldVersionServer"]; + params ["_clientErrors"]; + _clientErrors params ["_missingAddonClient", "_additionalAddonClient", "_olderVersionClient", "_newerVersionClient"]; + _thisArgs params ["_mode"]; - (_this select 0) params ["_mode", "_checkAll", "_whitelist"]; + // Display error message(s) + if (_missingAddonClient || {_additionalAddonClient} || {_olderVersionClient} || {_newerVersionClient}) then { + private _errorMsg = "[ACE] Version mismatch:

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

"; - private _error = format ["ACE version mismatch: %1: ", profileName]; - - if (_missingAddon) then { - _text = _text + "Detected missing addon on client
"; - _error = _error + "Missing file(s); "; - }; - if (_missingAddonServer) then { - _text = _text + "Detected missing addon on server
"; - _error = _error + "Additional file(s); "; - }; - if (_oldVersionClient) then { - _text = _text + "Detected old client version
"; - _error = _error + "Older version; "; - }; - if (_oldVersionServer) then { - _text = _text + "Detected old server version
"; - _error = _error + "Newer version; "; + if (_missingAddonClient) then { + _errorMsg = _errorMsg + "Detected missing addon on client
"; + _error pushBack "Missing file(s)"; }; - //[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; + if (_additionalAddonClient) then { + _errorMsg = _errorMsg + "Detected additional addon on client
"; + _error pushBack "Additional file(s)"; + }; - ERROR(_error); + if (_olderVersionClient) then { + _errorMsg = _errorMsg + "Detected older client version
"; + _error pushBack "Older version"; + }; + if (_newerVersionClient) then { + _errorMsg = _errorMsg + "Detected newer client version
"; + _error pushBack "Newer version"; + }; + + ERROR_2("[ACE] Version mismatch: %1: %2",profileName,_error joinString ", "); + + _errorMsg = parseText format ["%1", _errorMsg]; + + // Warn if (_mode < 2) then { - _text = composeText [lineBreak, parseText format ["%1", _text]]; - private _rscLayer = "ACE_RscErrorHint" call BIS_fnc_rscLayer; _rscLayer cutRsc ["ACE_RscErrorHint", "PLAIN", 0, true]; - disableSerialization; - private _ctrlHint = uiNamespace getVariable "ACE_ctrlErrorHint"; - _ctrlHint ctrlSetStructuredText _text; + (uiNamespace getVariable "ACE_ctrlErrorHint") ctrlSetStructuredText composeText [lineBreak, _errorMsg]; if (_mode == 0) then { [{ - params ["_rscLayer"]; - TRACE_2("Hiding Error message after 10 seconds",time,_rscLayer); - _rscLayer cutFadeOut 0.2; - }, [_rscLayer], 10] call CBA_fnc_waitAndExecute; + TRACE_2("Hiding Error message after 10 seconds",time,_this); + _this cutFadeOut 0.2; + }, _rscLayer, 10] call CBA_fnc_waitAndExecute; }; - }; - - if (_mode == 2) then { - [{alive player}, { // To be able to show list if using checkAll - params ["_text"]; - TRACE_2("Player is alive, showing msg and exiting",time,_text); - _text = composeText [parseText format ["%1", _text]]; - ["[ACE] ERROR", _text, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); - }, [_text]] call CBA_fnc_waitUntilAndExecute; + } else { + // Kick + ["[ACE] ERROR", composeText [_errorMsg]] call FUNC(errorMessage); }; }; - - [_this select 1] call CBA_fnc_removePerFrameHandler; - }, 1, [_mode, _checkAll, _whitelist]] call CBA_fnc_addPerFrameHandler; + }, [_mode]] call CBA_fnc_addEventHandlerArgs; }; -if (_checkAll) then { - 0 spawn COMPILE_FILE(scripts\checkVersionNumber); // @todo -}; +// Check file version numbers +[_whitelist] call FUNC(checkVersionNumber); diff --git a/addons/common/functions/fnc_checkVersionNumber.sqf b/addons/common/functions/fnc_checkVersionNumber.sqf new file mode 100644 index 0000000000..a286129917 --- /dev/null +++ b/addons/common/functions/fnc_checkVersionNumber.sqf @@ -0,0 +1,161 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Compares version numbers from loaded addons. + * + * Arguments: + * 0: Lowercase addon whitelist (default: missionNamespace getVariable ["ACE_Version_Whitelist", []]) + * + * Return Value: + * None + * + * Example: + * call ace_common_fnc_checkVersionNumber + * + * Public: No + */ + +// Don't execute in scheduled environment +if (canSuspend) exitWith { + [FUNC(checkVersionNumber), _this] call CBA_fnc_directCall; +}; + +params [["_whitelist", missionNamespace getVariable ["ACE_Version_Whitelist", []]]]; + +private _files = CBA_common_addons select { + (_x select [0, 3] != "a3_") && + {_x select [0, 4] != "ace_"} && + {!((toLowerANSI _x) in _whitelist)} +}; + +private _cfgPatches = configFile >> "CfgPatches"; +private _versions = []; + +{ + (getText (_cfgPatches >> _x >> "version") splitString ".") params [["_major", "0"], ["_minor", "0"]]; + private _version = parseNumber _major + parseNumber _minor / 100; + _versions pushBack _version; +} forEach _files; + +if (isServer) exitWith { + ACE_Version_ServerVersions = [_files, _versions]; + publicVariable "ACE_Version_ServerVersions"; + + // Raise event when done + ["ace_versioning_serverCheckDone", [+ACE_Version_ServerVersions]] call CBA_fnc_localEvent; +}; + +// Begin client version check +ACE_Version_ClientVersions = [_files, _versions]; + +private _fnc_check = { + ACE_Version_ClientVersions params [["_files", []], ["_versions", []]]; + ACE_Version_ServerVersions params [["_serverFiles", []], ["_serverVersions", []]]; + + // Compare client and server files and versions + private _client = profileName; + private _missingAddonsClient = []; + private _olderVersionsClient = []; + private _newerVersionsClient = []; + + { + private _serverVersion = _serverVersions select _forEachIndex; + + private _index = _files find _x; + + if (_index == -1) then { + if (_x != "ace_server") then { + _missingAddonsClient pushBack _x; + }; + } else { + private _clientVersion = _versions select _index; + + if (_clientVersion < _serverVersion) then { + _olderVersionsClient pushBack [_x, _clientVersion, _serverVersion]; + }; + + if (_clientVersion > _serverVersion) then { + _newerVersionsClient pushBack [_x, _clientVersion, _serverVersion]; + }; + }; + } forEach _serverFiles; + + // Find client files which the server doesn't have + private _additionalAddonsClient = _files select {!(_x in _serverFiles)}; + + // Check for client missing addons, server missing addons, client outdated addons and server outdated addons + private _clientErrors = []; + + #define DISPLAY_NUMBER_ADDONS (10 + 1) // +1 to account for header + + { + _x params ["_items", "_string"]; + + // Check if something is either missing or outdated + private _isMissingItems = _items isNotEqualTo []; + + if (_isMissingItems) then { + // Generate error message + private _errorLog = +_items; + private _header = format ["[ACE] %1: ERROR %2 addon(s): ", _client, _string]; + + // Don't display all missing items, as they are logged + private _errorMsg = _header + ((_errorLog select [0, DISPLAY_NUMBER_ADDONS]) joinString ", "); + _errorLog = _header + (_errorLog joinString ", "); + + private _count = count _items; + + if (_count > DISPLAY_NUMBER_ADDONS) then { + _errorMsg = _errorMsg + format [", and %1 more.", _count - DISPLAY_NUMBER_ADDONS]; + }; + + // Wait until in briefing screen + [{ + getClientStateNumber >= 9 // "BRIEFING SHOWN" + }, { + params ["_errorLog", "_errorMsg"]; + + // Log and display error messages + diag_log text _errorLog; + [QGVAR(serverLog), _errorLog] call CBA_fnc_serverEvent; + [QGVAR(systemChatGlobal), _errorMsg] call CBA_fnc_globalEvent; + + // Wait until after map screen + [{ + !isNull (call BIS_fnc_displayMission) + }, { + params ["_errorMsg", "_timeOut"]; + + // If the briefing screen was shown for less than 5 seconds, display the error message again, but locally + if (_timeOut < CBA_missionTime) exitWith {}; + + // Make sure systemChat is ready by waiting a bit + [{ + systemChat _this; + }, _errorMsg, 1] call CBA_fnc_waitAndExecute; + }, [_errorMsg, CBA_missionTime + 5]] call CBA_fnc_waitUntilAndExecute; + }, [_errorLog, _errorMsg]] call CBA_fnc_waitUntilAndExecute; + }; + + _clientErrors pushBack _isMissingItems; + } forEach [ + [_missingAddonsClient, "client missing"], + [_additionalAddonsClient, "client additional"], + [_olderVersionsClient, "older client"], + [_newerVersionsClient, "newer client"] + ]; + + TRACE_4("",_missingAddonsClient,_additionalAddonsClient,_olderVersionsClient,_newerVersionsClient); + + ACE_Version_ClientErrors = _clientErrors; + + // Raise event when done + ["ace_versioning_clientCheckDone", [+ACE_Version_ClientErrors]] call CBA_fnc_localEvent; +}; + +// Wait for server to send the servers files and version numbers +if (isNil "ACE_Version_ServerVersions") then { + ACE_Version_ServerVersions addPublicVariableEventHandler _fnc_check; +} else { + call _fnc_check; +}; diff --git a/addons/common/functions/fnc_claim.sqf b/addons/common/functions/fnc_claim.sqf index 3c30b8f28f..997d54f33b 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Unit claims the ownership over an object. This is used to prevent multiple players from draging the same ammo box or using up the same wheel when repairing etc. @@ -30,17 +30,10 @@ _target setVariable [QGVAR(owner), _unit, true]; // lock target object if (_lockTarget) then { - 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 { - _target enableWeaponDisassembly false; - }; } else { [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; - if (_canBeDisassembled) then { - _target enableWeaponDisassembly true; - }; }; }; diff --git a/addons/common/functions/fnc_claimSafeServer.sqf b/addons/common/functions/fnc_claimSafeServer.sqf new file mode 100644 index 0000000000..6ebee7cb4f --- /dev/null +++ b/addons/common/functions/fnc_claimSafeServer.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, PabstMirror + * Unit claims the ownership over an object. This is used to prevent multiple players from dragging the same ammo box or using up the same wheel when repairing etc. + * This function only runs on the server and handles the "ace_common_claimSafe" event. It provides a network safe way claiming objects as all claims are run on server. + * Return event is passed [_unit, _target, _success] for new claims, no event on claim release + * + * Arguments: + * 0: Unit that claims another object. ObjNull to remove claim. + * 1: The object that gets claimed. + * 2: Lock the claimed object aswell? (optional: false) + * 3: Target event to trigger for calling machine (called where _unit is local) + * + * Return Value: + * None + * + * Example: + * [bob, flag, true, "claimReturn"] call ace_common_fnc_claimSafeServer + * + * Public: Yes + */ + +params ["_unit", "_target", ["_lockTarget", false], ["_returnEvent", ""]]; + +private _owner = _target getVariable [QGVAR(owner), objNull]; +TRACE_4("claimSafeServer",_unit,_target,_returnEvent,_owner); + +if (!isNull _owner && {!isNull _unit} && {_unit != _owner}) exitWith { + WARNING_1("Claiming already owned object. - %1",_this); + if (_returnEvent == "") exitWith {}; + [_returnEvent, [_unit, _target, false], _unit] call CBA_fnc_targetEvent; +}; + +// transfer this immediately +_target setVariable [QGVAR(owner), _unit, true]; + +// lock target object +if (_lockTarget) then { + if (!isNull _unit) then { + [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; + } else { + [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; + }; +}; + +if (!isNull _unit) then { + TRACE_2("claim success",_unit,_target); + if (_returnEvent == "") exitWith {}; + [_returnEvent, [_unit, _target, true], _unit] call CBA_fnc_targetEvent; +}; diff --git a/addons/common/functions/fnc_codeToString.sqf b/addons/common/functions/fnc_codeToString.sqf index b938148220..e686dc353b 100644 --- a/addons/common/functions/fnc_codeToString.sqf +++ b/addons/common/functions/fnc_codeToString.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Removes the brackets around a code and returns the code as a string. It does nothing if the code is already a string. @@ -16,10 +16,7 @@ */ params ["_code"]; + if (_code isEqualType "") exitWith {_code}; -_code = str(_code); -_code = _code select [1, count _code - 2]; - -_code - +toString _code diff --git a/addons/common/functions/fnc_createOrthonormalReference.sqf b/addons/common/functions/fnc_createOrthonormalReference.sqf index d705086e85..1b57dd6f0d 100644 --- a/addons/common/functions/fnc_createOrthonormalReference.sqf +++ b/addons/common/functions/fnc_createOrthonormalReference.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Returns a orthonormal system of reference aligned with the supplied vector * * Arguments: - * Vector to align the coordinate system with + * 0: Vector to align the coordinate system with * * Return Value: * 0: Vector Normalized diff --git a/addons/common/functions/fnc_currentChannel.sqf b/addons/common/functions/fnc_currentChannel.sqf index 350f91c9a2..da43a7e2c9 100644 --- a/addons/common/functions/fnc_currentChannel.sqf +++ b/addons/common/functions/fnc_currentChannel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns the current radio / chat / marker channel. diff --git a/addons/common/functions/fnc_debug.sqf b/addons/common/functions/fnc_debug.sqf index 2e08a19faf..055bf58380 100644 --- a/addons/common/functions/fnc_debug.sqf +++ b/addons/common/functions/fnc_debug.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Print logging messages through the ACE framework. diff --git a/addons/common/functions/fnc_debugModule.sqf b/addons/common/functions/fnc_debugModule.sqf index 90ad5ab6ba..c77b5a27ee 100644 --- a/addons/common/functions/fnc_debugModule.sqf +++ b/addons/common/functions/fnc_debugModule.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * ? diff --git a/addons/common/functions/fnc_defineVariable.sqf b/addons/common/functions/fnc_defineVariable.sqf index ba12d1c426..85eb7b447f 100644 --- a/addons/common/functions/fnc_defineVariable.sqf +++ b/addons/common/functions/fnc_defineVariable.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Define a variable for the ACE variable framework @@ -24,7 +24,7 @@ params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persi if (isNil "_defaultGlobal") exitWith {}; -if (!(_name isEqualType "")) exitwith { +if !(_name isEqualType "") exitwith { [format ["Tried to the deinfe a variable with an invalid name: %1 Arguments: %2", _name, _this]] call FUNC(debug); }; diff --git a/addons/common/functions/fnc_deprecateComponent.sqf b/addons/common/functions/fnc_deprecateComponent.sqf index a723b733ec..5408a896a1 100644 --- a/addons/common/functions/fnc_deprecateComponent.sqf +++ b/addons/common/functions/fnc_deprecateComponent.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Mark a component as deprecated and switches it to a new component if that is available @@ -22,7 +22,7 @@ params ["_oldComponent", "_newComponent", "_version"]; _oldComponent params ["_oldComponentName", "_oldSettingName"]; _newComponent params ["_newComponentName", "_newSettingName"]; -private _isReplacementAvailable = isClass (configFile >> "CfgPatches" >> _newComponentName); +private _isReplacementAvailable = [_newComponentName] call FUNC(isModLoaded); private _isDeprecatedLoaded = missionNamespace getvariable [_oldSettingName, false]; private _isReplacementLoaded = missionNamespace getvariable [_newSettingName, false]; diff --git a/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf b/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf index 1e8ea86a53..062d10793e 100644 --- a/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf +++ b/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Finds next valid index for the device array. diff --git a/addons/common/functions/fnc_deviceKeyRegisterNew.sqf b/addons/common/functions/fnc_deviceKeyRegisterNew.sqf index 2e6dbbee99..9479efe916 100644 --- a/addons/common/functions/fnc_deviceKeyRegisterNew.sqf +++ b/addons/common/functions/fnc_deviceKeyRegisterNew.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Finds next valid index for the device array. diff --git a/addons/common/functions/fnc_disableAI.sqf b/addons/common/functions/fnc_disableAI.sqf index 88b6f2bd49..52f1ed37c3 100644 --- a/addons/common/functions/fnc_disableAI.sqf +++ b/addons/common/functions/fnc_disableAI.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Disables/Enables AI diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index ecc3a0a987..b89750e656 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -1,6 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "\a3\ui_f_curator\ui\defineResinclDesign.inc" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: commy2 + * Author: commy2, johnb43 * Disables key input. ESC can still be pressed to open the menu. * * Arguments: @@ -15,6 +17,8 @@ * Public: No */ +#define IDD_TEAMSWITCH 632 + params ["_state"]; TRACE_1("disableUserInput",_state); @@ -24,7 +28,7 @@ if (_state) then { if (!isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull])) exitWith {}; if (!isNil QGVAR(disableInputPFH)) exitWith {}; - // end TFAR and ACRE2 radio transmissions + // End TFAR and ACRE2 radio transmissions call FUNC(endRadioTransmission); // Close map @@ -32,73 +36,210 @@ if (_state) then { openMap false; }; - closeDialog 0; - createDialog QGVAR(DisableMouse_Dialog); + if (isNull findDisplay IDD_INTERRUPT && {isNull findDisplay IDD_RSCDISPLAYCURATOR} && {isNull findDisplay IDD_TEAMSWITCH}) then { + closeDialog 0; + createDialog QGVAR(DisableMouse_Dialog); - private _dlg = uiNamespace getVariable QGVAR(dlgDisableMouse); + private _display = uiNamespace getVariable QGVAR(dlgDisableMouse); - _dlg displayAddEventHandler ["KeyDown", { - params ["", "_key"]; + // Hide cursor by using custom transparent cursor + private _map = _display displayCtrl 101; + _map ctrlMapCursor ["", QGVAR(blank)]; - if (_key == 1 && {alive player}) then { - createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select isMultiplayer); + GVAR(keyboardInputMain) = createHashMap; + GVAR(keyboardInputCombo) = createHashMap; - disableSerialization; + _display displayAddEventHandler ["KeyDown", { + // If input is enabled again, ignore + if (isNil QGVAR(keyboardInputMain)) exitWith {}; - private _dlg = findDisplay 49; + params ["", "_key"]; - for "_index" from 100 to 2000 do { - (_dlg displayCtrl _index) ctrlEnable false; + // Get key info; Stored as [isPressed, pressedCount] + private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0], true]; + _keyPressedInfo params ["_keyPressed", "_keyPressedCount"]; + + // For regular keys: If pressed, set to release and remove one key press + if (!_keyPressed) then { + _keyPressedInfo set [0, true]; + _keyPressedInfo set [1, _keyPressedCount + 1]; }; - private _ctrl = _dlg displayctrl 103; - _ctrl ctrlSetEventHandler ["buttonClick", QUOTE(while {!isNull (uiNamespace getVariable [ARR_2(QUOTE(QGVAR(dlgDisableMouse)),displayNull)])} do {closeDialog 0}; failMission 'LOSER'; [false] call DFUNC(disableUserInput);)]; - _ctrl ctrlEnable true; - _ctrl ctrlSetText "ABORT"; - _ctrl ctrlSetTooltip "Abort."; - - _ctrl = _dlg displayctrl ([104, 1010] select isMultiplayer); - _ctrl ctrlSetEventHandler ["buttonClick", QUOTE(closeDialog 0; player setDamage 1; [false] call DFUNC(disableUserInput);)]; - _ctrl ctrlEnable (call {private _config = missionConfigFile >> "respawnButton"; !isNumber _config || {getNumber _config == 1}}); - _ctrl ctrlSetText "RESPAWN"; - _ctrl ctrlSetTooltip "Respawn."; - }; - - if (_key in actionKeys "TeamSwitch" && {teamSwitchEnabled}) then { - (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; - - private _acc = accTime; - teamSwitch; - setAccTime _acc; - }; - - if (_key in actionKeys "CuratorInterface" && {getAssignedCuratorLogic player in allCurators}) then { - (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; - openCuratorInterface; - }; - - if (_key in actionKeys "ShowMap" && {player getVariable ["ACE_canSwitchUnits", false]}) then { - (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; - 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 (!(_key in (actionKeys "DefaultAction" + actionKeys "Throw")) && {_key in (actionKeys "Chat" + actionKeys "PrevChannel" + actionKeys "NextChannel")}) then { - _key = 0; + // For combo keys, register only if pushed or released (no keypress count) + if !(GVAR(keyboardInputCombo) getOrDefault [_key, false]) then { + GVAR(keyboardInputCombo) set [_key, true]; }; - }; - _key > 0 - }]; + // Look if keybinds of various actions have been pressed + private _action = ""; + private _comboDikPressed = false; + private _return = false; - _dlg displayAddEventHandler ["KeyUp", {true}]; + // This technique has a limitation: It can't process the Escape key properly (KeyUp EH does not fire) + (["TeamSwitch", "CuratorInterface", "ShowMap", "DefaultAction", "Throw", "Chat", "PrevChannel", "NextChannel"] apply { + _action = _x; + + { + _x params ["_mainKeyArray", "_comboKeyArray", "_isDoubleTap"]; + _mainKeyArray params ["_mainDik", "_mainDevice"]; + + // If keybind doesn't contain key combo, it returns empty array; Therefore, return true + _comboDikPressed = if (_comboKeyArray isEqualTo []) then { + true + } else { + _comboKeyArray params ["_comboDik", "_comboDevice"]; + + _comboDevice == "KEYBOARD" && {GVAR(keyboardInputCombo) getOrDefault [_comboDik, false]} + }; + + // Check if the necessary keys were pressed for a keybind + _return = _comboDikPressed && + {_mainDevice == "KEYBOARD"} && + {((GVAR(keyboardInputMain) getOrDefault [_mainDik, [false, 0]]) select 1) > (parseNumber _isDoubleTap)}; // check how many times the main key was pressed + + // Keybind was detected + if (_return) exitWith { + TRACE_1("Action triggered: ",_action); + }; + } forEach (actionKeysEx _action); + + _return + }) params ["_teamSwitch", "_curatorInterface", "_showMap", "_defaultAction", "_throw", "_chat", "_prevChannel", "_nextChannel"]; + + // Handle Escape separately because of limitation mentioned above + if (_key == DIK_ESCAPE && {alive player}) then { + disableSerialization; + + private _isMultiplayer = isMultiplayer; + private _is3DENPreview = is3DENPreview; + + createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select _isMultiplayer); + + private _dlg = findDisplay 49; + + for "_index" from 100 to 2000 do { + (_dlg displayCtrl _index) ctrlEnable false; + }; + + private _ctrl = _dlg displayCtrl 103; + _ctrl ctrlSetEventHandler ["ButtonClick", toString { + while {!isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull])} do { + closeDialog 0 + }; + + failMission "LOSER"; + + [false] call FUNC(disableUserInput); + }]; + _ctrl ctrlEnable true; + _ctrl ctrlSetText localize (["str_disp_int_abort", "STR_3DEN_RscDisplayInterrupt_ButtonAbort_3DEN_text"] select (_is3DENPreview && !_isMultiplayer)); + _ctrl ctrlSetTooltip localize ([ + "STR_TOOLTIP_MAIN_ABORT_CAMPAIGN", + "STR_3DEN_RscDisplayInterrupt_ButtonAbort_3DEN_tooltip", + "STR_TOOLTIP_MAIN_ABORT" + ] select (([_is3DENPreview, _isMultiplayer] call FUNC(toBitmask)) min 2)); + + _ctrl = _dlg displayCtrl ([104, 1010] select _isMultiplayer); + _ctrl ctrlSetEventHandler ["ButtonClick", toString { + closeDialog 0; + + [player, "respawn_button"] call FUNC(setDead); + + [false] call FUNC(disableUserInput); + }]; + + private _respawnEnabled = (getMissionConfigValue ["respawnButton", -1]) != 0; + + _ctrl ctrlEnable _respawnEnabled; // handles 3den attribute or description.ext + _ctrl ctrlSetText localize "str_disp_int_respawn"; + _ctrl ctrlSetTooltip localize (["str_3den_attributes_respawn_none_tooltip", "str_disp_int_respawn"] select _respawnEnabled); + }; + + if (_teamSwitch && teamSwitchEnabled) then { + (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + + private _acc = accTime; + teamSwitch; + setAccTime _acc; + }; + + if (_curatorInterface && {!isNull getAssignedCuratorLogic player}) then { + (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + + openCuratorInterface; + }; + + if (_showMap && {player getVariable ["ACE_canSwitchUnits", false]}) then { + (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + + openMap true; + }; + + if (isMultiplayer && {isServer || {serverCommandAvailable "#kick"}}) then { + if (!(_defaultAction || _throw) && {_chat || _prevChannel || _nextChannel}) then { + _key = 0; + }; + }; + + _key > 0 + }]; + + _display displayAddEventHandler ["KeyUp", { + // If input is enabled again, ignore + if (isNil QGVAR(keyboardInputMain)) exitWith {}; + + params ["", "_key"]; + + // For combo keys: If pressed, release + if (GVAR(keyboardInputCombo) getOrDefault [_key, false]) then { + GVAR(keyboardInputCombo) deleteAt _key; + }; + + private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0]]; + + // If pressed, release it + if (_keyPressedInfo select 0) then { + _keyPressedInfo set [0, false]; + }; + + // Cache keystrokes of regular keys for a small amount of time + [{ + // If input is enabled again, ignore + if (isNil QGVAR(keyboardInputMain)) exitWith {}; + + params ["_key"]; + + private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0]]; + + // Release it + _keyPressedInfo set [1, ((_keyPressedInfo select 1) - 1) max 0]; + + if (_keyPressedInfo isEqualTo [false, 0]) then { + GVAR(keyboardInputMain) deleteAt _key; + }; + }, _key, 0.5] call CBA_fnc_waitAndExecute; + }]; + }; GVAR(disableInputPFH) = [{ - if (isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) && {!visibleMap && isNull findDisplay 49 && isNull findDisplay 312 && isNull findDisplay 632}) then { + if (isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) && {!visibleMap && {isNull findDisplay IDD_INTERRUPT} && {isNull findDisplay IDD_RSCDISPLAYCURATOR} && {isNull findDisplay IDD_TEAMSWITCH}}) exitWith { [GVAR(disableInputPFH)] call CBA_fnc_removePerFrameHandler; GVAR(disableInputPFH) = nil; [true] call FUNC(disableUserInput); }; + + // Allow user input if the player is respawning and a respawn template (menu position or spectator) + // is open (otherwise they cannot click the respawn button) + if ( + !alive player + && {playerRespawnTime != -1} + && { + missionNamespace getVariable ["BIS_RscRespawnControlsMap_shown", false] + || {missionNamespace getVariable ["BIS_RscRespawnControlsSpectate_shown", false]} + } + ) exitWith { + [false] call FUNC(disableUserInput); + }; }, 0, []] call CBA_fnc_addPerFrameHandler; } else { if (!isNil QGVAR(disableInputPFH)) then { @@ -107,4 +248,7 @@ if (_state) then { }; (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + + GVAR(keyboardInputMain) = nil; + GVAR(keyboardInputCombo) = nil; }; diff --git a/addons/common/functions/fnc_displayIcon.sqf b/addons/common/functions/fnc_displayIcon.sqf index 11e9f5d6e7..da08fa832a 100644 --- a/addons/common/functions/fnc_displayIcon.sqf +++ b/addons/common/functions/fnc_displayIcon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Draw progress bar and execute given function if succesful. @@ -15,7 +15,7 @@ * None * * Example: - * ["myID", true, QPATHTOF(data\icon_group.paa), [1,1,1,1], 0] call ace_gui_fnc_displayIcon; + * ["myID", true, QPATHTOF(data\icon_group.paa), [1,1,1,1], 0] call ace_common_fnc_displayIcon; * * Public: Yes */ @@ -53,8 +53,7 @@ private _refresh = { { ctrlDelete _x; - false - } count _allControls; + } forEach _allControls; _allControls = []; @@ -80,7 +79,6 @@ private _refresh = { _ctrl ctrlSetTextColor _xcolor; _ctrl ctrlCommit 0; _allControls pushBack _ctrl; - false } forEach (missionNamespace getVariable [QGVAR(displayIconList),[]]); }; @@ -116,8 +114,7 @@ if (_show) then { if (_x select 0 != _iconId) then { _newList pushBack _x; }; - false - } count _list; + } forEach _list; missionNamespace setVariable [QGVAR(displayIconList), _newList]; call _refresh; diff --git a/addons/common/functions/fnc_displayText.sqf b/addons/common/functions/fnc_displayText.sqf index f34a0cdfcd..cdec636b13 100644 --- a/addons/common/functions/fnc_displayText.sqf +++ b/addons/common/functions/fnc_displayText.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Display a message. diff --git a/addons/common/functions/fnc_displayTextPicture.sqf b/addons/common/functions/fnc_displayTextPicture.sqf index b25945382f..2da2977482 100644 --- a/addons/common/functions/fnc_displayTextPicture.sqf +++ b/addons/common/functions/fnc_displayTextPicture.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Glowbal * Display a structured text with image. diff --git a/addons/common/functions/fnc_displayTextStructured.sqf b/addons/common/functions/fnc_displayTextStructured.sqf index e54e481b5a..a9376552a9 100644 --- a/addons/common/functions/fnc_displayTextStructured.sqf +++ b/addons/common/functions/fnc_displayTextStructured.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Glowbal, GitHawk * Display a structured text. diff --git a/addons/common/functions/fnc_doAnimation.sqf b/addons/common/functions/fnc_doAnimation.sqf index 667ab792c1..9e85c30dce 100644 --- a/addons/common/functions/fnc_doAnimation.sqf +++ b/addons/common/functions/fnc_doAnimation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Execute an animation. This is used to not break things like the unconsciousness animation. diff --git a/addons/common/functions/fnc_doGesture.sqf b/addons/common/functions/fnc_doGesture.sqf index 3aa4656cfd..84d448143a 100644 --- a/addons/common/functions/fnc_doGesture.sqf +++ b/addons/common/functions/fnc_doGesture.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Play a gesture. diff --git a/addons/common/functions/fnc_dropBackpack.sqf b/addons/common/functions/fnc_dropBackpack.sqf index 38f1be8a52..f87f462561 100644 --- a/addons/common/functions/fnc_dropBackpack.sqf +++ b/addons/common/functions/fnc_dropBackpack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Drops a backback. Also returns the ground wepaon holder object of the dropped backpack. diff --git a/addons/common/functions/fnc_dummy.sqf b/addons/common/functions/fnc_dummy.sqf index a70fed35c0..30074d29c8 100644 --- a/addons/common/functions/fnc_dummy.sqf +++ b/addons/common/functions/fnc_dummy.sqf @@ -1,5 +1,5 @@ /* - * Author: SilentSpike + * Author: kymckay * A dummy function which does nothing. Can be useful. * * Arguments: diff --git a/addons/common/functions/fnc_dumpArray.sqf b/addons/common/functions/fnc_dumpArray.sqf index 4997ad119a..87437c37e2 100644 --- a/addons/common/functions/fnc_dumpArray.sqf +++ b/addons/common/functions/fnc_dumpArray.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ? * Dumps an array to the RPT, showing the depth of each element. @@ -34,8 +34,7 @@ if (IS_ARRAY(_var)) then { { [_x, _depth] call FUNC(dumpArray); - false - } count _var; + } forEach _var; diag_log text format ["%1],", _pad]; }; diff --git a/addons/common/functions/fnc_dumpPerformanceCounters.sqf b/addons/common/functions/fnc_dumpPerformanceCounters.sqf index 2dad092a2c..309b82c673 100644 --- a/addons/common/functions/fnc_dumpPerformanceCounters.sqf +++ b/addons/common/functions/fnc_dumpPerformanceCounters.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ? * Dumps performance counter statistics into Logs. @@ -25,8 +25,7 @@ if (!isNil "ACE_PFH_COUNTER") then { private _isActive = ["ACTIVE", "REMOVED"] select isNil {CBA_common_PFHhandles select (_pfh select 0)}; diag_log text format ["Registered PFH: id=%1 [%2, delay %3], %4:%5", _pfh select 0, _isActive, _parameters select 1, _pfh select 1, _pfh select 2]; - false - } count ACE_PFH_COUNTER; + } forEach ACE_PFH_COUNTER; }; diag_log text format ["ACE COUNTER RESULTS"]; @@ -50,8 +49,7 @@ diag_log text format ["-------------------------------------------"]; }; _iter = _iter + 1; - false - } count _counterEntry; + } forEach _counterEntry; // results _averageResult = (_total / _count) * 1000; @@ -61,8 +59,7 @@ diag_log text format ["-------------------------------------------"]; } else { diag_log text format ["%1: No results", _counterEntry select 0]; }; - false -} count ACE_COUNTERS; +} forEach ACE_COUNTERS; /* // Dump PFH Trackers diff --git a/addons/common/functions/fnc_endRadioTransmission.sqf b/addons/common/functions/fnc_endRadioTransmission.sqf index 16985a8773..289936c95e 100644 --- a/addons/common/functions/fnc_endRadioTransmission.sqf +++ b/addons/common/functions/fnc_endRadioTransmission.sqf @@ -1,8 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * - * End radio transmissions of addons TFAR and ACRE2. TFAR v0.9.x, ACRE Public Beta 2.0.3.571 + * End radio transmissions of addons TFAR and ACRE2. TFAR v0.9.x, ACRE Public Beta 2.0.3.571, TFAR v1.0.-1.x * * Arguments: * None @@ -19,7 +19,7 @@ ["ace_endRadioTransmissions"] call CBA_fnc_localEvent; // ACRE -if (isClass (configFile >> "CfgPatches" >> "acre_main")) then { +if (["acre_main"] call FUNC(isModLoaded)) then { [-1] call acre_sys_core_fnc_handleMultiPttKeyPressUp; [0] call acre_sys_core_fnc_handleMultiPttKeyPressUp; [1] call acre_sys_core_fnc_handleMultiPttKeyPressUp; @@ -27,7 +27,10 @@ if (isClass (configFile >> "CfgPatches" >> "acre_main")) then { }; // TFAR -if (isClass (configFile >> "CfgPatches" >> "task_force_radio")) then { +if (["task_force_radio"] call FUNC(isModLoaded)) then { + if (["tfar_core"] call FUNC(isModLoaded)) exitWith { // Beta TFAR, exit to avoid script errors from legacy functions not existing + ACE_Player call TFAR_fnc_releaseAllTangents; + }; call TFAR_fnc_onSwTangentReleased; call TFAR_fnc_onAdditionalSwTangentReleased; call TFAR_fnc_onLRTangentReleased; diff --git a/addons/common/functions/fnc_eraseCache.sqf b/addons/common/functions/fnc_eraseCache.sqf index 79eb4444fa..1f574db588 100644 --- a/addons/common/functions/fnc_eraseCache.sqf +++ b/addons/common/functions/fnc_eraseCache.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Deletes a cached result diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index c062c8836c..e98a5baf8f 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -1,147 +1,141 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: commy2, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) - * Stops simulation and opens a textbox with error message. + * Author: commy2, johnb43, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) + * Opens a textbox with an error message, used for PBO checking. * * Arguments: - * ? + * 0: Header + * 1: Text * * Return Value: * None * * Example: - * call ace_common_fnc_errorMessage + * ["[ACE] ERROR", "Test"] call ace_common_fnc_errorMessage * * Public: No */ -disableSerialization; +// Force stop any loading screens endLoadingScreen; -// no message without player possible +// No message without interface possible if (!hasInterface) exitWith {}; -// wait for display -if (isNull (call BIS_fnc_displayMission)) exitWith { - [{ - if (isNull (call BIS_fnc_displayMission)) exitWith {}; +[{ + !isNull (call BIS_fnc_displayMission) +}, { + params ["_textHeader", "_textMessage"]; - (_this select 0) call FUNC(errorMessage); - [_this select 1] call CBA_fnc_removePerFrameHandler; + disableSerialization; - }, 1, _this] call CBA_fnc_addPerFrameHandler; -}; + // Use curator display if present + private _curatorDisplay = findDisplay 312; -params ["_textHeader", "_textMessage", ["_onOK", {}], ["_onCancel", {}]]; + private _mainDisplay = if (!isNull _curatorDisplay) then { + _curatorDisplay + } else { + call BIS_fnc_displayMission + }; -if (_textMessage isEqualType "") then { - _textMessage = parseText _textMessage; -}; + if (_textMessage isEqualType "") then { + _textMessage = parseText _textMessage; + }; -ARR_SELECT(_this,4,call BIS_fnc_displayMission) createDisplay "RscDisplayCommonMessagePause"; + private _display = _mainDisplay createDisplay "RscDisplayCommonMessagePause"; -private _display = uiNamespace getVariable "RscDisplayCommonMessage_display"; -private _ctrlRscMessageBox = _display displayCtrl 2351; -private _ctrlBcgCommonTop = _display displayCtrl 235100; -private _ctrlBcgCommon = _display displayCtrl 235101; -private _ctrlText = _display displayCtrl 235102; -private _ctrlBackgroundButtonOK = _display displayCtrl 235103; -private _ctrlBackgroundButtonMiddle = _display displayCtrl 235104; -private _ctrlBackgroundButtonCancel = _display displayCtrl 235105; -private _ctrlButtonOK = _display displayCtrl 235106; -private _ctrlButtonCancel = _display displayCtrl 235107; + if (isNull _display) exitWith {}; -_ctrlBcgCommonTop ctrlSetText _textHeader; + private _ctrlRscMessageBox = _display displayCtrl 2351; + private _ctrlBcgCommonTop = _display displayCtrl 235100; + private _ctrlBcgCommon = _display displayCtrl 235101; + private _ctrlText = _display displayCtrl 235102; + private _ctrlBackgroundButtonOK = _display displayCtrl 235103; + private _ctrlBackgroundButtonMiddle = _display displayCtrl 235104; + private _ctrlBackgroundButtonCancel = _display displayCtrl 235105; + private _ctrlButtonOK = _display displayCtrl 235106; + private _ctrlButtonCancel = _display displayCtrl 235107; -private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK; -private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon; -private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3)); + _ctrlBcgCommonTop ctrlSetText _textHeader; -private _ctrlTextPos = ctrlPosition _ctrlText; -private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0); -private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1); + private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK; + private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon; + private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3)); -_ctrlText ctrlSetStructuredText _textMessage; -private _ctrlTextPosH = ctrlTextHeight _ctrlText; + private _ctrlTextPos = ctrlPosition _ctrlText; + private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0); + private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1); -_ctrlBcgCommon ctrlSetPosition [ - _ctrlBcgCommonPos select 0, - _ctrlBcgCommonPos select 1, - _ctrlBcgCommonPos select 2, - _ctrlTextPosH + _marginY * 2 -]; -_ctrlBcgCommon ctrlCommit 0; + _ctrlText ctrlSetStructuredText _textMessage; + private _ctrlTextPosH = ctrlTextHeight _ctrlText; -_ctrlText ctrlSetPosition [ - (_ctrlBcgCommonPos select 0) + _marginX, - (_ctrlBcgCommonPos select 1) + _marginY, - (_ctrlBcgCommonPos select 2) - _marginX * 2, - _ctrlTextPosH -]; -_ctrlText ctrlCommit 0; + _ctrlBcgCommon ctrlSetPosition [ + _ctrlBcgCommonPos select 0, + _ctrlBcgCommonPos select 1, + _ctrlBcgCommonPos select 2, + _ctrlTextPosH + _marginY * 2 + ]; + _ctrlBcgCommon ctrlCommit 0; -private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY; + _ctrlText ctrlSetPosition [ + (_ctrlBcgCommonPos select 0) + _marginX, + (_ctrlBcgCommonPos select 1) + _marginY, + (_ctrlBcgCommonPos select 2) - _marginX * 2, + _ctrlTextPosH + ]; + _ctrlText ctrlCommit 0; -{ - private _xPos = ctrlPosition _x; + private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY; - _xPos set [1, _bottomPosY]; - _x ctrlSetPosition _xPos; - _x ctrlCommit 0; -} forEach [ - _ctrlBackgroundButtonOK, - _ctrlBackgroundButtonMiddle, - _ctrlBackgroundButtonCancel, - _ctrlButtonOK, - _ctrlButtonCancel -]; + { + private _xPos = ctrlPosition _x; -private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox; -private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3); + _xPos set [1, _bottomPosY]; + _x ctrlSetPosition _xPos; + _x ctrlCommit 0; + } forEach [ + _ctrlBackgroundButtonOK, + _ctrlBackgroundButtonMiddle, + _ctrlBackgroundButtonCancel, + _ctrlButtonOK, + _ctrlButtonCancel + ]; -_ctrlRscMessageBox ctrlSetPosition [ - 0.5 - (_ctrlBcgCommonPos select 2) / 2, - 0.5 - _ctrlRscMessageBoxPosH / 2, - (_ctrlBcgCommonPos select 2) + 0.5, - _ctrlRscMessageBoxPosH -]; + private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox; + private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3); -_ctrlRscMessageBox ctrlEnable true; -_ctrlRscMessageBox ctrlCommit 0; + _ctrlRscMessageBox ctrlSetPosition [ + 0.5 - (_ctrlBcgCommonPos select 2) / 2, + 0.5 - _ctrlRscMessageBoxPosH / 2, + (_ctrlBcgCommonPos select 2) + 0.5, + _ctrlRscMessageBoxPosH + ]; -if (_onOK isEqualTo {}) then { - _ctrlButtonOK ctrlEnable false; - _ctrlButtonOK ctrlSetFade 0; - _ctrlButtonOK ctrlSetText ""; - _ctrlButtonOK ctrlCommit 0; -} else { + _ctrlRscMessageBox ctrlEnable true; + _ctrlRscMessageBox ctrlCommit 0; + + // Enable ok button _ctrlButtonOK ctrlEnable true; _ctrlButtonOK ctrlSetFade 0; _ctrlButtonOK ctrlSetText localize "STR_DISP_OK"; _ctrlButtonOK ctrlCommit 0; ctrlSetFocus _ctrlButtonOK; -}; -if (_onCancel isEqualTo {}) then { + // Disable cancel button _ctrlButtonCancel ctrlEnable false; _ctrlButtonCancel ctrlSetFade 0; _ctrlButtonCancel ctrlSetText ""; _ctrlButtonCancel ctrlCommit 0; -} else { - _ctrlButtonCancel ctrlEnable true; - _ctrlButtonCancel ctrlSetFade 0; - _ctrlButtonCancel ctrlSetText localize "STR_DISP_CANCEL"; - _ctrlButtonCancel ctrlCommit 0; - ctrlSetFocus _ctrlButtonCancel; -}; + _ctrlButtonOK ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay IDC_OK; true}]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}]; -_ctrlButtonCancel ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; + // Intercept all keystrokes except the enter keys + _display displayAddEventHandler ["KeyDown", {!((_this select 1) in [DIK_RETURN, DIK_NUMPADENTER])}]; -GVAR(errorOnOK) = _onOK; -GVAR(errorOnCancel) = _onCancel; - -_display displayAddEventHandler ["unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; -_display displayAddEventHandler ["keyDown", {_this select 1 == 1}]; + // Close curator and mission displays (because of the message display, it doesn't quit the mission yet) + findDisplay 312 closeDisplay 0; + findDisplay 46 closeDisplay 0; +}, _this] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/common/functions/fnc_escapeRegex.sqf b/addons/common/functions/fnc_escapeRegex.sqf new file mode 100644 index 0000000000..8266a7dfa7 --- /dev/null +++ b/addons/common/functions/fnc_escapeRegex.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Escapes special characters used in regex from a string + * + * Arguments: + * 0: String + * + * Return Value: + * Safe string + * + * Example: + * "\Q.*?AK-15.*?\E" call ace_common_fnc_escapeRegex + * + * Public: Yes + */ +params [["_string", "", [""]]]; + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping +_string regexReplace ["[.?*+^$[\]\\(){}|-]/gio", "\\$&"] diff --git a/addons/common/functions/fnc_findUnloadPosition.sqf b/addons/common/functions/fnc_findUnloadPosition.sqf index 22e23c7f2b..2047f7349d 100644 --- a/addons/common/functions/fnc_findUnloadPosition.sqf +++ b/addons/common/functions/fnc_findUnloadPosition.sqf @@ -1,135 +1,151 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, ViperMaul * Find a safe place near a vehicle to unload something. - * Handles Normal Terrain, In Water or On Buildings (Pier, StaticShip). + * Handles normal terrain, water or on buildings (Pier, StaticShip). * * Arguments: - * 0: Source Vehicle - * 1: Cargo or - * 2: Unloader (player) (default: objNull) - * 3: Max Distance (meters) (default: 10) - * 4: Check Vehicle is Stable (default: true) + * 0: Holder object (vehicle) + * 1: Item to be unloaded or + * 2: Unit doing the unloading (default: objNull) + * 3: Max distance (meters) (default: 10) + * 4: Check if holder object is stable (default: true) * * Return Value: - * Unload PositionAGL (can Be [] if no valid pos found) + * Unload PositionAGL ([] if no valid pos found) * * Example: - * [theCar, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition + * [cursorObject, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition * * Public: No */ -//Number of tests run (effects performance in worst case scenarior where nothing is found VERSUES reliably finding a pos): +// Number of tests run (effects performance in worst case scenario where nothing is found VERSUS reliably finding a pos) #define MAX_TESTS 75 -//Manual collision tests (count and radius): +// Manual collision tests (count and radius) #define COL_TEST_COUNT 12 -params ["_vehicle", "_cargo", ["_theUnloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]]; -TRACE_5("params",_vehicle,_cargo,_theUnloader,_maxDistance,_checkVehicleIsStable); +params ["_vehicle", "_item", ["_unloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]]; +TRACE_5("params",_vehicle,_item,_unloader,_maxDistance,_checkVehicleIsStable); scopeName "main"; if (_checkVehicleIsStable) then { if (((vectorMagnitude (velocity _vehicle)) > 1.5) || {(!(_vehicle isKindOf "Ship")) && {(!isTouchingGround _vehicle) && {((getPos _vehicle) select 2) > 1.5}}}) then { TRACE_4("bad vehicle state",_vehicle,velocity _vehicle,isTouchingGround _vehicle,getPos _vehicle); - [] breakOut "main"; + + [] breakOut "main" }; }; private _radiusOfItem = 1; -if (_cargo isKindOf "CAManBase") then { + +if (_item isKindOf "CAManBase") then { _radiusOfItem = 1.1; } else { - //`sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size - private _typeOfCargo = if (_cargo isEqualType "") then {_cargo} else {typeOf _cargo}; - private _itemSize = if (isNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size)) && {getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size)) != -1}) then { - getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size)); - } else { - if (["ace_cargo"] call FUNC(isModLoaded)) then { - [_cargo] call EFUNC(cargo,getSizeItem); - } else { - _radiusOfItem; + // `sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size + if (["ace_cargo"] call FUNC(isModLoaded)) then { + private _itemSize = _item call EFUNC(cargo,getSizeItem); + + if (_itemSize > 0) then { + _radiusOfItem = (_itemSize ^ 0.35) max 0.75; }; }; - if (_itemSize != -1) then { - _radiusOfItem = (_itemSize ^ 0.35) max 0.75; - }; }; -if (isNull _theUnloader) then {_theUnloader = _vehicle;}; +if (isNull _unloader || {_unloader in _vehicle}) then { + _unloader = _vehicle; +}; -//Ideal unload pos is halfway between unloader and vehicle (at the unloader's height) -private _originASL = ((getPosASL _theUnloader) vectorAdd (getPosASL _vehicle)) vectorMultiply 0.5; -_originASL set [2, (getPosASL _theUnloader) select 2]; +// Ideal unload pos is halfway between unloader and vehicle (at the unloader's height) +private _originASL = ((getPosASL _unloader) vectorAdd (getPosASL _vehicle)) vectorMultiply 0.5; +_originASL set [2, (getPosASL _unloader) select 2]; private _originAGL = ASLtoAGL _originASL; -//Do a manual search for empty pos (handles underwater, buildings or piers) +// Do a manual search for empty pos (handles underwater, buildings or piers) TRACE_2("Checking for unload",_originAGL,_radiusOfItem); private _rangeToCheck = 0; + while {_rangeToCheck < _maxDistance} do { private _roundDistance = random _rangeToCheck; private _roundAngle = random 360; private _roundAGL = _originAGL vectorAdd [(cos _roundAngle) * _roundDistance, (sin _roundAngle) * _roundDistance, 0]; private _roundPointIsValid = false; + if (((AGLtoASL _roundAGL) select 2) > 0) then { - //Shoot a ray down, and make sure we hit something solid like a building or the ground: - private _belowRoundArray = lineIntersectsSurfaces [(AGLtoASL _roundAGL) vectorAdd [0,0,0.5], (AGLtoASL _roundAGL) vectorAdd [0,0,-1]]; + // Shoot a ray down, and make sure we hit something solid like a building or the ground + private _belowRoundArray = lineIntersectsSurfaces [(AGLtoASL _roundAGL) vectorAdd [0, 0, 0.5], (AGLtoASL _roundAGL) vectorAdd [0, 0, -1]]; TRACE_4("Testing for solid",_roundDistance,_roundAngle,_roundAGL,_belowRoundArray); - if (!(_belowRoundArray isEqualTo [])) then { + + if (_belowRoundArray isNotEqualTo []) then { private _aboveBuilding = (_belowRoundArray select 0) select 2; - //Point is above something: Terrain(null) or Building + + // Point is above something: Terrain (null) or Building if ((isNull _aboveBuilding) || {_aboveBuilding isKindOf "Building"}) then { - //Get the real intersection point: + // Get the real intersection point _roundAGL = ASLtoAGL ((_belowRoundArray select 0) select 0); + _roundPointIsValid = true; }; }; } else { - //Underwater, just unload anywhere + // Underwater, just unload anywhere TRACE_3("Under the sea",_roundDistance,_roundAngle,_roundAGL); + _roundPointIsValid = true; }; - //Make sure point is valid and do a fast check for people in the way (which sometimes aren't caught by line scaning) + // Make sure point is valid and do a fast check for people in the way (which sometimes aren't caught by line scanning) if (_roundPointIsValid && {(_roundAGL nearEntities ["Man", _radiusOfItem]) isEqualTo []}) then { for "_index" from 0 to (COL_TEST_COUNT -1) do { - //Scan for colisions with objects with lineIntersectsSurfaces + // Scan for collisions with objects with lineIntersectsSurfaces private _angle = _index * (360 / COL_TEST_COUNT); private _point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.1]; - private _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, (_radiusOfItem + 0.5)]; + private _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, _radiusOfItem + 0.5]; private _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL]; + if (((count _testIntersections) == 1) && {isNull ((_testIntersections select 0) select 2)}) then { private _hitGroundASL = (_testIntersections select 0) select 0; private _hitHeightOffset = ((AGLtoASL _roundAGL) select 2) - (_hitGroundASL select 2); private _hit2dOffset = _roundAGL distance2D _hitGroundASL; private _slope = _hitHeightOffset atan2 _hit2dOffset; - if (_slope < 25) then { //Ignore ground hit if slope is reasonable + + // Ignore ground hit if slope is reasonable + if (_slope < 25) then { _testIntersections = []; }; }; - if (!(_testIntersections isEqualTo [])) exitWith { + + if (_testIntersections isNotEqualTo []) exitWith { TRACE_2("collision low/high",_roundAGL,_testIntersections); + _roundPointIsValid = false; }; + _point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.5]; _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, 1]; _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL]; - if (!(_testIntersections isEqualTo [])) exitWith { + + if (_testIntersections isNotEqualTo []) exitWith { TRACE_2("collision mid",_roundAGL,_testIntersections); + _roundPointIsValid = false; }; }; + if (_roundPointIsValid) then { - TRACE_3("Valid point found", _rangeToCheck,_roundAGL, (_originAGL distance _roundAGL)); - //Raise it slightly so we don't sink through the floor: - (_roundAGL vectorAdd [0,0,0.05]) breakOut "main"; + TRACE_3("Valid point found",_rangeToCheck,_roundAGL,_originAGL distance _roundAGL); + + // Raise it slightly so we don't sink through the floor + (_roundAGL vectorAdd [0, 0, 0.05]) breakOut "main"; // return }; }; + _rangeToCheck = _rangeToCheck + (_maxDistance / MAX_TESTS); }; TRACE_1("no valid spots found",_rangeToCheck); -[] //return empty array + +[] // return diff --git a/addons/common/functions/fnc_firedEH.sqf b/addons/common/functions/fnc_firedEH.sqf index 22a64f5c23..2c0c32994d 100644 --- a/addons/common/functions/fnc_firedEH.sqf +++ b/addons/common/functions/fnc_firedEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Unfied handling of weapon fire @@ -24,7 +24,7 @@ BEGIN_COUNTER(firedEH); params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; -TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); +TRACE_7("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); if (_unit isKindOf "CAManBase") then { // The unit it on foot @@ -50,8 +50,7 @@ if (_unit isKindOf "CAManBase") then { _gunner = _unit turretUnit _x; _turret = _x; }; - false - } count allTurrets [_unit, true]; + } forEach allTurrets [_unit, true]; // Ensure that at least the pilot is returned if there is no gunner if (isManualFire _unit && {isNull _gunner}) then { _gunner = effectiveCommander _unit; diff --git a/addons/common/functions/fnc_fixCollision.sqf b/addons/common/functions/fnc_fixCollision.sqf index ee61d83c35..0269ccb594 100644 --- a/addons/common/functions/fnc_fixCollision.sqf +++ b/addons/common/functions/fnc_fixCollision.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Attempt to fix PhysX collisions causing unreasonable impact forces and damage. diff --git a/addons/common/functions/fnc_fixFloating.sqf b/addons/common/functions/fnc_fixFloating.sqf index 03e7933e2e..e82375cbbf 100644 --- a/addons/common/functions/fnc_fixFloating.sqf +++ b/addons/common/functions/fnc_fixFloating.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Attempt to fix floating physx with disabled damage after setPosXXX commands. diff --git a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf index d89a3978c6..8982d6bbad 100644 --- a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf +++ b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Fixes the lowered rifle animation @@ -17,6 +17,6 @@ params ["_unit"]; -if (currentWeapon _unit != "" && {currentWeapon _unit == primaryWeapon _unit} && {weaponLowered _unit} && {stance _unit == "STAND"} && {vehicle _unit == _unit}) then { +if (currentWeapon _unit != "" && {currentWeapon _unit == primaryWeapon _unit} && {weaponLowered _unit} && {stance _unit == "STAND"} && {isNull objectParent _unit}) then { [_unit, "amovpercmstpsraswrfldnon", 0] call FUNC(doAnimation); }; diff --git a/addons/common/functions/fnc_fixPosition.sqf b/addons/common/functions/fnc_fixPosition.sqf index ac152cf5c9..79d3c6272b 100644 --- a/addons/common/functions/fnc_fixPosition.sqf +++ b/addons/common/functions/fnc_fixPosition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Jonpas * Fixes position of an object. E.g. moves object above ground and adjusts to terrain slope. Requires local object. @@ -19,7 +19,7 @@ if (!local _this) exitWith {}; // Objects with disabled simulation and objects with simulation type "house" don't have gravity/physics, so make sure they are not floating -private _hasGravity = simulationEnabled _this && {getText (configFile >> "CfgVehicles" >> typeOf _this >> "simulation") != "house"}; +private _hasGravity = simulationEnabled _this && {getText (configOf _this >> "simulation") != "house"}; if (!_hasGravity) then { private _positionASL = getPosASL _this; diff --git a/addons/common/functions/fnc_getAddon.sqf b/addons/common/functions/fnc_getAddon.sqf new file mode 100644 index 0000000000..b1a6f7cf99 --- /dev/null +++ b/addons/common/functions/fnc_getAddon.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Returns a config's addon. + * + * Arguments: + * 0: Config entry + * + * Return Value: + * Addon name + * + * Example: + * [configFile >> "CfgWeapons" >> "arifle_AK12_F"] call ace_common_fnc_getAddon + * + * Public: Yes +*/ + +params ["_config"]; + +(uiNamespace getVariable QGVAR(addonCache)) getOrDefaultCall [_config, { + private _addons = configSourceAddonList _config; + + // Return first addon + if (_addons isNotEqualTo []) then { + (configSourceModList (configfile >> "CfgPatches" >> _addons select 0)) param [0, ""] + } else { + // If nothing found at all, return "" + "" + } +}, true] diff --git a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf index eeb96002d1..081836c196 100644 --- a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf +++ b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Returns an 2d array of all variables that have been set on the object @@ -35,7 +35,6 @@ private _return = []; _return pushBack [_x select 0, typeName _val, _val, _x select 2, _x select 5]; }; }; - false -} count GVAR(OBJECT_VARIABLES_STORAGE); +} forEach GVAR(OBJECT_VARIABLES_STORAGE); _return diff --git a/addons/common/functions/fnc_getAwakeAnim.sqf b/addons/common/functions/fnc_getAwakeAnim.sqf index 7da2837759..e7db13ac63 100644 --- a/addons/common/functions/fnc_getAwakeAnim.sqf +++ b/addons/common/functions/fnc_getAwakeAnim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Report awake animation of unit inside vehicle. @@ -23,7 +23,7 @@ private _vehicle = vehicle _unit; if (_vehicle isEqualTo _unit) exitWith {""}; // --- driver -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; if (_unit == driver _vehicle) exitWith { getText (configFile >> "CfgMovesBasic" >> "ManActions" >> getText (_config >> "driverAction")) // return @@ -32,7 +32,7 @@ if (_unit == driver _vehicle) exitWith { // --- turret private _turret = _unit call CBA_fnc_turretPath; -if !(_turret isEqualTo []) exitWith { +if (_turret isNotEqualTo []) exitWith { private _turretConfig = [_vehicle, _turret] call CBA_fnc_getTurret; getText (configFile >> "CfgMovesBasic" >> "ManActions" >> getText (_turretConfig >> "gunnerAction")) // return @@ -42,7 +42,9 @@ if !(_turret isEqualTo []) exitWith { private _cargoIndex = _vehicle getCargoIndex _unit; if (_cargoIndex != -1) exitWith { - getText (configFile >> "CfgMovesBasic" >> "ManActions" >> getArray (_config >> "cargoAction") select _cargoIndex) // return + private _cargoAction = getArray (_config >> "cargoAction"); + _cargoIndex = _cargoIndex min (count _cargoAction - 1); // The array can be smaller than the max cargo index, just use last element + getText (configFile >> "CfgMovesBasic" >> "ManActions" >> (_cargoAction select _cargoIndex)) // return }; // --- default diff --git a/addons/common/functions/fnc_getChildren.sqf b/addons/common/functions/fnc_getChildren.sqf index 998d0b4399..b632b0642f 100644 --- a/addons/common/functions/fnc_getChildren.sqf +++ b/addons/common/functions/fnc_getChildren.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Obtain children of a config entry diff --git a/addons/common/functions/fnc_getConfigCommander.sqf b/addons/common/functions/fnc_getConfigCommander.sqf index f3d011c57a..6fbe381173 100644 --- a/addons/common/functions/fnc_getConfigCommander.sqf +++ b/addons/common/functions/fnc_getConfigCommander.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the commander config of a vehicles turret. @@ -17,7 +17,7 @@ params ["_vehicle"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _turret = _vehicle call FUNC(getTurretCommander); [_config, _turret] call FUNC(getTurretConfigPath) // return diff --git a/addons/common/functions/fnc_getConfigGunner.sqf b/addons/common/functions/fnc_getConfigGunner.sqf index 732256b8a1..68aa432aa3 100644 --- a/addons/common/functions/fnc_getConfigGunner.sqf +++ b/addons/common/functions/fnc_getConfigGunner.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the gunner config of a vehicles turret. @@ -17,7 +17,7 @@ params ["_vehicle"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _turret = _vehicle call FUNC(getTurretGunner); [_config, _turret] call FUNC(getTurretConfigPath) // return diff --git a/addons/common/functions/fnc_getConfigName.sqf b/addons/common/functions/fnc_getConfigName.sqf new file mode 100644 index 0000000000..3495014d55 --- /dev/null +++ b/addons/common/functions/fnc_getConfigName.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Returns an item's config case sensitive name. + * + * Arguments: + * 0: Class name (item or object) + * + * Return Value: + * Config case item name ("" if config is not found) + * + * Example: + * ["arifle_AK12_F"] call ace_common_fnc_getConfigName + * + * Public: Yes +*/ + +params ["_className"]; + +(uiNamespace getVariable QGVAR(configNames)) getOrDefaultCall [toLowerANSI _className, { + private _config = configNull; + + { + _config = configFile >> _x >> _className; + + if (isClass _config) exitWith {}; + } forEach ["CfgWeapons", "CfgMagazines", "CfgGlasses", "CfgVehicles", "CfgVoice", "CfgUnitInsignia"]; + + configName _config +}, true] diff --git a/addons/common/functions/fnc_getCountOfItem.sqf b/addons/common/functions/fnc_getCountOfItem.sqf index a6cf3b9233..5114f375d2 100644 --- a/addons/common/functions/fnc_getCountOfItem.sqf +++ b/addons/common/functions/fnc_getCountOfItem.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Dedmen + * Author: Dedmen, Blue, johnb43 * Return how many items of type _itemType the player has in his containers (Uniform, Vest, Backpack) * Doesn't count assignedItems, weapons, weapon attachments, magazines in weapons * @@ -19,13 +19,17 @@ params ["_unit", "_itemType"]; -private _countItemsInContainer = { - (getItemCargo _this) params ["_itemTypes", "_itemCounts"]; +private _count = 0; +private _isMagazine = isClass (configFile >> "CfgMagazines" >> _itemType); - private _index = _itemTypes find _itemType; - _itemCounts param [_index, 0] -}; +{ + (if (_isMagazine) then { + getMagazineCargo _x + } else { + getItemCargo _x + }) params ["_itemTypes", "_itemCounts"]; -((uniformContainer _unit) call _countItemsInContainer) + -((vestContainer _unit) call _countItemsInContainer) + -((backpackContainer _unit) call _countItemsInContainer) + _count = _count + (_itemCounts param [_itemTypes find _itemType, 0]); +} forEach [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]; + +_count diff --git a/addons/common/functions/fnc_getDeathAnim.sqf b/addons/common/functions/fnc_getDeathAnim.sqf index 8fb72e0a21..18c6c93c07 100644 --- a/addons/common/functions/fnc_getDeathAnim.sqf +++ b/addons/common/functions/fnc_getDeathAnim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, PabstMirror * Get the death animation for the unit at current time @@ -27,9 +27,9 @@ if (getNumber (_unitAnimationCfg >> "terminal") == 1) exitWith {_animationState} private _unitActionsCfg = configFile >> "CfgMovesBasic" >> "Actions" >> getText (_unitAnimationCfg >> "actions"); -TRACE_2("Animation/Action", configName _unitAnimationCfg, configName _unitActionsCfg); +TRACE_2("Animation/Action",configName _unitAnimationCfg,configName _unitActionsCfg); -if (vehicle _unit != _unit) then { +if (!isNull objectParent _unit) then { private _interpolateArray = getArray (_unitAnimationCfg >> "interpolateTo"); for "_index" from 0 to (count _interpolateArray - 1) step 2 do { diff --git a/addons/common/functions/fnc_getDefaultAnim.sqf b/addons/common/functions/fnc_getDefaultAnim.sqf index 9fea3e15df..bd294ba0c0 100644 --- a/addons/common/functions/fnc_getDefaultAnim.sqf +++ b/addons/common/functions/fnc_getDefaultAnim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the Defualt animation for the unit @@ -17,7 +17,7 @@ params ["_unit"]; -private _anim = toLower animationState _unit; +private _anim = toLowerANSI animationState _unit; // stance is broken for some animations. private _stance = stance _unit; diff --git a/addons/common/functions/fnc_getDefinedVariable.sqf b/addons/common/functions/fnc_getDefinedVariable.sqf index 7e20570cc1..d600d62cf2 100644 --- a/addons/common/functions/fnc_getDefinedVariable.sqf +++ b/addons/common/functions/fnc_getDefinedVariable.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Grabs a variable. If variable has not been set, attempts to use default defined value diff --git a/addons/common/functions/fnc_getDefinedVariableDefault.sqf b/addons/common/functions/fnc_getDefinedVariableDefault.sqf index edae4ef3ef..e78090b636 100644 --- a/addons/common/functions/fnc_getDefinedVariableDefault.sqf +++ b/addons/common/functions/fnc_getDefinedVariableDefault.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Get the variable default value @@ -19,7 +19,7 @@ params ["_varName"]; private _variableDefinition = _varName call FUNC(getDefinedVariableInfo); -if !(_variableDefinition isEqualTo []) exitWith { +if (_variableDefinition isNotEqualTo []) exitWith { _variableDefinition select 1; }; diff --git a/addons/common/functions/fnc_getDefinedVariableInfo.sqf b/addons/common/functions/fnc_getDefinedVariableInfo.sqf index f6aeca0df9..61dec04e04 100644 --- a/addons/common/functions/fnc_getDefinedVariableInfo.sqf +++ b/addons/common/functions/fnc_getDefinedVariableInfo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Get the variable Informations diff --git a/addons/common/functions/fnc_getDisplayConfigName.sqf b/addons/common/functions/fnc_getDisplayConfigName.sqf index f952d5c385..f6be033be3 100644 --- a/addons/common/functions/fnc_getDisplayConfigName.sqf +++ b/addons/common/functions/fnc_getDisplayConfigName.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get display classnames from config with given idd. diff --git a/addons/common/functions/fnc_getDoorTurrets.sqf b/addons/common/functions/fnc_getDoorTurrets.sqf index 93b0360042..1b6f22152a 100644 --- a/addons/common/functions/fnc_getDoorTurrets.sqf +++ b/addons/common/functions/fnc_getDoorTurrets.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Returns all turret indecies of door gunners. @@ -22,14 +22,13 @@ private _turrets = allTurrets [_vehicle, true]; private _doorTurrets = []; { - private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; + private _config = configOf _vehicle; _config = [_config, _x] call FUNC(getTurretConfigPath); if (((getNumber (_config >> "isCopilot")) == 0) && {count getArray (_config >> "weapons") > 0}) then { _doorTurrets pushBack _x; }; - false -} count _turrets; +} forEach _turrets; _doorTurrets diff --git a/addons/common/functions/fnc_getFiremodeIndex.sqf b/addons/common/functions/fnc_getFiremodeIndex.sqf new file mode 100644 index 0000000000..7abf65cafa --- /dev/null +++ b/addons/common/functions/fnc_getFiremodeIndex.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Get the firemode index of the weapon for use with "SwitchWeapon" + * + * Arguments: + * 0: Unit + * 1: Muzzle (default: current weapon muzzle) + * 2: Firemode (default: current weapon fire mode) + * + * Return Value: + * Weapon/Mode index + * + * Example: + * [player] call ace_common_fnc_getFiremodeIndex + * + * Public: Yes + */ + +params ["_unit"]; +(weaponState _unit) params ["", "_currentMuzzle", "_currentFiremode"]; +params ["", ["_muzzle", _currentMuzzle], ["_firemode", _currentFireMode]]; + +private _weapons = _unit weaponsInfo [_muzzle, false]; +private _index = -1; +{ + _x params ["_xIndex", "", "", "", "_xFiremode"]; + if (_xFiremode == _firemode) exitWith { _index = _xIndex; }; +} forEach _weapons; + +_index diff --git a/addons/common/functions/fnc_getFirstObjectIntersection.sqf b/addons/common/functions/fnc_getFirstObjectIntersection.sqf index 1120707b2b..cc2e9ff736 100644 --- a/addons/common/functions/fnc_getFirstObjectIntersection.sqf +++ b/addons/common/functions/fnc_getFirstObjectIntersection.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg - * Returns the the first intersection with terrain between two positions. @todo rewrite using lineIntersectsSurfaces? + * Returns the the first intersection with terrain between two positions. * * Arguments: * 0: PositionASL @@ -18,31 +18,14 @@ * Public: Yes */ -params ["_source", "_destination", "_accuracy"]; +params ["_source", "_destination"]; private _result = [false, [0, 0, 0]]; - -private _distance = _source vectorDistance _destination; - -if !(lineIntersectsWith [_source, _destination] isEqualTo []) then { - private _lower = 0; - private _upper = 1; - private _mid = 0.5; - - private _dir = _source vectorFromTo _destination; - - while {(_upper - _lower) * _distance > _accuracy} do { - _mid = _lower + (_upper - _lower) / 2; - - if !(lineIntersectsWith [_source, _source vectorAdd (_dir vectorMultiply (_mid * _distance))] isEqualTo []) then { - _upper = _mid; - } else { - _lower = _mid; - }; +private _hits = lineIntersectsSurfaces [_source, _destination, objNull, objNull, true, -1]; +{ + _x params ["_pos", "", "_obj"]; + if (!isNull _obj) exitWith { + _result = [true, _pos]; }; - - _mid = _lower + (_upper - _lower) / 2; - _result = [true, _source vectorAdd (_dir vectorMultiply (_mid * _distance))]; -}; - +} forEach _hits; _result diff --git a/addons/common/functions/fnc_getFirstTerrainIntersection.sqf b/addons/common/functions/fnc_getFirstTerrainIntersection.sqf index 989486b1ac..cc85562087 100644 --- a/addons/common/functions/fnc_getFirstTerrainIntersection.sqf +++ b/addons/common/functions/fnc_getFirstTerrainIntersection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Returns the the first intersection with an object between two positions. @todo rewrite using lineIntersectsSurfaces? diff --git a/addons/common/functions/fnc_getGunner.sqf b/addons/common/functions/fnc_getGunner.sqf index bd65c49ed4..376f18070e 100644 --- a/addons/common/functions/fnc_getGunner.sqf +++ b/addons/common/functions/fnc_getGunner.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns gunner using specified weapon type in vehicle. Only works if all turrets have different weapons. @@ -19,7 +19,7 @@ params [["_vehicle", objNull, [objNull]], ["_weapon", "", [""]]]; // on foot -if (gunner _vehicle == _vehicle && {_weapon in weapons _vehicle || {toLower _weapon in ["throw", "put"]}}) exitWith {gunner _vehicle}; +if (gunner _vehicle == _vehicle && {_weapon in weapons _vehicle || {toLowerANSI _weapon in ["throw", "put"]}}) exitWith {gunner _vehicle}; // inside vehicle private _gunner = objNull; @@ -28,8 +28,7 @@ private _gunner = objNull; if (_weapon in (_vehicle weaponsTurret _x)) exitWith { _gunner = _vehicle turretUnit _x; }; - false -} count allTurrets [_vehicle, true]; +} forEach allTurrets [_vehicle, true]; // ensure that at least the pilot is returned if there is no gunner if (isManualFire _vehicle && {isNull _gunner}) then { diff --git a/addons/common/functions/fnc_getInPosition.sqf b/addons/common/functions/fnc_getInPosition.sqf index a45b5546a6..076fd7a23c 100644 --- a/addons/common/functions/fnc_getInPosition.sqf +++ b/addons/common/functions/fnc_getInPosition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Move unit into given vehicle position or switch to that position if the unit is already inside the vehicle. @@ -23,12 +23,12 @@ params ["_unit", "_vehicle", "_position", ["_index", -1]]; -_position = toLower _position; +_position = toLowerANSI _position; // general if (!alive _vehicle || {locked _vehicle > 1}) exitWith {false}; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _turret = []; private _isInside = vehicle _unit == _vehicle; @@ -38,8 +38,7 @@ private _enemiesInVehicle = false; //Possible Side Restriction { if (side _unit getFriend side _x < 0.6) exitWith {_enemiesInVehicle = true}; - false -} count crew _vehicle; +} forEach crew _vehicle; switch (_position) do { case "driver" : { @@ -206,7 +205,7 @@ switch (_position) do { // this will execute all config based event handlers. Not script based ones unfortunately, but atleast we don't use any. private _fnc_getInEH = { // config based getIn EHs are assigned to the soldier, not the vehicle. Why Bis? Why? - private _config = configFile >> "CfgVehicles" >> typeOf _unit >> "EventHandlers"; + private _config = configOf _unit >> "EventHandlers"; if (isClass _config) then { //getIn is local effects with global arguments. It doesn't trigger if the unit was already inside and only switched seats diff --git a/addons/common/functions/fnc_getItemType.sqf b/addons/common/functions/fnc_getItemType.sqf index 5212c6d57e..49f1b757da 100644 --- a/addons/common/functions/fnc_getItemType.sqf +++ b/addons/common/functions/fnc_getItemType.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns item type of given classname. @@ -67,7 +67,7 @@ switch (true) do { case (_type == TYPE_UNIFORM): {["item", "uniform"]}; case (_type == TYPE_BINOCULAR_AND_NVG): { - switch (toLower _simulation) do { + switch (toLowerANSI _simulation) do { case ("weapon"): {["weapon", "binocular"]}; case ("binocular"): {["weapon", "binocular"]}; case ("nvgoggles"): {["item", "nvgoggles"]}; @@ -78,7 +78,7 @@ switch (true) do { case (_type == TYPE_WEAPON_VEHICLE): {["weapon", "vehicle"]}; case (_type == TYPE_ITEM): { - switch (toLower _simulation) do { + switch (toLowerANSI _simulation) do { case ("itemmap"): {["item", "map"]}; case ("itemgps"): {["item", "gps"]}; case ("itemradio"): {["item", "radio"]}; diff --git a/addons/common/functions/fnc_getLightProperties.sqf b/addons/common/functions/fnc_getLightProperties.sqf index 002868dd4e..03cefc63dc 100644 --- a/addons/common/functions/fnc_getLightProperties.sqf +++ b/addons/common/functions/fnc_getLightProperties.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Read properties of given vehicles light. @@ -22,7 +22,7 @@ params ["_vehicle", "_light"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle >> "Reflectors" >> _light; +private _config = configOf _vehicle >> "Reflectors" >> _light; private _intensity = getNumber (_config >> "intensity"); private _position = getText (_config >> "position"); diff --git a/addons/common/functions/fnc_getLightPropertiesWeapon.sqf b/addons/common/functions/fnc_getLightPropertiesWeapon.sqf index fca17dd51f..1bf6ae6cac 100644 --- a/addons/common/functions/fnc_getLightPropertiesWeapon.sqf +++ b/addons/common/functions/fnc_getLightPropertiesWeapon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Read properties of given flashlight. diff --git a/addons/common/functions/fnc_getLocalUnits.sqf b/addons/common/functions/fnc_getLocalUnits.sqf index 17163d0e77..5bf0788283 100644 --- a/addons/common/functions/fnc_getLocalUnits.sqf +++ b/addons/common/functions/fnc_getLocalUnits.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: dedmen * Gets localUnits array filtering out nullObjects. @@ -6,7 +6,7 @@ * Should be equivalent to `allUnits select {local _x}` * * Arguments: - * Nothing + * None * * Return Value: * Array of local Units diff --git a/addons/common/functions/fnc_getMGRSdata.sqf b/addons/common/functions/fnc_getMGRSdata.sqf index f6ca81175b..92cedec3b9 100644 --- a/addons/common/functions/fnc_getMGRSdata.sqf +++ b/addons/common/functions/fnc_getMGRSdata.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Gets the current map's MGRS grid zone designator and 100km square. @@ -26,7 +26,7 @@ private _lat = -1 * getNumber (configFile >> "CfgWorlds" >> _map >> "latitude"); private _altitude = getNumber (configFile >> "CfgWorlds" >> _map >> "elevationOffset"); private _mapData = _map call FUNC(getMapData); -if (!(_mapData isEqualTo [])) then { +if (_mapData isNotEqualTo []) then { _lat = _mapData select 0; _altitude = _mapData select 1; }; diff --git a/addons/common/functions/fnc_getMapData.sqf b/addons/common/functions/fnc_getMapData.sqf index b4cb56d75f..379210ec8f 100644 --- a/addons/common/functions/fnc_getMapData.sqf +++ b/addons/common/functions/fnc_getMapData.sqf @@ -16,7 +16,7 @@ */ params ["_map"]; -_map = toLower _map; +_map = toLowerANSI _map; // [latitude, altitude] diff --git a/addons/common/functions/fnc_getMapGridData.sqf b/addons/common/functions/fnc_getMapGridData.sqf index c329c0b3f9..daa4bd86cd 100644 --- a/addons/common/functions/fnc_getMapGridData.sqf +++ b/addons/common/functions/fnc_getMapGridData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Finds real x/y offset and map step for a 10 digit grid @@ -12,7 +12,7 @@ * None * * Example: - * [] call ace_map_fnc_getMapGridData + * [] call ace_common_fnc_getMapGridData * * Public: No */ @@ -23,7 +23,7 @@ GVAR(mapGridData) = []; private _cfgGrid = configFile >> "CfgWorlds" >> worldName >> "Grid"; private _offsetX = getNumber (_cfgGrid >> "offsetX"); private _offsetY = getNumber (_cfgGrid >> "offsetY"); -private _zoomMax = 1e99; +private _zoomMax = 1e38; private _formatX = ""; private _formatY = ""; private _stepX = 1e10; @@ -38,13 +38,12 @@ private _stepY = 1e10; _stepX = getNumber (_x >> "stepX"); _stepY = getNumber (_x >> "stepY"); }; - false -} count configProperties [_cfgGrid, "isClass _x", false]; +} forEach configProperties [_cfgGrid, "isClass _x", false]; private _letterGrid = false; -if (toLower _formatX find "a" != -1) then {_letterGrid = true}; -if (toLower _formatY find "a" != -1) then {_letterGrid = true}; +if (toLowerANSI _formatX find "a" != -1) then {_letterGrid = true}; +if (toLowerANSI _formatY find "a" != -1) then {_letterGrid = true}; if (_letterGrid) exitWith { WARNING_3("Map Grid Warning (%1) - Map uses letter grids [%2, %3]",worldName,_formatX,_formatY); diff --git a/addons/common/functions/fnc_getMapGridFromPos.sqf b/addons/common/functions/fnc_getMapGridFromPos.sqf index defee04e57..fb12ad9dfc 100644 --- a/addons/common/functions/fnc_getMapGridFromPos.sqf +++ b/addons/common/functions/fnc_getMapGridFromPos.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing, PabstMirror * Gets a 10-digit map grid for the given world position diff --git a/addons/common/functions/fnc_getMapPosFromGrid.sqf b/addons/common/functions/fnc_getMapPosFromGrid.sqf index d4469b56cc..7466ce5899 100644 --- a/addons/common/functions/fnc_getMapPosFromGrid.sqf +++ b/addons/common/functions/fnc_getMapPosFromGrid.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Gets position from grid cords diff --git a/addons/common/functions/fnc_getMarkerType.sqf b/addons/common/functions/fnc_getMarkerType.sqf index ed551e4c1b..3f5d5132be 100644 --- a/addons/common/functions/fnc_getMarkerType.sqf +++ b/addons/common/functions/fnc_getMarkerType.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Get the apropriate marker for a group. @@ -10,7 +10,7 @@ * Marker Type * * Example: - * ["GROUP"] call ace_common_fnc_getmarkerType + * ["GROUP"] call ace_common_fnc_getMarkerType * * Public: No */ @@ -23,9 +23,9 @@ private _side = side _leader; if (_vehicle == _leader) exitWith { if ( - getNumber (configFile >> "CfgVehicles" >> typeOf _leader >> "detectSkill") > 20 || - getNumber (configFile >> "CfgVehicles" >> typeOf _leader >> "camouflage") < 1 || - getText (configFile >> "CfgVehicles" >> typeOf _leader >> "textsingular") == "diver" + getNumber (configOf _leader >> "detectSkill") > 20 || + getNumber (configOf _leader >> "camouflage") < 1 || + getText (configOf _leader >> "textsingular") == "diver" ) then { ["n_recon", "b_recon", "o_recon"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) } else { @@ -33,16 +33,16 @@ if (_vehicle == _leader) exitWith { }; }; -if (getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "attendant") == 1) exitWith { +if (getNumber (configOf _vehicle >> "attendant") == 1) exitWith { ["n_med", "b_med", "o_med"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) }; if ( - getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "transportRepair") > 0 || - getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "transportFuel") > 0 || - getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "transportAmmo") > 0 || - getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "ACE_canRepair") > 0 || - getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "ACE_fuelCapacityCargo") > 0 + getNumber (configOf _vehicle >> "transportRepair") > 0 || + getNumber (configOf _vehicle >> "transportFuel") > 0 || + getNumber (configOf _vehicle >> "transportAmmo") > 0 || + getNumber (configOf _vehicle >> "ACE_canRepair") > 0 || + getNumber (configOf _vehicle >> "ACE_fuelCapacityCargo") > 0 ) exitWith { ["n_maint", "b_maint", "o_maint"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) }; @@ -59,7 +59,7 @@ if (_vehicle isKindOf "StaticMortar") exitWith { ["n_mortar", "b_mortar", "o_mortar"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) }; -if (getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "artilleryScanner") == 1) exitWith { +if (getNumber (configOf _vehicle >> "artilleryScanner") == 1) exitWith { ["n_art", "b_art", "o_art"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) }; @@ -68,7 +68,7 @@ if (_vehicle isKindOf "Car") exitWith { }; if (_vehicle isKindOf "Tank") exitWith { - if (getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "transportSoldier") > 0) then { + if (getNumber (configOf _vehicle >> "transportSoldier") > 0) then { ["n_mech_inf", "b_mech_inf", "o_mech_inf"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) } else { ["n_armor", "b_armor", "o_armor"] select ((["GUER", "WEST", "EAST"] find str _side) max 0) diff --git a/addons/common/functions/fnc_getName.sqf b/addons/common/functions/fnc_getName.sqf index 0bcce9d2c8..058386cde4 100644 --- a/addons/common/functions/fnc_getName.sqf +++ b/addons/common/functions/fnc_getName.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns the name of the object. Used to prevent issues with the name command. @@ -27,7 +27,7 @@ if (_unit isKindOf "CAManBase") then { if (_showEffective) then { _name = [effectiveCommander _unit, false, _useRaw] call FUNC(getName); } else { - _name = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "displayName"); + _name = getText (configOf _unit >> "displayName"); }; }; diff --git a/addons/common/functions/fnc_getNumberMagazinesIn.sqf b/addons/common/functions/fnc_getNumberMagazinesIn.sqf index 7beaf3ee37..b71e6729dd 100644 --- a/addons/common/functions/fnc_getNumberMagazinesIn.sqf +++ b/addons/common/functions/fnc_getNumberMagazinesIn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Count magazines of unit. @@ -25,8 +25,7 @@ if (_unit isKindOf "CAManBase") then { } else { { _return = _return + ({_x == _magazine} count magazines _x); - false - } count crew _unit; + } forEach crew _unit; (getMagazineCargo _unit) params [["_magNames", []], ["_magCount", []]]; { diff --git a/addons/common/functions/fnc_getPitchBankYaw.sqf b/addons/common/functions/fnc_getPitchBankYaw.sqf index 6cdec367de..e53d1d7fc4 100644 --- a/addons/common/functions/fnc_getPitchBankYaw.sqf +++ b/addons/common/functions/fnc_getPitchBankYaw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Returns pitch, bank, yaw for given vehicle in degrees. diff --git a/addons/common/functions/fnc_getPylonTurret.sqf b/addons/common/functions/fnc_getPylonTurret.sqf index b27e6eb582..f7891e4ba9 100644 --- a/addons/common/functions/fnc_getPylonTurret.sqf +++ b/addons/common/functions/fnc_getPylonTurret.sqf @@ -1,14 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Finds turret owner of a pylon. + * Returns the turret path that owns the given pylon. * * Arguments: * 0: Vehicle * 1: Pylon Index (starting at 0) * * Return Value: - * * Turret index (either [-1] or [0]) + * Turret Path (either [-1] or [0]) * * Example: * [cursorObject, 0] call ace_common_fnc_getPylonTurret @@ -18,46 +18,4 @@ params ["_vehicle", "_pylonIndex"]; -// See if index is in ace_pylonTurrets setVar on vehicle -private _pylonTurrets = _vehicle getVariable ["ace_pylonTurrets", []]; -private _returnValue = _pylonTurrets param [_pylonIndex, []]; - -if (!(_returnValue isEqualTo [])) then { - TRACE_1("Using ace_pylonTurrets value",_returnValue); -} else { - // Attempt to determine turret owner based on magazines in the vehicle - private _pyMags = getPylonMagazines _vehicle; - private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> typeOf _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; - if (_pylonIndex >= (count _pyMags)) exitWith {ERROR("out of bounds");}; - if (_pylonIndex >= (count _pylonConfigs)) exitWith {ERROR("out of bounds");}; - - private _targetMag = _pyMags select _pylonIndex; - private _inPilot = _targetMag in (_vehicle magazinesTurret [-1]); - private _inGunner = _targetMag in (_vehicle magazinesTurret [0]); - - if (_inPilot) then { - if (_inGunner) then { - TRACE_3("ambiguous - in both",_targetMag,_inPilot,_inGunner); - } else { - TRACE_3("Pilot Mag",_targetMag,_inPilot,_inGunner); - _returnValue = [-1]; - }; - } else { - if (_inGunner) then { - TRACE_3("Gunner Mag",_targetMag,_inPilot,_inGunner); - _returnValue = [0]; - } else { - TRACE_3("ambiguous - in neither",_targetMag,_inPilot,_inGunner); - }; - }; - - if (_returnValue isEqualTo []) then { // If not sure, just use config value - _returnValue = getArray ((_pylonConfigs select _pylonIndex) >> "turret"); - if (_returnValue isEqualTo []) then { - _returnValue = [-1]; - }; - }; -}; - -TRACE_3("",_vehicle,_pylonIndex,_returnValue); -_returnValue +getAllPylonsInfo _vehicle param [_pylonIndex, []] param [2, [-1]] diff --git a/addons/common/functions/fnc_getReflectorsWithSelections.sqf b/addons/common/functions/fnc_getReflectorsWithSelections.sqf index 97feca6e19..1e874c0208 100644 --- a/addons/common/functions/fnc_getReflectorsWithSelections.sqf +++ b/addons/common/functions/fnc_getReflectorsWithSelections.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * @@ -21,7 +21,7 @@ params ["_vehicle"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _hitpoints = []; private _selections = []; diff --git a/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf b/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf index 5c30245732..5367b0ae61 100644 --- a/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf +++ b/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/common/functions/fnc_getSettingData.sqf b/addons/common/functions/fnc_getSettingData.sqf index 79ee4f3264..eeb8dff1d8 100644 --- a/addons/common/functions/fnc_getSettingData.sqf +++ b/addons/common/functions/fnc_getSettingData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Returns the metadata of a setting if it exists @@ -32,7 +32,6 @@ scopeName "main"; if (_x select 0 == _name) then { _x breakOut "main"; }; - false -} count GVAR(settings); +} forEach GVAR(settings); [] diff --git a/addons/common/functions/fnc_getStaminaBarControl.sqf b/addons/common/functions/fnc_getStaminaBarControl.sqf index a426a7f933..18721606fb 100644 --- a/addons/common/functions/fnc_getStaminaBarControl.sqf +++ b/addons/common/functions/fnc_getStaminaBarControl.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns the control of the Stamina Bar from Arma 1.54. diff --git a/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf b/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf index 3a4da0326f..baf1871b9f 100644 --- a/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf +++ b/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get players viewing direction and slope. diff --git a/addons/common/functions/fnc_getTargetDistance.sqf b/addons/common/functions/fnc_getTargetDistance.sqf index ff6d2cc198..27a336d9ab 100644 --- a/addons/common/functions/fnc_getTargetDistance.sqf +++ b/addons/common/functions/fnc_getTargetDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Get the distance to the next object the player is looking at. Used for laser distance measurements. diff --git a/addons/common/functions/fnc_getTargetObject.sqf b/addons/common/functions/fnc_getTargetObject.sqf index a15cd309be..ab699e1f3d 100644 --- a/addons/common/functions/fnc_getTargetObject.sqf +++ b/addons/common/functions/fnc_getTargetObject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the nearest object the player is looking at. Used for laser designator instead of cursorTarget. diff --git a/addons/common/functions/fnc_getTurnedOnLights.sqf b/addons/common/functions/fnc_getTurnedOnLights.sqf index a40832d61d..fcfd1b92df 100644 --- a/addons/common/functions/fnc_getTurnedOnLights.sqf +++ b/addons/common/functions/fnc_getTurnedOnLights.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns all turned on lights of any vehicle or streetlamp. diff --git a/addons/common/functions/fnc_getTurretCommander.sqf b/addons/common/functions/fnc_getTurretCommander.sqf index 49d0798d35..5bb1e107c6 100644 --- a/addons/common/functions/fnc_getTurretCommander.sqf +++ b/addons/common/functions/fnc_getTurretCommander.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the turret index of a vehicles commander. diff --git a/addons/common/functions/fnc_getTurretConfigPath.sqf b/addons/common/functions/fnc_getTurretConfigPath.sqf index aee865b3fb..98cc6b08a9 100644 --- a/addons/common/functions/fnc_getTurretConfigPath.sqf +++ b/addons/common/functions/fnc_getTurretConfigPath.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the config path of a vehicles turret. @@ -16,27 +16,4 @@ * Public: Yes */ -params ["_config", "_turretIndex"]; - -for "_index" from 0 to (count _turretIndex - 1) do { - _config = _config >> "Turrets"; - - private _offset = 0; - private _config2 = _config select 0; - private _foundClasses = 0; - - for "_a" from 0 to (count _config - 1) do { - if (isClass _config2) then { - _foundClasses = _foundClasses + 1; - } else { - _offset = _offset + 1; - }; - _config2 = _config select (_turretIndex select _index) + _offset; - - if (_foundClasses == _turretIndex select _index) exitWith {}; - }; - - _config = _config2; -}; - -_config +call CBA_fnc_getTurret diff --git a/addons/common/functions/fnc_getTurretCopilot.sqf b/addons/common/functions/fnc_getTurretCopilot.sqf index 7207ac5b17..0b2fee3f37 100644 --- a/addons/common/functions/fnc_getTurretCopilot.sqf +++ b/addons/common/functions/fnc_getTurretCopilot.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the turret index of a vehicles copilot. diff --git a/addons/common/functions/fnc_getTurretDirection.sqf b/addons/common/functions/fnc_getTurretDirection.sqf index 78db8bc8e6..7592bc8f33 100644 --- a/addons/common/functions/fnc_getTurretDirection.sqf +++ b/addons/common/functions/fnc_getTurretDirection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Get the absolute turret direction for FOV/PIP turret. @@ -25,19 +25,19 @@ private _pov = getText (_turret >> "memoryPointGunnerOptics"); private _gunBeg = getText (_turret >> "gunBeg"); private _gunEnd = getText (_turret >> "gunEnd"); -TRACE_3("", _pov, _gunBeg, _gunEnd); +TRACE_3("",_pov,_gunBeg,_gunEnd); // Pull the PIP pov or barrel direction, depending on how the model is set up -private _povPos = ATLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition _pov)); //@todo AGLToASL ? +private _povPos = _vehicle modelToWorldVisualWorld (_vehicle selectionPosition _pov); private _povDir = [0,0,0]; if (_pov == "pip0_pos") then { - private _pipDir = ATLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition "pip0_dir")); + private _pipDir = _vehicle modelToWorldVisualWorld (_vehicle selectionPosition "pip0_dir"); _povDir = _pipDir vectorDiff _povPos; } else { - private _gunBeginPos = ATLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition _gunBeg)); - private _gunEndPos = ATLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition _gunEnd)); + private _gunBeginPos = _vehicle modelToWorldVisualWorld (_vehicle selectionPosition _gunBeg); + private _gunEndPos = _vehicle modelToWorldVisualWorld (_vehicle selectionPosition _gunEnd); _povDir = _gunBeginPos vectorDiff _gunEndPos; }; diff --git a/addons/common/functions/fnc_getTurretGunner.sqf b/addons/common/functions/fnc_getTurretGunner.sqf index 180a10914e..f485ab3bbc 100644 --- a/addons/common/functions/fnc_getTurretGunner.sqf +++ b/addons/common/functions/fnc_getTurretGunner.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the turret index of a vehicles gunner. diff --git a/addons/common/functions/fnc_getTurretIndex.sqf b/addons/common/functions/fnc_getTurretIndex.sqf index 423f2e6289..75deced412 100644 --- a/addons/common/functions/fnc_getTurretIndex.sqf +++ b/addons/common/functions/fnc_getTurretIndex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the turret index of a units current turret. @@ -20,11 +20,10 @@ params [["_unit", objNull, [objNull]]]; private _vehicle = vehicle _unit; if (_unit == _vehicle) exitWith {[]}; -scopeName "main"; +scopeName "main"; { if (_unit == (_vehicle turretUnit _x)) then {_x breakOut "main"}; - nil -} count allTurrets [_vehicle, true]; +} forEach allTurrets [_vehicle, true]; [] diff --git a/addons/common/functions/fnc_getTurretsFFV.sqf b/addons/common/functions/fnc_getTurretsFFV.sqf index 0ae04a3032..e7ea4b369e 100644 --- a/addons/common/functions/fnc_getTurretsFFV.sqf +++ b/addons/common/functions/fnc_getTurretsFFV.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the turret indices of ffv turrets. diff --git a/addons/common/functions/fnc_getTurretsOther.sqf b/addons/common/functions/fnc_getTurretsOther.sqf index c84b50d842..681596a329 100644 --- a/addons/common/functions/fnc_getTurretsOther.sqf +++ b/addons/common/functions/fnc_getTurretsOther.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the turret indices of other turrets (not gunner, commander, copilot or ffv). diff --git a/addons/common/functions/fnc_getUavControlPosition.sqf b/addons/common/functions/fnc_getUavControlPosition.sqf index 9d6f6de9f2..0c6be45bf5 100644 --- a/addons/common/functions/fnc_getUavControlPosition.sqf +++ b/addons/common/functions/fnc_getUavControlPosition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Returns the seat position of a UAV that the unit is activly controling. diff --git a/addons/common/functions/fnc_getVehicleCargo.sqf b/addons/common/functions/fnc_getVehicleCargo.sqf index 82442700a2..fc3ec83994 100644 --- a/addons/common/functions/fnc_getVehicleCargo.sqf +++ b/addons/common/functions/fnc_getVehicleCargo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the vehicle cargo positions. Codrivers and ffv positions are not listed. @@ -15,15 +15,16 @@ * Public: Yes */ -params [["_vehicle", objNull, [objNull]]]; +params [["_classname", "", [""]]]; -private _config = configFile >> "CfgVehicles" >> _vehicle; +private _config = configFile >> "CfgVehicles" >> _classname; +if (isNull _config) then { ERROR_1("ace_common_fnc_getVehicleCargo bad classname %1",_this); }; private _cargo = []; private _codrivers = getArray (_config >> "cargoIsCoDriver"); for "_index" from 0 to (getNumber (_config >> "transportSoldier") - 1) do { - if !(_index in _codrivers && {_vehicle isKindOf "Car"} && {!(_vehicle isKindOf "Wheeled_APC_F")}) then { + if !(_index in _codrivers && {_classname isKindOf "Car"} && {!(_classname isKindOf "Wheeled_APC_F")}) then { _cargo pushBack _index; }; }; diff --git a/addons/common/functions/fnc_getVehicleCodriver.sqf b/addons/common/functions/fnc_getVehicleCodriver.sqf index 8deef3f9cd..366c4db8ff 100644 --- a/addons/common/functions/fnc_getVehicleCodriver.sqf +++ b/addons/common/functions/fnc_getVehicleCodriver.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the vehicle codriver positions. @@ -17,7 +17,7 @@ params [["_vehicle", objNull, [objNull]]]; -private _config = configFile >> "CfgVehicles" >> _vehicle; +private _config = configOf _vehicle; private _cargo = []; private _codrivers = getArray (_config >> "cargoIsCoDriver"); diff --git a/addons/common/functions/fnc_getVehicleCrew.sqf b/addons/common/functions/fnc_getVehicleCrew.sqf index af699d3b6b..a1bc06f6ab 100644 --- a/addons/common/functions/fnc_getVehicleCrew.sqf +++ b/addons/common/functions/fnc_getVehicleCrew.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns array of crew member objects. @@ -29,11 +29,10 @@ private _crew = []; }; } else { // otherwise check if we search for that type. toLower, because fullCrew returns "driver" vs. "Turret". - if (toLower (_x select 1) in _types) then { + if (toLowerANSI (_x select 1) in _types) then { _crew pushBack (_x select 0); }; }; - false -} count fullCrew _vehicle; +} forEach fullCrew _vehicle; _crew diff --git a/addons/common/functions/fnc_getVehicleIcon.sqf b/addons/common/functions/fnc_getVehicleIcon.sqf index ce17a66bc2..c63d54a8d8 100644 --- a/addons/common/functions/fnc_getVehicleIcon.sqf +++ b/addons/common/functions/fnc_getVehicleIcon.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: AACO * Function used to get the vehicle icon for provided object (cached for repeat use) * * Arguments: - * 0: Object to get icon of + * 0: Object to get icon of * * Return Value: * Icon of vehicle @@ -18,21 +18,21 @@ params [["_object", objNull, [objNull, ""]]]; -if ((_object isEqualType objNull && {isNull _object}) || {_object isEqualType "" && {_object == ""}}) exitWith { DEFAULT_TEXTURE }; +if (_object isEqualTo objNull || {_object isEqualTo ""}) exitWith { DEFAULT_TEXTURE }; private _objectType = if (_object isEqualType objNull) then { typeOf _object } else { _object }; -private _cachedValue = GVAR(vehicleIconCache) getVariable _objectType; +private _cachedValue = GVAR(vehicleIconCache) get _objectType; if (isNil "_cachedValue") then { private _vehicleValue = getText (configfile >> "CfgVehicles" >> _objectType >> "icon"); private _vehicleIconValue = getText (configfile >> "CfgVehicleIcons" >> _vehicleValue); if (_vehicleIconValue == "") then { - if (_vehicleValue != "" && {((toLower _vehicleValue) find ".paa") > -1}) then { + if (_vehicleValue != "" && {((toLowerANSI _vehicleValue) find ".paa") > -1}) then { _cachedValue = _vehicleValue; } else { _cachedValue = DEFAULT_TEXTURE; @@ -41,7 +41,7 @@ if (isNil "_cachedValue") then { _cachedValue = _vehicleIconValue; }; - GVAR(vehicleIconCache) setVariable [_objectType, _cachedValue]; + GVAR(vehicleIconCache) set [_objectType, _cachedValue]; }; _cachedValue diff --git a/addons/common/functions/fnc_getVehicleUAVCrew.sqf b/addons/common/functions/fnc_getVehicleUAVCrew.sqf index 45d151bc30..f991e08d57 100644 --- a/addons/common/functions/fnc_getVehicleUAVCrew.sqf +++ b/addons/common/functions/fnc_getVehicleUAVCrew.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns array of uav dummy ais. @@ -17,4 +17,4 @@ params [["_vehicle", objNull, [objNull]]]; -crew _vehicle select {getText (configFile >> "CfgVehicles" >> typeOf _x >> "simulation") == "UAVPilot"} // return +(crew _vehicle) select {unitIsUAV _x} // return diff --git a/addons/common/functions/fnc_getVersion.sqf b/addons/common/functions/fnc_getVersion.sqf index 8f9e39e360..3908cd3050 100644 --- a/addons/common/functions/fnc_getVersion.sqf +++ b/addons/common/functions/fnc_getVersion.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Get the version number of the current ACE build. @@ -15,4 +15,4 @@ * Public: Yes */ -getText (configFile >> "CfgPatches" >> "ACE_main" >> "version") // return +getText (configFile >> "CfgPatches" >> "ACE_main" >> "versionStr") // return diff --git a/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf b/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf index 83df3782e4..2370a19e69 100644 --- a/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf +++ b/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get local players weapon direction and slope. diff --git a/addons/common/functions/fnc_getWeaponIndex.sqf b/addons/common/functions/fnc_getWeaponIndex.sqf index b4e94e678f..f6077806e1 100644 --- a/addons/common/functions/fnc_getWeaponIndex.sqf +++ b/addons/common/functions/fnc_getWeaponIndex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the index of the weapon. diff --git a/addons/common/functions/fnc_getWeaponModes.sqf b/addons/common/functions/fnc_getWeaponModes.sqf index 93a8614f7f..c1ca241cab 100644 --- a/addons/common/functions/fnc_getWeaponModes.sqf +++ b/addons/common/functions/fnc_getWeaponModes.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the available firing modes of a weapon. Will ignore the AI helper modes. @@ -29,7 +29,6 @@ private _modes = []; if (_x == "this") then { _modes pushBack _weapon; }; - false -} count getArray (_config >> "modes"); +} forEach getArray (_config >> "modes"); _modes diff --git a/addons/common/functions/fnc_getWeaponMuzzles.sqf b/addons/common/functions/fnc_getWeaponMuzzles.sqf index 264ad2b405..11fffaf196 100644 --- a/addons/common/functions/fnc_getWeaponMuzzles.sqf +++ b/addons/common/functions/fnc_getWeaponMuzzles.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the muzzles of a weapon. diff --git a/addons/common/functions/fnc_getWeaponState.sqf b/addons/common/functions/fnc_getWeaponState.sqf index 219f52d369..2fadbd23ea 100644 --- a/addons/common/functions/fnc_getWeaponState.sqf +++ b/addons/common/functions/fnc_getWeaponState.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Return current state of the weapon. Attachments and magazines with ammo. @@ -42,7 +42,6 @@ private _ammo = _muzzles apply {0}; _ammo set [_index, _x select 1]; }; }; - false -} count magazinesAmmoFull _unit; +} forEach magazinesAmmoFull _unit; [_attachments, _muzzles, _magazines, _ammo]; diff --git a/addons/common/functions/fnc_getWeaponType.sqf b/addons/common/functions/fnc_getWeaponType.sqf index 1b3e8fd331..527ce7c893 100644 --- a/addons/common/functions/fnc_getWeaponType.sqf +++ b/addons/common/functions/fnc_getWeaponType.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check what kind of weapon the given class name is. diff --git a/addons/common/functions/fnc_getWeight.sqf b/addons/common/functions/fnc_getWeight.sqf index 5fc92b7703..300a74d382 100644 --- a/addons/common/functions/fnc_getWeight.sqf +++ b/addons/common/functions/fnc_getWeight.sqf @@ -1,14 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns the weight (from the loadAbs command) in lbs/kg (based on user option) * * Arguments: * 0: The Unit (usually the player) - * 1: Force a return type + * 1: Return imperial units * * Return Value: - * The return value + * Weight string * * Example: * [player] call ace_common_fnc_getWeight diff --git a/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf new file mode 100644 index 0000000000..2194c2aca0 --- /dev/null +++ b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -0,0 +1,104 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Returns the wheel hitpoints and their selections. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * 0: Wheel hitpoints + * 1: Wheel hitpoint selections + * + * Example: + * cursorObject call ace_common_fnc_getWheelHitPointsWithSelections + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("params",_vehicle); + +// TODO: Fix for GM vehicles +GVAR(wheelSelections) getOrDefaultCall [typeOf _vehicle, { + // Get the vehicles wheel config + private _wheels = configOf _vehicle >> "Wheels"; + + if (isClass _wheels) then { + // Get all hitpoints and selections + (getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; + + // Get all wheels and read selections from config + _wheels = "true" configClasses _wheels; + + private _wheelHitPoints = []; + private _wheelHitPointSelections = []; + + { + private _wheelName = configName _x; + private _wheelCenter = getText (_x >> "center"); + private _wheelBone = getText (_x >> "boneName"); + private _wheelBoneNameResized = _wheelBone select [0, 9]; // Count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. + + TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); + + private _wheelHitPoint = ""; + private _wheelHitPointSelection = ""; + + // Commy's orginal method + { + if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. + _wheelHitPoint = _hitPoints select _forEachIndex; + _wheelHitPointSelection = _hitPointSelections select _forEachIndex; + TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); + }; + } forEach _hitPointSelections; + + + if (_vehicle isKindOf "Car") then { + // Backup method, search for the closest hitpoint to the wheel's center selection pos. + // Ref #2742 - RHS's HMMWV + if (_wheelHitPoint == "") then { + private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + if (_wheelCenterPos isEqualTo [0, 0, 0]) exitWith {TRACE_1("no center?",_wheelCenter);}; + + + private _bestDist = 99; + private _bestIndex = -1; + { + if (_x != "") then { + // Filter out things that definitly aren't wheeels (#3759) + if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; + private _xPos = _vehicle selectionPosition _x; + if (_xPos isEqualTo [0, 0, 0]) exitWith {}; + private _xDist = _wheelCenterPos distance _xPos; + if (_xDist < _bestDist) then { + _bestIndex = _forEachIndex; + _bestDist = _xDist; + }; + }; + } forEach _hitPointSelections; + + TRACE_2("closestPoint",_bestDist,_bestIndex); + if (_bestIndex != -1) then { + _wheelHitPoint = _hitPoints select _bestIndex; + _wheelHitPointSelection = _hitPointSelections select _bestIndex; + TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); + }; + }; + }; + + if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { + _wheelHitPoints pushBack _wheelHitPoint; + _wheelHitPointSelections pushBack _wheelHitPointSelection; + }; + } forEach _wheels; + + [_wheelHitPoints, _wheelHitPointSelections] + } else { + // Exit with nothing if the vehicle has no wheels class + TRACE_1("No Wheels",_wheels); + + [[], []] + } +}, true] // return diff --git a/addons/common/functions/fnc_getWindDirection.sqf b/addons/common/functions/fnc_getWindDirection.sqf index cb10e18f85..d34df2a529 100644 --- a/addons/common/functions/fnc_getWindDirection.sqf +++ b/addons/common/functions/fnc_getWindDirection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get the compass direction the wind is blowing from. diff --git a/addons/common/functions/fnc_getZoom.sqf b/addons/common/functions/fnc_getZoom.sqf index 26144da81e..2b79ac9cf1 100644 --- a/addons/common/functions/fnc_getZoom.sqf +++ b/addons/common/functions/fnc_getZoom.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns a value depending on current zoom level. diff --git a/addons/common/functions/fnc_goKneeling.sqf b/addons/common/functions/fnc_goKneeling.sqf index e9317cc74e..303a413385 100644 --- a/addons/common/functions/fnc_goKneeling.sqf +++ b/addons/common/functions/fnc_goKneeling.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Move unit to kneeling position (only if not yet prone and not underwater). @@ -18,7 +18,7 @@ params ["_unit"]; // Animation changes even inside vehicle post-1.60 -if (stance _unit == "PRONE" || {vehicle _unit != _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; +if (stance _unit == "PRONE" || {!isNull objectParent _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; [ _unit, diff --git a/addons/common/functions/fnc_hadamardProduct.sqf b/addons/common/functions/fnc_hadamardProduct.sqf index 07295dcef9..7d5d6557ae 100644 --- a/addons/common/functions/fnc_hadamardProduct.sqf +++ b/addons/common/functions/fnc_hadamardProduct.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Returns the Hadamard Product of two vectors. diff --git a/addons/common/functions/fnc_handleEngine.sqf b/addons/common/functions/fnc_handleEngine.sqf index 40574c69c6..442c800d28 100644 --- a/addons/common/functions/fnc_handleEngine.sqf +++ b/addons/common/functions/fnc_handleEngine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Blocks turning on the vehicles engine if set by the status effect handler. diff --git a/addons/common/functions/fnc_handleModifierKey.sqf b/addons/common/functions/fnc_handleModifierKey.sqf index 1440a7849e..1c7c968149 100644 --- a/addons/common/functions/fnc_handleModifierKey.sqf +++ b/addons/common/functions/fnc_handleModifierKey.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles key down event for modifier key. diff --git a/addons/common/functions/fnc_handleModifierKeyUp.sqf b/addons/common/functions/fnc_handleModifierKeyUp.sqf index 9ab3cadf7d..2047e21036 100644 --- a/addons/common/functions/fnc_handleModifierKeyUp.sqf +++ b/addons/common/functions/fnc_handleModifierKeyUp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles key up event for modifier key. diff --git a/addons/common/functions/fnc_hasHatch.sqf b/addons/common/functions/fnc_hasHatch.sqf index 90053f43d9..5a2157d1ae 100644 --- a/addons/common/functions/fnc_hasHatch.sqf +++ b/addons/common/functions/fnc_hasHatch.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if unit is in a vehicle position where it can turn in or out. @@ -21,7 +21,7 @@ private _vehicle = vehicle _unit; if (_unit == _vehicle) exitWith {false}; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; if (getNumber (_config >> "hideProxyInCombat") != 1) exitWith {false}; diff --git a/addons/common/functions/fnc_hasItem.sqf b/addons/common/functions/fnc_hasItem.sqf index 9ae4e7ec63..f446c5dac0 100644 --- a/addons/common/functions/fnc_hasItem.sqf +++ b/addons/common/functions/fnc_hasItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if unit has item. Note: case-sensitive. diff --git a/addons/common/functions/fnc_hasMagazine.sqf b/addons/common/functions/fnc_hasMagazine.sqf index fceee87c11..7874bcbd16 100644 --- a/addons/common/functions/fnc_hasMagazine.sqf +++ b/addons/common/functions/fnc_hasMagazine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if given unit has a magazine of given classname diff --git a/addons/common/functions/fnc_hasZeusAccess.sqf b/addons/common/functions/fnc_hasZeusAccess.sqf new file mode 100644 index 0000000000..2ac1f1efb3 --- /dev/null +++ b/addons/common/functions/fnc_hasZeusAccess.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Check if current player has Zeus access + * + * Arguments: + * None + * + * Return Value: + * Has Zeus + * + * Example: + * call ace_common_fnc_hasZeusAccess + * + * Public: Yes + */ + +// Use of player is intentional +!isNull getAssignedCuratorLogic player // return diff --git a/addons/common/functions/fnc_headBugFix.sqf b/addons/common/functions/fnc_headBugFix.sqf index edea791f24..838f48c89e 100644 --- a/addons/common/functions/fnc_headBugFix.sqf +++ b/addons/common/functions/fnc_headBugFix.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: rocko * Fixes animation issues that may get you stuck @@ -25,6 +25,8 @@ private _anim = animationState _unit; if (_unit != vehicle _unit || {!([_unit, objNull, ["isNotSitting"]] call FUNC(canInteractWith))}) exitWith {false}; +["ace_headBugFix", true] call FUNC(setDisableUserInputStatus); + private _pos = getPosATL _unit; private _dir = getDir _unit; @@ -47,4 +49,7 @@ deleteVehicle _dummy; [_unit, "headBugFix"] call FUNC(unhideUnit); titleCut ["", "PLAIN"]; + +["ace_headBugFix", false] call FUNC(setDisableUserInputStatus); + true diff --git a/addons/common/functions/fnc_hideUnit.sqf b/addons/common/functions/fnc_hideUnit.sqf index e67f68dcc3..6c81729dde 100644 --- a/addons/common/functions/fnc_hideUnit.sqf +++ b/addons/common/functions/fnc_hideUnit.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike (based on muteUnit) + * Author: kymckay (based on muteUnit) * Globally hides a unit. This allows the handling of more than one reason to hide an object globally. * * Arguments: diff --git a/addons/common/functions/fnc_inTransitionAnim.sqf b/addons/common/functions/fnc_inTransitionAnim.sqf index 5999bcbe27..bd731f4be6 100644 --- a/addons/common/functions/fnc_inTransitionAnim.sqf +++ b/addons/common/functions/fnc_inTransitionAnim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if given unit is in a transitional animation diff --git a/addons/common/functions/fnc_interpolateFromArray.sqf b/addons/common/functions/fnc_interpolateFromArray.sqf index 851d368d37..184ccba765 100644 --- a/addons/common/functions/fnc_interpolateFromArray.sqf +++ b/addons/common/functions/fnc_interpolateFromArray.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Interpolates between two set points in a curve. diff --git a/addons/common/functions/fnc_isAwake.sqf b/addons/common/functions/fnc_isAwake.sqf index 5a59a3cb69..f564e5e872 100644 --- a/addons/common/functions/fnc_isAwake.sqf +++ b/addons/common/functions/fnc_isAwake.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if unit is awake. Will be false when death or unit is unconscious. diff --git a/addons/common/functions/fnc_isEOD.sqf b/addons/common/functions/fnc_isEOD.sqf index 303b258cb5..f2ec119d23 100644 --- a/addons/common/functions/fnc_isEOD.sqf +++ b/addons/common/functions/fnc_isEOD.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth de Wet (LH) * Checks whether the passed unit is an explosive specialist. diff --git a/addons/common/functions/fnc_isEngineer.sqf b/addons/common/functions/fnc_isEngineer.sqf index 1805bb50e5..f01472dc02 100644 --- a/addons/common/functions/fnc_isEngineer.sqf +++ b/addons/common/functions/fnc_isEngineer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: marc_book, edited by commy2 * Checks if a unit is an engineer. diff --git a/addons/common/functions/fnc_isFeatureCameraActive.sqf b/addons/common/functions/fnc_isFeatureCameraActive.sqf deleted file mode 100644 index 24ea0667be..0000000000 --- a/addons/common/functions/fnc_isFeatureCameraActive.sqf +++ /dev/null @@ -1,39 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Sniperwolf572 - * Checks if one of the following common feature cameras is active: - * - * - Curator - * - ACE Spectator - * - Arsenal camera (BIS_fnc_arsenal) - * - Nexus Spectator (BIS_fnc_EGSpectator) - * - Establishing shot (BIS_fnc_establishingShot) - * - Splendid camera (BIS_fnc_camera) - * - Animation viewer (BIS_fnc_animViewer) - * - Classic camera (BIS_fnc_cameraOld) - * - * Arguments: - * 0: None - * - * Return Value: - * A feature camera is active - * - * Example: - * [] call ace_common_fnc_isFeatureCameraActive - * - * Public: Yes - */ - -ACE_DEPRECATED(QFUNC(isFeatureCameraActive),"3.14.0","CBA_fnc_getActiveFeatureCamera"); - -!( - isNull curatorCamera && // Curator - {!GETMVAR(EGVAR(spectator,isSet),false)} && // ACE Spectator - {GETMVAR(EGVAR(huntir,stop),true)} && // ACE Hunt IR - {isNull GETMVAR(BIS_EGSpectatorCamera_camera, objNull)} && // BIS Nexus Spectator - {isNull GETUVAR(BIS_fnc_arsenal_cam, objNull)} && // Arsenal camera - {isNull GETMVAR(BIS_fnc_establishingShot_fakeUAV, objNull)} && // Establishing shot camera - {isNull GETMVAR(BIS_fnc_camera_cam, objNull)} && // Splendid camera - {isNull GETUVAR(BIS_fnc_animViewer_cam, objNull)} && // Animation viewer camera - {isNull GETMVAR(BIS_DEBUG_CAM, objNull)} // Classic camera -) // return diff --git a/addons/common/functions/fnc_isInBuilding.sqf b/addons/common/functions/fnc_isInBuilding.sqf index 4b843fcea4..a6813ec4f3 100644 --- a/addons/common/functions/fnc_isInBuilding.sqf +++ b/addons/common/functions/fnc_isInBuilding.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit is in a building. Will return true if the unit is sitting in a bush. diff --git a/addons/common/functions/fnc_isMedic.sqf b/addons/common/functions/fnc_isMedic.sqf index 9618a15548..a5a70c6443 100644 --- a/addons/common/functions/fnc_isMedic.sqf +++ b/addons/common/functions/fnc_isMedic.sqf @@ -1,12 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Check if a unit is a medic * * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * Unit is medic * * Example: @@ -17,6 +17,6 @@ params ["_unit"]; -private _isMedic = _unit getVariable [QEGVAR(medical,medicClass), getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "attendant")]; +private _isMedic = _unit getVariable [QEGVAR(medical,medicClass), getNumber (configOf _unit >> "attendant")]; _isMedic > 0 diff --git a/addons/common/functions/fnc_isModLoaded.sqf b/addons/common/functions/fnc_isModLoaded.sqf index b69086e39d..b070b39b38 100644 --- a/addons/common/functions/fnc_isModLoaded.sqf +++ b/addons/common/functions/fnc_isModLoaded.sqf @@ -1,20 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal - * Check in cfgPatches if modification is loaded + * Author: Glowbal, Grim + * Check in CfgPatches if modification is loaded * * Arguments: - * 0: Mod Name or Classname of the mod in cfgPatches + * 0: Classname of the mod in CfgPatches * * Return Value: - * if modification is loaded + * If modification is loaded * * Example: - * ["class"] call ace_common_fnc_isModLoaded + * "class" call ace_common_fnc_isModLoaded * * Public: Yes */ params [["_modName", "", [""]]]; -isClass (configFile >> "CfgPatches" >> _modName) // return +GVAR(isModLoadedCache) getOrDefaultCall [toLowerANSI _modName, {isClass (configFile >> "CfgPatches" >> _modName)}, true] diff --git a/addons/common/functions/fnc_isPlayer.sqf b/addons/common/functions/fnc_isPlayer.sqf index 8aabbd3bc0..ae5dc72197 100644 --- a/addons/common/functions/fnc_isPlayer.sqf +++ b/addons/common/functions/fnc_isPlayer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578, commy2, akalegman * Checks if a unit is a player / curator controlled unit. diff --git a/addons/common/functions/fnc_isSwimming.sqf b/addons/common/functions/fnc_isSwimming.sqf index c7b290a65c..f190284503 100644 --- a/addons/common/functions/fnc_isSwimming.sqf +++ b/addons/common/functions/fnc_isSwimming.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: das attorney, Jonpas * Check if unit is swimming (surface swimming or diving). diff --git a/addons/common/functions/fnc_lightIntensityFromObject.sqf b/addons/common/functions/fnc_lightIntensityFromObject.sqf index 246424ae4d..38895557ad 100644 --- a/addons/common/functions/fnc_lightIntensityFromObject.sqf +++ b/addons/common/functions/fnc_lightIntensityFromObject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Calculate light intensity object 1 recieves from object 2 @@ -30,8 +30,6 @@ if (_lightSource isKindOf "CAManBase") then { private _flashlight = (_lightSource weaponAccessories _weapon) select 1; - if (getNumber (configFile >> "CfgWeapons" >> _flashlight >> "ACE_laserpointer") > 0) exitWith {}; // Red = 1, Green = 2 - private _properties = [[_flashlight], FUNC(getLightPropertiesWeapon), uiNamespace, format [QEGVAR(cache,%1_%2), QUOTE(DFUNC(getLightPropertiesWeapon)), _flashlight], 1E11] call FUNC(cachedCall); //_properties = [_flashlight] call FUNC(getLightPropertiesWeapon); @@ -82,7 +80,7 @@ if (_lightSource isKindOf "CAManBase") then { if (isCollisionLightOn _lightSource) then { private _markerLights = [ _lightSource, - {configProperties [configFile >> "CfgVehicles" >> typeOf _this >> "MarkerLights", "isClass _x", true]}, + {configProperties [configOf _this >> "MarkerLights", "isClass _x", true]}, uiNamespace, format [QEGVAR(cache,MarkerLights_%1), typeOf _lightSource], 1E11 diff --git a/addons/common/functions/fnc_loadPerson.sqf b/addons/common/functions/fnc_loadPerson.sqf index 466387cc72..f8fe96d17c 100644 --- a/addons/common/functions/fnc_loadPerson.sqf +++ b/addons/common/functions/fnc_loadPerson.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Loads a specified unit into any nearby vehicle, or _vehicle parameter. @@ -7,6 +7,8 @@ * 0: Unit that will load * 1: Unit to be loaded * 2: Vehicle that the unit will be loaded in (default: objNull) + * 3: Preferred seats + * 4: Reverse fill * * Return Value: * Vehicle that the unitToBeloaded has been loaded in. Returns objNull if function failed @@ -19,9 +21,10 @@ #define GROUP_SWITCH_ID QFUNC(loadPerson) -params ["_caller", "_unit", ["_vehicle", objNull]]; +params ["_caller", "_unit", ["_vehicle", objNull], ["_preferredSeats", []], ["_reverseFill", false]]; +TRACE_5("loadPerson",_caller,_unit,_vehicle,_preferredSeats,_reverseFill); -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 { @@ -29,8 +32,17 @@ if (isNull _vehicle) then { }; if (!isNull _vehicle) then { - [_unit, true, GROUP_SWITCH_ID, side group _caller] call FUNC(switchToGroupSide); - ["ace_loadPersonEvent", [_unit, _vehicle, _caller], _unit] call CBA_fnc_targetEvent; + switch (true) do { + case ((crew _vehicle isEqualTo []) && {side group _caller != side group _unit}): { + [_unit, true, GROUP_SWITCH_ID, side group _caller] call FUNC(switchToGroupSide); + }; + case (side group _vehicle != side group _unit): { + [_unit, true, GROUP_SWITCH_ID, side group _vehicle] call FUNC(switchToGroupSide); + }; + }; + + TRACE_5("sending ace_loadPersonEvent",_unit,_vehicle,_caller,_preferredSeats,_reverseFill); + ["ace_loadPersonEvent", [_unit, _vehicle, _caller, _preferredSeats, _reverseFill], _unit] call CBA_fnc_targetEvent; }; _vehicle diff --git a/addons/common/functions/fnc_loadPersonLocal.sqf b/addons/common/functions/fnc_loadPersonLocal.sqf index 109e7e8e77..8288f13924 100644 --- a/addons/common/functions/fnc_loadPersonLocal.sqf +++ b/addons/common/functions/fnc_loadPersonLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Load a person, local @@ -7,6 +7,8 @@ * 0: unit to be loaded * 1: vehicle that will beloaded * 2: caller that will load + * 3: preferred seats + * 4: reverse fill * * Return Value: * None @@ -17,47 +19,72 @@ * Public: Yes */ -params ["_unit", "_vehicle", "_caller"]; - -// if (!alive _unit) then { -// _unit = [_unit, _caller] call makeCopyOfBody; //func does not exist -// }; +params ["_unit", "_vehicle", ["_caller", objNull], ["_preferredSeats", []], ["_reverseFill", false]]; +TRACE_5("loadPersonLocal",_unit,_vehicle,_caller,_preferredSeats,_reverseFill); private _slotsOpen = false; - -if (_vehicle emptyPositions "cargo" > 0) then { - _unit moveInCargo _vehicle; - _slotsOpen = true; +if ((_vehicle emptyPositions "cargo" > 0) && {!(_unit getVariable ['ACE_isUnconscious', false]) || {(getNumber (configOf _vehicle >> "ejectDeadCargo")) == 0}}) then { + if (_preferredSeats isNotEqualTo []) then { + private _taken = []; + { + _taken pushBackUnique (_vehicle getCargoIndex _x); + } forEach crew _vehicle; + private _preferredSeats = _preferredSeats - _taken; + if (count _preferredSeats > 0) then { + _unit moveInCargo [_vehicle, _preferredSeats select 0]; + TRACE_2("moveInCargo",_vehicle,_preferredSeats select 0); + _slotsOpen = true; + }; + }; + if (!_slotsOpen) then { + private _cargoSeats = fullCrew [_vehicle, "cargo", true]; + // FFV cargo seats are empty cargo positions but are not returned by fullCrew "cargo" + if (_cargoSeats isEqualTo []) then { + _cargoSeats = (fullCrew [_vehicle, "turret", true]) select {_x select 4}; + }; + if (_reverseFill) then { + reverse _cargoSeats; + }; + private _index = _cargoSeats findIf {isNull (_x select 0)}; + _unit moveInCargo [_vehicle, (_cargoSeats select _index) select 2]; + TRACE_2("moveInCargo",_vehicle,_index); + _slotsOpen = true; + }; } else { - if (_vehicle emptyPositions "gunner" > 0) then { + // Check if an empty turret is available + // This already excludes FFV seats, which count as cargo positions + private _turrets = fullCrew [_vehicle, "turret", true]; + private _index = _turrets findIf {isNull (_x#0)}; + if (_index >= 0) exitWith { + _unit moveInTurret [_vehicle, _turrets#_index#3]; + TRACE_2("moveInTurret",_vehicle,_turrets#_index#3); + _slotsOpen = true; + }; + + // Check if the commander seat is available + if (_vehicle emptyPositions "commander" > 0) exitWith { + _unit moveInCommander _vehicle; + TRACE_1("moveInCommander",_vehicle); + _slotsOpen = true; + }; + + // Lastly, check if the gunner seat is available + if (_vehicle emptyPositions "gunner" > 0) exitWith { _unit moveInGunner _vehicle; _slotsOpen = true; }; }; -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_moduleCheckPBOs.sqf b/addons/common/functions/fnc_moduleCheckPBOs.sqf index 583441d4d2..2720292c8e 100644 --- a/addons/common/functions/fnc_moduleCheckPBOs.sqf +++ b/addons/common/functions/fnc_moduleCheckPBOs.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Initializes the check-PBOs module. diff --git a/addons/common/functions/fnc_moduleLSDVehicles.sqf b/addons/common/functions/fnc_moduleLSDVehicles.sqf index 97ce3833eb..35e1f07eba 100644 --- a/addons/common/functions/fnc_moduleLSDVehicles.sqf +++ b/addons/common/functions/fnc_moduleLSDVehicles.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, joko // Jonas * Nothing to see here, move along. @@ -17,19 +17,18 @@ params ["", "_units", "_activated"]; -if !(_activated) exitWith {}; +if (!_activated || {GVAR(epilepsyFriendlyMode)}) exitWith {}; if (isNil QGVAR(LSD_Vehicles)) then { GVAR(LSD_Vehicles) = []; }; { - _hSCount = count (getArray (configFile >> "CfgVehicles" >> typeOf _x >> "hiddenSelections")); + _hSCount = count (getArray (configOf _x >> "hiddenSelections")); if (_hSCount > 0) then { GVAR(LSD_Vehicles) pushBack [_x, _hSCount]; }; - nil -} count _units; +} forEach _units; if (isNil QGVAR(LSD_Colors)) then { GVAR(LSD_Colors) = [ @@ -51,8 +50,7 @@ if (isNil QGVAR(LSD_PFH)) then { for "_i" from 0 to (_hSCount - 1) do { _vehicle setObjectTexture [_i, GVAR(LSD_Colors) select _index]; }; - nil - } count GVAR(LSD_Vehicles); + } forEach GVAR(LSD_Vehicles); _index = ((_index + 1) % 7) mod count GVAR(LSD_Colors); (_this select 0) set [0, _index]; diff --git a/addons/common/functions/fnc_monitor.sqf b/addons/common/functions/fnc_monitor.sqf index 17d3087c53..d6fd5c1330 100644 --- a/addons/common/functions/fnc_monitor.sqf +++ b/addons/common/functions/fnc_monitor.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * hint retun value of given function every frame * * Arguments: - * + * 0: Code to monitor * * Return Value: * None diff --git a/addons/common/functions/fnc_muteUnit.sqf b/addons/common/functions/fnc_muteUnit.sqf index fe65a56492..392f7ed61a 100644 --- a/addons/common/functions/fnc_muteUnit.sqf +++ b/addons/common/functions/fnc_muteUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Mutes the unit. It won't trigger auto generated chat messages either. diff --git a/addons/common/functions/fnc_muteUnitHandleInitPost.sqf b/addons/common/functions/fnc_muteUnitHandleInitPost.sqf index 4681ca73aa..134cc0ee3d 100644 --- a/addons/common/functions/fnc_muteUnitHandleInitPost.sqf +++ b/addons/common/functions/fnc_muteUnitHandleInitPost.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Applies speaker changes on init post. Used because setSpeaker is broken on init. diff --git a/addons/common/functions/fnc_muteUnitHandleRespawn.sqf b/addons/common/functions/fnc_muteUnitHandleRespawn.sqf index b507e7ec1d..6aa878bea5 100644 --- a/addons/common/functions/fnc_muteUnitHandleRespawn.sqf +++ b/addons/common/functions/fnc_muteUnitHandleRespawn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Applies speaker changes on respawn. Used because speaker is respawning breaks the speaker on non-local clients. Also resets the public object variable (broken for JIP clients, that join after respawn) diff --git a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf index 30b0594b30..71f62959b9 100644 --- a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -1,22 +1,33 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Returns a list of vehicles near given unit that the unit can be a passenger in. * * Arguments: * 0: Unit - * 1: Distance + * 1: Distance + * 2: Restriceted to cargo only * * Return Value: * Nearest vehicles with a free seat * * Example: - * [bob] call ace_common_fnc_nearestVehiclesFreeSeat + * [cursorObject] call ace_common_fnc_nearestVehiclesFreeSeat * * Public: Yes */ -params ["_unit", ["_distance", 10]]; +params ["_unit", ["_distance", 10], ["_cargoOnly", false]]; private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance]; -_nearVehicles select {(_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}} +_nearVehicles select { + // Filter cargo seats that will eject unconscious units (e.g. quad bike) + private _canSitInCargo = (!(_unit getVariable ['ACE_isUnconscious', false])) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0}; + ((fullCrew [_x, "", true]) findIf { + _x params ["_body", "_role", "_cargoIndex"]; + (isNull _body) // seat empty + && {_role != "DRIVER"} // not driver seat + && {_canSitInCargo || {_cargoIndex == -1}} // won't be ejected (uncon) + && {(!_cargoOnly) || {_cargoIndex != -1}} // not restricted (captive) + }) > -1 +} diff --git a/addons/common/functions/fnc_numberToDigits.sqf b/addons/common/functions/fnc_numberToDigits.sqf index ff4cd23977..83fad813c8 100644 --- a/addons/common/functions/fnc_numberToDigits.sqf +++ b/addons/common/functions/fnc_numberToDigits.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, SilentSpike + * Author: commy2, kymckay * Transforms a number to an array of the correspondending digits. * * Arguments: * 0: Number to 'digitize' - * 1: Set the minimal length of the returned array. Useful for getting left hand zeroes. , optional + * 1: Set the minimal length of the returned array. Useful for getting left hand zeroes. (default: 1) * * Return Value: * Digits. The maximum count is six digits. @@ -16,7 +16,7 @@ * Public: Yes */ -params ["_number", "_minLength"]; +params ["_number", ["_minLength", 1]]; _number = [_number min 999999, _minLength] call CBA_fnc_formatNumber; diff --git a/addons/common/functions/fnc_numberToDigitsString.sqf b/addons/common/functions/fnc_numberToDigitsString.sqf deleted file mode 100644 index 35b0d0fd9b..0000000000 --- a/addons/common/functions/fnc_numberToDigitsString.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Transforms a number to an string of the correspondending digits. - * - * Arguments: - * 0: Number to 'digitize' - * 1: Set the minimal length of the returned string. Useful for getting left hand zeroes. (Optional) - * - * Return Value: - * Digits. The maximum length is six digits. - * - * Example: - * [5, 5] call ace_common_fnc_numberToDigitsString - * - * Public: Yes - */ - -ACE_DEPRECATED(QFUNC(numberToDigitsString),"3.14.0","CBA_fnc_formatNumber"); - -_this call CBA_fnc_formatNumber diff --git a/addons/common/functions/fnc_numberToString.sqf b/addons/common/functions/fnc_numberToString.sqf index 8d5aaa09a1..bb1c4f7ced 100644 --- a/addons/common/functions/fnc_numberToString.sqf +++ b/addons/common/functions/fnc_numberToString.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Converts a number to a string without losing as much precission as str or format. diff --git a/addons/common/functions/fnc_onAnswerRequest.sqf b/addons/common/functions/fnc_onAnswerRequest.sqf index 5613e5d1bc..f3ab80de17 100644 --- a/addons/common/functions/fnc_onAnswerRequest.sqf +++ b/addons/common/functions/fnc_onAnswerRequest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * N/A diff --git a/addons/common/functions/fnc_owned.sqf b/addons/common/functions/fnc_owned.sqf index e216b10c39..15e8dce3be 100644 --- a/addons/common/functions/fnc_owned.sqf +++ b/addons/common/functions/fnc_owned.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Counterpart of ace_common_fnc_claim. Check if the given object is claimed by another unit. diff --git a/addons/common/functions/fnc_parseList.sqf b/addons/common/functions/fnc_parseList.sqf index d3e2871f44..a559994bfa 100644 --- a/addons/common/functions/fnc_parseList.sqf +++ b/addons/common/functions/fnc_parseList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Jonpas * Makes a list from a string using comma as a delimiter, optionally trim or remove whitespace and check each for object existence. @@ -32,8 +32,7 @@ private _whitespaceList = []; } else { _whitespaceList pushBack ([_x] call CBA_fnc_trim); }; - false -} count _list; +} forEach _list; _list = _whitespaceList; TRACE_1("Whitespace List",_list); @@ -43,11 +42,10 @@ if (_checkNil) then { private _nilCheckedList = []; { - if !(isNil _x) then { + if (!isNil _x) then { _nilCheckedList pushBack (missionNamespace getVariable _x); }; - false - } count _list; + } forEach _list; _list = _nilCheckedList; }; diff --git a/addons/common/functions/fnc_playConfigSound3D.sqf b/addons/common/functions/fnc_playConfigSound3D.sqf index ee8d81f2c9..1069cf0f18 100644 --- a/addons/common/functions/fnc_playConfigSound3D.sqf +++ b/addons/common/functions/fnc_playConfigSound3D.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Plays a sound defined in CfgSounds using playSound3D, with global effect. @@ -22,7 +22,7 @@ params ["_soundClass", "_posASL", "_volume", "_distance"]; private _sound = getArray (configFile >> "CfgSounds" >> _soundClass >> "sound"); if (_sound isEqualTo []) exitWith { - ERROR_1("CfgSounds class [%1] does not exist or contains empty sound array", _soundClass); + ERROR_1("CfgSounds class [%1] does not exist or contains empty sound array",_soundClass); }; TRACE_2("sound",_soundClass,_sound); @@ -35,7 +35,7 @@ ISNILS(_distance,_cfgDistance); _fileName = _fileName select [1]; // add file extension .wss as default -if !(toLower (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { ADD(_fileName,".wss"); }; TRACE_5("vars",_fileName,_posASL,_volume,_pitch,_distance); diff --git a/addons/common/functions/fnc_player.sqf b/addons/common/functions/fnc_player.sqf index 382db0bced..1a5614e44e 100644 --- a/addons/common/functions/fnc_player.sqf +++ b/addons/common/functions/fnc_player.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578, commy2 * Returns the player or curator controlled unit. diff --git a/addons/common/functions/fnc_playerSide.sqf b/addons/common/functions/fnc_playerSide.sqf index 6d42df6511..fe6c6e44eb 100644 --- a/addons/common/functions/fnc_playerSide.sqf +++ b/addons/common/functions/fnc_playerSide.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Return the current side of the player diff --git a/addons/common/functions/fnc_positionToASL.sqf b/addons/common/functions/fnc_positionToASL.sqf index 8d0586e097..b286d2f7ab 100644 --- a/addons/common/functions/fnc_positionToASL.sqf +++ b/addons/common/functions/fnc_positionToASL.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Converts Arma "Position" to ASL diff --git a/addons/common/functions/fnc_progressBar.sqf b/addons/common/functions/fnc_progressBar.sqf index 9b52796569..9b5519c232 100644 --- a/addons/common/functions/fnc_progressBar.sqf +++ b/addons/common/functions/fnc_progressBar.sqf @@ -1,4 +1,5 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* * Author: commy2, Glowbal, PabstMirror * Draw progress bar and execute given function if succesful. @@ -9,9 +10,10 @@ * 1: Arguments, passed to condition, fail and finish * 2: On Finish: Code called or STRING raised as event. * 3: On Failure: Code called or STRING raised as event. - * 4: (Optional) Localized Title - * 5: Code to check each frame (Optional) - * 6: Exceptions for checking EFUNC(common,canInteractWith) (Optional) + * 4: Localized Title (default: "") + * 5: Code to check each frame (default: {true}) + * 6: Exceptions for checking ace_common_fnc_canInteractWith (default: []) + * 7: Create progress bar as dialog, this blocks user input (default: true) * * Return Value: * None @@ -22,13 +24,34 @@ * Public: Yes */ -params ["_totalTime", "_args", "_onFinish", "_onFail", ["_localizedTitle", ""], ["_condition", {true}], ["_exceptions", []]]; +params ["_totalTime", "_args", "_onFinish", "_onFail", ["_localizedTitle", ""], ["_condition", {true}], ["_exceptions", []], ["_dialog", true]]; private _player = ACE_player; //Open Dialog and set the title closeDialog 0; -createDialog QGVAR(ProgressBar_Dialog); +if (_dialog) then { + createDialog QGVAR(ProgressBar_Dialog); +} else { + QGVAR(progressBarDisplay) cutRsc [QGVAR(ProgressBar_Display), "PLAIN"]; +}; + +private _display = uiNamespace getVariable QGVAR(dlgProgress); + +// Ensure CBA keybindings are hooked into the display +_display call (uiNamespace getVariable "CBA_events_fnc_initDisplayCurator"); + +// Hide cursor by using custom transparent cursor +if (_dialog) then { + private _map = _display displayCtrl 101; + _map ctrlMapCursor ["", QGVAR(blank)]; +} else { // Add key handler for ESC to cancel + [DIK_ESCAPE, [false, false, false], { + QGVAR(progressBarDisplay) cutText ["", "PLAIN"]; + [QGVAR(progressBarKeyHandler), "keydown"] call CBA_fnc_removeKeyHandler; + true + }, "keydown", QGVAR(progressBarKeyHandler)] call CBA_fnc_addKeyHandler; +}; (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlSetText _localizedTitle; @@ -44,7 +67,7 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlCommit 0; [{ - (_this select 0) params ["_args", "_onFinish", "_onFail", "_condition", "_player", "_startTime", "_totalTime", "_exceptions"]; + (_this select 0) params ["_args", "_onFinish", "_onFail", "_condition", "_player", "_startTime", "_totalTime", "_exceptions", "_title", "_dialog"]; private _elapsedTime = CBA_missionTime - _startTime; private _errorCode = -1; @@ -62,8 +85,12 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / if !([_player, objNull, _exceptions] call EFUNC(common,canInteractWith)) then { _errorCode = 4; } else { - if (_elapsedTime >= _totalTime) then { - _errorCode = 0; + if (!_dialog && {dialog}) then { + _errorCode = 5; + } else { + if (_elapsedTime >= _totalTime) then { + _errorCode = 0; + }; }; }; }; @@ -75,7 +102,13 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / //Only close dialog if it's the progressBar: if (!isNull (uiNamespace getVariable [QGVAR(ctrlProgressBar), controlNull])) then { - closeDialog 0; + if (_dialog) then { + closeDialog 0; + } else { + QGVAR(progressBarDisplay) cutText ["", "PLAIN"]; + // Remove key handler for non-dialog bar + [QGVAR(progressBarKeyHandler), "keydown"] call CBA_fnc_removeKeyHandler; + }; }; [_this select 1] call CBA_fnc_removePerFrameHandler; @@ -95,6 +128,16 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / }; } else { //Update Progress Bar (ratio of elepased:total) - (uiNamespace getVariable QGVAR(ctrlProgressBar)) progressSetPosition (_elapsedTime / _totalTime); + private _ratio = _elapsedTime / _totalTime; + (uiNamespace getVariable QGVAR(ctrlProgressBar)) progressSetPosition _ratio; + switch (GVAR(progressBarInfo)) do { + case 0: {}; + case 1: { + (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlSetText (_title + format [" (%1", floor (_ratio * 100)] + "%)"); + }; + case 2: { + (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlSetText (_title + " " + format [localize LSTRING(TimeLeft), ceil (_totalTime - _elapsedTime)]); + }; + }; }; -}, 0, [_args, _onFinish, _onFail, _condition, _player, CBA_missionTime, _totalTime, _exceptions]] call CBA_fnc_addPerFrameHandler; +}, 0, [_args, _onFinish, _onFail, _condition, _player, CBA_missionTime, _totalTime, _exceptions, _localizedTitle, _dialog]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/common/functions/fnc_readSettingFromModule.sqf b/addons/common/functions/fnc_readSettingFromModule.sqf index d61671d604..5f9678f97b 100644 --- a/addons/common/functions/fnc_readSettingFromModule.sqf +++ b/addons/common/functions/fnc_readSettingFromModule.sqf @@ -1,5 +1,5 @@ #define DEBUG_MODE_FULL -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Reads a setting value from a module, set it and force it. Logs if the setting is missing from the module. @@ -23,7 +23,7 @@ params ["_logic", "_settingName", "_moduleVariable"]; // Check if the variable is already defined if (isNil _settingName) exitWith { - ERROR_1("readSettingFromModule - param [%1] is not an ace_setting", _settingName); + ERROR_1("readSettingFromModule - param [%1] is not an ace_setting",_settingName); }; // Check if the parameter is defined in the module diff --git a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf index e205fb15bf..7273fc61ca 100644 --- a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf +++ b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Read settins from paramsArray that have a ACE_setting = 1. @@ -32,7 +32,7 @@ TRACE_1("Reading missionConfigFile params",_paramsArray); // Check if the variable is already defined if (isNil _settingName) exitWith { - ERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting", _settingName); + ERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting",_settingName); }; // The setting is not forced, so update the value @@ -47,12 +47,12 @@ TRACE_1("Reading missionConfigFile params",_paramsArray); case (_settingType == "CHECKBOX"): { _settingValue = _settingValue > 0; _validValue = [_settingName, _settingValue] call CBA_settings_fnc_check; - }; + }; // Will not Handle ARRAY,COLOR,STRING??? (bool/scalar covers most important settings) }; if (!_validValue) exitWith { - WARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]", _settingName,_settingValue,_settingType); + WARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]",_settingName,_settingValue,_settingType); }; if ([_settingName, "mission"] call CBA_settings_fnc_isForced) then { diff --git a/addons/common/functions/fnc_receiveRequest.sqf b/addons/common/functions/fnc_receiveRequest.sqf index e2f25ed734..02a9379e6c 100644 --- a/addons/common/functions/fnc_receiveRequest.sqf +++ b/addons/common/functions/fnc_receiveRequest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * N/A @@ -14,7 +14,7 @@ * None * * Example: - * [bob, kevin, "ID", "Message", {Callback}] call ace_common_fnc_recieveRequest + * [bob, kevin, "ID", "Message", {Callback}] call ace_common_fnc_receiveRequest * * Public: No */ @@ -31,9 +31,9 @@ if (isLocalized _requestMessage) then { _requestMessage = format [_requestMessage, [_caller, false, true] call FUNC(getName)]; }; -hint format ["%1", _requestMessage]; // @todo ? +hint str _requestMessage; // @todo ? -if !(isNil QGVAR(RECIEVE_REQUEST_TIME_OUT_SCRIPT)) then { +if (!isNil QGVAR(RECIEVE_REQUEST_TIME_OUT_SCRIPT)) then { terminate GVAR(RECIEVE_REQUEST_TIME_OUT_SCRIPT); }; diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf new file mode 100644 index 0000000000..f1e068c322 --- /dev/null +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -0,0 +1,65 @@ +#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); + +// Setup on first run +if (isNil QGVAR(itemReplacements)) then { + GVAR(itemReplacements) = createHashMap; + GVAR(inheritedReplacements) = []; + GVAR(oldItems) = []; + ["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler; +}; + +// Get config case - if item doesn't exist, "" is returned +if (_oldItem isEqualType "") then { + _oldItem = _oldItem call FUNC(getConfigName); +}; + +if (_oldItem isEqualTo "") exitWith { + ERROR("Item doesn't exist"); +}; + +// Save item replacement +// $ prefix is used for types (numbers) and replacements with inheritance +if (_replaceInherited) then { + _oldItem = "$" + _oldItem; + GVAR(inheritedReplacements) pushBack _oldItem; +}; +if (_oldItem isEqualType 0) then { + _oldItem = "$" + str _oldItem; +}; +if (_newItems isEqualType "") then { + _newItems = [_newItems]; +}; + +private _oldReplacements = GVAR(itemReplacements) getOrDefault [_oldItem, [], true]; +_oldReplacements append _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. + [LINKFUNC(replaceRegisteredItems), [ACE_player]] call CBA_fnc_execNextFrame; +}; diff --git a/addons/common/functions/fnc_removeActionEventHandler.sqf b/addons/common/functions/fnc_removeActionEventHandler.sqf index e536adc191..6d5b0711c3 100644 --- a/addons/common/functions/fnc_removeActionEventHandler.sqf +++ b/addons/common/functions/fnc_removeActionEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove an addAction event from a unit. diff --git a/addons/common/functions/fnc_removeActionMenuEventHandler.sqf b/addons/common/functions/fnc_removeActionMenuEventHandler.sqf index ed072db89a..cb07949188 100644 --- a/addons/common/functions/fnc_removeActionMenuEventHandler.sqf +++ b/addons/common/functions/fnc_removeActionMenuEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove an addAction menu event from a unit. diff --git a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf index 4538a67fb0..6c5e8b56b6 100644 --- a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove a condition that gets checked by ace_common_fnc_canInteractWith. @@ -17,7 +17,7 @@ params ["_conditionName"]; -_conditionName = toLower _conditionName; +_conditionName = toLowerANSI _conditionName; private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; diff --git a/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf b/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf index 2a95b0f4d7..950ac5002e 100644 --- a/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf +++ b/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove a map marker creation event handler. diff --git a/addons/common/functions/fnc_removeSpecificMagazine.sqf b/addons/common/functions/fnc_removeSpecificMagazine.sqf index 141aa28526..8a93e25ef0 100644 --- a/addons/common/functions/fnc_removeSpecificMagazine.sqf +++ b/addons/common/functions/fnc_removeSpecificMagazine.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain - * Removes a magazine from the unit that has an specific ammo count + * Removes a magazine from the unit or object that has a specific ammo count * * Arguments: * 0: Unit @@ -9,7 +9,7 @@ * 2: Ammo count * * Return Value: - * None + * Magazine Removed * * Example: * [bob, "magazine", 5] call ace_common_fnc_removeSpecificMagazine @@ -21,62 +21,24 @@ params [["_unit", objNull, [objNull]], ["_magazineType", "", [""]], ["_ammoCount private _isRemoved = false; -// Check uniform -private _magazines = magazinesAmmoCargo uniformContainer _unit select {_x select 0 == _magazineType}; -private _index = _magazines find [_magazineType, _ammoCount]; +private _fnc_removeMagazine = { + params ["_container", "_magArray"]; + _magArray params ["_magazineType", "_ammoCount"]; -if (_index > -1) exitWith { - { - _unit removeItemFromUniform (_x select 0); - false - } count _magazines; - - { - if (!_isRemoved && (_x isEqualTo [_magazineType,_ammoCount])) then { - _isRemoved = true; - } else { - (uniformContainer _unit) addMagazineAmmoCargo [_x select 0, 1, _x select 1]; - }; - false - } count _magazines; + if (_magArray in (magazinesAmmoCargo _container)) exitWith { + _container addMagazineAmmoCargo [_magazineType, -1, _ammoCount]; + true + }; + false }; -// Check vest -_magazines = magazinesAmmoCargo vestContainer _unit select {_x select 0 == _magazineType}; -_index = _magazines find [_magazineType, _ammoCount]; - -if (_index > -1) exitWith { - { - _unit removeItemFromVest (_x select 0); - false - } count _magazines; - - { - if (!_isRemoved && (_x isEqualTo [_magazineType,_ammoCount])) then { - _isRemoved = true; - } else { - (vestContainer _unit) addMagazineAmmoCargo [_x select 0, 1, _x select 1]; - }; - false - } count _magazines; +private _containerArray = [_unit]; +if (_unit isKindOf "CAManBase") then { + _containerArray = [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]; }; -// Check backpack -_magazines = magazinesAmmoCargo backpackContainer _unit select {_x select 0 == _magazineType}; -_index = _magazines find [_magazineType, _ammoCount]; +{ + if ([_x, [_magazineType, _ammoCount]] call _fnc_removeMagazine) exitWith {_isRemoved = true}; +} forEach _containerArray; -if (_index > -1) exitWith { - { - _unit removeItemFromBackpack (_x select 0); - false - } count _magazines; - - { - if (!_isRemoved && (_x isEqualTo [_magazineType,_ammoCount])) then { - _isRemoved = true; - } else { - (backpackContainer _unit) addMagazineAmmoCargo [_x select 0, 1, _x select 1]; - }; - false - } count _magazines; -}; +_isRemoved diff --git a/addons/common/functions/fnc_removeSyncedEventHandler.sqf b/addons/common/functions/fnc_removeSyncedEventHandler.sqf index 5e9eb48aa7..615f50ce49 100644 --- a/addons/common/functions/fnc_removeSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_removeSyncedEventHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Remove a synced event handler @@ -17,13 +17,13 @@ params ["_name"]; -if !([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler).", _name); +if !(_name in GVAR(syncedEvents)) exitWith { + ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler)",_name); false }; -private _data = [GVAR(syncedEvents), _name] call CBA_fnc_hashGet; +private _data = GVAR(syncedEvents) get _name; _data params ["", "", "", "_eventId"]; [_eventId] call CBA_fnc_removeEventHandler; -[GVAR(syncedEvents), _name] call CBA_fnc_hashRem; +GVAR(syncedEvents) deleteAt _name; diff --git a/addons/common/functions/fnc_replaceRegisteredItems.sqf b/addons/common/functions/fnc_replaceRegisteredItems.sqf new file mode 100644 index 0000000000..baa591c8d8 --- /dev/null +++ b/addons/common/functions/fnc_replaceRegisteredItems.sqf @@ -0,0 +1,96 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Handles replacing unit's items with their registered replacements. + * Called by CBA Player Loadout Event, but can be used to replace items on AI. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [ACE_player] call ace_common_fnc_replaceRegisteredItems + * + * Public: Yes + */ +params [["_unit", objNull, [objNull]]]; + +private _items = items _unit; +if (_items isEqualTo GVAR(oldItems)) exitWith {}; + +private _newItems = _items - GVAR(oldItems); +_newItems = _newItems arrayIntersect _newItems; // Get unique items only +if (_newItems isEqualTo []) exitWith { + GVAR(oldItems) = _items; +}; +TRACE_2("replacing",_unit,_newItems); + +if (GVAR(blockItemReplacement)) exitWith { + TRACE_2("blocked delay",_unit,_newItems); + [{!GVAR(blockItemReplacement)}, LINKFUNC(replaceRegisteredItems), _unit] call CBA_fnc_waitUntilAndExecute; +}; + +private _cfgWeapons = configFile >> "CfgWeapons"; // Microoptimization +private _containerItems = [uniformItems _unit, vestItems _unit, backpackItems _unit]; + +for "_i" from 0 to count _newItems - 1 do { + private _item = _newItems#_i; + + private _doReplace = false; + private _replacements = []; + + // Determine replacement items: direct replacements, ... + private _directReplacements = GVAR(itemReplacements) get _item; + if (!isNil "_directReplacements") then { + _doReplace = true; + _replacements append _directReplacements; + }; + + // ... item type replacements ... + private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); + private _typeReplacements = GVAR(itemReplacements) get ("$" + str _type); + if (!isNil "_typeReplacements") then { + _doReplace = true; + _replacements append _typeReplacements; + }; + + // ... and inherited replacements + { + if (_item isKindOf [_x, _cfgWeapons]) then { + private _inheritedReplacements = GVAR(itemReplacements) get _x; + if (!isNil "_inheritedReplacements") then { + _doReplace = true; + _replacements append _inheritedReplacements; + }; + }; + } forEach GVAR(inheritedReplacements); + + // Replace all items of current class in list + if (_doReplace) then { + TRACE_2("replace",_item,_replacements); + _unit removeItems _item; + + if (_replacements isEqualTo []) exitWith {}; + // Get count of item in each container + private _containerCount = _containerItems apply {{_x == _item} count _x}; + TRACE_1("",_containerCount); + + { + if (_x == 0) then {continue}; + private _container = ["uniform", "vest", "backpack"] select _forEachIndex; + for "_j" from 1 to _x do { + { + if ([_unit, _x, 1, _container == "uniform", _container == "vest", _container == "backpack"] call CBA_fnc_canAddItem) then { + [_unit, _x, _container] call FUNC(addToInventory) // add to specific container + } else { + [_unit, _x, ""] call FUNC(addToInventory) // no room, add anywhere + } + } forEach _replacements; + } + } forEach _containerCount; + }; +}; + +GVAR(oldItems) = items _unit; diff --git a/addons/common/functions/fnc_requestCallback.sqf b/addons/common/functions/fnc_requestCallback.sqf index 6729c19a6d..ddd2f89233 100644 --- a/addons/common/functions/fnc_requestCallback.sqf +++ b/addons/common/functions/fnc_requestCallback.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * N/A diff --git a/addons/common/functions/fnc_requestSyncedEvent.sqf b/addons/common/functions/fnc_requestSyncedEvent.sqf index 44b633b9de..8e566c0e67 100644 --- a/addons/common/functions/fnc_requestSyncedEvent.sqf +++ b/addons/common/functions/fnc_requestSyncedEvent.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Send a request to synchronize an event name from the client->server. Execute on client only. diff --git a/addons/common/functions/fnc_resetAllDefaults.sqf b/addons/common/functions/fnc_resetAllDefaults.sqf index dc638e4947..ef74724183 100644 --- a/addons/common/functions/fnc_resetAllDefaults.sqf +++ b/addons/common/functions/fnc_resetAllDefaults.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * reset all variables that have been defined @@ -23,12 +23,11 @@ _unit setVariable ["ACE_isUnconscious", nil, true]; if (isPlayer _unit) then { [true] call FUNC(setVolume); - if !(isNil QGVAR(DISABLE_USER_INPUT_COLLECTION)) then { + if (!isNil QGVAR(DISABLE_USER_INPUT_COLLECTION)) then { // clear all disable user input { [_x, false] call FUNC(setDisableUserInputStatus); - false - } count GVAR(DISABLE_USER_INPUT_COLLECTION); + } forEach GVAR(DISABLE_USER_INPUT_COLLECTION); }; }; @@ -36,5 +35,4 @@ if (isPlayer _unit) then { if !(_x select 4) then { _unit setVariable [_x select 0, nil, _x select 3]; }; - false -} count ([_unit] call FUNC(getAllDefinedSetVariables)); +} forEach ([_unit] call FUNC(getAllDefinedSetVariables)); diff --git a/addons/common/functions/fnc_restoreVariablesJIP.sqf b/addons/common/functions/fnc_restoreVariablesJIP.sqf index 0c0617be77..ac22cd3fa0 100644 --- a/addons/common/functions/fnc_restoreVariablesJIP.sqf +++ b/addons/common/functions/fnc_restoreVariablesJIP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called from respawn eventhandler. Resets all public object namespace variables that are added via FUNC(setVariableJIP). @@ -24,6 +24,4 @@ _respawnVariables pushBack "ACE_PersistentFunctions"; { _unit setVariable [_x, _unit getVariable _x, true]; - false -} count _respawnVariables; -nil +} forEach _respawnVariables; diff --git a/addons/common/functions/fnc_rscObjectHelper.sqf b/addons/common/functions/fnc_rscObjectHelper.sqf new file mode 100644 index 0000000000..95ddb2f74b --- /dev/null +++ b/addons/common/functions/fnc_rscObjectHelper.sqf @@ -0,0 +1,64 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Convert between screen and 3d object coordinates + * + * Arguments: + * 0: Function + * 1: Input array + * 2: Scale (optional: 1) + * + * Return Value: + * Value + * + * Example: + * ["2d", [0,0,0], 1] call ace_common_fnc_rscObjectHelper + * + * Public: No + */ + +params ["_func", "_array", ["_scale", 1]]; + +private _adjustCam = 1; +private _topFOV = getResolution # 6; +private _leftFOV = getResolution # 7; + +private _topLeftX = (_leftFOV-1)*0.5/_leftFOV; +private _bottomRightX = 1-_topLeftX; +private _topLeftY = 0; +private _bottomRightY = 1; + +private _return = []; + +switch (toLowerANSI _func) do { + case ("2d"): { + _array params ["_pointX", "_z", "_pointY"]; + + private _scrX = _pointX * (_bottomRightX - _topLeftX) + _topLeftX; + private _vX = _leftFOV * (_scrX - 0.5) * _adjustCam * _z; + + private _scrY = _pointY * (_bottomRightY - _topLeftY) + _topLeftY; + private _vY = _topFOV * (0.5 - _scrY) * _adjustCam * _z; + + _vX = _vX / _scale; + _vY = _vY / _scale; + + _return = [_vX, _vY, _z]; + }; + case ("3d"): { + _array params ["_vX", "_vY", "_z"]; // z is distance from screen + + _vX = _vX * _scale; + _vY = _vY * _scale; + + private _scrX = _vX / (_leftFOV * _adjustCam * _z) + 0.5; + private _pointX = (_scrX - _topLeftX) / (_bottomRightX - _topLeftX); + + private _scrY = 0.5 - _vY / (_topFOV * _adjustCam * _z); + private _pointY = (_scrY - _topLeftY) / (_bottomRightY - _topLeftY); + + _return = [_pointX, _z, _pointY]; + }; +}; + +_return diff --git a/addons/common/functions/fnc_runAfterSettingsInit.sqf b/addons/common/functions/fnc_runAfterSettingsInit.sqf index f989501dd5..5a731d130d 100644 --- a/addons/common/functions/fnc_runAfterSettingsInit.sqf +++ b/addons/common/functions/fnc_runAfterSettingsInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Executes code after setting are initilized. diff --git a/addons/common/functions/fnc_runTests.sqf b/addons/common/functions/fnc_runTests.sqf index 4e937d87b6..4a449fb7eb 100644 --- a/addons/common/functions/fnc_runTests.sqf +++ b/addons/common/functions/fnc_runTests.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Run test functions. @@ -22,7 +22,7 @@ private _startTime = diag_tickTime; private _fails = []; private _total = 0; -INFO_1("ace_common_fnc_runTests starting for [%1]", _specificTest); +INFO_1("ace_common_fnc_runTests starting for [%1]",_specificTest); { private _testName = configName _x; @@ -31,7 +31,7 @@ INFO_1("ace_common_fnc_runTests starting for [%1]", _specificTest); private _testFile = getText _x; diag_log text format ["----- Starting Testing %1 [%2] -----", _testName, _testFile]; private _return = ([nil] apply (compile preProcessFileLineNumbers _testFile)) select 0; - if ((isNil "_return") || {!(_return isEqualTo true)}) then { + if ((isNil "_return") || {_return isNotEqualTo true}) then { systemChat format ["Test [%1] Failed", _testName]; diag_log text format ["----- Finished Testing %1 [Failed] -----", _testName]; _fails pushBack _testName; @@ -41,8 +41,8 @@ INFO_1("ace_common_fnc_runTests starting for [%1]", _specificTest); }; } forEach (configProperties [configFile >> "ACE_Tests"]); -INFO_1("ace_common_fnc_runTests finished in %1 ms", (1000 * (diag_tickTime - _startTime)) toFixed 1); -INFO_2("[%1 / %2] Tests Passed", (_total - (count _fails)), _total); -if (!(_fails isEqualTo [])) then { - INFO_1("Failed: %1", _fails); +INFO_1("ace_common_fnc_runTests finished in %1 ms",(1000 * (diag_tickTime - _startTime)) toFixed 1); +INFO_2("[%1 / %2] Tests Passed",(_total - (count _fails)),_total); +if (_fails isNotEqualTo []) then { + INFO_1("Failed: %1",_fails); }; diff --git a/addons/common/functions/fnc_sanitizeString.sqf b/addons/common/functions/fnc_sanitizeString.sqf index 3517c5086a..7d0b2dd2f1 100644 --- a/addons/common/functions/fnc_sanitizeString.sqf +++ b/addons/common/functions/fnc_sanitizeString.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain, based on Killzone-Kid code * Removes quotation marks to avoid exploits and optionally html tags from text to avoid conflicts with structured text. @@ -47,7 +47,6 @@ private _array = []; _array pushBack _x; }; }; - false -} count toArray _string; +} forEach toArray _string; toString _array // return diff --git a/addons/common/functions/fnc_sendRequest.sqf b/addons/common/functions/fnc_sendRequest.sqf index cfa52de068..d5ec9643da 100644 --- a/addons/common/functions/fnc_sendRequest.sqf +++ b/addons/common/functions/fnc_sendRequest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Send a request to an unit and execute code based upon results. diff --git a/addons/common/functions/fnc_serverLog.sqf b/addons/common/functions/fnc_serverLog.sqf index 183e110071..0ea811c3c2 100644 --- a/addons/common/functions/fnc_serverLog.sqf +++ b/addons/common/functions/fnc_serverLog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Log a RPT messaged on just the server diff --git a/addons/common/functions/fnc_setAimCoef.sqf b/addons/common/functions/fnc_setAimCoef.sqf index 5680918dfa..8b22831c06 100644 --- a/addons/common/functions/fnc_setAimCoef.sqf +++ b/addons/common/functions/fnc_setAimCoef.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: xrufix, Glowbal * Handle set AimCoef calls. Will use the highest available setting. diff --git a/addons/common/functions/fnc_setApproximateVariablePublic.sqf b/addons/common/functions/fnc_setApproximateVariablePublic.sqf index 562bdfd1c8..ebd4476de5 100644 --- a/addons/common/functions/fnc_setApproximateVariablePublic.sqf +++ b/addons/common/functions/fnc_setApproximateVariablePublic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Publish a variable if it's different enough from the previously published value. @@ -38,4 +38,4 @@ if (abs(_value - _oldValue) < _tolerance) exitWith {}; _object setVariable [_varName, _value, true]; _object setVariable [_oldVarName, _value]; -TRACE_2("Published variable:", _varName, _value); +TRACE_2("Published variable:",_varName,_value); diff --git a/addons/common/functions/fnc_setDead.sqf b/addons/common/functions/fnc_setDead.sqf new file mode 100644 index 0000000000..f6d62abd34 --- /dev/null +++ b/addons/common/functions/fnc_setDead.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Kills a unit without changing visual appearance. + * + * Arguments: + * 0: Unit + * 1: Reason for death (only used if ace_medical is loaded) (default: "") + * 2: Killer (vehicle that killed unit) (default: objNull) + * 3: Instigator (unit who pulled trigger) (default: objNull) + * + * Return Value: + * None + * + * Example: + * [cursorObject, "", player, player] call ace_common_fnc_setDead; + * + * Public: Yes + */ + +params [["_unit", objNull, [objNull]], ["_reason", "", [""]], ["_source", objNull, [objNull]], ["_instigator", objNull, [objNull]]]; + +if (!local _unit) exitWith { + WARNING_1("setDead executed on non-local unit - %1",_this); +}; + +if (GETEGVAR(medical,enabled,false)) then { + [_unit, _reason, _source, _instigator] call EFUNC(medical_status,setDead); +} else { + // From 'ace_medical_status_fnc_setDead': Kill the unit without changing visual appearance + + // (#8803) Reenable damage if disabled to prevent having live units in dead state + // Keep this after death event for compatibility with third party hooks + if (!isDamageAllowed _unit) then { + WARNING_1("setDead executed on unit with damage blocked - %1",_this); + _unit allowDamage true; + }; + + private _currentDamage = _unit getHitPointDamage "HitHead"; + + _unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; + + _unit setHitPointDamage ["HitHead", _currentDamage, true, _source, _instigator]; +}; diff --git a/addons/common/functions/fnc_setDefinedVariable.sqf b/addons/common/functions/fnc_setDefinedVariable.sqf index 4800958048..a9cb8ac595 100644 --- a/addons/common/functions/fnc_setDefinedVariable.sqf +++ b/addons/common/functions/fnc_setDefinedVariable.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * setVariable value diff --git a/addons/common/functions/fnc_setDisableUserInputStatus.sqf b/addons/common/functions/fnc_setDisableUserInputStatus.sqf index 843837caba..8de0a0c72d 100644 --- a/addons/common/functions/fnc_setDisableUserInputStatus.sqf +++ b/addons/common/functions/fnc_setDisableUserInputStatus.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Disables the user input. Works stacked. diff --git a/addons/common/functions/fnc_setHearingCapability.sqf b/addons/common/functions/fnc_setHearingCapability.sqf index 5fdb5b1272..45858278c1 100644 --- a/addons/common/functions/fnc_setHearingCapability.sqf +++ b/addons/common/functions/fnc_setHearingCapability.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Handle set volume calls. Will use the lowest available volume setting. diff --git a/addons/common/functions/fnc_setName.sqf b/addons/common/functions/fnc_setName.sqf index d725dcc30d..1b0a436aee 100644 --- a/addons/common/functions/fnc_setName.sqf +++ b/addons/common/functions/fnc_setName.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Sets the name variable of the object. Used to prevent issues with the name command. diff --git a/addons/common/functions/fnc_setParameter.sqf b/addons/common/functions/fnc_setParameter.sqf index f7b2ca579f..25dc183865 100644 --- a/addons/common/functions/fnc_setParameter.sqf +++ b/addons/common/functions/fnc_setParameter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Sets the value of an ACE_Parameter and makes it public. diff --git a/addons/common/functions/fnc_setPitchBankYaw.sqf b/addons/common/functions/fnc_setPitchBankYaw.sqf index debe133484..8d46c08639 100644 --- a/addons/common/functions/fnc_setPitchBankYaw.sqf +++ b/addons/common/functions/fnc_setPitchBankYaw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Bohemia Interactive edit by KoffeinFlummi * Sets the value of an ACE_Parameter and makes it public. diff --git a/addons/common/functions/fnc_setPlayerOwner.sqf b/addons/common/functions/fnc_setPlayerOwner.sqf index c15974098b..2b37349f9a 100644 --- a/addons/common/functions/fnc_setPlayerOwner.sqf +++ b/addons/common/functions/fnc_setPlayerOwner.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Sets the player's owner id as a variable on his player ojbect. diff --git a/addons/common/functions/fnc_setProne.sqf b/addons/common/functions/fnc_setProne.sqf index f12545290c..20bbbfe550 100644 --- a/addons/common/functions/fnc_setProne.sqf +++ b/addons/common/functions/fnc_setProne.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Force a unit to go prone diff --git a/addons/common/functions/fnc_setSetting.sqf b/addons/common/functions/fnc_setSetting.sqf index a50cf89214..93c6045a6c 100644 --- a/addons/common/functions/fnc_setSetting.sqf +++ b/addons/common/functions/fnc_setSetting.sqf @@ -1,5 +1,5 @@ #define DEBUG_MODE_FULL -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Change the value of an existing setting if it was not previously forced. Force if neccesary. diff --git a/addons/common/functions/fnc_setVariableJIP.sqf b/addons/common/functions/fnc_setVariableJIP.sqf index 857bd1b9b9..36b3d0c3ed 100644 --- a/addons/common/functions/fnc_setVariableJIP.sqf +++ b/addons/common/functions/fnc_setVariableJIP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Sets a public object namespace variable that gets reset with the same value after respawn, so JIP clients keep the value. diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index 067765fc27..678e2bc057 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 and CAA-Picard and joko and PabstMirror * Publish a variable, but wait a certain amount of time before allowing it to be published it again. @@ -34,7 +34,7 @@ if (_object isEqualTo (_object getVariable [format ["ACE_onEmbargo_%1", _varName _object setVariable [_varName, _value, true]; _object setVariable [format ["ACE_onEmbargo_%1", _varName], _object]; -TRACE_2("Starting Embargo", _varName, _delay); +TRACE_2("Starting Embargo",_varName,_delay); [{ params ["_object", "_varName", "_value"]; @@ -43,10 +43,10 @@ TRACE_2("Starting Embargo", _varName, _delay); _object setVariable [format ["ACE_onEmbargo_%1", _varName], nil]; //Remove Embargo private _curValue = _object getVariable _varName; - TRACE_4("End of embargo", _object, _varName, _value, _curValue); + TRACE_4("End of embargo",_object,_varName,_value,_curValue); //If value at start of embargo doesn't equal current, then broadcast and start new embargo - if (!(_value isEqualTo _curValue)) then { + if (_value isNotEqualTo _curValue) then { _this set [2, _curValue]; _this call FUNC(setVariablePublic); }; diff --git a/addons/common/functions/fnc_setVolume.sqf b/addons/common/functions/fnc_setVolume.sqf index 0ab00e26be..1b0378bb78 100644 --- a/addons/common/functions/fnc_setVolume.sqf +++ b/addons/common/functions/fnc_setVolume.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Sets the volume of the game, including third party radio modifications such as TFAR and ACRE. @@ -17,36 +17,32 @@ * Note: Uses player */ -#define MUTED_LEVEL 0.2 +#define MUTED_LEVEL 0.2 #define NORMAL_LEVEL 1 -#define NO_SOUND 0 +#define NO_SOUND 0 -params [["_setVolume", false]]; +params [ + ["_setVolume", false], + ["_unit", player] +]; if (_setVolume) then { // Vanilla Game 2 fadeSound NORMAL_LEVEL; // TFAR - player setVariable ["tf_voiceVolume", NORMAL_LEVEL, true]; - player setVariable ["tf_globalVolume", NORMAL_LEVEL]; - player setVariable ["tf_unable_to_use_radio", false]; + _unit setVariable ["tf_globalVolume", NORMAL_LEVEL]; // ACRE2 if (!isNil "acre_api_fnc_setGlobalVolume") then { [NORMAL_LEVEL^0.33] call acre_api_fnc_setGlobalVolume; }; - player setVariable ["acre_sys_core_isDisabled", false, true]; } else { // Vanilla Game 2 fadeSound MUTED_LEVEL; // TFAR - player setVariable ["tf_voiceVolume", NO_SOUND, true]; - player setVariable ["tf_globalVolume", MUTED_LEVEL]; - player setVariable ["tf_unable_to_use_radio", true]; + _unit setVariable ["tf_globalVolume", MUTED_LEVEL]; // ACRE2 if (!isNil "acre_api_fnc_setGlobalVolume") then { [MUTED_LEVEL^0.33] call acre_api_fnc_setGlobalVolume; }; - player setVariable ["acre_sys_core_isDisabled", true, true]; - }; diff --git a/addons/common/functions/fnc_setupLocalUnitsHandler.sqf b/addons/common/functions/fnc_setupLocalUnitsHandler.sqf index 75f696e324..0ab01cddbd 100644 --- a/addons/common/functions/fnc_setupLocalUnitsHandler.sqf +++ b/addons/common/functions/fnc_setupLocalUnitsHandler.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: dedmen * Adds the local unit event handlers. diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 86d9e3be8e..5bb0153772 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Allows multiple sources to not overwrite showHud command. @@ -41,29 +41,29 @@ if (isArray (missionConfigFile >> "showHUD")) then { if (_reason != "") then { _reason = toLower _reason; if (_mask isEqualTo []) then { - TRACE_2("Removing", _reason, _mask); - [GVAR(showHudHash), _reason] call CBA_fnc_hashRem; + TRACE_2("Removing",_reason,_mask); + GVAR(showHudHash) deleteAt _reason; } else { while {(count _mask) < 10} do { _mask pushBack true; }; - TRACE_2("Setting", _reason, _mask); - [GVAR(showHudHash), _reason, _mask] call CBA_fnc_hashSet; + TRACE_2("Setting",_reason,_mask); + GVAR(showHudHash) set [_reason, _mask]; }; }; -GVAR(showHudHash) params ["", "_reasons", "_masks"]; +private _masks = values GVAR(showHudHash); private _resultMask = []; for "_index" from 0 to 9 do { private _set = true; //Default to true { - if (!(_x select _index)) exitWith { + if !(_x select _index) exitWith { _set = false; //Any false will make it false }; } forEach _masks; _resultMask pushBack _set; }; -TRACE_2("showHud", _resultMask, _reasons); +TRACE_2("showHud",_resultMask,keys GVAR(showHudHash)); showHud _resultMask; _resultMask diff --git a/addons/common/functions/fnc_showUser.sqf b/addons/common/functions/fnc_showUser.sqf index a30c7cada3..3907849e15 100644 --- a/addons/common/functions/fnc_showUser.sqf +++ b/addons/common/functions/fnc_showUser.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * hint the Variable ACE_isUsedBy from the input Object every frame diff --git a/addons/common/functions/fnc_statusEffect_addType.sqf b/addons/common/functions/fnc_statusEffect_addType.sqf index 6be61967d9..5535b0d914 100644 --- a/addons/common/functions/fnc_statusEffect_addType.sqf +++ b/addons/common/functions/fnc_statusEffect_addType.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Adds a status effect that will be handled. * * Arguments: * 0: Status Effect Name, this should match a corresponding event name - * 1: Send event globaly + * 1: Send event globally * 2: Common Effect Reaons to pre-seed durring init + * 3: Send event to JIP (requires sending event globally) * * Return Value: * None @@ -17,18 +18,20 @@ * Public: No */ -params [["_name", "", [""]], ["_isGlobal", false, [false]], ["_commonReasonsArray", [], [[]]]]; +params [["_name", "", [""]], ["_isGlobal", false, [false]], ["_commonReasonsArray", [], [[]]], ["_sendJIP", false, [false]]]; TRACE_3("params",_name,_isGlobal,_commonReasonsArray); -if (_name == "") exitWith {ERROR_1("addStatusEffect - Bad Name %1", _this)}; -if (_name in GVAR(statusEffect_Names)) exitWith {WARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1", _this)}; +if (_name == "") exitWith {ERROR_1("addStatusEffect - Bad Name %1",_this)}; +if (_name in GVAR(statusEffect_Names)) exitWith {WARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1",_this)}; +if (_sendJIP && !_isGlobal) exitWith {WARNING_1("addStatusEffect - Trying to add non-global JIP effect %1",_this)}; GVAR(statusEffect_Names) pushBack _name; GVAR(statusEffect_isGlobal) pushBack _isGlobal; +GVAR(statusEffect_sendJIP) pushBack _sendJIP; //We add reasons at any time, but more efficenet to add all common ones at one time during init -if (isServer && {!(_commonReasonsArray isEqualTo [])}) then { +if (isServer && {_commonReasonsArray isNotEqualTo []}) then { //Switch case to lower: - _commonReasonsArray = _commonReasonsArray apply { toLower _x }; + _commonReasonsArray = _commonReasonsArray apply { toLowerANSI _x }; missionNamespace setVariable [(format [QGVAR(statusEffects_%1), _name]), _commonReasonsArray, true]; }; diff --git a/addons/common/functions/fnc_statusEffect_get.sqf b/addons/common/functions/fnc_statusEffect_get.sqf index 683c235214..bef27fc6e8 100644 --- a/addons/common/functions/fnc_statusEffect_get.sqf +++ b/addons/common/functions/fnc_statusEffect_get.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Retrives list of current status effects diff --git a/addons/common/functions/fnc_statusEffect_localEH.sqf b/addons/common/functions/fnc_statusEffect_localEH.sqf index 9f5cd7c42a..e60679350d 100644 --- a/addons/common/functions/fnc_statusEffect_localEH.sqf +++ b/addons/common/functions/fnc_statusEffect_localEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles locality switch, runs a respawn check and then reapplies all effect events. @@ -22,12 +22,12 @@ TRACE_2("params",_object,_isLocal); //Only run this after the settings are initialized //Need to wait for all EH to be installed (local event will happen between pre and post init) if !(GVAR(settingsInitFinished)) exitWith { - TRACE_1("pushing to runAtSettingsInitialized", _this); + TRACE_1("pushing to runAtSettingsInitialized",_this); GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_localEH), _this]; }; -if (!_isLocal) exitWith {TRACE_1("object no longer local", _this)}; -if (isNull _object) exitWith {TRACE_1("object null", _this)}; +if (!_isLocal) exitWith {TRACE_1("object no longer local",_this)}; +if (isNull _object) exitWith {TRACE_1("object null",_this)}; //Reset any variables because of respawn [_object, false] call FUNC(statusEffect_resetVariables); diff --git a/addons/common/functions/fnc_statusEffect_resetVariables.sqf b/addons/common/functions/fnc_statusEffect_resetVariables.sqf index b819174753..a9b6853b9f 100644 --- a/addons/common/functions/fnc_statusEffect_resetVariables.sqf +++ b/addons/common/functions/fnc_statusEffect_resetVariables.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Resets all effect numbers to 0 when an object respawns (but does not apply the effect event). diff --git a/addons/common/functions/fnc_statusEffect_respawnEH.sqf b/addons/common/functions/fnc_statusEffect_respawnEH.sqf index 56fe38b6a8..edad032a9a 100644 --- a/addons/common/functions/fnc_statusEffect_respawnEH.sqf +++ b/addons/common/functions/fnc_statusEffect_respawnEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the Respawn Event Handler to reset effects. @@ -21,12 +21,12 @@ TRACE_1("params",_object); //Only run this after the settings are initialized //Need to wait for all EH to be installed (local event will happen between pre and post init) if !(GVAR(settingsInitFinished)) exitWith { - TRACE_1("pushing to runAtSettingsInitialized", _this); + TRACE_1("pushing to runAtSettingsInitialized",_this); GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_respawnEH), _this]; }; -if (!local _object) exitWith {TRACE_1("object no longer local", _this)}; -if (isNull _object) exitWith {TRACE_1("object null", _this)}; +if (!local _object) exitWith {TRACE_1("object no longer local",_this)}; +if (isNull _object) exitWith {TRACE_1("object null",_this)}; //Reset any variables on "real" respawn [_object, false] call FUNC(statusEffect_resetVariables); diff --git a/addons/common/functions/fnc_statusEffect_sendEffects.sqf b/addons/common/functions/fnc_statusEffect_sendEffects.sqf index dae88d35e4..a4e3f2d2a4 100644 --- a/addons/common/functions/fnc_statusEffect_sendEffects.sqf +++ b/addons/common/functions/fnc_statusEffect_sendEffects.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Sends all status effects for an object (can be run on non-local objects) @@ -30,12 +30,21 @@ if (isNull _object) exitWith {}; TRACE_2("checking if event is nil",_x,_effectNumber); if (_effectNumber != -1) then { private _eventName = format [QGVAR(%1), _x]; - if (GVAR(statusEffect_isGlobal) select _forEachIndex) then { - TRACE_2("Sending Global Event", _object, _effectNumber); - [_eventName, [_object, _effectNumber]] call CBA_fnc_globalEvent; - } else { - TRACE_2("Sending Target Event", _object, _effectNumber); - [_eventName, [_object, _effectNumber], _object] call CBA_fnc_targetEvent; + switch (true) do { + case (GVAR(statusEffect_sendJIP) select _forEachIndex): { + TRACE_2("Sending Global JIP Event",_object,_effectNumber); + private _jipID = format [QGVAR(effect_%1_%2), _eventName, hashValue _object]; + [_eventName, [_object, _effectNumber], _jipID] call CBA_fnc_globalEventJIP; + [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; + }; + case (GVAR(statusEffect_isGlobal) select _forEachIndex): { + TRACE_2("Sending Global Event",_object,_effectNumber); + [_eventName, [_object, _effectNumber]] call CBA_fnc_globalEvent; + }; + default { + TRACE_2("Sending Target Event",_object,_effectNumber); + [_eventName, [_object, _effectNumber], _object] call CBA_fnc_targetEvent; + }; }; }; }; diff --git a/addons/common/functions/fnc_statusEffect_set.sqf b/addons/common/functions/fnc_statusEffect_set.sqf index ff8fa8565a..a4bf352a56 100644 --- a/addons/common/functions/fnc_statusEffect_set.sqf +++ b/addons/common/functions/fnc_statusEffect_set.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Adds or removes an id to a status effect and will send an event to apply. @@ -23,7 +23,7 @@ TRACE_4("params",_object,_effectName,_ID,_set); //Only run this after the settings are initialized if !(GVAR(settingsInitFinished)) exitWith { - TRACE_1("pushing to runAtSettingsInitialized", _this); + TRACE_1("pushing to runAtSettingsInitialized",_this); GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_set), _this]; }; @@ -32,7 +32,7 @@ if (isNull _object) exitWith {TRACE_1("null",_object);}; [_object, true] call FUNC(statusEffect_resetVariables); //Check for mismatch, and set object ref //check ID case and set globally if not already set: -_ID = toLower _ID; +_ID = toLowerANSI _ID; private _statusReasons = missionNamespace getVariable [(format [QGVAR(statusEffects_%1), _effectName]), []]; private _statusIndex = _statusReasons find _ID; if (_statusIndex == -1) then { diff --git a/addons/common/functions/fnc_stopGesture.sqf b/addons/common/functions/fnc_stopGesture.sqf new file mode 100644 index 0000000000..53e319b04b --- /dev/null +++ b/addons/common/functions/fnc_stopGesture.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: ACRE2Team + * Stops a unit's gesture. + * + * Arguments: + * 0: Target + * + * Return Value: + * None + * + * Example: + * [bob] call ace_common_fnc_stopGesture + * + * Public: Yes + */ + +params ["_unit"]; + +[QGVAR(playActionNow), [_unit, QGVAR(stop)], _unit] call CBA_fnc_targetEvent diff --git a/addons/common/functions/fnc_stringCompare.sqf b/addons/common/functions/fnc_stringCompare.sqf index 9a0955b27a..8ed3c63c75 100644 --- a/addons/common/functions/fnc_stringCompare.sqf +++ b/addons/common/functions/fnc_stringCompare.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bovine3dom * Determines whether one string matches another and how many characters match. Case insensitive. diff --git a/addons/common/functions/fnc_stringToColoredText.sqf b/addons/common/functions/fnc_stringToColoredText.sqf index c7eaaaecb3..0a292753c4 100644 --- a/addons/common/functions/fnc_stringToColoredText.sqf +++ b/addons/common/functions/fnc_stringToColoredText.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Create a centered, colored text. diff --git a/addons/common/functions/fnc_swayLoop.sqf b/addons/common/functions/fnc_swayLoop.sqf new file mode 100644 index 0000000000..adbc32053f --- /dev/null +++ b/addons/common/functions/fnc_swayLoop.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Calculates and applies final sway coefficient from sway factors + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_common_fnc_swayLoop + * + * Public: No +*/ + +private _baseline = 1; +if (GVAR(swayFactorsBaseline) isNotEqualTo []) then { + _baseline = 1 max ([missionNamespace, "ACE_setCustomAimCoef_baseline", "max"] call FUNC(arithmeticGetResult)); +}; + +private _multiplier = 1; +if (GVAR(swayFactorsMultiplier) isNotEqualTo []) then { + _multiplier = [missionNamespace, "ACE_setCustomAimCoef_multiplier", "product"] call FUNC(arithmeticGetResult); +}; + +ACE_player setCustomAimCoef (_baseline * _multiplier); + +[FUNC(swayLoop), [], 0.5] call CBA_fnc_waitAndExecute diff --git a/addons/common/functions/fnc_switchPersistentLaser.sqf b/addons/common/functions/fnc_switchPersistentLaser.sqf index 2e2fb7505b..a2b7b9c1a8 100644 --- a/addons/common/functions/fnc_switchPersistentLaser.sqf +++ b/addons/common/functions/fnc_switchPersistentLaser.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Controls persistent laser state. diff --git a/addons/common/functions/fnc_switchToGroupSide.sqf b/addons/common/functions/fnc_switchToGroupSide.sqf index 842bdffabd..1a3e588855 100644 --- a/addons/common/functions/fnc_switchToGroupSide.sqf +++ b/addons/common/functions/fnc_switchToGroupSide.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Stack group switches. Will always trace back to original group. @@ -58,7 +58,7 @@ if (_switch) then { private _newGroup = createGroup (_x select 1); [_unit] joinSilent _newGroup; }; - if (count units _currentGroup == 0) then { + if (units _currentGroup isEqualTo []) then { deleteGroup _currentGroup; }; _previousGroupsList set [_forEachIndex, objNull]; diff --git a/addons/common/functions/fnc_syncedEvent.sqf b/addons/common/functions/fnc_syncedEvent.sqf index 9ddb071dac..75170fe7d1 100644 --- a/addons/common/functions/fnc_syncedEvent.sqf +++ b/addons/common/functions/fnc_syncedEvent.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Call and propegate a synced event @@ -19,8 +19,8 @@ params ["_name", "_args", ["_ttl", 0]]; -if !([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ERROR_1("Synced event key [%1] not found (syncedEvent).", _name); +if !(_name in GVAR(syncedEvents)) exitWith { + ERROR_1("Synced event key [%1] not found (syncedEvent)",_name); false }; diff --git a/addons/common/functions/fnc_syncedEventPFH.sqf b/addons/common/functions/fnc_syncedEventPFH.sqf index 6d5d2ea12c..2ed238bd9e 100644 --- a/addons/common/functions/fnc_syncedEventPFH.sqf +++ b/addons/common/functions/fnc_syncedEventPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -21,9 +21,8 @@ if (!isServer) exitWith {false}; // Walk through the local synced events and clean up anything thats already EOL // @TODO: This should be iteration limited to prevent FPS lag -[GVAR(syncedEvents), { - _value params ["_eventTime", "_eventLog", "_globalEventTTL"]; - +{ + _y params ["_eventTime", "_eventLog", "_globalEventTTL"]; private _newEventLog = []; // @TODO: This should be iteration limited to prevent FPS lag @@ -52,11 +51,8 @@ if (!isServer) exitWith {false}; if (_ttlReturn) then { _newEventLog pushBack _x; }; - false - } count _eventLog; - - _value set [1, _newEventLog]; - false -}] call CBA_fnc_hashEachPair; + } forEach _eventLog; + _y set [1, _newEventLog]; +} forEach GVAR(syncedEvents); // @TODO: Next, detect if we had a new request from a JIP player, and we need to continue syncing events diff --git a/addons/common/functions/fnc_throttledPublicVariable.sqf b/addons/common/functions/fnc_throttledPublicVariable.sqf index abfcfc8c8c..e6b1fdbaf6 100644 --- a/addons/common/functions/fnc_throttledPublicVariable.sqf +++ b/addons/common/functions/fnc_throttledPublicVariable.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Schedules the publishment of an object variable to reduce network overhead @@ -29,8 +29,7 @@ if (isNil QGVAR(publishSchedId)) then { { _x params ["_unit", "_varName"]; _unit setVariable [_varName, _unit getVariable _varName, true]; - false - } count GVAR(publishVarNames); + } forEach GVAR(publishVarNames); GVAR(publishVarNames) = []; GVAR(publishNextTime) = 1e7; diff --git a/addons/common/functions/fnc_throwWeapon.sqf b/addons/common/functions/fnc_throwWeapon.sqf new file mode 100644 index 0000000000..c3c234e61f --- /dev/null +++ b/addons/common/functions/fnc_throwWeapon.sqf @@ -0,0 +1,49 @@ +#include "..\script_component.hpp" +/* + * Author: commy2 + * Makes the unit throw their currently selected weapon. + * Unit must be local and not inside a vehicle or attached to another object. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Weapon Holder + * + * Example: + * player call ace_common_fnc_throwWeapon + * + * Public: No + */ + +#define OFFSET_LATERAL 0.59 +#define THROW_ANGLE 63.43 +#define THROW_VELOCITY 1.5 +#define THROW_TORQUE 0.2 + +params ["_unit"]; + +private _weapon = currentWeapon _unit; +if (!isNull objectParent _unit || _weapon isEqualTo "") exitWith {objNull}; + +private _data = weaponsItems _unit select {_x select 0 == _weapon} select 0; + +private _holder = createVehicle ["WeaponHolderSimulated", [0, 0, 0], [], 0, "CAN_COLLIDE"]; +_holder addWeaponWithAttachmentsCargoGlobal [_data, 1]; + +private _vDir = _unit weaponDirection _weapon; +private _vLat = vectorNormalized (_vDir vectorCrossProduct [0, 0, 1]); +private _vUp = _vLat vectorCrossProduct _vDir; + +private _position = _unit modelToWorldWorld (_unit selectionPosition "RightHand") vectorAdd (_vLat vectorMultiply OFFSET_LATERAL); +private _velocity = vectorNormalized (_vDir vectorAdd (_vUp vectorMultiply tan THROW_ANGLE)) vectorMultiply THROW_VELOCITY vectorAdd velocity _unit; + +_unit removeWeapon _weapon; +_holder setPosWorld _position; +_holder setVectorDirAndUp [_vUp, _vLat]; +_holder setVelocity _velocity; +_holder addTorque (call CBA_fnc_randomVector3D vectorMultiply THROW_TORQUE); + +["ACE_weaponThrown", [_unit, _holder, _data]] call CBA_fnc_localEvent; + +_holder // return diff --git a/addons/common/functions/fnc_toBin.sqf b/addons/common/functions/fnc_toBin.sqf index c5da7ece8e..038a091d83 100644 --- a/addons/common/functions/fnc_toBin.sqf +++ b/addons/common/functions/fnc_toBin.sqf @@ -1,10 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Converts number to binary number * * Arguments: - * A number + * 0: A number + * 1: Minumum length of numbers (default: 1) * * Return Value: * A binary number as string diff --git a/addons/common/functions/fnc_toBitmask.sqf b/addons/common/functions/fnc_toBitmask.sqf index 2d46811c6b..2efd5414c9 100644 --- a/addons/common/functions/fnc_toBitmask.sqf +++ b/addons/common/functions/fnc_toBitmask.sqf @@ -1,10 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Convert an array of booleans into a number. * * Arguments: - * N: Booleans + * 0: Boolean + * 1: Boolean + * 2: Boolean + * ... * * Return Value: * Bitmask diff --git a/addons/common/functions/fnc_toHex.sqf b/addons/common/functions/fnc_toHex.sqf index 697fbb9b6d..08e903405b 100644 --- a/addons/common/functions/fnc_toHex.sqf +++ b/addons/common/functions/fnc_toHex.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, esteldunedain * Converts number to hexadecimal number * * Arguments: - * A number between 0 and 255 + * 0: A number between 0 and 255 * * Return Value: * A hexadecimal number as string diff --git a/addons/common/functions/fnc_toNumber.sqf b/addons/common/functions/fnc_toNumber.sqf index 14e8179a63..835ebfb48a 100644 --- a/addons/common/functions/fnc_toNumber.sqf +++ b/addons/common/functions/fnc_toNumber.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth de Wet (LH) * Takes a string/number and returns the number. diff --git a/addons/common/functions/fnc_translateToModelSpace.sqf b/addons/common/functions/fnc_translateToModelSpace.sqf index 843c710c8d..9583f6063c 100644 --- a/addons/common/functions/fnc_translateToModelSpace.sqf +++ b/addons/common/functions/fnc_translateToModelSpace.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * ? diff --git a/addons/common/functions/fnc_translateToWeaponSpace.sqf b/addons/common/functions/fnc_translateToWeaponSpace.sqf index 4f4bbeae3b..143ded9350 100644 --- a/addons/common/functions/fnc_translateToWeaponSpace.sqf +++ b/addons/common/functions/fnc_translateToWeaponSpace.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * ? diff --git a/addons/common/functions/fnc_unhideUnit.sqf b/addons/common/functions/fnc_unhideUnit.sqf index b6d669366e..d78de70b26 100644 --- a/addons/common/functions/fnc_unhideUnit.sqf +++ b/addons/common/functions/fnc_unhideUnit.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike (based on unmuteUnit) + * Author: kymckay (based on unmuteUnit) * Globally unhides a unit. Only unhides if the last reason was removed. * * Arguments: diff --git a/addons/common/functions/fnc_uniqueElements.sqf b/addons/common/functions/fnc_uniqueElements.sqf index 5aad721d48..8a578cd008 100644 --- a/addons/common/functions/fnc_uniqueElements.sqf +++ b/addons/common/functions/fnc_uniqueElements.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Make a copy of an array with only the unique elements. diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf index 5d7e5e8633..204501ca3f 100644 --- a/addons/common/functions/fnc_uniqueItems.sqf +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -1,37 +1,84 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: mharis001 - * Returns list of unique items in a unit's inventory. - * Items are cached if unit is ACE_player. + * Author: mharis001, Blue, Brett Mayson + * Returns list of unique items in the target's inventory. * * Arguments: - * 0: Unit + * 0: Target + * 1: Include magazines + * 0: No (default) + * 1: Yes + * 2: Only magazines * * Return Value: * Items * * Example: - * [player] call ace_common_fnc_uniqueItems + * [player, 2] call ace_common_fnc_uniqueItems * * Public: No */ -params ["_unit"]; +params ["_target", ["_includeMagazines", 0]]; private _fnc_getItems = { - private _items = (getItemCargo uniformContainer _unit) select 0; - _items append ((getItemCargo vestContainer _unit) select 0); - _items append ((getItemCargo backpackContainer _unit) select 0); + private _items = []; + + private _inventoryItems = (getItemCargo uniformContainer _target) select 0; + _inventoryItems append ((getItemCargo vestContainer _target) select 0); + _inventoryItems append ((getItemCargo backpackContainer _target) select 0); + + _items set [0, _inventoryItems]; + _items set [1, magazines _target]; _items arrayIntersect _items }; -// Use cached items list if unit is ACE_player -if (_unit isEqualTo ACE_player) then { +// Cache items list if unit is ACE_player +if (_target isEqualTo ACE_player) then { if (isNil QGVAR(uniqueItemsCache)) then { GVAR(uniqueItemsCache) = call _fnc_getItems; }; - +GVAR(uniqueItemsCache) + + switch (_includeMagazines) do { + case 0: { + GVAR(uniqueItemsCache) select 0 + }; + case 1: { + (GVAR(uniqueItemsCache) select 1) + (GVAR(uniqueItemsCache) select 0) + }; + case 2: { + GVAR(uniqueItemsCache) select 1 + }; + }; } else { - call _fnc_getItems; + if (_target isKindOf "CAManBase") then { + private _items = call _fnc_getItems; + + switch (_includeMagazines) do { + case 0: { + _items select 0 + }; + case 1: { + (_items select 1) + (_items select 0) + }; + case 2: { + _items select 1 + }; + }; + } else { + private _items = switch (_includeMagazines) do { + case 0: { + itemCargo _target + }; + case 1: { + (magazineCargo _target) + (itemCargo _target) + }; + case 2: { + magazineCargo _target + }; + }; + + _items arrayIntersect _items + }; }; diff --git a/addons/common/functions/fnc_uniqueUnitItems.sqf b/addons/common/functions/fnc_uniqueUnitItems.sqf new file mode 100644 index 0000000000..9fa03386c6 --- /dev/null +++ b/addons/common/functions/fnc_uniqueUnitItems.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Returns list of items (including magazines, backpacks and other) in a unit's inventory. + * Number definition: 0: Do not return value, 1: Return container only, 2: Return container and content, 3: Return content only + * + * Arguments: + * 0: Unit + * 1: Weapon items (default: 2) + * 2: Uniform items (default: 2) + * 3: Vest items (default: 2) + * 4: Backpack items (default: 2) + * 5: Assigned items (default: true) + * + * Return Value: + * Items + * + * Example: + * [player] call ace_common_fnc_uniqueUnitItems + * + * Public: Yes + */ + +params ["_unit", ["_weaponItems", 2, [0]], ["_uniformItems", 2, [0]], ["_vestItems", 2, [0]], ["_backpackItems", 2, [0]], ["_assignedItems", true, [false]]]; + +// 'uniqueUnitItems' can take any number, number other than 0 and 1 have the same effect as the number '2' +private _uniqueUnitItems = uniqueUnitItems [_unit, _weaponItems, _uniformItems, _vestItems, _backpackItems, _assignedItems]; + +private _amount = 0; + +// Remove unit's uniform, vest and backpack if there aren't in the containers themselves if necessary +{ + _x params ["_container", "_filter"]; + + if ((_filter == 3) && {_container != ""}) then { + _amount = _uniqueUnitItems get _container; + + // Delete item from hashmap if it's the only one + if (_amount == 1) then { + _uniqueUnitItems deleteAt _container; + } else { + _uniqueUnitItems set [_container, _amount - 1]; + }; + }; +} forEach [[uniform _unit, _uniformItems], [vest _unit, _vestItems], [backpack _unit, _backpackItems]]; + +_uniqueUnitItems diff --git a/addons/common/functions/fnc_unloadPerson.sqf b/addons/common/functions/fnc_unloadPerson.sqf index b744cbc272..f6dc7534d2 100644 --- a/addons/common/functions/fnc_unloadPerson.sqf +++ b/addons/common/functions/fnc_unloadPerson.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Unload a person from a vehicle @@ -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..0378c6a4b8 100644 --- a/addons/common/functions/fnc_unloadPersonLocal.sqf +++ b/addons/common/functions/fnc_unloadPersonLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ViperMaul * Unload a person from a vehicle, local @@ -12,22 +12,30 @@ * Succesfully unloaded person * * Example: - * [bob, car, bob] call ace_common_fnc_unloadpersonLocal + * [bob, car, bob] call ace_common_fnc_unloadPersonLocal * * Public: No */ #define GROUP_SWITCH_ID QFUNC(loadPerson) -params ["_unit", "_vehicle", ["_unloader", objNull]]; -TRACE_3("params",_unit,_vehicle,_unloader); +params ["_unit", ["_vehicle", objNull], ["_unloader", objNull]]; +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); + WARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle,getPosASL _vehicle,isTouchingGround _vehicle,speed _vehicle); if ((!isNull _unloader) && {[_unloader] call FUNC(isPlayer)}) then { //display text saying there are no safe places to exit the vehicle [QGVAR(displayTextStructured), [localize LSTRING(NoRoomToUnload)], [_unloader]] call CBA_fnc_targetEvent; @@ -38,57 +46,44 @@ 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_2("Ejecting",alive _unit,local _vehicle); + +if (local _vehicle) then { + _unit action ["Eject", _vehicle]; + // Failsafe - sometimes eject alone doesn't work, but moveOut does + [{ + params ["_unit"]; + + if (!isNull objectParent _unit) then { + if ([_unit] call FUNC(isAwake)) then { + WARNING_1("UnloadPersonLocal [%1] did not eject normally",_unit); + } else { + TRACE_1("UnloadPersonLocal dead/uncon did not eject normally",_unit); + }; + moveOut _unit; + }; + }, [_unit], 1] call CBA_fnc_waitAndExecute; + +} else { + moveOut _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); - }; - - _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; +// Wait until unit has actually exited vehicle and then move them to the unload position +if (alive _unit) then { + [{ + params ["_unit", "_emptyPos"]; + (alive _unit) && {isNull objectParent _unit} + }, { + params ["_unit", "_emptyPos"]; + TRACE_2("unload success",_unit,_emptyPos); + _unit setPosASL AGLToASL _emptyPos; + }, [_unit, _emptyPos], 2, { + params ["_unit", "_emptyPos"]; + if (!alive _unit) exitWith {}; + WARNING_2("timeout %1->%2",_unit,objectParent _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_unloadUnitWeapon.sqf b/addons/common/functions/fnc_unloadUnitWeapon.sqf new file mode 100644 index 0000000000..ef367d103c --- /dev/null +++ b/addons/common/functions/fnc_unloadUnitWeapon.sqf @@ -0,0 +1,128 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh, commy2, johnb43 + * Unload the magazine from the unit's weapon and attempt to put it in a sensible place. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: Muzzle (default: Weapon) + * 3: Magazine (default: magazine in Weapon) + * 4: Ammo count (default: Unit ammo Muzzle) + * 5: Skip animation? (default: false) + * + * Return Value: + * None + * + * Example: + * [ACE_player, currentWeapon ACE_player, currentMuzzle ACE_player, currentMagazine ACE_player, 23, false] call ace_common_fnc_unloadUnitWeapon + * + * Public: No + */ + +params ["_unit", "_weapon", "_muzzle", "_magazine", "_ammoCount", ["_skipAnim", false]]; +TRACE_6("params",_unit,_weapon,_muzzle,_magazine,_ammoCount,_skipAnim); + +if (_unit getVariable [QGVAR(isUnloadingWeapon), false]) exitWith {}; + +// Only allow 1 weapon to be unloaded at a time (because of animation length) +_unit setVariable [QGVAR(isUnloadingWeapon), true]; + +if (isNil "_muzzle") then { + _muzzle = _weapon; +}; + +if (isNil "_magazine") then { + private _weaponState = _unit weaponState _muzzle; + + _magazine = _weaponState select 3; + _ammoCount = _weaponState select 4; +}; + +if (isNil "_ammoCount") then { + _ammoCount = _unit ammo _muzzle; +}; + +// Audiovisual effects +private _delay = 0; + +if (!_skipAnim) then { + _delay = 1.5; + + private _config = configFile >> "CfgWeapons" >> _weapon; + + if (_weapon != _muzzle) then { + _config = _config >> _muzzle; + }; + + // Get and play animation + private _unloadAction = getText (_config >> "ACE_unloadAction"); + + if (_unloadAction == "") then { + _unloadAction = getText (_config >> "reloadAction"); + }; + + [_unit, _unloadAction, 1] call FUNC(doGesture); + + // Get and play sound + private _unloadSound = getText (_config >> "ACE_unloadSound"); + + if (_unloadSound == "") then { + _unloadSound = "A3\Sounds_F\arsenal\weapons\Rifles\Katiba\reload_Katiba.wss"; + + private _unloadSoundArray = getArray (_config >> "reloadMagazineSound"); + + // File extention is required for playSound3D + if (_unloadSoundArray isNotEqualTo []) then { + private _wssTest = format ["%1.wss", _unloadSoundArray select 0]; + + if (fileExists _wssTest) then { + _unloadSound = _wssTest; + } else { + private _wavTest = format ["%1.wav", _unloadSoundArray select 0]; + + if (fileExists _wavTest) then { + _unloadSound = _wavTest; + } else { + private _oggTest = format ["%1.ogg", _unloadSoundArray select 0]; + + if (fileExists _oggTest) then { + _unloadSound = _oggTest; + }; + }; + }; + }; + }; + + playSound3D [_unloadSound, _unit]; +}; + +// Remove magazine from weapon and add it to inventory +[{ + params ["_unit", "_weapon", "_muzzle", "_magazine", "_ammoCount"]; + + _unit setVariable [QGVAR(isUnloadingWeapon), nil]; + + private _returnMagazine = true; + + // Check if it's possible to remove given item from weapon; If possible, remove weapon item + switch (true) do { + case (_weapon == primaryWeapon _unit && {_weapon canAdd [_magazine, _muzzle]}): { + _unit removePrimaryWeaponItem _magazine; + }; + case (_weapon == handgunWeapon _unit && {_weapon canAdd [_magazine, _muzzle]}): { + _unit removeHandgunItem _magazine; + }; + case (_weapon == secondaryWeapon _unit && {_weapon canAdd [_magazine, _muzzle]}): { + _unit removeSecondaryWeaponItem _magazine; + }; + default { + _returnMagazine = false; + }; + }; + + // Avoid duplicating magazines (e.g. by switching weapons mid unload) + if (!_returnMagazine) exitWith {}; + + [_unit, _magazine, _ammoCount, true] call CBA_fnc_addMagazine; +}, [_unit, _weapon, _muzzle, _magazine, _ammoCount], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/common/functions/fnc_unmuteUnit.sqf b/addons/common/functions/fnc_unmuteUnit.sqf index 03a7a33e23..e624cfac54 100644 --- a/addons/common/functions/fnc_unmuteUnit.sqf +++ b/addons/common/functions/fnc_unmuteUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Unmutes the unit. Only unmutes if the last reason was removed. diff --git a/addons/common/functions/fnc_useItem.sqf b/addons/common/functions/fnc_useItem.sqf index ba4e668792..ea2a743751 100644 --- a/addons/common/functions/fnc_useItem.sqf +++ b/addons/common/functions/fnc_useItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Use item diff --git a/addons/common/functions/fnc_useMagazine.sqf b/addons/common/functions/fnc_useMagazine.sqf index 109f01f996..c08cb1534a 100644 --- a/addons/common/functions/fnc_useMagazine.sqf +++ b/addons/common/functions/fnc_useMagazine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Use magazine diff --git a/addons/common/functions/fnc_watchVariable.sqf b/addons/common/functions/fnc_watchVariable.sqf index 6fa86dc9bc..fb1f7db671 100644 --- a/addons/common/functions/fnc_watchVariable.sqf +++ b/addons/common/functions/fnc_watchVariable.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Shows multiple watched variables on the main display (for easy debugging). @@ -7,12 +7,12 @@ * 0: Title (var name) (default: "") * 1: Code to generate result (passed nothing, can return any) (default: {}) * 2: Array containing modifiers (default: []) - * For Numbers: - * 0: Show Delta change (default: true) - * 1: Slider Min Value (default: 0) - * 1: Slider Max Value (default: 0) - * For Anything else: - * 0: Number of structured text lines (default: 1) + * For Numbers: + * - 0: Show Delta change (default: true) + * - 1: Slider Min Value (default: 0) + * - 2: Slider Max Value (default: 0) + * For Anything else: + * + 0: Number of structured text lines (default: 1) * * Return Value: * None @@ -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/functions/fnc_waveHeightAt.sqf b/addons/common/functions/fnc_waveHeightAt.sqf index 969f4fc87e..ae0ad9f192 100644 --- a/addons/common/functions/fnc_waveHeightAt.sqf +++ b/addons/common/functions/fnc_waveHeightAt.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Gets the wave height at a specific location. Uses a logic, so may be performance iffy diff --git a/addons/common/functions/fnc_worldToScreenBounds.sqf b/addons/common/functions/fnc_worldToScreenBounds.sqf index 74c19d0b4e..13cb7f5633 100644 --- a/addons/common/functions/fnc_worldToScreenBounds.sqf +++ b/addons/common/functions/fnc_worldToScreenBounds.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: zGuba 2011 * Function helper for framing objects on screen. diff --git a/addons/common/functions/script_component.hpp b/addons/common/functions/script_component.hpp deleted file mode 100644 index 6a1bf9154d..0000000000 --- a/addons/common/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\common\script_component.hpp" diff --git a/addons/common/initSettings.inc.sqf b/addons/common/initSettings.inc.sqf new file mode 100644 index 0000000000..a784ac64a9 --- /dev/null +++ b/addons/common/initSettings.inc.sqf @@ -0,0 +1,141 @@ +private _category = format ["ACE %1", LLSTRING(DisplayName)]; +private _categoryColors = [_category, LSTRING(subcategory_colors)]; +private _categorySway = [_category, LSTRING(subcategory_sway)]; + +[ + QGVAR(checkPBOsAction), + "LIST", + [LSTRING(CheckPBOsAction), LSTRING(CheckPBOsActionDesc)], + _category, + [[0, 1, 2], [LSTRING(CheckPBO_Action_WarnOnce), LSTRING(CheckPBO_Action_WarnPerm), LSTRING(CheckPBO_Action_Kick)], 0], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(checkPBOsCheckAll), + "CHECKBOX", + [LSTRING(CheckPBOsCheckAll), LSTRING(CheckPBOsCheckAllDesc)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(checkPBOsWhitelist), + "EDITBOX", + [LSTRING(CheckPBOsWhitelist), LSTRING(CheckPBOsWhiteListDesc)], + _category, + "[]", + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(settingFeedbackIcons), + "LIST", + [LSTRING(SettingFeedbackIconsName), LSTRING(SettingFeedbackIconsDesc)], + _category, + [[0, 1, 2, 3, 4], [LSTRING(Hide), LSTRING(TopRightDown), LSTRING(TopRightLeft), LSTRING(TopLeftDown), LSTRING(TopLeftRight)], 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(settingProgressBarLocation), + "LIST", + [LSTRING(SettingProgressBarLocationName), LSTRING(SettingProgressBarLocationDesc)], + _category, + [[0, 1], [LSTRING(Top), LSTRING(Bottom)], 0], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(displayTextColor), + "COLOR", + [LSTRING(SettingDisplayTextColorName),LSTRING(SettingDisplayTextColorDesc)], + _categoryColors, + [0, 0, 0, 0.1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(displayTextFontColor), + "COLOR", + [LSTRING(SettingDisplayTextFontColorName),LSTRING(SettingDisplayTextFontColorDesc)], + _categoryColors, + [1, 1, 1, 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(persistentLaserEnabled), + "CHECKBOX", + [LSTRING(SettingPersistentLaserName), LSTRING(SettingPersistentLaserDesc)], + LSTRING(ACEKeybindCategoryWeapons), + false, + false, + LINKFUNC(switchPersistentLaser) +] call CBA_fnc_addSetting; + +[ + QGVAR(allowFadeMusic), + "CHECKBOX", + [LSTRING(AllowFadeMusic), LSTRING(AllowFadeMusicTooltip)], + _category, + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(epilepsyFriendlyMode), + "CHECKBOX", + [LSTRING(EpilepsyFriendlyMode), LSTRING(EpilepsyFriendlyModeTooltip)], + _category, + false, + 2 +] call CBA_fnc_addSetting; + +[ + QGVAR(progressBarInfo), + "LIST", + [LSTRING(progressBarInfoName), LSTRING(progressBarInfoDesc)], + _category, + [[0, 1, 2], [LSTRING(None), LSTRING(progressBarInfoPercentage), LSTRING(progressBarInfoTime)], 2], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableSway), + "CHECKBOX", + [LSTRING(enableSway), LSTRING(enableSway_Description)], + _categorySway, + true, + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(swayFactor), + "SLIDER", + [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(restedSwayFactor), + "SLIDER", + [LSTRING(RestedSwayFactor), LSTRING(RestedSwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(deployedSwayFactor), + "SLIDER", + [LSTRING(DeployedSwayFactor), LSTRING(DeployedSwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/common/initSettings.sqf b/addons/common/initSettings.sqf deleted file mode 100644 index fcaa242ac3..0000000000 --- a/addons/common/initSettings.sqf +++ /dev/null @@ -1,18 +0,0 @@ -[ - QGVAR(persistentLaserEnabled), - "CHECKBOX", - [LSTRING(SettingPersistentLaserName), LSTRING(SettingPersistentLaserDesc)], - localize LSTRING(ACEKeybindCategoryWeapons), - false, - false, - LINKFUNC(switchPersistentLaser) -] call CBA_settings_fnc_init; - -[ - QGVAR(allowFadeMusic), - "CHECKBOX", - [LSTRING(AllowFadeMusic), LSTRING(AllowFadeMusicTooltip)], - localize LSTRING(ACEKeybindCategoryCommon), - true, - true -] call CBA_settings_fnc_init; 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..a5c9744c88 100644 --- a/addons/common/script_component.hpp +++ b/addons/common/script_component.hpp @@ -16,11 +16,7 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define VERSION_CONFIG_COMMON VERSION_CONFIG;\ - versionDesc = "ACE 3";\ - versionAct = QUOTE(call COMPILE_FILE(init_versionTooltip)) - - +// just kept for BWC, canDig now uses GVAR(canDigSurfaces) #define DIG_SURFACE_BLACKLIST [ \ "concrete", "concrete_exp", "concrete_int", "int_concrete", "int_concrete_exp", \ "pavement_exp", "int_pavement_exp", \ @@ -33,4 +29,4 @@ "wood", "wood_int", "int_wood", "softwood_exp", "int_softwood_exp", "int_solidwood_exp" \ ] -#define DIG_SURFACE_WHITELIST ["grass", "grasstall_exp", "forest_exp"] +#define DIG_SURFACE_WHITELIST ["grass", "grasstall_exp", "forest_exp", "snow"] diff --git a/addons/common/scripts/checkVersionNumber.sqf b/addons/common/scripts/checkVersionNumber.sqf deleted file mode 100644 index 5d4b1734e4..0000000000 --- a/addons/common/scripts/checkVersionNumber.sqf +++ /dev/null @@ -1,156 +0,0 @@ -// by commy2 -#include "script_component.hpp" - -private _aceWhitelist = missionNamespace getVariable ["ACE_Version_Whitelist", []]; -private _files = CBA_common_addons select { - (_x select [0,3] != "a3_") && - {_x select [0,4] != "ace_"} && - {!((toLower _x) in _aceWhitelist)} -}; - -private _versions = []; -{ - getText (configFile >> "CfgPatches" >> _x >> "version") splitString "." params [["_major", "0"], ["_minor", "0"]]; - private _version = parseNumber _major + parseNumber _minor/100; - _versions set [_forEachIndex, _version]; -} forEach _files; - -if (isServer) then { - ACE_Version_ServerVersions = [_files, _versions]; - publicVariable "ACE_Version_ServerVersions"; -} else { - ACE_Version_ClientVersions = [_files, _versions]; -}; - -// Begin client version check -if (!isServer) then { - // Wait for server to send the servers files and version numbers - waitUntil { - sleep 1; - !isNil "ACE_Version_ClientVersions" && {!isNil "ACE_Version_ServerVersions"} - }; - - private _client = profileName; - - _files = ACE_Version_ClientVersions select 0; - _versions = ACE_Version_ClientVersions select 1; - - private _serverFiles = ACE_Version_ServerVersions select 0; - private _serverVersions = ACE_Version_ServerVersions select 1; - - // Compare client and server files and versions - private _missingAddons = []; - private _oldVersionsClient = []; - private _oldVersionsServer = []; - { - private _serverVersion = _serverVersions select _forEachIndex; - - private _index = _files find _x; - if (_index == -1) then { - if (_x != "ace_server") then {_missingAddons pushBack _x;}; - } else { - - private _clientVersion = _versions select _index; - - if (_clientVersion < _serverVersion) then { - _oldVersionsClient pushBack [_x, _clientVersion, _serverVersion]; - }; - - if (_clientVersion > _serverVersion) then { - _oldVersionsServer pushBack [_x, _clientVersion, _serverVersion]; - }; - }; - } forEach _serverFiles; - - // find client files which the server doesn't have - private _missingAddonsServer = []; - { - private _index = _serverFiles find _x; - if (_index == -1) then { - _missingAddonsServer pushBack _x; - } - } forEach _files; - - // display and log error messages - private _fnc_cutComma = { - private _string = _this; - _string = toArray _string; - - private _count = count _string; - _string set [_count - 2, toArray "." select 0]; - _string set [_count - 1, -1]; - _string = _string - [-1]; - - toString _string; - }; - - private _missingAddon = false; - if (count _missingAddons > 0) then { - _missingAddon = true; - - private _error = format ["[ACE] %1: ERROR client missing addon(s): ", _client]; - { - _error = _error + format ["%1, ", _x]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _missingAddons; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - }; - - private _missingAddonServer = false; - if (count _missingAddonsServer > 0) then { - _missingAddonServer = true; - - private _error = format ["[ACE] %1: ERROR server missing addon(s): ", _client]; - { - _error = _error + format ["%1, ", _x]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _missingAddonsServer; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - }; - - private _oldVersionClient = false; - if (count _oldVersionsClient > 0) then { - _oldVersionClient = true; - - private _error = format ["[ACE] %1: ERROR outdated client addon(s): ", _client]; - { - _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _oldVersionsClient; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - }; - - private _oldVersionServer = false; - if (count _oldVersionsServer > 0) then { - _oldVersionServer = true; - - private _error = format ["[ACE] %1: ERROR outdated server addon(s): ", _client]; - { - _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _oldVersionsServer; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - }; - - ACE_Version_ClientErrors = [_missingAddon, _missingAddonServer, _oldVersionClient, _oldVersionServer]; -}; diff --git a/addons/common/scripts/script_component.hpp b/addons/common/scripts/script_component.hpp deleted file mode 100644 index 23da62b05c..0000000000 --- a/addons/common/scripts/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\common\script_component.hpp" \ No newline at end of file diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 0bb411d168..96ad037cc1 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -5,12 +5,16 @@ Common Allgemein Comune - 全般 + 一般 通用 通用 일반 Ogólny - Общий + Общие + Comum + Común + Obecné + Commun ACE-Team @@ -23,10 +27,11 @@ ACE-Team ACE-Team ACE-Team - ACE-チーム - ACE-Team + ACE チーム + ACE-팀 ACE-製作團隊 - ACE-制作团队 + ACE—制作团队 + ACE-Takımı Advanced @@ -36,11 +41,14 @@ Erweitert Pokročilé Avançada - Avancée + Avancé Fejlett Avanzato アドバンスド 고급 + 進階 + 进阶 + Gelişmiş Save @@ -57,6 +65,7 @@ 저장 儲存 储存 + Kaydet Cancel @@ -73,6 +82,7 @@ 취소 取消 取消 + Iptal ACE Options @@ -88,7 +98,8 @@ ACE オプション ACE 옵션 ACE設定選項 - ACE设定选项 + ACE 设定选项 + ACE Ayarları @@ -106,6 +117,7 @@ + K NNE @@ -121,7 +133,8 @@ 北北東 북북동 北北東 - 北北东 + 东北偏北 + KKD NE @@ -138,6 +151,7 @@ 북동 東北 东北 + KD ENE @@ -153,7 +167,8 @@ 東北東 동북동 東北東 - 东北东 + 东北偏东 + DKD E @@ -170,6 +185,7 @@ + D ESE @@ -185,7 +201,8 @@ 東南東 동남동 東南東 - 东南东 + 东南偏东 + DGD SE @@ -202,6 +219,7 @@ 남동 東南 东南 + GD SSE @@ -217,7 +235,8 @@ 南南東 남남동 南南東 - 南南东 + 东南偏南 + GGD S @@ -234,6 +253,7 @@ + G SSW @@ -249,7 +269,8 @@ 南南西 남남서 南南西 - 南南西 + 西南偏南 + GGB SW @@ -266,6 +287,7 @@ 남서 西南 西南 + GB WSW @@ -281,7 +303,8 @@ 西南西 서남서 西南西 - 西南西 + 西南偏西 + BGB W @@ -298,6 +321,7 @@ 西 西 + B WNW @@ -310,10 +334,11 @@ ONO NyÉNy ONO - 北北西 + 西北西 서북서 西北西 - 西北西 + 西北偏西 + BKB NW @@ -330,6 +355,7 @@ 북서 西北 西北 + KB NNW @@ -345,7 +371,8 @@ 北北西 북북서 北北西 - 北北西 + 西北偏北 + KKB Action cancelled. @@ -353,15 +380,16 @@ Acción cancelada. Przerwano czynność Akce přerušena - Action annulée. + Action annulée Действие отменено. Ação cancelada. Művelet megszakítva. Azione cancellata. - 動作を中止した。 + アクションを中断した。 행동 취소됨. 動作已被取消 动作已被取消 + Işlem iptal edildi. [ACE] Miscellaneous Items @@ -378,6 +406,7 @@ [ACE] 기타 물품. [ACE] 雜項 [ACE] 杂项 + [ACE] Çeşitli Nesneler Disable Command Menu @@ -386,14 +415,15 @@ Wyłącz menu dowodzenia Vypnout velící menu Désactiver menu commande - Выключить командное меню + Выкл. командное меню Parancsnoki menü kikapcsolása Disabilita menù di comando Desabilitar menu de comando 指揮メニューを無効化 - 지휘 메뉴 종료 + 지휘 메뉴 비활성화 關閉命令選單 - 关闭命令选单 + 关闭命令菜单 + Komut Menüsünü Devre Dışı Bırak Unknown @@ -410,13 +440,14 @@ 알 수 없음 未知的 未知的 + Bilinmeyen Normal Normal Normale Нормальное - Normale + Normal Normalne Normal Normális @@ -424,6 +455,9 @@ Normal 通常 보통 + 普通 + 正常 + Normal No Voice @@ -438,105 +472,99 @@ Sem voz 音声なし 무음 - 沒聲音 - 没声音 - - - Accept Requests - Anfrage akzeptieren - Aceptar peticiones - Akceptuj prośby - Přijmout žádost - Accepter requête - Принять запросы - Kérések elfogadása - Aceitar Pedido - Accetta la richiesta - 要求を受け入れ - 요청 수락 - 接受請求 - 接受请求 - - - Decline Requests - Anfrage ablehnen - Rechazar peticiones - Ignoruj prośby - Zamítnout žádost - Отклонить запросы - Rejeter requête - Kérések elutasítása - Rejeitar pedido - Rifiuta la richiesta - 要求を拒否 - 요청 거부 - 拒絕請求 - 拒绝请求 - - - Accept Requests send by other players. These can be requests to use / share equipment, perform certain actions. - Anfragen werden von anderen Mitspielen gestellt. Diese können Anfragen u.a. zum Teilen/Verwenden von Ausrüstungsgegenständen, oder auch zum Ausführen von Handlungen sein. - Acepta peticiones de otros jugadores. Pueden ser solicitudes para usar / compartir equipamiento, realizar ciertas acciones. - Akceptuj prośby wysłane przez innych graczy. Akceptacji wymagają między innymi akcje używania / współdzielenia wyposażenia, wykonywania określonych czynności. - Accetta le richieste degli altri giocatori. Queste possono riguardare l'uso o la condivisione dell'equipaggiamento, o di determinate azioni. - Přijimutí žádosti poslané jinými hráči. Mohou to být žádosti k použítí/sdílení vybavení nebo k vykonání určité činnosti. - Принять запросы, отправленные другими игроками. Например, запросы на использование/совместное использование снаряжения, выполнение определенных действий - Accepter les requêtes d'autres joueurs. Comme l'utilisation / l'échange d'équipement, la réalisation d'actions. - Más játékosok általi kérések elfogadása. Ezek a kérések vonatkozhatnak a felszerelés használatára/megosztására, valamint különböző cselekményekre. - Aceitar pedidos enviados por outros jogadores. Podem ser pedidos para usar/ compartilhar equipamento, realizar certas ações. - 他プレイヤからの要求を許可します。他プレイヤは装備を共有し、使うなど特定の動作を行えます。 - 다른 플레이어가 보내온 요청을 수락합니다. 이것은 장비 사용 / 공유 요청, 특정 작업 수행 등이 될 수 있습니다. - 接受由其他玩家送出的請求。包含使用/共享裝備與執行特定動作 - 接受由其他玩家送出的请求。包含使用/共享装备与执行特定动作。 - - - Decline Requests send by other players. These can be requests to use / share equipment, perform certain actions. - Anfragen werden von anderen Mitspielen gestellt. Diese können Anfragen u.a. zum Teilen/Verwenden von Ausrüstungsgegenständen, oder auch zum Ausführen von Handlungen sein. - Rechazar peticiones de otros jugadores. Pueden ser solicitudes para usar / compartir equipamiento, realizar ciertas acciones. - Ignoruj prośby wysłane przez innych graczy. Akceptacji wymagają między innymi akcje używania / współdzielenia wyposażenia, wykonywania określonych czynności. - Rifiuta le richieste degli altri giocatori. Queste possono riguardare l'uso o la condivisione dell'equipaggiamento, o di determinate azioni. - Zamítnutí žádostii poslané jinými hráči. Mohou to být žádosti k použítí/sdílení vybavení nebo k vykonání určité činnosti. - Отклонить запросы, отправленные другими игроками. Например, запросы на использование/совместное использование снаряжения, выполнение определенных действий - Rejeter les requêtes d'autres joueurs. Comme l'utilisation / l'échange d'équipement, la réalisation d'actions. - Más játékosok általi kérések elutasítása. Ezek a kérések vonatkozhatnak a felszerelés használatára/megosztására, valamint különböző cselekményekre. - Rejeita pedidos enviados por outros jogadores. Podem ser pedidos para usar/ compartilhar equipamento, realizar certas ações. - 他プレイヤからの要求を拒否します。他プレイヤは装備を共有し、使うなど特定の動作をできません。 - 다른 플레이어가 보내온 요청을 거부합니다. 이것은 장비 사용 / 공유 요청, 특정 작업 수행 등이 될 수 있습니다. - 拒絕由其他玩家送出的請求。包含使用/共享裝備與執行特定動作 - 拒绝由其他玩家送出的请求。包含使用/共享装备与执行特定动作。 + 無語音 + 无语音 + Ses yok Check PBO Action PBO Überprüfung Controlla Azioni PBO 檢查PBO動作 - 检查PBO动作 - PBO 検査の挙動 + 检查 PBO 动作 + PBO検査の挙動 PBO 검사 Sprawdź akcję PBO Действие при проверке PBO + Ação de Checar PBO + Comprobar PBO + Action à la vérification des PBOs + Zkontrolovat PBO + + + Defines the action to be taken if a player does not have the correct PBOs. + Définit l'action à effectuer si un joueur n'a pas les bons PBOs. + 設定當玩家有錯誤的PBO檔案時要如何處置。 + 设定当玩家有错误的 PBO 时要如何处理。 + Nastavuje jakou akci provést pokud hráč nemá správné PBO. + Określa akcję, która ma być podjęta, jeśli gracz nie ma właściwych PBO. + プレイヤーが不正規のPBOを所持している場合の動作を定義します。 + Define la accion a tomar si un jugador no tiene el PBO correcto + Definisce l'azione che verrà presa se il giocatore non ha gli stessi PBO. + Определяет, какое действие будет предпринято, если игрок не имеет корректные PBO. + Definiert, was passieren soll, wenn ein Spieler nicht die korrekten PBOs nutzt. + 플레이어가 같은 PBO를 가지고 있지 않을 시 취할 행동을 정합니다. + Define a ação a ser tomada se um jogador não tiver os PBOs corretos. Check PBO All Alle PBOs überprüfen Controlla Tutti i PBO 檢查所有PBO - 检查所有PBO - PBO 全てを検査 + 检查所有 PBO + 全てのPBOを検査 모든 PBO 검사 Sprawdź wszystkie PBO Проверять все PBO + Checar Todos os PBOs + Comprobar todos los PBO + Vérifier tous les PBOs + Zkontrolovat všechny PBO + + + Check all addons, not only those of ACE. + Vérifie tous les addons, même ceux qui ne sont pas liés à ACE. + Controlla tutti gli addon, non solo quelli ACE. + 檢查全部的插件而非只有ACE。 + 检查全部插件而非只有 ACE。 + Zkontrolovat všechny addony a ne jenom ACE. + Sprawdź wszystkie dodatki, nie tylko ACE. + ACE だけでなく、全てのアドオンを検査します。 + Comprueba todos los complementos, no sólo los de ACE + Проверять все аддоны, а не только ACE. + Überprüft alle Erweiterungen, nicht nur die von ACE. + ACE 뿐만이 아닌 다른 PBO 모두 검사합니다. + Verifica todos os addons, não apenas os do ACE. Check PBO Whitelist PBO Whitelist Controlla Whitelist PBO 檢查PBO白名單 - 检查PBO白名单 - 許可リスト内の PBO を検査 - 검사 제외 PBO + 检查 PBO 白名单 + PBO 検査のホワイトリスト + PBO 화이트리스트 확인 Sprawdź białą listę PBO Белый список для проверки PBO + Lista Branca de PBO + Comprobar lista blanca de PBOs + Vérifier les PBOs en liste blanche + Zkontrolovat PBO proti whitelistu + + + Define a list of regardless allowed addons. + Permet de définir une liste d'addons autorisés systématiquement. + Definisce una lista di PBO permessi in ogni caso. + 定義哪些插件是允許使用的。 + 定义哪些插件是允许使用的。 + Nastavte seznam addonů, které jsou povolené. + Zdefiniuj listę niezależnie od dozwolonych dodatków. + 関係なく使用が許可されるアドオンのリストを定義します。 + Comprueba la lista de PBOs permitidos + Задать список непроверяемых аддонов. + Ermöglicht das Erstellen einer Liste von immer erlaubten Erweiterungen. + 허용된 애드온 목록을 정의합니다. + Define uma lista de addons permitidos. Feedback icons @@ -545,7 +573,7 @@ Icone informative Иконки состояний Ikony pomocnicze - Icones d'information + Icônes d'information Pomocné ikony Visszajelző ikonok Ícones de Feedback @@ -561,21 +589,21 @@ Seleziona la posizione o disabilita le icone informative sul tuo schermo. Queste saranno mostrate per fornire informazioni aggiuntive sullo stato o sulle azioni del giocatore. Выберите положение или или отключите отображение иконок состояний на Вашем экране. Эти иконки предоставят дополнительную информацию о состоянии персонажа и выполняемых действиях. Ustaw pozycję lub wyłącz całkowicie ikony pomocnicze na ekranie. Te ikony dostarczają dodatkowych informacji na temat statusu Twojej postaci i wykonywanych przez nią akcji. - Sélection de la position ou la désactivation des icones de feedback. Ces icones vous apportent des informations complémentaires sur votre status et sur les actions en cours. + Permet de sélectionner la position des icônes de feedback sur l'écran, ou de les désactiver.\nCes icônes vous apportent des informations supplémentaires sur votre personnage et sur les actions effectuées. Nastavuje pozici nebo vypíná pomocné ikony. Tyto ikony ukazují extra informace ke stavu postavy a vykonávaných činností. Itt beállítható a visszajelző ikonok képernyőn lévő helyzete és jelenléte. Ezek az ikonok extra visszajelzést biztosítanak a karaktered állapotán és végrehajtott cselekvésein. Selecione a posição ou disabilite a posição dos ícones de feedback na sua tela. Esses ícones irão aparecer para mostrar feedback extra do status do seu personagem e ações realizadas. - 画面上に表示するフィードバック アイコンの位置や無効化を選択できます。このアイコンは自キャラクター状態や動作の状況をフィードバックするために表示されています。 + 画面上のフィードバック アイコンの位置を選択するか、無効にします。 これらのアイコンは、キャラクターのステータスと実行されたアクションに関する追加のフィードバックを提供するために表示されます。 피드백 아이콘의 위치를 설정하거나 비활성화합니다. 피드백 아이콘은 캐릭터의 상세정보와 행동을 보여줍니다. 選擇位置或取消回饋圖標顯示在螢幕上。這些圖標將顯示出你角色額外的狀態與行動等資訊 - 选择位置或取消回馈图标显示在荧幕上。这些图标将显示出你角色额外的状态与行动等资讯。 + 选择位置或取消回馈图标显示在屏幕上。这些图标将显示出你角色额外的状态与行动等信息。 Progress bar location Position der Fortschrittsanzeige Ubicación de la barra de progreso Posizione della barra di avanzamento - Положение прогресс-бара + Положение индикатора процесса Lokalizacja paska postępu Position de la barre de progression Pozice ukazetele průběhu činnosti @@ -593,7 +621,7 @@ Modifica la posizione della barra di avanzamernto sullo schermo Установите желаемое положение строки состояния на экране. Ustaw pożądaną lokalizację paska postępu na ekranie - Appliquer la position de la barre de progression sur l'écran + Définit la position de la barre de progression sur l'écran. Nastavuje pozici ukazetele průběhu činnosti na vaší obrazovce. Itt beállítható az állapotjelző sáv képernyődön lévő helyzete. Define o local desejado da barra de progresso na sua tela. @@ -609,7 +637,7 @@ Colore di sfondo dei suggerimenti Цвет фона всплывающих подсказок Kolor tła powiadomień - Notification: couleur de l'arrière plan + Notifications - couleur de l'arrière-plan Barva pozadí nápovědy Súgó háttérszíne Cor do fundo da hint @@ -625,14 +653,14 @@ Il colore di sfondo dei suggerimenti di ACE. Цвет фона всплывающих подсказок АСЕ. Kolor tła dla powiadomień ACE - Notification ACE: couleur de l'arrière plan + Définit la couleur d'arrière-plan des notifications ACE. Barva pozadí ACE nápovědy. Az ACE-súgók hátterének színe. A cor de fundo das hints do ACE. ACE によるヒントの背景色を指定します。 ACE힌트의 배경색을 정합니다. 設定ACE提示的背景顏色. - 设定ACE提示的背景颜色. + 设定 ACE 提示的背景颜色。 Hint text font color @@ -641,11 +669,11 @@ Il colore del testo dei suggerimenti Цвет шрифта всплывающих подсказок Kolor tekstu powiadomień - Notification: couleur du texte + Notifications - couleur du texte Barva fontu nápovědy. Súgószöveg betűinek színe Cor do do texto da hint - ヒント文章の色 + ヒント文章の文字色 힌트 글씨색 提示文字的顏色 提示文字的颜色 @@ -657,36 +685,58 @@ Il colore del testo dei suggerimenti di ACE. Questo è il colore predefinito per tutto il testo mostrato dal sistema di suggerimenti di ACE quando il colore del testo non ha altro colore specificato. Цвет шрифта текста всплывающих подсказок АСЕ. Этот цвет является стандартным для всего текста, транслирующегося через систему подсказок АСЕ, если не установлено другого цвета для текста подсказок. Kolor tekstu dla powiadomień ACE. Ten kolor jest domyślnym dla wszystkich tekstów wyświetlanych poprzez System Powiadomień ACE, jeżeli dla powiadomienia nie określono innego koloru. - Notification ACE: couleur du texte. C'est la couleur par défaut de tout texte affiché dans les notifications ACE, si aucune couleur n'est spécifiée pour les notifications + Définit la couleur du texte des notifications ACE.\nCette couleur est la couleur par défaut pour tout texte affiché par le système de notifications ACE, si aucune autre couleur n'est spécifiée. Barva fontu ACE nápověd. Toto je standardní barva pro všechen text zobrazovaný ACE nápovědami, pokud nemá nápověda žádnou specifikanou barvu. Az ACE-súgók betűkészletének színek. Ez a szín alapértelmezett az összes szövegre az ACE-súgórendszerben, ha a súgószöveg maga nem ad meg más színt. A cor do texto das hints do ACE. Essa cor é a cor default para todos os texos exibidos pelo sistema de hints do ACE , caso o texto da hint não tem outra cor especificada. - ACE によるヒントの文章へ、色を設定できます。この色は ACE ヒント システムを介して表示される全文章の色と標準でなっており、特定の色を設定していても、標準色になります。 + ACE ヒント文章の文字色。 ヒント文章に他の色が指定されていない場合、この色は、ACE ヒント システムを通じて表示されるすべての文章の標準色になります。 ACE 힌트에 쓰이는 글씨 색입니다. 힌트 글씨의 색이 정해지지 않을경우 모든 힌트의 색은 기본으로 설정됩니다. 設定ACE提示文字的顏色。若提示字體並無指定其他顏色,將會自動選用ACE系統的預設顏色 - 设定ACE提示文字的颜色。若提示字体并无指定其他颜色,将会自动选用ACE系统的预设颜色。 + 设定 ACE 提示文字的颜色。若提示字体并无指定其他颜色,将会自动选用 ACE 的预设颜色。 + + + Colors + Barvy + Couleurs + Farben + Colori + Kolory + Cores + Цвета + Colores + + 颜色 + 색상 Persistent weapon laserpointer/flashlight Автоматический ЛЦУ/тактический фонарь - 武器のレーザー ポインタ/フラッシュライトの永続 - Laser/torcia dell'arma costantemente accesi - 무기 레이저 포인터 / 손전등 지속 + 武器のレーザー ポインター/フラッシュライトの永続性 + Laser/torcia dell'arma rimangono accesi + 무기 레이저 지시기/손전등 지속 Kontinuität des Laserpointers/Taktischen Lichts 保持武器雷射/手電筒的狀態 - 保持武器雷射/手电筒的状态 + 保持武器激光/手电筒的状态 Trwały znacznik laserowy/latarka + Luz da lanterna/laser da arma persistente + Rémanence du pointeur laser/de la lampe torche + Perzistentní laser/baterka na zbrani + Punto láser/Linterna persistente en arma Enable gunlight after weapon switch or vehicle enter/exit if it was previously enabled. Включать ЛЦУ/тактический фонарь после смены оружия или входа/выхода из машины, если он был до этого включен. 銃のライト等を点けていると武器を切り替えた後や車両を乗り降りしても、ライト等を点けたままにします。 Abilita la torcia/laser dopo il cambio dell'arma o l'entrata/uscita del veicolo se precedentemente attiva. - 무기를 바꾸거나 차량에 승하차 할 때 이전에 스위치 켜고 끔을 유지합니다. + 이전에 무기의 손전등/레이저를 켠 경우 무기 전환이나 차량 승하차시 켠 상태를 유지합니다. Aktiviert Laserpointer/Taktisches Licht nach einem Waffenwechsel oder dem Auf-/Absitzen, falls es zuvor aktiv war. - 保存武器雷射/手電筒的開關狀態,使玩家切換武器或進出載具時能保持之前的的狀態 - 保存武器雷射/手电筒的开关状态,使玩家切换武器或进出载具时能保持之前的的状态。 + 保存武器雷射/手電筒的開關狀態,使玩家切換武器或進出載具時能保持之前的狀態 + 保持武器激光/手电筒的开关状态,使玩家切换武器或进出载具时能保持之前的状态。 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. + Si le pointeur laser/la lampe torche est allumé(e), cette option permet de le/la réallumer automatiquement après un changement d'arme, ou après une entrée/sortie d'un véhicule. + Pokud jsou zaplé, zapíná laser/baterku po přepnutí zbraně nebo po nástupu/výstupu z vozidla. + Habilita la luz en el arma después de cambiarla o tras la entrada/salida de un vehículo si estaba préviamente habilitada Banana @@ -699,7 +749,7 @@ Banane Banán Banana - 甘蕉 + バナナ 바나나 香蕉 香蕉 @@ -713,12 +763,12 @@ Банан - это съедобный фрукт, ягода с ботанической точки зрения, произрастающий на нескольких видах травянистых растениях рода Банан (Musa). A banán egy ehető gyümölcs, technikai szempontból bogyótermés, melyet több fürtvirágzatú növény termel a Musa rendszertani nemzetségben. Rodzaj roślin z rodziny bananowatych, obejmujący około 80 gatunków.<br />Przedstawiciele są typowymi przedstawicielami flory międzyzwrotnikowej Azji, Afryki i Australii.<br />Część gatunków dostarcza jadalnych owoców. Słowo banan pochodzi prawdopodobnie od arabskiego słowa banan, co oznacza palec, lub afrykańskiego języka wolof, w którym rośliny te określa się mianem banaana. - Une banane est un fruit qui, d'un point de vue botanique, fait partie du groupe des baies. Produite par plusieurs sortes de grandes plantes à fleurs herbacées du type Musa. + Une banane est un fruit comestible qui, d'un point de vue botanique, fait partie du groupe des baies.\nProduite par plusieurs espèces de grandes plantes à fleurs herbacées du genre Musa. A banana é uma fruta comestível, botanicamente uma baga, produzida por vários tipos de plantas herbáceas grandes do genero Musa. - 甘蕉は食べられる果物でバショウ科バショウ属のうち、果実を食用とする品種群の総称。また、その果実のこと。いくつかの原種から育種された多年草。種によっては熟すまでは毒を持つものもある。 + バナナは、バショウ科バショウ属のうち、果実を食用とする品種群の総称である。また、その果実のこと。いくつかの原種から育種された多年性植物。熱帯~亜熱帯の地域で栽培されるトロピカルフルーツ。種によっては熟すまでは毒を持つものもある。 바나나는 식용 과일로써 식물학적으로 열매류이며 여러 종류의 개화가능한 초본의 파초과로 부터 생산됩니다. 香蕉(學名: Musa × paradisiaca),為芭蕉科芭蕉屬小果野蕉及野蕉的人工栽培雜交種,為多年生草本植物。果實長有棱; 果皮黃色,果肉白色,味道香甜。主要生長在熱帶、亞熱帶地區。原產於亞洲東南部熱帶、亞熱帶地區 - 香蕉(学名: Musa × paradisiaca),为芭蕉科芭蕉属小果野蕉及野蕉的人工栽培杂交种,为多年生草本植物。果实长有棱; 果皮黄色,果肉白色,味道香甜。主要生长在热带、亚热带地区。原产于亚洲东南部热带、亚热带地区。 + 香蕉(学名:Musa paradisiaca),为芭蕉科芭蕉属小果野蕉及野蕉的人工栽培杂交种,为多年生草本植物。果实长有棱; 果皮黄色,果肉白色,味道香甜。主要生长在热带、亚热带地区。原产于亚洲东南部热带、亚热带地区。 Check PBOs @@ -727,14 +777,14 @@ Überprüfe PBOs Zkontrolovat soubory PBO Verificar PBOs - Vérifier les PBOs + /!\ Module obsolète /!\ - Vérifier les PBOs PBO-k ellenőrzése Проверка аддонов Controlla PBO - PBO を検査 + PBOを検査 PBO 검사 檢查PBO檔 - 检查PBO档 + 检查 PBO Check addon integrity with server and do selected action if an addon is missing. @@ -744,12 +794,12 @@ Zjistit addon který je v souladu se serverem Este módulo verifica a integridade dos addons quando iniciamos a simulação Выполняет проверку версий аддонов ACE у подключаемых игроков - Ce module contrôle si les PBOs de chaque joueur sont corrects + /!\ Module obsolète /!\ - Vérifie l'intégrité des addons avec le serveur, et effectue l'action sélectionnée si un addon est manquant. Controlla l'integrità degli addon con il server ed esegui l'azione selezionata se un addon è mancante - サーバがアドオンの整合性を検査し、もし不備があれば実行する動作を選択できます。 - 서버 에드온의 무결성을 검사하고 사라진 에드온이 있을경우 행동을 선택합니다. + サーバーとのアドオンの整合性をチェックし、不備があった場合は選択したアクションを実行します。 + 서버 애드온의 무결성을 검사하고 사라진 애드온이 있을 경우 행동을 선택합니다. 檢查客戶端與伺服器端的模組清單是否一致且完整,並提供訊息表示遺失的模組 - 检查客户端与伺服器端的模组清单是否一致且完整,并提供讯息表示遗失的模组。 + 检查客户端与服务器端的模组清单是否一致且完整,并提供信息表示遗失的模组。 Action @@ -758,7 +808,7 @@ Aktion Akce Ação - Action + /!\ Module obsolète /!\ - Action Cselekvés Действие Azione @@ -774,14 +824,14 @@ Was soll mit Leuten geschehen, die nicht die richtigen PBO-Dateien geladen haben? Co udělat s lidmi, co nemají správné addony? O que fazer com pessoas que não tem os PBOs corretos? - Que faire avec les personnes n'ayant pas les bons PBO ? + /!\ Module obsolète /!\ - Définit l'action à effectuer si un joueur n'a pas les bons PBOs. Mi legyen azokkal a személyekkel, akiknek nincsenek meg a helyes PBO-k? Что делать с игроками с неправильными аддонами? Cosa fare con giocatori che non hanno i PBO corretti? - プレイヤーが正しい PBO を持っていない場合は? - 올바르지 않는 PBO를 가진 사람을 어떻게 할까요? + プレイヤーが正しいPBOを持っていない場合は? + 올바르지 않은 PBO를 가진 사람을 어떻게 할까요? 若玩家沒有正確的PBO檔時,將採取何種動作? - 若玩家没有正确的PBO档时,将采取何种动作? + 若玩家没有正确的 PBO 档时,将采取何种动作? Warn once @@ -794,10 +844,11 @@ Egyszeri figyelmeztetés Предупредить один раз Avverti una volta - 一度の警告 + 一度警告 경고 한 번 警告 (一次) - 警告 (一次) + 警告(一次) + UYAR Warn (permanent) @@ -806,14 +857,15 @@ Verwarnen (permanent) Upozornit (permanentně) Avisar (permanente) - Avertir (permanent) + Avertir (systématiquement) Figyelmeztetés (tartós) Предупреждать (постоянно) Avverti (permanente) - 警告 (永久的) + 警告 (永続) 경고 (영구적) 警告 (持續) - 警告 (持续) + 警告(持续) + UYAR (KALICI) Kick @@ -822,7 +874,7 @@ Kicken Vyhodit Chutar - Ejecter + Éjecter Kirúgás Кикнуть Kick @@ -830,6 +882,7 @@ 추방 踢除 踢除 + AT Check all addons @@ -838,12 +891,12 @@ Alle Addons überprüfen Zkontrolovat všechny addony Verificar todos addons - Vérifier tous les addons + /!\ Module obsolète /!\ - Vérifier tous les addons Összes bővítmény ellenőrzése Проверять все аддоны Controlla tutti gli addon 全アドオンを検査 - 모든 에드온 검사 + 모든 애드온 검사 檢查所有模組 检查所有模组 @@ -854,14 +907,14 @@ Alle Addons anstatt nur ACE überprüfen? Zkontrolovat všechny addony namísto jen těch od ACE? Verificar todos addons invés de só os do ACE? - Vérifie tous les addons, même ceux qui ne sont pas liés à ACE + /!\ Module obsolète /!\ - Vérifie tous les addons, même ceux qui ne sont pas liés à ACE. Az összes bővítmény ellenőrzése, csak az ACE helyett? Проверять все аддоны, а не только ACE? Controlla tutti gli addon invece dei soli addon ACE? - ACE MOD の代わりに全アドオンを検査しますか? + ACE のアドオンだけではなく、すべてのアドオンをチェックしますか? ACE를 제외한 모든 모드를 검사할까요? 檢查包含ACE之外的其他模組? - 检查包含ACE之外的其他模组? + 检查包含 ACE 之外的其他模组? Whitelist @@ -870,14 +923,15 @@ Whitelist Seznam povolených Lista branca - Liste blanche + /!\ Module obsolète /!\ - Liste blanche Fehérlista Вайтлист доп. аддонов Lista Bianca - 許可制 + ホワイトリスト 화이트리스트 白名單 白名单 + Beyaz Liste What addons are allowed regardless? @@ -886,14 +940,14 @@ Welche Addons werden dennoch erlaubt? Jaké addony jsou povoleny? Quais addons são permitidos de qualquer maneira? - Quels addons sont tolérés ? + /!\ Module obsolète /!\ - Permet de définir une liste d'addons autorisés systématiquement. Milyen bővítmények vannak feltétlenül engedélyezve? Какие аддоны дополнительно разрешены? Quali addon sono permessi in ogni caso? どのようなアドオンを許可しますか? - 허가되는 에드온은 어느것입니까? + 허가되는 애드온은 어느 것입니까? 哪些模組是可被允許/忽略的? - 哪些模组是可被允许/忽略的? + 无论如何都允许的附加组件 LSD Vehicles @@ -918,14 +972,14 @@ Fügt einen LSD-Effekt zum synchronisierten Fahrzeug hinzu Přidá LSD efekt pro synchronizované vozidla Adiciona efeito LSD ao veículo sincronizado - Ajoute l'effet LSD aux véhicules synchronisés + Ajoute l'effet LSD aux véhicules synchronisés. LSD-effekt hozzáadása a szinkronizált járművekhez Добавляет эффект LSD (мигание всеми цветами радуги) синхронизированным транспортным средствам Aggiunge effetti LSD ai veicoli sincronizzati - 同期されたオブジェクトに LSD の効果を追加します - 동기화된 차량에 LSD효과를 추가합니다. + 同期された車両に LSD 効果を追加します + 동기화된 차량에 LSD 효과를 추가합니다. 使被同步的載具產生瘋狂的迷幻效果。(後果自負) - 使被同步的载具产生疯狂的迷幻效果。(后果自负) + 使被同步的载具产生疯狂的迷幻效果。(后果自负) Toggle Handheld Device @@ -934,11 +988,11 @@ Ativa dispositivo de mão Przełącz urządzenie podręczne Přepnout ruční zařízení - Allumer l'ordinateur de poche + Allumer l'appareil portatif Kézi eszköz kapcsolása Включить портативное устройство Apri dispositivo palmare - デバイスを常に表示 + 携帯装置の表示を切り替え 휴대장치 토글 切換手持裝備 切换手持装备 @@ -950,11 +1004,11 @@ Fecha dispositivo de mão Zamknij urządzenie podręczne Zavřít ruční zařízení - Fermer l'ordinateur de poche + Éteindre l'appareil portatif Kézi eszköz bezárása Закрыть портативное устройство Chiudi dispositivo palmare - デバイスを閉じる + 携帯装置を閉じる 휴대장치 닫기 關閉手持裝備 关闭手持装备 @@ -966,11 +1020,11 @@ Troca dispositivos de mão Następne urządzenie podręczne Procházet ruční zařízení - Changer (cycle) d'ordinateur de poche + Changer d'appareil portatif Kézi eszköz váltása Следующее портативное устройство Cicla tra dispositivi palmari - 表示するデバイスを変える + 表示する携帯装置をサイクル 휴대장치 순환 循環切換手持裝備 循环切换手持装备 @@ -978,38 +1032,50 @@ Disabled Zakázáno - Désactiver + Désactivé Deaktiviert Disattivato Wyłączone Desativado - Откл. + Отключено Desactivado 無効化 비활성화 停用 停用 + Devre Dışı Enabled Povoleno - Activer + Activé Aktiviert Attivato Włączone Ativado - Вкл. + Включено Activado 有効化 활성화 啟用 启用 + Etkin Always Immer 常に Всегда + Sempre + Siempre + Toujours + 一直 + Sempre + Vždy + Zawsze + Her Zaman + 总是 + 항상 Anywhere @@ -1024,6 +1090,9 @@ Ovunque どこでも 어디서나 + 任何地方 + 任何地方 + Herhangi bir yer Basic @@ -1038,6 +1107,9 @@ Basico ベーシック 기본 + 基礎 + 基础 + Basit Medical Vehicles @@ -1047,11 +1119,14 @@ Sanitätsfahrzeuge Zdravotnická vozidla Veículos médcos - Dans les véhicules médicals + Dans les véhicules médicaux Orvosi járművek Veicoli medici 医療車両のみ 의료차량 + 醫療載具 + 医疗载具 + Medikal Araçlar Yes @@ -1068,6 +1143,7 @@ + Evet No @@ -1084,18 +1160,39 @@ 아니오 + Hayır Confirm 確認 Bestätigen Подтвердить + Confirmar + Confirmar + Confirmer + 確認 + 确认 + Conferma + Potvrdit + Potwierdź + Onayla + 확인 Never 行わない Nie Никогда + Nunca + Nunca + Jamais + 從不 + 从不 + Mai + Nikdy + Nigdy + Hiçbir zaman + 안함 Vehicles only @@ -1111,6 +1208,7 @@ 차량 전용 只有載具 只有载具 + Sadece Arabalar Do Not Force @@ -1123,9 +1221,10 @@ Non forzare Ne pas forcer 強制しない - 강제하지 말것 + 강제하지 말 것 不要強行 不要强行 + Zorlama ACE Equipment @@ -1136,11 +1235,12 @@ ACE Vybavení ACE Equipo ACE Equipaggiamento - ACE Equipement + ACE Équipement ACE 装備 ACE 장비 ACE 裝備按鍵 - ACE 装备按键 + ACE 装备 + ACE Ekipmanlar ACE Common @@ -1152,10 +1252,11 @@ ACE Obecné ACE Comune ACE Commun - ACE 全般 + ACE 一般 ACE 일반 ACE 通用按鍵 - ACE 通用按键 + ACE 通用 + ACE Common ACE Weapons @@ -1170,7 +1271,8 @@ ACE 武器 ACE 무기 ACE 武器按鍵 - ACE 武器按键 + ACE 武器 + ACE Silahlar ACE Movement @@ -1185,7 +1287,8 @@ ACE 移動 ACE 움직임 ACE 動作按鍵 - ACE 动作按键 + ACE 移动 + ACE Hareket ACE Scope Adjustment @@ -1196,11 +1299,11 @@ ACE Nastavení optiky ACE Ajuste de miras ACE Regolazione Ottiche - ACE Ajustement de la lunette + ACE Réglage des lunettes ACE スコープ調節 ACE 조준경 조정 ACE 瞄準鏡調節按鍵 - ACE 瞄准镜调节按键 + ACE 瞄准镜调节 ACE Vehicles @@ -1211,11 +1314,25 @@ ACE Vozidla ACE Vehículos ACE Veicoli - ACE Vehicules + ACE Véhicules ACE 車両 ACE 차량 ACE 載具按鍵 - ACE 载具按键 + ACE 载具 + ACE Araçlar + + + ACE Uncategorized + ACE 未分类 + ACE 무분류 + ACE Unkategorisiert + ACE Non-Categorizzati + ACE Nieskategoryzowane + ACE 未分類 + ACE Без категории + ACE Sin categoría + ACE Non classé + ACE Sem Categoria No Room to unload @@ -1230,11 +1347,28 @@ 降ろすための空間がありません 沒有空間可卸載 没有空间可卸载 - 언로드 할 공간이 없습니다. + 내릴 공간이 없습니다. + + + No inventory space + Kein Platz im Inventar + Sin espacio en inventario + Brak miejsca w ekwipunku + Pas de place dans l'inventaire + Nedostatek místa v inventáři + Sem espaço no inventário + Non hai più spazio + Nincs több hely + В инвентаре нет места + インベントリに空きがない + 넣을 공간이 없습니다 + 無可用空間 + 无可用空间 + Envanter de alan yok Toggle - переключить + Przełącz переключить Basculer Cambiar @@ -1247,6 +1381,7 @@ 토글 切換 切换 + Değiştir Weight: @@ -1261,8 +1396,9 @@ Вес: 重量: 무게: - 重量: + 重量: 重量: + Ağırlık: Allow turning down music @@ -1274,37 +1410,85 @@ Permesso di abbassare la musica Zezwól na przyciszanie muzyki Разрешить приглушение музыки + Permite diminuir volume da música + Permission d'abaisser la musique + Povolit snížení hlasitosti hudby + Permitir reducir el volumen de la música + Müziği kısmaya izin ver Allow ACE scripts to turn down the music. Erlaube ACE-Skripten, die Musik leiser zu stellen. ACE 스크립트가 음악을 끌 수 있습니다. 允許ACE腳本去控制音樂的音量 - 允许ACE脚本去控制音乐的音量。 - ACE スプリントへ音量低下を許可します。 + 允许 ACE 脚本去控制音乐的音量。 + 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. + Autorise les scripts ACE à baisser le volume de la musique. + Povolit ACE skriptům snížit hlasitost hudby + Permitir a los scripts de ACE reducir el volumen la música + ACE scripti müziği kısmana izin verir + + + Epilepsy friendly mode + Epilepsiefreundlicher Modus + けいれん回避モード + Tryb dla epileptyków + Mode adapté à l'épilepsie + Modalità per Epilettici + 癫痫病友好模式 + 광과민 친화적 모드 + Режим для эпилептиков + Modo adaptado para epilepsia + Modo adaptado para epilepsia + + + Disables some flashing light effects to reduce seizure risk. + Deaktiviert einige Lichtflackereffekte um das Risiko von Epilepsieanfällen zu reduzieren. + いくつかの光点滅エフェクトを無効化し、けいれんの恐れを低下させます。 + Wyłącz część migających efektów w celu zredukowania ryzyka napadu epilepsji + Désactive certains effets de lumière clignotante afin de réduire les risques de crise d'épilepsie. + Disattiva alcuni effetti di luci intermittenti per ridurre il rischio di crisi epilettiche. + 禁用一些闪烁的灯光效果,以降低癫痫发作的风险。 + 반짝거리는 빛으로 인해 일어날 발작 상황을 줄여줍니다. + Отключает некоторые вспышки во избежание риска приступа. + Deshabilita algunos efectos de iluminación para reducir el riesgo de convulsiones. + Desabilita alguns efeitos de luz para reduzir o risco de convulsões. Flag (ACE - Black) Flagge (Ace - Schwarz) - 旗帜(ACE-黑色): + 旗帜(ACE-黑色): 旗幟(ACE-黑色) Bandiera (ACE - Nera) 旗 (ACE - 黒) Flaga (ACE - Czarna) Флаг (ACE - Черный) + Bandeira (ACE - Preto) + Drapeau (ACE - Noir) + Vlajka (ACE - Černá) + Bayrak (ACE- Siyah) + Bandera (ACE - Negra) + 깃발 (ACE 검정) Flag (ACE - White) Flagge (Ace - Weiß) - 旗帜(ACE-白色): + 旗帜(ACE-白色): 旗幟(ACE-白色) Bandiera (ACE - Bianca) 旗 (ACE - 白) Flaga (ACE - Biała) Флаг (ACE - Белый) + Bandeira (ACE - Branco) + Drapeau (ACE - Blanc) + Vlajka (ACE - Bílá) + Bayrak (ACE - Beyaz) + Bandera (ACE - Blanca) + 깃발 (ACE 하양) Players only @@ -1314,13 +1498,27 @@ Nur Spieler Pouze hráči Somente jogadores - Joueur uniquement + Joueurs uniquement Csak játékosok Solo giocatori プレイヤーのみ 플레이어만 只限玩家 只限玩家 + Sadece oyuncular + + + AI only + Tylko dla AI + 인공지능만 + Nur KI + Solo IA + 仅 AI + AIのみ + Только ИИ + Sólo IA + IA uniquement + Somente IA Players and AI @@ -1333,10 +1531,406 @@ Joueurs et IA Játékosok és AI Giocatori ed IA - プレイヤーと AI + プレイヤーとAI 플레이어 및 인공지능 - 玩家与AI + 玩家与 AI 玩家與AI + Oyuncular ve AI + + + Show the action in the self-interaction menu + Affiche l'action dans le menu d'interaction personnel. + 在自我互動選單內顯示動作 + 在自我互动菜单内显示动作 + Pokaż akcje w menu interakcji własnej + Mostra a ação no menu de auto-interação + セルフ インタラクションにアクションを表示 + Mostra le azioni nel menu di interazione con se stessi + Mostrar la acción en el menú de interacción propio + Zobrazit akci v menu vlastních interakcí + Показывать действие в меню взаимодействия с собой. + Kendi etkileşimim menüsünde animasyonları göster + Zeigt die Aktion im Selbstinteraktionsmenü + 자기 상호작용 메뉴에서 행동을 보여줍니다 + + + Both + İkisi de + 両方 + Les deux + Оба + Beide + Entrambi + Oba + 两方 + 둘 다 + Ambos + Ambos + + + Additional progress bar information + プログレス バーの詳細情報 + Infos supplémentaires de la barre de progression + Доп. информация индикатора процесса + Zusätzliche Informationen beim Fortschrittsbalken + Info aggiuntive sulla barra del progresso + Dodatkowe informacje na pasku postępu + 额外的进度条信息 + 추가 진행 막대 정보 + Barra adicional de información de progreso + Informações adicionais na barra de progresso + + + Controls extra information shown in progress bar. + プログレス バーへ表示される情報量を制御します。 + Définit quelles informations supplémentaires sont affichées dans la barre de progression. + Устанавливает дополнительную информацию в индикаторе процесса. + Kontrolliert zusätzliche Informationen beim Fortschrittsbalkens. + Mostra ulteriori informazioni nella barra di avanzamento. + Kontroluje dodatkowe informacje na pasku postępu. + 控制进度条中显示的额外信息。 + 진행 막대에 추가적인 정보를 보여주는걸 결정합니다. + Controla la información extra mostrada en la barra de progreso. + Controla informações adicionais mostradas na barra de progresso. + + + Percentage + パーセンテージ + Pourcentage + Процент выполнения + Prozent + Percentuale + Procent + 百分比 + 백분율 + Porcentaje + Porcentagem + + + Time remaining + 残り時間 + Temps restant + Времени осталось + Zeit verbleibend + Tempo rimanente + Pozostały czas + 剩余时间 + 남은 시간 + Tiempo restante + Tempo restante + + + None + Žádná + Keine + Нет + Brak + Nessuna + Nada + Aucune + + なし + 활성화 없음 + Nenhuma + + Yok + + + Rename + Renombrar + Renommer + Umbenennen + Zmień nazwę + 名前変更 + Rinomina + 이름 바꾸기 + 重新命名 + 重新命名 + Переименовать + Renomear + Přejmenovat + Yeniden adlandır + + + Time left: %1s + 残り時間: %1秒 + Temps restant : %1 s + Оставшееся время: %1s + Zeit übrig %1s + Tempo rimanente: %1s + Pozostały czas: %1s + 剩余时间:%1秒 + 남은 시간: %1초 + Tiempo restante: %1s + Tempo restante: %1s + + + Locations Boost Training + Zdravotnická místa zvyšují zdravotnickou úrovně + Luoghi che potenziano le abilità + Örtliche Trainingssteigerung + Ubicación mejora entrenamiento. + Miejsca zwiększają wyszkolenie + Localização melhora treinamento + Le lieu améliore l'efficacité + Места ускоренного обучения + 能力が向上する場所 + 교육 증가 지역 + 位置提升能力 + 受所在位置影響提升醫療能力 + Konumlar Tedaviyi Hızlandırır + + + Unload Weapon + Wyładuj Broń + 武器からマガジンを抜く + 탄창 빼기 + 卸掉武器弹匣 + Разрядить оружие + Descargar arma + Waffe entladen + Scarica Arma + Décharger l'arme + Descarregar arma + + + Load + Beladen + Załaduj + Carregar + Загрузить + Naložit + Cargar + Carica + Charger + 積み込む + 싣기 + 裝載 + 装载 + Yükle + + + Hide + Ukryj + Ocultar + Verstecken + Skrýt + Ocultar + Cacher + Elrejtés + Скрыть + Nascondi + 非表示 + 숨기기 + 隐藏 + 隱藏 + Gizle + + + Top right, downwards + Po prawej u góry, w dół + Arriba a la derecha, hacia abajo + Oben rechts, nach unten + Vpravo nahoře, dolů + Superior direito, para baixo + En haut à droite, vers le bas + Jobb felül, lefele + Справа — сверху вниз + In Alto a Destra, verso il Basso + 右上、下向 + 오른쪽 위에서 아래로 + 右上角,向下 + 右上角,向下 + Sağ üst, aşağı + + + Top right, to the left + Po prawej u góry, do lewej + Arriba a la derecha, hacia la izquierda + Von rechts nach links + Vpravo nahoře, do leva + Superior direito, à esquerda + En haut à droite, vers la gauche + Jobb felül, balra + Сверху — справа налево + In Alto a Destra, verso Sinistra + 右上、左向 + 오른쪽 위에서 왼쪽으로 + 右上角,向左 + 右上角,向左 + Sağ üstte, solda + + + Top left, downwards + Po lewej u góry, w dół + Arriba a la izquierda, hacia abajo + Von links, nach unten + Vlevo nahoře, dolů + Superior esquerdo, para baixo + En haut à gauche, vers le bas + Bal felül, lefele + Слева - сверху вниз + In Alto a Sinistra, verso il Basso + 左上、下向 + 왼쪽 위에서 아래로 + 左上角,向下 + 左上角,向下 + Sol üst, aşağı + + + Top left, to the right + Po lewej u góry, do prawej + Arriba a la izquierda, hacia la derecha + Oben links nach rechts + Vlevo nahoře, do prava + Superior esquerdo, para a direita + En haut à gauche, vers la droite + Bal felül, jobbra + Сверху — слева направо + In Alto a Sinistra, verso Destra + 右上、右向 + 왼쪽 위에서 오른쪽으로 + 左上角,向右 + 左上角,向右 + Sol üst, sağa + + + Top + Góra + Arriba + Oben + Nahoře + Acima + En haut + Fent + Сверху + Alto + 上側 + 상단 + 上方 + 上方 + Üst + + + Bottom + Dół + Abajo + Unten + Dole + Abaixo + En bas + Alul + Снизу + Basso + 下側 + 하단 + 下方 + 下方 + Alt + + + Weapon Sway + 手ぶれ + 무기 흔들림 + Oscillation de l'arme + Колебание оружия + Waffen schwanken + Oscilación del arma + Oscillazione arma + + + Enable Weapon Sway + 手ぶれを有効化 + 무기 흔들림 추가 + Activer l'oscillation de l'arme + Включить колебание оружия + Aktiviere Waffen schwanken + Habilitar oscilación del arma + Abilita oscillazione arma + + + Enables weapon sway influenced by sway factors, such as stance, fatigue and medical condition.\nDisabling this setting will defer sway to vanilla or other mods. + 姿勢、疲労、負傷状態などの手ぶれ要因に影響を受ける武器照準の揺れを有効にします。\nこの設定を無効にすると、手ぶれの揺れはバニラまたは他のMODの処理に任されます。 + 흔들림 계수, 자세, 피로도, 건강 상태 등의 요인에 영향을 받는 무기 흔들림을 활성화합니다.\n이 설정을 비활성화하면 바닐라 또는 다른 모드의 흔들림으로 대체됩니다. + Active l'oscillation de l'arme influencé par les facteurs d'oscillation, tels que la position, la fatigue et l'état de santé.\nLa désactivation de ce paramètre reportera l'oscillation à vanilla ou à d'autres mods. + Активируйте колебание оружия в зависимости от таких факторов, как стойка, усталость и состояние здоровья.\nОтключение этого параметра приведет к переносу раскачивания на vanilla или другие моды. + Ermöglicht die Beeinflussung des Waffen-Schwankens durch Beeinflussungsfaktoren wie Haltung, Müdigkeit und Gesundheitszustand.\nDie Deaktivierung dieser Einstellung erlaubt die Beeinflussung durch Vanilla oder andere Mods. + Habilita la oscilación del arma afectado por factores como la postura, la fatiga y la condición médica.\nDeshabilitar esta opción hará que el comportamiento de la oscilación venga definido por Vanilla o por otros mods. + Abilita l'oscillazione ACE, influenzata da fattori come postura, fatica e condizione medica.\nDisabilitare questa impostazione farà controllare l'oscillazione al gioco vanilla o altre mod. + + + Sway factor + Factor de balanceo de mira + Verwacklungsfaktor + 手ぶれ因数 + 抖动系数 + 抖動因素 + Facteur de tremblement + Fattore di Oscillazione + Czynnik kołysania + Фактор колебания прицела + Fator de Balanço de Mira + Faktor kývání + 손떨림 정도 + + + Influences the amount of weapon sway. Higher means more sway. + Afecta al la estabilidad de la mira. Más alto significa más balanceo + Beeinflusst, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung. + 武器の手ぶれの大きさに影響します。値が高いほど、手ぶれが強くなります。 + 影响手持武器的晃动程度,数值越高,抖动的越厉害。 + 影響手持武器晃動程度,數值越高抖動越厲害 + Influe sur l'amplitude du tremblement de l'arme. Une valeur plus élevée signifie plus de tremblement. + Influenza l'aumento di oscillazione dell'arma quando affaticato. Maggiore significa più oscillazione. + Wpływa na poziom kołysania broni. Większa ilość znaczy większe kołysanie. + Влияет на колебания прицела оружия. Чем выше - тем больше. + Influencia a quantidade de balanço da mira da arma. Quanto maior, mais balanço. + Ovlivňuje množství kývání zbraní. Vyšší znamená více kývání. + 손떨림의 정도를 정합니다. 높을 수록 많이 휘적입니다. + + + Rested sway factor + Facteur de balancement au repos + 휴식 시 손떨림 정도 + Fator de balanço de mira em repouso + Verwacklungsfaktor, wenn aufgelegt + Fattore di Oscillazione Appoggiato + 静止依託時の手ぶれ係数 + Коэффициент колебания прицела в состоянии покоя + Factor de oscilación apoyado + + + Influences the amount of weapon sway while weapon is rested. + Influence le degré de balancement de l'arme au repos. + 무기가 아무런 행동도 하지 않는 동안 무기가 흔들리는 정도를 정합니다. + Influencia a quantidade de balanço de mira enquanto a arma está em repouso. + Beeinflusst, wie ruhig man die Waffe hält, während sie aufgelegt ist. + Determina la quantità di oscillazione dell'arma quando questa è appoggiata. + 静止し壁などに依託している時の武器の手ぶれの大きさに影響します。 + Влияет на величину колебания прицела оружия в состоянии покоя. + Afecta la cantidad de oscilación del arma cuando se está apoyado. + + + Deployed sway factor + Facteur de balancement déployé + 거치 시 손떨림 정도 + Fator de balanço de mira em posição de tiro + Verwacklungsfaktor, wenn Zweibein aufgestellt ist. + Fattore di Oscillazione su Bipode + 接地展開時の手ぶれ係数 + Коэффициент колебания прицела при развертывании + Factor de oscilación desplegado + + + Influences the amount of weapon sway while weapon is deployed. + Influence le degré de balancement de l'arme déployée. + 무기를 거치하는 동안 무기를 흔드는 정도를 정합니다. + Influencia a quantidade de balanço de mira enquanto a arma está em posição de tiro. + Beeinflusst, wie ruhig man die Waffen hält, während das Zweibein aufgestellt ist. + Determina la quantità di oscillazione dell'arma quando questa è stabilizzata usando il bipode. + 武器の接地展開時の武器の手ぶれの大きさに影響します。 + Влияет на величину колебания прицела оружия при его развертывании. + Afecta la cantidad de oscilación del arma cuando se está desplegado. diff --git a/addons/compat_csla/$PBOPREFIX$ b/addons/compat_csla/$PBOPREFIX$ new file mode 100644 index 0000000000..4d7b298fef --- /dev/null +++ b/addons/compat_csla/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_csla diff --git a/addons/compat_csla/CfgMagazines.hpp b/addons/compat_csla/CfgMagazines.hpp new file mode 100644 index 0000000000..f938272c8b --- /dev/null +++ b/addons/compat_csla/CfgMagazines.hpp @@ -0,0 +1,22 @@ +class CfgMagazines { + + class CSLA_UK59_50rnd_7_62vz59; + class CSLA_UK59_50rnd_7_62Sv59: CSLA_UK59_50rnd_7_62vz59 { + ace_isBelt = 1; + }; + + class US85_Magazine; + class US85_50Rnd_762x51: US85_Magazine { + ace_isBelt = 1; + }; + + class US85_20Rnd_762x51; + class US85_100Rnd_762x51: US85_20Rnd_762x51 { + ace_isBelt = 1; + }; + + class US85_30Rnd_556x45; + class US85_200Rnd_556x45: US85_30Rnd_556x45 { + ace_isBelt = 1; + }; +}; diff --git a/addons/compat_csla/CfgWeapons.hpp b/addons/compat_csla/CfgWeapons.hpp new file mode 100644 index 0000000000..dcfa6744cc --- /dev/null +++ b/addons/compat_csla/CfgWeapons.hpp @@ -0,0 +1,72 @@ +class CfgWeapons { + + class CSLA_LauncherBase; + class CSLA_Launcher_AT; + class CSLA_MachinegunBase_7_62; + + class CSLA_RPG7: CSLA_Launcher_AT { + EGVAR(reloadlaunchers,enabled) = 1; + }; + + // class CSLA_RPG75: CSLA_Launcher_AT {}; + + class CSLA_Strela: CSLA_LauncherBase { + EGVAR(overpressure,angle) = 30; + EGVAR(overpressure,damage) = 0.5; + EGVAR(overpressure,range) = 2; + }; + + class CSLA_UK59L: CSLA_MachinegunBase_7_62 { + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,closedBolt) = 0; + }; + + class US85_Launcher_AA; + class US85_Launcher_AT; + class US85_MachinegunBase_5_56; + class US85_MachinegunBase_7_62; + class US85_weaponBase; + + // class US85_M16_base: US85_weaponBase {}; + + class US85_M249: US85_MachinegunBase_5_56 { + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,closedBolt) = 0; + }; + + class US85_M60: US85_MachinegunBase_7_62 { + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,closedBolt) = 0; + }; + + class US85_FIM92: US85_Launcher_AA { + EGVAR(overpressure,angle) = 45; + EGVAR(overpressure,damage) = 0.3; + EGVAR(overpressure,range) = 6; + }; + + class US85_LAW72: US85_Launcher_AT { + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,damage) = 0.5; + EGVAR(overpressure,range) = 15; + }; + + class US85_M136: US85_Launcher_AT { + EGVAR(overpressure,angle) = 45; + EGVAR(overpressure,damage) = 0.3; + EGVAR(overpressure,range) = 10; + }; + + class US85_MAAWS: US85_Launcher_AT { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,angle) = 60; + EGVAR(overpressure,damage) = 0.7; + EGVAR(overpressure,priority) = 1; + EGVAR(overpressure,range) = 10; + }; + + class US85_SMAW: US85_Launcher_AT { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,angle) = 45; + }; +}; diff --git a/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp b/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..b29f7e717d --- /dev/null +++ b/addons/compat_csla/compat_csla_explosives/CfgMagazines.hpp @@ -0,0 +1,15 @@ +class CfgMagazines { + class US85_Magazine; + class US85_ATMine_mag: US85_Magazine { + EGVAR(explosives,SetupObject) = "ACE_Explosives_Place_US85_ATMine_mag"; + useAction = 0; + }; + class US85_M14Mine_mag: US85_Magazine { + EGVAR(explosives,SetupObject) = "ACE_Explosives_Place_US85_M14Mine"; + useAction = 0; + }; + class US85_SatchelCharge_Mag: US85_Magazine { + EGVAR(explosives,SetupObject) = "ACE_Explosives_Place_US85_SatchelCharge_Mag"; + useAction = 0; + }; +}; diff --git a/addons/compat_csla/compat_csla_explosives/CfgVehicles.hpp b/addons/compat_csla/compat_csla_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..02dd9367ea --- /dev/null +++ b/addons/compat_csla/compat_csla_explosives/CfgVehicles.hpp @@ -0,0 +1,18 @@ +class CfgVehicles { + + // ACE Explosives + class ACE_Explosives_Place; + + class ACE_Explosives_Place_US85_ATMine_mag: ACE_Explosives_Place { + model = "\a3\weapons_f\explosives\mine_at.p3d"; + }; + + class ACE_Explosives_Place_US85_M14Mine: ACE_Explosives_Place { + model = "\a3\weapons_f\explosives\mine_ap.p3d"; + }; + + class ACE_Explosives_Place_US85_SatchelCharge_Mag: ACE_Explosives_Place { + model = "\a3\weapons_f\explosives\satchel.p3d"; + }; + +}; diff --git a/addons/compat_csla/compat_csla_explosives/config.cpp b/addons/compat_csla/compat_csla_explosives/config.cpp new file mode 100644 index 0000000000..95f9534cca --- /dev/null +++ b/addons/compat_csla/compat_csla_explosives/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_explosives", "CSLA", "US85"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Dahlgren"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_csla/compat_csla_explosives/script_component.hpp b/addons/compat_csla/compat_csla_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_csla/compat_csla_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_csla/config.cpp b/addons/compat_csla/config.cpp new file mode 100644 index 0000000000..d0f99c092c --- /dev/null +++ b/addons/compat_csla/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "CSLA", "US85"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Dahlgren"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_csla/script_component.hpp b/addons/compat_csla/script_component.hpp new file mode 100644 index 0000000000..480a8cc4cc --- /dev/null +++ b/addons/compat_csla/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_csla +#define COMPONENT_BEAUTIFIED CSLA Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_cup_terrains/$PBOPREFIX$ b/addons/compat_cup_terrains/$PBOPREFIX$ new file mode 100644 index 0000000000..f904236cf3 --- /dev/null +++ b/addons/compat_cup_terrains/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_terrains diff --git a/addons/compat_cup_terrains/CfgEventHandlers.hpp b/addons/compat_cup_terrains/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9cc1b0427b --- /dev/null +++ b/addons/compat_cup_terrains/CfgEventHandlers.hpp @@ -0,0 +1,5 @@ +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/compat_cup_terrains/CfgVehicles.hpp b/addons/compat_cup_terrains/CfgVehicles.hpp new file mode 100644 index 0000000000..3fbd69f291 --- /dev/null +++ b/addons/compat_cup_terrains/CfgVehicles.hpp @@ -0,0 +1,56 @@ +class CBA_Extended_EventHandlers; +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + +class CfgVehicles { + class House; + class House_Small_F; + class Strategic; + class House_EP1: House {}; + + class Land_Benzina_schnell: House { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-1.5,-3.93,-1.25}, {2.35,-3.93,-1.25}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + position = "[0,-3.93,-1.25]"; + distance = 5; + condition = "true"; + }; + }; + }; + class Land_A_FuelStation_Feed: Strategic { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class Land_Ind_FuelStation_Feed_EP1: House_EP1 { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class Land_FuelStation_Feed_PMC: Strategic { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class FuelStation: House_Small_F { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{1.25, .2, -1.1}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + position = "[1.25, .2, -1]"; + distance = 5; + condition = "true"; + }; + }; + }; + class WarfareBBaseStructure; + class Base_WarfareBVehicleServicePoint: WarfareBBaseStructure { + // "vehicle service point" (a conex /w barrels) - need hooks??? + XEH_INHERITED; + }; +}; diff --git a/addons/compat_cup_terrains/XEH_postInit.sqf b/addons/compat_cup_terrains/XEH_postInit.sqf new file mode 100644 index 0000000000..32b9393d98 --- /dev/null +++ b/addons/compat_cup_terrains/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (["CUP_Terrains_ACE_compat"] call EFUNC(common,isModLoaded)) exitWith { + ERROR_WITH_TITLE("Duplicate CUP/ACE Compats","Compats are now part of ACE - Uninstall 'CUP ACE3 Compatibility Addon - Terrains'"); +}; diff --git a/addons/compat_cup_terrains/config.cpp b/addons/compat_cup_terrains/config.cpp new file mode 100644 index 0000000000..a7020be4da --- /dev/null +++ b/addons/compat_cup_terrains/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" +#include "\z\ace\addons\refuel\defines.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CABuildings", + "CAStructuresHouse_A_FuelStation", + "CAStructures_E_Ind_Ind_FuelStation", + "CAStructures_PMC_FuelStation", + "CUP_Buildings_Config", + "ace_refuel" // not a sub-component because it's all this compat does + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" +#include "CfgEventHandlers.hpp" diff --git a/addons/compat_cup_terrains/script_component.hpp b/addons/compat_cup_terrains/script_component.hpp new file mode 100644 index 0000000000..633de5584b --- /dev/null +++ b/addons/compat_cup_terrains/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_cup_terrains +#define COMPONENT_BEAUTIFIED CUP Terrains Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_cup_units/$PBOPREFIX$ b/addons/compat_cup_units/$PBOPREFIX$ new file mode 100644 index 0000000000..7a3dc51ddd --- /dev/null +++ b/addons/compat_cup_units/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_units diff --git a/addons/compat_cup_units/CfgGlasses.hpp b/addons/compat_cup_units/CfgGlasses.hpp new file mode 100644 index 0000000000..1620f74212 --- /dev/null +++ b/addons/compat_cup_units/CfgGlasses.hpp @@ -0,0 +1,492 @@ +class CfgGlasses { + + #define ESS_OVERLAY \ + ace_overlay = QPATHTOEF(goggles,textures\hud\combatgoggles.paa); \ + ace_overlayCracked = QPATHTOEF(goggles,textures\hud\combatgogglescracked.paa) + + class None; + class CUP_G_PMC_RadioHeadset_Glasses; + + // ESS Goggles - Dark + class CUP_G_ESS_BLK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Ember + class CUP_G_ESS_BLK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_White: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Clear + class CUP_G_ESS_BLK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Facewrap_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Ranger: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Skull: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Tropical: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + + // Oakleys - Dark + class CUP_G_Oakleys_Drk: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Dark: CUP_G_PMC_RadioHeadset_Glasses { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Oakleys - Ember + class CUP_G_Oakleys_Embr: None { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Ember: CUP_G_PMC_RadioHeadset_Glasses { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Dark + class CUP_G_Beard_Shades_Black: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_Beard_Shades_Blonde: CUP_G_Beard_Shades_Black { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Clear + class CUP_G_Grn_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + + // Thug - Dark + class CUP_PMC_G_thug: None { + ace_tintAmount = 8; + }; +}; diff --git a/addons/compat_cup_units/CfgWeapons.hpp b/addons/compat_cup_units/CfgWeapons.hpp new file mode 100644 index 0000000000..37a210db9d --- /dev/null +++ b/addons/compat_cup_units/CfgWeapons.hpp @@ -0,0 +1,87 @@ +#define HEARING(CLASSNAME) \ + class CLASSNAME: ItemCore { \ + ace_hearing_protection = 0.75; \ + ace_hearing_lowerVolume = 0; \ + } + +#define HEARING_PARENT(CLASSNAME,PARENT) \ + class CLASSNAME: PARENT { \ + ace_hearing_protection = 0.75; \ + ace_hearing_lowerVolume = 0; \ + } + +class CfgWeapons { + class ItemCore; + class CUP_H_PMC_Beanie_Khaki; + + HEARING(CUP_H_BAF_DDPM_Mk6_CREW_PRR); + HEARING(CUP_H_BAF_DPM_Mk6_CREW_PRR); + HEARING(CUP_H_BAF_MTP_Mk6_CREW_PRR); + HEARING(CUP_H_CZ_Cap_Headphones); + HEARING(CUP_H_CZ_Cap_Headphones_des); + HEARING(CUP_H_CZ_Helmet05); + HEARING(CUP_H_CZ_Helmet07); + HEARING(CUP_H_CZ_Helmet08); + HEARING(CUP_H_CZ_Helmet09); + HEARING(CUP_H_CZ_Helmet10); + HEARING(CUP_H_FR_ECH); + HEARING(CUP_H_Ger_Beret_TankCommander_Blk); + HEARING(CUP_H_Ger_Beret_TankCommander_Grn); + HEARING(CUP_H_Ger_Cap_EP_Grn1); + HEARING(CUP_H_Ger_Cap_EP_Grn2); + HEARING(CUP_H_Ger_Cap_EP_Tan1); + HEARING(CUP_H_Ger_Cap_EP_Tan2); + HEARING(CUP_H_OpsCore_Black); + HEARING(CUP_H_OpsCore_Black_SF); + HEARING(CUP_H_OpsCore_Covered_AAF); + HEARING(CUP_H_OpsCore_Covered_AAF_SF); + HEARING(CUP_H_OpsCore_Covered_Fleck); + HEARING(CUP_H_OpsCore_Covered_Fleck_SF); + HEARING(CUP_H_OpsCore_Covered_MCAM); + HEARING(CUP_H_OpsCore_Covered_MCAM_SF); + HEARING(CUP_H_OpsCore_Covered_MCAM_US); + HEARING(CUP_H_OpsCore_Covered_MCAM_US_SF); + HEARING(CUP_H_OpsCore_Covered_MTP); + HEARING(CUP_H_OpsCore_Covered_MTP_SF); + HEARING(CUP_H_OpsCore_Covered_Tigerstripe); + HEARING(CUP_H_OpsCore_Covered_Tigerstripe_SF); + HEARING(CUP_H_OpsCore_Covered_Tropen); + HEARING(CUP_H_OpsCore_Covered_Tropen_SF); + HEARING(CUP_H_OpsCore_Covered_UCP); + HEARING(CUP_H_OpsCore_Covered_UCP_SF); + HEARING(CUP_H_OpsCore_Green); + HEARING(CUP_H_OpsCore_Green_SF); + HEARING(CUP_H_OpsCore_Grey); + HEARING(CUP_H_OpsCore_Grey_SF); + HEARING(CUP_H_OpsCore_Spray); + HEARING(CUP_H_OpsCore_Spray_SF); + HEARING(CUP_H_OpsCore_Spray_US); + HEARING(CUP_H_OpsCore_Spray_US_SF); + HEARING(CUP_H_OpsCore_Tan); + HEARING(CUP_H_OpsCore_Tan_SF); + HEARING_PARENT(CUP_H_PMC_Beanie_Headphones_Khaki,CUP_H_PMC_Beanie_Khaki); + HEARING_PARENT(CUP_H_PMC_Beanie_Headphones_Black,CUP_H_PMC_Beanie_Headphones_Khaki); + HEARING_PARENT(CUP_H_PMC_Beanie_Headphones_Winter,CUP_H_PMC_Beanie_Headphones_Khaki); + HEARING(CUP_H_PMC_Cap_Back_EP_Grey); + HEARING(CUP_H_PMC_Cap_Back_EP_Tan); + HEARING(CUP_H_PMC_Cap_EP_Grey); + HEARING(CUP_H_PMC_Cap_EP_Tan); + HEARING(CUP_H_PMC_EP_Headset); + HEARING(CUP_H_USArmy_HelmetMICH_earpro); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_DCU); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_ess); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_ess_DCU); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_ess_wdl); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_wdl); + HEARING(CUP_H_USArmy_Helmet_ECH1_Black); + HEARING(CUP_H_USArmy_Helmet_ECH1_Green); + HEARING(CUP_H_USArmy_Helmet_ECH1_Sand); + HEARING(CUP_H_USArmy_Helmet_ECH2_Black); + HEARING(CUP_H_USArmy_Helmet_ECH2_GREEN); + HEARING(CUP_H_USArmy_Helmet_ECH2_Sand); + HEARING(CUP_H_USMC_Crew_Helmet); + HEARING(CUP_H_USMC_MICH2000_DEF_DES); + HEARING(CUP_H_USMC_MICH2000_DEF_ESS_DES); + HEARING(CUP_H_USMC_MICH2000_DEF_ESS_WDL); + HEARING(CUP_H_USMC_MICH2000_DEF_WDL); +}; diff --git a/addons/compat_cup_units/compat_cup_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_cup_units/compat_cup_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 0000000000..386cc7df0b --- /dev/null +++ b/addons/compat_cup_units/compat_cup_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,86 @@ +class CfgVehicles { + class SoldierWB; + class Civilian_F; + + class CUP_BAF_Soldier_DPM_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_BAF_Soldier_DDPM_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_BAF_Soldier_MTP_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_GER_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_NAPA_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_PMC_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_PMC_Soldier_Winter_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_RUS_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_TK_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_TKI_Insurgent_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_TKG_Guerrilla_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_USMC_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_FR_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Civil_Chernarus_Base: Civilian_F { + modelSides[] = {6}; + }; + class CUP_Creatures_Civil_Takistan_Base: Civilian_F { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_ACR_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_CDF_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_UNO_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_OPFINS_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_RACS_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_SLA_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_USA_Soldier_ACU_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_USA_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_Reservist_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_Recon_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_Man_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_SF_Base: SoldierWB { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_cup_units/compat_cup_nouniformrestrictions/config.cpp b/addons/compat_cup_units/compat_cup_nouniformrestrictions/config.cpp new file mode 100644 index 0000000000..826f796226 --- /dev/null +++ b/addons/compat_cup_units/compat_cup_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Creatures_People_LoadOrder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Jonpas"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_units/compat_cup_nouniformrestrictions/script_component.hpp b/addons/compat_cup_units/compat_cup_nouniformrestrictions/script_component.hpp new file mode 100644 index 0000000000..0b98185fa0 --- /dev/null +++ b/addons/compat_cup_units/compat_cup_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_cup_units/config.cpp b/addons/compat_cup_units/config.cpp new file mode 100644 index 0000000000..c3ba110e74 --- /dev/null +++ b/addons/compat_cup_units/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"CUP_Creatures_People_LoadOrder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Jonpas"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgGlasses.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_units/script_component.hpp b/addons/compat_cup_units/script_component.hpp new file mode 100644 index 0000000000..46e1542b50 --- /dev/null +++ b/addons/compat_cup_units/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_cup_units +#define COMPONENT_BEAUTIFIED CUP Units Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_cup_vehicles/$PBOPREFIX$ b/addons/compat_cup_vehicles/$PBOPREFIX$ new file mode 100644 index 0000000000..da4cebbc16 --- /dev/null +++ b/addons/compat_cup_vehicles/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_vehicles diff --git a/addons/compat_cup_vehicles/CfgEventHandlers.hpp b/addons/compat_cup_vehicles/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/compat_cup_vehicles/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/compat_cup_vehicles/CfgVehicles.hpp b/addons/compat_cup_vehicles/CfgVehicles.hpp new file mode 100644 index 0000000000..5334987fff --- /dev/null +++ b/addons/compat_cup_vehicles/CfgVehicles.hpp @@ -0,0 +1,288 @@ +class CfgVehicles { + class CUP_MTVR_Base; + class CUP_MTVR_Reammo_Base: CUP_MTVR_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class CUP_V3S_Open_Base; + class CUP_V3S_Rearm_Base: CUP_V3S_Open_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class CUP_Kamaz_5350_Base; + class CUP_Kamaz_5350_ReAmmo_Base: CUP_Kamaz_5350_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class CUP_T810_Unarmed_Base; + class CUP_T810_Reammo_Base: CUP_T810_Unarmed_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class Wheeled_APC_F; + class CUP_BTR80_Common_Base: Wheeled_APC_F { + class ace_viewports { + class view_0 { + camLocation[] = {0.734863, 0.143927, -0.291199}; + camAttach = 45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.950684, -0.00122738, -0.344391}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {0.932129, -0.729811, -0.319}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-0.963379, -0.749183, -0.351501}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_4 { + camLocation[] = {-0.973145, 0.0148516, -0.364868}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_5 { + camLocation[] = {-0.73584, 0.119176, -0.291229}; + camAttach = -45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + class CUP_BTR90_Base: Wheeled_APC_F { + class ace_viewports { + class view_0 { + camLocation[] = {0.533417, 2.4613, -0.309951}; + camAttach = 0; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.877106, 2.38684, -0.306068}; + camAttach = 30; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {1.04312, 0.0909424, -0.281996}; + camAttach = 60; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_3 { + type = ""; + camLocation[] = {1.03799, -0.928223, -0.282196}; + camAttach = 80; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_4 { + type = ""; + camLocation[] = {-0.90097, -0.913086, -0.282192}; + camAttach = -80; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_5 { + type = ""; + camLocation[] = {-0.939301, 0.109985, -0.281992}; + camAttach = -60; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + class CUP_BTR90_HQ_Base: CUP_BTR90_Base { delete ace_viewports; }; // no cargo seats + + class Tank_F; + class CUP_M2Bradley_Base: Tank_F { + ace_hunterkiller = 1; + class ace_viewports { + class view_0 { + camLocation[] = {0.987915, -0.324707, -0.0673385}; + camAttach = 70; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.90979, -0.970215, -0.043139}; + camAttach = 120; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {0.328003, -1.87402, -0.0408039}; + camAttach = 160; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-0.357178, -1.89063, -0.0480237}; + camAttach = 175; + roles[]={"cargo"}; + }; + class view_4 { + camLocation[] = {-0.752075, -1.87061, -0.0522318}; + camAttach = 190; + roles[]={"cargo"}; + }; + class view_5 { + camLocation[] = {-0.936401, -0.0942383, -0.107764}; + camAttach = -75; + roles[]={"cargo"}; + }; + class SLD { // suppose to only be only on A3, but the A2s have the screen on the model? + screenLocation[] = {0.729126,-0.191597,-0.573349}; + maxDistance = 5; + type = "screen"; + camLocation[] = {0,0,0.05}; + camAttach[] = {0,0}; + roles[]={"cargo"}; + }; + }; + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l1", "hitera_l2", "hitera_l3", "hitera_l4", "hitera_l5", + "hitera_l6", "hitera_l7", "hitera_l8", "hitera_r1", "hitera_r2", + "hitera_r3", "hitera_r4", "hitera_r5", "hitera_r6", "hitera_r7", + "hitera_r8", "hitera_t1", "hitera_t2", "hitera_t3", "hitera_t4", + "hitera_t5", "hitera_t6", "hitera_t7", "hitera_t8", "hitera_fr1", + "hitera_fr2", "hitera_fr3", "hitera_fr4", "hitera_fr5", "hitera_fr6", + "hitera_fr7", "hitera_fr8", "hitera_fr9", "hitera_fl1", "hitera_fl2", + "hitera_fl3", "hitera_fl4", "hitera_fl5" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + class CUP_T90_Base: Tank_F { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l1", "hitera_l2", "hitera_l3", "hitera_r1", "hitera_r2", + "hitera_r3", "hitera_1_t_l", "hitera_1_t_r", "hitera_2_t_l", + "hitera_2_t_r" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + class CUP_T90M_Base: Tank_F { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_t1", "hitera_t2", "hitera_t3", "hitera_t4", "hitera_t5", + "hitera_t6", "hitera_t7", "hitera_t8", "hitera_t9", "hitera_t10", + "hitera_t11", "hitera_t12", "hitera_t13", "hitera_t14", "hitera_t15", + "hitera_t16", "hitera_t17", "hitera_t18", "hitera_t19", "hitera_t20", + "hitera_t21", "hitera_f1", "hitera_f2", "hitera_f3", "hitera_f4", + "hitera_f5", "hitera_f6", "hitera_f7", "hitera_s1", "hitera_s2", + "hitera_s3", "hitera_s4", "hitera_s5", "hitera_s6", "hitera_s7", + "hitera_s8", "hitera_s9", "hitera_s10", "hitera_s11", "hitera_s12", + "hitera_t22", "hitera_t23", "hitera_t24", "hitera_t25", "hitera_t26", + "hitera_t27", "hitera_t28", "hitera_t29", "hitera_t30", "hitera_t31", + "hitera_t32", "hitera_t33" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_left", "hitslat_right", "hitslat_turret_rear", + "hitslat_turret_left", "hitslat_rear" + }; + }; + + class CUP_T72_ACR_Base; + class CUP_B_T72_CZ: CUP_T72_ACR_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_top_l1", "hitera_top_l2", "hitera_top_l3", "hitera_top_l4", + "hitera_top_r1", "hitera_top_r2", "hitera_top_r3", "hitera_top_r4", + "hitera_front_r1", "hitera_front_r2", "hitera_front_l1", + "hitera_front_l2", "hitera_top_rear" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + + class CUP_Leopard2_Base; + class CUP_Leopard2_ERA_Base: CUP_Leopard2_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_1", "hitera_2", "hitera_3", "hitera_4", "hitera_5", "hitera_6", + "hitera_7", "hitera_8", "hitera_9", "hitera_10", "hitera_11", "hitera_12", + "hitera_13", "hitera_14", "hitera_15", "hitera_16", "hitera_17", "hitera_18", + "hitera_19", "hitera_20", "hitera_21", "hitera_22", "hitera_23", "hitera_24", + "hitera_25", "hitera_26", "hitera_27", "hitera_28", "hitera_29", "hitera_30", + "hitera_31", "hitera_32", "hitera_33", "hitera_34", "hitera_35", "hitera_36", + "hitera_37", "hitera_38", "hitera_39", "hitera_40", "hitera_41", "hitera_42", + "hitera_43", "hitera_44", "hitera_45", "hitera_46", "hitera_47" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + + class CUP_M1_Abrams_base; + class CUP_M1A2_TUSK_base: CUP_M1_Abrams_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l1", "hitera_l2", "hitera_l3", "hitera_l4", "hitera_r1", + "hitera_r2", "hitera_r3", "hitera_r4" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + + class CUP_M1Abrams_Base; + class CUP_M1Abrams_TUSK_Base: CUP_M1Abrams_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", + "hitera_r05", "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", + "hitera_r10", "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", + "hitera_r15", "hitera_r16" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + + class CUP_M1Abrams_A2_Base; + class CUP_M1Abrams_A2_TUSK_Base: CUP_M1Abrams_A2_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_l17", "hitera_l18", "hitera_l19", "hitera_l20", + "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", "hitera_r05", + "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", "hitera_r10", + "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", "hitera_r15", + "hitera_r16", "hitera_r17", "hitera_r18", "hitera_r19", "hitera_r20" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + + class CUP_M1A2Abrams_Base; + class CUP_M1A2Abrams_TUSK_Base: CUP_M1A2Abrams_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", + "hitera_r05", "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", + "hitera_r10", "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", + "hitera_r15", "hitera_r16" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + class CUP_M1A2Abrams_TUSK_II_Base: CUP_M1A2Abrams_TUSK_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_l17", "hitera_l18", "hitera_l19", "hitera_l20", + "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", "hitera_r05", + "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", "hitera_r10", + "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", "hitera_r15", + "hitera_r16", "hitera_r17", "hitera_r18", "hitera_r19", "hitera_r20" + }; + }; +}; diff --git a/addons/compat_cup_vehicles/XEH_PREP.hpp b/addons/compat_cup_vehicles/XEH_PREP.hpp new file mode 100644 index 0000000000..20674eee81 --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_PREP.hpp @@ -0,0 +1,4 @@ +PREP(onCutHC3); +PREP(onCutUH1Y); +PREP(onPrepareHC3); +PREP(onPrepareUH1Y); diff --git a/addons/compat_cup_vehicles/XEH_postInit.sqf b/addons/compat_cup_vehicles/XEH_postInit.sqf new file mode 100644 index 0000000000..09bda76106 --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (["CUP_Vehicles_ACE_compat"] call EFUNC(common,isModLoaded)) exitWith { + ERROR_WITH_TITLE("Duplicate CUP/ACE Compats","Compats are now part of ACE - Uninstall 'CUP ACE3 Compatibility Addon - Vehicles'"); +}; diff --git a/addons/disposable/XEH_preInit.sqf b/addons/compat_cup_vehicles/XEH_preInit.sqf similarity index 100% rename from addons/disposable/XEH_preInit.sqf rename to addons/compat_cup_vehicles/XEH_preInit.sqf diff --git a/addons/compat_cup_vehicles/XEH_preStart.sqf b/addons/compat_cup_vehicles/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/CfgVehicles.hpp new file mode 100644 index 0000000000..168fdcc8d2 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/CfgVehicles.hpp @@ -0,0 +1,143 @@ +class CfgVehicles { + class CUP_AH6_BASE; + class CUP_MH6_TRANSPORT: CUP_AH6_BASE { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + class CUP_B_MH6M_OBS_USA: CUP_MH6_TRANSPORT { + EGVAR(fastroping,enabled) = 0; + }; + class CUP_B_MH6J_OBS_USA: CUP_MH6_TRANSPORT { + EGVAR(fastroping,enabled) = 0; + }; + + class Helicopter_Base_H; + class CUP_AW159_Unarmed_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesGantry"; + EGVAR(fastroping,friesAttachmentPoint)[] = {1.05, 1, 1.3}; + EGVAR(fastroping,onCut) = QEFUNC(fastroping,onCutCommon); + EGVAR(fastroping,onPrepare) = QEFUNC(fastroping,onPrepareCommon); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + EQUIP_FRIES_ATTRIBUTE; + + class UserActions { + class CloseRdoor { + condition = QUOTE(this doorPhase 'CargoDoorR' > 0.5 && ((this getCargoIndex player) isEqualTo 0) && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_CH47F_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight", "ropeOriginMid"}; + }; + + class CUP_CH53E_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + + class UserActions { + class RampClose { + condition = QUOTE(this animationPhase 'ramp_bottom' >= 0.56 && player == driver this && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_Merlin_HC3_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginRight"}; + EGVAR(fastroping,onPrepare) = QEFUNC(compat_cup_vehicles,onPrepareHC3); + EGVAR(fastroping,onCut) = QEFUNC(compat_cup_vehicles,onCutHC3); + + class UserActions { + class CloseRdoor { + condition = QUOTE(this doorPhase 'dvere_p' > 0.5 && {(this getCargoIndex player) isEqualTo 0} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + }; + class OutWinch { + condition = "false"; + }; + class InWinch { + condition = "false"; + }; + }; + }; + + class CUP_Ka60_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + + class CUP_MH60S_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginRight"}; + + class UserActions { + class OpenDoors; + class CloseDoors: OpenDoors { + condition = QUOTE(this animationPhase 'doors' > 0.5 && driver this == player && alive (this) && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_Mi8_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft"}; + }; + + class CUP_Mi8_medevac_base: CUP_Mi8_base { + EGVAR(fastroping,enabled) = 0; + }; + + class CUP_Mi171Sh_Base: CUP_Mi8_base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + + class CUP_SA330_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + + class UserActions { + class CloseRdoor { + condition = QUOTE(alive this && {this doorPhase 'ofrp_puma_porte_droite' > 0.5} && {(this getCargoIndex player) isEqualTo 0} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + }; + class CloseLdoor { + condition = QUOTE(alive this && {this doorPhase 'ofrp_puma_porte_gauche' > 0.5} && {(this getCargoIndex player) isEqualTo 1} && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_UH1H_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesAnchorBar"; + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.45, -0.3}; + EGVAR(fastroping,onCut) = QEFUNC(fastroping,onCutCommon); + EGVAR(fastroping,onPrepare) = QEFUNC(fastroping,onPrepareCommon); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + EQUIP_FRIES_ATTRIBUTE; + }; + + class CUP_B_UH1Y_Base; + class CUP_B_UH1Y_UNA_USMC: CUP_B_UH1Y_Base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + EGVAR(fastroping,onPrepare) = QEFUNC(compat_cup_vehicles,onPrepareUH1Y); + EGVAR(fastroping,onCut) = QEFUNC(compat_cup_vehicles,onCutUH1Y); + }; + class CUP_B_UH1Y_MEV_USMC: CUP_B_UH1Y_UNA_USMC { + EGVAR(fastroping,enabled) = 0; + }; + + class CUP_UH60_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginRight"}; + + class UserActions { + class OpenDoors; + class CloseDoors: OpenDoors { + condition = QUOTE(this animationPhase 'doors' > 0.5 && driver this == player && alive (this) && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp new file mode 100644 index 0000000000..1abe0de6ea --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_fastroping" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/script_component.hpp new file mode 100644 index 0000000000..a3a1b47a32 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT fastroping +#define SUBCOMPONENT_BEAUTIFIED Fastroping +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..1042c0eacf --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -0,0 +1,31 @@ +class CfgVehicles { + class CUP_T810_Unarmed_Base; + class CUP_T810_Refuel_Base: CUP_T810_Unarmed_Base { + EGVAR(refuel,hooks)[] = {{-1.01, 0.21, -0.5},{1.08, 0.2, -0.5}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class Truck_02_fuel_base_F; + class CUP_Kamaz_5350_Refuel_Base: Truck_02_fuel_base_F { + EGVAR(refuel,hooks)[] = {{-0.02, -3.33, -1.05}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class CUP_Ural_Support_Base; + class CUP_Ural_Refuel_Base: CUP_Ural_Support_Base { + EGVAR(refuel,hooks)[] = {{-0.05, -3.65, -0.42}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class CUP_V3S_Open_Base; + class CUP_V3S_Refuel_Base: CUP_V3S_Open_Base { + EGVAR(refuel,hooks)[] = {{-0.35, -3.35, -0.4},{0.40, -3.35, -0.4}}; + EGVAR(refuel,fuelCargo) = 6500; + }; + + class CUP_MTVR_Base; + class CUP_MTVR_Refuel_Base: CUP_MTVR_Base { + EGVAR(refuel,hooks)[] = {{-1.09, -0.01, -0.5},{1, -0.01, -0.5}}; + EGVAR(refuel,fuelCargo) = 10000; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/config.cpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/config.cpp new file mode 100644 index 0000000000..f77c9903b9 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_refuel" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/script_component.hpp new file mode 100644 index 0000000000..b58db9432d --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED Refuel +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/config.cpp b/addons/compat_cup_vehicles/config.cpp new file mode 100644 index 0000000000..513993ef57 --- /dev/null +++ b/addons/compat_cup_vehicles/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_interaction" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/functions/fnc_onCutHC3.sqf b/addons/compat_cup_vehicles/functions/fnc_onCutHC3.sqf new file mode 100644 index 0000000000..8514dd2aed --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onCutHC3.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for retracting the hooks for CUP HC3 helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onCutHC3 + * + * Public: No + */ + +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", false, true]; + +_vehicle animateSource ["Winchsection", 0]; +_vehicle animateSource ["Winchsection2", 0]; +_vehicle animateDoor ["dvere_p", 1]; + +2 diff --git a/addons/compat_cup_vehicles/functions/fnc_onCutUH1Y.sqf b/addons/compat_cup_vehicles/functions/fnc_onCutUH1Y.sqf new file mode 100644 index 0000000000..82a3eaf8a9 --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onCutUH1Y.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for retracting the hooks for CUP UH-1Y helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onCutUH1Y + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", false, true]; +_vehicle animateSource ["fries_extend", 0]; + +2 diff --git a/addons/compat_cup_vehicles/functions/fnc_onPrepareHC3.sqf b/addons/compat_cup_vehicles/functions/fnc_onPrepareHC3.sqf new file mode 100644 index 0000000000..aad828a3a0 --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onPrepareHC3.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for opening doors and extending the hook for HC3 helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onPrepareUH1Y + * + * Public: No + */ + +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", true, true]; + +_vehicle animateSource ["Winchsection", 1]; +_vehicle animateSource ["Winchsection2", 1]; +_vehicle animateDoor ["dvere_p", 0]; + +2 diff --git a/addons/compat_cup_vehicles/functions/fnc_onPrepareUH1Y.sqf b/addons/compat_cup_vehicles/functions/fnc_onPrepareUH1Y.sqf new file mode 100644 index 0000000000..f17ea79613 --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onPrepareUH1Y.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for extending the hook for the CUP UH-1Y Helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onPrepareUH1Y + * + * Public: No + */ + +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", true, true]; +_vehicle animateSource ["fries_extend", 1]; + +2 diff --git a/addons/compat_cup_vehicles/script_component.hpp b/addons/compat_cup_vehicles/script_component.hpp new file mode 100644 index 0000000000..effb2d5534 --- /dev/null +++ b/addons/compat_cup_vehicles/script_component.hpp @@ -0,0 +1,20 @@ +#define COMPONENT compat_cup_vehicles +#define COMPONENT_BEAUTIFIED CUP Vehicles Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" + +// Fries Macro +#define EQUIP_FRIES_ATTRIBUTE \ + class Attributes { \ + class ace_fastroping_equipFRIES { \ + property = "ace_fastroping_equipFRIES"; \ + control = "Checkbox"; \ + displayName = ECSTRING(fastroping,Eden_equipFRIES); \ + tooltip = ECSTRING(fastroping,Eden_equipFRIES_Tooltip); \ + expression = "[_this] call ace_fastroping_fnc_equipFRIES"; \ + typeName = "BOOL"; \ + condition = "objectVehicle"; \ + defaultValue = 0; \ + }; \ + } diff --git a/addons/compat_cup_weapons/$PBOPREFIX$ b/addons/compat_cup_weapons/$PBOPREFIX$ new file mode 100644 index 0000000000..c5368b0a6d --- /dev/null +++ b/addons/compat_cup_weapons/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_weapons diff --git a/addons/compat_cup_weapons/CfgEventHandlers.hpp b/addons/compat_cup_weapons/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9cc1b0427b --- /dev/null +++ b/addons/compat_cup_weapons/CfgEventHandlers.hpp @@ -0,0 +1,5 @@ +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/compat_cup_weapons/CfgMagazines.hpp b/addons/compat_cup_weapons/CfgMagazines.hpp new file mode 100644 index 0000000000..6fd6e2f1cc --- /dev/null +++ b/addons/compat_cup_weapons/CfgMagazines.hpp @@ -0,0 +1,37 @@ +class CfgMagazines { + class CA_LauncherMagazine; + class CUP_NLAW_M: CA_LauncherMagazine { + ammo = "ACE_NLAW"; + }; + + // legacy classes from ACE disposable launchers + class CUP_M136_M; + class ACE_PreloadedMissileDummy_CUP: CUP_M136_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_RPG18_M; + class ACE_PreloadedMissileDummy_RPG18_CUP: CUP_RPG18_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_M72A6_M; + class ACE_PreloadedMissileDummy_M72A6_CUP: CUP_M72A6_M { + scope = 1; + scopeArsenal = 0; + }; + class ACE_PreloadedMissileDummy_NLAW_CUP: CUP_NLAW_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_Stinger_M; + class ACE_PreloadedMissileDummy_Stinger_CUP: CUP_Stinger_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_Strela_2_M; + class ACE_PreloadedMissileDummy_Strela_2_CUP: CUP_Strela_2_M { + scope = 1; + scopeArsenal = 0; + }; +}; diff --git a/addons/compat_cup_weapons/CfgWeapons.hpp b/addons/compat_cup_weapons/CfgWeapons.hpp new file mode 100644 index 0000000000..e69c75dee5 --- /dev/null +++ b/addons/compat_cup_weapons/CfgWeapons.hpp @@ -0,0 +1,36 @@ +class CfgWeapons { + class Launcher_Base_F; + class CUP_launch_M47: Launcher_Base_F { + ace_overpressure_angle = 45; + ace_overpressure_range = 8; + ace_overpressure_damage = 0.5; + }; + + class CUP_launch_MAAWS: Launcher_Base_F { + ace_overpressure_angle = 60; + ace_overpressure_range = 15; + ace_overpressure_damage = 0.7; + }; + class CUP_launch_MAAWS_Scope: CUP_launch_MAAWS {}; + + class CUP_launch_RPG7V: Launcher_Base_F { + ace_overpressure_angle = 45; + ace_overpressure_range = 6; + ace_overpressure_damage = 0.5; + }; + + class CUP_launch_Mk153Mod0: Launcher_Base_F { + ace_overpressure_angle = 30; + ace_overpressure_range = 15; + ace_overpressure_damage = 0.7; + }; + class CUP_launch_Mk153Mod0_SMAWOptics: CUP_launch_Mk153Mod0 {}; + + class CUP_launch_NLAW_Loaded: Launcher_Base_F { + ace_overpressure_angle = 30; + ace_overpressure_range = 2; + ace_overpressure_damage = 0.5; + ace_nlaw_enabled = 1; + canLock = 1; + }; +}; diff --git a/addons/compat_cup_weapons/XEH_postInit.sqf b/addons/compat_cup_weapons/XEH_postInit.sqf new file mode 100644 index 0000000000..79d81fda26 --- /dev/null +++ b/addons/compat_cup_weapons/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (["CUP_Weapons_ACE_compat"] call EFUNC(common,isModLoaded)) exitWith { + ERROR_WITH_TITLE("Duplicate CUP/ACE Compats","Compats are now part of ACE - Uninstall 'CUP ACE3 Compatibility Addon - Weapons'"); +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazineGroups.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazineGroups.hpp new file mode 100644 index 0000000000..430a5272ae --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazineGroups.hpp @@ -0,0 +1,56 @@ +class ace_csw_groups { + class CUP_compats_29Rnd_30mm_AGS30_M { + CUP_29Rnd_30mm_AGS30_M = 1; + }; + class CUP_compats_48Rnd_40mm_MK19_M { + CUP_48Rnd_40mm_MK19_M = 1; + }; + class CUP_AT13_M { + CUP_6Rnd_AT13_M = 1; + }; + class CUP_compats_TOW_M { + CUP_6Rnd_TOW_HMMWV_M = 1; + }; + class CUP_compats_TOW2_M { + CUP_6Rnd_TOW2_M = 1; + }; + class CUP_compats_PG9_M { + CUP_16Rnd_PG9_AT_M = 1; + }; + class CUP_compats_OG9_M { + CUP_16Rnd_OG9_HE_M = 1; + }; + class CUP_compats_105mm_he { + CUP_30Rnd_105mmHE_M119_M = 1; + }; + class CUP_compats_105mm_smoke { + CUP_30Rnd_105mmSMOKE_M119_M = 1; + }; + class CUP_compats_105mm_wp { + CUP_30Rnd_105mmWP_M119_M = 1; + }; + class CUP_compats_105mm_laser { + CUP_30Rnd_105mmLASER_M119_M = 1; + }; + class CUP_compats_105mm_illum { + CUP_30Rnd_105mmILLUM_M119_M = 1; + }; + class CUP_compats_122mm_he { + CUP_30Rnd_122mmHE_D30_M = 1; + }; + class CUP_compats_122mm_smoke { + CUP_30Rnd_122mmSMOKE_D30_M = 1; + }; + class CUP_compats_122mm_wp { + CUP_30Rnd_122mmHE_D30_M = 1; + }; + class CUP_compats_122mm_laser { + CUP_30Rnd_122mmLASER_D30_M = 1; + }; + class CUP_compats_122mm_illum { + CUP_30Rnd_122mmILLUM_D30_M = 1; + }; + class CUP_compats_122mm_at { + CUP_30Rnd_122mmAT_D30_M = 1; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazines.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazines.hpp new file mode 100644 index 0000000000..1a37f4d1c9 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazines.hpp @@ -0,0 +1,111 @@ +class CfgMagazines { + class VehicleMagazine; + class CUP_29Rnd_30mm_AGS30_M: VehicleMagazine { + ace_isbelt = 1; + }; + + class CUP_compats_29Rnd_30mm_AGS30_M: CUP_29Rnd_30mm_AGS30_M { + scope = 2; + type = 256; + count = 29; + mass = 40; + displayName = SUBCSTRING(mag_AGS30_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + + class 200Rnd_40mm_G_belt; + class CUP_48Rnd_40mm_MK19_M: 200Rnd_40mm_G_belt { + ace_isbelt = 1; + }; + + class CUP_compats_48Rnd_40mm_MK19_M: CUP_29Rnd_30mm_AGS30_M { + scope = 2; + type = 256; + count = 48; + mass = 40; + displayname = SUBCSTRING(mag_MK19_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + + class CUP_6Rnd_TOW_HMMWV_M; + class CUP_compats_TOW_M: CUP_6Rnd_TOW_HMMWV_M { + scope = 2; + type = 256; + count = 1; + mass = 200; + displayname = SUBCSTRING(mag_TOW_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_beta\Launchers\titan\Data\UI\gear_titan_missile_at_ca.paa"; + }; + + class CUP_6Rnd_TOW2_M; + class CUP_compats_TOW2_M: CUP_6Rnd_TOW2_M { + scope = 2; + type = 256; + count = 1; + mass = 200; + displayname = SUBCSTRING(mag_TOW2_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_beta\Launchers\titan\Data\UI\gear_titan_missile_at_ca.paa"; + }; + + class CUP_16Rnd_PG9_AT_M; + class CUP_compats_PG9_M: CUP_16Rnd_PG9_AT_M { + displayName = SUBCSTRING(mag_PG9_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + scope = 2; + type = 256; + count = 1; + mass = 80; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_ca.paa"; + }; + + class CUP_16Rnd_OG9_HE_M; + class CUP_compats_OG9_M: CUP_16Rnd_OG9_HE_M { + displayName = SUBCSTRING(mag_OG9_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + scope = 2; + type = 256; + count = 1; + mass = 80; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_ca.paa"; + }; + + class ACE_1Rnd_82mm_Mo_HE; + class CUP_compats_105mm_he: ACE_1Rnd_82mm_Mo_HE { + displayName = SUBCSTRING(mag_M1HE_displayName); + mass = 120; + }; + class CUP_compats_105mm_smoke: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M84Smoke_displayName); + }; + class CUP_compats_105mm_wp: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M60A2_displayName); + }; + class CUP_compats_105mm_laser: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M67AT_displayName); + }; + class CUP_compats_105mm_illum: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M314Illum_displayName); + }; + class CUP_compats_122mm_he: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_3OF56_displayName); + }; + class CUP_compats_122mm_laser: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_3OF69M_displayName); + }; + class CUP_compats_122mm_wp: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmWP_displayName); + }; + class CUP_compats_122mm_smoke: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmSmoke_displayName); + }; + class CUP_compats_122mm_illum: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmIllum_displayName); + }; + class CUP_compats_122mm_at: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmAT_displayName); + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp new file mode 100644 index 0000000000..3924ae0386 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp @@ -0,0 +1,200 @@ +class CfgVehicles { + class LandVehicle; + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class StaticMortar: StaticWeapon {}; + class CUP_2b14_82mm_Base: StaticMortar { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = ""; // no good selections for this mortar + }; + }; + class ace_csw { + enabled = 1; + magazineLocation = "_target selectionPosition 'otochlaven'"; + proxyWeapon = "CUP_proxy_mortar_82mm"; + disassembleWeapon = "CUP_2b14_carry"; + disassembleTurret = "ace_csw_mortarBaseplate"; + desiredAmmo = 1; + ammoLoadTime = 3; + ammoUnloadTime = 3; + }; + }; + + class CUP_M252_base: CUP_2b14_82mm_Base { + class ace_csw: ace_csw { + disassembleWeapon = "CUP_m252_carry"; + disassembleTurret = "ace_csw_mortarBaseplate"; + }; + }; + + class CUP_L16A2_base: CUP_M252_base { + class ace_csw: ace_csw { + disassembleWeapon = "CUP_l16a2_carry"; + disassembleTurret = "ace_csw_mortarBaseplate"; + }; + }; + + class StaticMGWeapon; + class CUP_M2StaticMG_base: StaticMGWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_m2"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_m2_carry"; + disassembleTurret = "ace_csw_m3Tripod"; + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_M2StaticMG_MiniTripod_base: CUP_M2StaticMG_base { + class ace_csw: ace_csw { + enabled = 1; + disassembleTurret = "ace_csw_m3TripodLow"; + }; + }; + + class CUP_DSHKM_base: StaticMGWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_DSHKM"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_DSHKM_carry"; + disassembleTurret = "ace_csw_kordTripod"; + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_DSHKM_MiniTripod_base: CUP_DSHKM_base { + class ace_csw: ace_csw { + enabled = 1; + disassembleTurret = "ace_csw_kordTripodLow"; + }; + }; + + class CUP_KORD_Base: StaticMGWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_KORD"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_KORD_carry"; + disassembleTurret = "ace_csw_kordTripod"; + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_KORD_MiniTripod_Base: CUP_KORD_Base { + class ace_csw: ace_csw { + enabled = 1; + disassembleTurret = "ace_csw_kordTripodLow"; + }; + }; + + class StaticGrenadeLauncher; + class CUP_AGS_base: StaticGrenadeLauncher { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_AGS30"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + disassembleWeapon = "CUP_AGS30_carry"; + disassembleTurret = "ace_csw_sag30Tripod"; + desiredAmmo = 29; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_MK19_TriPod_base: StaticGrenadeLauncher { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_MK19"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_MK19_carry"; + disassembleTurret = "ace_csw_m3TripodLow"; + desiredAmmo = 48; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class StaticATWeapon; + class CUP_Metis_Base: StaticATWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_AT13"; + magazineLocation = "_target selectionPosition 'gun'"; + disassembleWeapon = "CUP_launch_Metis"; + disassembleTurret = ""; + desiredAmmo = 1; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + + class CUP_TOW_TriPod_base: StaticATWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_TOW"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + disassembleWeapon = "CUP_TOW_carry"; + disassembleTurret = "ace_csw_m220Tripod"; + desiredAmmo = 1; + ammoLoadTime = 8; + ammoUnloadTime = 5; + }; + }; + + class CUP_TOW2_TriPod_base: CUP_TOW_TriPod_base { + class ace_csw: ace_csw { + disassembleWeapon = "CUP_TOW2_carry"; + }; + }; + + class CUP_SPG9_base: StaticATWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_SPG9"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + disassembleWeapon = "CUP_SPG9_carry"; + disassembleTurret = "ace_csw_spg9Tripod"; + desiredAmmo = 1; + ammoLoadTime = 5; + ammoUnloadTime = 3; + }; + }; + + class StaticCannon; + class CUP_D30_base: StaticCannon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_D30"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + desiredAmmo = 1; + ammoLoadTime = 5; + ammoUnloadTime = 5; + }; + }; + + class CUP_D30_AT_base: CUP_D30_base { + class ace_csw: ace_csw { + proxyWeapon = "CUP_proxy_D30AT"; + }; + }; + + class CUP_M119_base: CUP_D30_base { + class ace_csw: ace_csw { + proxyWeapon = "CUP_proxy_M119"; + }; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp new file mode 100644 index 0000000000..9ff8519ce1 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp @@ -0,0 +1,289 @@ +class CfgWeapons { + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + class CUP_2b14_carry: Launcher_Base_F { + displayName = ECSTRING(csw,2b14_tube); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\Podnos\data\ui\podnos_2b14_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + ace_csw_mortarBaseplate = "CUP_I_2b14_82mm_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 670; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_m252_carry: CUP_2b14_carry { + displayName = ECSTRING(csw,m252_tube); + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M252\data\ui\icomap_mortar_m251_ca.paa"; + class ace_csw: ace_csw { + class assembleTo { + ace_csw_mortarBaseplate = "CUP_I_M252_AAF"; + }; + }; + }; + + class CUP_l16a2_carry: CUP_2b14_carry { + displayName = ECSTRING(csw,m252_tube); + scope = 1; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M252\data\ui\icomap_mortar_m251_ca.paa"; + class ace_csw: ace_csw { + class assembleTo { + ace_csw_mortarBaseplate = "CUP_I_L16A2_AAF"; + }; + }; + }; + + class CUP_m2_carry: Launcher_Base_F { + displayName = ECSTRING(csw,m2_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M2\data\ui\icomap_M2_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_m3Tripod = "CUP_I_M2StaticMG_AAF"; + ace_csw_m3TripodLow = "CUP_I_M2StaticMG_MiniTripod_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 840; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_DSHKM_carry: Launcher_Base_F { + displayName = ECSTRING(csw,dshk_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\DShKM\data\ui\icomap_DShKM_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_kordTripod = "CUP_I_DSHKM_AAF"; + ace_csw_kordTripodLow = "CUP_I_DSHKM_MiniTriPod_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 740; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_KORD_carry: Launcher_Base_F { + displayName = ECSTRING(csw,kord_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\KORD\data\ui\icomap_kord_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_kordTripod = "CUP_I_KORD_high_AAF"; + ace_csw_kordTripodLow = "CUP_I_KORD_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 550; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_AGS30_carry: Launcher_Base_F { + displayName = ECSTRING(csw,ags30_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\AGS\data\ui\ags_static_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_sag30Tripod = "CUP_I_AGS_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 400; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_MK19_carry: Launcher_Base_F { + displayName = ECSTRING(csw,mk19_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\Mk19\data\ui\icomap_mk19_stat_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_m3TripodLow = "CUP_I_MK19_TriPod_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 770; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_launch_Metis: Launcher_Base_F { + ace_overpressure_angle = 45; + ace_overpressure_range = 15; + ace_overpressure_damage = 0.7; + class ace_csw { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "CUP_I_Metis_AAF"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 300; + }; + }; + + class CUP_TOW_carry: Launcher_Base_F { + displayName = ECSTRING(csw,tow_tube); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\TOW\data\ui\icomap_tow_static_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_m220Tripod = "CUP_I_TOW_TriPod_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 500; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_TOW2_carry: CUP_TOW_carry { + class ace_csw: ace_csw { + class assembleTo { + ace_csw_m220Tripod = "CUP_I_TOW2_TriPod_AAF"; + }; + }; + }; + + class CUP_SPG9_carry: Launcher_Base_F { + displayName = ECSTRING(csw,spg9_tube); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\SPG9\data\ui\icon_spg9_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_spg9Tripod = "CUP_I_SPG9_AAF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 1000; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class mortar_82mm; + class CUP_proxy_mortar_82mm: mortar_82mm { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_M2_static; + class CUP_proxy_m2: CUP_Vhmg_M2_static { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_DSHKM_veh; + class CUP_proxy_DSHKM: CUP_Vhmg_DSHKM_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_KORD_veh; + class CUP_proxy_KORD: CUP_Vhmg_KORD_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_AGS30_veh; + class CUP_proxy_AGS30: CUP_Vhmg_AGS30_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vgmg_MK19_veh; + class CUP_proxy_MK19: CUP_Vgmg_MK19_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vmlauncher_AT13_single_veh; + class CUP_proxy_AT13: CUP_Vmlauncher_AT13_single_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vmlauncher_TOW_single_veh; + class CUP_proxy_TOW: CUP_Vmlauncher_TOW_single_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vacannon_SPG9_veh; + class CUP_proxy_SPG9: CUP_Vacannon_SPG9_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vcannon_M119_veh; + class CUP_proxy_M119: CUP_Vcannon_M119_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vcannon_D30_veh; + class CUP_proxy_D30: CUP_Vcannon_D30_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vcannon_D30AT_veh; + class CUP_proxy_D30AT: CUP_Vcannon_D30AT_veh { + magazineReloadTime = 0.5; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/config.cpp new file mode 100644 index 0000000000..ccc2f0baf2 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_loadOrder", + "ace_csw" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgMagazineGroups.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/script_component.hpp new file mode 100644 index 0000000000..77a1b484cb --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT csw +#define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons +#include "..\script_component.hpp" + +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml new file mode 100644 index 0000000000..ea16be2905 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -0,0 +1,169 @@ + + + + + [CSW] AGS30 Belt + [CSW] AGS30 ベルト + [CSW] Лента AGS 30 + [CSW] AGS-30 벨트 + [CSW] AGS30 Gurt + [CSW] Cinta de AGS30 + [CSW] Nastro AGS30 + + + [CSW] MK19 Belt + [CSW] Mk19 ベルト + [CSW] Лента Mk19 + [CSW] Mk.19 벨트 + [CSW] MK19 Gurt + [CSW] Cinta de MK19 + [CSW] Nastro MK19 + + + [CSW] TOW Tube + [CSW] TOW チューブ + [CSW] Туба TOW + [CSW] TOW 튜브 + [CSW] TOW Rohr + [CSW] Tubo de TOW + [CSW] Tubo TOW + + + [CSW] TOW2 Tube + [CSW] TOW2 チューブ + [CSW] Туба TOW-2 + [CSW] TOW2 튜브 + [CSW] TOW2 Rohr + [CSW] Tubo de TOW2 + [CSW] Tubo TOW2 + + + [CSW] PG-9 Round + [CSW] PG-9 砲弾 + [CSW] Снаряд ПГ-9 + [CSW] PG-9 대전차고폭탄 + [CSW] PG-9 Rakete + [CSW] Carga de PG-9 + [CSW] Razzo PG-9 + + + [CSW] OG-9 Round + [CSW] OG-9 砲弾 + [CSW] Снаряд OГ-9 + [CSW] OG-9 고폭파편탄 + [CSW] OG-9 Rakete + [CSW] Carga de OG-9 + [CSW] Razzo OG-9 + + + [CSW] M1 HE + [CSW] M1 榴弾 + [CSW] M1 HE + [CSW] M1 고폭탄 + [CSW] M1 HE + [CSW] M1 HE + [CSW] HE de M1 + [CSW] M1 HE + + + [CSW] M84 Smoke + [CSW] M84 白煙弾 + [CSW] M84 Дымовая + [CSW] M84 연막탄 + [CSW] M84 Fumigène + [CSW] M84 Rauch + [CSW] Humo M84 + [CSW] M84 Fumogeno + + + [CSW] M60A2 WP + [CSW] M60A2 白リン弾 + [CSW] M60A2 WP + [CSW] M60A2 백린연막탄 + [CSW] M60A2 WP + [CSW] M60A2 WP + [CSW] M60A2 WP + [CSW] M60A2 WP + + + [CSW] M67 AT Laser Guided + [CSW] M67 対戦車レーザー誘導弾 + [CSW] M67 AT Laser Guided + [CSW] M67 레이저유도 대전차탄 + [CSW] M67 AT Guidé laser + [CSW] M67 AT Lasergelenkt + [CSW] AT Guiado por Láser M67 + [CSW] M67 AT Laserguidato + + + [CSW] M314 Illumination + [CSW] M314 照明弾 + [CSW] M314 Осветительная + [CSW] M314 조명탄 + [CSW] M314 Illumination + [CSW] M314 Beleuchtung + [CSW] Iluminación M314 + [CSW] M314 Illuminante + + + [CSW] 3OF56 HE + [CSW] 3OF56 榴弾 + [CSW] 3OF56 HE + [CSW] 3OF56 고폭탄 + [CSW] 3OF56 HE + [CSW] 3OF56 HE + [CSW] HE de 3OF56 + [CSW] 3OF56 HE + + + [CSW] 3OF69M Laser Guided + [CSW] 3OF69M レーザー誘導弾 + [CSW] 3OF69M Laser Guided + [CSW] 3OF69M 레이저유도탄 + [CSW] 3OF69M Guidé laser + [CSW] 3OF69M Lasergelenkt + [CSW] 3OF69M Guiado por Láser + [CSW] 3OF69M Laserguidato + + + [CSW] 122mm WP + [CSW] 122mm 白リン弾 + [CSW] 122mm WP + [CSW] 122mm 백린탄 + [CSW] 122mm WP + [CSW] 122mm WP + [CSW] WP de 122mm + [CSW] 122mm WP + + + [CSW] D-462 Smoke + [CSW] D-462 白煙弾 + [CSW] D-462 Дымовая + [CSW] D-462 연막탄 + [CSW] D-462 Fumigène + [CSW] D-462 Rauch + [CSW] Humo D-462 + [CSW] D-462 Fumogeno + + + [CSW] S-463 Illumination + [CSW] S-463 照明弾 + [CSW] S-463 Осветительная + [CSW] S-463 조명탄 + [CSW] S-463 Eclairante + [CSW] S-463 Beleuchtung + [CSW] Iluminación S-463 + [CSW] S-463 Illuminante + + + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT弾 + [CSW] BK-6M HEAT + [CSW] BK-6M 대전차고폭탄 + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT + + + diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..1658715ddb --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp @@ -0,0 +1,21 @@ +class CfgAmmo { + class PipeBombBase; + class CUP_TimeBomb_Ammo: PipeBombBase { + hit = 3000; + indirectHit = 3000; + indirectHitRange = 5; + ace_explosives_explodeOnDefuse = 0.02; + }; + class CUP_PipeBomb_Ammo: PipeBombBase { + hit = 3000; + indirectHit = 3000; + indirectHitRange = 5; + ace_explosives_explodeOnDefuse = 0.02; + }; + + class CUP_Mine_Ammo; + class CUP_IED_V1_Ammo: CUP_Mine_Ammo { + ace_explosives_explodeOnDefuse = 0.06; + triggerWhenDestroyed = 1; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..15df2f7333 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp @@ -0,0 +1,103 @@ +class CfgMagazines { + class CA_Magazine; + class CUP_TimeBomb_M: CA_Magazine { + scope = 1; + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_PipeBomb_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + }; + }; + class CUP_Mine_M: CUP_TimeBomb_M { + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_Mine_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.08; + }; + }; + }; + class CUP_MineE_M: CUP_TimeBomb_M { + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_MineE_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.06; + }; + }; + }; + + class CUP_IED_V1_M: CUP_Mine_M { + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V1_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; + }; + }; + class CUP_IED_V2_M: CUP_IED_V1_M { + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V2_place_CUP"; + }; + class CUP_IED_V3_M: CUP_IED_V1_M { + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V3_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; + class Timer { + digDistance = 0.06; + }; + class Command { + digDistance = 0.06; + }; + class MK16_Transmitter { + digDistance = 0.06; + }; + class DeadmanSwitch { + digDistance = 0.06; + }; + class Cellphone { + digDistance = 0.06; + }; + class PressurePlate { + digDistance = 0.06; + }; + }; + }; + class CUP_IED_V4_M: CUP_IED_V1_M { + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V4_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; + class Timer { + digDistance = 0.08; + }; + class Command { + digDistance = 0.08; + }; + class MK16_Transmitter { + digDistance = 0.08; + }; + class DeadmanSwitch { + digDistance = 0.08; + }; + class Cellphone { + digDistance = 0.08; + }; + class PressurePlate { + digDistance = 0.08; + }; + }; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..d10c315c3d --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp @@ -0,0 +1,32 @@ +class CfgVehicles { + class ACE_Explosives_Place; + class ACE_PipeBomb_place_CUP: ACE_Explosives_Place { + displayName = "Satchel Charge"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_Satchel.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_Mine_place_CUP: ACE_Explosives_Place { + displayName = "AT-15 Anti-Tank Mine"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_AT15.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_MineE_place_CUP: ACE_Explosives_Place { + displayName = "TM46 Anti-Tank Mine"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_TM46.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_IED_V1_place_CUP: ACE_Explosives_Place { + displayName = "IED"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V1.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_IED_V2_place_CUP: ACE_IED_V1_place_CUP { + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V2.p3d"; + }; + class ACE_IED_V3_place_CUP: ACE_IED_V1_place_CUP { + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V3.p3d"; + }; + class ACE_IED_V4_place_CUP: ACE_IED_V1_place_CUP { + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V4.p3d"; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/config.cpp new file mode 100644 index 0000000000..ce16a310a8 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_LoadOrder", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp new file mode 100644 index 0000000000..2632a43e61 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp @@ -0,0 +1,26 @@ +class CfgAmmo { + class MissileBase; + class CUP_M_Javelin_AT: MissileBase { + irLock = 1; + laserLock = 0; + airLock = 0; + + class ace_missileguidance { + enabled = 1; + minDeflection = 0.00005; + maxDeflection = 0.025; + incDeflection = 0.00005; + canVanillaLock = 0; + defaultSeekerType = "Optic"; + seekerTypes[] = {"Optic"}; + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + seekerAngle = 180; + seekerAccuracy = 1; + seekerMinRange = 0; + seekerMaxRange = 2500; + defaultAttackProfile = "JAV_TOP"; + attackProfiles[] = {"JAV_TOP", "JAV_DIR"}; + }; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgWeapons.hpp new file mode 100644 index 0000000000..35b1d2bf09 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgWeapons.hpp @@ -0,0 +1,14 @@ +class CfgWeapons { + class Launcher_Base_F; + class CUP_launch_Javelin: Launcher_Base_F { + ace_javelin_enabled = 1; + weaponInfoType = "ACE_RscOptics_javelin"; + modelOptics = QPATHTOEF(javelin,data\reticle_titan.p3d); + canLock = 0; + lockingTargetSound[] = {"", 0, 1}; + lockedTargetSound[] = {"", 0, 1}; + ace_overpressure_angle = 30; + ace_overpressure_range = 2; + ace_overpressure_damage = 0.5; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/config.cpp new file mode 100644 index 0000000000..8d5eeb37d5 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_LoadOrder", + "ace_javelin" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/script_component.hpp new file mode 100644 index 0000000000..d42e0f4f01 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT javelin +#define SUBCOMPONENT_BEAUTIFIED Javelin +#include "..\script_component.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp new file mode 100644 index 0000000000..04d26b8ead --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp @@ -0,0 +1,118 @@ +#define NVG_BINO_PRESET \ + ace_nightvision_bluRadius = 0.13; \ + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_binos_4096.paa); \ + EGVAR(nightvision,generation) = 3; \ + modelOptics = "" + +#define NVG_MONO_PRESET(GEN) \ + EGVAR(nightvision,eyeCups) = 1; \ + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_4096.paa); \ + EGVAR(nightvision,bluRadius) = 0.13; \ + EGVAR(nightvision,generation) = GEN; \ + modelOptics = "" + +#define NVG_GPNVG_PRESET \ + EGVAR(nightvision,bluRadius) = 0.13; \ + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_quad_4096.paa); \ + EGVAR(nightvision,generation) = 4; \ + modelOptics = "" + +#define NVG_GREEN_PRESET EGVAR(nightvision,colorPreset)[] = {0, {0.0, 0.0, 0.0, 0.0}, {1.3, 1.2, 0.0, 0.9}, {6, 1, 1, 0}} +#define NVG_WP_PRESET EGVAR(nightvision,colorPreset)[] = {0, {0.0, 0.0, 0.0, 0.0}, {1.1, 0.8, 1.9, 0.9}, {1, 1, 6, 0}} + +class CfgWeapons { + class NVGoggles; + // Monocular + class CUP_NVG_PVS7: NVGoggles { + NVG_MONO_PRESET(3); + NVG_GREEN_PRESET; + }; + class CUP_NVG_HMNVS: NVGoggles { + NVG_MONO_PRESET(3); + NVG_GREEN_PRESET; + }; + + // Binocular + class CUP_NVG_PVS14: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_black: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_green: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_tan: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_winter: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + + // White Phosphor NVGs + class CUP_NVG_PVS14_WP: CUP_NVG_PVS14 { + displayName = SUBCSTRING(CUP_NVG_PVS14_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_black_WP: CUP_NVG_PVS15_black { + displayName = SUBCSTRING(CUP_NVG_PVS15_black_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_green_WP: CUP_NVG_PVS15_green { + displayName = SUBCSTRING(CUP_NVG_PVS15_green_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_tan_WP: CUP_NVG_PVS15_tan { + displayName = SUBCSTRING(CUP_NVG_PVS15_tan_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_winter_WP: CUP_NVG_PVS15_winter { + displayName = SUBCSTRING(CUP_NVG_PVS15_winter_WP); + NVG_WP_PRESET; + }; + + // Gen4s + class CUP_NVG_1PN138: NVGoggles { + NVG_MONO_PRESET(4); + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_black: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_tan: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_green: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_winter: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + + // White Phosphor NVGs + class CUP_NVG_GPNVG_black_WP: CUP_NVG_GPNVG_black { + displayName = SUBCSTRING(CUP_NVG_GPNVG_black_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_GPNVG_tan_WP: CUP_NVG_GPNVG_tan { + displayName = SUBCSTRING(CUP_NVG_GPNVG_tan_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_GPNVG_green_WP: CUP_NVG_GPNVG_green { + displayName = SUBCSTRING(CUP_NVG_GPNVG_green_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_GPNVG_winter_WP: CUP_NVG_GPNVG_winter { + displayName = SUBCSTRING(CUP_NVG_GPNVG_winter_WP); + NVG_WP_PRESET; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp new file mode 100644 index 0000000000..4730cdf3a9 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = { + "CUP_NVG_PVS14_WP", "CUP_NVG_PVS15_black_WP", "CUP_NVG_PVS15_green_WP", "CUP_NVG_PVS15_tan_WP", "CUP_NVG_PVS15_winter_WP", + "CUP_NVG_GPNVG_black_WP", "CUP_NVG_GPNVG_tan_WP", "CUP_NVG_GPNVG_green_WP", "CUP_NVG_GPNVG_winter_WP" + }; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_LoadOrder", + "ace_nightvision" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/script_component.hpp new file mode 100644 index 0000000000..85036e02b6 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nightvision +#define SUBCOMPONENT_BEAUTIFIED Night Vision +#include "..\script_component.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml new file mode 100644 index 0000000000..5e31f93caf --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml @@ -0,0 +1,102 @@ + + + + + AN/PVS-14 (WP) + AN/PVS-14 (白色蛍光) + AN/PVS-14 (FB) + AN/PVS-14 (WP) + AN/PVS-14 (WP) + AN/PVS-14 (백색광) + AN/PVS-14 (WP) + AN/PVS-14 (БФ) + AN/PVS-14 (WP) + + + AN/PVS-15 (Black, WP) + AN/PVS-15 (ブラック、白色蛍光) + AN/PVS-15 (Nero, FB) + AN/PVS-15 (Czarne, WP) + AN/PVS-15 (Schwarz, WP) + AN/PVS-15 (검정, 백색광) + AN/PVS-15 (Noires, WP) + AN/PVS-15 (Чёрный, БФ) + AN/PVS-15 (Negras, WP) + + + AN/PVS-15 (Green, WP) + AN/PVS-15 (グリーン, 白色蛍光) + AN/PVS-15 (Verde, FB) + AN/PVS-15 (Zielone, WP) + AN/PVS-15 (Grün, WP) + AN/PVS-15 (녹색, 백색광) + AN/PVS-15 (Vertes, WP) + AN/PVS-15 (Зелёный, БФ) + AN/PVS-15 (Verdes, WP) + + + AN/PVS-15 (Tan, WP) + AN/PVS-15 (タン, 白色蛍光) + AN/PVS-15 (Marroncino, FB) + AN/PVS-15 (Jasnobrązowa, WP) + AN/PVS-15 (Hellbraun, WP) + AN/PVS-15 (황갈색, 백색광) + AN/PVS-15 (Marron clair, WP) + AN/PVS-15 (Желтовато-коричневый, БФ) + AN/PVS-15 (Marrones, WP) + + + AN/PVS-15 (Winter, WP) + AN/PVS-15 (冬季迷彩, WP) + AN/PVS-15 (Invernale, FB) + AN/PVS-15 (설상, 백색광) + AN/PVS-15 (Белый, БФ) + AN/PVS-15 (Blanc, WP) + AN/PVS-15 (Winter, WP) + AN/PVS-15 (Blancas, WP) + + + GPNVG (Black, WP) + GPNVG (ブラック、白色蛍光) + GPNVG (Nero, FB) + GPNVG (Czarne, WP) + GPNVG (Schwarz, WP) + GPNVG (검정, 백색광) + GPNVG (Noires, WP) + GPNVG (Чёрный, БФ) + GPNVG (Negras, WP) + + + GPNVG (Tan, WP) + GPNVG (タン, 白色蛍光) + GPNVG (Marroncino, FB) + GPNVG (Jasnobrązowa, WP) + GPNVG (Hellbraun, WP) + GPNVG (황갈색, 백색광) + GPNVG (Marron clair, WP) + GPNVG (Желтовато-коричневый, БФ) + GPNVG (Marrones, WP) + + + GPNVG (Green, WP) + GPNVG (グリーン, 白色蛍光) + GPNVG (Verde, FB) + GPNVG (Zielone, WP) + GPNVG (Grün, WP) + GPNVG (녹색, 백색광) + GPNVG (Vertes, WP) + GPNVG (Зелёный, БФ) + GPNVG (Verdes, WP) + + + GPNVG (Winter, WP) + GPNVG (冬季迷彩, WP) + GPNVG (Invernale, FB) + GPNVG (설상, 백색광) + AN/PVS-15 (Белый, БФ) + GPNVG (Blanc, WP) + GPNVG (Winter, WP) + GPNVG (Blancas, WP) + + + diff --git a/addons/compat_cup_weapons/config.cpp b/addons/compat_cup_weapons/config.cpp new file mode 100644 index 0000000000..54dd0271cc --- /dev/null +++ b/addons/compat_cup_weapons/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"CUP_Weapons_LoadOrder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/script_component.hpp b/addons/compat_cup_weapons/script_component.hpp new file mode 100644 index 0000000000..9fb9892c1d --- /dev/null +++ b/addons/compat_cup_weapons/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_cup_weapons +#define COMPONENT_BEAUTIFIED CUP Weapons Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_gm/$PBOPREFIX$ b/addons/compat_gm/$PBOPREFIX$ new file mode 100644 index 0000000000..6076e73cbf --- /dev/null +++ b/addons/compat_gm/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_gm diff --git a/addons/compat_gm/CfgEventHandlers.hpp b/addons/compat_gm/CfgEventHandlers.hpp new file mode 100644 index 0000000000..865276cfba --- /dev/null +++ b/addons/compat_gm/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; diff --git a/addons/compat_gm/CfgMagazines.hpp b/addons/compat_gm/CfgMagazines.hpp new file mode 100644 index 0000000000..ee5d017275 --- /dev/null +++ b/addons/compat_gm/CfgMagazines.hpp @@ -0,0 +1,28 @@ +class CfgMagazines { + // MG3 + class gm_120rnd_762x51mm_mg3_grn; + class gm_120Rnd_762x51mm_B_T_DM21_mg3_grn: gm_120rnd_762x51mm_mg3_grn { + ACE_isBelt = 1; + }; + class gm_120Rnd_762x51mm_B_T_DM21A1_mg3_grn: gm_120rnd_762x51mm_mg3_grn { + ACE_isBelt = 1; + }; + class gm_120Rnd_762x51mm_B_T_DM21A2_mg3_grn: gm_120rnd_762x51mm_mg3_grn { + ACE_isBelt = 1; + }; + + // PK + class gm_100rnd_762x54mmR_pk_grn; + class gm_100Rnd_762x54mm_API_b32_pk_grn: gm_100rnd_762x54mmR_pk_grn { + ACE_isBelt = 1; + }; + class gm_100Rnd_762x54mm_B_T_t46_pk_grn: gm_100rnd_762x54mmR_pk_grn { + ACE_isBelt = 1; + }; + class gm_100Rnd_762x54mmR_API_7bz3_pk_grn: gm_100rnd_762x54mmR_pk_grn { + ACE_isBelt = 1; + }; + class gm_100Rnd_762x54mmR_B_T_7t2_pk_grn: gm_100rnd_762x54mmR_pk_grn { + ACE_isBelt = 1; + }; +}; diff --git a/addons/compat_gm/CfgVehicles.hpp b/addons/compat_gm/CfgVehicles.hpp new file mode 100644 index 0000000000..6d03465cd7 --- /dev/null +++ b/addons/compat_gm/CfgVehicles.hpp @@ -0,0 +1,369 @@ +class CfgVehicles { + + // REPAIR, REFUEL, REARM + + class ReammoBox_F; + class gm_AmmoBox_base: ReammoBox_F { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0,1,1}; + EGVAR(dragging,carryDirection) = 0; + + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0,1.2,0}; + EGVAR(dragging,dragDirection) = 0; + }; + + class gm_jerrycan_base; + class gm_jerrycan: gm_jerrycan_base { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0,1,1}; + EGVAR(dragging,carryDirection) = 0; + + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0,1.2,0}; + EGVAR(dragging,dragDirection) = 0; + }; + + // STATIC + + class gm_ge_army_shelteraceII_repair_base; + class gm_ge_army_shelteraceII_repair: gm_ge_army_shelteraceII_repair_base { + EGVAR(repair,canRepair) = 1; + }; + + class gm_gc_army_shelterlakII_repair_base; + class gm_gc_army_shelterlakII_repair: gm_gc_army_shelterlakII_repair_base { + EGVAR(repair,canRepair) = 1; + }; + + + // W H E E L E D + + class gm_wheeled_base; + class gm_wheeled_truck_base; + class gm_wheeled_APC_base; + class gm_wheeled_motorcycle_base; + + // EAST + + class gm_wheeled_car_base: gm_wheeled_base { + EGVAR(cargo,hasCargo) = 1; + EGVAR(cargo,space) = 4; + EGVAR(refuel,canReceive) = 1; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.03; + EGVAR(vehicle_damage,engineDetonationProb) = 0.03; + EGVAR(vehicle_damage,hullFireProb) = 0.6; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 0.1; + }; + + class gm_wheeled_bicycle_base: gm_wheeled_base { + EGVAR(cargo,hasCargo) = 0; + EGVAR(refuel,canReceive) = 0; + }; + + class gm_uaz469_base: gm_wheeled_car_base { + EGVAR(refuel,fuelCapacity) = 78; + }; + + class gm_p601_base: gm_wheeled_car_base { + EGVAR(refuel,fuelCapacity) = 26; + }; + + class gm_brdm2_base: gm_wheeled_APC_base { + EGVAR(refuel,fuelCapacity) = 290; + }; + + class gm_btr60_base: gm_wheeled_APC_base { + EGVAR(refuel,fuelCapacity) = 290; + EGVAR(cookoff,cookoffSelections)[] = {"commanderturret_hatch"}; + }; + + class gm_ural4320_base: gm_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 360; + }; + + class gm_ural4320_reammo_base: gm_ural4320_base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class gm_ural4320_refuel_base: gm_ural4320_base { + EGVAR(refuel,hooks)[] = {{-0.05,-3.6,-0.45}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class gm_ural4320_medic_base: gm_ural4320_base { + EGVAR(medical,medicClass) = 1; + }; + + + // WEST + + class gm_k125_base: gm_wheeled_motorcycle_base { + EGVAR(refuel,fuelCapacity) = 14.5; + }; + + class gm_typ1_base: gm_wheeled_car_base { + EGVAR(refuel,fuelCapacity) = 47.3; + }; + + class gm_iltis_base: gm_wheeled_car_base { + EGVAR(refuel,fuelCapacity) = 83; + }; + + + class gm_u1300l_base: gm_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 90; + }; + + class gm_u1300l_medic_base: gm_u1300l_base { + EGVAR(medical,medicClass) = 1; + }; + + class gm_kat1_base: gm_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 270; + }; + + class gm_kat1_451_base; + class gm_kat1_451_refuel_base: gm_kat1_451_base { + gm_InsigniasDefaultHazardSign = "gm_insignia_hazard_fuelF54_wht"; + EGVAR(refuel,fuelCargo) = 4600; + EGVAR(refuel,hooks)[] = {{-0.60,-3.44,-0.919689},{0.60,-3.44,-0.919689}}; + }; + + class gm_kat1_454_base; + class gm_kat1_454_cargo_base: gm_kat1_454_base { + EGVAR(cargo,space) = 10; + }; + + class gm_fuchs_base: gm_wheeled_APC_base { + EGVAR(refuel,fuelCapacity) = 390; + }; + + class gm_luchs_base: gm_wheeled_APC_base { + EGVAR(refuel,fuelCapacity) = 500; + EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch", "commanderturret_hatch"}; + }; + + + // T R A C K E D + + class Tank_F; + class gm_tracked_base: Tank_F { + EGVAR(cargo,hasCargo) = 1; + EGVAR(cargo,space) = 4; + EGVAR(refuel,canReceive) = 1; + }; + class gm_tracked_APC_base: gm_tracked_base { + EGVAR(vehicle_damage,hullDetonationProb) = 0.03; + EGVAR(vehicle_damage,turretDetonationProb) = 0.03; + EGVAR(vehicle_damage,engineDetonationProb) = 0.03; + EGVAR(vehicle_damage,hullFireProb) = 0.3; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 0.1; + }; + class gm_tracked_Tank_base: gm_tracked_base { + EGVAR(vehicle_damage,hullDetonationProb) = 0.01; + EGVAR(vehicle_damage,turretDetonationProb) = 0.01; + EGVAR(vehicle_damage,engineDetonationProb) = 0.01; + EGVAR(vehicle_damage,hullFireProb) = 0.2; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 0.1; + }; + + // EAST + class gm_bmp1_base: gm_tracked_APC_base { + EGVAR(map,vehicleLightColor)[] = {0,1,0,0.1}; + EGVAR(refuel,fuelCapacity) = 460; + EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch","commanderturret_hatch"}; + }; + + class gm_pt76_base: gm_tracked_Tank_base { + EGVAR(refuel,fuelCapacity) = 250; + }; + + class gm_t55_base: gm_tracked_Tank_base { + EGVAR(refuel,fuelCapacity) = 900; // only with external tanks + EGVAR(cookoff,cookoffSelections)[] = {"machinegunturret_01_hatch","commanderturret_hatch"}; + }; + + class gm_zsu234_base: gm_tracked_Tank_base { + EGVAR(refuel,fuelCapacity) = 812; + }; + + // WEST + class gm_Leopard1_base; + class gm_Leopard1a0_base: gm_Leopard1_base { + EGVAR(refuel,fuelCapacity) = 955; + EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch_1","commanderturret_hatch"}; + }; + + class gm_Gepard_base: gm_Leopard1_base { + EGVAR(refuel,fuelCapacity) = 985; + }; + + class gm_BPz2_base; + class gm_BPz2a0_base: gm_BPz2_base { + EGVAR(refuel,fuelCapacity) = 1160; + EGVAR(cookoff,cookoffSelections)[] = {"commanderturret_hatch"}; + }; + + class gm_marder1_base: gm_tracked_APC_base { + EGVAR(refuel,fuelCapacity) = 652; + EGVAR(cookoff,cookoffSelections)[] = {"observerturret_hatch", "commanderturret_hatch"}; + }; + + class gm_m113_base: gm_tracked_APC_base { + EGVAR(refuel,fuelCapacity) = 360; + }; + + class gm_m113a1g_base; + class gm_m113a1g_medic_base: gm_m113a1g_base { + EGVAR(medical,medicClass) = 1; + }; + + class gm_m113a1dk_base; + class gm_m113a1dk_medic_base: gm_m113a1dk_base { + EGVAR(medical,medicClass) = 1; + }; + + // If any hard edits are made, move to an appropriate subcomponent + // fastroping not needed unlike RHS as no hard edits are made here + // H E L I C O P T E R S + + class Helicopter_Base_F; + class Helicopter_Base_H: Helicopter_Base_F { + class EventHandlers; + }; + class gm_helicopter_base: Helicopter_Base_H {}; + + // WEST + + class gm_bo105_base: gm_helicopter_base { + EGVAR(map,vehicleLightColor)[] = {1,0,0,0.1}; + EGVAR(refuel,fuelCapacity) = 3700; + EGVAR(fastroping,enabled) = 0; + + // TODO: stringtables + class UserActions { + class openDoor_L { + displayNameDefault = "Open left Door"; + displayName = "Open left Door"; + position = ""; + radius = 2.7; + onlyForPlayer = 1; + condition = QUOTE((this animationSourcePhase 'door_2_1_unhide' > 0.5) && (this doorPhase 'door_2_1_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + statement = "this animateDoor ['door_2_1_source',1]"; + }; + + class openDoor_R: openDoor_L { + displayNameDefault = "Open right Door"; + displayName = "Open right Door"; + condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + statement = "this animateDoor ['door_2_2_source',1]"; + }; + + class closeDoor_L { + displayNameDefault = "Close left Door"; + displayName = "Close left Door"; + position = ""; + radius = 2.7; + onlyForPlayer = 1; + condition = QUOTE((this animationSourcePhase 'door_2_1_unhide' > 0.5) && (this doorPhase 'door_2_1_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + statement = "this animateDoor ['door_2_1_source',0]"; + }; + + class closeDoor_R: closeDoor_L { + displayNameDefault = "Close right Door"; + displayName = "Close right Door"; + condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + statement = "this animateDoor ['door_2_2_source',0]"; + }; + }; + }; + class gm_bo105p1m_vbh_base; + class gm_bo105p1m_vbh_swooper_base: gm_bo105p1m_vbh_base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{-1.34,0.695,-0.0757732},{1.34,0.695,-0.0973468}}; + EGVAR(fastroping,onCut) = QFUNC(onCut); + EGVAR(fastroping,onCutRopes) = QFUNC(onCutRopes); + EGVAR(fastroping,onDeployRopes) = QFUNC(onDeployRopes); + EGVAR(fastroping,onPrepare) = QFUNC(onPrepare); + }; + + class gm_ch53_base: gm_helicopter_base { + EGVAR(map,vehicleLightColor)[] = {1,0,0,0.1}; + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{0.6, -5.2, -0.8},{-0.6, -5.2, -0.8}}; + EGVAR(refuel,fuelCapacity) = 3850; + EGVAR(fastroping,onCut) = QFUNC(onCut); + EGVAR(fastroping,onPrepare) = QFUNC(onPrepare); + }; + + class gm_ch53g_base: gm_ch53_base { + EGVAR(refuel,fuelCapacity) = 8770; + }; + + // EAST + class gm_mi2_base: gm_helicopter_base { + EGVAR(map,vehicleLightColor)[] = {1,0,0,0.1}; + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{-1.17969,0.0205078,-0.178533}}; + EGVAR(refuel,fuelCapacity) = 600; + EGVAR(fastroping,onCut) = QFUNC(onCut); + EGVAR(fastroping,onPrepare) = QFUNC(onPrepare); + }; + + + class gm_mi2sr_base: gm_mi2_base { + EGVAR(refuel,fuelCapacity) = 1076; + }; + + class gm_mi2p_base: gm_mi2_base { + EGVAR(refuel,fuelCapacity) = 1076; + }; + + class gm_mi2ch_base: gm_mi2_base { + EGVAR(refuel,fuelCapacity) = 1076; + }; + + class gm_mi2platan_base: gm_mi2_base { + EGVAR(refuel,fuelCapacity) = 1076; + }; + + // P L A N E S + + class Plane_Base_F; + class gm_plane_base: Plane_Base_F { + EGVAR(refuel,canReceive) = 1; + EGVAR(cargo,hasCargo) = 1; + EGVAR(cargo,space) = 4; + }; + + // EAST + class gm_l410_base: gm_plane_base { + EGVAR(refuel,fuelCapacity) = 1300; + }; + + // WEST + class gm_do28d2_base: gm_plane_base { + EGVAR(refuel,fuelCapacity) = 894; // source mondkalb + }; + + class gm_do28d2_medevac_base: gm_do28d2_base { + EGVAR(medical,medicClass) = 1; + }; +}; diff --git a/addons/compat_gm/CfgWeapons.hpp b/addons/compat_gm/CfgWeapons.hpp new file mode 100644 index 0000000000..7c77827b2f --- /dev/null +++ b/addons/compat_gm/CfgWeapons.hpp @@ -0,0 +1,147 @@ +class CfgWeapons { + + // MACHINE GUNS + class gm_pk_base; + class gm_pkm_base: gm_pk_base { + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; + }; + class gm_rifle_base; + class gm_machineGun_base: gm_rifle_base { + EGVAR(overheating,closedBolt) = 0; + }; + class gm_mg3_base: gm_machineGun_base { + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; + }; + class gm_mg3_veh_base: gm_mg3_base { + EGVAR(overheating,allowSwapBarrel) = 0; + }; + class gm_launcher_base; + class gm_carlgustaf_m2_base: gm_launcher_base { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,angle) = 60; + EGVAR(overpressure,damage) = 0.7; + EGVAR(overpressure,priority) = 1; + EGVAR(overpressure,range) = 10; + }; + + // SUB MACHINE GUNS + class gm_mp2_base: gm_rifle_base { + EGVAR(overheating,closedBolt) = 0; + }; + class gm_pm63_base: gm_rifle_base { + EGVAR(overheating,closedBolt) = 0; + }; + + // GRENADE LAUNCHERS + class gm_hk69a1_base: gm_rifle_base { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + class gm_pallad_d_base: gm_rifle_base { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + + // FLARE GUNS + class gm_pistol_base; + class gm_lp1_base: gm_pistol_base { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + class gm_p2a1_base: gm_pistol_base { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + + // HELMETS + class gm_ge_headgear_headset_crew_base; + class gm_ge_headgear_headset_crew_oli: gm_ge_headgear_headset_crew_base { + HEARING_PROTECTION_PELTOR; + }; + + class gm_ge_headgear_sph4_base; + class gm_ge_headgear_sph4_oli: gm_ge_headgear_sph4_base { + HEARING_PROTECTION_PELTOR; + }; + + class gm_pl_headgear_wz63_base; + class gm_pl_army_headgear_wz63_oli: gm_pl_headgear_wz63_base { + HEARING_PROTECTION_PELTOR; + }; + class gm_pl_army_headgear_wz63_net_oli: gm_pl_headgear_wz63_base { + HEARING_PROTECTION_PELTOR; + }; + + class gm_ge_headgear_crewhat_80_base; + class gm_ge_headgear_crewhat_80_blk: gm_ge_headgear_crewhat_80_base { + HEARING_PROTECTION_PELTOR; + }; + + class gm_gc_headgear_crewhat_80_base; + class gm_gc_army_headgear_crewhat_80_blk: gm_gc_headgear_crewhat_80_base { + HEARING_PROTECTION_PELTOR; + }; + + class gm_gc_headgear_zsh3_base; + class gm_gc_headgear_zsh3_wht: gm_gc_headgear_zsh3_base { + HEARING_PROTECTION_PELTOR; + }; + class gm_gc_headgear_zsh3_blu: gm_gc_headgear_zsh3_base { + HEARING_PROTECTION_PELTOR; + }; + class gm_gc_headgear_zsh3_orn: gm_gc_headgear_zsh3_base { + HEARING_PROTECTION_PELTOR; + }; + + class gm_ge_headgear_beret_crew_bdx; + class gm_ge_headgear_beret_crew_blk; + class gm_ge_headgear_beret_crew_grn; + class gm_ge_headgear_beret_crew_red; + class gm_ge_headgear_beret_crew_red_antiair: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_blk_antitank: gm_ge_headgear_beret_crew_blk { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_blk_armor: gm_ge_headgear_beret_crew_blk { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_blk_armorrecon: gm_ge_headgear_beret_crew_blk { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_artillery: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_engineer: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_maintenance: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_grn_mechinf: gm_ge_headgear_beret_crew_grn { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_militarypolice: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_nbc: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_opcom: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_bdx_paratrooper: gm_ge_headgear_beret_crew_bdx { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_blk_recon: gm_ge_headgear_beret_crew_blk { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_supply: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; + class gm_ge_headgear_beret_crew_red_signals: gm_ge_headgear_beret_crew_red { + HEARING_PROTECTION_PELTOR; + }; +}; diff --git a/addons/compat_gm/XEH_PREP.hpp b/addons/compat_gm/XEH_PREP.hpp new file mode 100644 index 0000000000..b93865ad78 --- /dev/null +++ b/addons/compat_gm/XEH_PREP.hpp @@ -0,0 +1,4 @@ +PREP(onCut); +PREP(onCutRopes); +PREP(onDeployRopes); +PREP(onPrepare); diff --git a/addons/compat_gm/XEH_preStart.sqf b/addons/compat_gm/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_gm/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_gm/XEH_preinit.sqf b/addons/compat_gm/XEH_preinit.sqf new file mode 100644 index 0000000000..d35e14fec5 --- /dev/null +++ b/addons/compat_gm/XEH_preinit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +// handle GM uniform additional insignia +[QEGVAR(arsenal,displayClosed), { + EGVAR(arsenal,center) call gm_core_characters_fnc_updateUniformDetails; +}] call CBA_fnc_addEventHandler; + +ADDON = true; diff --git a/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp b/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..3da49f45ab --- /dev/null +++ b/addons/compat_gm/compat_gm_explosives/CfgAmmo.hpp @@ -0,0 +1,25 @@ +class CfgAmmo { + class PipeBombBase; + class gm_explosive_petn_charge: PipeBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; + }; + class gm_explosive_plnp_charge: PipeBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; + }; + + class gm_mine_at_base; + class gm_mine_at_mn111: gm_mine_at_base { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; + }; + class gm_mine_at_dm21: gm_mine_at_base { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; + }; + class gm_mine_at_tm46: gm_mine_at_base { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; + }; + + class gm_mine_bounce_base; + class gm_mine_ap_dm31: gm_mine_bounce_base { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; + }; +}; diff --git a/addons/compat_gm/compat_gm_explosives/CfgMagazines.hpp b/addons/compat_gm/compat_gm_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..17d51d3b45 --- /dev/null +++ b/addons/compat_gm/compat_gm_explosives/CfgMagazines.hpp @@ -0,0 +1,87 @@ +class CfgMagazines { + // Explosives + class gm_explosive_petn_charge_base; + class gm_explosive_petn_charge: gm_explosive_petn_charge_base { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_petn); + useAction = 0; + 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 gm_explosive_plnp_charge_base; + class gm_explosive_plnp_charge: gm_explosive_plnp_charge_base { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_plnp); + useAction = 0; + 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 gm_mine_at_base; + class gm_mine_at_tm46: gm_mine_at_base { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_mine_tm46); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; + class gm_mine_at_dm21: gm_mine_at_base { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_dm21); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; + class gm_mine_at_mn111: gm_mine_at_base { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_m111); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; + + class gm_mine_ap_dm31: gm_mine_at_base { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_dm31); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.125; + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp b/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..bb279c82b9 --- /dev/null +++ b/addons/compat_gm/compat_gm_explosives/CfgVehicles.hpp @@ -0,0 +1,67 @@ +class CfgVehicles { + + class Items_base_F; + class EGVAR(explosives,Place): Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + // CHARGE + class EGVAR(explosives,Place_gm_explosive_petn): EGVAR(explosives,Place) { + displayName = "PETN Charge"; + model = "gm\gm_weapons\gm_put\gm_explosive_charge_petn"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + class EGVAR(explosives,Place_gm_explosive_plnp): EGVAR(explosives,Place) { + displayName = "PLNP Charge"; + model = "gm\gm_weapons\gm_put\gm_explosive_charge_plnp"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + // AT MINE + class EGVAR(explosives,Place_gm_mine_tm46): EGVAR(explosives,Place) { + displayName = "AT Mine TM46"; + model = "gm\gm_weapons\gm_put\gm_mine_at_tm46"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + class EGVAR(explosives,Place_gm_explosive_dm21): EGVAR(explosives,Place) { + displayName = "AT Mine DM21"; + model = "gm\gm_weapons\gm_put\gm_mine_at_dm21"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + class EGVAR(explosives,Place_gm_explosive_m111): EGVAR(explosives,Place) { + displayName = "MN 111"; + model = "gm\gm_weapons\gm_launchers\gm_platan\gm_mine_at_mn111_disarmed"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + // AP + class EGVAR(explosives,Place_gm_explosive_dm31): EGVAR(explosives,Place) { + displayName = "AP Mine DM31"; + model = "gm\gm_weapons\gm_put\gm_mine_ap_dm31"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_explosives/config.cpp b/addons/compat_gm/compat_gm_explosives/config.cpp new file mode 100644 index 0000000000..e240c28389 --- /dev/null +++ b/addons/compat_gm/compat_gm_explosives/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "gm_core", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/compat_gm_explosives/script_component.hpp b/addons/compat_gm/compat_gm_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_gm/compat_gm_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_gm/compat_gm_refuel/CfgEventHandlers.hpp b/addons/compat_gm/compat_gm_refuel/CfgEventHandlers.hpp new file mode 100644 index 0000000000..81ef39f88d --- /dev/null +++ b/addons/compat_gm/compat_gm_refuel/CfgEventHandlers.hpp @@ -0,0 +1,7 @@ +class Extended_InitPost_EventHandlers { + class gm_jerrycan { + class ADDON { + init = QUOTE(call EFUNC(refuel,makeJerryCan)); + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_refuel/config.cpp b/addons/compat_gm/compat_gm_refuel/config.cpp new file mode 100644 index 0000000000..05688eff70 --- /dev/null +++ b/addons/compat_gm/compat_gm_refuel/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "gm_core", + "ace_refuel" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgEventHandlers.hpp" diff --git a/addons/compat_gm/compat_gm_refuel/script_component.hpp b/addons/compat_gm/compat_gm_refuel/script_component.hpp new file mode 100644 index 0000000000..b58db9432d --- /dev/null +++ b/addons/compat_gm/compat_gm_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED Refuel +#include "..\script_component.hpp" diff --git a/addons/compat_gm/config.cpp b/addons/compat_gm/config.cpp new file mode 100644 index 0000000000..3f00812dc1 --- /dev/null +++ b/addons/compat_gm/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "gm_core"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"sancron", "nomisum"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/functions/fnc_onCut.sqf b/addons/compat_gm/functions/fnc_onCut.sqf new file mode 100644 index 0000000000..458c5d8de8 --- /dev/null +++ b/addons/compat_gm/functions/fnc_onCut.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: nomisum + * Function for closing doors for GM helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_gm_fnc_onCut + * + * Public: No + */ +params ["_vehicle"]; + +switch (true) do { + case (_vehicle isKindOf "gm_ge_army_bo105p1m_vbh_swooper"): { + _vehicle setVariable [QEGVAR(fastroping,doorsLocked), false, true]; + _vehicle animateDoor ["door_2_1_source", 0]; + _vehicle animateDoor ["door_2_2_source", 0]; + }; + case (_vehicle isKindOf "gm_ch53_base"): { + _vehicle setVariable [QEGVAR(fastroping,doorsLocked), false, true]; + _vehicle animateDoor ["cargoramp_source", 0]; + _vehicle animateSource ["slingloadlights_source", 0]; + }; + case (_vehicle isKindOf "gm_mi2_base"): { + _vehicle setVariable [QEGVAR(fastroping,doorsLocked), false, true]; + _vehicle animate ["door_2_1_anim", 0]; // animateSource/animateDoor didnt work + }; + default {}; +}; + +2 diff --git a/addons/compat_gm/functions/fnc_onCutRopes.sqf b/addons/compat_gm/functions/fnc_onCutRopes.sqf new file mode 100644 index 0000000000..a02b2fe90c --- /dev/null +++ b/addons/compat_gm/functions/fnc_onCutRopes.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: nomisum + * Function for animating ropes (first introduced for GM Bo 105). + * Original onCut runs when _stowing_ FRIES. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait for animation to finish + * + * Example: + * [_vehicle] call ace_compat_gm_fnc_onCutRopes + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle animateSource ["swooperRopes_unhide", 1, true]; + +0 diff --git a/addons/compat_gm/functions/fnc_onDeployRopes.sqf b/addons/compat_gm/functions/fnc_onDeployRopes.sqf new file mode 100644 index 0000000000..ea4c084b4c --- /dev/null +++ b/addons/compat_gm/functions/fnc_onDeployRopes.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: nomisum + * Function for animating ropes when actually dropping (first introduced for GM Bo 105). + * Original onPrepare already animates when preparing FRIES. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait for animation to finish + * + * Example: + * [_vehicle] call ace_compat_gm_fnc_onDeployRopes + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle animateSource ["swooperRopes_unhide", 0, true]; + +0 diff --git a/addons/compat_gm/functions/fnc_onPrepare.sqf b/addons/compat_gm/functions/fnc_onPrepare.sqf new file mode 100644 index 0000000000..df62ad36b1 --- /dev/null +++ b/addons/compat_gm/functions/fnc_onPrepare.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: nomisum + * Function for opening doors for most GM helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_gm_fnc_onPrepare + * + * Public: No + */ +params ["_vehicle"]; + +switch (true) do { + case (_vehicle isKindOf "gm_ge_army_bo105p1m_vbh_swooper"): { + _vehicle setVariable [QEGVAR(fastroping,doorsLocked), true, true]; + _vehicle animateDoor ["door_2_1_source", 1]; + _vehicle animateDoor ["door_2_2_source", 1]; + }; + case (_vehicle isKindOf "gm_ch53_base"): { + _vehicle setVariable [QEGVAR(fastroping,doorsLocked), true, true]; + _vehicle animateDoor ["cargoramp_source", 1]; + _vehicle animateSource ["slingloadlights_source", 1]; + }; + case (_vehicle isKindOf "gm_mi2_base"): { + _vehicle setVariable [QEGVAR(fastroping,doorsLocked), true, true]; + _vehicle animate ["door_2_1_anim", 1]; // animateSource/animateDoor didnt work + _vehicle animateSource ["winch_unhide", 1]; // just in case this wasnt already set + }; + default {}; +}; + +2 diff --git a/addons/compat_gm/script_component.hpp b/addons/compat_gm/script_component.hpp new file mode 100644 index 0000000000..6b044b1192 --- /dev/null +++ b/addons/compat_gm/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_gm +#define COMPONENT_BEAUTIFIED GM Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/optionals/compat_r3f/$PBOPREFIX$ b/addons/compat_r3f/$PBOPREFIX$ similarity index 100% rename from optionals/compat_r3f/$PBOPREFIX$ rename to addons/compat_r3f/$PBOPREFIX$ diff --git a/addons/compat_r3f/CfgAmmo.hpp b/addons/compat_r3f/CfgAmmo.hpp new file mode 100644 index 0000000000..93a93e41fe --- /dev/null +++ b/addons/compat_r3f/CfgAmmo.hpp @@ -0,0 +1,116 @@ +class CfgAmmo { + class Default; + class BulletBase; + class R3F_9x19_Ball: BulletBase { // https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L495 + airFriction = -0.00201185; // ACE3 value, default -0.001413 + ACE_caliber = 9.017; + ACE_bulletLength = 15.494; + ACE_bulletMass = 8.0352; + 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.165}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {341, 371, 401}; // at 21°C, at 15°C 400 m/s according with the R3F_MP5A5 initSpeed + ACE_barrelLengths[] = {101.6, 127, 225}; + }; + class R3F_556x45_Ball: BulletBase { // M855 https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L117 + ACE_caliber = 5.69; + ACE_bulletLength = 23.012; + ACE_bulletMass = 4.0176; + ACE_ammoTempMuzzleVelocityShifts[] = {-19.25, -18.49, -15.81, -13.05, -9.59, -5.15, 0, 6.33, 14.19, 23.43, 35.70}; + ACE_ballisticCoefficients[] = {0.151}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900}; + ACE_barrelLengths[] = {210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6}; + }; + class R3F_762x51_Ball: BulletBase { // M80 https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L280 + ACE_caliber = 7.82; + ACE_bulletLength = 28.96; + ACE_bulletMass = 9.46; + ACE_ammoTempMuzzleVelocityShifts[] = {-18.91, -17.83, -15.21, -12.48, -09.34, -05.16, 0, 6.11, 13.60, 22.81, 33.83}; + ACE_ballisticCoefficients[] = {0.2}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {700, 800, 820, 833, 845}; + ACE_barrelLengths[] = {254.0, 406.4, 508.0, 609.6, 660.4}; + }; + class R3F_762x51_Ball2: R3F_762x51_Ball { // M993 AP https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L351 + ACE_caliber = 7.82; + ACE_bulletLength = 31.5; + ACE_bulletMass = 8.23; + ACE_ammoTempMuzzleVelocityShifts[] = {-18.91, -17.83, -15.21, -12.48, -09.34, -05.16, 0, 6.11, 13.60, 22.81, 33.83}; + ACE_ballisticCoefficients[] = {0.359}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {850}; + ACE_barrelLengths[] = {650}; + }; + class R3F_762x51_Ball_SCAR: BulletBase { // M80 https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L280 + ACE_caliber = 7.82; + ACE_bulletLength = 28.96; + ACE_bulletMass = 9.46; + ACE_ammoTempMuzzleVelocityShifts[] = {-26.55, -25.47, -22.85, -20.12, -16.98, -12.8, -7.64, -1.53, 5.96, 15.17, 26.19}; + ACE_ballisticCoefficients[] = {0.2}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {708, 808, 828, 841, 853}; // at 21°C, at 15°C 820 m/s according with the R3F SCAR-H initSpeed + ACE_barrelLengths[] = {254.0, 406.4, 508.0, 609.6, 660.4}; + }; + class R3F_127x99_Ball: BulletBase { // PGM Hécate 2 M33 https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L635 + ACE_caliber = 12.95; + ACE_bulletLength = 58.67; + ACE_bulletMass = 41.93; + ACE_muzzleVelocityVariationSD = 0.35; + ACE_ammoTempMuzzleVelocityShifts[] = {-18.91, -17.83, -15.21, -12.48, -09.34, -05.16, 0, 6.11, 13.60, 22.81, 33.83}; + ACE_ballisticCoefficients[] = {0.670}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {780}; + ACE_barrelLengths[] = {700}; + EGVAR(vehicle_damage,incendiary) = 0.2; + }; + class R3F_127x99_PEI: R3F_127x99_Ball { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class R3F_127x99_Ball2: BulletBase { // BARRETT M107 M33 https://github.com/acemod/ACE3/blob/master/addons/ballistics/CfgAmmo.hpp#L635 + airFriction = -0.000618; // ACE3 value, default -0.00086 + ACE_caliber = 12.95; + ACE_bulletLength = 58.67; + ACE_bulletMass = 41.93; + ACE_muzzleVelocityVariationSD = 0.35; + ACE_ammoTempMuzzleVelocityShifts[] = {-18.91, -17.83, -15.21, -12.48, -09.34, -05.16, 0, 6.11, 13.60, 22.81, 33.83}; + ACE_ballisticCoefficients[] = {0.670}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {850}; + ACE_barrelLengths[] = {736.6}; + EGVAR(vehicle_damage,incendiary) = 0.2; + }; + class R3F_127x99_PEI2: R3F_127x99_Ball2 { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class R3F_127x99_Ball3: BulletBase { // McMillan TAC-50 AMAX https://web.archive.org/web/20080527201619/http://mcmfamily.com/pdfs/Tac-50%20Technical%20Data.pdf + typicalSpeed = 823; // R3F default value 820 + airFriction = -0.000388; // R3F default value -0.00086 + ACE_caliber = 12.98; + ACE_bulletLength = 64.52; + ACE_bulletMass = 48.6; + ACE_muzzleVelocityVariationSD = 0.2; + ACE_ammoTempMuzzleVelocityShifts[] = {-26.55, -25.47, -22.85, -20.12, -16.98, -12.8, -7.64, -1.53, 5.96, 15.17, 26.19}; + ACE_ballisticCoefficients[] = {1.05}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {831}; // at 21°C, at 15°C 823 m/s (2700 fps) according with the R3F_TAC50 initSpeed + ACE_barrelLengths[] = {736.6}; + EGVAR(vehicle_damage,incendiary) = 0.2; + }; +}; diff --git a/addons/compat_r3f/CfgMagazines.hpp b/addons/compat_r3f/CfgMagazines.hpp new file mode 100644 index 0000000000..ea20d8c06d --- /dev/null +++ b/addons/compat_r3f/CfgMagazines.hpp @@ -0,0 +1,18 @@ +class CfgMagazines { + class CA_magazine; + class R3F_securite_mag: CA_magazine { + scope = 1; // Game Update 1.84: "Tweaked: Magazines can now be hidden in Virtual Arsenal by setting their scope to 1", R3F default value 2 + }; + class R3F_15Rnd_9x19_PAMAS: CA_magazine { + initSpeed = 368; // according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C), R3F default value 350 + }; + class R3F_15Rnd_9x19_HKUSP: CA_magazine { + initSpeed = 363; // according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C), R3F default value 350 + }; + class R3F_17Rnd_9x19_G17: CA_magazine { + initSpeed = 355; // according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C), R3F default value 350 + }; + class R3F_5Rnd_127x99_TAC50: CA_magazine { // AtragMx GunList: R3F TAC50 AMAX + initSpeed = 823; // 2700 fps according with the McMillan Tactical Products specification and the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C), R3F default value 820 + }; +}; diff --git a/addons/compat_r3f/CfgWeapons.hpp b/addons/compat_r3f/CfgWeapons.hpp new file mode 100644 index 0000000000..44a660f704 --- /dev/null +++ b/addons/compat_r3f/CfgWeapons.hpp @@ -0,0 +1,518 @@ +class Mode_SemiAuto; + +class CfgWeapons { + class Pistol_Base_F; + class Rifle_Base_F; + class Rifle_Long_Base_F; + class R3F_Famas_F1: Rifle_Base_F { + ACE_RailHeightAboveBore = 10.1796; + ACE_barrelTwist = 304.8; // 1:12" + ACE_barrelLength = 488.0; + muzzles[] = {"this"}; + }; + class R3F_Famas_F1_M203: R3F_Famas_F1 { + muzzles[] = {"this","Lance_Grenades"}; + }; + class R3F_Famas_surb: R3F_Famas_F1 { // R3F FAMAS Surbaissé, should be FAMAS Valorisé: http://narval34.free.fr/fiche_tech_famas.pdf + ACE_RailHeightAboveBore = 5.08219; + ACE_barrelTwist = 177.8; // 1:7" FAMAS Valorisé + ACE_barrelLength = 450.0; // 3D model with Beretta barrel : FAMAS Valorisé + }; + class R3F_Famas_surb_M203: R3F_Famas_surb { + muzzles[] = {"this","Lance_Grenades"}; + }; + class R3F_Famas_G2: R3F_Famas_F1 { + ACE_RailHeightAboveBore = 10.1808; + ACE_barrelTwist = 228.6; // 1:9" + ACE_barrelLength = 488.0; + }; + class R3F_Famas_G2_M203: R3F_Famas_G2 { + muzzles[] = {"this","Lance_Grenades"}; + }; + class R3F_Famas_felin: R3F_Famas_G2 { + ACE_RailHeightAboveBore = 5.14504; + ACE_barrelTwist = 177.8; // 1:7" + ACE_barrelLength = 450.0; // Beretta barrel + // Fix a ghost mag in the VA with the FAMAS FELIN: default magazines[]={...,"",...} + magazines[] = { + "R3F_25Rnd_556x45_FAMAS", + "R3F_30Rnd_556x45_FAMAS", + "R3F_25Rnd_556x45_TRACER_FAMAS", + "R3F_30Rnd_556x45_TRACER_FAMAS", + "R3F_30Rnd_556x45_HK416", + "R3F_30Rnd_556x45_tracer_hk416", + "30Rnd_556x45_Stanag", + "30Rnd_556x45_Stanag_Tracer_Red", + "30Rnd_556x45_Stanag_Tracer_Green", + "30Rnd_556x45_Stanag_Tracer_Yellow" + }; + }; + class R3F_FRF2: Rifle_Base_F { + ACE_RailHeightAboveBore = 1.79013; + ACE_barrelTwist = 294.6; + ACE_barrelLength = 650.0; + muzzles[] = {"this"}; + }; + class R3F_PGM_Hecate_II: Rifle_Base_F { + ACE_RailHeightAboveBore = 1.84858; + ACE_barrelTwist = 381.0; + ACE_barrelLength = 700.0; + muzzles[] = {"this"}; + }; + class R3F_M107: Rifle_Base_F { + ACE_RailHeightAboveBore = 3.13099; + ACE_barrelTwist = 381.0; + ACE_barrelLength = 736.6; + muzzles[] = {"this"}; + }; + class R3F_TAC50: Rifle_Base_F { + ACE_RailHeightAboveBore = 2.99563; + ACE_barrelTwist = 381.0; + ACE_barrelLength = 736.6; + muzzles[] = {"this"}; + }; + class R3F_Minimi: Rifle_Base_F { // FN HERSTAL Minimi 5.56 Mk3 https://www.fnherstal.com/sites/default/files/2020-06/technical-data-fn-minimi-556-mk3.pdf + ACE_RailHeightAboveBore = 3.81385; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 349; + muzzles[] = {"this"}; + }; + class R3F_Minimi_762: R3F_Minimi { // FN HERSTAL Minimi 7.62 Mk3 https://www.fnherstal.com/sites/default/files/2020-06/technical-data-fn-minimi-762-mk3.pdf + ACE_RailHeightAboveBore = 3.80834; + ACE_barrelTwist = 304.8; + ACE_barrelLength = 422; + }; + class R3F_HK417M: Rifle_Base_F { // https://www.heckler-koch.com/ + ACE_RailHeightAboveBore = 3.23377; + ACE_barrelTwist = 279.4; + ACE_barrelLength = 406.4; + muzzles[] = {"this"}; + }; + class R3F_HK417S_HG: R3F_HK417M { + ACE_barrelLength = 304.8; + }; + class R3F_HK417L: R3F_HK417M { + ACE_barrelLength = 508.0; + }; + class R3F_HK416M: Rifle_Base_F { + ACE_RailHeightAboveBore = 2.84776; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 368.3; + muzzles[] = {"this"}; + }; + class R3F_HK416M_M203: R3F_HK416M { + muzzles[] = {"this","Lance_Grenades"}; + }; + class R3F_HK416M_HG: R3F_HK416M {}; + class R3F_HK416S_HG: R3F_HK416M_HG { + ACE_barrelLength = 279.4; + }; + class R3F_SIG551: Rifle_Base_F { // http://www.sigsauer.swiss + ACE_RailHeightAboveBore = 3.95288; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 363.5; // SG551 SB http://www.sigsauer.swiss/en/accessories-conversion-kits.php + muzzles[] = {"this"}; + }; + class R3F_MP5SD: Rifle_Base_F { // https://www.heckler-koch.com/en/products/military/submachine-guns/mp5/mp5sd/overview.html + ACE_RailHeightAboveBore = 4.21816; + ACE_barrelTwist = 254.0; + ACE_barrelLength = 146; + initSpeed = -0.94; // 400*0.94= 376 m/s according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C), R3F default value 0 + muzzles[] = {"this"}; + }; + class R3F_MP5A5: R3F_MP5SD { // https://www.heckler-koch.com/en/products/military/submachine-guns/mp5/mp5/overview.html + ACE_barrelLength = 225; + initSpeed = -1; // 400 m/s according with the ACE_ammoTempMuzzleVelocityShifts at the normal conditions (15°C), R3F default value 0 + muzzles[] = {"this"}; + }; + class R3F_M4S90: Rifle_Base_F { // https://www.benelli.it + ACE_RailHeightAboveBore = 1.86213; + ACE_twistDirection = 0; + ACE_barrelTwist = 0; + ACE_barrelLength = 470; + }; + class R3F_SCAR_H_PR_20cps_base: Rifle_Base_F { // FN HERSTAL https://www.fnherstal.com/sites/default/files/2020-06/technical-data-fn-scar-h-pr_0.pdf + ACE_barrelTwist = 279.4; + ACE_barrelLength = 508; + muzzles[] = {"this"}; + }; + class R3F_SCAR_H_PR_20cps_recup_base: Rifle_Base_F { + ACE_barrelTwist = 279.4; + ACE_barrelLength = 508; + muzzles[] = {"this"}; + }; + class R3F_SCAR_H_CAM_base: Rifle_Base_F { // FN HERSTAL https://www.fnherstal.com/sites/default/files/2020-06/technical-data-fn-scar-h_0.pdf + ACE_barrelTwist = 304.8; + ACE_barrelLength = 330.2; + muzzles[] = {"this"}; + }; + class R3F_SCAR_H_CAM_LG_GHILLIE: R3F_SCAR_H_CAM_base { + muzzles[] = {"this", "EGLM"}; + }; + class R3F_SCAR_H_CAM_LG: R3F_SCAR_H_CAM_base { + muzzles[] = {"this", "EGLM"}; + }; + class R3F_SCAR_L_CAM_base: Rifle_Base_F { // FN HERSTAL https://www.fnherstal.com/sites/default/files/2020-06/technical-data-fn-scar-l_1.pdf + ACE_barrelTwist = 177.8; + ACE_barrelLength = 368.3; + muzzles[] = {"this"}; + }; + class R3F_SCAR_L_CAM_ghillie_LG: R3F_SCAR_L_CAM_base { + muzzles[] = {"this", "EGLM"}; + }; + class R3F_SCAR_L_CQC_CAM: R3F_SCAR_L_CAM_base { + ACE_barrelLength = 254; + }; + class R3F_SCAR_L_CQC_LG_CAM: R3F_SCAR_L_CAM_base { + ACE_barrelLength = 254; + muzzles[] = {"this", "EGLM"}; + }; + class R3F_FN_MAG58: Rifle_Long_Base_F { // FN HERSTAL https://www.fnherstal.com/sites/default/files/2020-10/technical-data-fn-mag-1.pdf + ACE_barrelTwist = 304.8; + ACE_barrelLength = 630; + muzzles[] = {"this"}; + }; + class R3F_PAMAS: Pistol_Base_F { + ACE_barrelTwist = 250.0; + ACE_barrelLength = 125.0; + muzzles[] = {"this"}; + initSpeed = -1.0; // default 410 + class Single: Mode_SemiAuto { + dispersion=0.0025; // 8.59 MOA (a square of 6.25/6.25cm at 25 meters), R3F default value 0.025 (85.94 MOA) + }; + }; + class R3F_HKUSP: Pistol_Base_F { + ACE_barrelTwist = 250.0; + ACE_barrelLength = 121.0; + muzzles[] = {"this"}; + initSpeed = -1.0; // default 410 + class Single: Mode_SemiAuto { + dispersion=0.002; // 6.88 MOA (a square of 5/5cm at 25 meters), R3F default value 0.02 (68.75 MOA) + }; + }; + class R3F_G17: Pistol_Base_F { + ACE_barrelTwist = 250.0; + ACE_barrelLength = 114.0; + muzzles[] = {"this"}; + initSpeed = -1.0; // default 410 + }; + class ItemCore; + class InventoryOpticsItem_Base_F; + class R3F_AIMPOINT: ItemCore { + ACE_ScopeHeightAboveRail = 3.1916; + }; + class R3F_EOTECH: ItemCore { + ACE_ScopeHeightAboveRail = 4.25923; + }; + class R3F_J4: ItemCore { // http://www.scrome.com/assets/templates/flexibility/pdf/Scrome_Riflescope_LTE_J4_Datasheet_GB.pdf + ACE_ScopeHeightAboveRail = 3.20641; + ACE_ScopeAdjust_Vertical[] = {-8, 8}; + ACE_ScopeAdjust_Horizontal[] = {-8, 8}; + ACE_ScopeAdjust_VerticalIncrement = 0.2; + ACE_ScopeAdjust_HorizontalIncrement = 0.2; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class J4 { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class R3F_FELIN: ItemCore { + ACE_ScopeHeightAboveRail = 8.13689; + }; + class R3F_FELIN_FRF2: ItemCore { + ACE_ScopeHeightAboveRail = 4.28091; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class Felin {}; + class Oeilleton: Felin { + opticsID = 2; + opticsDisplayName = ""; + useModelOptics = 0; + opticsPPEffects[] = {}; + opticsFlare = 0; + opticsDisablePeripherialVision = 0; + opticsZoomMin = 0.25; + opticsZoomMax = 1.25; + opticsZoomInit = 0.75; + memoryPointCamera = "eye_Oeilleton"; + visionMode[] = {}; + discretefov[] = {}; + discreteDistance[] = {200}; + discreteDistanceInitIndex = 0; + distanceZoomMin = 200; + distanceZoomMax = 200; + discreteInitIndex = 0; + cameraDir = ""; + }; + }; + }; + }; + class R3F_J8: ItemCore { // http://www.scrome.com/assets/templates/flexibility/pdf/Scrome_Marksman_Scope_LTE_Datasheet_GB.pdf + ACE_ScopeHeightAboveRail = -2.237; // Off-center BDC reticle designed to work with the vanilla ballistic and R3F values only. + ACE_ScopeAdjust_Vertical[] = {-10, 10}; + ACE_ScopeAdjust_Horizontal[] = {-10, 10}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + }; + class R3F_J8_MILDOT: R3F_J8 { + ACE_ScopeHeightAboveRail = 4.474; + ACE_ScopeAdjust_Vertical[] = {0, 20}; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class J8_MILDOT { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class R3F_J10: ItemCore { // http://www.scrome.com/assets/templates/flexibility/pdf/Scrome_Marksman_Scope_LTE_Datasheet_GB.pdf + ACE_ScopeHeightAboveRail = 4.474; // BDC reticle designed to work with the vanilla ballistic and R3F values only. + ACE_ScopeAdjust_Vertical[] = {-10, 10}; + ACE_ScopeAdjust_Horizontal[] = {-10, 10}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + }; + class R3F_J10_MILDOT: R3F_J10 { + ACE_ScopeAdjust_Vertical[] = {0, 20}; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class J10_MILDOT { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class R3F_ZEISS: ItemCore { // https://www.hensoldt.net/fileadmin/hensoldt/Datenbl%C3%A4tter/En/0714_SL_0817_9-6-24x72_6-24x56_EN_LoRes.pdf#page=2 + ACE_ScopeHeightAboveRail = 4.96547; + ACE_ScopeAdjust_Vertical[] = {0, 16}; + ACE_ScopeAdjust_Horizontal[] = {-3.5, 3.5}; // {-5,5} for the Hensoldt but {-3.5,3.5} for the Zeiss according with the official documentation. + ACE_ScopeAdjust_VerticalIncrement = 0.05; + ACE_ScopeAdjust_HorizontalIncrement = 0.05; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class ZEISS_MILDOT { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class R3F_NF: ItemCore { // http://nightforceoptics.com/nxs/3-5-15x56 + ACE_ScopeHeightAboveRail = 4.30469; + ACE_ScopeAdjust_Vertical[] = {0, 30}; + ACE_ScopeAdjust_Horizontal[] = {-11, 11}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class NF_MILDOT { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class R3F_NF42: ItemCore { // http://nightforceoptics.com/nxs/12-42x56 + ACE_ScopeHeightAboveRail = 4.30469; + ACE_ScopeAdjust_Vertical[] = {0, 12}; + ACE_ScopeAdjust_Horizontal[] = {-5, 5}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class NF42_MILDOT { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class R3F_OB50: ItemCore { + ACE_ScopeHeightAboveRail = 4.13217; + }; + class R3F_SB_PM: ItemCore { // Off-center BDC reticle designed to work with the vanilla ballistic and R3F values only. + ACE_ScopeAdjust_Vertical[] = {0, 12}; // https://www.schmidtundbender.de/en/products/police-military-forces/1-8x24-pm-ii-shortdot-dual-cc.html + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class SB_PM { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + distanceZoomMin = 100; + distanceZoomMax = 1200; + }; + }; + }; + }; + class R3F_SB_PM_BLACK: R3F_SB_PM { + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class SB_PM { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + distanceZoomMin = 100; + distanceZoomMax = 1200; + }; + }; + }; + }; + class InventoryMuzzleItem_Base_F; + class R3F_SILENCIEUX_HK416: ItemCore { + class ItemInfo: InventoryMuzzleItem_Base_F { + class MagazineCoef { + initSpeed = 1.0; + }; + + class AmmoCoef { + hit = 1.0; // default "0.8" + visibleFire = 0.5; + audibleFire = 0.1; // default "0.3" + visibleFireTime = 0.5; + audibleFireTime = 0.5; + cost = 1.0; + typicalSpeed = 1.0; + airFriction = 1.0; + }; + + class MuzzleCoef { + dispersionCoef = "0.95f"; // default "0.8f" + artilleryDispersionCoef = "1.0f"; + fireLightCoef = "0.5f"; // default "0.1f" + recoilCoef = "0.95f"; // default "1.0f" + recoilProneCoef = "0.95f"; // default "1.0f" + minRangeCoef = "1.0f"; + minRangeProbabCoef = "1.0f"; + midRangeCoef = "1.0f"; + midRangeProbabCoef = "1.0f"; + maxRangeCoef = "1.0f"; + maxRangeProbabCoef = "1.0f"; + }; + }; + }; + class R3F_SILENCIEUX_HK417: ItemCore { + class ItemInfo: InventoryMuzzleItem_Base_F { + class MagazineCoef { + initSpeed = 1.0; + }; + + class AmmoCoef { + hit = 1.0; + visibleFire = 0.5; + audibleFire = 0.1; + visibleFireTime = 0.5; + audibleFireTime = 0.5; + cost = 1.0; + typicalSpeed = 1.0; + airFriction = 1.0; + }; + + class MuzzleCoef { + dispersionCoef = "0.95f"; + artilleryDispersionCoef = "1.0f"; + fireLightCoef = "0.5f"; + recoilCoef = "0.95f"; + recoilProneCoef = "0.95f"; + minRangeCoef = "1.0f"; + minRangeProbabCoef = "1.0f"; + midRangeCoef = "1.0f"; + midRangeProbabCoef = "1.0f"; + maxRangeCoef = "1.0f"; + maxRangeProbabCoef = "1.0f"; + }; + }; + }; + class R3F_SILENCIEUX_FRF2: ItemCore { + class ItemInfo: InventoryMuzzleItem_Base_F { + class MagazineCoef { + initSpeed = 1.0; + }; + + class AmmoCoef { + hit = 1.0; + visibleFire = 0.5; + audibleFire = 0.1; + visibleFireTime = 0.5; + audibleFireTime = 0.5; + cost = 1.0; + typicalSpeed = 1.0; + airFriction = 1.0; + }; + + class MuzzleCoef { + dispersionCoef = "0.95f"; + artilleryDispersionCoef = "1.0f"; + fireLightCoef = "0.5f"; + recoilCoef = "0.95f"; + recoilProneCoef = "0.95f"; + minRangeCoef = "1.0f"; + minRangeProbabCoef = "1.0f"; + midRangeCoef = "1.0f"; + midRangeProbabCoef = "1.0f"; + maxRangeCoef = "1.0f"; + maxRangeProbabCoef = "1.0f"; + }; + }; + }; + class R3F_SILENCIEUX_SCAR_H_PR: ItemCore { + class ItemInfo: InventoryMuzzleItem_Base_F { + class MagazineCoef { + initSpeed = 1.0; + }; + + class AmmoCoef { + hit = 1.0; + visibleFire = 0.5; + audibleFire = 0.1; + visibleFireTime = 0.5; + audibleFireTime = 0.5; + cost = 1.0; + typicalSpeed = 1.0; + airFriction = 1.0; + }; + + class MuzzleCoef { + dispersionCoef = "0.95f"; + artilleryDispersionCoef = "1.0f"; + fireLightCoef = "0.5f"; + recoilCoef = "0.95f"; + recoilProneCoef = "0.95f"; + minRangeCoef = "1.0f"; + minRangeProbabCoef = "1.0f"; + midRangeCoef = "1.0f"; + midRangeProbabCoef = "1.0f"; + maxRangeCoef = "1.0f"; + maxRangeProbabCoef = "1.0f"; + }; + }; + }; +}; + +class ACE_ATragMX_Presets { + class R3F_PGM_Hecate_II { + // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation + preset[] = {"R3F PGM M33", 780, 100, 0.0845596, -0.00086, 6.35, 0, 2, 10, 120, 0, 0, 41.92, 12.18, 38.10, 0.670, 1, "ASM", {{-15, 761},{0, 768},{10, 775},{15, 780},{25, 794},{30, 803},{35, 814}}, {{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}}}; + }; + class R3F_M107 { + // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation + preset[] = {"R3F M107 M33", 850, 100, 0.0841653, -0.00061813, 7.62, 0, 2, 10, 120, 0, 0, 41.92, 12.19, 38.10, 0.670, 1, "ASM", {{-15, 831},{0, 838},{10, 845},{15, 850},{25, 864},{30, 873},{35, 884}}, {{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}}}; + }; + class R3F_TAC50 { + // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation + preset[] = {"R3F TAC50 AMAX", 823, 100, 0.0848384, -0.00038793, 7.37, 0, 2, 10, 120, 0, 0, 48.6, 12.44, 38.10, 1.050, 1, "ICAO", {{-15, 804},{0, 811},{10, 818},{15, 823},{25, 837},{30, 846},{35, 857}}, {{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}}}; + }; + class R3F_FRF2 { + // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation + preset[] = {"R3F FRF2 M993", 850, 100, 0.0783702, -0.00095, 6.35, 0, 2, 10, 120, 0, 0, 8.23, 7.35, 29.46, 0.359, 1, "ICAO", {{-15, 831},{0, 838},{10, 845},{15, 850},{25, 864},{30, 873},{35, 884}}, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}}; + }; + class R3F_HK417L { + // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation + preset[] = {"R3F HK417L M80", 820, 100, 0.0884758, -0.00095, 7.62, 0, 2, 10, 120, 0, 0, 9.46, 8.02, 27.94, 0.394, 1, "ICAO", {{-15, 801},{0, 808},{10, 815},{15, 820},{25, 834},{30, 843},{35, 854}}, {{0, 0.394}, {700, 0.394}, {800, 0.391}, {900, 0.386}, {1000, 0.383}, {1100, 0.381}, {1300, 0.379}}}; + }; +}; diff --git a/addons/compat_r3f/config.cpp b/addons/compat_r3f/config.cpp new file mode 100644 index 0000000000..9f962372d0 --- /dev/null +++ b/addons/compat_r3f/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"r3f_armes_c", "r3f_acc", "R3F_G17_addons", "R3F_G_SCAR", "R3F_SCAR_H", "R3F_SCAR_L", "R3F_FN_MAG"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" diff --git a/optionals/compat_r3f/script_component.hpp b/addons/compat_r3f/script_component.hpp similarity index 100% rename from optionals/compat_r3f/script_component.hpp rename to addons/compat_r3f/script_component.hpp diff --git a/addons/compat_rf/$PBOPREFIX$ b/addons/compat_rf/$PBOPREFIX$ new file mode 100644 index 0000000000..78e6f45daf --- /dev/null +++ b/addons/compat_rf/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_rf diff --git a/addons/compat_rf/CfgWeapons.hpp b/addons/compat_rf/CfgWeapons.hpp new file mode 100644 index 0000000000..d1daa7c710 --- /dev/null +++ b/addons/compat_rf/CfgWeapons.hpp @@ -0,0 +1,42 @@ +class CfgWeapons { + // Ballistics + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + ace_barrelTwist = 254; + ace_barrelLength = 102; + ace_twistDirection = 1; + }; + + class hgun_DEagle_RF: Pistol_Base_F { + ace_barrelTwist = 482; + ace_barrelLength = 127; + ace_twistDirection = 1; + }; + + class Rifle_Long_Base_F; + class srifle_h6_base_rf: Rifle_Long_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 460; + ace_twistDirection = 1; + }; + + class Rifle_Base_F; + class arifle_ash12_base_RF: Rifle_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 400; + ace_twistDirection = 1; + }; + + class arifle_ash12_LR_base_RF: arifle_ash12_base_RF { + ace_barrelLength = 450; + }; + + // Hearing + class H_HelmetIA; + class H_HelmetIA_sb_arid_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; + class H_HelmetIA_sb_digital_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 0000000000..553c199ee6 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,12 @@ +// Generated using ace_nouniformrestrictions_fnc_exportConfig +class CfgVehicles { + class B_Helipilot_F; + class C_Helipilot_Green_UniformHolder_RF; + + class C_Helipilot_Rescue_UniformHolder_RF: B_Helipilot_F { + modelSides[] = {6}; + }; + class B_Helipilot_Green_UniformHolder_RF: C_Helipilot_Green_UniformHolder_RF { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp new file mode 100644 index 0000000000..2de1cf9673 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp new file mode 100644 index 0000000000..0b98185fa0 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp new file mode 100644 index 0000000000..9915ad1d44 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp @@ -0,0 +1,41 @@ +class optic_MRD; +class optic_MRD_khk_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_khk_Name); +}; +class optic_MRD_tan_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_tan_Name); +}; + +class optic_ACO_grn; +class optic_ACO_grn_desert_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_desert_Name); +}; +class optic_ACO_grn_wood_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_wood_Name); +}; + +class optic_Aco; +class optic_ACO_desert_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_desert_Name); +}; +class optic_ACO_wood_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_wood_Name); +}; + +class ItemCore; +class optic_rds_RF: ItemCore { + displayName = SUBCSTRING(optic_rds_Name); +}; + +class optic_VRCO_RF: ItemCore { + displayName = SUBCSTRING(optic_vrco_Name); +}; +class optic_VRCO_tan_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_tan_Name); +}; +class optic_VRCO_khk_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_khk_Name); +}; +class optic_VRCO_pistol_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_pistol_Name); +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp new file mode 100644 index 0000000000..52231bcf07 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp @@ -0,0 +1,24 @@ +class CfgMagazines { + class CA_Magazine; + class 1Rnd_RC40_shell_RF: CA_Magazine { + displayName = SUBCSTRING(rc40_Name); + }; + class 1Rnd_RC40_HE_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class 1Rnd_RC40_SmokeWhite_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class 1Rnd_RC40_SmokeBlue_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class 1Rnd_RC40_SmokeRed_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class 1Rnd_RC40_SmokeGreen_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class 1Rnd_RC40_SmokeOrange_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp new file mode 100644 index 0000000000..2983525ec8 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp @@ -0,0 +1,152 @@ +class CfgVehicles { + class Heli_light_03_dynamicLoadout_base_F; + class B_Heli_light_03_dynamicLoadout_RF: Heli_light_03_dynamicLoadout_base_F { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class Heli_light_03_unarmed_base_F; + class B_Heli_light_03_unarmed_RF: Heli_light_03_unarmed_base_F { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + class I_Heli_light_03_dynamicLoadout_RF; + class I_E_Heli_light_03_dynamicLoadout_RF: I_Heli_light_03_dynamicLoadout_RF { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class I_Heli_light_03_unarmed_RF; + class I_E_Heli_light_03_unarmed_RF: I_Heli_light_03_unarmed_RF { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + // H240 Transport, Gendarmerie/ION Transport + class Helicopter_Base_H; + class Heli_EC_01_base_RF: Helicopter_Base_H { + displayName = SUBCSTRING(ec_01_base_Name); + }; + // H240C Transport, CIV Transport + class Heli_EC_01_civ_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_01_civ_base_Name); + }; + // H235 Transport, CIV Transport Float-less (not used) + class Heli_EC_01A_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_01a_base_Name); + }; + // H235C Transport, CIV Transport Float-less + class Heli_EC_01A_civ_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_civ_base_Name); + }; + // RAI-350M Cougar (Unarmed), IND/UNA Transport Float-less + class Heli_EC_01A_military_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_military_base_Name); + }; + // RAI-360M Cougar, IND/OPF SOCAT Float-less + class Heli_EC_02_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_02_base_Name); + }; + // MH-360M Cougar, NATO SOCAT (not used) Float-less + class B_Heli_EC_02_RF: Heli_EC_02_base_RF { + displayName = SUBCSTRING(ec_02_nato_Name); + }; + // MH-245 Cougar, NATO Combat Type + class Heli_EC_03_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_03_base_Name); + }; + // H245 SAR, CIV SAR Type + class Heli_EC_04_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_04_base_Name); + }; + // MH-245 Cougar (Unarmed), NATO Transport Type (Maybe SAR?) + class Heli_EC_04_military_base_RF: Heli_EC_04_base_RF { + displayName = SUBCSTRING(ec_04_military_base_Name); + }; + + // HEMTT + class B_Truck_01_fuel_F; + class C_Truck_01_water_rf: B_Truck_01_fuel_F { + displayName = SUBCSTRING(truck_01_water_Name); + }; + + // Typhoon + class O_Truck_03_fuel_F; + class C_Truck_03_water_rf: O_Truck_03_fuel_F { + displayName = SUBCSTRING(truck_03_water_Name); + }; + + // RAM 1500 (Pickup) + class Offroad_01_unarmed_base_F; + class Pickup_01_base_rf: Offroad_01_unarmed_base_F { + displayName = SUBCSTRING(pickup_01_Name); + }; + class Pickup_fuel_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_fuel_Name); + }; + class Pickup_service_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_service_Name); + }; + class Pickup_repair_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_comms_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_comms_Name); + }; + class Pickup_repair_ig_base_rf: Pickup_repair_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_01_hmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_hmg_Name); + }; + class Pickup_01_mmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mmg_Name); + }; + class Pickup_01_mrl_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mrl_Name); + }; + class Pickup_01_aat_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_aa_Name); + }; + class Pickup_covered_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_covered_Name); + }; + + class C_IDAP_Pickup_rf; + class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf { + displayName = SUBCSTRING(pickup_01_water_Name); + }; + + class StaticMortar; + class CommandoMortar_base_RF: StaticMortar { + displayName = SUBCSTRING(commando_Name); + }; + + class StaticMGWeapon; + class TwinMortar_base_RF: StaticMGWeapon { + displayName = SUBCSTRING(twinmortar_Name); + }; + + class Helicopter_Base_F; + class UAV_RC40_Base_RF: Helicopter_Base_F { + displayName = SUBCSTRING(rc40_base_Name); + }; + class UAV_RC40_Base_Sensor_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_Name); + }; + class UAV_RC40_Base_HE_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class UAV_RC40_Base_SmokeWhite_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class UAV_RC40_Base_SmokeBlue_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class UAV_RC40_Base_SmokeRed_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class UAV_RC40_Base_SmokeGreen_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class UAV_RC40_Base_SmokeOrange_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp new file mode 100644 index 0000000000..c2d9003f11 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp @@ -0,0 +1,111 @@ +class CfgWeapons { + #include "Attachments.hpp" + + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + displayName = SUBCSTRING(glock19_Name); + }; + class hgun_Glock19_khk_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_khk_Name); + }; + class hgun_Glock19_Tan_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_tan_Name); + }; + class hgun_Glock19_auto_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_auto_Name); + }; + class hgun_Glock19_auto_khk_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_khk_Name); + }; + class hgun_Glock19_auto_Tan_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_tan_Name); + }; + + class hgun_DEagle_RF: Pistol_Base_F { + displayName = SUBCSTRING(deagle_Name); + }; + class hgun_DEagle_classic_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_classic_Name); + }; + class hgun_DEagle_bronze_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_bronze_Name); + }; + class hgun_DEagle_copper_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_copper_Name); + }; + class hgun_DEagle_gold_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_gold_Name); + }; + + class srifle_h6_base_rf; + class srifle_h6_tan_rf: srifle_h6_base_rf { + displayName = SUBCSTRING(h6_tan_Name); + }; + class srifle_h6_oli_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_oli_Name); + }; + class srifle_h6_blk_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_blk_Name); + }; + class srifle_h6_digi_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_digi_Name); + }; + class srifle_h6_gold_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_gold_Name); + }; + + class srifle_DMR_01_F; + class srifle_DMR_01_black_RF: srifle_DMR_01_F { + displayName = SUBCSTRING(dmr_01_black_Name); + }; + class srifle_DMR_01_tan_RF: srifle_DMR_01_black_RF { + displayName = SUBCSTRING(dmr_01_tan_Name); + }; + + class SMG_01_F; + class SMG_01_black_RF: SMG_01_F { + displayName = SUBCSTRING(smg_01_black_Name); + }; + + class arifle_ash12_base_RF; + class arifle_ash12_blk_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_blk_Name); + }; + class arifle_ash12_desert_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_desert_Name); + }; + class arifle_ash12_urban_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_urban_Name); + }; + class arifle_ash12_wood_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_wood_Name); + }; + + class arifle_ash12_GL_base_RF; + class arifle_ash12_GL_blk_RF: arifle_ash12_GL_base_RF { + displayName = SUBCSTRING(ash12_gl_blk_Name); + }; + class arifle_ash12_GL_desert_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_desert_Name); + }; + class arifle_ash12_GL_urban_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_urban_Name); + }; + class arifle_ash12_GL_wood_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_wood_Name); + }; + + class arifle_ash12_LR_base_RF; + class arifle_ash12_LR_blk_RF: arifle_ash12_LR_base_RF { + displayName = SUBCSTRING(ash12_lr_blk_Name); + }; + class arifle_ash12_LR_desert_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_desert_Name); + }; + class arifle_ash12_LR_urban_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_urban_Name); + }; + class arifle_ash12_LR_wood_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_wood_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/config.cpp b/addons/compat_rf/compat_rf_realisticnames/config.cpp new file mode 100644 index 0000000000..47003c4a42 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_realisticnames" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Marc"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/script_component.hpp b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp new file mode 100644 index 0000000000..b8d0682fa4 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT realisticnames +#define SUBCOMPONENT_BEAUTIFIED Realistic Names +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/stringtable.xml b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml new file mode 100644 index 0000000000..c65a8fd4ad --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml @@ -0,0 +1,548 @@ + + + + + EOTech MRDS (Khaki) + EOTech MRDS (カーキ) + 이오텍 MRDS (카키) + EOTech MRDS (Khaki) + EOTech MRDS (Cachi) + + + EOTech MRDS (Tan) + EOTech MRDS (タン) + 이오텍 MRDS (황갈) + EOTech MRDS (Hellbraun) + EOTech MRDS (Marroncino) + + + C-More Railway (Green, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + 씨모어 레일웨이 (녹색, 사막) + C-More Railway (Grün, Wüste) + C-More Railway (Verde, Deserto) + + + C-More Railway (Green, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + 씨모어 레일웨이 (녹색, 수풀 위장) + C-More Railway (Grün, Grünes Tarnmuster) + C-More Railway (Verde, Boschivo) + + + C-More Railway (Red, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + 씨모어 레일웨이 (빨강, 사막) + C-More Railway (Rot, Wüste) + C-More Railway (Rosso, Desert) + + + C-More Railway (Red, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + 씨모어 레일웨이 (빨강, 수풀) + C-More Railway (Rot, Grünes Tarnmuster) + C-More Railway (Rosso, Boschivo) + + + Aimpoint Micro R-1 + Aimpoint マイクロ R-1 + 에임포인트 마이크로 R-1 + Aimpoint Micro R-1 + Aimpoint Micro R-1 + + + Vortex Spitfire Prism + Vortex スピットファイア プリズム + 버텍스 스핏파이어 프리즘 + Vortex Spitfire Prism + Vortex Spitfire Prism + + + Vortex Spitfire Prism (Tan) + Vortex スピットファイア プリズム (タン) + 버텍스 스핏파이어 프리즘 (황갈) + Vortex Spitfire Prism (Hellbraun) + Vortex Spitfire Prism (Marroncino) + + + Vortex Spitfire Prism (Khaki) + Vortex スピットファイア プリズム (カーキ) + 버텍스 스핏파이어 프리즘 (카키) + Vortex Spitfire Prism (Khaki) + Vortex Spitfire Prism (Cachi) + + + Vortex Spitfire Prism (Pistol) + Vortex スピットファイア プリズム (ピストル用) + 버텍스 스핏파이어 프리즘 (권총용) + Vortex Spitfire Prism (Pistole) + Vortex Spitfire Prism (Pistola) + + + Glock 19X + グロック 19X + 글록 19X + Glock 19X + Glock 19X + + + Glock 19X (Khaki) + グロック 19X (カーキ) + 글록 19X (카키) + Glock 19X (Khaki) + Glock 19X (Cachi) + + + Glock 19X (Tan) + グロック 19X (タン) + 글록 19X (황갈) + Glock 19X (Hellbraun) + Glock 19X (Marroncino) + + + Glock 19X Auto + グロック 19X オート + 글록 19X 기관권총 + Glock 19X Auto + Glock 19X Auto + + + Glock 19X Auto (Khaki) + グロック 19X オート (カーキ) + 글록 19X 기관권총 (카키) + Glock 19X Auto (Khaki) + Glock 19X Auto (Cachi) + + + Glock 19X Auto (Tan) + グロック 19X オート (タン) + 글록 19X 기관권총 (황갈) + Glock 19X Auto (Hellbraun) + Glock 19X Auto (Marroncino) + + + Desert Eagle Mark XIX L5 + デザートイーグル Mark XIX L5 + 데저트 이글 마크 XIX L5 + Desert Eagle Mark XIX L5 + Desert Eagle Mark XIX L5 + + + Desert Eagle Mark XIX L5 (Classic) + デザートイーグル Mark XIX L5 (クラシック) + 데저트 이글 마크 XIX L5 (클래식) + Desert Eagle Mark XIX L5 (Klassisch) + Desert Eagle Mark XIX L5 (Classico) + + + Desert Eagle Mark XIX L5 (Bronze) + デザートイーグル Mark XIX L5 (ブロンズ) + 데저트 이글 마크 XIX L5 (브론즈) + Desert Eagle Mark XIX L5 (Bronze) + Desert Eagle Mark XIX L5 (Bronzo) + + + Desert Eagle Mark XIX L5 (Copper) + デザートイーグル Mark XIX L5 (カッパー) + 데저트 이글 마크 XIX L5 (구리) + Desert Eagle Mark XIX L5 (Kupfer) + Desert Eagle Mark XIX L5 (Rame) + + + Desert Eagle Mark XIX L5 (Gold) + デザートイーグル Mark XIX L5 (ゴールド) + 데저트 이글 마크 XIX L5 (금색) + Desert Eagle Mark XIX L5 (Gold) + Desert Eagle Mark XIX L5 (Oro) + + + HERA H6 (Tan) + HERA H6 (タン) + 헤라 H6 (황갈) + HERA H6 (Hellbraun) + HERA H6 (Marroncino) + + + HERA H6 (Olive) + HERA H6 (オリーブ) + 헤라 H6 (올리브) + HERA H6 (Olivgrün) + HERA H6 (Oliva) + + + HERA H6 (Black) + HERA H6 (ブラック) + 헤라 H6 (검정) + HERA H6 (Schwarz) + HERA H6 (Nero) + + + HERA H6 (Digital) + HERA H6 (AAF迷彩) + 헤라 H6 (AAF 디지털) + HERA H6 (Digital) + HERA H6 (Digitale) + + + HERA H6 (Gold) + HERA H6 (ゴールド) + 헤라 H6 (금색) + HERA H6 (Gold) + HERA H6 (Oro) + + + VS-121 (Black) + VS-121 (ブラック) + VS-121 (검정) + VS-121 (Schwarz) + VS-121 (Nero) + + + VS-121 (Tan) + VS-121 (タン) + VS-121 (황갈) + VS-121 (Hellbraun) + VS-121 (Marroncino) + + + Vector SMG (Black) + ベクター SMG (ブラック) + 벡터 SMG (검정) + Vector SMG (Schwarz) + Vector SMG (Nero) + + + ASh-12 (Black) + ASh-12 (ブラック) + ASh-12 (검정) + ASh-12 (Schwarz) + ASh-12 (Nero) + + + ASh-12 (Desert) + ASh-12 (砂漠迷彩) + ASh-12 (사막) + ASh-12 (Wüste) + ASh-12 (Deserto) + + + ASh-12 (Urban) + ASh-12 (市街地迷彩) + ASh-12 (도심) + ASh-12 (Urban) + ASh-12 (Urbano) + + + ASh-12 (Woodland) + ASh-12 (森林迷彩) + ASh-12 (수풀) + ASh-12 (Grünes Tarnmuster) + ASh-12 (Boschivo) + + + ASh-12 GL (Black) + ASh-12 GL (ブラック) + ASh-12 GL (검정) + ASh-12 GL (Schwarz) + ASh-12 GL (Nero) + + + ASh-12 GL (Desert) + ASh-12 GL (砂漠迷彩) + ASh-12 GL (사막) + ASh-12 GL (Wüste) + ASh-12 GL (Deserto) + + + ASh-12 GL (Urban) + ASh-12 GL (市街地迷彩) + ASh-12 GL (도심) + ASh-12 GL (Urban) + ASh-12 GL (Urbano) + + + ASh-12 GL (Woodland) + ASh-12 GL (森林迷彩) + ASh-12 GL (수풀) + ASh-12 GL (Grünes Tarnmuster) + ASh-12 GL (Boschivo) + + + ASh-12 LR (Black) + ASh-12 LR (ブラック) + ASh-12 LR (검정) + ASh-12 LR (Schwarz) + ASh-12 LR (Nero) + + + ASh-12 LR (Desert) + ASh-12 LR (砂漠迷彩) + ASh-12 LR (사막) + ASh-12 LR (Wüste) + ASh-12 LR (Deserto) + + + ASh-12 LR (Urban) + ASh-12 LR (市街地迷彩) + ASh-12 LR (도심) + ASh-12 LR (Urban) + ASh-12 LR (Urbano) + + + ASh-12 LR (Woodland) + ASh-12 LR (森林迷彩) + ASh-12 LR (수풀) + ASh-12 LR (Grünes Tarnmuster) + ASh-12 LR (Boschivo) + + + AW159 Wildcat ASW + AW159 ワイルドキャット ASW + AW159 와일드캣 ASW + AW159 Wildcat ASW + AW159 Wildcat ASW + + + AW159 Wildcat ASW (Unarmed) + AW159 ワイルドキャット ASW (非武装) + AW159 와일드캣 ASW (비무장) + AW159 Wildcat ASW (Unbewaffnet) + AW159 Wildcat ASW (Disarmato) + + + H225 Super Puma (Transport) + H225 シュペル ピューマ (輸送型) + H225 슈퍼 퓨마 (비무장) + H225 Super Puma (Transport) + H225 Super Puma (Trasporto) + + + H225 Super Puma (Civilian) + H225 シュペル ピューマ (民生型) + H225 슈퍼 퓨마 (비무장) + H225 Super Puma (Zivil) + H225 Super Puma (Civile) + + + H215 Super Puma (Transport) + H215 シュペル ピューマ (輸送型) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Transport) + H215 Super Puma (Trasporto) + + + H215 Super Puma (Civilian) + H215 シュペル ピューマ (民生型) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Zivil) + H215 Super Puma (Civile) + + + H215 Super Puma (Unarmed) + H215 シュペル ピューマ (非武装) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Unbewaffnet) + H215 Super Puma (Disarmato) + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + H225M 슈퍼 쿠거 SOCAT + H225M Super Cougar SOCAT + H225M Super Cougar SOCAT + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + H225M 슈퍼 쿠거 SOCAT + H225M Super Cougar SOCAT + H225M Super Cougar SOCAT + + + H225M Super Cougar + H225M シュペル クーガー + H225M 슈퍼 쿠거 + H225M Super Cougar + H225M Super Cougar + + + H225 Super Puma SAR + H225 シュペル ピューマ 捜索救難型 + H225 슈퍼 퓨마 SAR + H225 Super Puma SAR + H225 Super Puma SAR + + + H225M Super Cougar (Unarmed) + H225M シュペル クーガー (非武装) + H225M Super Cougar (Unbewaffnet) + H225M Super Cougar (Disarmato) + + + HEMTT Fire Truck + HEMTT anti-incendie + HEMTT (wersja pożarnicza) + HEMTT-Löschfahrzeug + HEMTT (camión de bomberos) + Пожарная машина HEMTT + HEMTT 消防卡车 + HEMTT contra incêndio + HEMTT 消防車 + HEMTT Autobotte + + + Typhoon Water + タイフーン 給水 + 타이푼 급수 + Typhoon Water + Typhoon Acqua + + + Ram 1500 + ラム 1500 + 램 1500 + Ram 1500 + Ram 1500 + + + Ram 1500 (Fuel) + ラム 1500 (燃料) + 램 1500 (연료) + Ram 1500 (Treibstoff) + Ram 1500 (Carburante) + + + Ram 1500 (Services) + ラム 1500 (サービス) + 램 1500 (서비스) + Ram 1500 (Pannenhilfe) + Ram 1500 (Servizi) + + + Ram 1500 (Repair) + ラム 1500 (修理) + 램 1500 (정비) + Ram 1500 (Instandsetzung) + Ram 1500 (Riparazioni) + + + Ram 1500 (Comms) + ラム 1500 (通信) + 램 1500 (통신) + Ram 1500 (Kommunikation) + Ram 1500 (Comunicazioni) + + + Ram 1500 (HMG) + ラム 1500 (HMG) + 램 1500 (중기관총) + Ram 1500 (HMG) + Ram 1500 (HMG) + + + Ram 1500 (MMG) + ラム 1500 (MMG) + 램 1500 (중형기관총) + Ram 1500 (MMG) + Ram 1500 (MMG) + + + Ram 1500 (MRL) + ラム 1500 (MRL) + 램 1500 (다연장로켓) + Ram 1500 (MRL) + Ram 1500 (MRL) + + + Ram 1500 (AA) + ラム 1500 (対空) + 램 1500 (대공) + Ram 1500 (AA) + Ram 1500 (AA) + + + Ram 1500 (Covered) + ラム 1500 (カバー) + 램 1500 (커버) + Ram 1500 (Abgedeckt) + Ram 1500 (Coperto) + + + Ram 1500 (Water) + ラム 1500 (給水) + 램 1500 (급수) + Ram 1500 (Wasser) + Ram 1500 (Acqua) + + + RSG60 + RSG60 + RSG60 + RSG60 + RSG60 + + + AMOS Container + AMOS コンテナ + AMOS 컨테이너 + AMOS Container + AMOS Container + + + Drone40 + ドローン40 + 드론40 + Drone40 + Drone40 + + + Drone40 Scout + ドローン40 偵察型 + 드론40 정찰 + Drone40 Scout + Drone40 Scout + + + Drone40 HE + ドローン40 榴弾 + 드론40 고폭 + Drone40 HE + Drone40 HE + + + Drone40 Smoke (White) + ドローン40 発煙弾 (白) + 드론40 연막 (백색) + Drone40 Smoke (Weiß) + Drone40 Smoke (Bianco) + + + Drone40 Smoke (Blue) + ドローン40 発煙弾 (青) + 드론40 연막 (청색) + Drone40 Smoke (Blau) + Drone40 Smoke (Blu) + + + Drone40 Smoke (Red) + ドローン40 発煙弾 (赤) + 드론40 연막 (적색) + Drone40 Smoke (Rot) + Drone40 Smoke (Rosso) + + + Drone40 Smoke (Green) + ドローン40 発煙弾 (緑) + 드론40 연막 (녹색) + Drone40 Smoke (Grün) + Drone40 Smoke (Verde) + + + Drone40 Smoke (Orange) + ドローン40 発煙弾 (橙) + 드론40 연막 (주황색) + Drone40 Smoke (Orange) + Drone40 Smoke (Arancione) + + + diff --git a/addons/compat_rf/config.cpp b/addons/compat_rf/config.cpp new file mode 100644 index 0000000000..ab6fb94275 --- /dev/null +++ b/addons/compat_rf/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RF_Data_Loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rf/script_component.hpp b/addons/compat_rf/script_component.hpp new file mode 100644 index 0000000000..2cc45da490 --- /dev/null +++ b/addons/compat_rf/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_rf +#define COMPONENT_BEAUTIFIED Reaction Forces Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/optionals/compat_rh_acc/$PBOPREFIX$ b/addons/compat_rh_acc/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rh_acc/$PBOPREFIX$ rename to addons/compat_rh_acc/$PBOPREFIX$ diff --git a/addons/compat_rh_acc/CfgWeapons.hpp b/addons/compat_rh_acc/CfgWeapons.hpp new file mode 100644 index 0000000000..85c5725523 --- /dev/null +++ b/addons/compat_rh_acc/CfgWeapons.hpp @@ -0,0 +1,161 @@ + +class CfgWeapons { + class ItemCore; + + /* Scopes */ + class InventoryOpticsItem_Base_F; + + class RH_shortdot: ItemCore { + ACE_ScopeHeightAboveRail = 4.40511; + /* // This would require MOA turrets + ACE_ScopeAdjust_Vertical[] = { -1, 25 }; + ACE_ScopeAdjust_Horizontal[] = { -13, 13 }; + ACE_ScopeAdjust_VerticalIncrement = 0.5; + ACE_ScopeAdjust_Unit = "MOA"; + */ + }; + + class RH_accupoint: ItemCore { + ACE_ScopeHeightAboveRail = 3.726; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class Accupoint { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_m3lr: ItemCore { + ACE_ScopeHeightAboveRail = 3.5751; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class m3lr { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_leu_mk4: ItemCore { + ACE_ScopeHeightAboveRail = 4.64216; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class mk4 { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_c79: ItemCore { + ACE_ScopeHeightAboveRail = 4.16731; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class c79scope { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_c79_2d: ItemCore { + ACE_ScopeHeightAboveRail = 4.16731; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class c79scope { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_anpvs10: ItemCore { + ACE_ScopeHeightAboveRail = 2.64379; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class pvs10 { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_pas13cm: ItemCore { + ACE_ScopeHeightAboveRail = 10.601; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class MTWS { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_pas13cmg: ItemCore { + ACE_ScopeHeightAboveRail = 10.601; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class MTWSmg { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class RH_pas13ch: ItemCore { + ACE_ScopeHeightAboveRail = 10.6017; + ACE_ScopeAdjust_Vertical[] = { -4, 30 }; + ACE_ScopeAdjust_Horizontal[] = { -6, 6 }; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class HTWS { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; +}; diff --git a/addons/compat_rh_acc/config.cpp b/addons/compat_rh_acc/config.cpp new file mode 100644 index 0000000000..41aee34292 --- /dev/null +++ b/addons/compat_rh_acc/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_scopes", "RH_acc"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/optionals/compat_rh_acc/script_component.hpp b/addons/compat_rh_acc/script_component.hpp similarity index 100% rename from optionals/compat_rh_acc/script_component.hpp rename to addons/compat_rh_acc/script_component.hpp diff --git a/optionals/compat_rh_de/$PBOPREFIX$ b/addons/compat_rh_de/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rh_de/$PBOPREFIX$ rename to addons/compat_rh_de/$PBOPREFIX$ diff --git a/addons/compat_rh_de/CfgAmmo.hpp b/addons/compat_rh_de/CfgAmmo.hpp new file mode 100644 index 0000000000..cb6254ad5c --- /dev/null +++ b/addons/compat_rh_de/CfgAmmo.hpp @@ -0,0 +1,147 @@ +class CfgAmmo { + class BulletBase; + class RH_50_AE_Ball: BulletBase { + ACE_caliber=12.7; + ACE_bulletLength=28.194; + ACE_bulletMass=21.06; + 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.228}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={360, 398, 420}; + ACE_barrelLengths[]={101.6, 152.4, 228.6}; + }; + class RH_454_Casull: BulletBase { + ACE_caliber=11.481; + ACE_bulletLength=22.733; + ACE_bulletMass=21.06; + 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_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={450, 490, 500}; + ACE_barrelLengths[]={101.6, 190.5, 228.6}; + }; + class RH_32ACP: BulletBase { + ACE_caliber=7.938; + ACE_bulletLength=15.494; + ACE_bulletMass=4.212; + 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.118}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={282, 300, 320}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class RH_45ACP: BulletBase { + ACE_caliber=11.481; + ACE_bulletLength=17.272; + ACE_bulletMass=14.904; + 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.195}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={230, 250, 285}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class RH_B_40SW: BulletBase { + ACE_caliber=10.16; + ACE_bulletLength=11.354; + ACE_bulletMass=8.748; + 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.105, 0.115, 0.120, 0.105}; + ACE_velocityBoundaries[]={365, 305, 259}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={360, 380, 400}; + ACE_barrelLengths[]={101.6, 152.4, 228.6}; + }; + class RH_44mag_ball: BulletBase { + ACE_caliber=10.897; + ACE_bulletLength=20.422; + ACE_bulletMass=12.96; + 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.172}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={360, 390, 420}; + ACE_barrelLengths[]={101.6, 190.5, 228.6}; + }; + class RH_357mag_ball: BulletBase { + ACE_caliber=9.068; + ACE_bulletLength=13.741; + ACE_bulletMass=8.1; + 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.148}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={490, 510, 535}; + ACE_barrelLengths[]={101.6, 152.4, 228.6}; + }; + class RH_762x25: BulletBase { + ACE_caliber=7.874; + ACE_bulletLength=13.856; + ACE_bulletMass=5.5728; + 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.17}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={360, 380, 400}; + ACE_barrelLengths[]={101.6, 152.4, 228.6}; + }; + class RH_9x18_Ball: BulletBase { + ACE_caliber=9.271; + ACE_bulletLength=15.494; + ACE_bulletMass=6.00048; + 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.125}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={298, 330, 350}; + ACE_barrelLengths[]={96.52, 127.0, 228.6}; + }; + class RH_B_9x19_Ball: BulletBase { + ACE_caliber=9.017; + ACE_bulletLength=15.494; + ACE_bulletMass=8.0352; + 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.165}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={340, 370, 400}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class RH_B_22LR_SD: BulletBase { + ACE_caliber=5.664; + ACE_bulletLength=11.43; + ACE_bulletMass=2.4624; + 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.111}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={330, 340, 360}; + ACE_barrelLengths[]={101.6, 152.4, 228.6}; + }; + class RH_57x28mm: BulletBase { + ACE_caliber=5.69; + ACE_bulletLength=12.573; + ACE_bulletMass=1.8144; + 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.144}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={550, 625, 720}; + ACE_barrelLengths[]={101.6, 152.4, 262.89}; + }; +}; diff --git a/addons/compat_rh_de/CfgWeapons.hpp b/addons/compat_rh_de/CfgWeapons.hpp new file mode 100644 index 0000000000..ed8322e356 --- /dev/null +++ b/addons/compat_rh_de/CfgWeapons.hpp @@ -0,0 +1,112 @@ +class CfgWeapons { + class Pistol_Base_F; + class RH_Pistol_Base_F; + class RH_deagle: RH_Pistol_Base_F { + ACE_barrelTwist=482.6; + ACE_barrelLength=152.4; + }; + class RH_mateba: Pistol_Base_F { + ACE_barrelTwist=355.6; + ACE_barrelLength=152.4; + }; + class RH_mp412: Pistol_Base_F { + ACE_barrelTwist=254.0; + ACE_barrelLength=152.4; + }; + class RH_python: Pistol_Base_F { + ACE_barrelTwist=355.6; + ACE_barrelLength=152.4; + }; + class RH_bull: RH_python { + ACE_barrelTwist=609.6; + ACE_barrelLength=165.1; + }; + class RH_ttracker: Pistol_Base_F { + ACE_barrelTwist=304.8; + ACE_barrelLength=101.6; + }; + class RH_cz75: RH_Pistol_Base_F { + ACE_barrelTwist=246.38; + ACE_barrelLength=119.38; + }; + class RH_p226: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=111.76; + }; + class RH_sw659: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=188.976; + }; + class RH_usp: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=112.014; + }; + class RH_uspm: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=152.4; + }; + class RH_kimber: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=127.0; + }; + class RH_m1911: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=127.0; + }; + class RH_tt33: RH_Pistol_Base_F { + ACE_barrelTwist=240.03; + ACE_barrelLength=116.84; + }; + class RH_mak: RH_Pistol_Base_F { + ACE_barrelTwist=240.03; + ACE_barrelLength=93.472; + }; + class RH_mk2: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=101.6; + }; + class RH_m9: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=124.46; + }; + class RH_g18: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=114.046; + }; + class RH_g17: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=114.046; + }; + class RH_g19: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=101.6; + }; + class RH_gsh18: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=104.14; + }; + class RH_fnp45: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=114.3; + }; + class RH_fn57: RH_fnp45 { + ACE_barrelTwist=231.14; + ACE_barrelLength=121.92; + }; + class RH_vp70: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=116.84; + }; + class RH_vz61: RH_Pistol_Base_F { + ACE_barrelTwist=406.4; + ACE_barrelLength=114.3; + }; + class RH_tec9: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=127.0; + }; + class RH_muzi: RH_Pistol_Base_F { + ACE_barrelTwist=248.92; + ACE_barrelLength=127.0; + }; +}; diff --git a/addons/compat_rh_de/config.cpp b/addons/compat_rh_de/config.cpp new file mode 100644 index 0000000000..90a37e33fc --- /dev/null +++ b/addons/compat_rh_de/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RH_de_cfg"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/optionals/compat_rh_de/script_component.hpp b/addons/compat_rh_de/script_component.hpp similarity index 100% rename from optionals/compat_rh_de/script_component.hpp rename to addons/compat_rh_de/script_component.hpp diff --git a/optionals/compat_rh_m4/$PBOPREFIX$ b/addons/compat_rh_m4/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rh_m4/$PBOPREFIX$ rename to addons/compat_rh_m4/$PBOPREFIX$ diff --git a/addons/compat_rh_m4/CfgAmmo.hpp b/addons/compat_rh_m4/CfgAmmo.hpp new file mode 100644 index 0000000000..03b6098ad2 --- /dev/null +++ b/addons/compat_rh_m4/CfgAmmo.hpp @@ -0,0 +1,191 @@ +class CfgAmmo { + + class Default; + class BulletCore; + class BulletBase; + class B_9x21_Ball; + class B_556x45_Ball; + class B_65x39_Caseless; + class B_762x51_Ball; + + class RH_9x19_B_M822: BulletBase { + ACE_caliber=9.017; + ACE_bulletLength=15.494; + ACE_bulletMass=8.0352; + 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.165}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={340, 370, 400}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class RH_9x19_B_HP: BulletBase { + ACE_caliber=9.017; + ACE_bulletLength=15.494; + ACE_bulletMass=8.0352; + 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.165}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={340, 370, 400}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class RH_9x19_B_HPSB: BulletBase { + ACE_caliber=9.017; + ACE_bulletLength=15.316; + ACE_bulletMass=9.5256; + 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.212}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={295, 310, 330}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class RH_556x45_B_M855A1: B_556x45_Ball { + ACE_caliber=5.69; + ACE_bulletLength=23.012; + ACE_bulletMass=4.0176; + ACE_ammoTempMuzzleVelocityShifts[]={-27.20, -26.44, -23.76, -21.00, -17.54, -13.10, -7.95, -1.62, 6.24, 15.48, 27.75}; + ACE_ballisticCoefficients[]={0.151}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900}; + ACE_barrelLengths[]={210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6}; + }; + class RH_556x45_B_Mk318: B_556x45_Ball { + ACE_caliber=5.69; + ACE_bulletLength=23.012; + ACE_bulletMass=4.0176; + 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.307}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={780, 886, 950}; + ACE_barrelLengths[]={254.0, 393.7, 508.0}; + }; + class RH_556x45_B_Mk262: B_556x45_Ball { + ACE_caliber=5.69; + ACE_bulletLength=23.012; + ACE_bulletMass=4.9896; + 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.361}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={624, 816, 832, 838}; + ACE_barrelLengths[]={190.5, 368.3, 457.2, 508.0}; + }; + class RH_68x43_B_FMJ: B_65x39_Caseless { + ACE_caliber=7.036; + ACE_bulletLength=24.359; + ACE_bulletMass=7.452; + 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.162}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={713, 785, 810, 850}; + ACE_barrelLengths[]={304.8, 406.4, 508.0, 609.6}; + }; + class RH_68x43_B_Match: B_65x39_Caseless { + ACE_caliber=7.036; + ACE_bulletLength=31.75; + ACE_bulletMass=8.748; + 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.253}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={700, 732, 750, 780}; + ACE_barrelLengths[]={304.8, 406.4, 508.0, 609.6}; + }; + class RH_762x35_B_FMJ: B_65x39_Caseless { + ACE_caliber=7.823; + ACE_bulletLength=28.397; + ACE_bulletMass=9.5256; + 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.398}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={559, 609, 625}; + ACE_barrelLengths[]={152.4, 406.4, 508.0}; + }; + class RH_762x35_B_Match: B_65x39_Caseless { + ACE_caliber=7.823; + ACE_bulletLength=29.286; + ACE_bulletMass=8.1; + 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.349, 0.338, 0.330, 0.310}; + ACE_velocityBoundaries[]={792, 610, 488}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={572, 676, 700}; + ACE_barrelLengths[]={152.4, 406.4, 508.0}; + }; + class RH_762x35_B_MSB: B_65x39_Caseless { + ACE_caliber=7.823; + ACE_bulletLength=37.821; + ACE_bulletMass=14.256; + 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.608}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={300, 320, 340}; + ACE_barrelLengths[]={228.6, 406.4, 508.0}; + }; + class RH_762x51_B_M80A1: B_762x51_Ball { + ACE_caliber=7.823; + ACE_bulletLength=28.956; + ACE_bulletMass=9.4608; + 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.2}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={700, 800, 820, 833, 845}; + ACE_barrelLengths[]={254.0, 406.4, 508.0, 609.6, 660.4}; + }; + class RH_762x51_B_Mk316LR: B_762x51_Ball { + ACE_caliber=7.823; + ACE_bulletLength=31.496; + ACE_bulletMass=11.34; + ACE_ammoTempMuzzleVelocityShifts[]={-5.3, -5.1, -4.6, -4.2, -3.4, -2.6, -1.4, -0.3, 1.4, 3.0, 5.2}; + ACE_ballisticCoefficients[]={0.243}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={775, 790, 805, 810}; + ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + }; + class RH_762x51_B_Mk319: B_762x51_Ball { + ACE_caliber=7.823; + ACE_bulletLength=31.496; + ACE_bulletMass=8.424; + 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.377}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={838, 892, 910}; + ACE_barrelLengths[]={330.2, 406.4, 508.0}; + }; + class RH_762x51_B_LFMJSB: B_762x51_Ball { + ACE_caliber=7.823; + ACE_bulletLength=34.036; + ACE_bulletMass=12.96; + 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.235}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={305, 325, 335, 340}; + ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + }; +}; diff --git a/addons/compat_rh_m4/CfgWeapons.hpp b/addons/compat_rh_m4/CfgWeapons.hpp new file mode 100644 index 0000000000..2156dd9399 --- /dev/null +++ b/addons/compat_rh_m4/CfgWeapons.hpp @@ -0,0 +1,103 @@ +class CfgWeapons { + class Rifle_Base_F; + class RH_ar10: Rifle_Base_F { + ACE_barrelTwist=285.75; + ACE_barrelLength=528.32; + }; + class RH_m110: Rifle_Base_F { + ACE_barrelTwist=254.0; + ACE_barrelLength=508.0; + }; + class RH_Mk11: RH_m110 { + ACE_barrelTwist=285.75; + ACE_barrelLength=609.6; + }; + class RH_SR25EC: RH_m110 { + ACE_barrelTwist=285.75; + ACE_barrelLength=508.0; + }; + class RH_m4: Rifle_Base_F { + ACE_barrelTwist=177.8; + ACE_barrelLength=368.3; + }; + class RH_M4_ris: RH_m4 { + ACE_barrelTwist=177.8; + ACE_barrelLength=368.3; + }; + class RH_M4A1_ris: RH_M4_ris { + ACE_barrelTwist=177.8; + ACE_barrelLength=368.3; + }; + class RH_M4m: RH_M4A1_ris { + ACE_barrelTwist=177.8; + ACE_barrelLength=266.7; + }; + class RH_M4sbr: RH_M4A1_ris { + ACE_barrelTwist=177.8; + ACE_barrelLength=266.7; + }; + class RH_hb: Rifle_Base_F { + ACE_barrelTwist=203.2; + ACE_barrelLength=152.4; + }; + class RH_hb_b: RH_hb { + ACE_barrelTwist=203.2; + ACE_barrelLength=152.4; + }; + class RH_sbr9: Rifle_Base_F { + ACE_barrelTwist=246.38; + ACE_barrelLength=228.6; + }; + class RH_M4A6: RH_M4A1_ris { + ACE_barrelTwist=254.0; + ACE_barrelLength=368.3; + }; + class RH_M16a1: RH_m4 { + ACE_barrelTwist=355.6; + ACE_barrelLength=508.0; + }; + class RH_M16A2: RH_m4 { + ACE_barrelTwist=177.8; + ACE_barrelLength=508.0; + }; + class RH_M16A4: RH_M4_ris { + ACE_barrelTwist=177.8; + ACE_barrelLength=508.0; + }; + class RH_M16A3: RH_M16A4 { + ACE_barrelTwist=177.8; + ACE_barrelLength=508.0; + }; + class RH_M16A4_m: RH_M16A4 { + ACE_barrelTwist=177.8; + ACE_barrelLength=508.0; + }; + class RH_M16A6: RH_M16A4 { + ACE_barrelTwist=177.8; + ACE_barrelLength=508.0; + }; + class RH_Mk12mod1: RH_M16A4 { + ACE_barrelTwist=177.8; + ACE_barrelLength=457.2; + }; + class RH_SAMR: RH_Mk12mod1 { + ACE_barrelTwist=195.58; + ACE_barrelLength=508.0; + }; + class RH_Hk416: RH_M4A1_ris { + ACE_barrelTwist=177.8; + ACE_barrelLength=368.3; + }; + class RH_Hk416s: RH_M4sbr { + ACE_barrelTwist=177.8; + ACE_barrelLength=264.16; + }; + class RH_Hk416c: RH_M4sbr { + ACE_barrelTwist=177.8; + ACE_barrelLength=228.6; + }; + class RH_M27IAR: RH_Mk12mod1 { + ACE_barrelTwist=177.8; + ACE_barrelLength=419.1; + }; +}; diff --git a/addons/compat_rh_m4/config.cpp b/addons/compat_rh_m4/config.cpp new file mode 100644 index 0000000000..48365df49c --- /dev/null +++ b/addons/compat_rh_m4/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RH_m4_cfg"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/optionals/compat_rh_m4/script_component.hpp b/addons/compat_rh_m4/script_component.hpp similarity index 100% rename from optionals/compat_rh_m4/script_component.hpp rename to addons/compat_rh_m4/script_component.hpp diff --git a/optionals/compat_rh_pdw/$PBOPREFIX$ b/addons/compat_rh_pdw/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rh_pdw/$PBOPREFIX$ rename to addons/compat_rh_pdw/$PBOPREFIX$ diff --git a/addons/compat_rh_pdw/CfgAmmo.hpp b/addons/compat_rh_pdw/CfgAmmo.hpp new file mode 100644 index 0000000000..7c5e8a45a8 --- /dev/null +++ b/addons/compat_rh_pdw/CfgAmmo.hpp @@ -0,0 +1,13 @@ +class BulletBase; +class RH_B_6x35: BulletBase { + ACE_caliber=5.69; + ACE_bulletLength=11.303; + ACE_bulletMass=4.212; + 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.26}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={730, 750, 760}; + ACE_barrelLengths[]={203.2, 254.0, 304.8}; +}; diff --git a/addons/compat_rh_pdw/CfgWeapons.hpp b/addons/compat_rh_pdw/CfgWeapons.hpp new file mode 100644 index 0000000000..e64a9f2e67 --- /dev/null +++ b/addons/compat_rh_pdw/CfgWeapons.hpp @@ -0,0 +1,7 @@ +class CfgWeapons { + class Rifle_Base_F; + class RH_PDW: Rifle_Base_F { + ACE_barrelTwist=177.8; + ACE_barrelLength=254.0; + }; +}; diff --git a/addons/compat_rh_pdw/config.cpp b/addons/compat_rh_pdw/config.cpp new file mode 100644 index 0000000000..433a8d111c --- /dev/null +++ b/addons/compat_rh_pdw/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RH_PDW"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/optionals/compat_rh_pdw/script_component.hpp b/addons/compat_rh_pdw/script_component.hpp similarity index 100% rename from optionals/compat_rh_pdw/script_component.hpp rename to addons/compat_rh_pdw/script_component.hpp diff --git a/optionals/compat_rhs_afrf3/$PBOPREFIX$ b/addons/compat_rhs_afrf3/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rhs_afrf3/$PBOPREFIX$ rename to addons/compat_rhs_afrf3/$PBOPREFIX$ diff --git a/addons/compat_rhs_afrf3/CfgAmmo.hpp b/addons/compat_rhs_afrf3/CfgAmmo.hpp new file mode 100644 index 0000000000..11aee03d79 --- /dev/null +++ b/addons/compat_rhs_afrf3/CfgAmmo.hpp @@ -0,0 +1,268 @@ +class CfgAmmo { + class BulletBase; + class B_556x45_Ball; + class rhs_B_545x39_Ball: B_556x45_Ball { + 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="ASM"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={780, 880, 920}; + ACE_barrelLengths[]={254.0, 414.02, 508.0}; + }; + class rhs_B_545x39_Ball_Tracer_Green: rhs_B_545x39_Ball { + ACE_caliber=5.588; + ACE_bulletLength=21.59; + ACE_bulletMass=3.22704; + 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="ASM"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={785, 883, 925}; + ACE_barrelLengths[]={254.0, 414.02, 508.0}; + }; + class B_762x51_Ball; + class rhs_B_762x54_Ball: B_762x51_Ball { + ACE_caliber=7.925; + ACE_bulletLength=28.956; + ACE_bulletMass=9.8496; + 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.4}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={700, 800, 820, 833}; + ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + }; + class rhs_B_762x54_Ball_Tracer_Green: rhs_B_762x54_Ball { + ACE_caliber=7.925; + ACE_bulletLength=28.956; + ACE_bulletMass=9.6552; + 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.395}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={680, 750, 798, 800}; + ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + }; + class rhs_B_762x54_7N1_Ball: rhs_B_762x54_Ball { + ACE_caliber=7.925; + ACE_bulletLength=28.956; + ACE_bulletMass=9.8496; + ACE_muzzleVelocityVariationSD=0.4; + 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.4}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={700, 800, 820, 833}; + ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + }; + class rhs_B_762x39_Ball: B_762x51_Ball { + 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 rhs_B_762x39_Tracer: rhs_B_762x39_Ball { + ACE_caliber=7.823; + ACE_bulletLength=28.956; + ACE_bulletMass=7.5816; + 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_9x21_Ball; + class rhs_B_9x19_7N21: B_9x21_Ball { + ACE_caliber=9.017; + ACE_bulletLength=15.494; + ACE_bulletMass=5.19696; + 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.14}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={445, 460, 480}; + ACE_barrelLengths[]={101.6, 127.0, 228.6}; + }; + class rhs_B_9x18_57N181S: B_9x21_Ball { + ACE_caliber=9.271; + ACE_bulletLength=15.494; + ACE_bulletMass=6.00048; + 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.125}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={298, 330, 350}; + ACE_barrelLengths[]={96.52, 127.0, 228.6}; + }; + class rhs_B_545x39_7U1_Ball: rhs_B_545x39_Ball { + ACE_caliber = 5.67; + ACE_bulletLength = 24.3; + ACE_bulletMass = 5.2; + ACE_ammoTempMuzzleVelocityShifts[] = {-8.85,-8.49,-7.61667,-6.70667,-5.66,-4.26667,-2.54667,-0.51,1.98667,5.05667,8.73}; + ACE_muzzleVelocities[] = {300, 320, 335}; + ACE_barrelLengths[] = {200, 300, 400}; + }; + class rhs_B_762x39_U_Ball: rhs_B_762x39_Ball { + ACE_caliber = 7.94; + ACE_bulletLength = 33.62; + ACE_bulletMass = 12.5; + ACE_ammoTempMuzzleVelocityShifts[] = {-8.85,-8.49,-7.61667,-6.70667,-5.66,-4.26667,-2.54667,-0.51,1.98667,5.05667,8.73}; //Just Scaled Down Normal? + ACE_muzzleVelocities[]= {270, 290, 320}; + ACE_barrelLengths[]= {254.0, 414.02, 508.0}; + }; + class rhs_B_9x39_SP5: rhs_B_762x39_Ball { + ACE_caliber = 9.246; + ACE_bulletLength = 31.496; + ACE_bulletMass = 16.1; + ACE_ammoTempMuzzleVelocityShifts[] = {-2.655,-2.547,-2.285,-2.012,-1.698,-1.28,-0.764,-0.153,0.596,1.517,2.619}; + ACE_ballisticCoefficients[] = {0.275}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_muzzleVelocities[] = {280, 300, 320}; + ACE_barrelLengths[] = {254.0, 414.02, 508.0}; + }; + class rhs_B_9x39_SP6: rhs_B_9x39_SP5 { + ACE_caliber = 9.26; + ACE_bulletMass = 16.2; + ACE_ballisticCoefficients[] = {0.225}; + ACE_muzzleVelocities[] = {290, 310, 335}; + ACE_barrelLengths[] = {254.0, 414.02, 508.0}; + }; + + class SubmunitionBase; + class rhs_ammo_127x108mm_x5: SubmunitionBase { + ACE_rearm_caliber=13; + }; + + class GrenadeHand; + class rhs_ammo_rgd5: GrenadeHand { + EGVAR(frag,enabled) = 1; + EGVAR(frag,metal) = 200; + EGVAR(frag,charge) = 110; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; + EGVAR(frag,skip) = 0; + EGVAR(frag,force) = 1; + }; + class rhs_ammo_rgn: rhs_ammo_rgd5 { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class rhs_ammo_fakel: GrenadeHand { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class rhs_ammo_fakels: rhs_ammo_fakel {}; + class rhs_ammo_zarya2: rhs_ammo_fakels {}; + class rhs_ammo_plamyam: rhs_ammo_fakels {}; + + class RocketBase; + class R_PG32V_F: RocketBase {}; + class rhs_rpg26_rocket: R_PG32V_F {}; + class rhs_rpg7v2_pg7vl: rhs_rpg26_rocket {}; + class rhs_rpg7v2_og7v: rhs_rpg7v2_pg7vl { + EGVAR(frag,enabled) = 1; + EGVAR(frag,metal) = 400; + EGVAR(frag,charge) = 210; + EGVAR(frag,gurney_c) = 2800; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium_HD"}; + EGVAR(frag,skip) = 0; + EGVAR(frag,force) = 1; + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + class rhs_rpg7v2_tbg7v: rhs_rpg7v2_pg7vl { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + EGVAR(vehicle_damage,incendiary) = 0.7; + }; + class rhs_rshg2_rocket: rhs_rpg7v2_tbg7v { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + + class G_40mm_HE; + class rhs_g_vog25: G_40mm_HE {}; + class rhs_g_vg40tb: rhs_g_vog25 { //Thermobaric + EGVAR(frag,force) = 0; + }; + class rhs_g_vg40sz: rhs_g_vog25 { //Flashbang + EGVAR(frag,force) = 0; + }; + class rhs_g_gdm40: rhs_g_vog25 { //Smoke + EGVAR(frag,force) = 0; + }; + class rhs_g_vg40md_white: rhs_g_vog25 { //Smoke + EGVAR(frag,force) = 0; + }; + + class SmokeShell; + class rhs_ammo_rdg2_white: SmokeShell { + EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}}; + }; + + class Sh_125mm_APFSDS; + class Sh_125mm_HE; + class rhs_ammo_bm_base: Sh_125mm_APFSDS { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + class rhs_ammo_bk_base: rhs_ammo_bm_base { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_3bm_base: rhs_ammo_bm_base {}; + class rhs_ammo_of_base: Sh_125mm_HE { + EGVAR(vehicle_damage,incendiary) = 0.30; + }; + class rhs_ammo_base_penetrator: rhs_ammo_3bm_base { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_ap_penetrator: Sh_125mm_APFSDS { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + + class M_Titan_AT; + class rhs_ammo_atgmCore_base: M_Titan_AT { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_atgmBase_base: M_Titan_AT { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + + class rhs_ammo_rpgShell_base; + class rhs_ammo_og9v: rhs_ammo_rpgShell_base { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + + class rhs_ammo_rpg15Shell_base; + class rhs_ammo_og15v: rhs_ammo_rpg15Shell_base { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + + class B_30mm_AP; + class rhs_ammo_30x165mm_base: B_30mm_AP { + EGVAR(vehicle_damage,incendiary) = 0.2; + }; +}; diff --git a/addons/compat_rhs_afrf3/CfgEventHandlers.hpp b/addons/compat_rhs_afrf3/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/compat_rhs_afrf3/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/compat_rhs_afrf3/CfgMagazines.hpp b/addons/compat_rhs_afrf3/CfgMagazines.hpp new file mode 100644 index 0000000000..b554686f3d --- /dev/null +++ b/addons/compat_rhs_afrf3/CfgMagazines.hpp @@ -0,0 +1,20 @@ +class cfgMagazines { + class VehicleMagazine; + class rhs_30Rnd_545x39_7N6_AK; + + class rhs_100Rnd_762x54mmR: rhs_30Rnd_545x39_7N6_AK { + ACE_isBelt = 1; + }; + class rhs_mag_127x108mm_50: VehicleMagazine { + ACE_isBelt = 1; + }; + class rhs_mag_127x108mm_150: rhs_mag_127x108mm_50 { + ACE_isBelt = 0; + }; + class rhs_mag_127x108mm_1470: rhs_mag_127x108mm_50 { + ACE_isBelt = 0; + }; + class RHS_mag_VOG30_30: VehicleMagazine { + ACE_isBelt = 1; + }; +}; diff --git a/addons/compat_rhs_afrf3/CfgVehicles.hpp b/addons/compat_rhs_afrf3/CfgVehicles.hpp new file mode 100644 index 0000000000..1cf5029bc3 --- /dev/null +++ b/addons/compat_rhs_afrf3/CfgVehicles.hpp @@ -0,0 +1,651 @@ +class CfgVehicles { + class LandVehicle; + class Tank: LandVehicle { + class NewTurret; + }; + class Tank_F: Tank { + class Turrets { + class MainTurret: NewTurret { + class Turrets { + class CommanderOptics; + }; + }; + }; + }; + class Car: LandVehicle { + class ACE_Actions { + class ACE_MainActions {}; + }; + }; + class Car_F: Car { + class ViewPilot; + class NewTurret; + }; + class Wheeled_APC_F: Car_F { + class NewTurret; + class Turrets { + class MainTurret: NewTurret { + class ViewOptics; + }; + }; + class CommanderOptics; + }; + class Air; + class Helicopter: Air { + class Turrets; + }; + class Helicopter_Base_F: Helicopter { + class Turrets: Turrets { + class MainTurret; + }; + }; + + class rhs_tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 1200; + EGVAR(vehicle_damage,hullDetonationProb) = 0.8; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0.2; + EGVAR(vehicle_damage,hullFireProb) = 0.8; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.5; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + }; + class rhs_btr_base: Wheeled_APC_F { + EGVAR(map,vehicleLightColor)[] = {0,0,1,0.1}; + EGVAR(refuel,fuelCapacity) = 300; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.7; + EGVAR(vehicle_damage,turretFireProb) = 0.7; + EGVAR(vehicle_damage,engineFireProb) = 0.7; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + + class rhs_infantry_msv_base; + class rhs_pilot_base: rhs_infantry_msv_base { + ace_gforcecoef = 0.55; + }; + + class O_Plane_CAS_02_F; + class RHS_su25_base: O_Plane_CAS_02_F { + EGVAR(refuel,fuelCapacity) = 3600; + }; + + class Helicopter_Base_H: Helicopter_Base_F { + class EventHandlers; + }; + class Heli_Light_02_base_F: Helicopter_Base_H {}; + class RHS_Mi8_base: Heli_Light_02_base_F { + EGVAR(map,vehicleLightColor)[] = {1,0,0,0.1}; + EGVAR(refuel,fuelCapacity) = 3700; + }; + class Heli_Attack_02_base_F: Helicopter_Base_F {}; + class RHS_Ka52_base: Heli_Attack_02_base_F { + EGVAR(refuel,fuelCapacity) = 1870; + }; + + class RHS_Mi24_base: Heli_Attack_02_base_F { + EGVAR(map,vehicleLightColor)[] = {1,0,0,0.1}; + EGVAR(refuel,fuelCapacity) = 1851; + }; + + class rhs_t80b: rhs_tank_base { + EGVAR(refuel,fuelCapacity) = 1100; + EGVAR(vehicle_damage,canHaveFireRing) = 1; + }; + class Truck_F: Car_F {}; + class RHS_Ural_BaseTurret: Truck_F { + EGVAR(refuel,fuelCapacity) = 360; + }; + + class RHS_Ural_Base: RHS_Ural_BaseTurret {}; + class RHS_Ural_MSV_Base: RHS_Ural_Base {}; + class RHS_Ural_Support_MSV_Base_01: RHS_Ural_MSV_Base {}; + class RHS_Ural_Fuel_MSV_01: RHS_Ural_Support_MSV_Base_01 { + EGVAR(refuel,hooks)[] = {{-0.05,-3.6,-0.45}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + class RHS_Ural_Ammo_Base: RHS_Ural_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class rhs_kraz255b1_base; + class rhs_kraz255b1_fuel_base: rhs_kraz255b1_base { + EGVAR(refuel,hooks)[] = {{-0.05,-3.6,-0.45}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class rhs_truck: Truck_F { + EGVAR(refuel,fuelCapacity) = 210; + }; + + class rhs_gaz66_vmf; + class rhs_gaz66_ammo_base: rhs_gaz66_vmf { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class rhs_kamaz5350; + class rhs_kamaz5350_ammo_base: rhs_kamaz5350 { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class MRAP_02_base_F; + class rhs_tigr_base: MRAP_02_base_F { + EGVAR(refuel,fuelCapacity) = 138; + }; + + class Offroad_01_base_f; + class RHS_UAZ_Base: Offroad_01_base_f { + EGVAR(refuel,fuelCapacity) = 78; + }; + + class APC_Tracked_02_base_F: Tank_F { + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; + }; + + class rhs_zsutank_base: APC_Tracked_02_base_F { + EGVAR(refuel,fuelCapacity) = 515; + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0; + EGVAR(vehicle_damage,engineDetonationProb) = 0.2; + EGVAR(vehicle_damage,hullFireProb) = 0.7; + EGVAR(vehicle_damage,turretFireProb) = 0.7; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.8; + EGVAR(vehicle_damage,canHaveFireRing) = 1; + }; + + class rhs_btr60_base: rhs_btr_base { + EGVAR(refuel,fuelCapacity) = 290; + }; + class rhs_btr70_vmf: rhs_btr_base { + EGVAR(refuel,fuelCapacity) = 350; + class ace_viewports { + class view_0 { + camLocation[] = {0.478394, -0.575, -0.145}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {-1.38184, -0.575, -0.145}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + + class rhs_btr70_msv: rhs_btr70_vmf {}; + class rhs_btr80_msv: rhs_btr70_msv { + EGVAR(refuel,fuelCapacity) = 300; + class ace_viewports { + class view_0 { + camLocation[] = {0.534424, -0.336914, 0.636819}; + camAttach = 45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.760254, -0.459473, 0.526328}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {0.770508, -1.21924, 0.526954}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-1.13, -1.2085, 0.490339}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_4 { + camLocation[] = {-1.14124, -0.416992, 0.460611}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_5 { + camLocation[] = {-0.932983, -0.326172, 0.647666}; + camAttach = -45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + class rhs_btr80a_msv: rhs_btr80_msv { + class ace_viewports { + class view_0 { + camLocation[] = {0.589844, -0.314941, 0.449678}; + camAttach = 45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.809082, -0.442871, 0.276865}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {0.819092, -1.24414, 0.27857}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-1.1012, -1.22461, 0.341089}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_4 { + camLocation[] = {-1.11597, -0.458984, 0.307256}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_5 { + camLocation[] = {-0.869995, -0.304688, 0.461181}; + camAttach = -45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + + class rhs_2s3tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 830; + }; + + class OTR21_Base: Truck_F { + EGVAR(refuel,fuelCapacity) = 500; + }; + + class rhs_bmd_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 300; + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.8; + EGVAR(vehicle_damage,turretFireProb) = 0.5; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + class rhs_bmp1tank_base: Tank_F { + EGVAR(map,vehicleLightColor)[] = {0,1,0,0.1}; + EGVAR(refuel,fuelCapacity) = 460; + }; + class rhs_bmp3tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 460; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.5; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + class ace_viewports { + class view_0 { + camLocation[] = {1.02881, -0.923828, -0.647231}; + screenLocation[] = {1.12881, -0.653828, -1.08223}; + camAttach = 50; + maxDistance = 0.5; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {1.01709, -1.55664, -0.647231}; + screenLocation[] = {1.10709, -1.42664, -1.14223}; + camAttach = 82; + maxDistance = 0.5; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {-0.871094, -1.55762, -0.647231}; + screenLocation[] = {-0.981094, -1.42762, -1.13223}; + camAttach = 285; + maxDistance = 0.5; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-1.00879, -0.939941, -0.650259}; + screenLocation[] = {-0.97879, -0.689941, -1.09526}; + camAttach = 310; + maxDistance = 0.5; + roles[]={"cargo"}; + }; + }; + }; + class rhs_a3spruttank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 400; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.5; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + class rhs_a3t72tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 1200; + EGVAR(vehicle_damage,hullDetonationProb) = 0.8; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0.2; + EGVAR(vehicle_damage,hullFireProb) = 0.8; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.5; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + }; + class rhs_bmp_base: rhs_bmp1tank_base { + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.8; + EGVAR(vehicle_damage,turretFireProb) = 0.5; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + class rhs_t72bd_tv: rhs_a3t72tank_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", + "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", + "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", + "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", + "era_29_hitpoint", "era_30_hitpoint", "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", + "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", + "era_50_hitpoint", "era_51_hitpoint", "era_52_hitpoint", "era_53_hitpoint", "era_51_hitpoint", "era_55_hitpoint", "era_56_hitpoint", + "era_57_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", "era_62_hitpoint", "era_63_hitpoint", + "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint", "era_67_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "SLAT_68_hitpoint", "SLAT_69_hitpoint", "SLAT_70_hitpoint" + }; + }; + class rhs_t90_tv: rhs_t72bd_tv { + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.2; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.5; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0; + }; + + class rhs_t14_base: Tank_F { + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.2; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.5; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0; + // Dear LORD RHS loves their ERA + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "SLAT_38_hitpoint", "SLAT_39_hitpoint", "SLAT_40_hitpoint", "SLAT_41_hitpoint" + }; + EGVAR(vehicle_damage,canHaveFireRing) = 1; + }; + + class rhs_t72bb_tv: rhs_a3t72tank_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint" + }; + }; + + class rhs_t72bc_tv: rhs_a3t72tank_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint" + }; + }; + + class rhs_t72be_tv: rhs_t72bd_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", + "era_49_hitpoint", "era_50_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", + "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint", "era_67_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "SLAT_51_hitpoint", "SLAT_52_hitpoint", "SLAT_53_hitpoint", + "SLAT_54_hitpoint", "SLAT_55_hitpoint", "SLAT_56_hitpoint", + "SLAT_57_hitpoint", "SLAT_68_hitpoint", "SLAT_69_hitpoint", + "SLAT_70_hitpoint" + }; + }; + + class rhs_t90a_tv: rhs_t90_tv {}; + class rhs_t90saa_tv: rhs_t90a_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "SLAT_51_hitpoint", "SLAT_52_hitpoint", "SLAT_53_hitpoint", "SLAT_54_hitpoint" + }; + }; + class rhs_t90sab_tv: rhs_t90a_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", + "era_49_hitpoint", "era_50_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_51_hitpoint", "slat_52_hitpoint", "slat_53_hitpoint", "slat_54_hitpoint" + }; + }; + class rhs_t90am_tv: rhs_t90_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", + "era_49_hitpoint", "era_50_hitpoint", "era_51_hitpoint", "era_52_hitpoint", "era_53_hitpoint", "era_54_hitpoint", + "era_55_hitpoint", "era_56_hitpoint", "era_57_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", + "era_61_hitpoint", "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "SLAT_18_hitpoint", "SLAT_19_hitpoint", "SLAT_20_hitpoint", "SLAT_21_hitpoint", + "SLAT_22_hitpoint", "SLAT_23_hitpoint", "SLAT_24_hitpoint", "SLAT_25_hitpoint", + "SLAT_51_hitpoint", "SLAT_52_hitpoint", "SLAT_53_hitpoint", "SLAT_54_hitpoint" + }; + }; + class rhs_t90sm_tv: rhs_t90am_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", + "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", + "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", + "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", + "era_35_hitpoint", "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", + "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", + "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint", + "era_26_hitpoint", "era_55_hitpoint", "era_56_hitpoint", "era_57_hitpoint", + "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", + "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", + "era_66_hitpoint", "era_23_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_23_hitpoint", "slat_26_hitpoint", "slat_51_hitpoint", + "slat_52_hitpoint", "slat_53_hitpoint", "slat_54_hitpoint", + "slat_55_hitpoint", "slat_56_hitpoint", "slat_57_hitpoint", + "slat_18_hitpoint", "slat_19_hitpoint", "slat_20_hitpoint", + "slat_21_hitpoint", "slat_22_hitpoint", "slat_24_hitpoint", + "slat_25_hitpoint" + }; + }; + + class rhs_t80bv: rhs_t80b { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint" + }; + }; + class rhs_t80a; + class rhs_t80u: rhs_t80a { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint" + }; + }; + class rhs_t80uk: rhs_t80u { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" + }; + }; + class rhs_t80ue1: rhs_t80a { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" + }; + }; + class rhs_t80um: rhs_t80u { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" + }; + }; + + class rhs_t15_base; + class rhs_t15_tv: rhs_t15_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", + "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", + "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", + "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", + "era_29_hitpoint", "era_30_hitpoint", "era_31_hitpoint", "era_32_hitpoint", + "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_38_hitpoint", "slat_39_hitpoint", "slat_40_hitpoint", "slat_41_hitpoint" + }; + }; + + // Wirecutter Backpacks + class rhs_assault_umbts; + class rhs_assault_umbts_engineer: rhs_assault_umbts { + EGVAR(logistics_wirecutter,hasWirecutter) = 1; + }; + + class rhs_rk_sht_30_emr; + class rhs_rk_sht_30_emr_engineer: rhs_rk_sht_30_emr { + EGVAR(logistics_wirecutter,hasWirecutter) = 1; + }; + + class rhs_rk_sht_30_olive; + class rhs_rk_sht_30_olive_engineer: rhs_rk_sht_30_olive { + EGVAR(logistics_wirecutter,hasWirecutter) = 1; + }; + + // Interaction positions for static weapons + // Not a fan of this style of inheritance but it's less of a headache in this case + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + }; + class StaticMGWeapon: StaticWeapon {}; + class AT_01_base_F: StaticMGWeapon {}; + class StaticMortar: StaticWeapon {}; + + class rhs_SPG9_base: AT_01_base_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + }; + }; + }; + class rhs_Kornet_Base: AT_01_base_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "tripod"; + }; + }; + }; + + class rhs_2b14_82mm_Base: StaticMortar { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = ""; // no good selections for this mortar + }; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/CfgWeapons.hpp b/addons/compat_rhs_afrf3/CfgWeapons.hpp new file mode 100644 index 0000000000..a6def44c40 --- /dev/null +++ b/addons/compat_rhs_afrf3/CfgWeapons.hpp @@ -0,0 +1,167 @@ +class CfgWeapons { + class hgun_Rook40_F; + class rhs_weap_pya: hgun_Rook40_F { + ACE_barrelTwist = 254.0; + ACE_barrelLength = 111.76; + }; + class Pistol_Base_F; + class rhs_weap_makarov_pm: rhs_weap_pya { + ACE_barrelTwist = 240.03; + ACE_barrelLength = 93.472; + }; + class rhs_weap_ak74m_Base_F; + class rhs_weap_ak74m: rhs_weap_ak74m_Base_F { + ACE_RailHeightAboveBore = -0.456233; + ACE_barrelTwist = 199.898; + ACE_barrelLength = 414.02; + }; + class rhs_weap_ak103_base; + class rhs_weap_ak104: rhs_weap_ak103_base { + ACE_barrelLength = 314.96; + }; + class rhs_weap_ak105: rhs_weap_ak74m { + ACE_barrelLength = 314.96; + }; + class rhs_weap_akm: rhs_weap_ak74m { + ACE_RailHeightAboveBore = -0.456233;//from rhs_weap_akmn and rhs_weap_ak74m + ACE_barrelTwist = 199.898; + ACE_barrelLength = 414.02; + }; + class rhs_weap_aks74; + class rhs_weap_aks74u: rhs_weap_aks74 { + ACE_RailHeightAboveBore = -0.30262; + ACE_barrelTwist = 160.02; + ACE_barrelLength = 210.82; + }; + class rhs_weap_asval: rhs_weap_ak74m { + ACE_barrelTwist = 210.82; + ACE_barrelLength = 200.66; + }; + class rhs_weap_svd: rhs_weap_ak74m { + ACE_RailHeightAboveBore = -0.617396; + ACE_barrelTwist = 238.76; + ACE_barrelLength = 619.76; + }; + class rhs_weap_svdp; + class rhs_weap_svdp_npz: rhs_weap_svdp { + ACE_RailHeightAboveBore = 4.3348; + }; + class rhs_weap_svdp_wd: rhs_weap_svdp { + ACE_RailHeightAboveBore = -0.617396; + }; + class rhs_weap_svdp_wd_npz: rhs_weap_svdp_wd { + ACE_RailHeightAboveBore = 4.3348; + }; + class rhs_weap_svds: rhs_weap_svdp { + ACE_RailHeightAboveBore = -0.617396; + ACE_barrelTwist = 238.76; + ACE_barrelLength = 563.88; + }; + class rhs_weap_svds_npz: rhs_weap_svds { + ACE_RailHeightAboveBore = 4.3348; + }; + class rhs_weap_rpk_base; + class rhs_weap_rpk74_base: rhs_weap_rpk_base { + ACE_barrelLength = 590.00; + ACE_barrelTwist = 195.072; + }; + class rhs_pkp_base; + class rhs_weap_pkp: rhs_pkp_base { + ACE_barrelTwist = 240.03; + ACE_barrelLength = 657.86; + }; + class rhs_weap_pkm: rhs_weap_pkp { + EGVAR(overheating,allowSwapBarrel) = 1; + ACE_barrelTwist = 240.03; + ACE_barrelLength = 645.16; + }; + class rhs_weap_orsis_Base_F; + class rhs_weap_t5000: rhs_weap_orsis_Base_F { // http://en.orsis.com/production/catalog/19046/ + ACE_barrelTwist = 254.0; // 1:10" + ACE_barrelLength = 698.5; // 27.5" + ACE_RailHeightAboveBore = 2.12198; + }; + + class Launcher_Base_F; + class rhs_weap_rpg7: Launcher_Base_F { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,offset) = 0.9; + }; + + class rhs_weap_rpg26: Launcher_Base_F { + EGVAR(overpressure,range) = 10; + EGVAR(overpressure,angle) = 50; + EGVAR(overpressure,offset) = 0.65; + }; + + class rhs_weap_rpg18: rhs_weap_rpg26 { + EGVAR(overpressure,angle) = 45; + EGVAR(overpressure,offset) = 1; + }; + + class rhs_weap_strela; + class rhs_weap_igla: rhs_weap_strela { + EGVAR(overpressure,range) = 6; + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,damage) = 0.6; + EGVAR(overpressure,offset) = 1.65; + }; + + class H_HelmetB; + class rhs_tsh4: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + + class rhs_6b47_bare; + class rhs_6b48: rhs_6b47_bare { + HEARING_PROTECTION_VICCREW; + }; + + class rhs_zsh7a: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_zsh7a_alt: rhs_zsh7a { + ACE_Protection = 1; + }; + class rhs_zsh7a_mike; + class rhs_zsh7a_mike_alt: rhs_zsh7a_mike { + ACE_Protection = 1; + }; + class rhs_zsh7a_mike_green; + class rhs_zsh7a_mike_green_alt: rhs_zsh7a_mike_green { + ACE_Protection = 1; + }; + + class rhs_gssh18: H_HelmetB { + HEARING_PROTECTION_EARMUFF; + }; + + class rhs_6b47; + class rhs_6b47_6m2: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + class rhs_6b47_6m2_1: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6m2: H_HelmetB { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_weap_d81; + class rhs_weap_2a70: rhs_weap_d81 { // "Low pressure" 100mm cannon + EGVAR(overpressure,range) = 15; + EGVAR(overpressure,damage) = 0.5; + }; + class cannon_120mm; + class rhs_weap_2a28_base: cannon_120mm { // "Low pressure" + EGVAR(overpressure,range) = 15; + EGVAR(overpressure,damage) = 0.5; + }; + + class rhs_uniform_flora; + class rhs_uniform_df15: rhs_uniform_flora { + ACE_GForceCoef = 0.8; + }; +}; diff --git a/optionals/compat_rhs_afrf3/XEH_PREP.hpp b/addons/compat_rhs_afrf3/XEH_PREP.hpp similarity index 100% rename from optionals/compat_rhs_afrf3/XEH_PREP.hpp rename to addons/compat_rhs_afrf3/XEH_PREP.hpp diff --git a/optionals/compat_rhs_afrf3/XEH_postInit.sqf b/addons/compat_rhs_afrf3/XEH_postInit.sqf similarity index 100% rename from optionals/compat_rhs_afrf3/XEH_postInit.sqf rename to addons/compat_rhs_afrf3/XEH_postInit.sqf diff --git a/optionals/compat_rhs_afrf3/XEH_preInit.sqf b/addons/compat_rhs_afrf3/XEH_preInit.sqf similarity index 100% rename from optionals/compat_rhs_afrf3/XEH_preInit.sqf rename to addons/compat_rhs_afrf3/XEH_preInit.sqf diff --git a/addons/compat_rhs_afrf3/XEH_preStart.sqf b/addons/compat_rhs_afrf3/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_rhs_afrf3/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp new file mode 100644 index 0000000000..4fda436d18 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp @@ -0,0 +1,14 @@ +class CfgWeapons { + // Last update: RHSAFRF 0.5.6 + class rhs_acc_perst3_2dp_light; + class rhs_acc_perst3_2dp_light_h: rhs_acc_perst3_2dp_light { + baseWeapon = "rhs_acc_perst3_2dp_h"; + }; + + class acc_pointer_IR; + class rhs_acc_perst1ik: acc_pointer_IR { + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp new file mode 100644 index 0000000000..b544accac3 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_arsenal" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/script_component.hpp new file mode 100644 index 0000000000..9de14c499c --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT arsenal +#define SUBCOMPONENT_BEAUTIFIED Arsenal +#include "..\script_component.hpp" diff --git a/optionals/compat_rhs_afrf3/CfgMagazineGroups.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgMagazineGroups.hpp similarity index 100% rename from optionals/compat_rhs_afrf3/CfgMagazineGroups.hpp rename to addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgMagazineGroups.hpp diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgMagazines.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgMagazines.hpp new file mode 100644 index 0000000000..4010e550a9 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgMagazines.hpp @@ -0,0 +1,143 @@ +class CfgMagazines { + // RHS magazines for crew handled ammo + class rhs_mag_9M131M; + class GVAR(mag_9M131M): rhs_mag_9M131M { + scope = 2; + displayName = SUBCSTRING(mag_9M131M_displayName); + 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; + displayName = SUBCSTRING(mag_9M131F_displayName); + 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; + displayName = SUBCSTRING(mag_9m133_displayName); + 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; + displayName = SUBCSTRING(mag_9m133f_displayName); + 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; + displayName = SUBCSTRING(mag_9m1331_displayName); + 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; + displayName = SUBCSTRING(mag_9m133m2_displayName); + 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; + displayName = SUBCSTRING(mag_PG9V_displayName); + 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; + displayName = SUBCSTRING(mag_PG9N_displayName); + 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; + displayName = SUBCSTRING(mag_PG9VNT_displayName); + 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; + displayName = SUBCSTRING(mag_OG9VM_displayName); + 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; + displayName = SUBCSTRING(mag_OG9V_displayName); + 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_VOG30_30; + class GVAR(mag_VOG30_30): RHS_mag_VOG30_30 { + scope = 2; + displayName = SUBCSTRING(mag_VOG30_30_displayName); + 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_GPD30_30; + class GVAR(mag_GPD30_30): RHS_mag_GPD30_30 { + scope = 2; + displayName = SUBCSTRING(mag_GPD30_30_displayName); + 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; + displayName = SUBCSTRING(mag_VOG17m_30_displayName); + 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/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp new file mode 100644 index 0000000000..6a3bb0a083 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp @@ -0,0 +1,109 @@ +class CfgVehicles { + class AT_01_base_F; + class StaticMortar; + class StaticMGWeapon; + class StaticGrenadeLauncher; + + class rhs_SPG9_base: AT_01_base_F { + 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_SPG9M_base: rhs_SPG9_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + disassembleWeapon = QGVAR(spg9m_carry); + }; + }; + + class rhs_Kornet_Base: AT_01_base_F { + 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_Metis_Base: AT_01_base_F { + 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; + }; + }; + + class rhs_2b14_82mm_Base: StaticMortar { + 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 RHS_AGS30_TriPod_base: StaticGrenadeLauncher { + 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; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp new file mode 100644 index 0000000000..1e8f4dbdfd --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgWeapons.hpp @@ -0,0 +1,191 @@ +class CfgWeapons { + 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 Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + class GVAR(2b14_carry): Launcher_Base_F { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + EGVAR(csw,mortarBaseplate) = "rhs_2b14_82mm_msv"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + // One WeaponSlot with a positive value for iconScale forces game to use icon overlay method. + // Required, because the inventory icon has no accessory variants. + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,kordTripodLow) = "RHS_NSV_TriPod_MSV"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + 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 { + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,sag30Tripod) = "RHS_AGS30_TriPod_MSV"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,spg9Tripod) = "rhs_SPG9_INS"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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: ACE_CSW { + class assembleTo { + EGVAR(csw,spg9Tripod) = "rhs_SPG9M_MSV"; + }; + }; + displayName = ECSTRING(csw,spg9m_tube); + author = ECSTRING(common,ACETeam); + }; + + class GVAR(metis_carry): Launcher_Base_F { + dlc = "ace"; + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "rhs_Metis_9k115_2_msv"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "rhs_Kornet_9M133_2_msv"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/config.cpp new file mode 100644 index 0000000000..4018785e82 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {QGVAR(2b14_carry), QGVAR(nsv_carry), QGVAR(kord_carry), QGVAR(ags30_carry), QGVAR(spg9_carry), QGVAR(spg9m_carry), QGVAR(metis_carry), QGVAR(kornet_carry)}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_csw" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgMagazineGroups.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/script_component.hpp new file mode 100644 index 0000000000..77a1b484cb --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT csw +#define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons +#include "..\script_component.hpp" + +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/stringtable.xml b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/stringtable.xml new file mode 100644 index 0000000000..ba168178d9 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/stringtable.xml @@ -0,0 +1,201 @@ + + + + + [CSW] VOG-17M + [CSW] VOG-17M + [CSW] VOG-17M + [CSW] VOG-17M + [CSW] VOG-17M + [CSW] WOG-17M + [CSW] VOG-17M + [CSW] ВОГ-17М + [CSW] VOG-17M + [CSW] VOG-17M + [CSW] VOG-17M + [班组] VOG-17M + + + [CSW] VOG-30 + [CSW] VOG-30 + [CSW] VOG-30 + [CSW] VOG-30 + [CSW] VOG-30 + [CSW] WOG-30 + [CSW] VOG-30 + [CSW] ВОГ-30 + [CSW] VOG-30 + [CSW] VOG-30 + [CSW] VOG-30 + [班组] VOG-30 + + + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] ГПД-30 + [CSW] GPD-30 + [CSW] GPD-30 + [CSW] GPD-30 + [班组] GPD-30 + + + [CSW] ATGM 9M131M + [CSW] ATGM 9M131M + [CSW] ATGM 9M131M + [CSW] ATGM 9M131M + [CSW] ATGM 9M131M + [CSW] ATGM 9M131M + [CSW] ATGM 9M131M + [CSW] ПТРК 9М131М + [CSW] ATGM 9M131M + [CSW] 9M131M 대전차미사일 + [CSW] ATGM 9M131M + [班组] 9M131M 反坦克导弹 + + + [CSW] ATGM 9M131F + [CSW] ATGM 9M131F + [CSW] ATGM 9M131F + [CSW] ATGM 9M131F + [CSW] ATGM 9M131F + [CSW] ATGM 9M131F + [CSW] ATGM 9M131F + [CSW] ПТРК 9М131Ф + [CSW] ATGM 9M131F + [CSW] 9M131F 대전차미사일 + [CSW] ATGM 9M131F + [班组] 9M131F 反坦克导弹 + + + [CSW] ATGM 9M133F + [CSW] ATGM 9M133F + [CSW] ATGM 9M133F + [CSW] ATGM 9M133F + [CSW] ATGM 9M133F + [CSW] ATGM 9M133F + [CSW] ATGM 9M133F + [CSW] ПТРК 9М133Ф + [CSW] ATGM 9M133F + [CSW] 9M133F 대전차미사일 + [CSW] ATGM 9M133F + [班组] 9M133F 反坦克导弹 + + + [CSW] ATGM 9M133 + [CSW] ATGM 9M133 + [CSW] ATGM 9M133 + [CSW] ATGM 9M133 + [CSW] ATGM 9M133 + [CSW] ATGM 9M133 + [CSW] ATGM 9M133 + [CSW] ПТРК 9М133 + [CSW] ATGM 9M133 + [CSW] 9M133 대전차미사일 + [CSW] ATGM 9M133 + [班组] 9M133 反坦克导弹 + + + [CSW] ATGM 9M133-1 + [CSW] ATGM 9M133-1 + [CSW] ATGM 9M133-1 + [CSW] ATGM 9M133-1 + [CSW] ATGM 9M133-1 + [CSW] ATGM 9M133-1 + [CSW] ATGM 9M133-1 + [CSW] ПТРК 9М133-1 + [CSW] ATGM 9M133-1 + [CSW] 9M133-1 대전차미사일 + [CSW] ATGM 9M133-1 + [班组] 9M133-1 反坦克导弹 + + + [CSW] ATGM 9M133M2 + [CSW] ATGM 9M133M2 + [CSW] ATGM 9M133M2 + [CSW] ATGM 9M133M2 + [CSW] ATGM 9M133M2 + [CSW] ATGM 9M133M2 + [CSW] ATGM 9M133M2 + [CSW] ПТРК 9М133M2 + [CSW] ATGM 9M133M2 + [CSW] 9M133M2 대전차미사일 + [CSW] ATGM 9M133M2 + [班组] 9M133M2 反坦克导弹 + + + [CSW] HEAT PG-9V + [CSW] HEAT PG-9V + [CSW] HEAT PG-9V + [CSW] AEAT PG-9V + [CSW] HEAT PG-9V + [CSW] HEAT PG-9V + [CSW] HEAT PG-9V + [CSW] ПГ-9В + [CSW] HEAT PG-9V + [CSW] PG-9V 대전차고폭탄 + [CSW] HEAT PG-9V + [班组] PG-9V 破甲弹 + + + [CSW] HEAT PG-9N + [CSW] HEAT PG-9N + [CSW] HEAT PG-9N + [CSW] AEAT PG-9N + [CSW] HEAT PG-9N + [CSW] HEAT PG-9N + [CSW] HEAT PG-9N + [CSW] ПГ-9Н + [CSW] HEAT PG-9N + [CSW] PG-9N 대전차고폭탄 + [CSW] HEAT PG-9N + [班组] PG-9N 破甲弹 + + + [CSW] HEAT PG-9VNT + [CSW] HEAT PG-9VNT + [CSW] HEAT PG-9VNT + [CSW] AEAT PG-9VNT + [CSW] HEAT PG-9VNT + [CSW] HEAT PG-9VNT + [CSW] HEAT PG-9VNT + [CSW] ПГ-9ВНТ + [CSW] HEAT PG-9VNT + [CSW] PG-9VNT 대전차고폭탄 + [CSW] HEAT PG-9VNT + [班组] PG-9VN 破甲弹 + + + [CSW] HE-FRAG OG-9V + [CSW] HE-FRAG OG-9V + [CSW] HE-FRAG OG-9V + [CSW] AE-FRAG OG-9V + [CSW] HE-FRAG OG-9V + [CSW] HE-FRAG OG-9V + [CSW] HE-FRAG OG-9V + [CSW] ОГ-9В + [CSW] HE-FRAG OG-9V + [CSW] OG-9V 고폭파편탄 + [CSW] HE-FRAG OG-9V + [班组] OG-9V 高爆破片弹 + + + [CSW] HE-FRAG OG-9VM + [CSW] HE-FRAG OG-9VM + [CSW] HE-FRAG OG-9VM + [CSW] AE-FRAG OG-9VM + [CSW] HE-FRAG OG-9VM + [CSW] HE-FRAG OG-9VM + [CSW] HE-FRAG OG-9VM + [CSW] ОГ-9ВМ + [CSW] HE-FRAG OG-9VM + [CSW] OG-9VM 고폭파편탄 + [CSW] HE-FRAG OG-9VM + [班组] OG-9VM 高爆破片弹 + + + diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgAmmo.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..fd994e3f99 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgAmmo.hpp @@ -0,0 +1,50 @@ +class CfgAmmo { + // ACE Explosives + class MineBase; + class rhs_mine_tm62m_ammo: MineBase { + EGVAR(explosives,defuseObjectPosition)[] = {-0.005, 0.025, 0.06}; + }; + + class rhs_mine_pmn2_ammo: MineBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.012}; + }; + + class ATMine_Range_Ammo; + class rhs_ammo_ptm1: ATMine_Range_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.17, 0.02}; + }; + + class APERSMine_Range_Ammo; + class rhs_ammo_pfm1: APERSMine_Range_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0.015, -0.018, 0}; + }; + + class PipeBombBase; + class rhs_ec75_ammo: PipeBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.04, 0.02}; + }; + + class rhs_ec200_ammo: rhs_ec75_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.05, 0.008}; + }; + + class rhs_ec400_ammo: rhs_ec75_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.03, 0.02}; + }; + + class rhs_mine_msk40p_white_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0.025, 0, 0.4}; + }; + + class rhs_mine_sm320_white_ammo: rhs_mine_msk40p_white_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0.01, 0, 0.25}; + }; + + class rhs_mine_ozm72_a_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, -0.125, 0.11}; + }; + + class rhs_mine_ozm72_c_ammo: rhs_mine_ozm72_a_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, -0.015, 0.12}; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..4f8e808bd5 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgMagazines.hpp @@ -0,0 +1,147 @@ +class CfgMagazines { + // ACE Explosives + class ATMine_Range_Mag; + class rhs_mine_tm62m_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_tm62m); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.09; + }; + }; + }; + + class rhs_mine_pmn2_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_pmn2); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.02; + }; + }; + }; + + class rhs_mag_mine_ptm1: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_ptm1); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.04; + }; + }; + }; + + class rhs_mag_mine_pfm1: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_pfm1); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.02; + }; + }; + }; + + class rhs_ec75_mag: ATMine_Range_Mag { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec75); + 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 rhs_ec75_sand_mag: rhs_ec75_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec75_sand); + }; + + class rhs_ec200_mag: rhs_ec75_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec200); + }; + + class rhs_ec200_sand_mag: rhs_ec200_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec200_sand); + }; + + class rhs_ec400_mag: rhs_ec75_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec400); + }; + + class rhs_ec400_sand_mag: rhs_ec400_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_ec400_sand); + }; + + class rhs_mine_msk40p_white_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_msk40p_white); + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.07; + }; + }; + }; + + class rhs_mine_msk40p_red_mag: rhs_mine_msk40p_white_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_msk40p_red); + }; + + class rhs_mine_msk40p_green_mag: rhs_mine_msk40p_white_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_msk40p_green); + }; + + class rhs_mine_msk40p_blue_mag: rhs_mine_msk40p_white_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_msk40p_blue); + }; + + class rhs_mine_sm320_white_mag: rhs_mine_msk40p_white_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_sm320_white); + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.05; + }; + }; + }; + + class rhs_mine_sm320_red_mag: rhs_mine_sm320_white_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_sm320_red); + }; + + class rhs_mine_sm320_green_mag: rhs_mine_sm320_white_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_sm320_green); + }; + + class rhs_mine_ozm72_a_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_ozm72_a); + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.04; + }; + }; + }; + + class rhs_mine_ozm72_b_mag: rhs_mine_ozm72_a_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_ozm72_b); + }; + + class rhs_mine_ozm72_c_mag: rhs_mine_ozm72_a_mag { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhs_mine_ozm72_c); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..8e874d8d11 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/CfgVehicles.hpp @@ -0,0 +1,164 @@ +class CfgVehicles { + // ACE Explosives + class Items_base_F; + class EGVAR(explosives,Place): Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_tm62m): EGVAR(explosives,Place) { + displayName = "$STR_RHS_CFGMAGAZINES_TM62M0"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_tm62m"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.005, -0.025, 0.06]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_pmn2): EGVAR(explosives,Place) { + displayName = "$STR_RHS_CFGMAGAZINES_PMN20"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_pmn2"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.012]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_ptm1): EGVAR(explosives,Place) { + displayName = "$STR_RHS_PTM1_NAME"; + model = "\rhsafrf\addons\rhs_airweapons\rhs_m_ptm1_d"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, -0.17, 0.02]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_pfm1): EGVAR(explosives,Place) { + displayName = "$STR_RHS_PFM1_NAME"; + model = "\rhsafrf\addons\rhs_airweapons\rhs_m_pfm1_d"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.015, 0.018, 0]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_ec75): EGVAR(explosives,Place) { + displayName = "$STR_RHS_CFGMAGAZINES_EC75"; + model = "\rhsafrf\addons\rhs_weapons2\explosives\rhs_ec75_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, -0.04, 0.02]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_ec75_sand): EGVAR(explosives,Place_rhs_ec75) { + displayName = "$STR_RHS_CFGMAGAZINES_EC75_SAND"; + model = "\rhsafrf\addons\rhs_weapons2\explosives\rhs_ec75_sand_e"; + }; + + class EGVAR(explosives,Place_rhs_ec200): EGVAR(explosives,Place) { + displayName = "$STR_RHS_CFGMAGAZINES_EC200"; + model = "\rhsafrf\addons\rhs_weapons2\explosives\rhs_ec200_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, -0.05, 0.008]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_ec200_sand): EGVAR(explosives,Place_rhs_ec200) { + displayName = "$STR_RHS_CFGMAGAZINES_EC200_SAND"; + model = "\rhsafrf\addons\rhs_weapons2\explosives\rhs_ec200_sand_e"; + }; + + class EGVAR(explosives,Place_rhs_ec400): EGVAR(explosives,Place) { + displayName = "$STR_RHS_CFGMAGAZINES_EC400"; + model = "\rhsafrf\addons\rhs_weapons2\explosives\rhs_ec400_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, -0.03, 0.02]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_ec400_sand): EGVAR(explosives,Place_rhs_ec400) { + displayName = "$STR_RHS_CFGMAGAZINES_EC400_SAND"; + model = "\rhsafrf\addons\rhs_weapons2\explosives\rhs_ec400_sand_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_msk40p_white): EGVAR(explosives,Place) { + displayName = "$STR_RHS_MINE_MSK40P_W_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_msk40p_white_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.025, 0, 0.4]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_msk40p_red): EGVAR(explosives,Place_rhs_mine_msk40p_white) { + displayName = "$STR_RHS_MINE_MSK40P_R_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_msk40p_red_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_msk40p_green): EGVAR(explosives,Place_rhs_mine_msk40p_white) { + displayName = "$STR_RHS_MINE_MSK40P_G_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_msk40p_green_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_msk40p_blue): EGVAR(explosives,Place_rhs_mine_msk40p_white) { + displayName = "$STR_RHS_MINE_MSK40P_B_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_msk40p_blue_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_sm320_white): EGVAR(explosives,Place) { + displayName = "$STR_RHS_MINE_SM320_W_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_sm320_white_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.01, 0, 0.25]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_sm320_red): EGVAR(explosives,Place_rhs_mine_sm320_white) { + displayName = "$STR_RHS_MINE_SM320_R_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_sm320_red_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_sm320_green): EGVAR(explosives,Place_rhs_mine_sm320_white) { + displayName = "$STR_RHS_MINE_SM320_G_MAG_DISPLAYNAME"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_sm320_green_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_ozm72_a): EGVAR(explosives,Place) { + displayName = "$STR_RHS_CFGMAGAZINES_OZM72A"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_ozm72_a_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0.125, 0.11]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhs_mine_ozm72_b): EGVAR(explosives,Place_rhs_mine_ozm72_a) { + displayName = "$STR_RHS_CFGMAGAZINES_OZM72B"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_ozm72_b_e"; + }; + + class EGVAR(explosives,Place_rhs_mine_ozm72_c): EGVAR(explosives,Place_rhs_mine_ozm72_a) { + displayName = "$STR_RHS_CFGMAGAZINES_OZM72C"; + model = "\rhsafrf\addons\rhs_weapons\mines\rhs_ozm72_c_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0.015, 0.12]"; + }; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/config.cpp new file mode 100644 index 0000000000..c0861a5872 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/CfgVehicles.hpp new file mode 100644 index 0000000000..8b8e76f29c --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/CfgVehicles.hpp @@ -0,0 +1,65 @@ +class CfgVehicles { + class Air; + class Helicopter: Air {}; + class Helicopter_Base_F: Helicopter {}; + class Helicopter_Base_H: Helicopter_Base_F { + class EventHandlers; + }; + class Heli_Light_02_base_F: Helicopter_Base_H {}; + class RHS_Mi8_base: Heli_Light_02_base_F { + EGVAR(fastroping,enabled) = 0; + class EventHandlers: EventHandlers { + class RHS_EventHandlers; + }; + }; + + class RHS_Mi8amt_base: RHS_Mi8_base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{-1.13, 4.67, -0.89}}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_arf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_arf3,onPrepare); + class UserActions { + class openDoor; + class closeDoor_L: openDoor { + condition = QUOTE((this doorPhase 'LeftDoor' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + }; + }; + + class EventHandlers: EventHandlers { + class RHS_EventHandlers: RHS_EventHandlers { + getOut = QUOTE(if !((_this select 0) getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)]) then {_this call rhs_fnc_mi8_doors}); + }; + }; + }; + + class RHS_Mi8_VVS_Base: RHS_Mi8_base {}; + class RHS_Mi8mt_vvs: RHS_Mi8_VVS_Base {}; + class RHS_Mi8mt_Cargo_vvs: RHS_Mi8mt_vvs { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{-1.13, 4.67, -0.89}}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_arf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_arf3,onPrepare); + + class UserActions { + class openDoor_L; + class closeDoor_L: openDoor_L { + condition = QUOTE((this doorPhase 'LeftDoor' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + }; + }; + + class EventHandlers: EventHandlers { + class RHS_EventHandlers: RHS_EventHandlers { + getOut = QUOTE(if !((_this select 0) getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)]) then {_this call rhs_fnc_mi8_doors}); + }; + }; + }; + + class Heli_Attack_02_base_F: Helicopter_Base_F {}; + class RHS_Ka52_base: Heli_Attack_02_base_F { + EGVAR(fastroping,enabled) = 0; + }; + + class RHS_Mi24_base: Heli_Attack_02_base_F { + EGVAR(fastroping,enabled) = 0; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/config.cpp new file mode 100644 index 0000000000..8809558aa6 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_fastroping" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/script_component.hpp new file mode 100644 index 0000000000..77632a2484 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_fastroping/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT fastroping +#define SUBCOMPONENT_BEAUTIFIED Fastroping +#include "..\script_component.hpp" + +#include "\z\ace\addons\fastroping\script_macros.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/CfgWeapons.hpp new file mode 100644 index 0000000000..6720519685 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/CfgWeapons.hpp @@ -0,0 +1,8 @@ +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; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/config.cpp new file mode 100644 index 0000000000..4a349ababe --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_nightvision" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/script_component.hpp new file mode 100644 index 0000000000..14bc3772cc --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_nightvision/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nightvision +#define SUBCOMPONENT_BEUTIFIEID Night Vision +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp new file mode 100644 index 0000000000..8e1986b65f --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_refuel" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +// ADDON kept for backward compatiblity diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/script_component.hpp new file mode 100644 index 0000000000..b58db9432d --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED Refuel +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/CfgWeapons.hpp new file mode 100644 index 0000000000..c6666f0192 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/CfgWeapons.hpp @@ -0,0 +1,34 @@ +class CfgWeapons { + class rhs_acc_sniper_base; + class rhs_acc_pso1m2: rhs_acc_sniper_base { + ACE_ScopeHeightAboveRail = 4.41386; + ACE_ScopeAdjust_Vertical[] = {0, 0}; + ACE_ScopeAdjust_Horizontal[] = {-10, 10}; + ACE_ScopeAdjust_VerticalIncrement = 0.5; + ACE_ScopeAdjust_HorizontalIncrement = 0.5; + }; + class rhs_acc_pso1m21: rhs_acc_pso1m2 { + ACE_ScopeHeightAboveRail = 7.75566; + ACE_ScopeAdjust_Vertical[] = {0, 0}; + ACE_ScopeAdjust_Horizontal[] = {-10, 10}; + ACE_ScopeAdjust_VerticalIncrement = 0.5; + ACE_ScopeAdjust_HorizontalIncrement = 0.5; + }; + class ItemCore; + class InventoryOpticsItem_Base_F; + class rhs_acc_dh520x56: ItemCore { // http://nightvision.ru/catalog/4/item/35 + ACE_ScopeHeightAboveRail = 4.71476; + ACE_ScopeAdjust_Vertical[] = {0, 33}; + ACE_ScopeAdjust_Horizontal[] = {-9, 9}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class dedal_520 { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/config.cpp new file mode 100644 index 0000000000..6ca402478f --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_scopes" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/script_component.hpp new file mode 100644 index 0000000000..613b4322f9 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_scopes/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT scopes +#define SUBCOMPONENT_BEAUTIFIED Scopes +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/config.cpp b/addons/compat_rhs_afrf3/config.cpp new file mode 100644 index 0000000000..44fcd30fcb --- /dev/null +++ b/addons/compat_rhs_afrf3/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"rhs_main_loadorder"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; + url = ECSTRING(main,URL); + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_afrf3/functions/fnc_onCut.sqf b/addons/compat_rhs_afrf3/functions/fnc_onCut.sqf new file mode 100644 index 0000000000..4acb91ae0a --- /dev/null +++ b/addons/compat_rhs_afrf3/functions/fnc_onCut.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Function for closing doors and retracting the hooks for RHS USF helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_rhs_afrf3_fnc_onCut + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable [QEGVAR(fastroping,doorsLocked), false, true]; +_vehicle animateDoor ["LeftDoor", 0]; + +2 diff --git a/addons/compat_rhs_afrf3/functions/fnc_onPrepare.sqf b/addons/compat_rhs_afrf3/functions/fnc_onPrepare.sqf new file mode 100644 index 0000000000..2a11bbd779 --- /dev/null +++ b/addons/compat_rhs_afrf3/functions/fnc_onPrepare.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Function for opening doors and extending the hook for most vanilla helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_rhs_afrf3_fnc_onPrepare + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable [QEGVAR(fastroping,doorsLocked), true, true]; +_vehicle animateDoor ["LeftDoor", 1]; + +2 diff --git a/addons/compat_rhs_afrf3/script_component.hpp b/addons/compat_rhs_afrf3/script_component.hpp new file mode 100644 index 0000000000..58681cf6a0 --- /dev/null +++ b/addons/compat_rhs_afrf3/script_component.hpp @@ -0,0 +1,10 @@ +#define COMPONENT compat_rhs_afrf3 +#define COMPONENT_BEAUTIFIED RHS AFRF Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" + +// Backwards compatibility +#undef GVAR +#define GVAR(var) TRIPLES(PREFIX,COMPONENT,var) diff --git a/optionals/compat_rhs_gref3/$PBOPREFIX$ b/addons/compat_rhs_gref3/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rhs_gref3/$PBOPREFIX$ rename to addons/compat_rhs_gref3/$PBOPREFIX$ diff --git a/addons/compat_rhs_gref3/CfgAmmo.hpp b/addons/compat_rhs_gref3/CfgAmmo.hpp new file mode 100644 index 0000000000..566f7c87fe --- /dev/null +++ b/addons/compat_rhs_gref3/CfgAmmo.hpp @@ -0,0 +1,44 @@ +class CfgAmmo { + class GrenadeHand; + class rhsgref_ammo_rkg3em: GrenadeHand { // Scripted shaped charge + ace_frag_force = 0; + }; + + class BulletBase; + class rhs_ammo_762x25_Ball: BulletBase { + ACE_caliber = 7.874; + ACE_bulletLength = 13.856; + ACE_bulletMass = 5.5728; + 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.17}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {360, 380, 400}; + ACE_barrelLengths[] = {101.6, 152.4, 228.6}; + }; + + class rhs_ammo_792x57_Ball: BulletBase { + ACE_caliber = 8.077; + ACE_bulletLength = 28.651; + ACE_bulletMass = 12.7008; + 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.315}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {785, 800, 815}; + ACE_barrelLengths[] = {508.0, 599.948, 660.4}; + }; + + class rhs_ammo_3bk12_penetrator; + class rhsgref_ammo_rkg3em_penetrator: rhs_ammo_3bk12_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_rpg75_penetrator: rhs_ammo_3bk12_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_panzerfaust60_penetrator: rhs_ammo_3bk12_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; +}; diff --git a/addons/compat_rhs_gref3/CfgEventHandlers.hpp b/addons/compat_rhs_gref3/CfgEventHandlers.hpp new file mode 100644 index 0000000000..865276cfba --- /dev/null +++ b/addons/compat_rhs_gref3/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; diff --git a/optionals/compat_rhs_gref3/CfgMagazines.hpp b/addons/compat_rhs_gref3/CfgMagazines.hpp similarity index 100% rename from optionals/compat_rhs_gref3/CfgMagazines.hpp rename to addons/compat_rhs_gref3/CfgMagazines.hpp diff --git a/addons/compat_rhs_gref3/CfgVehicles.hpp b/addons/compat_rhs_gref3/CfgVehicles.hpp new file mode 100644 index 0000000000..89692c8300 --- /dev/null +++ b/addons/compat_rhs_gref3/CfgVehicles.hpp @@ -0,0 +1,18 @@ +class CfgVehicles { + class Rubber_duck_base_F; + class rhsgref_canoe_base: Rubber_duck_base_F { + // Canoes are propelled by paddlers + EGVAR(refuel,canReceive) = 0; + }; + + class Wheeled_APC_F; + class rhsgref_BRDM2: Wheeled_APC_F { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0.2; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0.7; + GVAR(engineFireProb) = 0.7; + GVAR(detonationDuringFireProb) = 0.5; + }; +}; diff --git a/addons/compat_rhs_gref3/CfgWeapons.hpp b/addons/compat_rhs_gref3/CfgWeapons.hpp new file mode 100644 index 0000000000..68c2c08d06 --- /dev/null +++ b/addons/compat_rhs_gref3/CfgWeapons.hpp @@ -0,0 +1,134 @@ +class CfgWeapons { + + // ACE Ballistics + class rhs_weap_kar98k_Base_F; + class rhs_weap_kar98k: rhs_weap_kar98k_Base_F { + ACE_barrelTwist = 240; + ACE_barrelLength = 600; + }; + + class rhs_weap_m38_Base_F; + class rhs_weap_m38: rhs_weap_m38_Base_F { + ACE_barrelTwist = 250; + ACE_barrelLength = 315; + }; + + class rhs_weap_m38_rail; + class rhs_weap_mosin_sbr: rhs_weap_m38_rail { + ACE_barrelTwist = 240; + ACE_barrelLength = 254; + }; + + class rhs_weap_m70_base; + class rhs_weap_m70ab2: rhs_weap_m70_base { + ACE_barrelTwist = 240; + ACE_barrelLength = 415; + }; + + class rhs_weap_m92: rhs_weap_m70_base { + ACE_barrelTwist = 240; + ACE_barrelLength = 254; + }; + + class rhs_weap_m76: rhs_weap_m70_base { + ACE_barrelTwist = 250; + ACE_barrelLength = 200; + }; + + class rhs_weap_m21_base: rhs_weap_m70_base { + ACE_barrelLength = 460; + ACE_barrelTwist = 177.8; + }; + + class rhs_weap_m21s: rhs_weap_m21_base { + ACE_barrelLength = 375; + }; + + class rhs_weap_m21a_pr; + class rhs_weap_m21s_pr: rhs_weap_m21a_pr { + ACE_barrelLength = 375; + }; + + class Rifle_Base_F; + class rhs_weap_savz58_base: Rifle_Base_F { + ACE_barrelTwist = 240; + ACE_barrelLength = 390; + }; + + class rhs_weap_stgw57_base; + class rhs_weap_stgw57: rhs_weap_stgw57_base { + ACE_barrelTwist = 270; + ACE_barrelLength = 583; + }; + + class rhs_weap_vhs2_base; + class rhs_weap_vhsd2: rhs_weap_vhs2_base { + ACE_barrelTwist = 177.8; + ACE_barrelLength = 500.0; + }; + + class rhs_weap_vhsk2: rhs_weap_vhsd2 { + ACE_barrelTwist = 177.8; + ACE_barrelLength = 410.0; + }; + class rhs_weap_vhsd2_ct15x: rhs_weap_vhs2_base { + ACE_barrelTwist = 177.8; + ACE_barrelLength = 500.0; + }; + class rhs_weap_vhsd2_bg: rhs_weap_vhs2_base { + ACE_barrelTwist = 177.8; + ACE_barrelLength = 500.0; + }; + + class rhs_weap_fnfal_base; + class rhs_weap_l1a1_base: rhs_weap_fnfal_base { + ACE_barrelTwist = 302.26; + ACE_barrelLength = 554.4; + }; + + class rhs_weap_mg42_base: Rifle_Base_F { + EGVAR(overheating,closedBolt) = 0; + EGVAR(overheating,allowSwapBarrel) = 1; + ACE_barrelTwist = 305.0; + ACE_barrelLength = 530.0; + }; + + class rhs_weap_MP44_base: Rifle_Base_F { + ACE_barrelTwist = 240.0; + ACE_barrelLength = 420.0; + }; + + class rhs_weap_m3a1_base: Rifle_Base_F { + ACE_barrelTwist = 406.0; + ACE_barrelLength = 203.2; + }; + + class rhs_weap_M1garand_Base_F: Rifle_Base_F { + ACE_barrelTwist = 254.0; + ACE_barrelLength = 610.0; + }; + + class rhs_weap_Izh18: Rifle_Base_F { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + + class rhs_weap_m79: Rifle_Base_F { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + class rhs_weap_panzerfaust60: Launcher_Base_F { + EGVAR(overpressure,range) = 6; + EGVAR(overpressure,angle) = 30; + EGVAR(overpressure,damage) = 0.4; + }; + + class rhs_weap_rpg75: Launcher_Base_F { + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,offset) = 0.9; + }; +}; diff --git a/optionals/compat_rhs_usf3/XEH_PREP.hpp b/addons/compat_rhs_gref3/XEH_PREP.hpp similarity index 100% rename from optionals/compat_rhs_usf3/XEH_PREP.hpp rename to addons/compat_rhs_gref3/XEH_PREP.hpp diff --git a/optionals/compat_rhs_usf3/XEH_preInit.sqf b/addons/compat_rhs_gref3/XEH_preInit.sqf similarity index 100% rename from optionals/compat_rhs_usf3/XEH_preInit.sqf rename to addons/compat_rhs_gref3/XEH_preInit.sqf diff --git a/addons/compat_rhs_gref3/XEH_preStart.sqf b/addons/compat_rhs_gref3/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_rhs_gref3/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp new file mode 100644 index 0000000000..7e58387dab --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp @@ -0,0 +1,21 @@ +class CfgVehicles { + class StaticMGWeapon; + class rhs_DSHKM_base: StaticMGWeapon { + 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/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgWeapons.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgWeapons.hpp new file mode 100644 index 0000000000..15ff9488ca --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgWeapons.hpp @@ -0,0 +1,34 @@ +class CfgWeapons { + 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 { + // One WeaponSlot with a positive value for iconScale forces game to use icon overlay method. + // Required, because the inventory icon has no accessory variants. + class MuzzleSlot { + iconScale = 0.1; + }; + 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/addons/compat_rhs_gref3/compat_rhs_gref3_csw/config.cpp b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/config.cpp new file mode 100644 index 0000000000..2628bffcd5 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {QGVAR(dshkm_carry)}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsgref_main_loadorder", + "ace_csw" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/script_component.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/script_component.hpp new file mode 100644 index 0000000000..77a1b484cb --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT csw +#define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons +#include "..\script_component.hpp" + +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..0808c7ff1d --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgAmmo.hpp @@ -0,0 +1,83 @@ +class CfgAmmo { + class APERSMine_Range_Ammo; + class rhs_mine_a200_bz_ammo: APERSMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.035}; + }; + + class rhs_mine_a200_dz35_ammo: rhs_mine_a200_bz_ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.02}; + }; + + class rhs_mine_glasmine43_hz_ammo: APERSMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.015}; + }; + + class rhs_mine_glasmine43_bz_ammo: rhs_mine_glasmine43_hz_ammo { + ace_minedetector_detectable = 0; + }; + + class rhs_mine_bounding_trigger_base; + class rhs_mine_m2a3b_press_ammo: rhs_mine_bounding_trigger_base { + ace_explosives_defuseObjectPosition[] = {0, 0.046, 0.02}; + }; + + class rhs_mine_m2a3b_trip_ammo: rhs_mine_m2a3b_press_ammo { + ace_explosives_defuseObjectPosition[] = {0, 0.046, 0.055}; + }; + + class rhs_mine_M3_pressure_ammo: APERSMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.015}; + }; + + class rhs_mine_M3_tripwire_ammo: rhs_mine_M3_pressure_ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.055}; + }; + + class ATMine_Range_Ammo; + class rhs_mine_TM43_ammo: ATMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.072}; + }; + + class rhs_mine_M7A2_ammo: APERSMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.067}; + }; + + class rhs_mine_Mk2_pressure_ammo: APERSMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.02}; + }; + + class rhs_mine_Mk2_tripwire_ammo: rhs_mine_Mk2_pressure_ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.055}; + }; + + class APERSBoundingMine_Range_Ammo; + class rhs_mine_smine35_press_ammo: APERSBoundingMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.03}; + }; + + class rhs_mine_smine35_trip_ammo: rhs_mine_bounding_trigger_base { + ace_explosives_defuseObjectPosition[] = {0, 0, 0.04}; + }; + + class rhs_mine_smine44_trip_ammo: rhs_mine_smine35_trip_ammo { + ace_explosives_defuseObjectPosition[] = {-0.03, 0, 0.015}; + }; + + class rhs_mine_smine44_press_ammo: APERSBoundingMine_Range_Ammo { + ace_explosives_defuseObjectPosition[] = {-0.02, 0, 0.02}; + }; + + class APERSTripMine_Wire_Ammo; + class rhs_mine_stockmine43_2m_ammo: APERSTripMine_Wire_Ammo { + ace_explosives_defuseObjectPosition[] = {-1, 0, 0.25}; + }; + + class rhs_mine_stockmine43_4m_ammo: rhs_mine_stockmine43_2m_ammo { + ace_explosives_defuseObjectPosition[] = {-2, 0, 0.25}; + }; + + class DemoCharge_Remote_Ammo; + class rhs_charge_M2tet_x2_ammo: DemoCharge_Remote_Ammo { + ace_explosives_defuseObjectPosition[] = {0.095, 0, 0.055}; + }; +}; diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgMagazines.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..ce882e1825 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgMagazines.hpp @@ -0,0 +1,195 @@ +class CfgMagazines { + class APERSMine_Range_Mag; + class rhs_mine_a200_bz_mag: APERSMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_a200_bz"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.05; + }; + }; + }; + + class rhs_mine_a200_dz35_mag: rhs_mine_a200_bz_mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_a200_dz35"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.04; + }; + }; + }; + + class rhs_mine_glasmine43_hz_mag: APERSMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_glasmine43_hz"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.01; + }; + }; + }; + + class rhs_mine_glasmine43_bz_mag: rhs_mine_glasmine43_hz_mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_glasmine43_bz"; + }; + + class APERSBoundingMine_Range_Mag; + class rhs_mine_m2a3b_press_mag: APERSBoundingMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_m2a3b_press"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.185; + }; + }; + }; + + class rhs_mine_m2a3b_trip_mag: rhs_mine_m2a3b_press_mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_m2a3b_trip"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.13; + }; + }; + }; + + class rhs_mine_m3_pressure_mag: APERSMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_m3_pressure"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = -0.015; + }; + }; + }; + + class APERSTripMine_Wire_Mag; + class rhs_mine_M3_tripwire_mag: APERSTripMine_Wire_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_M3_tripwire"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0; + }; + }; + }; + + class ATMine_Range_Mag; + class rhs_mine_TM43_mag: ATMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_TM43"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.057; + }; + }; + }; + + class rhs_mine_M7A2_mag: APERSMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_M7A2"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.062; + }; + }; + }; + + class rhs_mine_mk2_pressure_mag: APERSMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_mk2_pressure"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; + }; + + class rhs_mine_Mk2_tripwire_mag: APERSTripMine_Wire_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_Mk2_tripwire"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0; + }; + }; + }; + + class rhs_mine_smine35_press_mag: APERSBoundingMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine35_press"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.18; + }; + }; + }; + + class rhs_mine_smine35_trip_mag: rhs_mine_smine35_press_mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine35_trip"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0; + }; + }; + }; + + class rhs_mine_smine44_trip_mag: APERSBoundingMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine44_trip"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0; + }; + }; + }; + + class rhs_mine_smine44_press_mag: rhs_mine_smine44_trip_mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_smine44_press"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.175; + }; + }; + }; + + class rhs_mine_stockmine43_2m_mag: APERSTripMine_Wire_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_stockmine43_2m"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.25; + }; + }; + }; + + class rhs_mine_stockmine43_4m_mag: rhs_mine_stockmine43_2m_mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_stockmine43_4m"; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.25; + }; + }; + }; + + class DemoCharge_Remote_Mag; + class rhs_charge_M2tet_x2_mag: DemoCharge_Remote_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_charge_M2tet_x2"; + 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 {}; + }; + }; +}; diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgVehicles.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..9e68a4a524 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/CfgVehicles.hpp @@ -0,0 +1,193 @@ +class CfgVehicles { + class Items_base_F; + class ACE_Explosives_Place: Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class ACE_Explosives_Place_rhs_mine_a200_bz: ACE_Explosives_Place { + displayName = "Beh.Schu.Mi.A200 (B.Z.) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\A200\A200_BZ_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.095]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_a200_dz35: ACE_Explosives_Place_rhs_mine_a200_bz { + displayName = "Beh.Schu.Mi.A200 (D.Z.35) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\A200\A200_DZ35_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.125]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_glasmine43_hz: ACE_Explosives_Place { + displayName = "Gl.Mi.43 (H.Z.44) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Glasmine43\GLMI43_HZ_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.105]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_glasmine43_bz: ACE_Explosives_Place_rhs_mine_glasmine43_hz { + displayName = "Gl.Mi.43 (B.Z.) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Glasmine43\GLMI43_BZ_ITEM"; + }; + + class ACE_Explosives_Place_rhs_mine_m2a3b_press: ACE_Explosives_Place { + displayName = "M2A3B APB Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M2A3B\M2A3_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.052, 0, 0.225]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_m2a3b_trip: ACE_Explosives_Place_rhs_mine_m2a3b_press { + displayName = "M2A3B (Tripwire) APB Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M2A3B\M2A3_HELPER_TRIPWIRE"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, -0.046, 0.06]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_m3_pressure: ACE_Explosives_Place { + displayName = "M3 AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M3\M3_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.23]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_M3_tripwire: ACE_Explosives_Place_rhs_mine_m3_pressure { + displayName = "M3 (Tripwire) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M3\M6M7FUZE_HELPER_TRIPWIRE"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.055]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_TM43: ACE_Explosives_Place { + displayName = "Tellermine 43"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\TM43\TM43"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.072]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_M7A2: ACE_Explosives_Place { + displayName = "M7A2 AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M7A2\M7A2_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.066]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_mk2_pressure: ACE_Explosives_Place { + displayName = "Mk 2 AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\MKII_BOOBYTRAP\MKII_TRAP_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.09, 0, 0.011]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_Mk2_tripwire: ACE_Explosives_Place { + displayName = "Mk 2 (Tripwire) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M3\M6M7FUZE_HELPER_TRIPWIRE"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.055]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_smine35_press: ACE_Explosives_Place { + displayName = "S.Mi.35 (S.Mi.Z.35) APB Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Smine35\SMI35_ITEM_PRESS"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.217]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_smine35_trip: ACE_Explosives_Place { + displayName = "S.Mi.35 (W) APB Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Smine35\SMI35_HELPER_TRIP"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.02]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_smine44_trip: ACE_Explosives_Place { + displayName = "S.Mi.44 (W) APB Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Smine44\SMI44_HELPER_TRIP"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.03, 0, 0.015]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_smine44_press: ACE_Explosives_Place { + displayName = "S.Mi.44 (S.Mi.Z.44) APB Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Smine44\SMI44_ITEM_PRESS"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.02, 0, 0.21]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_stockmine43_2m: ACE_Explosives_Place { + displayName = "St.Mi.43/I (2m) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Stockmine43\STMI43_HELPER_2M"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[1, 0, 0.25]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_stockmine43_4m: ACE_Explosives_Place { + displayName = "St.Mi.43/II (4m) AP Mine"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\Stockmine43\STMI43_HELPER_4M"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[2, 0, 0.25]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_charge_M2tet_x2: ACE_Explosives_Place { + displayName = "Tetrytol Charge (2.5lb Placed)"; + model = "\rhsgref\addons\rhsgref_weapons2\mines\M2_TETRYTOL_x2\M2TET_x2_ITEM"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.125, 0, 0.055]"; + }; + }; + }; +}; diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/config.cpp b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/config.cpp new file mode 100644 index 0000000000..e1e71ebbfa --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsgref_main_loadorder", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/script_component.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/CfgVehicles.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/CfgVehicles.hpp new file mode 100644 index 0000000000..39bda1b8b6 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/CfgVehicles.hpp @@ -0,0 +1,59 @@ +class CfgVehicles { + class Helicopter_Base_H; + class rhs_uh1h_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesAnchorBar"; + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.95, -0.26}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_gref3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_gref3,onPrepare); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + + class rhs_uh1h_hidf: rhs_uh1h_base { + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; + + class rhs_uh1h_hidf_unarmed: rhs_uh1h_hidf { + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.8, -0.27}; + class UserActions { + class Open_Side_Doors; + + class Close_Side_Doors: Open_Side_Doors { + condition = QUOTE([ARR_2(this,'close_cargo_doors')] call EFUNC(compat_rhs_gref3,canCloseDoor)); + }; + }; + + class Attributes: Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; + + class rhs_uh1h_idap: rhs_uh1h_base { + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.8, -0.27}; + class UserActions { + class Open_Side_Doors; + + class Close_Side_Doors: Open_Side_Doors { + condition = QUOTE([ARR_2(this,'close_cargo_doors')] call EFUNC(compat_rhs_gref3,canCloseDoor)); + }; + }; + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; + + class rhs_uh1h_un: rhs_uh1h_base { + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.8, -0.27}; + class UserActions { + class Open_Side_Doors; + class Close_Side_Doors: Open_Side_Doors { + condition = QUOTE([ARR_2(this,'close_cargo_doors')] call EFUNC(compat_rhs_gref3,canCloseDoor)); + }; + }; + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; +}; diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/config.cpp b/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/config.cpp new file mode 100644 index 0000000000..b057aa1267 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsgref_main_loadorder", + "ace_fastroping" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/script_component.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/script_component.hpp new file mode 100644 index 0000000000..77632a2484 --- /dev/null +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_fastroping/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT fastroping +#define SUBCOMPONENT_BEAUTIFIED Fastroping +#include "..\script_component.hpp" + +#include "\z\ace\addons\fastroping\script_macros.hpp" diff --git a/addons/compat_rhs_gref3/config.cpp b/addons/compat_rhs_gref3/config.cpp new file mode 100644 index 0000000000..f2e7aeacde --- /dev/null +++ b/addons/compat_rhs_gref3/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"rhsgref_main_loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror", "Ruthberg", "Anton"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_gref3/functions/fnc_canCloseDoor.sqf b/addons/compat_rhs_gref3/functions/fnc_canCloseDoor.sqf new file mode 100644 index 0000000000..d874e1e23d --- /dev/null +++ b/addons/compat_rhs_gref3/functions/fnc_canCloseDoor.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Checks if the door can be closed. + * + * Arguments: + * 0: Helicopter + * 1: Door + * + * Return Value: + * Door can be closed + * + * Example: + * [_vehicle, "DoorLB"] call ace_compat_rhs_gref3_fnc_canCloseDoor + * + * Public: No + */ + +params ["_vehicle", "_door"]; + +(alive _vehicle) && +{!(_vehicle getVariable [QEGVAR(fastroping,doorsLocked),false])} && +{ + switch (true) do { + case (_vehicle isKindOf "rhs_uh1h_base"): { + ((_vehicle doorPhase _door) == 0) && + {ACE_player in _vehicle} + }; + default { + ((_vehicle doorPhase _door) > 0) && + {ACE_player in _vehicle} + }; + } +} diff --git a/addons/compat_rhs_gref3/functions/fnc_onCut.sqf b/addons/compat_rhs_gref3/functions/fnc_onCut.sqf new file mode 100644 index 0000000000..27b9559b11 --- /dev/null +++ b/addons/compat_rhs_gref3/functions/fnc_onCut.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Function for closing doors and retracting the hooks for RHS USF helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_rhs_gref3_fnc_onCut + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable [QEGVAR(fastroping,doorsLocked), false, true]; + +private _fries = _vehicle getVariable [QEGVAR(fastroping,FRIES), objNull]; +if !(isNull _fries) then { + _fries animate ["extendHookRight", 0]; + _fries animate ["extendHookLeft", 0]; + [{ + _this animateDoor ["doorRB", 0]; + _this animateDoor ["doorLB", 0]; + _this animate ["doorHandler_R",0]; + _this animate ["doorHandler_L",0]; + _this animateDoor ["close_cargo_doors", 1]; + + }, _vehicle, 2] call CBA_fnc_waitAndExecute; + + 4 +} else { + _vehicle animateDoor ["ramp_anim", 0]; + _vehicle animate ["ramp_bottom",0]; + _vehicle animate ["ramp_top",0]; + + 2 +}; diff --git a/addons/compat_rhs_gref3/functions/fnc_onPrepare.sqf b/addons/compat_rhs_gref3/functions/fnc_onPrepare.sqf new file mode 100644 index 0000000000..da79074aac --- /dev/null +++ b/addons/compat_rhs_gref3/functions/fnc_onPrepare.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Function for opening doors and extending the hook for most vanilla helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_rhs_gref3_fnc_onPrepare + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable [QEGVAR(fastroping,doorsLocked), true, true]; + +private _waitTime = 2; + +_vehicle animateDoor ["doorRB", 1]; +_vehicle animateDoor ["doorLB", 1]; +_vehicle animate ["doorHandler_R",1]; +_vehicle animate ["doorHandler_L",1]; +_vehicle animateDoor ["ramp_anim", 1]; +_vehicle animate ["ramp_bottom",0.56]; +_vehicle animate ["ramp_top",1]; +_vehicle animateDoor ["close_cargo_doors", 0]; + +private _fries = _vehicle getVariable [QEGVAR(fastroping,FRIES), objNull]; +if !(isNull _fries) then { + [{ + _this animate ["extendHookRight", 1]; + _this animate ["extendHookLeft", 1]; + }, _fries, 2] call CBA_fnc_waitAndExecute; + _waitTime = 4; +}; + +_waitTime diff --git a/addons/compat_rhs_gref3/script_component.hpp b/addons/compat_rhs_gref3/script_component.hpp new file mode 100644 index 0000000000..9ee2dcf965 --- /dev/null +++ b/addons/compat_rhs_gref3/script_component.hpp @@ -0,0 +1,10 @@ +#define COMPONENT compat_rhs_gref3 +#define COMPONENT_BEAUTIFIED RHS GREF Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" + +// Backwards compatibility +#undef GVAR +#define GVAR(var) TRIPLES(PREFIX,COMPONENT,var) diff --git a/addons/compat_rhs_saf3/$PBOPREFIX$ b/addons/compat_rhs_saf3/$PBOPREFIX$ new file mode 100644 index 0000000000..48b28f1067 --- /dev/null +++ b/addons/compat_rhs_saf3/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_rhs_saf3 diff --git a/addons/compat_rhs_saf3/CfgAmmo.hpp b/addons/compat_rhs_saf3/CfgAmmo.hpp new file mode 100644 index 0000000000..e194042490 --- /dev/null +++ b/addons/compat_rhs_saf3/CfgAmmo.hpp @@ -0,0 +1,25 @@ +class CfgAmmo { + // ACE Ballistics + class BulletBase; + class rhs_ammo_792x57_Ball: BulletBase { + ACE_caliber = 8.077; + ACE_bulletLength = 28.651; + ACE_bulletMass = 12.7008; + 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.315}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {785, 800, 815}; + ACE_barrelLengths[] = {508.0, 599.948, 660.4}; + }; + + class rhs_B_762x39_Ball; + class rhssaf_ammo_762x39_m82_api: rhs_B_762x39_Ball { + ACE_Caliber = 7.8994; + ACE_bulletMass = 7.6074; + ACE_bulletLength = 27.2796; + ACE_muzzleVelocities[] = {650, 700, 748}; + ACE_barrelLengths[] = {206.85, 329.62, 412.75}; + }; +}; diff --git a/addons/compat_rhs_saf3/CfgWeapons.hpp b/addons/compat_rhs_saf3/CfgWeapons.hpp new file mode 100644 index 0000000000..3293514e38 --- /dev/null +++ b/addons/compat_rhs_saf3/CfgWeapons.hpp @@ -0,0 +1,83 @@ +class CfgWeapons { + + // ACE Ballistics + class rhs_weap_g36_base; + class rhs_weap_g36c: rhs_weap_g36_base { + ACE_barrelLength = 228; + ACE_barrelTwist = 178; + }; + + class rhs_weap_g36kv: rhs_weap_g36_base { + ACE_barrelLength = 318; + ACE_barrelTwist = 178; + }; + + class rhs_weap_m21_base; + class rhs_weap_m21a: rhs_weap_m21_base { + ACE_barrelLength = 460; + ACE_barrelTwist = 177.8; + }; + + class rhs_weap_m21a_pr: rhs_weap_m21_base { + ACE_barrelLength = 460; + ACE_barrelTwist = 177.8; + }; + + class rhs_weap_m21a_pr_pbg40: rhs_weap_m21_base { + ACE_barrelLength = 460; + ACE_barrelTwist = 177.8; + }; + + class rhs_weap_m21s: rhs_weap_m21_base { + ACE_barrelLength = 375; + ACE_barrelTwist = 177.8; + }; + + class rhs_weap_m21s_pr: rhs_weap_m21a_pr { + ACE_barrelLength = 375; + ACE_barrelTwist = 177.8; + }; + + class Rifle_Base_F; + class rhs_weap_m70_base: Rifle_Base_F { + ACE_barrelLength = 415; + ACE_barrelTwist = 240; + }; + + class rhs_weap_m92: rhs_weap_m70_base { + ACE_barrelLength = 254; + }; + + class rhs_weap_m76: rhs_weap_m70_base { + ACE_barrelLength = 550; + }; + + class Rifle_Long_Base_F; + class rhs_weap_m84: Rifle_Long_Base_F { + ACE_barrelLength = 658; + ACE_barrelTwist = 240; + EGVAR(overheating,allowSwapBarrel) = 1; + }; + + class hgun_P07_F; + class rhs_weap_cz99: hgun_P07_F { + ACE_barrelLength = 108; + }; + + class Uniform_Base; + class rhssaf_uniform_mig29_pilot: Uniform_Base { + ACE_GForceCoef = 0.8; + }; + class rhssaf_uniform_heli_pilot: Uniform_Base { + ACE_GForceCoef = 0.8; + }; + + // Launchers + class Launcher_Base_F; + class rhs_weap_m80: Launcher_Base_F { + EGVAR(overpressure,range) = 8; + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,damage) = 0.7; + EGVAR(overpressure,offset) = 1.15; + }; +}; diff --git a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgAmmo.hpp b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..4730718639 --- /dev/null +++ b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgAmmo.hpp @@ -0,0 +1,33 @@ +class CfgAmmo { + // ACE Explosives + class DirectionalBombBase; + class rhssaf_mine_mrud_a_ammo: DirectionalBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {-0.034, 0, 0.202}; + }; + + class rhssaf_mine_mrud_d_ammo: rhssaf_mine_mrud_a_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0.0325, 0, 0.18}; + }; + + class MineBase; + class rhssaf_mine_pma3_ammo: MineBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.025}; + }; + + class rhssaf_mine_tma4_ammo: MineBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.045}; + }; + + class PipeBombBase; + class rhssaf_tm100_ammo: PipeBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {-0.055, 0, 0.014}; + }; + + class rhssaf_tm200_ammo: rhssaf_tm100_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {-0.055, 0, 0.018}; + }; + + class rhssaf_tm500_ammo: rhssaf_tm100_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {-0.056, 0, 0.032}; + }; +}; diff --git a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..c004f58446 --- /dev/null +++ b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgMagazines.hpp @@ -0,0 +1,76 @@ +class CfgMagazines { + + // ACE Explosives + class ATMine_Range_Mag; + class rhssaf_mine_mrud_a_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_mrud_a); + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + }; + }; + + class rhssaf_mine_mrud_b_mag: rhssaf_mine_mrud_a_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_mrud_b); + }; + + class rhssaf_mine_mrud_c_mag: rhssaf_mine_mrud_a_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_mrud_c); + }; + + class rhssaf_mine_mrud_d_mag: rhssaf_mine_mrud_a_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_mrud_d); + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; + }; + + class rhssaf_mine_pma3_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_pma3); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.026; + }; + }; + }; + + class rhssaf_mine_tma4_mag: ATMine_Range_Mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_mine_tma4); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.05; + }; + }; + }; + + class CA_Magazine; + class rhssaf_tm100_mag: CA_Magazine { + useAction = 0; + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_tm100); + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; + }; + + class rhssaf_tm200_mag: rhssaf_tm100_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_tm200); + }; + + class rhssaf_tm500_mag: rhssaf_tm100_mag { + EGVAR(explosives,SetupObject) = QEGVAR(explosives,Place_rhssaf_tm500); + }; +}; diff --git a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgVehicles.hpp b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..33771084b5 --- /dev/null +++ b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/CfgVehicles.hpp @@ -0,0 +1,90 @@ +class CfgVehicles { + + // ACE Explosives + class Items_base_F; + class EGVAR(explosives,Place): Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class EGVAR(explosives,Place_rhssaf_mine_mrud_a): EGVAR(explosives,Place) { + displayName = "$STR_RHSSAF_MRUD_A_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\mines_ap\mrud\rhssaf_mrud_a_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.034, 0, 0.202]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhssaf_mine_mrud_b): EGVAR(explosives,Place_rhssaf_mine_mrud_a) { + displayName = "$STR_RHSSAF_MRUD_B_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\mines_ap\mrud\rhssaf_mrud_b_e"; + }; + + class EGVAR(explosives,Place_rhssaf_mine_mrud_c): EGVAR(explosives,Place_rhssaf_mine_mrud_a) { + displayName = "$STR_RHSSAF_MRUD_C_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\mines_ap\mrud\rhssaf_mrud_c_e"; + }; + + class EGVAR(explosives,Place_rhssaf_mine_mrud_d): EGVAR(explosives,Place_rhssaf_mine_mrud_a) { + displayName = "$STR_RHSSAF_MRUD_D_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\mines_ap\mrud\rhssaf_mrud_d_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.0325, 0, 0.18]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhssaf_mine_pma3): EGVAR(explosives,Place) { + displayName = "$STR_RHSSAF_PMA3_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\mines_ap\pma\rhssaf_pma3_d"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.02]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhssaf_mine_tma4): EGVAR(explosives,Place) { + displayName = "$STR_RHSSAF_TMA4_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\mines_at\tma4\rhssaf_tma4_d"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.024]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhssaf_tm100): EGVAR(explosives,Place) { + displayName = "$STR_RHSSAF_TM100_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\tm500\rhssaf_tm100_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.055, 0, 0.014]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhssaf_tm200): EGVAR(explosives,Place) { + displayName = "$STR_RHSSAF_TM200_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\tm500\rhssaf_tm200_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.055, 0, 0.018]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhssaf_tm500): EGVAR(explosives,Place) { + displayName = "$STR_RHSSAF_TM500_DISPLAYNAME"; + model = "\rhssaf\addons\rhssaf_m_explosives\tm500\rhssaf_tm500_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.056, 0, 0.028]"; + }; + }; + }; +}; diff --git a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/config.cpp b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/config.cpp new file mode 100644 index 0000000000..099fef0b9d --- /dev/null +++ b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhssaf_main_loadorder", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/script_component.hpp b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_rhs_saf3/compat_rhs_saf3_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_saf3/config.cpp b/addons/compat_rhs_saf3/config.cpp new file mode 100644 index 0000000000..75ee4f5530 --- /dev/null +++ b/addons/compat_rhs_saf3/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"rhssaf_main_loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_saf3/script_component.hpp b/addons/compat_rhs_saf3/script_component.hpp new file mode 100644 index 0000000000..cdb9cd6dbe --- /dev/null +++ b/addons/compat_rhs_saf3/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_rhs_saf3 +#define COMPONENT_BEAUTIFIED RHS SAF Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/optionals/compat_rhs_usf3/$PBOPREFIX$ b/addons/compat_rhs_usf3/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rhs_usf3/$PBOPREFIX$ rename to addons/compat_rhs_usf3/$PBOPREFIX$ diff --git a/addons/compat_rhs_usf3/CfgAmmo.hpp b/addons/compat_rhs_usf3/CfgAmmo.hpp new file mode 100644 index 0000000000..6b885d7e04 --- /dev/null +++ b/addons/compat_rhs_usf3/CfgAmmo.hpp @@ -0,0 +1,392 @@ +class CfgAmmo { + class BulletBase; + class B_127x99_Ball; + class rhsusf_ammo_127x99_M33_Ball: B_127x99_Ball { // B_127x99_Ball (ballistics/CfgAmmo.hpp) + ACE_caliber = 12.954; + ACE_bulletLength = 58.674; + ACE_bulletMass = 41.9256; + ACE_muzzleVelocityVariationSD=0.35; + 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.670}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {900}; + ACE_barrelLengths[] = {736.6}; + }; + class rhsusf_ammo_127x99_mk211: rhsusf_ammo_127x99_M33_Ball { // ACE_127x99_API (ballistics/CfgAmmo.hpp) + ACE_caliber = 12.954; + ACE_bulletLength = 58.674; + ACE_bulletMass = 41.9904; + ACE_muzzleVelocityVariationSD=0.4; + 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.670}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {900}; + ACE_barrelLengths[] = {736.6}; + EGVAR(vehicle_damage,incendiary) = 1.0; // Raufoss Mk 211 HEIAP (high-explosive, incendiary, armor-piercing) + }; + class B_762x54_Ball; + class rhsusf_B_300winmag: B_762x54_Ball { // ACE_762x67_Ball_Mk248_Mod_1 (ballistics/CfgAmmo.hpp) + ACE_caliber = 7.823; + ACE_bulletLength = 37.821; + ACE_bulletMass = 14.256; + ACE_muzzleVelocityVariationSD=0.3; + ACE_ammoTempMuzzleVelocityShifts[] = {-5.3, -5.1, -4.6, -4.2, -3.4, -2.6, -1.4, -0.3, 1.4, 3.0, 5.2}; + ACE_ballisticCoefficients[] = {0.310}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {847, 867, 877}; + ACE_barrelLengths[] = {508.0, 609.6, 660.4}; + }; + class B_556x45_Ball; + class rhs_ammo_556x45_M855_Ball: B_556x45_Ball { // B_556x45_Ball (ballistics/CfgAmmo.hpp) + ACE_caliber = 5.69; + ACE_bulletLength = 23.012; + ACE_bulletMass = 4.0176; + ACE_ammoTempMuzzleVelocityShifts[] = {-27.20, -26.44, -23.76, -21.00, -17.54, -13.10, -7.95, -1.62, 6.24, 15.48, 27.75}; + ACE_ballisticCoefficients[] = {0.151}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900}; + ACE_barrelLengths[] = {210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6}; + }; + class rhs_ammo_556x45_M855A1_Ball: B_556x45_Ball { // B_556x45_Ball (ballistics/CfgAmmo.hpp) + ACE_caliber = 5.69; + ACE_bulletLength = 23.012; + ACE_bulletMass = 4.0176; + ACE_ammoTempMuzzleVelocityShifts[] = {-27.20, -26.44, -23.76, -21.00, -17.54, -13.10, -7.95, -1.62, 6.24, 15.48, 27.75}; + ACE_ballisticCoefficients[] = {0.151}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900}; + ACE_barrelLengths[] = {210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6}; + }; + class rhs_ammo_556x45_M855A1_Ball_Red: rhs_ammo_556x45_M855A1_Ball {}; // B_556x45_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_556x45_M855A1_Ball_Green: rhs_ammo_556x45_M855A1_Ball_Red {}; // B_556x45_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_556x45_M855A1_Ball_Yellow: rhs_ammo_556x45_M855A1_Ball_Red {}; // B_556x45_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_556x45_M855A1_Ball_Orange: rhs_ammo_556x45_M855A1_Ball_Red {}; // B_556x45_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_556x45_Mk318_Ball: B_556x45_Ball { // ACE_556x45_Ball_Mk318 (ballistics/CfgAmmo.hpp) + ACE_caliber = 5.69; + ACE_bulletLength = 23.012; + ACE_bulletMass = 4.0176; + 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.307}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {780, 886, 950}; + ACE_barrelLengths[] = {254.0, 393.7, 508.0}; + }; + class rhs_ammo_556x45_Mk262_Ball: B_556x45_Ball { // ACE_556x45_Ball_Mk262 (ballistics/CfgAmmo.hpp) + ACE_caliber = 5.69; + ACE_bulletLength = 23.012; + ACE_bulletMass = 4.9896; + ACE_muzzleVelocityVariationSD=0.4; + 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.361}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {624, 816, 832, 838}; + ACE_barrelLengths[] = {190.5, 368.3, 457.2, 508.0}; + }; + class rhs_ammo_762x51_M80_Ball: BulletBase { // B_762x51_Ball (ballistics/CfgAmmo.hpp) + ACE_caliber = 7.823; + ACE_bulletLength = 28.956; + ACE_bulletMass = 9.4608; + 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.2}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {700, 800, 820, 833, 845}; + ACE_barrelLengths[] = {254.0, 406.4, 508.0, 609.6, 660.4}; + }; + class rhs_ammo_762x51_M61_AP: rhs_ammo_762x51_M80_Ball {}; // B_762x51_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_762x51_M62_tracer: rhs_ammo_762x51_M80_Ball {}; // B_762x51_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_762x51_M80A1EPR_Ball: rhs_ammo_762x51_M80_Ball {}; // B_762x51_Ball (ballistics/CfgAmmo.hpp) + class rhs_ammo_762x51_M118_Special_Ball: rhs_ammo_762x51_M80_Ball { // ACE_762x51_Ball_M118LR (ballistics/CfgAmmo.hpp) + ACE_caliber = 7.823; + ACE_bulletLength = 31.496; + ACE_bulletMass = 11.34; + ACE_muzzleVelocityVariationSD=0.4; + 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.243}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {750, 780, 790, 794}; + ACE_barrelLengths[] = {406.4, 508.0, 609.6, 660.4}; + }; + class rhs_ammo_762x51_M993_Ball: rhs_ammo_762x51_M80_Ball { // ACE_762x51_Ball_M993_AP (ballistics/CfgAmmo.hpp) + ACE_caliber = 7.823; + ACE_bulletLength = 31.496; + ACE_bulletMass = 8.22946157; + 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.359}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + 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: 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.089}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + 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; + ACE_bulletLength = 17.4; + ACE_bulletMass = 2.0; + 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.112}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + 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; + ACE_bulletLength = 20.3; + ACE_bulletMass = 2.0; + 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.141}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + 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; + ACE_bulletLength = 17.272; + ACE_bulletMass = 14.904; + 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.195}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {230, 250, 285}; + ACE_barrelLengths[] = {101.6, 127.0, 228.6}; + }; + class rhs_ammo_9x19_FMJ: BulletBase { // ACE_9x19_Ball (ballistics/CfgAmmo.hpp) + ACE_caliber = 9.017; + ACE_bulletLength = 15.494; + ACE_bulletMass = 8.0352; + 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.165}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {340, 370, 400}; + ACE_barrelLengths[] = {101.6, 127.0, 228.6}; + }; + class rhs_ammo_9x19_JHP: BulletBase { // ACE_9x19_Ball (ballistics/CfgAmmo.hpp) + ACE_caliber = 9.017; + ACE_bulletLength = 15.494; + ACE_bulletMass = 8.0352; + 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.165}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ASM"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {340, 370, 400}; + ACE_barrelLengths[] = {101.6, 127.0, 228.6}; + }; + class rhs_ammo_he_fragments: BulletBase { // Shrapnel, compatibility with medical_damage + ACE_damageType = "grenade"; + }; + class B_12Gauge_Slug; + class rhs_ammo_12g_FRAG: B_12Gauge_Slug { // Frag rounds, compatibility with medical_damage + ACE_damageType = "grenade"; + }; + + class Sh_125mm_APFSDS; + class rhsusf_ammo_basic_penetrator: Sh_125mm_APFSDS { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + + class rhs_ammo_ap_penetrator: Sh_125mm_APFSDS { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + + class Sh_120mm_APFSDS; + class rhs_ammo_M829: Sh_120mm_APFSDS { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + + class rhs_ammo_M830: Sh_120mm_APFSDS { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + + class B_30mm_HE; + class RHS_ammo_M792_HEI: B_30mm_HE { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhs_ammo_mk19m3_M384; + class rhs_ammo_mk19m3_M430I: rhs_ammo_mk19m3_M384 { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhsusf_ammo_reduced_penetrator; + class rhs_ammo_mk19m3_M430I_penetrator: rhsusf_ammo_reduced_penetrator { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class B_30mm_APFSDS_Tracer_Red; + class rhs_ammo_PGU14B_API: B_30mm_APFSDS_Tracer_Red { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class SubmunitionBase; + class rhs_ammo_30x173mm_GAU8_mixed: SubmunitionBase { + EGVAR(rearm,caliber) = 30; + }; + + class M_Titan_AT; + class rhs_ammo_TOW_AT: M_Titan_AT { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + + class rhs_ammo_127x99_Ball; + class rhs_ammo_127x99_Ball_AI: rhs_ammo_127x99_Ball { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhs_ammo_127x99_Ball_Tracer_Red; + class rhs_ammo_127x99_Ball_Tracer_Red_AI: rhs_ammo_127x99_Ball_Tracer_Red { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhs_ammo_127x99_SLAP; + class rhs_ammo_127x99_SLAP_AI: rhs_ammo_127x99_SLAP { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhs_ammo_127x99_SLAP_Tracer_Red; + class rhs_ammo_127x99_SLAP_Tracer_Red_AI: rhs_ammo_127x99_SLAP_Tracer_Red { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhs_ammo_12gHEAP_penetrator: BulletBase { + EGVAR(vehicle_damage,incendiary) = 0.1; + }; + class rhs_ammo_M136_rocket; + class rhs_ammo_M136_hp_rocket: rhs_ammo_M136_rocket { + EGVAR(vehicle_damage,incendiary) = 0.5; + }; + class rhsusf_40mm_HE; + class rhsusf_40mm_HEDP: rhsusf_40mm_HE { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class rhs_ammo_M136_penetrator: rhsusf_ammo_basic_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_M136_hp_penetrator: rhs_ammo_M136_penetrator { + EGVAR(vehicle_damage,incendiary) = 0.5; + }; + class rhs_ammo_M136_hedp_penetrator: rhs_ammo_M136_penetrator { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + class rhs_ammo_M_fgm148_AT_penetrator: rhsusf_ammo_basic_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_smaw_HEAA_penetrator: rhsusf_ammo_basic_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class rhs_ammo_maaws_HEAT_penetrator: rhsusf_ammo_basic_penetrator { + EGVAR(vehicle_damage,incendiary) = 1.0; + }; + class RocketBase; + class rhs_ammo_maaws_HEDP: RocketBase { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + class rhs_ammo_maaws_HEDP_penetrator: rhs_ammo_M136_penetrator { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + class rhs_ammo_maaws_HE: RocketBase { + EGVAR(vehicle_damage,incendiary) = 0.5; + }; + class rhs_ammo_maaws_SMOKE: RocketBase { + EGVAR(vehicle_damage,incendiary) = 0; + }; + class rhs_ammo_maaws_ILLUM: RocketBase { + EGVAR(vehicle_damage,incendiary) = 0; + }; + class rhs_ammo_40mmHEDP_penetrator: rhs_ammo_12gHEAP_penetrator { + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + + class GrenadeHand; + class rhs_ammo_mk3a2: GrenadeHand { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class rhs_ammo_m84: GrenadeHand { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class rhs_ammo_m7a3_cs: GrenadeHand { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class GrenadeHand_stone; + class rhs_ammo_m69: GrenadeHand_stone { + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class rhs_ammo_m67: GrenadeHand { + EGVAR(frag,enabled) = 1; + EGVAR(frag,metal) = 213; + EGVAR(frag,charge) = 185; + EGVAR(frag,gurney_c) = 2700; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium_HD"}; + EGVAR(frag,skip) = 0; + EGVAR(frag,force) = 1; + }; + class rhs_ammo_M136_hedp_rocket: rhs_ammo_M136_rocket { + EGVAR(frag,enabled) = 1; + EGVAR(frag,metal) = 330; + EGVAR(frag,charge) = 280; + EGVAR(frag,gurney_c) = 2800; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium_HD"}; + EGVAR(frag,skip) = 0; + EGVAR(frag,force) = 1; + EGVAR(vehicle_damage,incendiary) = 0.8; + }; + class rhs_ammo_m72a7_rocket: rhs_ammo_M136_hedp_rocket { + EGVAR(vehicle_damage,incendiary) = 1.0; + EGVAR(frag,enabled) = 0; + EGVAR(frag,skip) = 1; + EGVAR(frag,force) = 0; + }; + class rhs_ammo_smaw_SR: RocketBase { + ACE_caliber = 9; + }; +}; diff --git a/addons/compat_rhs_usf3/CfgEventHandlers.hpp b/addons/compat_rhs_usf3/CfgEventHandlers.hpp new file mode 100644 index 0000000000..865276cfba --- /dev/null +++ b/addons/compat_rhs_usf3/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; diff --git a/addons/compat_rhs_usf3/CfgGlasses.hpp b/addons/compat_rhs_usf3/CfgGlasses.hpp new file mode 100644 index 0000000000..696b31dbeb --- /dev/null +++ b/addons/compat_rhs_usf3/CfgGlasses.hpp @@ -0,0 +1,110 @@ + +class CfgGlasses { + class G_Combat; + class rhs_ess_black: G_Combat { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 16.0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhs_googles_black: G_Combat { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 16.0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhs_googles_clear: G_Combat { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhs_googles_orange: G_Combat { + ACE_Color[] = {1,0.5,0}; + ACE_TintAmount = 8.0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhs_googles_yellow: G_Combat { + ACE_Color[] = {0,0,-1.5}; + ACE_TintAmount = 8.0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhsusf_oakley_goggles_base: G_Combat { + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhsusf_oakley_goggles_blk: rhsusf_oakley_goggles_base { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 16.0; + }; + class rhsusf_oakley_goggles_clr: rhsusf_oakley_goggles_base { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 0; + }; + class rhsusf_oakley_goggles_ylw: rhsusf_oakley_goggles_base { + ACE_Color[] = {0,0,-1.5}; + ACE_TintAmount = 8.0; + }; + class rhsusf_shemagh_gogg_base: G_Combat { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 16.0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhsusf_shemagh2_gogg_base: G_Combat { + ACE_Color[] = {0,0,0}; + ACE_TintAmount = 16.0; + ACE_Overlay = ""; + ACE_OverlayDirt = "A3\Ui_f\data\igui\rsctitles\HealthTextures\dust_upper_ca.paa"; + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\Cracked.paa); + ACE_Resistance = 1; + ACE_Protection = 0; + ACE_DustPath = QPATHTOEF(goggles,textures\fx\dust\%1.paa); + }; + class rhsusf_shemagh_base: G_Combat { + ACE_Overlay = ""; + ACE_OverlayDirt = ""; + ACE_OverlayCracked = ""; + ACE_Resistance = 0; + ACE_Protection = 0; + ACE_DustPath = ""; + }; + class rhsusf_shemagh2_base: G_Combat { + ACE_Overlay = ""; + ACE_OverlayDirt = ""; + ACE_OverlayCracked = ""; + ACE_Resistance = 0; + ACE_Protection = 0; + ACE_DustPath = ""; + }; +}; diff --git a/addons/compat_rhs_usf3/CfgJointRails.hpp b/addons/compat_rhs_usf3/CfgJointRails.hpp new file mode 100644 index 0000000000..0e0029857f --- /dev/null +++ b/addons/compat_rhs_usf3/CfgJointRails.hpp @@ -0,0 +1,11 @@ +// RHS specifically disables only the base vanilla 5.56 suppressor, the camo variants are untouched + +class asdg_MuzzleSlot; +class asdg_MuzzleSlot_556: asdg_MuzzleSlot { + class compatibleItems; +}; +class rhs_western_rifle_muzzle_slot: asdg_MuzzleSlot_556 { + class compatibleItems: compatibleItems { + muzzle_snds_M = 1; + }; +}; diff --git a/addons/compat_rhs_usf3/CfgMagazines.hpp b/addons/compat_rhs_usf3/CfgMagazines.hpp new file mode 100644 index 0000000000..471b345dcd --- /dev/null +++ b/addons/compat_rhs_usf3/CfgMagazines.hpp @@ -0,0 +1,41 @@ +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 { + ACE_isBelt = 1; + }; + class rhsusf_50Rnd_762x51: CA_Magazine { + ACE_isBelt = 1; + }; + class rhs_mag_100rnd_127x99_mag: VehicleMagazine { + ACE_isBelt = 1; + }; + class RHS_48Rnd_40mm_MK19: VehicleMagazine { + ACE_isBelt = 1; + }; + + class CA_LauncherMagazine; + class rhs_mag_smaw_SR: CA_LauncherMagazine { + EGVAR(overpressure,priority) = 99; + EGVAR(overpressure,angle) = 0; + EGVAR(overpressure,range) = 0; + EGVAR(overpressure,damage) = 0; + }; +}; diff --git a/addons/compat_rhs_usf3/CfgVehicles.hpp b/addons/compat_rhs_usf3/CfgVehicles.hpp new file mode 100644 index 0000000000..0593c5a868 --- /dev/null +++ b/addons/compat_rhs_usf3/CfgVehicles.hpp @@ -0,0 +1,272 @@ +class CfgVehicles { + class Heli_light_03_base_F; + class RHS_UH1_Base: Heli_light_03_base_F { + EGVAR(refuel,fuelCapacity) = 1447; + }; + class Heli_Transport_01_base_F; + class RHS_UH60_Base: Heli_Transport_01_base_F { + EGVAR(refuel,fuelCapacity) = 1360; + }; + + class Heli_Transport_02_base_F; + class RHS_CH_47F_base: Heli_Transport_02_base_F { + EGVAR(refuel,fuelCapacity) = 3914; + }; + class Helicopter_Base_H; + class rhsusf_CH53E_USMC: Helicopter_Base_H { + EGVAR(interaction,bodyWidth) = 3.5; + EGVAR(map,vehicleLightColor)[] = {1,0,0,0.1}; + }; + + class Heli_Attack_01_base_F; + class RHS_AH1Z_base: Heli_Attack_01_base_F { + EGVAR(refuel,fuelCapacity) = 1600; + EGVAR(hellfire,addLaserDesignator) = 1; + }; + + class RHS_AH64_base: Heli_Attack_01_base_F { + EGVAR(refuel,fuelCapacity) = 1420; + EGVAR(hellfire,addLaserDesignator) = 1; + }; + + class MBT_01_arty_base_F; + class rhsusf_m109tank_base: MBT_01_arty_base_F { + EGVAR(refuel,fuelCapacity) = 511; + }; + + class MRAP_01_base_F; + class rhsusf_hmmwe_base: MRAP_01_base_F { + EGVAR(refuel,fuelCapacity) = 95; + }; + + class rhsusf_rg33_base: MRAP_01_base_F { + EGVAR(refuel,fuelCapacity) = 302; + }; + + class Truck_F; + class Truck_01_base_F: Truck_F {}; + class rhsusf_fmtv_base: Truck_01_base_F { + EGVAR(refuel,fuelCapacity) = 219; + }; + class rhsusf_M1078A1P2_B_M2_fmtv_usarmy; + class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { + EGVAR(rearm,defaultSupply) = 800; + EGVAR(refuel,hooks)[] = {{1.1,0.9,-1.2}}; + EGVAR(refuel,fuelCargo) = 900; // 45 jerrycans + }; + + class rhsusf_HEMTT_A4_base: Truck_01_base_F {}; + class rhsusf_M977A4_usarmy_wd: rhsusf_HEMTT_A4_base {}; + class rhsusf_M977A4_AMMO_usarmy_wd: rhsusf_M977A4_usarmy_wd { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class rhsusf_M977A4_BKIT_usarmy_wd; + class rhsusf_M977A4_AMMO_BKIT_usarmy_wd: rhsusf_M977A4_BKIT_usarmy_wd { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class rhsusf_M977A4_BKIT_M2_usarmy_wd; + class rhsusf_M977A4_AMMO_BKIT_M2_usarmy_wd: rhsusf_M977A4_BKIT_M2_usarmy_wd { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class rhsusf_M978A4_usarmy_wd: rhsusf_M977A4_usarmy_wd { + EGVAR(refuel,hooks)[] = {{-0.44,-4.87,0}, {0.5,-4.87,0}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class rhsusf_M978A4_BKIT_usarmy_wd: rhsusf_M977A4_usarmy_wd { + EGVAR(refuel,hooks)[] = {{-0.44,-4.87,0}, {0.5,-4.87,0}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + class Tank_F; + class APC_Tracked_02_base_F: Tank_F {}; + class rhsusf_m113tank_base: APC_Tracked_02_base_F { + EGVAR(map,vehicleLightColor)[] = {0,1,0,0.1}; + EGVAR(refuel,fuelCapacity) = 360; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.7; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + + class rhsusf_m113_usarmy; + class rhsusf_m113_usarmy_supply: rhsusf_m113_usarmy { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class Wheeled_APC_F; + class APC_Tracked_03_base_F; + class RHS_M2A2_Base: APC_Tracked_03_base_F { + EGVAR(refuel,fuelCapacity) = 746; + EGVAR(vehicle_damage,canHaveFireRing) = 1; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.2; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + class rhsusf_M1117_base: Wheeled_APC_F { + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.7; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + class rhsusf_stryker_base: Wheeled_APC_F { + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.5; + EGVAR(vehicle_damage,turretFireProb) = 0.2; + EGVAR(vehicle_damage,engineFireProb) = 0.7; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + }; + class MBT_01_base_F; + class rhsusf_m1a1tank_base: MBT_01_base_F { + EGVAR(refuel,fuelCapacity) = 1909; + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0; + EGVAR(vehicle_damage,turretFireProb) = 0; + EGVAR(vehicle_damage,engineFireProb) = 0.5; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0; + EGVAR(vehicle_damage,hitpointAlias)[] = { { "hull", { "hitammohull", "hitammo" } } }; + }; + + class RHS_M2A2; + class RHS_M2A2_BUSKI: RHS_M2A2 { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", + "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", + "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", + "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", + "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", + "era_41_hitpoint", "era_42_hitpoint", "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint" + }; + EGVAR(vehicle_damage,canHaveFireRing) = 1; + }; + class RHS_M2A3: RHS_M2A2 { + ace_hunterkiller = 1; + }; + class RHS_M2A3_BUSKI: RHS_M2A3 { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", + "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", + "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", + "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", + "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", + "era_41_hitpoint", "era_42_hitpoint", "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint" + }; + EGVAR(vehicle_damage,canHaveFireRing) = 1; + }; + class RHS_M2A3_BUSKIII: RHS_M2A3_BUSKI { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", + "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", + "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", + "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", + "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", + "era_41_hitpoint", "era_42_hitpoint", "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", + "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint", + "era_51_hitpoint", "era_52_hitpoint", "era_53_hitpoint", "era_54_hitpoint", "era_55_hitpoint", + "era_56_hitpoint", "era_57_hitpoint", "era_58_hitpoint", "era_59_hitpoint" + }; + }; + class rhsusf_m1a1aim_tuski_wd: rhsusf_m1a1tank_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", + "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", + "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", + "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { "SLAT_1_hitpoint" }; + }; + class rhsusf_m1a2tank_base; + class rhsusf_m1a2sep1tuskid_usarmy: rhsusf_m1a2tank_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", + "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", + "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", + "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { "SLAT_1_hitpoint" }; + }; + class rhsusf_m1a2sep1tuskiiwd_usarmy: rhsusf_m1a2sep1tuskid_usarmy { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", + "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", + "era_11_hitpoint", "era_12_hitpoint", "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", + "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", + "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", + "era_41_hitpoint", "era_42_hitpoint", "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", + "era_46_hitpoint" + }; + }; + + class Plane_CAS_01_base_F; + class RHS_A10: Plane_CAS_01_base_F { + EGVAR(refuel,fuelCapacity) = 6223; + }; + + class Plane_Base_F; + class RHS_C130J_Base: Plane_Base_F { + EGVAR(refuel,fuelCapacity) = 25704; + EGVAR(cargo,space) = 4; + EGVAR(cargo,hasCargo) = 1; + }; + + class rhsusf_infantry_usmc_base; + class rhsusf_usmc_marpat_wd_helipilot: rhsusf_infantry_usmc_base { + ace_gforcecoef = 0.55; + }; + + class rhsusf_infantry_army_base; + class rhsusf_army_ocp_helipilot: rhsusf_infantry_army_base { + ace_gforcecoef = 0.55; + }; + + class rhsusf_usmc_marpat_wd_rifleman_m4; + class rhsusf_airforce_jetpilot: rhsusf_usmc_marpat_wd_rifleman_m4 { + ace_gforcecoef = 0.55; + }; + + class Items_base_F; + class rhsusf_props_JerryCan_Base: Items_base_F { + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,size) = 1; + EGVAR(dragging,canCarry) = 1; + }; + + class rhsusf_props_ScepterMWC_Base: rhsusf_props_JerryCan_Base { + EXGVAR(field_rations,waterSupply) = 20; + EXGVAR(field_rations,offset)[] = {-0.13, 0, 0.2}; + }; +}; diff --git a/addons/compat_rhs_usf3/CfgWeapons.hpp b/addons/compat_rhs_usf3/CfgWeapons.hpp new file mode 100644 index 0000000000..46ac7e56ba --- /dev/null +++ b/addons/compat_rhs_usf3/CfgWeapons.hpp @@ -0,0 +1,432 @@ +class CfgWeapons { + class Pistol_Base_F; + class Rifle_Base_F; + class rhs_weap_m14ebrri_base; + class GM6_base_F; + class rhs_weap_M107_Base_F: GM6_base_F { + ACE_barrelTwist = 381.0; + ACE_barrelLength = 736.6; + ACE_RailHeightAboveBore = 4.18639; + }; + class rhs_weap_XM2010_Base_F: Rifle_Base_F { + ACE_barrelTwist = 254.0; + ACE_barrelLength = 609.6; + EGVAR(overheating,dispersion) = 0.75; + ACE_RailHeightAboveBore = 3.1028; + }; + class rhs_weap_m24sws: rhs_weap_XM2010_Base_F { + ACE_barrelTwist = 285.75; + ACE_barrelLength = 609.6; + ACE_RailHeightAboveBore = 2.41891; + }; + class rhs_weap_m40a5: rhs_weap_XM2010_Base_F { + ACE_barrelTwist = 304.8; // 1:12" + ACE_barrelLength = 635.0; // 25" + ACE_RailHeightAboveBore = 2.46368; + }; + class arifle_MX_Base_F; + class rhs_weap_m4_Base: arifle_MX_Base_F { + ACE_RailHeightAboveBore = 2.56518; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 368.3; + }; + class rhs_weap_m4a1; + class rhs_weap_hk416d10: rhs_weap_m4a1 { + ACE_RailHeightAboveBore = 3.56139; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 254; + }; + class rhs_weap_hk416d145: rhs_weap_hk416d10 { + ACE_barrelTwist = 177.8; + ACE_barrelLength = 368.3; + }; + class rhs_weap_m27iar: rhs_weap_m4a1 { + ACE_RailHeightAboveBore = 3.56139; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 419.1; + }; + class rhs_weap_m4a1_blockII; + class rhs_weap_mk18: rhs_weap_m4a1_blockII { + ACE_RailHeightAboveBore = 2.6068; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 261.62; + }; + class rhs_weap_m16a4: rhs_weap_m4_Base { + ACE_RailHeightAboveBore = 2.59324; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 508.0; + }; + class rhs_weap_saw_base: Rifle_Base_F { // Base class for all Minimi + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,closedBolt) = 0; + }; + class rhs_weap_lmg_minimi_railed; + class rhs_weap_m249_pip_S: rhs_weap_lmg_minimi_railed { + ACE_RailHeightAboveBore = 4.11044; + ACE_barrelLength = 348; + ACE_barrelTwist = 177.8; + }; + class rhs_weap_m249_pip_L: rhs_weap_lmg_minimi_railed { + ACE_RailHeightAboveBore = 4.34899; + ACE_barrelLength = 464.8; + ACE_barrelTwist = 177.8; + }; + class rhs_weap_m249: rhs_weap_lmg_minimi_railed { + ACE_barrelLength = 464.8; + ACE_barrelTwist = 177.8; + }; + class rhs_weap_m249_pip: rhs_weap_lmg_minimi_railed { + ACE_barrelLength = 464.8; + ACE_barrelTwist = 177.8; + }; + class rhs_weap_M249_base; + class rhs_weap_m240_base: rhs_weap_M249_base { + ACE_RailHeightAboveBore = 4.3987; + ACE_barrelTwist = 304.8; + ACE_barrelLength = 629.92; + }; + class rhs_weap_m14_base; + class rhs_weap_m14: rhs_weap_m14_base { + ACE_barrelTwist = 304.8; + ACE_barrelLength = 558.8; + EGVAR(overheating,dispersion) = 0.75; + }; + class rhs_weap_m14ebrri: rhs_weap_m14ebrri_base { + ACE_barrelTwist = 304.8; + ACE_barrelLength = 558.8; + EGVAR(overheating,dispersion) = 0.75; + ACE_RailHeightAboveBore = 3.08341; + }; + class rhs_weap_m14_socom_base: rhs_weap_m14_base { + ACE_barrelTwist = 304.8; + ACE_barrelLength = 413; //16.25 in (413 mm) + EGVAR(overheating,dispersion) = 0.75; + }; + class rhs_weap_sr25: rhs_weap_m14ebrri { + ACE_barrelTwist = 285.75; + ACE_barrelLength = 609.6; + ACE_RailHeightAboveBore = 3.13162; + }; + class rhs_weap_sr25_ec: rhs_weap_sr25 { + ACE_barrelLength = 508.0; + ACE_RailHeightAboveBore = 3.13689; + }; + class rhs_weap_sr25_d; + class rhs_weap_sr25_ec_d: rhs_weap_sr25_d { + ACE_barrelLength = 508.0; + ACE_RailHeightAboveBore = 3.13689; + }; + class rhs_weap_sr25_wd; + class rhs_weap_sr25_ec_wd: rhs_weap_sr25_wd { + ACE_barrelLength = 508.0; + ACE_RailHeightAboveBore = 3.13689; + }; + class rhs_weap_SCAR_H_Base; + class rhs_weap_SCAR_H_CQC_Base: rhs_weap_SCAR_H_Base { + ACE_barrelTwist = 304.8; // 1:12" + ACE_barrelLength = 330.0; + }; + class rhs_weap_SCAR_H_LB_Base: rhs_weap_SCAR_H_Base { + ACE_barrelTwist = 304.8; // 1:12" + ACE_barrelLength = 508.0; + }; + class rhs_weap_SCAR_H_STD_Base: rhs_weap_SCAR_H_Base { + ACE_barrelTwist = 304.8; // 1:12" + ACE_barrelLength = 406.0; + }; + class rhs_weap_M590_5RD: Rifle_Base_F { + ACE_barrelTwist = 0.0; + ACE_twistDirection = 0; + ACE_barrelLength = 469.9; + }; + class rhs_weap_M590_8RD: rhs_weap_M590_5RD { + ACE_barrelTwist = 0.0; + ACE_twistDirection = 0; + ACE_barrelLength = 508.0; + }; + class rhs_weap_m32_Base_F: Rifle_Base_F { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + 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; + }; + // RHS pistols + class hgun_ACPC2_F; + class rhsusf_weap_m1911a1: hgun_ACPC2_F { + ACE_barrelTwist = 406.4; + ACE_barrelLength = 127.0; + }; + class hgun_P07_F; + class rhsusf_weap_glock17g4: hgun_P07_F { + ACE_barrelTwist = 248.92; + ACE_barrelLength = 114.046; + }; + class rhsusf_weap_m9: rhsusf_weap_glock17g4 { + ACE_barrelTwist = 248.92; + ACE_barrelLength = 124.46; + }; + class rhs_weap_M320_Base_F: Pistol_Base_F { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + + // RHS launchers + class launch_O_Titan_F; + + class rhs_weap_fim92: launch_O_Titan_F { + EGVAR(overpressure,range) = 6; + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,damage) = 0.6; + EGVAR(overpressure,offset) = 1.45; + }; + + class Launcher_Base_F; + + class rhs_weap_smaw: Launcher_Base_F { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,angle) = 45; + EGVAR(overpressure,offset) = 1.3; + }; + + class rhs_weap_maaws: Launcher_Base_F { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,range) = 15; + EGVAR(overpressure,angle) = 70; + EGVAR(overpressure,damage) = 0.75; + EGVAR(overpressure,offset) = 0.95; + }; + + class rhs_weap_M136: Launcher_Base_F { + EGVAR(overpressure,range) = 10; + EGVAR(overpressure,angle) = 50; + EGVAR(overpressure,offset) = 0.9; + }; + + // Fast Helmets + class rhsusf_opscore_01; + class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_cover; + class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_01; + class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + + // ACH Helmets + class rhsusf_ach_helmet_ocp; + class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + + // ACVC Helmets + class rhsusf_cvc_helmet: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + // MICH Helmets + class rhsusf_mich_bare; + class rhsusf_mich_bare_alt: rhsusf_mich_bare { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos; + class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc; + class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_semi; + class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_semi; + class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { + HEARING_PROTECTION_OPEN; + }; + class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_tan; + class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_tan; + class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_tan; + class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { + HEARING_PROTECTION_PELTOR; + }; + + class rhsusf_hgu56p: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + class rhsusf_hgu56p_visor: rhsusf_hgu56p { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_black; + class rhsusf_hgu56p_visor_black: rhsusf_hgu56p_black { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_green; + class rhsusf_hgu56p_visor_green: rhsusf_hgu56p_green { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_visor_mask: rhsusf_hgu56p { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_visor_mask_black: rhsusf_hgu56p_black { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_visor_mask_Empire_black: rhsusf_hgu56p_black { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_visor_mask_green: rhsusf_hgu56p_green { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_mask_smiley; + class rhsusf_hgu56p_visor_mask_smiley: rhsusf_hgu56p_mask_smiley { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_pink; + class rhsusf_hgu56p_visor_mask_pink: rhsusf_hgu56p_pink { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_visor_pink: rhsusf_hgu56p_pink { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_saf; + class rhsusf_hgu56p_visor_saf: rhsusf_hgu56p_saf { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_usa; + class rhsusf_hgu56p_visor_usa: rhsusf_hgu56p_usa { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_white; + class rhsusf_hgu56p_visor_white: rhsusf_hgu56p_white { + ACE_Protection = 1; + }; + class rhsusf_hgu56p_visor_mask_black_skull; + class rhsusf_hgu56p_mask_black_skull: rhsusf_hgu56p_visor_mask_black_skull { + ACE_Protection = 0; + }; + class rhsusf_ihadss: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + class H_HelmetB; + class RHS_jetpilot_usaf: H_HelmetB { + ACE_Protection = 1; + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_usf3/XEH_PREP.hpp b/addons/compat_rhs_usf3/XEH_PREP.hpp new file mode 100644 index 0000000000..821ee657be --- /dev/null +++ b/addons/compat_rhs_usf3/XEH_PREP.hpp @@ -0,0 +1,3 @@ +PREP(canCloseDoor); +PREP(onCut); +PREP(onPrepare); diff --git a/addons/compat_rhs_usf3/XEH_preInit.sqf b/addons/compat_rhs_usf3/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/compat_rhs_usf3/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/compat_rhs_usf3/XEH_preStart.sqf b/addons/compat_rhs_usf3/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_rhs_usf3/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp new file mode 100644 index 0000000000..b87223ae27 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp @@ -0,0 +1,69 @@ +class CfgWeapons { + // Last update: RHSUSAF 0.5.6 + class acc_pointer_IR; + class rhsusf_acc_anpeq15: acc_pointer_IR { + baseWeapon = "rhsusf_acc_anpeq15"; + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; + }; + class rhsusf_acc_anpeq15_bk: rhsusf_acc_anpeq15 { + baseWeapon = "rhsusf_acc_anpeq15_bk"; + }; + class rhsusf_acc_anpeq15_light; + class rhsusf_acc_anpeq15_bk_light: rhsusf_acc_anpeq15_light { + baseWeapon = "rhsusf_acc_anpeq15_bk"; + }; + class rhsusf_acc_anpeq15_wmx: rhsusf_acc_anpeq15 { + baseWeapon = "rhsusf_acc_anpeq15_wmx"; + }; + class rhsusf_acc_anpeq15_wmx_light: rhsusf_acc_anpeq15_light { + baseWeapon = "rhsusf_acc_anpeq15_wmx"; + }; + class rhsusf_acc_M952V: rhsusf_acc_anpeq15_light { + rhs_acc_combo = ""; // prevent materializing a PEQ-15 if RHS's attachment switch is called + rhs_anpeq15_base = ""; // same deal + baseWeapon = "rhsusf_acc_M952V"; + }; + class rhsusf_acc_wmx: rhsusf_acc_M952V { + baseWeapon = "rhsusf_acc_wmx"; + }; + class rhsusf_acc_wmx_bk: rhsusf_acc_M952V { + baseWeapon = "rhsusf_acc_wmx_bk"; + }; + + class rhsusf_acc_anpeq15A: acc_pointer_IR { + baseWeapon = "rhsusf_acc_anpeq15A"; + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; + }; + class rhsusf_acc_anpeq15_top: rhsusf_acc_anpeq15A { + baseWeapon = "rhsusf_acc_anpeq15_top"; + }; + class rhsusf_acc_anpeq15_bk_top: rhsusf_acc_anpeq15_top { + baseWeapon = "rhsusf_acc_anpeq15_bk_top"; + }; + + class rhsusf_acc_anpeq15side: acc_pointer_IR { + baseWeapon = "rhsusf_acc_anpeq15side"; + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; + }; + class rhsusf_acc_anpeq15side_bk: rhsusf_acc_anpeq15side { + baseWeapon = "rhsusf_acc_anpeq15side_bk"; + }; + class rhsusf_acc_anpeq16a: rhsusf_acc_anpeq15 { + baseWeapon = "rhsusf_acc_anpeq16a"; + }; + class rhsusf_acc_anpeq16a_light: rhsusf_acc_anpeq15_light { + baseWeapon = "rhsusf_acc_anpeq16a"; + }; + class rhsusf_acc_anpeq16a_top: rhsusf_acc_anpeq16a { + baseWeapon = "rhsusf_acc_anpeq16a_top"; + }; + class rhsusf_acc_anpeq16a_light_top: rhsusf_acc_anpeq16a_light { + baseWeapon = "rhsusf_acc_anpeq16a_top"; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/config.cpp new file mode 100644 index 0000000000..93e0f33289 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_arsenal" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/script_component.hpp new file mode 100644 index 0000000000..9de14c499c --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT arsenal +#define SUBCOMPONENT_BEAUTIFIED Arsenal +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgMagazineGroups.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgMagazineGroups.hpp new file mode 100644 index 0000000000..333aacbcfe --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgMagazineGroups.hpp @@ -0,0 +1,28 @@ +#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_M430A1) { + RHS_48Rnd_40mm_MK19_M430A1 = 1; + RHS_96Rnd_40mm_MK19_M430A1 = 1; + }; + class GVAR(48Rnd_40mm_MK19_M1001) { + RHS_48Rnd_40mm_MK19_M1001 = 1; + RHS_96Rnd_40mm_MK19_M1001 = 1; + }; +}; + diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgMagazines.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgMagazines.hpp new file mode 100644 index 0000000000..7b6cb387d4 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgMagazines.hpp @@ -0,0 +1,124 @@ +class CfgMagazines { + // RHS magazines for crew handled ammo + class rhs_mag_TOW; + class GVAR(mag_TOW): rhs_mag_TOW { + scope = 2; + displayName = SUBCSTRING(mag_TOW_displayName); + 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; + displayName = SUBCSTRING(mag_TOWB_displayName); + 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; + displayName = SUBCSTRING(mag_ITOW_displayName); + 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; + displayName = SUBCSTRING(mag_TOW2_displayName); + 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; + displayName = SUBCSTRING(mag_TOW2A_displayName); + 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; + displayName = SUBCSTRING(mag_TOW2b_displayName); + 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; + displayName = SUBCSTRING(mag_TOW2b_aero_displayName); + 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; + displayName = SUBCSTRING(mag_TOW2bb_displayName); + 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_48Rnd_40mm_MK19; + class GVAR(48Rnd_40mm_MK19): RHS_48Rnd_40mm_MK19 { + scope = 2; + displayName = SUBCSTRING(48Rnd_40mm_MK19_displayName); + 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; + displayName = SUBCSTRING(48Rnd_40mm_MK19_M430I_displayName); + 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_M430A1; + class GVAR(48Rnd_40mm_MK19_M430A1): RHS_48Rnd_40mm_MK19_M430A1 { + scope = 2; + displayName = SUBCSTRING(48Rnd_40mm_MK19_M430A1_displayName); + 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; + displayName = SUBCSTRING(48Rnd_40mm_MK19_M1001_displayName); + 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/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp new file mode 100644 index 0000000000..cbca20cce7 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgVehicles.hpp @@ -0,0 +1,77 @@ +class CfgVehicles { + class LandVehicle; + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + }; + class StaticMortar: StaticWeapon {}; + class RHS_M252_Base: StaticMortar { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "main_gun"; + }; + }; + + 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; + class rhs_m2staticmg_base: StaticMGWeapon { + 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; + class RHS_MK19_TriPod_base: StaticGrenadeLauncher { + 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; + class RHS_TOW_TriPod_base: StaticATWeapon { + 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; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp new file mode 100644 index 0000000000..d373e7fe67 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/CfgWeapons.hpp @@ -0,0 +1,110 @@ +class CfgWeapons { + 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 Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + class GVAR(m252_carry): Launcher_Base_F { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + EGVAR(csw,mortarBaseplate) = "RHS_M252_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + // One WeaponSlot with a positive value for iconScale forces game to use icon overlay method. + // Required, because the inventory icon has no accessory variants. + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + 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 { + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,m3TripodLow) = "RHS_MK19_TriPod_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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 { + dlc = "ace"; + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,m220Tripod) = "RHS_TOW_TriPod_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + 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/addons/compat_rhs_usf3/compat_rhs_usf3_csw/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/config.cpp new file mode 100644 index 0000000000..9e4940dd67 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {QGVAR(m252_carry), QGVAR(m2_carry), QGVAR(mk19_carry), QGVAR(tow_carry)}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_csw" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgMagazineGroups.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/script_component.hpp new file mode 100644 index 0000000000..77a1b484cb --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT csw +#define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons +#include "..\script_component.hpp" + +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml new file mode 100644 index 0000000000..bc2413a2ca --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml @@ -0,0 +1,137 @@ + + + + + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + [班组] BGM-71A TOW + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + + + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + [班组] BGM-71B TOW + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + + + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + [班组] BGM-71C ITOW + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + + + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [班组] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + + + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [班组] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + + + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [班组] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + + + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [班组] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + + + [CSW] BGM-71H Bunker Buster + [CSW] BGM-71H 벙커버스터 + [CSW] BGM-71H バンカーバスター + [班组] BGM-71H “碉堡克星” + [CSW] BGM-71H Bunker Buster + [CSW] BGM-71H Anti-Búnquer + [CSW] BGM-71H Bunker Buster + [CSW] BGM-71H Anti-Bunker + [CSW] BGM-71H Bunker Buster + + + [CSW] Mk. 19 40mm M384 HE + [CSW] Mk.19 40mm M384 HE + [CSW] Mk. 19 40mm M384 HE + [班组] Mk. 19 40mm M384 高爆 + [CSW] Mk. 19 40 мм M384 HE + [CSW] Mk. 19 40mm M384 HE + [CSW] Mk. 19 40mm M384 HE + [CSW] Mk. 19 40mm M384 HE + [CSW] Mk. 19 40mm M384 HE + + + [CSW] Mk. 19 40mm M430I HEDP + [CSW] Mk.19 40mm M430I 이중목적고폭탄 + [CSW] Mk. 19 40mm M430I HEDP + [班组] Mk. 19 40mm M430I 两用高爆 + [CSW] Mk. 19 40 мм M430I HEDP + [CSW] Mk. 19 40mm M430I HEDP + [CSW] Mk. 19 40mm M430I HEDP + [CSW] Mk. 19 40mm M430I HEDP + [CSW] Mk. 19 40mm M430I HEDP + + + [CSW] Mk. 19 40mm M430A1 HEDP + [CSW] Mk.19 40mm M430A1 이중목적고폭탄 + [CSW] Mk. 19 40mm M430A1 HEDP + [班组] Mk. 19 40mm M430A1 两用高爆 + [CSW] Mk. 19 40 мм M430A1 HEDP + [CSW] Mk. 19 40mm M430A1 HEDP + [CSW] Mk. 19 40mm M430A1 HEDP + [CSW] Mk. 19 40mm M430A1 HEDP + [CSW] Mk. 19 40mm M430A1 HEDP + + + [CSW] Mk. 19 40mm M1001 Canister + [CSW] Mk.19 40mm M1001 산탄 + [CSW] Mk. 19 40mm M1001 キャニスター + [班组] Mk. 19 40mm M1001 霰弹 + [CSW] Mk. 19 40 мм M1001 Канистровый + [CSW] Mk. 19 40mm M1001 Bote de metralla + [CSW] Mk. 19 40mm M1001 Kanister + [CSW] Mk. 19 40mm M1001 Pallettoni + [CSW] Mk. 19 40 mm M1001 Chevrotine + + + diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgAmmo.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..eea589b99b --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgAmmo.hpp @@ -0,0 +1,25 @@ +class CfgAmmo { + // ACE Explosives + class PipeBombBase; + class rhsusf_m112_ammo: PipeBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {0.055, 0, 0.038}; + }; + + class rhsusf_m112x4_ammo: PipeBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {0.055, -0.025, 0.102}; + }; + + class MineBase; + class rhsusf_mine_m19_ammo: MineBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.02, 0.046}; + }; + + class rhsusf_mine_m14_ammo: MineBase { + EGVAR(explosives,defuseObjectPosition)[] = {-0.02, -0.015, 0.02}; + }; + + class APERSMine_Range_Ammo; + class rhsusf_mine_m49a1_3m_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.016, 0.296}; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgMagazines.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..332c2bf1f2 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgMagazines.hpp @@ -0,0 +1,63 @@ +class CfgMagazines { + class CA_Magazine; + class rhsusf_m112_mag: CA_Magazine { + EGVAR(explosives,delayTime) = 1; + EGVAR(explosives,placeable) = 1; + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_explosive_m112); + 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 { + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_explosive_m112x4); + }; + + class ATMine_Range_Mag; + class rhs_mine_M19_mag: ATMine_Range_Mag { + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_mine_M19); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.075; + }; + }; + }; + + class rhsusf_mine_m14_mag: ATMine_Range_Mag { + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_mine_m14); + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; + + class rhsusf_mine_m49a1_3m_mag: ATMine_Range_Mag { + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_mine_m49a1_3m); + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.125; + }; + }; + }; + + class rhsusf_mine_m49a1_6m_mag: rhsusf_mine_m49a1_3m_mag { + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_mine_m49a1_6m); + }; + + class rhsusf_mine_m49a1_10m_mag: rhsusf_mine_m49a1_3m_mag { + EGVAR(explosives,setupObject) = QEGVAR(explosives,Place_rhsusf_mine_m49a1_10m); + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..668631b70d --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/CfgVehicles.hpp @@ -0,0 +1,69 @@ +class CfgVehicles { + class Items_base_F; + class EGVAR(explosives,Place): Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + // ACE Explosives + class EGVAR(explosives,Place_rhsusf_explosive_m112): EGVAR(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.055, 0, 0.038]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhsusf_explosive_m112x4): EGVAR(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.055, 0.025, 0.102]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhsusf_mine_M19): EGVAR(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.014, -0.002, 0.046]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhsusf_mine_m14): EGVAR(explosives,Place) { + displayName = "$STR_RHSUSF_M14_APMINE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m14_d"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhsusf_mine_m49a1_3m): EGVAR(explosives,Place) { + displayName = "M49A1 (3m)"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m49a1_a_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, -0.016, 0.296]"; + }; + }; + }; + + class EGVAR(explosives,Place_rhsusf_mine_m49a1_6m): EGVAR(explosives,Place_rhsusf_mine_m49a1_3m) { + displayName = "M49A1 (6m)"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m49a1_b_e"; + }; + + class EGVAR(explosives,Place_rhsusf_mine_m49a1_10m): EGVAR(explosives,Place_rhsusf_mine_m49a1_3m) { + displayName = "M49A1 (10m)"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m49a1_c_e"; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/config.cpp new file mode 100644 index 0000000000..9db8a0432d --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/CfgVehicles.hpp new file mode 100644 index 0000000000..1d2fd39ac9 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/CfgVehicles.hpp @@ -0,0 +1,127 @@ +class CfgVehicles { + class Air; + class Helicopter: Air {}; + class Helicopter_Base_F: Helicopter { + class Eventhandlers; + }; + class Heli_light_03_base_F: Helicopter_Base_F {}; + class RHS_UH1_Base: Heli_light_03_base_F {}; + class RHS_UH1Y_base: RHS_UH1_Base { + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; + class RHS_UH1Y_US_base: RHS_UH1Y_base {}; + class RHS_UH1Y: RHS_UH1Y_US_base { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesAnchorBar"; + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 2.38, -0.135}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_usf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_usf3,onPrepare); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + + class UserActions; + class EventHandlers: EventHandlers { + class RHSUSF_EventHandlers; + }; + }; + class RHS_UH1Y_FFAR: RHS_UH1Y { + class UserActions: UserActions { + class OpenCargoDoor; + class CloseCargoDoor: OpenCargoDoor { + condition = QUOTE([ARR_2(this,'doorRB')] call EFUNC(compat_rhs_usf3,canCloseDoor)); + }; + class CloseCargoLDoor: OpenCargoDoor { + condition = QUOTE([ARR_2(this,'doorLB')] call EFUNC(compat_rhs_usf3,canCloseDoor)); + }; + }; + }; + + class Helicopter_Base_H: Helicopter_Base_F { + class Eventhandlers; + }; + class Heli_Transport_01_base_F: Helicopter_Base_H {}; + + class RHS_MELB_base: Helicopter_Base_H {}; + class RHS_MELB_MH6M: RHS_MELB_base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{1.166, 0.79, -0.01}, {-1.166, 0.79, -0.01}}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_usf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_usf3,onPrepare); + }; + class RHS_UH60_Base: Heli_Transport_01_base_F {}; + class RHS_UH60M_base: RHS_UH60_Base { + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; + class RHS_UH60M_US_base: RHS_UH60M_base {}; + class RHS_UH60M: RHS_UH60M_US_base { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesAnchorBar"; + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.25, -0.65}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_usf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_usf3,onPrepare); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + + class UserActions { + class OpenCargoDoor; + class CloseCargoDoor: OpenCargoDoor { + condition = QUOTE([ARR_2(this,'doorRB')] call EFUNC(compat_rhs_usf3,canCloseDoor)); + }; + class CloseCargoLDoor: OpenCargoDoor { + condition = QUOTE([ARR_2(this,'doorLB')] call EFUNC(compat_rhs_usf3,canCloseDoor)); + }; + }; + }; + class RHS_UH60M2: RHS_UH60M {}; + class RHS_UH60M_ESSS: RHS_UH60M2 { + EGVAR(fastroping,enabled) = 0; + class Attributes: Attributes { + delete EGVAR(fastroping,equipFRIES); + }; + }; + + class RHS_UH60M_MEV: RHS_UH60M { + EGVAR(fastroping,enabled) = 0; + class Attributes: Attributes { + delete EGVAR(fastroping,equipFRIES); + }; + }; + + class RHS_UH60M_MEV2: RHS_UH60M_MEV { + EGVAR(fastroping,enabled) = 2; + class Attributes: Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; + }; + + class Heli_Transport_02_base_F; + class RHS_CH_47F_base: Heli_Transport_02_base_F { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{0.5, -7.15, -0.95}, {-0.5, -7.15, -0.95}}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_usf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_usf3,onPrepare); + + class UserActions { + class OpenCargoDoor; + class CloseCargoDoor: OpenCargoDoor { + condition = QUOTE([ARR_2(this,'ramp_anim')] call EFUNC(compat_rhs_usf3,canCloseDoor)); + }; + }; + }; + + class rhsusf_CH53E_USMC: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {{0,-9.5,2.6}}; + EGVAR(fastroping,onCut) = QEFUNC(compat_rhs_usf3,onCut); + EGVAR(fastroping,onPrepare) = QEFUNC(compat_rhs_usf3,onPrepare); + + class UserActions { + class RampOpen; + class RampClose: RampOpen { + condition = QUOTE([ARR_2(this,'ramp_bottom')] call EFUNC(compat_rhs_usf3,canCloseDoor)); + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/config.cpp new file mode 100644 index 0000000000..ad3c97d1c4 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_fastroping" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/script_component.hpp new file mode 100644 index 0000000000..77632a2484 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_fastroping/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT fastroping +#define SUBCOMPONENT_BEAUTIFIED Fastroping +#include "..\script_component.hpp" + +#include "\z\ace\addons\fastroping\script_macros.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp new file mode 100644 index 0000000000..16a0628d1f --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp @@ -0,0 +1,8 @@ +class CfgAmmo { + // Use RHS Hellfire 3D Model on ACE Hellfires + class M_Scalpel_AT; + class ACE_Hellfire_AGM114K: M_Scalpel_AT { + model = "\rhsusf\addons\rhsusf_airweapons\proxyammo\rhsusf_m_AGM114K_fly"; + proxyShape = "\rhsusf\addons\rhsusf_airweapons\proxyammo\rhsusf_m_AGM114K"; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazineWells.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazineWells.hpp new file mode 100644 index 0000000000..e574b123a2 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazineWells.hpp @@ -0,0 +1,11 @@ +class CfgMagazineWells { + class ace_hellfire_K { + ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k), QGVAR(pylon_mag_4rnd_hellfire_k)}; + }; + class ace_hellfire_N { + ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_n), QGVAR(pylon_mag_4rnd_hellfire_n)}; + }; + class ace_hellfire_L { + ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_l), QGVAR(pylon_mag_4rnd_hellfire_l)}; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazines.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazines.hpp new file mode 100644 index 0000000000..9d96974ab8 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazines.hpp @@ -0,0 +1,37 @@ +class CfgMagazines { + // 2x ACE Hellfire racks + class rhs_mag_AGM114K_2; + class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 { + displayName = "2x AGM-114K [ACE]"; + pylonWeapon = "ace_hellfire_launcher"; + ammo = "ACE_Hellfire_AGM114K"; + }; + class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 { + displayName = "2x AGM-114N [ACE]"; + pylonWeapon = "ace_hellfire_launcher_N"; + ammo = "ACE_Hellfire_AGM114N"; + }; + class GVAR(pylon_mag_2rnd_hellfire_l): rhs_mag_AGM114K_2 { + displayName = "2x AGM-114L [ACE]"; + pylonWeapon = "ace_hellfire_launcher_L"; + ammo = "ACE_Hellfire_AGM114L"; + }; + + // 4x ACE Hellfire racks that align better on RHS Apaches and Blackhawks than the standard ACE 4x racks + class rhs_mag_AGM114K_4; + class GVAR(pylon_mag_4rnd_hellfire_k): rhs_mag_AGM114K_4 { + displayName = "4x AGM-114K [ACE]"; + pylonWeapon = "ace_hellfire_launcher"; + ammo = "ACE_Hellfire_AGM114K"; + }; + class GVAR(pylon_mag_4rnd_hellfire_n): rhs_mag_AGM114K_4 { + displayName = "4x AGM-114N [ACE]"; + pylonWeapon = "ace_hellfire_launcher_N"; + ammo = "ACE_Hellfire_AGM114N"; + }; + class GVAR(pylon_mag_4rnd_hellfire_l): rhs_mag_AGM114K_4 { + displayName = "4x AGM-114L [ACE]"; + pylonWeapon = "ace_hellfire_launcher_L"; + ammo = "ACE_Hellfire_AGM114L"; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/config.cpp new file mode 100644 index 0000000000..f460508a18 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_hellfire" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgMagazineWells.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/script_component.hpp new file mode 100644 index 0000000000..387de2d3ad --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hellfire +#define SUBCOMPONENT_BEAUTIFIED Hellfire +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp new file mode 100644 index 0000000000..65ca880587 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgAmmo.hpp @@ -0,0 +1,39 @@ +class CfgAmmo { + class MissileBase; + class rhs_ammo_M_fgm148_AT: MissileBase { + irLock = 1; + laserLock = 0; + airLock = 0; + + // Begin ACE guidance Configs + class ace_missileguidance { + enabled = 1; + + minDeflection = 0.00005; // Minium flap deflection for guidance + maxDeflection = 0.025; // Maximum flap deflection for guidance + incDeflection = 0.00005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "Optic"; + seekerTypes[] = { "Optic" }; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + seekerAngle = 180; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + + // Attack profile type selection + defaultAttackProfile = "JAV_TOP"; + attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; + useModeForAttackProfile = 1; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgWeapons.hpp new file mode 100644 index 0000000000..678293925d --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/CfgWeapons.hpp @@ -0,0 +1,19 @@ +class CfgWeapons { + class launch_O_Titan_F; + class rhs_weap_fgm148: launch_O_Titan_F { + EGVAR(javelin,enabled) = 1; + EGVAR(overpressure,offset) = 1.1; + weaponInfoType = "ACE_RscOptics_javelin"; + modelOptics = "\z\ace\addons\javelin\data\reticle_titan.p3d"; + canLock = 0; + lockingTargetSound[] = {"",0,1}; + lockedTargetSound[] = {"",0,1}; + class Single; + class Cruise: Single { + EGVAR(missileGuidance,attackProfile) = "JAV_DIR"; + }; + class TopDown: Single { + EGVAR(missileGuidance,attackProfile) = "JAV_TOP"; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/config.cpp new file mode 100644 index 0000000000..de6f0491c6 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_javelin" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/script_component.hpp new file mode 100644 index 0000000000..d42e0f4f01 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_javelin/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT javelin +#define SUBCOMPONENT_BEAUTIFIED Javelin +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/CfgWeapons.hpp new file mode 100644 index 0000000000..006d332186 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/CfgWeapons.hpp @@ -0,0 +1,13 @@ +class CfgWeapons { + class NVGoggles; + class rhsusf_ANPVS_14: NVGoggles { // Monocular + modelOptics = ""; + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_4096.paa); + EGVAR(nightvision,bluRadius) = 0.13; + }; + class rhsusf_ANPVS_15: rhsusf_ANPVS_14 { // Binocular (same as base) + modelOptics = ""; + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_binos_4096.paa); + EGVAR(nightvision,bluRadius) = 0.15; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/config.cpp new file mode 100644 index 0000000000..54da457d4f --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_nightvision" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/script_component.hpp new file mode 100644 index 0000000000..85036e02b6 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_nightvision/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nightvision +#define SUBCOMPONENT_BEAUTIFIED Night Vision +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgEventHandlers.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9d5f334607 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgEventHandlers.hpp @@ -0,0 +1,7 @@ +class Extended_InitPost_EventHandlers { + class rhsusf_props_ScepterMFC_Base { + class ADDON { + init = QUOTE(call EFUNC(refuel,makeJerryCan)); + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp new file mode 100644 index 0000000000..bf600d5d5a --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_refuel" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgEventHandlers.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/script_component.hpp new file mode 100644 index 0000000000..b58db9432d --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED Refuel +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/CfgWeapons.hpp new file mode 100644 index 0000000000..8e440c8c57 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/CfgWeapons.hpp @@ -0,0 +1,123 @@ +class CfgWeapons { + // RHS sniper scopes + class ItemCore; + class InventoryOpticsItem_Base_F; + class rhsusf_acc_sniper_base: ItemCore { + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class pso1_scope { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + // ACOG is a sniper scope for some reason, but we don't want scope adjust + class rhsusf_acc_ACOG: rhsusf_acc_sniper_base { + ACE_ScopeAdjust_Vertical[] = { 0, 0 }; + ACE_ScopeAdjust_Horizontal[] = { 0, 0 }; + ACE_ScopeAdjust_VerticalIncrement = 0; + ACE_ScopeAdjust_HorizontalIncrement = 0; + }; + class rhsusf_acc_LEUPOLDMK4: rhsusf_acc_sniper_base { + ACE_ScopeHeightAboveRail = 2.62567; + }; + class rhsusf_acc_LEUPOLDMK4_2: rhsusf_acc_sniper_base { + ACE_ScopeHeightAboveRail = 3.86377; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class pso1_scope { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class rhsusf_acc_premier: rhsusf_acc_LEUPOLDMK4_2 { + ACE_ScopeHeightAboveRail = 5.26066; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class pso1_scope { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class rhsusf_acc_premier_low: rhsusf_acc_premier { + ACE_ScopeHeightAboveRail = 3.90899; + }; + class rhsusf_acc_premier_anpvs27: rhsusf_acc_premier { + ACE_ScopeHeightAboveRail = 5.25066; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class pso1_nvg { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class rhsusf_acc_M8541: rhsusf_acc_premier { // http://www.schmidtundbender.de/en/products/police-and-military-forces/3-12x50-pm-iilpmtc.html + ACE_ScopeHeightAboveRail = 4.2235; + ACE_ScopeAdjust_Vertical[] = {0, 22}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class Snip { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class rhsusf_acc_M8541_low: rhsusf_acc_M8541 { + ACE_ScopeHeightAboveRail = 2.9789; + }; + class rhsusf_acc_nxs_3515x50_base: ItemCore { // http://www.nightforceusa.com/PDF/nightforce-2011-catalog.pdf#page=12 + ACE_ScopeAdjust_Vertical[] = {0, 30}; + ACE_ScopeAdjust_Horizontal[] = {-10.9, 10.9}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class nxs_scope { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class rhsusf_acc_nxs_3515x50f1_base: rhsusf_acc_sniper_base { // http://www.nightforceusa.com/PDF/nightforce-2011-catalog.pdf#page=12 + ACE_ScopeAdjust_Vertical[] = {0, 30}; + ACE_ScopeAdjust_Horizontal[] = {-10.9, 10.9}; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class nxs_scope { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class rhsusf_acc_nxs_5522x56_base: ItemCore { // http://www.nightforceusa.com/PDF/nightforce-2011-catalog.pdf#page=12 + ACE_ScopeAdjust_Vertical[] = {0, 27.3}; + ACE_ScopeAdjust_Horizontal[] = {-8.2, 8.2}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class nxs_scope { + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/config.cpp new file mode 100644 index 0000000000..62db11efe8 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_scopes" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/script_component.hpp new file mode 100644 index 0000000000..613b4322f9 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_scopes/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT scopes +#define SUBCOMPONENT_BEAUTIFIED Scopes +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/config.cpp b/addons/compat_rhs_usf3/config.cpp new file mode 100644 index 0000000000..73b4723b2c --- /dev/null +++ b/addons/compat_rhs_usf3/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"rhsusf_main_loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "Fyuran"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" +#include "CfgGlasses.hpp" +#include "CfgJointRails.hpp" diff --git a/addons/compat_rhs_usf3/functions/fnc_canCloseDoor.sqf b/addons/compat_rhs_usf3/functions/fnc_canCloseDoor.sqf new file mode 100644 index 0000000000..8b7b9a392a --- /dev/null +++ b/addons/compat_rhs_usf3/functions/fnc_canCloseDoor.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Checks if the door can be closed. + * + * Arguments: + * 0: Helicopter + * 1: Door + * + * Return Value: + * Door can be closed + * + * Example: + * [_vehicle, "DoorLB"] call ace_compat_rhs_usf3_fnc_canCloseDoor + * + * Public: No + */ + +params ["_vehicle", "_door"]; + +(alive _vehicle) && +{!(_vehicle getVariable [QEGVAR(fastroping,doorsLocked),false])} && +{ + switch (true) do { + case (_vehicle isKindOf "rhsusf_CH53E_USMC"): { + ((_vehicle animationPhase _door) > 0) && + {ACE_player == (driver _vehicle)} + }; + case (_vehicle isKindOf "RHS_CH_47F"): { + ((_vehicle animationSourcePhase _door) > 0) && + {ACE_player in [driver _vehicle, _vehicle turretUnit [3], _vehicle turretUnit [4]]} + }; + default { + ((_vehicle doorPhase _door) > 0) && + {ACE_player in _vehicle} + }; + } +} diff --git a/addons/compat_rhs_usf3/functions/fnc_onCut.sqf b/addons/compat_rhs_usf3/functions/fnc_onCut.sqf new file mode 100644 index 0000000000..840c2aa2a7 --- /dev/null +++ b/addons/compat_rhs_usf3/functions/fnc_onCut.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Function for closing doors and retracting the hooks for RHS USF helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_rhs_usf3_fnc_onCut + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable [QEGVAR(fastroping,doorsLocked), false, true]; + +private _fries = _vehicle getVariable [QEGVAR(fastroping,FRIES), objNull]; +if !(isNull _fries) then { + _fries animate ["extendHookRight", 0]; + _fries animate ["extendHookLeft", 0]; + [{ + _this animateDoor ["doorRB", 0]; + _this animateDoor ["doorLB", 0]; + _this animate ["doorHandler_R",0]; + _this animate ["doorHandler_L",0]; + }, _vehicle, 2] call CBA_fnc_waitAndExecute; + + 4 +} else { + _vehicle animateDoor ["ramp_anim", 0]; + _vehicle animate ["ramp_bottom",0]; + _vehicle animate ["ramp_top",0]; + + 2 +}; diff --git a/addons/compat_rhs_usf3/functions/fnc_onPrepare.sqf b/addons/compat_rhs_usf3/functions/fnc_onPrepare.sqf new file mode 100644 index 0000000000..39821fb9bd --- /dev/null +++ b/addons/compat_rhs_usf3/functions/fnc_onPrepare.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Function for opening doors and extending the hook for most vanilla helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_rhs_usf3_fnc_onPrepare + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable [QEGVAR(fastroping,doorsLocked), true, true]; + +private _waitTime = 2; + +_vehicle animateDoor ["doorRB", 1]; +_vehicle animateDoor ["doorLB", 1]; +_vehicle animate ["doorHandler_R",1]; +_vehicle animate ["doorHandler_L",1]; +_vehicle animateDoor ["ramp_anim", 1]; +_vehicle animate ["ramp_bottom",0.56]; +_vehicle animate ["ramp_top",1]; + +private _fries = _vehicle getVariable [QEGVAR(fastroping,FRIES), objNull]; +if !(isNull _fries) then { + [{ + _this animate ["extendHookRight", 1]; + _this animate ["extendHookLeft", 1]; + }, _fries, 2] call CBA_fnc_waitAndExecute; + _waitTime = 4; +}; + +_waitTime diff --git a/addons/compat_rhs_usf3/script_component.hpp b/addons/compat_rhs_usf3/script_component.hpp new file mode 100644 index 0000000000..b84324ad8f --- /dev/null +++ b/addons/compat_rhs_usf3/script_component.hpp @@ -0,0 +1,10 @@ +#define COMPONENT compat_rhs_usf3 +#define COMPONENT_BEAUTIFIED RHS USAF Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" + +// Backwards compatibility +#undef GVAR +#define GVAR(var) TRIPLES(PREFIX,COMPONENT,var) diff --git a/optionals/compat_rksl_pm_ii/$PBOPREFIX$ b/addons/compat_rksl_pm_ii/$PBOPREFIX$ similarity index 100% rename from optionals/compat_rksl_pm_ii/$PBOPREFIX$ rename to addons/compat_rksl_pm_ii/$PBOPREFIX$ diff --git a/addons/compat_rksl_pm_ii/CfgWeapons.hpp b/addons/compat_rksl_pm_ii/CfgWeapons.hpp new file mode 100644 index 0000000000..d787565419 --- /dev/null +++ b/addons/compat_rksl_pm_ii/CfgWeapons.hpp @@ -0,0 +1,41 @@ + +class CfgWeapons { + class ItemCore; + class InventoryOpticsItem_Base_F; + + class RKSL_optic_PMII_312: ItemCore { // https://www.schmidtundbender.de/en/products/police-military-forces/3-12x50-pm-ii.html + ACE_ScopeHeightAboveRail = 4.2235; + ACE_ScopeAdjust_Vertical[] = {0, 13}; // Single Turn + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class Snip { + discreteDistance[] = {100}; // default RKSL {100,...,1500} + discreteDistanceInitIndex = 0; + distanceZoomMax = 1500; // default RKSL 100 + distanceZoomMin = 100; // default RKSL + }; + }; + }; + }; + + class RKSL_optic_PMII_525: ItemCore { // https://www.schmidtundbender.de/en/products/police-military-forces/5-25x56-pm-iilp.html + ACE_ScopeHeightAboveRail = 4.2235; + ACE_ScopeAdjust_Vertical[] = {0, 26}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class Snip { + discreteDistance[] = {100}; // default RKSL {300,...,2500} + discreteDistanceInitIndex = 0; + distanceZoomMax = 2500; // default RKSL 300 + distanceZoomMin = 300; // default RKSL + }; + }; + }; + }; +}; diff --git a/addons/compat_rksl_pm_ii/config.cpp b/addons/compat_rksl_pm_ii/config.cpp new file mode 100644 index 0000000000..e9f2abcbfa --- /dev/null +++ b/addons/compat_rksl_pm_ii/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_scopes", "RKSL_PMII", "RKSL_PMII_525"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg", "Dedmen"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/optionals/compat_rksl_pm_ii/script_component.hpp b/addons/compat_rksl_pm_ii/script_component.hpp similarity index 100% rename from optionals/compat_rksl_pm_ii/script_component.hpp rename to addons/compat_rksl_pm_ii/script_component.hpp diff --git a/optionals/compat_sma3_iansky/$PBOPREFIX$ b/addons/compat_sma3_iansky/$PBOPREFIX$ similarity index 100% rename from optionals/compat_sma3_iansky/$PBOPREFIX$ rename to addons/compat_sma3_iansky/$PBOPREFIX$ diff --git a/addons/compat_sma3_iansky/CfgWeapons.hpp b/addons/compat_sma3_iansky/CfgWeapons.hpp new file mode 100644 index 0000000000..e3d3e5a998 --- /dev/null +++ b/addons/compat_sma3_iansky/CfgWeapons.hpp @@ -0,0 +1,20 @@ + +class CfgWeapons { + class ItemCore; + class InventoryOpticsItem_Base_F; + + class iansky_nfbeast: ItemCore { + ACE_ScopeAdjust_Vertical[] = { -0.9, 34 }; + ACE_ScopeAdjust_Horizontal[] = { -11, 11 }; + ACE_ScopeAdjust_VerticalIncrement = 0.2; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class NF25_MILDOT { + discreteDistance[] = { 100 }; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; +}; diff --git a/addons/compat_sma3_iansky/config.cpp b/addons/compat_sma3_iansky/config.cpp new file mode 100644 index 0000000000..71ff70755d --- /dev/null +++ b/addons/compat_sma3_iansky/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_scopes", "iansky_opt"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Ruthberg"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/optionals/compat_sma3_iansky/script_component.hpp b/addons/compat_sma3_iansky/script_component.hpp similarity index 100% rename from optionals/compat_sma3_iansky/script_component.hpp rename to addons/compat_sma3_iansky/script_component.hpp diff --git a/addons/compat_sog/$PBOPREFIX$ b/addons/compat_sog/$PBOPREFIX$ new file mode 100644 index 0000000000..fd2896297c --- /dev/null +++ b/addons/compat_sog/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_sog diff --git a/addons/compat_sog/ACE_CSW_Groups.hpp b/addons/compat_sog/ACE_CSW_Groups.hpp new file mode 100644 index 0000000000..2bc81dbb65 --- /dev/null +++ b/addons/compat_sog/ACE_CSW_Groups.hpp @@ -0,0 +1,94 @@ +class ACE_CSW_Groups { + + // --- Gun Turrets ------------------------------------------------------------- + + class ace_csw_100Rnd_127x99_mag { + vn_m2_v_100_mag = 1; + }; + + class GVAR(tow_missile) { + vn_missile_tow_mag_x1 = 1; + }; + + class GVAR(m1919_250) { + vn_m1919_v_250_mag = 1; + }; + + class GVAR(m60_200) { + vn_m60_v_200_mag = 1; + }; + + class vn_m60_100_mag { + vn_m60_v_100_mag = 1; + }; + + class GVAR(dshkm_50) { + vn_dshkm_v_50_mag = 1; + }; + + class vn_rpd_100_mag { + vn_rpd_v_100_mag = 1; + }; + + class vn_pk_100_mag { + vn_pk_v_100_mag = 1; + }; + + class GVAR(mg42_250) { + vn_mg42_v_250_mag = 1; + }; + + class GVAR(sgm_250) { + vn_sgm_v_250_mag = 1; + }; + + class GVAR(mk18_24) { + vn_mk18_v_24_mag = 1; + }; + + class GVAR(mk18_48) { + vn_mk18_v_48_mag = 1; + }; + + // --- Mortars ----------------------------------------------------------------- + + class GVAR(81mm_he) { + vn_mortar_m29_mag_he_x8 = 1; + }; + + class GVAR(81mm_wp) { + vn_mortar_m29_mag_wp_x8 = 1; + }; + + class GVAR(81mm_chem) { + vn_mortar_m29_mag_chem_x8 = 1; + }; + + class GVAR(81mm_lume) { + vn_mortar_m29_mag_lume_x8 = 1; + }; + + class GVAR(60mm_he) { + vn_mortar_m2_mag_he_x8 = 1; + }; + + class GVAR(60mm_wp) { + vn_mortar_m2_mag_wp_x8 = 1; + }; + + class GVAR(60mm_lume) { + vn_mortar_m2_mag_lume_x8 = 1; + }; + + class GVAR(82mm_he) { + vn_mortar_type53_mag_he_x8 = 1; + }; + + class GVAR(82mm_wp) { + vn_mortar_type53_mag_wp_x8 = 1; + }; + + class GVAR(82mm_lume) { + vn_mortar_type53_mag_lume_x8 = 1; + }; +}; diff --git a/addons/compat_sog/ACE_Medical_Injuries.hpp b/addons/compat_sog/ACE_Medical_Injuries.hpp new file mode 100644 index 0000000000..62acb1401f --- /dev/null +++ b/addons/compat_sog/ACE_Medical_Injuries.hpp @@ -0,0 +1,15 @@ +class ACE_Medical_Injuries { + class damageTypes { + class woundHandlers; + + class explosive { + class woundHandlers: woundHandlers {}; + }; + class GVAR(explosive_incendiary): explosive { + class woundHandlers: woundHandlers { + // TODO use function name after bug with the woundHandlers config caching is fixed + ADDON = QUOTE({call FUNC(woundsHandlerIncendiary)}); + }; + }; + }; +}; diff --git a/addons/compat_sog/ACE_Triggers.hpp b/addons/compat_sog/ACE_Triggers.hpp new file mode 100644 index 0000000000..f7a804da13 --- /dev/null +++ b/addons/compat_sog/ACE_Triggers.hpp @@ -0,0 +1,11 @@ +class ACE_Triggers { + class Command; + class GVAR(Command): Command { + isAttachable = 0; + }; + + class MK16_Transmitter: Command {}; // define parent class to make this a soft depency on ACE Explosives + class GVAR(MK16_Transmitter): MK16_Transmitter { + isAttachable = 0; + }; +}; diff --git a/addons/compat_sog/CfgAmmo.hpp b/addons/compat_sog/CfgAmmo.hpp new file mode 100644 index 0000000000..0917727974 --- /dev/null +++ b/addons/compat_sog/CfgAmmo.hpp @@ -0,0 +1,6 @@ +class CfgAmmo { + #include "CfgAmmo\bombs.hpp" + #include "CfgAmmo\explosives.hpp" + #include "CfgAmmo\grenades.hpp" + #include "CfgAmmo\melee.hpp" +}; diff --git a/addons/compat_sog/CfgAmmo/bombs.hpp b/addons/compat_sog/CfgAmmo/bombs.hpp new file mode 100644 index 0000000000..0e35c7b6ec --- /dev/null +++ b/addons/compat_sog/CfgAmmo/bombs.hpp @@ -0,0 +1,15 @@ + +class BombCore; +class vn_bomb_base_he: BombCore { + ACE_damageType = "explosive"; +}; + +class Mo_cluster_AP; +class vn_napalm_cluster_bomb_01: Mo_cluster_AP { + ACE_damageType = QGVAR(explosive_incendiary); +}; + +class ShellBase; +class sticky_napalm_red_small: ShellBase { + ACE_damageType = QGVAR(explosive_incendiary); +}; diff --git a/addons/compat_sog/CfgAmmo/explosives.hpp b/addons/compat_sog/CfgAmmo/explosives.hpp new file mode 100644 index 0000000000..849f7e6948 --- /dev/null +++ b/addons/compat_sog/CfgAmmo/explosives.hpp @@ -0,0 +1,165 @@ +class DirectionalBombBase; +class vn_mine_m18_ammo: DirectionalBombBase { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.15}; + EGVAR(explosives,size) = 1; + EGVAR(explosives,explosive) = "vn_mine_m18_ammo_scripted"; +}; + +class vn_mine_m18_x3_ammo: vn_mine_m18_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.1}; + EGVAR(explosives,explosive) = "vn_mine_m18_x3_ammo_scripted"; +}; + +class vn_mine_m18_wp_ammo: vn_mine_m18_ammo { + EGVAR(explosives,explosive) = "vn_mine_m18_wp_ammo_scripted"; +}; + +class vn_mine_m16_base; +class vn_mine_tripwire_m16_02_ammo: vn_mine_m16_base { + EGVAR(explosives,defuseObjectPosition)[] = {0, -0.01, 0.088}; +}; + +class APERSTripMine_Wire_Ammo; +class vn_mine_tripwire_f1_02_ammo: APERSTripMine_Wire_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, -0.01, 0.18}; +}; + +class vn_mine_tripwire_arty_ammo: vn_mine_tripwire_f1_02_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, -0.01, 0.126}; +}; + +class DemoCharge_Remote_Ammo; +class vn_mine_m112_remote_ammo: DemoCharge_Remote_Ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0, 0.22, 0.75}; +}; + +// Disable engine damage of punji traps, script damage manually +// This allows a tighter control of caused wounds and removes ear ringing +class APERSBoundingMine_Range_Ammo; +class vn_mine_punji_01_ammo: APERSBoundingMine_Range_Ammo { + EGVAR(minedetector,detectable) = 0; + + hit = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_punji_01_ammo' >> 'GVAR(hit)')); + GVAR(hit) = QUOTE([ARR_2(0,1)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); + + indirectHit = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_punji_01_ammo' >> 'GVAR(indirectHit)')); + GVAR(indirectHit) = QUOTE([ARR_2(0,10)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); + + class EventHandlers { + class ADDON { + AmmoHit = QUOTE(call FUNC(handlePunjiTrapTrigger)); + }; + }; +}; + +class vn_mine_punji_02_ammo: vn_mine_punji_01_ammo { + indirectHit = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_punji_02_ammo' >> 'GVAR(indirectHit)')); + GVAR(indirectHit) = QUOTE([ARR_2(0,5)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); +}; + +class vn_mine_punji_03_ammo: vn_mine_punji_01_ammo { + EGVAR(explosives,defuseObjectPosition)[] = {0.25, 0.023, 0.035}; + + class EventHandlers { + class ADDON { + AmmoHit = QUOTE(call FUNC(handlePunjiTrapTrigger)); + }; + }; +}; + +class vn_mine_punji_04_ammo: APERSBoundingMine_Range_Ammo { + EGVAR(minedetector,detectable) = 0; + + hit = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_punji_01_ammo' >> 'GVAR(hit)')); + GVAR(hit) = QUOTE([ARR_2(0,1)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); + + indirectHit = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_punji_01_ammo' >> 'GVAR(indirectHit)')); + GVAR(indirectHit) = QUOTE([ARR_2(0,10)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); + + GVAR(spikesOffset)[] = {0, 0, 1.8}; + GVAR(spikesCheckSelection) = "head"; + GVAR(spikesCheckRadius) = 1; + + class EventHandlers { + class ADDON { + AmmoHit = QUOTE(call FUNC(handlePunjiTrapTrigger)); + }; + }; +}; + +class vn_mine_punji_05_ammo: vn_mine_punji_04_ammo { + GVAR(spikesOffset)[] = {0, 0, 0}; + GVAR(spikesCheckSelection) = ""; + + class EventHandlers { + class ADDON { + AmmoHit = QUOTE(call FUNC(handlePunjiTrapTrigger)); + }; + }; +}; + +class APERSMine_Range_Ammo; +class vn_mine_bike_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,explosive) = "vn_mine_bike_ammo_scripted"; +}; + +class vn_mine_cartridge_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,explosive) = "vn_mine_cartridge_ammo_scripted"; + + // bump range and damage slightly, default values do not work well with ACE Medical + indirectHit = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_cartridge_ammo' >> 'GVAR(indirectHit)')); + GVAR(indirectHit) = QUOTE([ARR_2(2,1)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); + + indirectHitRange = QUOTE(getNumber (configFile >> 'CfgAmmo' >> 'vn_mine_cartridge_ammo' >> 'GVAR(indirectHitRange)')); + GVAR(indirectHitRange) = QUOTE([ARR_2(0.7,0.3)] select isNull (configFile >> 'CfgPatches' >> 'ace_medical')); +}; + +class vn_mine_lighter_ammo: APERSMine_Range_Ammo { + ACE_damageType = QGVAR(explosive_incendiary); + + EGVAR(explosives,explosive) = "vn_mine_lighter_ammo_scripted"; +}; + +class vn_mine_jerrycan_ammo: APERSMine_Range_Ammo { + ACE_damageType = QGVAR(explosive_incendiary); + + EGVAR(explosives,explosive) = "vn_mine_jerrycan_ammo_scripted"; +}; + +class vn_mine_pot_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,explosive) = "vn_mine_pot_ammo_scripted"; +}; + +class vn_mine_mortar_range_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,explosive) = "vn_mine_mortar_range_ammo_scripted"; +}; + +class vn_mine_limpet_01_ammo: DemoCharge_Remote_Ammo { + EGVAR(explosives,explosive) = "vn_mine_limpet_01_ammo_scripted"; +}; + +class vn_mine_limpet_02_ammo: vn_mine_limpet_01_ammo { + EGVAR(explosives,explosive) = "vn_mine_limpet_02_ammo_scripted"; +}; + +class vn_mine_chicom_no8_ammo: APERSMine_Range_Ammo { + EGVAR(explosives,explosive) = "vn_mine_chicom_no8_ammo_scripted"; +}; + +class vn_mine_dh10_ammo: DirectionalBombBase { + EGVAR(explosives,explosive) = "vn_mine_dh10_ammo_scripted"; +}; + +class PipeBombBase; +class vn_mine_gboard_range_ammo: PipeBombBase { + EGVAR(explosives,explosive) = "vn_mine_gboard_range_ammo_scripted"; +}; + +class SatchelCharge_Remote_Ammo; +class vn_mine_satchelcharge_02_ammo: SatchelCharge_Remote_Ammo { + EGVAR(explosives,explosive) = "vn_mine_satchelcharge_02_ammo_scripted"; +}; + +class vn_mine_bangalore_ammo: SatchelCharge_Remote_Ammo { + EGVAR(explosives,explosive) = "vn_mine_bangalore_ammo_scripted"; +}; diff --git a/addons/compat_sog/CfgAmmo/grenades.hpp b/addons/compat_sog/CfgAmmo/grenades.hpp new file mode 100644 index 0000000000..6395756f64 --- /dev/null +++ b/addons/compat_sog/CfgAmmo/grenades.hpp @@ -0,0 +1,17 @@ +class vn_grenadehand; +class vn_molotov_grenade_ammo: vn_grenadehand { + ACE_damageType = QGVAR(explosive_incendiary); + EGVAR(frag,enabled) = 0; +}; + +class vn_t67_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}}; +}; +class vn_chicom_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}}; +}; + +class SmokeShell; +class vn_m14_grenade_ammo: SmokeShell { + EGVAR(grenades,incendiary) = 1; +}; diff --git a/addons/compat_sog/CfgAmmo/melee.hpp b/addons/compat_sog/CfgAmmo/melee.hpp new file mode 100644 index 0000000000..68f09299c4 --- /dev/null +++ b/addons/compat_sog/CfgAmmo/melee.hpp @@ -0,0 +1,8 @@ +class BulletBase; +class vn_melee_stab: BulletBase { + ACE_damageType = "stab"; +}; + +class vn_melee_stun: vn_melee_stab { + ACE_damageType = "punch"; +}; diff --git a/addons/compat_sog/CfgEventHandlers.hpp b/addons/compat_sog/CfgEventHandlers.hpp new file mode 100644 index 0000000000..d28b79fb99 --- /dev/null +++ b/addons/compat_sog/CfgEventHandlers.hpp @@ -0,0 +1,50 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + +class Extended_InitPost_EventHandlers { + class GVAR(spiderhole_01_nogeo) { + class ADDON { + init = QUOTE((_this select 0) setMass 1e-12); + }; + }; + class GVAR(spiderhole_02_nogeo) { + class ADDON { + init = QUOTE((_this select 0) setMass 1e-12); + }; + }; + class GVAR(spiderhole_03_nogeo) { + class ADDON { + init = QUOTE((_this select 0) setMass 1e-12); + }; + }; + class Land_vn_canisterfuel_f { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; + class Land_vn_fuelcan { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; + class vn_bicycle_base { + class ADDON { + init = QUOTE(call FUNC(disableCookoff)); + }; + }; +}; diff --git a/addons/compat_sog/CfgGlasses.hpp b/addons/compat_sog/CfgGlasses.hpp new file mode 100644 index 0000000000..0199591ec2 --- /dev/null +++ b/addons/compat_sog/CfgGlasses.hpp @@ -0,0 +1,4 @@ + +class CfgGlasses { + // TODO - Custom overlays are left as an exercise for the reader. +}; diff --git a/addons/compat_sog/CfgMagazines.hpp b/addons/compat_sog/CfgMagazines.hpp new file mode 100644 index 0000000000..c67e12edbc --- /dev/null +++ b/addons/compat_sog/CfgMagazines.hpp @@ -0,0 +1,6 @@ +class CfgMagazines { + #include "CfgMagazines\belts.hpp" + #include "CfgMagazines\csw.hpp" + #include "CfgMagazines\explosives.hpp" + #include "CfgMagazines\food.hpp" +}; diff --git a/addons/compat_sog/CfgMagazines/belts.hpp b/addons/compat_sog/CfgMagazines/belts.hpp new file mode 100644 index 0000000000..f46d6eec0c --- /dev/null +++ b/addons/compat_sog/CfgMagazines/belts.hpp @@ -0,0 +1,17 @@ +class vn_lmgmag_base; +class vn_m60_100_mag: vn_lmgmag_base { + ACE_isBelt = 1; +}; +class vn_pk_100_mag: vn_lmgmag_base { + ACE_isBelt = 1; +}; +class vn_rpd_100_mag: vn_lmgmag_base { + ACE_isBelt = 1; +}; +class vn_m16_mag_base; +class vn_m63a_100_mag: vn_m16_mag_base { + ACE_isBelt = 1; +}; +class vn_mg42_50_mag: vn_lmgmag_base { + ACE_isBelt = 1; +}; diff --git a/addons/compat_sog/CfgMagazines/csw.hpp b/addons/compat_sog/CfgMagazines/csw.hpp new file mode 100644 index 0000000000..f1532c6513 --- /dev/null +++ b/addons/compat_sog/CfgMagazines/csw.hpp @@ -0,0 +1,215 @@ +class vn_missile_tow_mag_x1; +class GVAR(tow_missile): vn_missile_tow_mag_x1 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\tow\vn_static_tow_mag.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_tow_ca.paa); + mass = 220; // to Arma, weight and volume are all the same which makes real life values unusable +}; + +// --- Gun Turrets ------------------------------------------------------------- + +class vn_m1919_v_250_mag; +class GVAR(m1919_250): vn_m1919_v_250_mag { + scope = 2; + scopeArsenal = 2; + type = 256; + count = 250; + model = "\vn\objects_f_vietnam\supply\a2_ammo\macv\vn_us_30cal.p3d"; + picture = QPATHTOF(UI\ammo_250rnd_30cal_ca.paa); + ACE_isBelt = 1; + mass = 170; +}; + +class vn_m60_v_200_mag; +class GVAR(m60_200): vn_m60_v_200_mag { + scope = 2; + type = 256; + count = 200; + model = "\vn\objects_f_vietnam\supply\a2_ammo\macv\vn_us_can_30.p3d"; + picture = QPATHTOF(UI\ammo_200rnd_762mm_ca.paa); + ACE_isBelt = 1; + mass = 187; +}; + +class vn_dshkm_v_50_mag; +class GVAR(dshkm_50): vn_dshkm_v_50_mag { + scope = 2; + type = 256; + count = 50; + model = "\vn\objects_f_vietnam\supply\a2_ammo\pavn\vn_pavn_50_can.p3d"; + picture = QPATHTOF(UI\ammo_50rnd_127mm_ca.paa); + ACE_isBelt = 1; + mass = 170; +}; + +class vn_mg42_v_250_mag; +class GVAR(mg42_250): vn_mg42_v_250_mag { + scope = 2; + type = 256; + model = "\vn\objects_f_vietnam\supply\a2_ammo\pavn\vn_pavn_30_can.p3d"; + picture = "\vn\weapons_f_vietnam\ui\icon_vn_pk_100_mag_ca.paa"; + ACE_isBelt = 1; + mass = 160; +}; + +class vn_sgm_v_250_mag; +class GVAR(sgm_250): vn_sgm_v_250_mag { + scope = 2; + type = 256; + model = "\vn\objects_f_vietnam\supply\a2_ammo\pavn\vn_pavn_30_can.p3d"; + picture = "\vn\weapons_f_vietnam\ui\icon_vn_pk_100_mag_ca.paa"; + ACE_isBelt = 1; + mass = 160; +}; + +class vn_mk18_v_24_mag; +class GVAR(mk18_24): vn_mk18_v_24_mag { + scope = 2; + type = 256; + 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); + mass = 160; +}; + +class vn_mk18_v_48_mag; +class GVAR(mk18_48): vn_mk18_v_48_mag { + scope = 2; + type = 256; + 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); + mass = 220; +}; + +// --- Mortars ----------------------------------------------------------------- + +class vn_mortar_m29_mag_he_x8; +class GVAR(81mm_he): vn_mortar_m29_mag_he_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m29\vn_shell_81mm_m374_he_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_81mm_ca.paa); + mass = 91; + displayName = CSTRING(Magazine_81mm_HE); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_m29_mag_wp_x8; +class GVAR(81mm_wp): vn_mortar_m29_mag_wp_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m29\vn_shell_81mm_m374_he_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_81mm_ca.paa); + mass = 91; + displayName = CSTRING(Magazine_81mm_WP); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_m29_mag_chem_x8; +class GVAR(81mm_chem): vn_mortar_m29_mag_chem_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m29\vn_shell_81mm_m374_he_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_81mm_ca.paa); + mass = 91; + displayName = CSTRING(Magazine_81mm_Smoke); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_m29_mag_lume_x8; +class GVAR(81mm_lume): vn_mortar_m29_mag_lume_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m29\vn_shell_81mm_m374_he_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_81mm_ca.paa); + mass = 91; + displayName = CSTRING(Magazine_81mm_Lume); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_m2_mag_he_x8; +class GVAR(60mm_he): vn_mortar_m2_mag_he_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m2\vn_shell_60mm_m49a2_he_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_60mm_ca.paa); + mass = 37; + displayName = CSTRING(Magazine_60mm_HE); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_m2_mag_wp_x8; +class GVAR(60mm_wp): vn_mortar_m2_mag_wp_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m2\vn_shell_60mm_m302_wp_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_60mm_ca.paa); + mass = 37; + displayName = CSTRING(Magazine_60mm_WP); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_m2_mag_lume_x8; +class GVAR(60mm_lume): vn_mortar_m2_mag_lume_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_m2\vn_shell_60mm_m83_lume_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_60mm_ca.paa); + mass = 37; + displayName = CSTRING(Magazine_60mm_Lume); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_type53_mag_he_x8; +class GVAR(82mm_he): vn_mortar_type53_mag_he_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_type53\vn_shell_82mm_o832d_he_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_82mm_ca.paa); + mass = 70; + displayName = CSTRING(Magazine_82mm_HE); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_type53_mag_wp_x8; +class GVAR(82mm_wp): vn_mortar_type53_mag_wp_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_type53\vn_shell_82mm_d832_wp_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_82mm_ca.paa); + mass = 70; + displayName = CSTRING(Magazine_82mm_WP); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; + +class vn_mortar_type53_mag_lume_x8; +class GVAR(82mm_lume): vn_mortar_type53_mag_lume_x8 { + scope = 2; + type = 256; + count = 1; + model = "\vn\static_f_vietnam\mortar_type53\vn_shell_82mm_s832s_lume_ammo.p3d"; + picture = QPATHTOF(UI\ammo_1rnd_82mm_ca.paa); + mass = 70; + displayName = CSTRING(Magazine_82mm_Lume); + displayNameShort = ""; + descriptionShort = ECSTRING(mk6mortar,magazine_descriptionShort); +}; diff --git a/addons/compat_sog/CfgMagazines/explosives.hpp b/addons/compat_sog/CfgMagazines/explosives.hpp new file mode 100644 index 0000000000..7e25609fc8 --- /dev/null +++ b/addons/compat_sog/CfgMagazines/explosives.hpp @@ -0,0 +1,443 @@ +class vn_magazine; + +// Claymore (Remote) +class vn_mine_m18_mag: vn_magazine { + useAction = 0; + + displayNameShort = ""; // Every explosive inherits this and it breaks naming in the placing menu + + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m18); + + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + digDistance = -0.05; + fuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; +}; +// Claymore (Proximity) +class vn_mine_m18_range_mag: vn_mine_m18_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = -0.05; + }; + }; +}; + +// Claymore (Fuse) +class vn_mine_m18_fuze10_mag: vn_mine_m18_mag { + class ACE_Triggers: ACE_Triggers { + class Command: Command { + fuseTime = 10; + }; + class MK16_Transmitter: MK16_Transmitter { + fuseTime = 10; + }; + }; +}; + +// Claymore x3 (Remote) +class vn_mine_m18_x3_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m18_x3); + + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + digDistance = 0.02; + fuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; +}; +// Claymore x3 (Proximity) +class vn_mine_m18_x3_range_mag: vn_mine_m18_x3_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.02; + }; + }; +}; + +// WP Claymore (Remote) +class vn_mine_m18_wp_mag: vn_mine_m18_fuze10_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m18_wp); + + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + digDistance = -0.05; + fuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; +}; + +// WP Claymore (Proximity) +class vn_mine_m18_wp_range_mag: vn_mine_m18_wp_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = -0.05; + }; + }; +}; + +// WP Claymore (Fuse) +class vn_mine_m18_wp_fuze10_mag: vn_mine_m18_wp_mag { + class ACE_Triggers: ACE_Triggers { + class Command: Command { + fuseTime = 10; + }; + class MK16_Transmitter: MK16_Transmitter { + fuseTime = 10; + }; + }; +}; + +// Toe-Popper +class vn_mine_m14_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m14); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.001; + }; + }; +}; + +// Bounding Mine +class vn_mine_m16_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m16); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.02; + }; + }; +}; + +// Bounding Mine (Trip Wire 2m) +class vn_mine_tripwire_m16_02_mag: vn_mine_m16_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m16_tripwire_2m); + + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.02; + }; + }; +}; +// Bounding Mine (Trip Wire 4m) +class vn_mine_tripwire_m16_04_mag: vn_mine_tripwire_m16_02_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m16_tripwire_4m); + + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.02; + }; + }; +}; + +// F1 (Trip Wire 2m) +class vn_mine_tripwire_f1_02_mag: vn_mine_tripwire_m16_02_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(f1_tripwire_2m); +}; +// F1 (Trip Wire 4m) +class vn_mine_tripwire_f1_04_mag: vn_mine_tripwire_f1_02_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(f1_tripwire_4m); +}; + +// Arty Shell (Trip Wire 4m) +class vn_mine_tripwire_arty_mag: vn_mine_tripwire_m16_02_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(arty_tripwire_4m); +}; + +// Satchel Charge +class vn_mine_satchel_remote_02_mag: vn_mine_m18_mag { + useAction = 0; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(satchel_remote_02); + + 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 {}; + }; +}; + +// TM57 Anti-Tank Mine +class vn_mine_tm57_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(tm57); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate {}; + }; +}; + +// M15 Anti-Tank Mine +class vn_mine_m15_mag: vn_mine_tm57_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m15); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; +}; + +// M112 Breaching charge +class vn_mine_m112_remote_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(m112); + + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; + class Timer { + fuseTime = 0.5; + digDistance = 1; + }; + class Command { + fuseTime = 0.5; + digDistance = 1; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; +}; + +// Spiked ammo box +class vn_mine_ammobox_range_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(ammobox_range); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.01; + }; + }; +}; + +// Punji large +class vn_mine_punji_01_mag: vn_mine_m18_mag { + useAction = 0; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_01); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + displayName = CSTRING(Action_DigIn); + }; + }; +}; + +// Punji small +class vn_mine_punji_02_mag: vn_mine_punji_01_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_02); +}; + +// Punji whip +class vn_mine_punji_03_mag: vn_mine_punji_01_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_03); +}; + +// Punji door-way +class vn_mine_punji_04_mag: vn_mine_m18_mag { + useAction = 0; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_04); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + displayName = CSTRING(Action_DigIn); + digDistance = -2.14; + }; + }; +}; + +// Punji side whip +class vn_mine_punji_05_mag: vn_mine_punji_04_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(punji_05); + + class ACE_Triggers: ACE_Triggers { + class PressurePlate: PressurePlate { + digDistance = 0; + }; + }; +}; + +// Bike mine (Remote) +class vn_mine_bike_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bike); + + class ACE_Triggers { + SupportedTriggers[] = {QGVAR(Command), QGVAR(MK16_Transmitter)}; + class GVAR(Command) { + digDistance = 0; + fuseTime = 1; + }; + class GVAR(MK16_Transmitter): GVAR(Command) {}; + }; +}; +// Bike mine (Proximity) +class vn_mine_bike_range_mag: vn_mine_bike_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; +}; + +// Cartridge mine +class vn_mine_cartridge_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(cartridge); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; +}; + +// Lighter mine (Proximity) +class vn_mine_lighter_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(lighter); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; +}; + +// Pot mine (Remote) +class vn_mine_pot_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(pot); + + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + digDistance = 0; + fuseTime = 1; + }; + class MK16_Transmitter: Command {}; + }; +}; +// Pot mine (Proximity) +class vn_mine_pot_range_mag: vn_mine_pot_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; +}; + +// Jerrycan mine (Remote) +class vn_mine_jerrycan_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(jerrycan); + + class ACE_Triggers { + SupportedTriggers[] = {"Command", "MK16_Transmitter"}; + class Command { + digDistance = 0.02; + fuseTime = 1; + }; + class MK16_Transmitter: Command {}; + }; +}; +// Jerrycan mine (Proximity) +class vn_mine_jerrycan_range_mag: vn_mine_jerrycan_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.02; + }; + }; +}; + +// Mortar shell on a stick (Proximity) +class vn_mine_mortar_range_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(mortar_range); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.5; + }; + }; +}; + +// Limpet mine USA (Remote) +class vn_mine_limpet_01_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(limpet_01); +}; + +// Limpet mine RUS (Remote) +class vn_mine_limpet_02_mag: vn_mine_limpet_01_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(limpet_02); +}; + +// Chicom NO8 mine +class vn_mine_chicom_no8_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(chicom_no8); + + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; +}; + +// DH10 mine (Remote) +class vn_mine_dh10_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(dh10); +}; +// DH10 mine (Proximity) +class vn_mine_dh10_range_mag: vn_mine_dh10_mag { + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0; + }; + }; +}; + +// Grenade board mine (Tripwire 4m) +class vn_mine_gboard_range_mag: vn_mine_m18_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(gboard); + + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0; + }; + }; +}; + +// Satchel charge +class vn_mine_satchelcharge_02_mag: vn_mine_satchel_remote_02_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(satchelcharge_02); +}; + +// Bangalore mine +class vn_mine_bangalore_mag: vn_mine_satchel_remote_02_mag { + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bangalore); +}; diff --git a/addons/compat_sog/CfgMagazines/food.hpp b/addons/compat_sog/CfgMagazines/food.hpp new file mode 100644 index 0000000000..b8f2c956e2 --- /dev/null +++ b/addons/compat_sog/CfgMagazines/food.hpp @@ -0,0 +1,675 @@ +#define DRINKING_ANIMS \ + EXGVAR(field_rations,consumeAnims)[] = { \ + QEGVAR(field_rations,drinkStand), \ + QEGVAR(field_rations,drinkCrouch), \ + QEGVAR(field_rations,drinkProne) \ + } +#define DRINKING_SOUNDS \ + EXGVAR(field_rations,consumeSounds)[] = { \ + QEGVAR(field_rations,drink1), \ + QEGVAR(field_rations,drink1), \ + QEGVAR(field_rations,drink2) \ + } + +class vn_prop_base; + +// US Canteen 0.75l +class vn_prop_drink_01: vn_prop_base { + // assuming 250ml = 5% of thirst + EXGVAR(field_rations,thirstQuenched) = 15; + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// US Canteen 1.0l +class vn_prop_drink_02: vn_prop_drink_01 { + EXGVAR(field_rations,thirstQuenched) = 20; + EXGVAR(field_rations,replacementItem) = "ACE_Canteen_Empty"; +}; + +// NVA Canteen 0.76l +class vn_prop_drink_03: vn_prop_drink_01 { + EXGVAR(field_rations,thirstQuenched) = 16; +}; + +// NVA Canteen 1.1l +class vn_prop_drink_04: vn_prop_drink_01 { + EXGVAR(field_rations,thirstQuenched) = 22; + EXGVAR(field_rations,replacementItem) = "ACE_Canteen_Empty"; +}; + +// Bottle 0.5l +class vn_prop_drink_05: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = 10; + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Bottle 2.0l +class vn_prop_drink_06: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = 40; + + EXGVAR(field_rations,consumeTime) = 15; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Tilts Hot Sauce +class vn_prop_drink_07_01: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = -10; + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Hoangs Muoc Mam +class vn_prop_drink_07_02: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = -10; + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Napalm Sauce +class vn_prop_drink_07_03: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = -10; + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Savage Bia (Beer) +class vn_prop_drink_08_01: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = 10; + EXGVAR(field_rations,hungerSatiated) = 2; // beer is food too ;) + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Whiskey +class vn_prop_drink_09_01: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = 5; + + EXGVAR(field_rations,consumeTime) = 10; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Water pack 2.0l +class vn_prop_drink_10: vn_prop_base { + EXGVAR(field_rations,thirstQuenched) = 40; + + EXGVAR(field_rations,consumeTime) = 15; + DRINKING_ANIMS; + DRINKING_SOUNDS; +}; + +// Ration 0.75Kg +class vn_prop_food_meal_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 15; + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Fox Hole Dinner for Two. Chicken and Noodles + Turkey Loaf + Cheese Spread + Hot sauce +class vn_prop_food_meal_01_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Soup Du Jour. Ham and Lima Beans + Crackers + Hot sauce +class vn_prop_food_meal_01_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Breast of Chicken Under Bullets. Boned Chicken + Cheese Spread + White Bread + Hot sauce +class vn_prop_food_meal_01_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Battlefield Fufu. Boned Chicken + Peanut Butter + Milk + Hot sauce +class vn_prop_food_meal_01_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Ham with Spiced Apricots. Fried Ham + Apricots + Jam + Hot sauce +class vn_prop_food_meal_01_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Pork Mandarin. Pork-steak + Hot sauce +class vn_prop_food_meal_01_06: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Tin Can Casserole. Frank and Beans + Beefsteak + Crackers + Cheese Spread + Hot sauce +class vn_prop_food_meal_01_07: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Creamed Turkey on Toast. Turkey loaf + White Bread + Hot sauce +class vn_prop_food_meal_01_08: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Fish with Front line Stuffing. Crackers + Ham and Egg Chopped + Hot sauce +class vn_prop_food_meal_01_09: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Combat Zone Burgoo. Spiced Beef + Ham and Lima Beans + Crackers + Hot sauce +class vn_prop_food_meal_01_10: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Patrol Chicken Soup. Fresh Chicken + Crackers + Hot sauce +class vn_prop_food_meal_01_11: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Guard Relief Eggs Benedict. White Bread + Ham and Eggs Chopped + Cheese Spread + Hot sauce +class vn_prop_food_meal_01_12: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Beefsteak En Croute. White Bread + Beefsteak + Hot sauce +class vn_prop_food_meal_01_13: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Curried Meat Balls Over Rice. Meat Balls and Beans + Hot sauce +class vn_prop_food_meal_01_14: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Cease Fire Casserole. Beefsteak + Spiced Beef + Hot sauce +class vn_prop_food_meal_01_15: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Rice Paddy Shrimp. Fresh Shrimp + Cheese Spread + Hot sauce +class vn_prop_food_meal_01_16: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Battlefield Birthday Cake. Pound Cake + Chocolate Candy + Hot sauce +class vn_prop_food_meal_01_17: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Pecan Cake Roll with Peanut Butter Sauce. Pecan Cake Roll + Peanut Butter + Hot sauce +class vn_prop_food_meal_01_18: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,thirstQuenched) = -1; // hot! + + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Con ho. Rice + Tiger + Vegetables + Fish Sauce +class vn_prop_food_meal_02_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Con voi. Rice + Elephant + Vegetables + Fish Sauce +class vn_prop_food_meal_02_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Con ran. Rice + Snake + Vegetables + Fish Sauce +class vn_prop_food_meal_02_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Cha ca la vong. Rice + Fish + Vegetables + Fish Sauce +class vn_prop_food_meal_02_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Con tom. Rice + Shrimp + Vegetables + Fish sauce +class vn_prop_food_meal_02_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Pho ga. Rice + Chicken + Vegetables + Fish sauce +class vn_prop_food_meal_02_06: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// PIR Rations. Contains 1Kg of high energy food: PIR ration (Beef) +class vn_prop_food_pir_01_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// PIR Rations. Contains 1Kg of high energy food: PIR ration (Fish and Squid) +class vn_prop_food_pir_01_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// PIR Rations. Contains 1Kg of high energy food: PIR ration (Shrimp and Mushroom) +class vn_prop_food_pir_01_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// PIR Rations. Contains 1Kg of high energy food: PIR ration (Mutton) +class vn_prop_food_pir_01_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// PIR Rations. Contains 1Kg of high energy food: PIR ration (Sausage) +class vn_prop_food_pir_01_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 10Kg of food: Ration box (LRP Ration Box) +class vn_prop_food_box_01_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 100; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 10Kg of food: Ration box (PIR Ration Box) +class vn_prop_food_box_01_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 100; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 10Kg of food: Ration box (MCI Ration Box) +class vn_prop_food_box_01_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 100; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Ham and Eggs Chopped) +class vn_prop_food_box_02_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Ham Fried) +class vn_prop_food_box_02_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Beans w/ Frankfurter Chunks) +class vn_prop_food_box_02_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Spaghetti w/ Ground Meat) +class vn_prop_food_box_02_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Turkey Loaf) +class vn_prop_food_box_02_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Pork Steak) +class vn_prop_food_box_02_06: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Beef w/ Spiced Sauce) +class vn_prop_food_box_02_07: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Boxed Rations. Contains 2Kg of food: Ration box (Chicken Boned) +class vn_prop_food_box_02_08: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 50; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Beefsteak) +class vn_prop_food_can_01_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Spiced Sauce) +class vn_prop_food_can_01_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Turkey Loaf) +class vn_prop_food_can_01_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Ham, Fried) +class vn_prop_food_can_01_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Ham and Eggs Chopped) +class vn_prop_food_can_01_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Tuna) +class vn_prop_food_can_01_06: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Chicken and Noodles) +class vn_prop_food_can_01_07: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Chicken Boned) +class vn_prop_food_can_01_08: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Pork Slices with Juices) +class vn_prop_food_can_01_09: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (B-1A Unit Crackers and Candy) +class vn_prop_food_can_01_10: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (B-2 Unit Crackers and Cheese Spread) +class vn_prop_food_can_01_11: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Pound Cake) +class vn_prop_food_can_01_12: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Pecan Cake Roll) +class vn_prop_food_can_01_13: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Chocolate Nut Roll) +class vn_prop_food_can_01_14: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (Fruitcake) +class vn_prop_food_can_01_15: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.5Kg of food: Ration can (White Bread) +class vn_prop_food_can_01_16: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 25; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Beans w/ Meat Balls in Tomato Sauce) +class vn_prop_food_can_02_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Ham and Lima Beans) +class vn_prop_food_can_02_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Beans w/ Frankfurter Chunks in Tomato Sauce) +class vn_prop_food_can_02_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Spaghetti w/ Ground Meat) +class vn_prop_food_can_02_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (B-3 Unit Cookies, Jam and Cocoa Beverage Powder) +class vn_prop_food_can_02_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Apricots) +class vn_prop_food_can_02_06: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Peaches) +class vn_prop_food_can_02_07: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.75Kg of food: Ration can (Pears) +class vn_prop_food_can_02_08: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.3Kg of food: Ration can (Peanut Butter) +class vn_prop_food_can_03_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 15; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.3Kg of food: Ration can (Jam, Seedless Blackberry) +class vn_prop_food_can_03_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 15; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.3Kg of food: Ration can (Pineapple Jam) +class vn_prop_food_can_03_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 15; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Canned Rations. Contains 0.3Kg of food: Ration can (Cheese Spread) +class vn_prop_food_can_03_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 15; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Orange +class vn_prop_food_fresh_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 10; + EXGVAR(field_rations,thirstQuenched) = 10; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Pumpik 3Kg +class vn_prop_food_fresh_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,thirstQuenched) = 5; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Chicken 3Kg +class vn_prop_food_fresh_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 35; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Shrimp 3Kg +class vn_prop_food_fresh_04: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Fish 3Kg +class vn_prop_food_fresh_05: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Pork 3Kg +class vn_prop_food_fresh_06: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 35; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Snake 3Kg +class vn_prop_food_fresh_07: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Tiger 3Kg +class vn_prop_food_fresh_08: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Elephant 3Kg +class vn_prop_food_fresh_09: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 20; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// Rau Ma 3Kg +class vn_prop_food_fresh_10: vn_prop_food_fresh_03 { + EXGVAR(field_rations,hungerSatiated) = 30; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Beef Hash) +class vn_prop_food_lrrp_01_01: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Chili Con Carne) +class vn_prop_food_lrrp_01_02: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Spaghetti w/ Meat Sauce) +class vn_prop_food_lrrp_01_03: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Beef and Rice) +class vn_prop_food_lrrp_01_04: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Chicken Stew) +class vn_prop_food_lrrp_01_05: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Pork w/ Escalloped Potatoes) +class vn_prop_food_lrrp_01_06: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Beef Stew) +class vn_prop_food_lrrp_01_07: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; + +// LRRP Rations. Contains 1Kg of high energy food: LRRP ration (Chicken and Rice) +class vn_prop_food_lrrp_01_08: vn_prop_base { + EXGVAR(field_rations,hungerSatiated) = 90; + EXGVAR(field_rations,consumeTime) = 10; +}; diff --git a/addons/compat_sog/CfgVehicles.hpp b/addons/compat_sog/CfgVehicles.hpp new file mode 100644 index 0000000000..d96ae7b75c --- /dev/null +++ b/addons/compat_sog/CfgVehicles.hpp @@ -0,0 +1,14 @@ +class CfgVehicles { + #include "CfgVehicles\backpacks.hpp" + #include "CfgVehicles\boxes.hpp" + #include "CfgVehicles\explosives.hpp" + #include "CfgVehicles\helicopters.hpp" + #include "CfgVehicles\planes.hpp" + #include "CfgVehicles\tracked.hpp" + #include "CfgVehicles\turrets.hpp" + #include "CfgVehicles\units.hpp" + #include "CfgVehicles\wheeled.hpp" + #include "CfgVehicles\land.hpp" + #include "CfgVehicles\vn_boxes.hpp" + #include "CfgVehicles\boats.hpp" +}; diff --git a/addons/compat_sog/CfgVehicles/backpacks.hpp b/addons/compat_sog/CfgVehicles/backpacks.hpp new file mode 100644 index 0000000000..8feb83332c --- /dev/null +++ b/addons/compat_sog/CfgVehicles/backpacks.hpp @@ -0,0 +1,33 @@ + +class vn_b_pack_pfield_01; +class vn_b_pack_pfield_02: vn_b_pack_pfield_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class vn_b_pack_p08_01; +class vn_b_pack_p08_02: vn_b_pack_p08_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class vn_b_pack_p08_03: vn_b_pack_p08_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class vn_b_pack_p44_01; +class vn_b_pack_p44_02: vn_b_pack_p44_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class vn_b_pack_p44_03: vn_b_pack_p44_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class vn_b_pack_01; +class vn_b_pack_prc77_01: vn_b_pack_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class vn_b_pack_lw_01; +class vn_b_pack_lw_03: vn_b_pack_lw_01 { + EGVAR(trenches,entrenchingTool) = 1; +}; diff --git a/addons/compat_sog/CfgVehicles/boats.hpp b/addons/compat_sog/CfgVehicles/boats.hpp new file mode 100644 index 0000000000..52aaef6b85 --- /dev/null +++ b/addons/compat_sog/CfgVehicles/boats.hpp @@ -0,0 +1,20 @@ +// PTF Nasty https://www.ptfnasty.com/ptf17chap2.html (610 Gallons) +class vn_boat_armed_base; +class vn_boat_05_base: vn_boat_armed_base { + EGVAR(refuel,fuelCapacity) = 2773; +}; + +// PBR https://www.warboats.org/pbr.htm +class vn_boat_12_base: vn_boat_armed_base { + EGVAR(refuel,fuelCapacity) = 727; +}; + +// STAB https://www.powercatboat.com/STAB/STAB.html +class vn_boat_09_base: vn_boat_armed_base { + EGVAR(refuel,fuelCapacity) = 464; +}; + +// Type 55A Shantou Gunboat (Could find no info on this, so same as the similarly sized PTF for now) +class vn_boat_03_base: vn_boat_armed_base { + EGVAR(refuel,fuelCapacity) = 2773; +}; diff --git a/addons/compat_sog/CfgVehicles/boxes.hpp b/addons/compat_sog/CfgVehicles/boxes.hpp new file mode 100644 index 0000000000..4e6e1093c7 --- /dev/null +++ b/addons/compat_sog/CfgVehicles/boxes.hpp @@ -0,0 +1,130 @@ +class Box_NATO_AmmoOrd_F; +class GVAR(box_81mm_he): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_81mm_HE); + author = ECSTRING(common,ACETeam); + maximumLoad = 300; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m29\vn_prop_81mm_crate_02.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(81mm_he),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_81mm_wp): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_81mm_WP); + author = ECSTRING(common,ACETeam); + maximumLoad = 300; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m29\vn_prop_81mm_crate_02.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(81mm_wp),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_81mm_chem): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_81mm_Smoke); + author = ECSTRING(common,ACETeam); + maximumLoad = 300; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m29\vn_prop_81mm_crate_02.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(81mm_chem),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_81mm_lume): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_81mm_Lume); + author = ECSTRING(common,ACETeam); + maximumLoad = 300; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m29\vn_prop_81mm_crate_02.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(81mm_lume),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_60mm_he): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_60mm_HE); + author = ECSTRING(common,ACETeam); + maximumLoad = 450; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m2\vn_prop_60mm_crate_01.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(60mm_he),12); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_60mm_wp): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_60mm_WP); + author = ECSTRING(common,ACETeam); + maximumLoad = 450; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m2\vn_prop_60mm_crate_01.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(60mm_wp),12); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_60mm_lume): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_60mm_Lume); + author = ECSTRING(common,ACETeam); + maximumLoad = 450; + model = "\vn\objects_f_vietnam\usarmy\supply\mortar_m2\vn_prop_60mm_crate_01.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(60mm_lume),12); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_82mm_he): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_82mm_HE); + author = ECSTRING(common,ACETeam); + maximumLoad = 210; + model = "\vn\objects_f_vietnam\usarmy\furniture\vn_us_fort_common_crate_01.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(82mm_he),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_82mm_wp): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_82mm_WP); + author = ECSTRING(common,ACETeam); + maximumLoad = 210; + model = "\vn\objects_f_vietnam\usarmy\furniture\vn_us_fort_common_crate_01.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(82mm_wp),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; + +class GVAR(box_82mm_lume): Box_NATO_AmmoOrd_F { + displayName = CSTRING(Box_82mm_Lume); + author = ECSTRING(common,ACETeam); + maximumLoad = 210; + model = "\vn\objects_f_vietnam\usarmy\furniture\vn_us_fort_common_crate_01.p3d"; + + class TransportMagazines { + MACRO_ADDMAGAZINE(GVAR(82mm_lume),3); + }; + class TransportItems {}; + class TransportWeapons {}; +}; diff --git a/addons/compat_sog/CfgVehicles/explosives.hpp b/addons/compat_sog/CfgVehicles/explosives.hpp new file mode 100644 index 0000000000..81a3fd514d --- /dev/null +++ b/addons/compat_sog/CfgVehicles/explosives.hpp @@ -0,0 +1,263 @@ +class Items_base_F; +class EGVAR(explosives,Place): Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + class EventHandlers; +}; + +// Claymore +class EXPLOSIVES_PLACE(m18): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_M18_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m18\vn_mine_m18"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.15]"; + }; + }; +}; + +// Claymore x3 +class EXPLOSIVES_PLACE(m18_x3): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_M18_X3_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m18\vn_mine_m18_x3"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.1]"; + }; + }; +}; + +// WP Claymore +class EXPLOSIVES_PLACE(m18_wp): EXPLOSIVES_PLACE(m18) { + displayName = "$STR_VN_MINE_M18_WP_MAG_DN"; + model = "vn\weapons_f_vietnam_04\mines\m18\vn_mine_m18_wp"; +}; + +// Toe-Popper +class EXPLOSIVES_PLACE(m14): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_M14_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m14\vn_mine_m14_mag"; +}; + +// Bounding Mine +class EXPLOSIVES_PLACE(m16): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_M16_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m16\vn_mine_m16_mag"; +}; + +// Bounding Mine (Trip Wire 2m) +class EXPLOSIVES_PLACE(m16_tripwire_2m): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_TRIPWIRE_M16_04_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m16\vn_mine_tripwire_m16_02"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0.0093, 0.088]"; + }; + }; +}; +// Bounding Mine (Trip Wire 4m) +class EXPLOSIVES_PLACE(m16_tripwire_4m): EXPLOSIVES_PLACE(m16_tripwire_2m) { + displayName = "$STR_VN_MINE_TRIPWIRE_M16_04_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m16\vn_mine_tripwire_m16_04"; +}; + +// F1 (Trip Wire 2m) +class EXPLOSIVES_PLACE(f1_tripwire_2m): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_TRIPWIRE_F1_02_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\tripwire_f1\vn_mine_tripwire_f1_02"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0.011, 0.18]"; + }; + }; +}; +// F1 (Trip Wire 4m) +class EXPLOSIVES_PLACE(f1_tripwire_4m): EXPLOSIVES_PLACE(f1_tripwire_2m) { + displayName = "$STR_VN_MINE_TRIPWIRE_F1_04_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\tripwire_f1\vn_mine_tripwire_f1_04"; +}; + +// Arty Shell (Trip Wire 4m) +class EXPLOSIVES_PLACE(arty_tripwire_4m): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_TRIPWIRE_ARTY_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\tripwire_arty\vn_mine_tripwire_arty"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0.01, 0.126]"; + }; + }; +}; + +// Satchel Charge +class EXPLOSIVES_PLACE(satchel_remote_02): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_SATCHEL_REMOTE_02_MAG_DN"; + model = "\vn\characters_f_vietnam\OPFOR\vests\items\vn_mine_satchel_02.p3d"; +}; + +// TM57 Anti-Tank Mine +class EXPLOSIVES_PLACE(tm57): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_TM57_MAG_DN"; + model = "vn\weapons_f_vietnam\mines\tm57\vn_mine_tm57_mag"; +}; + +// M15 Anti-Tank Mine +class EXPLOSIVES_PLACE(m15): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_M15_MAG_DN"; + model = "vn\weapons_f_vietnam\mines\m15\vn_mine_m15_mag"; +}; + +// M112 Breaching charge +class EXPLOSIVES_PLACE(m112): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_M112_REMOTE_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\m112\vn_mine_m112_mag"; +}; + +// Spiked ammo box +class EXPLOSIVES_PLACE(ammobox_range): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_AMMOBOX_RANGE_MAG_DN"; + model = "\vn\objects_f_vietnam\supply\a2_ammo\pavn\vn_pavn_ammo"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.3]"; + }; + }; +}; + +// Punji large +class EXPLOSIVES_PLACE(punji_01): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_PUNJI_01_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\punji\vn_mine_punji_01_mag"; +}; + +// Punji small +class EXPLOSIVES_PLACE(punji_02): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_PUNJI_01_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\punji\vn_mine_punji_02_mag"; +}; + +// Punji whip +class EXPLOSIVES_PLACE(punji_03): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_PUNJI_01_MAG_DN"; + model = "\vn\weapons_f_vietnam\mines\punji\vn_mine_punji_03"; + + class EventHandlers: EventHandlers { + class ADDON { + init = QUOTE(_this call FUNC(handlePunjiTrapPlace)); + }; + }; +}; + +// Punji door-way +class EXPLOSIVES_PLACE(punji_04): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_PUNJI_04_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\punji_02\vn_mine_punji_04_mag"; +}; + +// Punji side whip +class EXPLOSIVES_PLACE(punji_05): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_PUNJI_05_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\punji_02\vn_mine_punji_05_mag"; +}; + +// Bike mine +class EXPLOSIVES_PLACE(bike): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_BIKE_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\bike\vn_mine_bike_mag"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.085, 0.185, 0.54]"; + }; + }; + + class EventHandlers: EventHandlers { + class ADDON { + init = QUOTE(_this call FUNC(handleBikeMinePlace)); + }; + }; +}; + +// Cartridge mine +class EXPLOSIVES_PLACE(cartridge): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_CARTRIDGE_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\cartridge\vn_mine_cartridge_mag"; +}; + +// Lighter mine +class EXPLOSIVES_PLACE(lighter): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_LIGHTER_MAG_DN"; + model = "\vn\characters_f_vietnam\BLUFOR\headgear\items\vn_b_item_lighter_01"; +}; + +// Pot mine +class EXPLOSIVES_PLACE(pot): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_POT_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\pot\vn_mine_pot_mag"; +}; + +// Jerrycan mine +class EXPLOSIVES_PLACE(jerrycan): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_JERRYCAN_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\jerrycan\vn_mine_jerrycan_mag"; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.15]"; + }; + }; +}; + +// Mortar shell on a stick +class EXPLOSIVES_PLACE(mortar_range): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_MORTAR_RANGE_MAG_DN"; + model = "vn\static_f_vietnam\mortar_type53\vn_shell_82mm_o832d_he_mag"; +}; + +// Limpet mine USA +class EXPLOSIVES_PLACE(limpet_01): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_LIMPET_01_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\limpet_01\vn_mine_limpet_01_mag"; +}; + +// Limpet mine RUS +class EXPLOSIVES_PLACE(limpet_02): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_LIMPET_02_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\limpet_02\vn_mine_limpet_02_mag"; +}; + +// Chicom NO8 mine +class EXPLOSIVES_PLACE(chicom_no8): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_CHICOM_NO8_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\no8\vn_mine_chicom_no8_mag"; +}; + +// Dh10 mine +class EXPLOSIVES_PLACE(dh10): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_DH10_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\dh10\vn_mine_dh10_mag"; +}; + +// Grenade board mine +class EXPLOSIVES_PLACE(gboard): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_TRIPWIRE_RGD5_04_DN"; + model = "vn\weapons_f_vietnam_03\mines\gboard\vn_mine_gboard_range_mag"; +}; + +// Satchel charge +class EXPLOSIVES_PLACE(satchelcharge_02): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_SATCHELCHARGE_02_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\satchelcharge_02\vn_mine_satchelcharge_02_mag"; +}; + +// Bangalore mine +class EXPLOSIVES_PLACE(bangalore): EGVAR(explosives,Place) { + displayName = "$STR_VN_MINE_BANGALORE_MAG_DN"; + model = "vn\weapons_f_vietnam_03\mines\bangalore\vn_mine_bangalore_mag"; +}; diff --git a/addons/compat_sog/CfgVehicles/helicopters.hpp b/addons/compat_sog/CfgVehicles/helicopters.hpp new file mode 100644 index 0000000000..19db8f1ac3 --- /dev/null +++ b/addons/compat_sog/CfgVehicles/helicopters.hpp @@ -0,0 +1,43 @@ +// UH-1C - https://en.wikipedia.org/wiki/Bell_UH-1_Iroquois +class vn_helicopter_base; +class vn_air_uh1_01_base: vn_helicopter_base { + EGVAR(refuel,fuelCapacity) = 916; +}; + +// UH-1B - https://www.skytamer.com/Bell_H-1B(UH).html +class vn_air_uh1c_01_base; +class vn_air_uh1c_doorguns_base; +class vn_air_uh1c_07_base: vn_air_uh1c_doorguns_base { + EGVAR(refuel,fuelCapacity) = 625; +}; + +// UH-1D - http://www.aviastar.org/helicopters_eng/bell_uh-1.php +class vn_air_uh1d_base: vn_air_uh1_01_base { + EGVAR(refuel,fuelCapacity) = 832; +}; + +// UH-1P - based on the F variant which is based on the B variant +// Capacity might be wrong +class vn_air_uh1c_03_base: vn_air_uh1c_01_base { + EGVAR(refuel,fuelCapacity) = 625; +}; + +// UH-34D - https://www.easa.europa.eu/sites/default/files/dfu/TCDS_EASA_IM_R109_S58_Issue_02.pdf +class vn_air_ch34_01_base: vn_helicopter_base { + EGVAR(refuel,fuelCapacity) = 962; +}; + +// OH-6 - https://en.wikipedia.org/wiki/MD_Helicopters_MH-6_Little_Bird +class vn_air_oh6a_base: vn_helicopter_base { + EGVAR(refuel,fuelCapacity) = 242; +}; + +// AH-1G - http://all-aero.com/index.php/35-helicopters/copters/1479-bell-209-ah-1-249 +class vn_air_ah1g_01_base: vn_helicopter_base { + EGVAR(refuel,fuelCapacity) = 980; +}; + +// Mi-2 - https://fas.org/man/dod-101/sys/ac/row/mi-2.htm +class vn_air_mi2_base: vn_helicopter_base { + EGVAR(refuel,fuelCapacity) = 600; +}; diff --git a/addons/compat_sog/CfgVehicles/land.hpp b/addons/compat_sog/CfgVehicles/land.hpp new file mode 100644 index 0000000000..70b305a31d --- /dev/null +++ b/addons/compat_sog/CfgVehicles/land.hpp @@ -0,0 +1,67 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + +// fuel pumps +class Land_vn_commercial_base; +class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; +}; +class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; +}; +class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; +}; + +// fuel objects +class Land_vn_building_b_base; +class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}}; + EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785 +}; +class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 { + EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}}; + EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785 +}; +class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 { + EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}}; +}; +class Land_vn_building_industrial_base; +class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}}; + EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F +}; +class Land_vn_object_b_base; +class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0, 0}}; + EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F +}; +class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 { + EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}}; + EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300 +}; +class vn_b_ammobox_supply_07; +class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet + XEH_INHERITED; +}; +class vn_object_c_base_02; +class Land_vn_canisterfuel_f: vn_object_c_base_02 { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; +class Land_vn_object_c_base; +class Land_vn_fuelcan: Land_vn_object_c_base { + XEH_INHERITED; + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; diff --git a/addons/compat_sog/CfgVehicles/planes.hpp b/addons/compat_sog/CfgVehicles/planes.hpp new file mode 100644 index 0000000000..496065953a --- /dev/null +++ b/addons/compat_sog/CfgVehicles/planes.hpp @@ -0,0 +1,15 @@ +// F-4 - https://en.wikipedia.org/wiki/McDonnell_Douglas_F-4_Phantom_II +class Plane_Base_F; +class vn_air_f4_base: Plane_Base_F { + EGVAR(refuel,fuelCapacity) = 7548; +}; + +// F-100D https://www.supersabre.com/f-100specs.htm +class vn_air_f100d_base: Plane_Base_F { + EGVAR(refuel,fuelCapacity) = 4500; +}; + +// MIG-19S https://en.wikipedia.org/wiki/Mikoyan-Gurevich_MiG-19#cite_ref-60 +class vn_air_mig19_base: Plane_Base_F { + EGVAR(refuel,fuelCapacity) = 1800; +}; diff --git a/addons/compat_sog/CfgVehicles/tracked.hpp b/addons/compat_sog/CfgVehicles/tracked.hpp new file mode 100644 index 0000000000..e2832796a9 --- /dev/null +++ b/addons/compat_sog/CfgVehicles/tracked.hpp @@ -0,0 +1,26 @@ +// M41 +class vn_armor_tank_base; +class vn_armor_m41_base: vn_armor_tank_base { + EGVAR(refuel,fuelCapacity) = 530; +}; + +// Type 63 +class vn_armor_type63_base: vn_armor_tank_base { + EGVAR(refuel,fuelCapacity) = 545; +}; + +// M113A1 https://man.fas.org/dod-101/sys/land/m113.htm +class APC_Tracked_01_base_F; +class vn_armor_m113_base: APC_Tracked_01_base_F { + EGVAR(refuel,fuelCapacity) = 360; +}; + +// PT-76A https://en.wikipedia.org/wiki/PT-76 +class vn_armor_pt76_base: vn_armor_tank_base { + EGVAR(refuel,fuelCapacity) = 250; +}; + +// PT-76B (This variant increased the fuel size from 250 to 400 liters) +class vn_armor_pt76b_base: vn_armor_pt76_base { + EGVAR(refuel,fuelCapacity) = 400; +}; diff --git a/addons/compat_sog/CfgVehicles/turrets.hpp b/addons/compat_sog/CfgVehicles/turrets.hpp new file mode 100644 index 0000000000..6142a018e8 --- /dev/null +++ b/addons/compat_sog/CfgVehicles/turrets.hpp @@ -0,0 +1,508 @@ +class LandVehicle; +class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; +}; +class StaticCannon: StaticWeapon {}; +class StaticMGWeapon: StaticWeapon {}; + +// --- Gun Turrets ------------------------------------------------------------- + +// M2 Browning - High +class vn_static_m2_high_base: StaticMGWeapon { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "mg1_otochlaven"; + }; + }; + + class ACE_CSW { + enabled = 1; + proxyWeapon = "vn_m2_v_01"; + magazineLocation = "_target selectionPosition 'mg1_magazine'"; + disassembleWeapon = QGVAR(m2_carry); + disassembleTurret = QEGVAR(csw,m3Tripod); + ammoLoadTime = 4; + ammoUnloadTime = 8; + desiredAmmo = 100; + }; +}; + +// M2 Browning - Low +class vn_static_m2_low_base: vn_static_m2_high_base { + class ACE_CSW: ACE_CSW { + disassembleTurret = QEGVAR(csw,m3TripodLow); + }; +}; + +// M1919A6 - No tripod +class vn_static_m1919a6_base: vn_static_m2_low_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "mg1_otochlaven_recoil"; + }; + }; + + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = "vn_m1919_v_01"; + magazineLocation = "_target selectionPosition 'mg1_magazine' vectorAdd [-0.3, 0, 0]"; + disassembleWeapon = QGVAR(m1919A6_carry); + disassembleTurret = ""; + ammoLoadTime = 2; + ammoUnloadTime = 8; + desiredAmmo = 250; + }; +}; + +// M1919A4 - High +class vn_static_m1919a4_high_base: vn_static_m1919a6_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "mg1_otochlaven_recoil"; + }; + }; + + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = "vn_m1919_v_01"; + magazineLocation = "_target selectionPosition 'mg1_magazine'"; + disassembleWeapon = QGVAR(m1919A4_carry); + disassembleTurret = QEGVAR(csw,m3Tripod); + ammoLoadTime = 2; + ammoUnloadTime = 8; + desiredAmmo = 250; + }; +}; + +// M1919A4 - Low +class vn_static_m1919a4_low_base: vn_static_m1919a4_high_base { + class ACE_CSW: ACE_CSW { + disassembleTurret = QEGVAR(csw,m3TripodLow); + }; +}; + +// M60 - High +class vn_static_m60_high_base: vn_static_m2_low_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.15, 0.532, -1.06]"; + }; + }; + + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = "vn_m60_v_01"; + magazineLocation = "_target selectionPosition 'mg1_trigger'"; + disassembleWeapon = QGVAR(m60_carry); + disassembleTurret = QEGVAR(csw,m3Tripod); + ammoLoadTime = 3; + ammoUnloadTime = 8; + desiredAmmo = 250; + }; +}; + +// M60 - Low +class vn_static_m60_low_base: vn_static_m60_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.25, 0.15, -1.06]"; + }; + }; + + class ACE_CSW: ACE_CSW { + magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; + disassembleTurret = QEGVAR(csw,m3TripodLow); + }; +}; + +// TOW +class vn_static_at3_base: StaticMGWeapon {}; +class vn_static_tow_base: vn_static_at3_base { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,dragPosition)[] = {0.8, 1.3, 0}; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-1.04, 0.3, -0.5]"; + }; + }; + + class ACE_CSW { + enabled = 1; + proxyWeapon = "vn_missile_tow_launcher"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(tow_carry); + disassembleTurret = QEGVAR(csw,m220Tripod); + ammoLoadTime = 2; + ammoUnloadTime = 5; + desiredAmmo = 1; + }; +}; + +// DShKM - High +class vn_static_dp28_high_base: vn_static_m2_high_base { + class ACE_CSW: ACE_CSW { + enabled = 0; + }; +}; +class vn_static_dshkm_high_01_base: vn_static_dp28_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.15, 0.532, -1.06]"; + }; + }; + + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = "vn_dshkm_v_01"; + magazineLocation = "_target selectionPosition 'mg1_boxmag'"; + disassembleWeapon = QGVAR(dshkm_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + ammoLoadTime = 1; + ammoUnloadTime = 8; + desiredAmmo = 50; + }; +}; + +// DShKM - High, with AA sight +class vn_static_dshkm_high_02_base: vn_static_dshkm_high_01_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(dshkm_AA_carry); + }; +}; + +// DShKM - Low, with shield +class vn_static_dshkm_low_01_base: vn_static_dshkm_high_01_base { + EGVAR(dragging,canCarry) = 0; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.3, 0.75, -1]"; + }; + }; + + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(dshkm_shield_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; + +// DShKM - Low +class vn_static_dshkm_low_02_base: vn_static_dshkm_low_01_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(dshkm_carry); + }; +}; + +// RPD - High +class vn_static_rpd_high_base: vn_static_dp28_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.158, 0.745, -0.7]"; + }; + }; + + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = "vn_rpd_v_01"; + magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; + disassembleWeapon = QGVAR(rpd_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + ammoLoadTime = 10; + ammoUnloadTime = 8; + desiredAmmo = 100; + }; +}; + +// PK - High +class vn_static_pk_high_base: vn_static_rpd_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.156, 0.755, -1.05]"; + }; + }; + + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = "vn_pk_v_01"; + magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; + disassembleWeapon = QGVAR(pk_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + ammoLoadTime = 2; + ammoUnloadTime = 8; + desiredAmmo = 100; + }; +}; + +// PK - Low +class vn_static_pk_low_base: vn_static_pk_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.35, 0.43, -0.9]"; + }; + }; + + class ACE_CSW: ACE_CSW { + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; + +// MG42 - High +class vn_static_mg42_high_base: vn_static_rpd_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.18, 0.5, -0.3]"; + }; + }; + + class ACE_CSW { + enabled = 1; + proxyWeapon = "vn_mg42_v_01"; + magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; + disassembleWeapon = QGVAR(mg42_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + ammoLoadTime = 2; + ammoUnloadTime = 8; + desiredAmmo = 250; + }; +}; + +class vn_static_mg42_low_base: vn_static_mg42_high_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.1, 0.3, -0.9]"; + }; + }; + + class ACE_CSW: ACE_CSW { + disassembleTurret = ""; + }; +}; + +// SGM - High +class vn_static_sgm_base: StaticMGWeapon { + class ACE_Actions: ACE_Actions {}; +}; +class vn_static_sgm_high_base: vn_static_sgm_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "mg1_otocvez"; + }; + }; + + class ACE_CSW { + enabled = 1; + proxyWeapon = "vn_sgm_v_01"; + magazineLocation = "_target selectionPosition 'mg1_otochlaven_recoil'"; + disassembleWeapon = QGVAR(sgm_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + ammoLoadTime = 2; + ammoUnloadTime = 8; + desiredAmmo = 250; + }; +}; + +// SGM - Low +class vn_static_sgm_low_base: vn_static_sgm_high_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(sgm_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; + +// SGM - Shield +class vn_o_pl_static_sgm_low_01: vn_static_sgm_low_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(sgm_shield_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; +class vn_o_nva_65_static_sgm_low_01: vn_static_sgm_low_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(sgm_shield_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; +class vn_o_nva_static_sgm_low_01: vn_static_sgm_low_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(sgm_shield_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; +class vn_o_nva_navy_static_sgm_low_01: vn_static_sgm_low_base { + class ACE_CSW: ACE_CSW { + disassembleWeapon = QGVAR(sgm_shield_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; +}; + +// Mk18 Grenade laucher +class vn_static_mk18_base: StaticCannon { + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,canDrag) = 1; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "mg1_otochlaven"; + }; + }; + + class ACE_CSW { + enabled = 1; + proxyWeapon = "vn_mk18_v_01"; + magazineLocation = "_target selectionPosition 'mg1_magazine'"; + disassembleWeapon = QGVAR(mk18_carry); + disassembleTurret = QEGVAR(csw,m3TripodLow); + ammoLoadTime = 1; + ammoUnloadTime = 8; + desiredAmmo = 24; + }; +}; + +// --- Mortars ----------------------------------------------------------------- + +// M29 Mortar +class StaticMortar: StaticWeapon {}; +class Mortar_01_base_F: StaticMortar {}; +class vn_static_mortar_m29_base: Mortar_01_base_F { + EGVAR(dragging,canCarry) = 0; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "otochlaven"; + }; + }; + + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(vn_mortar_m29); + magazineLocation = "_target selectionPosition 'pohon'"; + disassembleWeapon = QGVAR(mortar_m29_carry); + disassembleTurret = QEGVAR(csw,mortarBaseplate); + ammoLoadTime = 3; + ammoUnloadTime = 3; + desiredAmmo = 1; + }; +}; + +// M2 / Type 63 Mortar +class vn_static_mortar_m2_base: vn_static_mortar_m29_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(vn_mortar_m2); + magazineLocation = "_target selectionPosition 'pohon'"; + disassembleWeapon = QGVAR(mortar_m2_carry); + disassembleTurret = QEGVAR(csw,mortarBaseplate); + ammoLoadTime = 3; + ammoUnloadTime = 3; + desiredAmmo = 1; + }; +}; + +// Type 53 Mortar +class vn_static_mortar_type53_base: vn_static_mortar_m29_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(vn_mortar_type53); + magazineLocation = "_target selectionPosition 'pohon'"; + disassembleWeapon = QGVAR(mortar_type53_carry); + disassembleTurret = QEGVAR(csw,mortarBaseplate); + ammoLoadTime = 3; + ammoUnloadTime = 3; + desiredAmmo = 1; + }; +}; + +// H-12 MLRS +class vn_static_h12_base: Mortar_01_base_F { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0.4, 2.1, 0}; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "damagegun"; + }; + }; + + class ACE_CSW { + enabled = 0; + }; +}; + +// --- Non-CSW Static Weapons -------------------------------------------------- + +class vn_static_m45_base: vn_static_m2_high_base { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,canDrag) = 0; + + class ACE_CSW: ACE_CSW { + enabled = 0; + }; +}; + +class vn_static_zpu4_base: vn_static_m2_high_base { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,canDrag) = 0; + + class ACE_CSW: ACE_CSW { + enabled = 0; + }; +}; + +class vn_o_static_rsna75: StaticMGWeapon { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,canDrag) = 0; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "mainturret"; + }; + }; + + class ACE_CSW { + enabled = 0; + }; +}; + +class vn_sa2: StaticMGWeapon { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,canDrag) = 0; +}; + +class vn_static_m40a1rr_base: StaticCannon { + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {-0.3, 1.9, 0}; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "mg1_otochlaven"; + }; + }; +}; + +class vn_static_type56rr_base: StaticCannon { + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {-0.1, 0.5, 0}; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "mg1_otocvez"; + }; + }; +}; + +// --- Spiderholes ------------------------------------------------------------- + +class vn_o_vc_spiderhole_01: StaticWeapon { + EGVAR(dragging,canCarry) = 0; + EGVAR(dragging,canDrag) = 0; + + EGVAR(cargo,canLoad) = 0; +}; diff --git a/addons/compat_sog/CfgVehicles/units.hpp b/addons/compat_sog/CfgVehicles/units.hpp new file mode 100644 index 0000000000..e0d194227d --- /dev/null +++ b/addons/compat_sog/CfgVehicles/units.hpp @@ -0,0 +1,14 @@ +class vn_b_men_aircrew_base; +class vn_b_men_jetpilot_01: vn_b_men_aircrew_base { + ACE_GForceCoef = 0.55; +}; + +class vn_o_men_aircrew_01; +class vn_o_men_aircrew_05: vn_o_men_aircrew_01 { + ACE_GForceCoef = 0.55; +}; + +class vn_i_men_aircrew_base; +class vn_i_men_jetpilot_01: vn_i_men_aircrew_base { + ACE_GForceCoef = 0.55; +}; diff --git a/addons/compat_sog/CfgVehicles/vn_boxes.hpp b/addons/compat_sog/CfgVehicles/vn_boxes.hpp new file mode 100644 index 0000000000..085f7cc324 --- /dev/null +++ b/addons/compat_sog/CfgVehicles/vn_boxes.hpp @@ -0,0 +1,15 @@ + +// dragging carrying items +class ReammoBox_F; +class vn_ammobox_base: ReammoBox_F { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0,1,1}; + EGVAR(dragging,carryDirection) = 0; + + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0,1.2,0}; + EGVAR(dragging,dragDirection) = 0; +}; diff --git a/addons/compat_sog/CfgVehicles/wheeled.hpp b/addons/compat_sog/CfgVehicles/wheeled.hpp new file mode 100644 index 0000000000..3a898519dd --- /dev/null +++ b/addons/compat_sog/CfgVehicles/wheeled.hpp @@ -0,0 +1,38 @@ +// M39 / M54 / M49 +class vn_wheeled_truck_base; +class vn_wheeled_m54_base: vn_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 189; +}; +class vn_wheeled_m54_cab_base; +class vn_wheeled_m54_fuel_base: vn_wheeled_m54_cab_base { + EGVAR(refuel,hooks)[] = {{-1.15, -2.3, 0.28}}; + EGVAR(refuel,fuelCargo) = 4542; +}; +class vn_wheeled_m54_01_base; +class vn_wheeled_m54_ammo_base: vn_wheeled_m54_01_base { + EGVAR(rearm,defaultSupply) = 1200; +}; + +// M151 +class vn_wheeled_car_base; +class vn_wheeled_m151_base: vn_wheeled_car_base { + EGVAR(refuel,fuelCapacity) = 65; +}; + +// ZIL-157 +class vn_wheeled_z157_base: vn_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 150; +}; +class vn_wheeled_z157_fuel_base: vn_wheeled_z157_base { + EGVAR(refuel,hooks)[] = {{-1.36, -3.575, -0.4}}; + EGVAR(refuel,fuelCargo) = 4000; +}; +class vn_wheeled_z157_01_base; +class vn_wheeled_z157_ammo_base: vn_wheeled_z157_01_base { + EGVAR(rearm,defaultSupply) = 1200; +}; + +// BTR-40 +class vn_wheeled_btr40_base: vn_wheeled_car_base { + EGVAR(refuel,fuelCapacity) = 122; +}; diff --git a/addons/compat_sog/CfgWeapons.hpp b/addons/compat_sog/CfgWeapons.hpp new file mode 100644 index 0000000000..c0c0ee807b --- /dev/null +++ b/addons/compat_sog/CfgWeapons.hpp @@ -0,0 +1,9 @@ +class CfgWeapons { + #include "CfgWeapons\csw.hpp" + #include "CfgWeapons\helmets.hpp" + #include "CfgWeapons\launchers.hpp" + #include "CfgWeapons\pistols.hpp" + #include "CfgWeapons\uniforms.hpp" + #include "CfgWeapons\weapons.hpp" + #include "CfgWeapons\weapons_melee.hpp" +}; diff --git a/addons/compat_sog/CfgWeapons/csw.hpp b/addons/compat_sog/CfgWeapons/csw.hpp new file mode 100644 index 0000000000..87b1b16c5e --- /dev/null +++ b/addons/compat_sog/CfgWeapons/csw.hpp @@ -0,0 +1,476 @@ +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" + +CREATE_CSW_PROXY(vn_mortar_m29); +CREATE_CSW_PROXY(vn_mortar_m2); +CREATE_CSW_PROXY(vn_mortar_type53); + +class Launcher; +class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; +}; + +// --- Gun Turrets ------------------------------------------------------------- + +class GVAR(m2_carry): Launcher_Base_F { + dlc = "ace"; + displayName = ECSTRING(csw,m2_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_m2b_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,m3Tripod) = "vn_b_army_static_m2_high"; + EGVAR(csw,m3TripodLow) = "vn_b_army_static_m2_low"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 840; + }; +}; + +class GVAR(m1919a4_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_m1919a4); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_m1919a4_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,m3Tripod) = "vn_b_army_static_m1919a4_high"; + EGVAR(csw,m3TripodLow) = "vn_b_sf_static_m1919a4_low"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 310; + }; +}; + +class GVAR(m1919a6_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_m1919a6); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_m1919a6_ca.paa); + + class ACE_CSW { + type = "mount"; + deployTime = 2; + pickupTime = 2; + deploy = "vn_b_army_static_m1919a6"; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 320; + }; +}; + +class GVAR(m60_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_m60); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_m60_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,m3Tripod) = "vn_b_army_static_m60_high"; + EGVAR(csw,m3TripodLow) = "vn_b_army_static_m60_low"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 232; + }; +}; + +class GVAR(tow_carry): Launcher_Base_F { + dlc = "ace"; + displayName = ECSTRING(csw,tow_tube); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_tow_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,m220Tripod) = "vn_b_army_static_tow"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 500; + }; +}; + +class GVAR(dshkm_carry): Launcher_Base_F { + dlc = "ace"; + displayName = ECSTRING(csw,dshk_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_dshkm_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripod) = "vn_o_nva_static_dshkm_high_01"; + EGVAR(csw,kordTripodLow) = "vn_o_nva_static_dshkm_low_02"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 750; + }; +}; + +class GVAR(dshkm_shield_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_dshkm_shield); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_dshkm_shield_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripodLow) = "vn_o_nva_static_dshkm_low_01"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 850; + }; +}; + +class GVAR(dshkm_AA_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_dshkm_aa); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_dshkm_aa_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripod) = "vn_o_nva_static_dshkm_high_02"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 750; + }; +}; + +class GVAR(rpd_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_rpd); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_rpd_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripod) = "vn_o_nva_static_rpd_high"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 163; + }; +}; + +class GVAR(pk_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_pk); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_pk_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripod) = "vn_o_nva_static_pk_high"; + EGVAR(csw,kordTripodLow) = "vn_o_nva_static_pk_low"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 198; + }; +}; + +class GVAR(mortar_m29_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_m29); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_m29_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + + class assembleTo { + EGVAR(csw,mortarBaseplate) = "vn_b_army_static_mortar_m29"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 730; + }; +}; + +class GVAR(mg42_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_mg42); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_mg42_ca.paa); + + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "vn_o_vc_static_mg42_low"; + + class assembleTo { + EGVAR(csw,kordTripod) = "vn_o_vc_static_mg42_high"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 310; + }; +}; + +class GVAR(sgm_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_sgm); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_sgm_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripod) = "vn_o_vc_static_sgm_high_01"; + EGVAR(csw,kordTripodLow) = "vn_o_vc_static_sgm_low_02"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 310; + }; +}; +class GVAR(sgm_shield_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_sgm_shield); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_sgm_shield_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,kordTripodLow) = "vn_o_vc_static_sgm_low_01"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 310; + }; +}; + +class GVAR(mk18_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_mk18); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_mk18_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + + class assembleTo { + EGVAR(csw,m3TripodLow) = "vn_b_army_static_mk18"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 310; + }; +}; + +// --- Mortars ----------------------------------------------------------------- + +class GVAR(mortar_m2_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_m2); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_m2_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + + class assembleTo { + EGVAR(csw,mortarBaseplate) = "vn_b_army_static_mortar_m2"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 300; + }; +}; + +class GVAR(mortar_type53_carry): Launcher_Base_F { + dlc = "ace"; + displayName = CSTRING(csw_type53); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\csw_type53_ca.paa); + + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + + class assembleTo { + EGVAR(csw,mortarBaseplate) = "vn_o_nva_static_mortar_type53"; + }; + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + class MuzzleSlot { + iconScale = 0.1; + }; + mass = 860; + }; +}; diff --git a/addons/compat_sog/CfgWeapons/helmets.hpp b/addons/compat_sog/CfgWeapons/helmets.hpp new file mode 100644 index 0000000000..b5fe500fb0 --- /dev/null +++ b/addons/compat_sog/CfgWeapons/helmets.hpp @@ -0,0 +1,39 @@ +class vn_b_headgear_base; +class vn_b_helmet_aph6_01_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; +}; +class vn_b_helmet_aph6_02_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; + ACE_Protection = 1; +}; +class vn_b_helmet_sph4_01_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; +}; +class vn_b_helmet_sph4_02_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; + ACE_Protection = 1; +}; +class vn_b_helmet_t56_01_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; +}; +class vn_b_helmet_svh4_01_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; +}; +class vn_b_helmet_svh4_02_01: vn_b_headgear_base { + HEARING_PROTECTION_VICCREW; + ACE_Protection = 1; +}; + +class vn_o_headgear_base; +class vn_o_helmet_tsh3_01: vn_o_headgear_base { + HEARING_PROTECTION_VICCREW; +}; +class vn_o_helmet_zsh3_01: vn_o_headgear_base { + HEARING_PROTECTION_VICCREW; +}; +class vn_o_helmet_zsh3_02: vn_o_helmet_zsh3_01 { + ACE_Protection = 1; +}; +class vn_o_helmet_shl61_01: vn_o_headgear_base { + HEARING_PROTECTION_VICCREW; +}; diff --git a/addons/compat_sog/CfgWeapons/launchers.hpp b/addons/compat_sog/CfgWeapons/launchers.hpp new file mode 100644 index 0000000000..3dfd4984e3 --- /dev/null +++ b/addons/compat_sog/CfgWeapons/launchers.hpp @@ -0,0 +1,24 @@ +class vn_Launcher_Base_F; +class vn_m127: vn_Launcher_Base_F { + EGVAR(overpressure,damage) = 0; +}; +class vn_rpg2: vn_Launcher_Base_F { + EGVAR(reloadlaunchers,enabled) = 1; + + EGVAR(overpressure,angle) = 45; + EGVAR(overpressure,offset) = 0.9; +}; +class vn_rpg7: vn_Launcher_Base_F { + EGVAR(reloadlaunchers,enabled) = 1; + + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,offset) = 0.9; +}; +class vn_sa7: vn_Launcher_Base_F { + EGVAR(reloadlaunchers,enabled) = 1; + + EGVAR(overpressure,range) = 6; + EGVAR(overpressure,angle) = 40; + EGVAR(overpressure,damage) = 0.6; + EGVAR(overpressure,offset) = 1.65; +}; diff --git a/addons/compat_sog/CfgWeapons/pistols.hpp b/addons/compat_sog/CfgWeapons/pistols.hpp new file mode 100644 index 0000000000..25eef4c56c --- /dev/null +++ b/addons/compat_sog/CfgWeapons/pistols.hpp @@ -0,0 +1,45 @@ +#define MX991_FLASHLIGHT_SIZE 1.75 + +class vn_pistol; +class vn_m79_p: vn_pistol { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; +}; +class vn_mk22; +class vn_m10: vn_mk22 { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; +}; +class vn_m1895: vn_mk22 { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; +}; + +class vn_pm; +class vn_fkb1_pm: vn_pm { + ACE_Flashlight_Colour = "white"; + ACE_Flashlight_Beam = QPATHTOEF(flashlights,UI\Flashlight_beam_white_ca.paa); + ACE_Flashlight_Size = MX991_FLASHLIGHT_SIZE; +}; +class vn_fkb1_pm_sd: vn_fkb1_pm { + ACE_Flashlight_Colour = "red"; + ACE_Flashlight_Beam = QPATHTOEF(flashlights,UI\Flashlight_beam_red_ca.paa); +}; +class vn_fkb1; +class vn_fkb1_red: vn_fkb1 { + ACE_Flashlight_Colour = "red"; + ACE_Flashlight_Beam = QPATHTOEF(flashlights,UI\Flashlight_beam_red_ca.paa); +}; + +class vn_m1911; +class vn_mx991_m1911: vn_m1911 { + ACE_Flashlight_Colour = "white"; + ACE_Flashlight_Beam = QPATHTOEF(flashlights,UI\Flashlight_beam_white_ca.paa); + ACE_Flashlight_Size = MX991_FLASHLIGHT_SIZE; +}; +class vn_mx991_m1911_sd: vn_mx991_m1911 { + ACE_Flashlight_Colour = "red"; + ACE_Flashlight_Beam = QPATHTOEF(flashlights,UI\Flashlight_beam_red_ca.paa); +}; +class vn_mx991; +class vn_mx991_red: vn_mx991 { + ACE_Flashlight_Colour = "red"; + ACE_Flashlight_Beam = QPATHTOEF(flashlights,UI\Flashlight_beam_red_ca.paa); +}; diff --git a/addons/compat_sog/CfgWeapons/uniforms.hpp b/addons/compat_sog/CfgWeapons/uniforms.hpp new file mode 100644 index 0000000000..1758196032 --- /dev/null +++ b/addons/compat_sog/CfgWeapons/uniforms.hpp @@ -0,0 +1,12 @@ +class vn_b_uniform_base; +class vn_b_uniform_k2b_01_01: vn_b_uniform_base { + ACE_GForceCoef = 0.8; +}; +class vn_b_uniform_k2b_01_02: vn_b_uniform_base { + ACE_GForceCoef = 0.8; +}; + +class vn_o_uniform_base; +class vn_o_uniform_nva_air_01: vn_o_uniform_base { + ACE_GForceCoef = 0.8; +}; diff --git a/addons/compat_sog/CfgWeapons/weapons.hpp b/addons/compat_sog/CfgWeapons/weapons.hpp new file mode 100644 index 0000000000..e1cf5f6485 --- /dev/null +++ b/addons/compat_sog/CfgWeapons/weapons.hpp @@ -0,0 +1,39 @@ + +class vn_rifle; +class vn_m63a_lmg: vn_rifle { + EGVAR(overheating,closedBolt) = 0; + EGVAR(overheating,allowSwapBarrel) = 1; +}; +class vn_lmg: vn_rifle { + EGVAR(overheating,closedBolt) = 0; +}; +class vn_pk: vn_lmg { + EGVAR(overheating,allowSwapBarrel) = 1; +}; +class vn_m60: vn_lmg { + EGVAR(overheating,allowSwapBarrel) = 1; +}; +class vn_mg42: vn_lmg { + EGVAR(overheating,allowSwapBarrel) = 1; +}; +class vn_l4: vn_lmg { + EGVAR(overheating,allowSwapBarrel) = 1; +}; + +class vn_smg: vn_rifle { + EGVAR(overheating,closedBolt) = 0; +}; +class vn_vz61: vn_smg { + EGVAR(overheating,closedBolt) = 1; +}; + +class vn_mk1_udg: vn_smg { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; +}; +class vn_m79: vn_rifle { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; +}; +class vn_shotgun; +class vn_izh54: vn_shotgun { + EGVAR(overheating,jamTypesAllowed)[] = {"Fire", "Dud"}; +}; diff --git a/addons/compat_sog/CfgWeapons/weapons_melee.hpp b/addons/compat_sog/CfgWeapons/weapons_melee.hpp new file mode 100644 index 0000000000..077e57d38b --- /dev/null +++ b/addons/compat_sog/CfgWeapons/weapons_melee.hpp @@ -0,0 +1,63 @@ + +// always show melee weapons in the Arsenal, +// they were considered "janky" by BI and are hidden by default until "vn_arsenalShowMelee = 1;" is set in the mission config +class vn_hand_melee_base_dynamic_scope; +class vn_m_wrench_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_hammer: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_shovel_01: vn_hand_melee_base_dynamic_scope { + scope = 2; + EGVAR(trenches,entrenchingTool) = 1; +}; +class vn_m_axe_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_axe_fire: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_bayo_carbine: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_bayo_m14: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_bayo_m16: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_bayo_m1897: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_mk2_knife_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_bolo_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_machete_02: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_typeivaxe_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_m51_etool_01: vn_hand_melee_base_dynamic_scope { + scope = 2; + EGVAR(trenches,entrenchingTool) = 1; +}; +class vn_m_bayo_m4956: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_fighting_knife_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_vc_knife_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_machete_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; +class vn_m_fishing_rod_01: vn_hand_melee_base_dynamic_scope { + scope = 2; +}; diff --git a/addons/compat_sog/EMM_mainMenu_CfgMenus.hpp b/addons/compat_sog/EMM_mainMenu_CfgMenus.hpp new file mode 100644 index 0000000000..4c854a665b --- /dev/null +++ b/addons/compat_sog/EMM_mainMenu_CfgMenus.hpp @@ -0,0 +1,26 @@ +class EMM_mainMenu_CfgMenus { + class VN { + class menus { + class MainMenu; + class Tutorials: MainMenu { + items[] = { + "Bootcamp", + "VRTraining", + "Arsenal", + QGVAR(Arsenal), + "FieldManual", + "CommunityGuides", + "Exit" + }; + + class Arsenal; + class GVAR(Arsenal): Arsenal { + idc = -1; + action = QUOTE(playMission [ARR_2('','PATHTOEF(Arsenal,missions\Arsenal.VR)')]); + text = ECSTRING(Arsenal,Mission); + tooltip = ECSTRING(Arsenal,Mission_tooltip); + }; + }; + }; + }; +}; diff --git a/addons/compat_sog/UI/ammo_1rnd_60mm_ca.paa b/addons/compat_sog/UI/ammo_1rnd_60mm_ca.paa new file mode 100644 index 0000000000..021374ff5d Binary files /dev/null and b/addons/compat_sog/UI/ammo_1rnd_60mm_ca.paa differ diff --git a/addons/compat_sog/UI/ammo_1rnd_81mm_ca.paa b/addons/compat_sog/UI/ammo_1rnd_81mm_ca.paa new file mode 100644 index 0000000000..a83c4ef753 Binary files /dev/null and b/addons/compat_sog/UI/ammo_1rnd_81mm_ca.paa differ diff --git a/addons/compat_sog/UI/ammo_1rnd_82mm_ca.paa b/addons/compat_sog/UI/ammo_1rnd_82mm_ca.paa new file mode 100644 index 0000000000..6eed14616b Binary files /dev/null and b/addons/compat_sog/UI/ammo_1rnd_82mm_ca.paa differ diff --git a/addons/compat_sog/UI/ammo_1rnd_TOW_ca.paa b/addons/compat_sog/UI/ammo_1rnd_TOW_ca.paa new file mode 100644 index 0000000000..a38956e117 Binary files /dev/null and b/addons/compat_sog/UI/ammo_1rnd_TOW_ca.paa differ diff --git a/addons/compat_sog/UI/ammo_200rnd_762mm_ca.paa b/addons/compat_sog/UI/ammo_200rnd_762mm_ca.paa new file mode 100644 index 0000000000..d6a735e739 Binary files /dev/null and b/addons/compat_sog/UI/ammo_200rnd_762mm_ca.paa differ diff --git a/addons/compat_sog/UI/ammo_250rnd_30cal_ca.paa b/addons/compat_sog/UI/ammo_250rnd_30cal_ca.paa new file mode 100644 index 0000000000..e3f416e993 Binary files /dev/null and b/addons/compat_sog/UI/ammo_250rnd_30cal_ca.paa differ diff --git a/addons/compat_sog/UI/ammo_50rnd_127mm_ca.paa b/addons/compat_sog/UI/ammo_50rnd_127mm_ca.paa new file mode 100644 index 0000000000..51f65d5dfb Binary files /dev/null and b/addons/compat_sog/UI/ammo_50rnd_127mm_ca.paa differ diff --git a/addons/compat_sog/UI/csw_dshkm_aa_ca.paa b/addons/compat_sog/UI/csw_dshkm_aa_ca.paa new file mode 100644 index 0000000000..ed5cc28a09 Binary files /dev/null and b/addons/compat_sog/UI/csw_dshkm_aa_ca.paa differ diff --git a/addons/compat_sog/UI/csw_dshkm_ca.paa b/addons/compat_sog/UI/csw_dshkm_ca.paa new file mode 100644 index 0000000000..9e9571b7d5 Binary files /dev/null and b/addons/compat_sog/UI/csw_dshkm_ca.paa differ diff --git a/addons/compat_sog/UI/csw_dshkm_shield_ca.paa b/addons/compat_sog/UI/csw_dshkm_shield_ca.paa new file mode 100644 index 0000000000..91e097f6f3 Binary files /dev/null and b/addons/compat_sog/UI/csw_dshkm_shield_ca.paa differ diff --git a/addons/compat_sog/UI/csw_m1919a4_ca.paa b/addons/compat_sog/UI/csw_m1919a4_ca.paa new file mode 100644 index 0000000000..a983d63ab6 Binary files /dev/null and b/addons/compat_sog/UI/csw_m1919a4_ca.paa differ diff --git a/addons/compat_sog/UI/csw_m1919a6_ca.paa b/addons/compat_sog/UI/csw_m1919a6_ca.paa new file mode 100644 index 0000000000..9732004eec Binary files /dev/null and b/addons/compat_sog/UI/csw_m1919a6_ca.paa differ diff --git a/addons/compat_sog/UI/csw_m29_ca.paa b/addons/compat_sog/UI/csw_m29_ca.paa new file mode 100644 index 0000000000..dd6ab04a00 Binary files /dev/null and b/addons/compat_sog/UI/csw_m29_ca.paa differ diff --git a/addons/compat_sog/UI/csw_m2_ca.paa b/addons/compat_sog/UI/csw_m2_ca.paa new file mode 100644 index 0000000000..189508a0aa Binary files /dev/null and b/addons/compat_sog/UI/csw_m2_ca.paa differ diff --git a/addons/compat_sog/UI/csw_m2b_ca.paa b/addons/compat_sog/UI/csw_m2b_ca.paa new file mode 100644 index 0000000000..111cf94a83 Binary files /dev/null and b/addons/compat_sog/UI/csw_m2b_ca.paa differ diff --git a/addons/compat_sog/UI/csw_m60_ca.paa b/addons/compat_sog/UI/csw_m60_ca.paa new file mode 100644 index 0000000000..11f180f902 Binary files /dev/null and b/addons/compat_sog/UI/csw_m60_ca.paa differ diff --git a/addons/compat_sog/UI/csw_mg42_ca.paa b/addons/compat_sog/UI/csw_mg42_ca.paa new file mode 100644 index 0000000000..a921dd5f1e Binary files /dev/null and b/addons/compat_sog/UI/csw_mg42_ca.paa differ diff --git a/addons/compat_sog/UI/csw_mk18_ca.paa b/addons/compat_sog/UI/csw_mk18_ca.paa new file mode 100644 index 0000000000..bd03dea3d1 Binary files /dev/null and b/addons/compat_sog/UI/csw_mk18_ca.paa differ diff --git a/addons/compat_sog/UI/csw_pk_ca.paa b/addons/compat_sog/UI/csw_pk_ca.paa new file mode 100644 index 0000000000..23d47b5265 Binary files /dev/null and b/addons/compat_sog/UI/csw_pk_ca.paa differ diff --git a/addons/compat_sog/UI/csw_rpd_ca.paa b/addons/compat_sog/UI/csw_rpd_ca.paa new file mode 100644 index 0000000000..00ab06a14c Binary files /dev/null and b/addons/compat_sog/UI/csw_rpd_ca.paa differ diff --git a/addons/compat_sog/UI/csw_sgm_ca.paa b/addons/compat_sog/UI/csw_sgm_ca.paa new file mode 100644 index 0000000000..8ab2d8e98f Binary files /dev/null and b/addons/compat_sog/UI/csw_sgm_ca.paa differ diff --git a/addons/compat_sog/UI/csw_sgm_shield_ca.paa b/addons/compat_sog/UI/csw_sgm_shield_ca.paa new file mode 100644 index 0000000000..3e17a9b143 Binary files /dev/null and b/addons/compat_sog/UI/csw_sgm_shield_ca.paa differ diff --git a/addons/compat_sog/UI/csw_tow_ca.paa b/addons/compat_sog/UI/csw_tow_ca.paa new file mode 100644 index 0000000000..e5b3c658cd Binary files /dev/null and b/addons/compat_sog/UI/csw_tow_ca.paa differ diff --git a/addons/compat_sog/UI/csw_type53_ca.paa b/addons/compat_sog/UI/csw_type53_ca.paa new file mode 100644 index 0000000000..c4c76553e8 Binary files /dev/null and b/addons/compat_sog/UI/csw_type53_ca.paa differ diff --git a/addons/compat_sog/XEH_PREP.hpp b/addons/compat_sog/XEH_PREP.hpp new file mode 100644 index 0000000000..b9f7907afe --- /dev/null +++ b/addons/compat_sog/XEH_PREP.hpp @@ -0,0 +1,6 @@ +PREP(disableCookoff); +PREP(handleBikeMinePlace); +PREP(handlePunjiTrapDamage); +PREP(handlePunjiTrapPlace); +PREP(handlePunjiTrapTrigger); +PREP(woundsHandlerIncendiary); diff --git a/addons/compat_sog/XEH_postInit.sqf b/addons/compat_sog/XEH_postInit.sqf new file mode 100644 index 0000000000..99d1ed65ab --- /dev/null +++ b/addons/compat_sog/XEH_postInit.sqf @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +[QGVAR(handlePunjiTrapDamage), LINKFUNC(handlePunjiTrapDamage)] call CBA_fnc_addEventHandler; + +if (isServer) then { + [QEGVAR(trenches,placed), { + params ["", "_trench"]; + if (_trench isKindOf "vn_o_vc_spiderhole_01") then { + _trench enableSimulationGlobal false; + }; + }] call CBA_fnc_addEventHandler; + + [QEGVAR(trenches,finished), { + params ["", "_trench"]; + if (_trench isKindOf "vn_o_vc_spiderhole_01") then { + _trench enableSimulationGlobal true; + }; + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/compat_sog/XEH_preInit.sqf b/addons/compat_sog/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/compat_sog/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/compat_sog/XEH_preStart.sqf b/addons/compat_sog/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_sog/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp b/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp new file mode 100644 index 0000000000..bb222eaed1 --- /dev/null +++ b/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp @@ -0,0 +1,63 @@ +class CfgVehicles { + // Trench Actions + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ACE_Equipment { + class EGVAR(trenches,digEnvelopeSmall); + class EGVAR(compat_sog,digSpiderhole): EGVAR(trenches,digEnvelopeSmall) { + displayName = ECSTRING(compat_sog,Action_DigSpiderhole); + statement = QUOTE([ARR_2({_this call EFUNC(trenches,placeTrench)},[ARR_2(_this select 0,'vn_o_vc_spiderhole_01')])] call CBA_fnc_execNextFrame); + }; + class EGVAR(compat_sog,digSpiderholeAngled): EGVAR(trenches,digEnvelopeSmall) { + displayName = ECSTRING(compat_sog,Action_DigSpiderholeAngled); + statement = QUOTE([ARR_2({_this call EFUNC(trenches,placeTrench)},[ARR_2(_this select 0,'vn_o_vc_spiderhole_02')])] call CBA_fnc_execNextFrame); + }; + class EGVAR(compat_sog,digSpiderholeDual): EGVAR(trenches,digEnvelopeSmall) { + displayName = ECSTRING(compat_sog,Action_DigSpiderholeDual); + statement = QUOTE([ARR_2({_this call EFUNC(trenches,placeTrench)},[ARR_2(_this select 0,'vn_o_vc_spiderhole_03')])] call CBA_fnc_execNextFrame); + }; + }; + }; + }; + + // Spiderholes + class LandVehicle; + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + }; + class vn_o_vc_spiderhole_01: StaticWeapon { + EGVAR(trenches,diggingDuration) = QEGVAR(trenches,smallEnvelopeDigDuration); + EGVAR(trenches,removalDuration) = QEGVAR(trenches,smallEnvelopeRemoveDuration); + EGVAR(trenches,noGeoClass) = QEGVAR(compat_sog,spiderhole_01_nogeo); + EGVAR(trenches,placementData)[] = {1.5, 1.5, 0.1}; + EGVAR(trenches,grassCuttingPoints)[] = {}; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class ACE_ContinueDiggingTrench { + displayName = ECSTRING(trenches,ContinueDiggingTrench); + condition = QUOTE([ARR_2(_target,_player)] call EFUNC(trenches,canContinueDiggingTrench)); + statement = QUOTE([ARR_2(_target,_player)] call EFUNC(trenches,continueDiggingTrench)); + }; + }; + }; + }; + class vn_o_vc_spiderhole_02: vn_o_vc_spiderhole_01 { + EGVAR(trenches,noGeoClass) = QEGVAR(compat_sog,spiderhole_02_nogeo); + }; + class vn_o_vc_spiderhole_03: vn_o_vc_spiderhole_01 { + EGVAR(trenches,noGeoClass) = QEGVAR(compat_sog,spiderhole_03_nogeo); + EGVAR(trenches,placementData)[] = {1.5, 2.5, 0.1}; + }; + class EGVAR(compat_sog,spiderhole_01_nogeo): vn_o_vc_spiderhole_01 { + scope = 1; + }; + class EGVAR(compat_sog,spiderhole_02_nogeo): vn_o_vc_spiderhole_02 { + scope = 1; + }; + class EGVAR(compat_sog,spiderhole_03_nogeo): vn_o_vc_spiderhole_03 { + scope = 1; + }; +}; diff --git a/addons/compat_sog/compat_sog_trenches/config.cpp b/addons/compat_sog/compat_sog_trenches/config.cpp new file mode 100644 index 0000000000..68fccc2fa3 --- /dev/null +++ b/addons/compat_sog/compat_sog_trenches/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"loadorder_f_vietnam", "ace_trenches"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"BaerMitUmlaut", "veteran29"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/compat_sog_trenches/script_component.hpp b/addons/compat_sog/compat_sog_trenches/script_component.hpp new file mode 100644 index 0000000000..10b90eb71e --- /dev/null +++ b/addons/compat_sog/compat_sog_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/compat_sog/compat_sog_trenches_grad/CfgVehicles.hpp b/addons/compat_sog/compat_sog_trenches_grad/CfgVehicles.hpp new file mode 100644 index 0000000000..a9c8873ceb --- /dev/null +++ b/addons/compat_sog/compat_sog_trenches_grad/CfgVehicles.hpp @@ -0,0 +1,20 @@ +class CfgVehicles { + // Trench Actions + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ACE_Equipment { + // delete in reverse order + delete EGVAR(compat_sog,digSpiderholeDual); + delete EGVAR(compat_sog,digSpiderholeAngled); + delete EGVAR(compat_sog,digSpiderhole); + delete EGVAR(trenches,digEnvelopeSmall); + }; + }; + }; + + // Spiderholes + delete EGVAR(compat_sog,spiderhole_01_nogeo); + delete EGVAR(compat_sog,spiderhole_02_nogeo); + delete EGVAR(compat_sog,spiderhole_03_nogeo); +}; diff --git a/addons/compat_sog/compat_sog_trenches_grad/config.cpp b/addons/compat_sog/compat_sog_trenches_grad/config.cpp new file mode 100644 index 0000000000..06d670fb9a --- /dev/null +++ b/addons/compat_sog/compat_sog_trenches_grad/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"loadorder_f_vietnam", "ace_compat_sog_trenches", "grad_trenches_main"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"BaerMitUmlaut", "veteran29"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/compat_sog_trenches_grad/script_component.hpp b/addons/compat_sog/compat_sog_trenches_grad/script_component.hpp new file mode 100644 index 0000000000..55f4feb1f4 --- /dev/null +++ b/addons/compat_sog/compat_sog_trenches_grad/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches_grad +#define SUBCOMPONENT_BEAUTIFIED Trenches GRAD +#include "..\script_component.hpp" diff --git a/addons/compat_sog/config.cpp b/addons/compat_sog/config.cpp new file mode 100644 index 0000000000..04db68293c --- /dev/null +++ b/addons/compat_sog/config.cpp @@ -0,0 +1,60 @@ +#include "script_component.hpp" +#include "\z\ace\addons\refuel\defines.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = { + QGVAR(box_81mm_he), + QGVAR(box_81mm_wp), + QGVAR(box_81mm_chem), + QGVAR(box_81mm_lume), + QGVAR(box_60mm_he), + QGVAR(box_60mm_wp), + QGVAR(box_60mm_lume), + QGVAR(box_82mm_he), + QGVAR(box_82mm_wp), + QGVAR(box_82mm_lume) + }; + weapons[] = { + QGVAR(m2_carry), + QGVAR(m1919a4_carry), + QGVAR(m1919a6_carry), + QGVAR(m60_carry), + QGVAR(tow_carry), + QGVAR(dshkm_carry), + QGVAR(dshkm_shield_carry), + QGVAR(dshkm_AA_carry), + QGVAR(rpd_carry), + QGVAR(pk_carry), + QGVAR(mg42_carry), + QGVAR(sgm_carry), + QGVAR(sgm_shield_carry), + QGVAR(mk18_carry), + QGVAR(mortar_m29_carry), + QGVAR(mortar_m2_carry), + QGVAR(mortar_type53_carry) + }; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "loadorder_f_vietnam"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"BaerMitUmlaut", "veteran29"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +class CBA_Extended_EventHandlers; + +#include "ACE_CSW_Groups.hpp" +#include "ACE_Medical_Injuries.hpp" +#include "ACE_Triggers.hpp" +#include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgGlasses.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" +#include "EMM_mainMenu_CfgMenus.hpp" diff --git a/addons/compat_sog/functions/fnc_disableCookoff.sqf b/addons/compat_sog/functions/fnc_disableCookoff.sqf new file mode 100644 index 0000000000..07c36567a6 --- /dev/null +++ b/addons/compat_sog/functions/fnc_disableCookoff.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Disables cookoff for bicycles. + * + * Arguments: + * 0: Bicycle + * + * Return Value: + * None + * + * Example: + * [bicycle] call ace_compat_sog_fnc_disableCookoff + * + * Public: No + */ + +params ["_bicycle"]; + +_bicycle setVariable [QEGVAR(cookoff,enable), false]; +_bicycle setVariable [QEGVAR(cookoff,enableAmmoCookoff), false]; diff --git a/addons/compat_sog/functions/fnc_handleBikeMinePlace.sqf b/addons/compat_sog/functions/fnc_handleBikeMinePlace.sqf new file mode 100644 index 0000000000..83314e4b64 --- /dev/null +++ b/addons/compat_sog/functions/fnc_handleBikeMinePlace.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Handle placement of bike mine object. + * + * Arguments: + * 0: Bike mine + * + * Return Value: + * None + * + * Example: + * [bikeMine] call ace_compat_sog_fnc_handleBikeMinePlace + * + * Public: No + */ + +params ["_mine"]; + +if (!local _mine) exitWith {}; + +// change COM to have the bike upright like the placed mine +_mine setCenterOfMass [0,0, -0.5]; + +// prevent the object from swinging left and right +[{isTouchingGround _this}, { + _this setVelocity [0,0,0] +}, _mine, 3] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapDamage.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapDamage.sqf new file mode 100644 index 0000000000..4799f6207a --- /dev/null +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapDamage.sqf @@ -0,0 +1,57 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Manually triggers punji trap damage. + * + * Arguments: + * 0: Punji trap + * 1: Affected units + * + * Return Value: + * None + * + * Example: + * [trap] call ace_compat_sog_fnc_handlePunjiTrapDamage + * + * Public: No + */ +params ["_trap", "_affectedUnits"]; + +(getShotParents _trap) params ["", "_instigator"]; + +private _bodyParts = []; +private _stabCount = 0; + +switch (typeOf _trap select [0, 16]) do { + // Large trap + case "vn_mine_punji_01": { + _bodyParts = ["LeftLeg", "RightLeg", "Body"]; + _stabCount = random [7, 10, 13]; + }; + // Small trap + case "vn_mine_punji_02": { + _bodyParts = ["LeftLeg", "RightLeg"]; + _stabCount = random [3, 5, 7]; + }; + // Whip trap + case "vn_mine_punji_03": { + _bodyParts = ["LeftLeg", "RightLeg", "Body"]; + _stabCount = random [3, 5, 7]; + }; + // Door way trap + case "vn_mine_punji_04": { + _bodyParts = ["Head", "Body"]; + _stabCount = random [3, 5, 7]; + }; + // Side whip trap + case "vn_mine_punji_05": { + _bodyParts = ["LeftLeg", "RightLeg"]; + _stabCount = random [3, 5, 7]; + }; +}; + +{ + for "_i" from 0 to _stabCount do { + [_x, random [1, 2, 3], selectRandom _bodyParts, "stab", _instigator] call EFUNC(medical,addDamageToUnit); + }; +} forEach (_affectedUnits select {isDamageAllowed _x}); // isDamageAllowed already does local check diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapPlace.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapPlace.sqf new file mode 100644 index 0000000000..315e1cbe90 --- /dev/null +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapPlace.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Handle placement of punji trap object. + * + * Arguments: + * 0: Punji trap + * + * Return Value: + * None + * + * Example: + * [trap] call ace_compat_sog_fnc_handlePunjiTrapPlace + * + * Public: No + */ + +params ["_trap"]; + +if (isServer && {_trap isKindOf QEXPLOSIVES_PLACE(punji_03)}) exitWith { + + private _spikes = createSimpleObject ["vn\weapons_f_vietnam\mines\punji\vn_mine_punji_03_ammo", [0,0,0]]; + _spikes animateSource ["mine_trigger_source", 0.1]; + + private _offset = [0.0655, -0.0357, 0.0906]; + _spikes attachTo [_trap, _offset]; + _trap setVariable [QGVAR(spikes), _spikes]; + + _trap addEventHandler ["Deleted", { + params ["_trap"]; + deleteVehicle (_trap getVariable [QGVAR(spikes), objNull]); + }]; +}; diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf new file mode 100644 index 0000000000..7cac6829c5 --- /dev/null +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: GhostIsSpooky, veteran29 + * Handler for 'detonation' of a local punji trap. Workaround for local-only ammo hit event. + * + * Arguments: + * 0: Punji trap + * + * Return Value: + * None + * + * Example: + * [trap] call ace_compat_sog_fnc_handlePunjiTrapTrigger + * + * Public: No + */ + +params ["_trap"]; + +if !(GETEGVAR(medical,enabled,false)) exitWith {}; + +private _radius = getNumber (configOf _trap >> "indirectHitRange"); +private _affectedUnits = _trap nearEntities ["CAManBase", _radius]; + +private _spikesOffset = [configOf _trap >> QGVAR(spikesOffset), "ARRAY", [0,0,0]] call CBA_fnc_getConfigEntry; +if (_spikesOffset isNotEqualTo [0,0,0]) then { + private _spikesPos = _trap modelToWorld _spikesOffset; + private _spikesCheckSelection = getText (configOf _trap >> QGVAR(spikesCheckSelection)); + private _spikesCheckRadius = getNumber (configOf _trap >> QGVAR(spikesCheckRadius)); + + TRACE_3("Using spikes offset for affected units",_spikesOffset,_spikesCheckSelection,_spikesCheckRadius); + + _affectedUnits = _affectedUnits select { + private _distance = _spikesPos distance (_x modelToWorld (_x selectionPosition _spikesCheckSelection)); + + _distance <= _spikesCheckRadius // return + }; +}; + +if (_affectedUnits isEqualTo []) exitWith {}; + +[QGVAR(handlePunjiTrapDamage), [_trap, _affectedUnits], _affectedUnits] call CBA_fnc_targetEvent; diff --git a/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf b/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf new file mode 100644 index 0000000000..6d3b7a8678 --- /dev/null +++ b/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Custom wound handler for SOG: PF explosive incendiary ammunition. + * Determines if the unit should be ignited and passes the damage to other wound handlers. + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * Input + * + * Example: + * [player, [[0.5, "Body", 5]]] call ace_compat_sog_fnc_woundsHandlerIncendiary + * + * Public: No + */ + +params ["_unit", "_damages"]; +TRACE_2("woundsHandlerIncendiary",_unit,_damages); + +private _fireDamage = 0; +{ + _x params ["", "", "_damage"]; + _fireDamage = _fireDamage + _damage; +} forEach _damages; + +private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true]; +TRACE_2("",_intensity,_fireDamage); + +// Let fire handle if unit is set ablaze or not +[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent; + +_this // return diff --git a/addons/compat_sog/script_component.hpp b/addons/compat_sog/script_component.hpp new file mode 100644 index 0000000000..bc006559b3 --- /dev/null +++ b/addons/compat_sog/script_component.hpp @@ -0,0 +1,12 @@ +#define COMPONENT compat_sog +#define COMPONENT_BEAUTIFIED S.O.G. Prairie Fire Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE + +#include "\z\ace\addons\main\script_macros.hpp" + +#define EXPLOSIVES_PLACE(CLASS) EGVAR(explosives,DOUBLES(Place,CLASS)) +#define QEXPLOSIVES_PLACE(CLASS) QUOTE(EXPLOSIVES_PLACE(CLASS)) diff --git a/addons/compat_sog/stringtable.xml b/addons/compat_sog/stringtable.xml new file mode 100644 index 0000000000..fc64aef97c --- /dev/null +++ b/addons/compat_sog/stringtable.xml @@ -0,0 +1,499 @@ + + + + + Dig in + Zakop + Eingraben + Trincerati + 掘る + 땅파기 + 挖掘 + Закопать + Enterrarse + Escavar + Creuser + + + M49A2 60mm HE + M49A2 60mm HE + M49A2 60mm HE + M49A2 60mm 榴弾 + M49A2 60mm HE + M49A2 60mm 고폭 + M49A2 60 mm 高爆弹 + M49A2 60 мм ОФ + M49A2 60mm HE + M49A2 60mm HE + M49A2 60mm HE + + + M302 60mm WP + M302 60mm Weißer Phosphor + M302 60mm Fosforo Bianco + M302 60mm 白リン弾 + M302 60mm WP + M302 60mm 백린 + M302 60 mm 白磷弹 + M302 60 мм Фосфорная + M302 60mm WP + M302 60mm WP + M302 60mm Phosphore Blanc + + + M83 60mm Lume + M83 60mm Leuchtpatrone + M83 60mm Illuminante + M83 60mm 照明弾 + M83 60mm ILUM + M83 60mm 조명 + M83 60 mm 照明弹 + M83 60 мм Осветительная + M83 60mm Iluminación + M83 60mm Iluminação + M83 60 mm Eclairant + + + M374 81mm HE + M374 81mm HE + M374 81mm HE + M374 81mm 榴弾 + M374 81mm HE + M374 81mm 고폭 + M374 81 mm 高爆弹 + M374 81 мм ОФ + M374 81mm HE + M374 81mm HE + M374 81mm HE + + + M375 81mm WP + M375 81mm Weißer Phosphor + M375 81mm Fosforo Bianco + M375 81mm 白リン弾 + M375 81mm WP + M375 81mm 백린 + M375 81 mm 白磷弹 + M375 81 мм Фосфорная + M375 81mm WP + M375 81mm WP + M375 81mm Phosphore Blanc + + + M301A3 81mm Lume + M301A3 81mm Leuchtpatrone + M301A3 81mm Illuminante + M301A3 81mm 照明弾 + M301A3 81mm ILUM + M301A3 81mm 조명 + M301A3 81 mm 照明弹 + M301A3 81 мм Осветительная + M301A3 81mm Iluminación + M301A3 81mm Iluminação + M301A3 81mm Eclairant + + + M57 81mm Smoke + M57 81mm Nebelpatrone + M57 81mm Fumogeno + M57 81mm 発煙弾 + M57 81mm Dymny + M57 81mm 연막 + M57 81 mm 烟雾弹 + M57 81 мм Дымовая + M57 81mm Smoke + M57 81mm Fumígena + M57 81mm Fumigène + + + O-832D 82mm HE + O-832D 82mm HE + O-832D 82mm HE + O-832D 82mm 榴弾 + O-832D 82mm HE + O-832D 82mm 고폭 + O-832D 82 mm 高爆弹 + О-832Д 82 мм ОФ + O-832D 82mm HE + O-832D 82mm HE + O-832D 82mm HE + + + D-832 82mm WP + D-832 82mm Weißer Phosphor + D-832 82mm Fosforo Bianco + D-832 82mm 白リン弾 + D-832 82mm WP + D-832 82mm 백린 + D-832 82 mm 白磷弹 + Д-832 82 мм Фосфорная + D-832 82mm WP + D-832 82mm WP + D-832 82mm Phosphore Blanc + + + S-832S 82mm Lume + S-832S 82mm Leuchtpatrone + S-832S 82mm Illuminante + S-832S 82mm 照明弾 + S-832S 82mm ILUM + S-832S 82mm 조명 + S-832S 82 mm 照明弹 + С-832С 82 мм Осветительная + S-832S 82mm Iluminación + S-832S 82mm Iluminação + S-832S 82mm Eclairant + + + [ACE] M49A2 60mm HE Box + [ACE] M49A2 60mm HE Box + [ACE] Scatola M49A2 60mm HE + [ACE] M49A2 60mm 榴弾入り弾薬箱 + [ACE] Skrzynia M49A2 60mm HE + [ACE] M49A2 60mm 고폭 상자 + [ACE] M49A2 60 mm 高爆弹弹药箱 + [ACE] Коробка M49A2 60 мм ОФ + [ACE] M49A2 60mm Caja de HE + [ACE] M49A2 60mm Caixa de HE + [ACE] Scatola M49A2 60mm HE + + + [ACE] M302 60mm WP Box + [ACE] M302 60mm Weißer Phosphor Box + [ACE] Scatola M302 60mm Fosforo Bianco + [ACE] M302 60mm 白リン弾入り弾薬箱 + [ACE] Skrzynia M302 60mm WP + [ACE] M302 60mm 백린 상자 + [ACE] M302 60 mm 白磷弹弹药箱 + [ACE] Коробка M302 60 мм Фосфорных + [ACE] M302 60mm Caja de WP + [ACE] M302 60mm Caixa de WP + [ACE] M302 60mm Phosphore Blanc Box + + + [ACE] M83 60mm Lume Box + [ACE] M83 60mm Leuchtpatrone Box + [ACE] Scatola M83 60mm Illuminanti + [ACE] M83 60mm 照明弾弾入り弾薬箱 + [ACE] Skrzynia ILUM M83 60mm + [ACE] M83 60mm 조명 상자 + [ACE] M83 60 mm 照明弹弹药箱 + [ACE] Коробка M83 60 мм Осветительных + [ACE] M83 60mm Caja de Iluminación + [ACE] M83 60mm Caixa de Iluminação + [ACE] M83 60mm Eclairant Box + + + [ACE] M374 81mm HE Box + [ACE] M374 81mm HE Box + [ACE] Scatola M374 81mm HE + [ACE] M374 81mm 榴弾入り弾薬箱 + [ACE] Skrzynia M374 81mm HE + [ACE] M374 81mm 고폭 상자 + [ACE] M374 81 mm 高爆弹弹药箱 + [ACE] Коробка M374 81 мм ОФ + [ACE] M374 81mm Caja de HE + [ACE] M374 81mm Caixa de HE + [ACE] Scatola M374 81mm HE + + + [ACE] M375 81mm WP Box + [ACE] M375 81mm Weißer Phosphor Box + [ACE] Scatola M375 81mm Fosforo Bianco + [ACE] M375 81mm 白リン弾入り弾薬箱 + [ACE] Skrzynia M375 81mm WP + [ACE] M375 81mm 백린 상자 + [ACE] M375 81 mm 白磷弹弹药箱 + [ACE] Коробка M375 81 мм Фосфорных + [ACE] M375 81mm Caja de WP + [ACE] M375 81mm Caixa de WP + [ACE] M375 81mm Phosphore Blanc Box + + + [ACE] M301A3 81mm Lume Box + [ACE] M301A3 81mm Leuchtpatrone Box + [ACE] Scatola M301A3 81mm Illuminanti + [ACE] M301A1 81mm 照明弾入り弾薬箱 + [ACE] Skrzynia M301A3 81mm ILUM + [ACE] M301A3 81mm 조명 상자 + [ACE] M301A3 81 mm 照明弹弹药箱 + [ACE] Коробка M301A3 81 мм Осветительных + [ACE] M301A3 81mm Caja de Iluminación + [ACE] M301A3 81mm Caixa de Iluminação + [ACE] M301A3 81mm Eclairant Box + + + [ACE] M57 81mm Smoke Box + [ACE] M57 81mm Nebelpatrone Box + [ACE] Scatola M57 81mm Fumogeni + [ACE] M57 81mm 煙幕弾入り弾薬箱 + [ACE] Skrzynia M57 81mm Dymny + [ACE] M57 81mm 연막 상자 + [ACE] M57 81 mm 烟雾弹弹药箱 + [ACE] Коробка M57 81 мм Дымовых + [ACE] M57 81mm Caja de Humo + [ACE] M57 81mm Caixa de Fumígena + [ACE] M57 81mm Fumigène Box + + + [ACE] O-832D 82mm HE Box + [ACE] O-832D 82mm HE Box + [ACE] Scatola O-832D 82mm HE + [ACE] O-832D 82mm 榴弾入り弾薬箱 + [ACE] Skrzynia O-832D 82mm HE + [ACE] O-832D 82mm 고폭 상자 + [ACE] O-832D 82 mm 高爆弹弹药箱 + [ACE] Коробка О-832Д 82 мм ОФ + [ACE] O-832D 82mm Caja de HE + [ACE] O-832D 82mm Caixa de HE + [ACE] Scatola O-832D 82mm HE + + + [ACE] D-832 82mm WP Box + [ACE] D-832 82mm Weißer Phosphor Box + [ACE] Scatola D-832 82mm Fosforo Bianco + [ACE] D-832 82mm 白リン弾入り弾薬箱 + [ACE] Skrzynia D-832 82mm WP + [ACE] D-832 82mm 백린 상자 + [ACE] D-832 82 mm 白磷弹弹药箱 + [ACE] Коробка Д-832 82 мм Фосфорных + [ACE] D-832 82mm Caja de WP + [ACE] D-832 82mm Caixa de WP + [ACE] D-832 82mm Phosphore Blanc Box + + + [ACE] S-832S 82mm Lume Box + [ACE] S-832S 82mm Leuchtpatrone Box + [ACE] Scatola S-832S 82mm Illuminanti + [ACE] S-832S 82mm 照明弾入り弾薬箱 + [ACE] Skrzynia S-832S 82mm ILUM + [ACE] S-832S 82mm 조명 상자 + [ACE] S-832S 82 mm 照明弹弹药箱 + [ACE] Коробка С-832С 82 мм Осветительных + [ACE] S-832S 82mm Caja de Iluminación + [ACE] S-832S 82mm Caixa de Iluminação + [ACE] S-832S 82mm Eclairant Box + + + Dig Spiderhole + Schützenloch graben + Scava buco di ragno + 蛸壺壕を掘る + Wykop Lisią Norę + 개인호 파기 + 挖掘散兵坑 + Выкопать паучью дыру + Excavar Agujero de araña + Escavar buraco de aranha + Creuser un trou d'araignée + + + Dig Spiderhole (Angled Cover) + Schützenloch graben (Abgeschrägte Abdeckung) + Scava buco di ragno (Coperchio Angolato) + 蛸壺壕 (屋根) を掘る + Wykop Lisią Norę (z dachem) + 개인호 파기 (각진 엄폐) + 挖掘带斜盖散兵坑 + Выкопать крытую паучью дыру + Excavar Agujero de araña (Cubierta inclinada) + Escavar buraco de aranha (Cobertura inclinada) + Creuser un trou d'araignée (couverture d'angle) + + + Dig Spiderhole (Dual) + Großes Schützenloch graben + Scava buco di ragno (Doppio) + 蛸壺壕 (2人用) を掘る + Wykop Lisią Norę (podwójną) + 개인호 파기 (2인용) + 挖掘双人散兵坑 + Выкопать двойную паучью дыру + Excavar Agujero de araña (Doble) + Escavar buraco de aranha (Duplo) + Creuser un trou d'araignée (double) + + + [CSW] M1919A4 Gun Bag + [CSW] M1919A4 Waffentasche + [CSW] Borsa per Mitra M1919A4 + [CSW] M1919A4 ガン バッグ + [CSW] Torba na M1919A4 + [CSW] M1919A4 총가방 + [班组] M1919A4 枪袋 + [CSW] Сумка с M1919A4 + [CSW] M1919A4 Bolsa para arma + [CSW] Bolsa para M1919A4 + [CSW] M1919A4 Gun Bag + + + [CSW] M1919A6 Gun Bag + [CSW] M1919A6 Waffentasche + [CSW] Borsa per Mitra M1919A6 + [CSW] M1919A6 ガン バッグ + [CSW] Torba na M1919A6 + [CSW] M1919A6 총가방 + [班组] M1919A6 枪袋 + [CSW] Сумка с M1919A6 + [CSW] M1919A6 Bolsa para arma + [CSW] Bolsa para M1919A6 + [CSW] M1919A6 Gun Bag + + + [CSW] M60 Gun Bag + [CSW] M60 Waffentasche + [CSW] Borsa per Mitra M60 + [CSW] M60 ガン バッグ + [CSW] Torba na M60 + [CSW] M60 총가방 + [班组] M60 枪袋 + [CSW] Сумка с M60 + [CSW] M60 Bolsa para arma + [CSW] Bolsa para M60 + [CSW] M60 Gun Bag + + + [CSW] DShK (Shield) Gun Bag + [CSW] DShK (Schutzschild) Waffentasche + [CSW] Borsa per Mitra DShK (con scudo) + [CSW] DShK (防盾) ガン バッグ + [CSW] Torba na DShK (z tarczą) + [CSW] DShK (방패) 총가방 + [班组] DShK(防盾)枪袋 + [CSW] Сумка с ДШК (со щитом) + [CSW] DShK (Apantallada) Bolsa para arma + [CSW] Bolsa para DShK (Escudo) + [CSW] DShK (Shield) Gun Bag + + + [CSW] DShK (AA) Gun Bag + [CSW] DShK (AA) Waffentasche + [CSW] Borsa per Mitra DShK (AA) + [CSW] DShK (対空) ガン バッグ + [CSW] Torba na DShK (AA) + [CSW] DShK (대공) 총가방 + [班组] DShK(高)枪袋 + [CSW] Сумка с ДШК (зенитный) + [CSW] DShK (AA) Bolsa para arma + [CSW] Bolsa para DShK (AA) + [CSW] DShK (AA) Gun Bag + + + [CSW] RPD Gun Bag + [CSW] RPD Waffentasche + [CSW] Borsa per Mitra RPD + [CSW] RPD ガン バッグ + [CSW] Torba na RPD + [CSW] RPD 총가방 + [班组] RPD 枪袋 + [CSW] Сумка с РПД + [CSW] RPD Bolsa para arma + [CSW] Bolsa para RPD + [CSW] RPD Gun Bag + + + [CSW] PK Gun Bag + [CSW] PK Waffentasche + [CSW] Borsa per Mitra PK + [CSW] PK ガン バッグ + [CSW] Torba na PK + [CSW] PK 총가방 + [班组] PK 枪袋 + [CSW] Сумка с ПК + [CSW] PK Bolsa para arma + [CSW] Bolsa para PK + [CSW] PK Sac d'armes + + + [CSW] MG42 Gun Bag + [CSW] MG42 Waffentasche + [CSW] Borsa per Mitra MG42 + [CSW] MG42 ガン バッグ + [CSW] Torba na MG42 + [CSW] MG42 총가방 + [班组] MG42 枪袋 + [CSW] Сумка с MG42 + [CSW] MG42 Bolsa para arma + [CSW] Bolsa para MG42 + [CSW] MG42 Sac d'armes + + + [CSW] SGM Gun Bag + [CSW] SGM Waffentasche + [CSW] Borsa per Mitra SGM + [CSW] SGM ガン バッグ + [CSW] Torba na SGM + [CSW] SGM 총가방 + [班组] SGM 枪袋 + [CSW] Сумка с СГМ + [CSW] SGM Bolsa para arma + [CSW] Bolsa para SGM + [CSW] SGM Sac d'armes + + + [CSW] SGM (Shield) Gun Bag + [CSW] SGM (Schutzschild) Waffentasche + [CSW] Borsa per Mitra SGM (con scudo) + [CSW] SGM (防盾) ガン バッグ + [CSW] Torba na SGM (z tarczą) + [CSW] SGM (방패) 총가방 + [班组] SGM(防盾)枪袋 + [CSW] Сумка с СГМ (со щитом) + [CSW] SGM (Apantallada) Bolsa para arma + [CSW] Bolsa para SGM (Escudo) + [CSW] SGM Sac d'armes (avec bouclier) + + + [CSW] Mk18 Gun Bag + [CSW] Mk18 Waffentasche + [CSW] Borsa per GMG Mk18 + [CSW] Mk18 ガン バッグ + [CSW] Torba na Mk18 + [CSW] Mk18 총가방 + [班组] Mk18 枪袋 + [CSW] Сумка с Mk18 + [CSW] Mk18 Bolsa para arma + [CSW] Bolsa para Mk18 + [CSW] Mk18 Sac d'armes + + + [CSW] M29 Mortar Tube + [CSW] M29 Mörserrohr + [CSW] Tubo di Mortaio M29 + [CSW] M29 発射筒 + [CSW] M29 Rura od moździerza + [CSW] M29 박격포 포신 + [班组] M29 迫击炮炮管 + [CSW] Сумка с миномётом M29 + [CSW] M29 Tubo de Mortero + [CSW] M29 Tubo de Morteiro + [CSW] Tube de mortier M29 + + + [CSW] M2 Mortar Tube + [CSW] M2 Mörserrohr + [CSW] Tubo di Mortaio M2 + [CSW] M2 底盤 + [CSW] M2 Rura od moździerza + [CSW] M2 박격포 포신 + [班组] M2 迫击炮炮管 + [CSW] Сумка с миномётом M2 + [CSW] M2 Tubo de mortero + [CSW] M2 Tubo de Morteiro + [CSW] Tube de mortier M2 + + + [CSW] Type 53 Mortar Tube + [CSW] Typ 53 Mörserrohr + [CSW] Tubo di Mortaio Type 53 + [CSW] 53 式 発射筒 + [CSW] Type 53 Rura od moździerza + [CSW] 53식 박격포 포신 + [班组] 53式迫击炮炮管 + [CSW] Сумка с миномётом Type 53 + [CSW] Type 53 Tubo de mortero + [CSW] Type 53 Tubo de Morteiro + [CSW] Tube de mortier Type 53 + + + diff --git a/addons/compat_spe/$PBOPREFIX$ b/addons/compat_spe/$PBOPREFIX$ new file mode 100644 index 0000000000..2334b339da --- /dev/null +++ b/addons/compat_spe/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_spe diff --git a/addons/compat_spe/ACE_Medical_Injuries.hpp b/addons/compat_spe/ACE_Medical_Injuries.hpp new file mode 100644 index 0000000000..62acb1401f --- /dev/null +++ b/addons/compat_spe/ACE_Medical_Injuries.hpp @@ -0,0 +1,15 @@ +class ACE_Medical_Injuries { + class damageTypes { + class woundHandlers; + + class explosive { + class woundHandlers: woundHandlers {}; + }; + class GVAR(explosive_incendiary): explosive { + class woundHandlers: woundHandlers { + // TODO use function name after bug with the woundHandlers config caching is fixed + ADDON = QUOTE({call FUNC(woundsHandlerIncendiary)}); + }; + }; + }; +}; diff --git a/addons/compat_spe/CfgAmmo.hpp b/addons/compat_spe/CfgAmmo.hpp new file mode 100644 index 0000000000..d11510648b --- /dev/null +++ b/addons/compat_spe/CfgAmmo.hpp @@ -0,0 +1,7 @@ +class CfgAmmo { + #include "CfgAmmo\bombs.hpp" + #include "CfgAmmo\explosives.hpp" + #include "CfgAmmo\grenades.hpp" + #include "CfgAmmo\melee.hpp" + #include "CfgAmmo\bullets.hpp" +}; diff --git a/addons/compat_spe/CfgAmmo/bombs.hpp b/addons/compat_spe/CfgAmmo/bombs.hpp new file mode 100644 index 0000000000..489930289c --- /dev/null +++ b/addons/compat_spe/CfgAmmo/bombs.hpp @@ -0,0 +1,46 @@ +class SPE_Bomb_base; +class SPE_NC250_Bomb: SPE_Bomb_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 166000; + EGVAR(frag,charge) = 130000; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large","ACE_frag_huge"}; +}; +class SPE_NC50_Bomb: SPE_Bomb_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 25000; + EGVAR(frag,charge) = 24400; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large"}; +}; +class SPE_SC500_Bomb: SPE_Bomb_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 200000; + EGVAR(frag,charge) = 275000; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large","ACE_frag_huge"}; +}; +class SPE_US_500lb_Bomb: SPE_Bomb_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 100000; + EGVAR(frag,charge) = 124000; + EGVAR(frag,gurney_c) = 2700; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large","ACE_frag_huge"}; +}; +class SPE_US_1000lb_Bomb: SPE_Bomb_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 200000; + EGVAR(frag,charge) = 158000; + EGVAR(frag,gurney_c) = 2700; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large","ACE_frag_huge"}; +}; diff --git a/addons/compat_spe/CfgAmmo/bullets.hpp b/addons/compat_spe/CfgAmmo/bullets.hpp new file mode 100644 index 0000000000..1e0e22e62d --- /dev/null +++ b/addons/compat_spe/CfgAmmo/bullets.hpp @@ -0,0 +1,12 @@ +class SPE_Bullet_Vehicle_base; + +class SPE_B_127x99_Mixed: SubmunitionBase { + ACE_caliber = 12.954; +}; + +class SPE_B_127x99_Ball: SPE_Bullet_Vehicle_base { + ACE_caliber = 12.954; +}; +class SPE_B_127x99_API: SPE_B_127x99_Ball { + EGVAR(vehicle_damage,incendiary) = 1; +}; diff --git a/addons/compat_spe/CfgAmmo/explosives.hpp b/addons/compat_spe/CfgAmmo/explosives.hpp new file mode 100644 index 0000000000..14b4910446 --- /dev/null +++ b/addons/compat_spe/CfgAmmo/explosives.hpp @@ -0,0 +1,231 @@ +class ShellBase; +class SubmunitionBase; +class MineCore; +class PipeBombBase; +class SPE_MAIN_pipebomb: PipeBombBase {}; +class SPE_ShellHE_base: ShellBase {}; +class SPE_ShellHEAT_base: ShellBase {}; +class RocketBase; +class SPE_MAIN_mine: MineCore {}; +class SPE_Rocket_base: RocketBase {}; +class SPE_PzFaust_30m: SPE_Rocket_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 150; + EGVAR(frag,charge) = 400; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_small"}; +}; +class SPE_60mm_M6: SPE_Rocket_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 250; + EGVAR(frag,charge) = 400; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_small"}; +}; +class SPE_Sh_M43A1_81_HE: SubmunitionBase { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 1200; + EGVAR(frag,charge) = 600; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; +}; +class SPE_M48_HE: SPE_ShellHE_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 1250; + EGVAR(frag,charge) = 670; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; +}; +class SPE_M101_M1_HE: SPE_ShellHE_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2500; + EGVAR(frag,charge) = 1980; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large"}; +}; +class SPE_S_105L28_Gr38: SPE_ShellHE_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2500; + EGVAR(frag,charge) = 1500; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large"}; +}; +class SPE_S_105L28_Gr39HlC: SPE_ShellHEAT_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2500; + EGVAR(frag,charge) = 1500; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large"}; +}; +class SPE_R_280mm_WkSpr: SubmunitionBase { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 37000; + EGVAR(frag,charge) = 50000; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_large","ACE_frag_huge"}; +}; +class SPE_US_Bangalore_ammo: SPE_MAIN_pipebomb { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 1700; + EGVAR(frag,charge) = 4100; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_Ladung_Big_ammo: SPE_MAIN_pipebomb { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 500; + EGVAR(frag,charge) = 1500; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_Ladung_Small_ammo: SPE_MAIN_pipebomb { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 250; + EGVAR(frag,charge) = 750; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_US_M1A1_ATMINE_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2100; + EGVAR(frag,charge) = 2700; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_US_TNT_half_pound_ammo: SPE_MAIN_pipebomb { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 100; + EGVAR(frag,charge) = 226; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_US_TNT_4pound_ammo: SPE_MAIN_pipebomb { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 372; + EGVAR(frag,charge) = 1814; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_US_M3_PRessure_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2267; + EGVAR(frag,charge) = 454; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_US_M3_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2267; + EGVAR(frag,charge) = 454; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_shumine42_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 300; + EGVAR(frag,charge) = 200; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_Shg24x7_Improvised_Mine_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 525; + EGVAR(frag,charge) = 1330; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; +}; +class SPE_SMI35_Pressure_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2720; + EGVAR(frag,charge) = 182; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_SMI35_1_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2720; + EGVAR(frag,charge) = 182; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_SMI35_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2720; + EGVAR(frag,charge) = 182; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_STMI_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 1520; + EGVAR(frag,charge) = 152; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; +class SPE_TMI42_ammo: SPE_MAIN_mine { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 2520; + EGVAR(frag,charge) = 5400; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_medium","ACE_frag_small"}; + EGVAR(explosives,defuseObjectPosition)[] = {0, 0, 0.02}; +}; diff --git a/addons/compat_spe/CfgAmmo/grenades.hpp b/addons/compat_spe/CfgAmmo/grenades.hpp new file mode 100644 index 0000000000..12043d5011 --- /dev/null +++ b/addons/compat_spe/CfgAmmo/grenades.hpp @@ -0,0 +1,117 @@ +class GrenadeBase; +class SPE_GrenadeHand_base; +class SPE_Grenade_base: GrenadeBase {}; + +class SPE_US_M15: SPE_GrenadeHand_base { + ACE_damageType = QGVAR(explosive_incendiary); + EGVAR(frag,enabled) = 1; +}; +class SPE_Shg24: SPE_GrenadeHand_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 75; + EGVAR(frag,charge) = 170; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_tiny_HD"}; +}; +class SPE_Shg24_Frag: SPE_GrenadeHand_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 250; + EGVAR(frag,charge) = 190; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; +}; +class SPE_Shg24x7: SPE_GrenadeHand_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 525; + EGVAR(frag,charge) = 1330; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; +}; +class SPE_M39: SPE_GrenadeHand_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 200; + EGVAR(frag,charge) = 112; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_tiny_HD"}; +}; +class SPE_US_Mk_2: SPE_GrenadeHand_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 400; + EGVAR(frag,charge) = 56; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; +}; +class SPE_US_Mk_2_Yellow: SPE_US_Mk_2 {}; +class SPE_US_Mk_3: SPE_GrenadeHand_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 90; + EGVAR(frag,charge) = 200; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_tiny_HD"}; +}; +class SPE_G_M9A1: SPE_Grenade_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 200; + EGVAR(frag,charge) = 113; + EGVAR(frag,gurney_c) = 2750; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_tiny_HD"}; +}; +class SPE_G_MK2: SPE_Grenade_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 400; + EGVAR(frag,charge) = 56; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "3/5"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; +}; +class SPE_G_PZGR_30: SPE_Grenade_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 120; + EGVAR(frag,charge) = 50; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_tiny_HD"}; +}; +class SPE_G_PZGR_40: SPE_Grenade_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 180; + EGVAR(frag,charge) = 75; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_tiny_HD"}; +}; +class SPE_G_SPRGR_30_Detonation: SPE_Grenade_base { + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,metal) = 150; + EGVAR(frag,charge) = 200; + EGVAR(frag,gurney_c) = 2440; + EGVAR(frag,gurney_k) = "1/2"; + EGVAR(frag,classes)[] = {"ACE_frag_small_HD"}; +}; + +class SmokeShell; +class SPE_SmokeShell_base: SmokeShell {}; +class SPE_US_AN_M14: SPE_SmokeShell_base { + EGVAR(grenades,incendiary) = 1; +}; +class SPE_US_Mk_1: SPE_SmokeShell_base { + EGVAR(frag,enabled) = 0; +}; diff --git a/addons/compat_spe/CfgAmmo/melee.hpp b/addons/compat_spe/CfgAmmo/melee.hpp new file mode 100644 index 0000000000..d9a07beb8b --- /dev/null +++ b/addons/compat_spe/CfgAmmo/melee.hpp @@ -0,0 +1,12 @@ +class BulletBase; +class BulletCore; +class BulletBase_NonAceAB: BulletCore {}; +class SPE_Bullet_base: BulletBase {}; + +class SPE_B_Bayonet: SPE_Bullet_base { + ACE_damageType = "stab"; +}; + +class SPE_Base_Flamethrower_Ammo: BulletBase_NonAceAB { + ACE_damageType = QGVAR(explosive_incendiary); +}; diff --git a/addons/compat_spe/CfgEventHandlers.hpp b/addons/compat_spe/CfgEventHandlers.hpp new file mode 100644 index 0000000000..865276cfba --- /dev/null +++ b/addons/compat_spe/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; diff --git a/addons/compat_spe/CfgGlasses.hpp b/addons/compat_spe/CfgGlasses.hpp new file mode 100644 index 0000000000..12f47c4099 --- /dev/null +++ b/addons/compat_spe/CfgGlasses.hpp @@ -0,0 +1,39 @@ +#define COMBAT_GOGGLES ACE_Overlay = QPATHTOEF(goggles,textures\HUD\CombatGoggles.paa); \ + ACE_OverlayCracked = QPATHTOEF(goggles,textures\HUD\CombatGogglesCracked.paa); \ + ACE_Resistance = 2; \ + ACE_Protection = 1; + +class CfgGlasses { + class SPE_GER_Glasses; + class G_SPE_Dust_Goggles_2: SPE_GER_Glasses { + ACE_TintAmount = 16; + COMBAT_GOGGLES + }; + class G_SPE_Dust_Goggles: SPE_GER_Glasses { + ACE_TintAmount = 8; + COMBAT_GOGGLES + }; + class SPE_US_Glasses; + class G_SPE_SWDG_Goggles: SPE_US_Glasses { + COMBAT_GOGGLES + }; + class G_SPE_Polar_Goggles: SPE_US_Glasses { + COMBAT_GOGGLES + }; + class G_SPE_Sunglasses_GER_Brown: SPE_GER_Glasses { + ACE_TintAmount = 16; + ACE_Resistance = 1; + }; + class G_SPE_Sunglasses_GER_Red: SPE_GER_Glasses { + ACE_TintAmount = 16; + ACE_Resistance = 1; + }; + class G_SPE_Sunglasses_US_Red: SPE_US_Glasses { + ACE_TintAmount = 16; + ACE_Resistance = 1; + }; + class G_SPE_Sunglasses_US_Yellow: SPE_US_Glasses { + ACE_TintAmount = 16; + ACE_Resistance = 1; + }; +}; diff --git a/addons/compat_spe/CfgMagazines.hpp b/addons/compat_spe/CfgMagazines.hpp new file mode 100644 index 0000000000..c5e0b54c75 --- /dev/null +++ b/addons/compat_spe/CfgMagazines.hpp @@ -0,0 +1,4 @@ +class CfgMagazines { + #include "CfgMagazines\csw.hpp" + #include "CfgMagazines\flamethrower.hpp" +}; diff --git a/addons/compat_spe/CfgMagazines/csw.hpp b/addons/compat_spe/CfgMagazines/csw.hpp new file mode 100644 index 0000000000..404156bd8f --- /dev/null +++ b/addons/compat_spe/CfgMagazines/csw.hpp @@ -0,0 +1,44 @@ +class CA_Magazine; + +// M1919A4/A6 +class SPE_50Rnd_762x63: CA_Magazine { + ACE_isBelt = 0; +}; + +class SPE_100Rnd_762x63: SPE_50Rnd_762x63 { + ACE_isBelt = 1; +}; + +class SPE_100Rnd_762x63_M1: SPE_100Rnd_762x63 { + ACE_isBelt = 1; +}; + +class SPE_100Rnd_762x63_M2_AP: SPE_100Rnd_762x63 { + ACE_isBelt = 1; +}; + +//MG34/42 + +class SPE_50Rnd_792x57: CA_Magazine { + ACE_isBelt = 0; +}; + +class SPE_50Rnd_792x57_sS: SPE_50Rnd_792x57 { + ACE_isBelt = 0; +}; + +class SPE_50Rnd_792x57_SMK: SPE_50Rnd_792x57_sS { + ACE_isBelt = 0; +}; + +class SPE_100Rnd_792x57: SPE_50Rnd_792x57 { + ACE_isBelt = 1; +}; + +class SPE_100Rnd_792x57_sS: SPE_50Rnd_792x57_sS { + ACE_isBelt = 1; +}; + +class SPE_100Rnd_792x57_SMK: SPE_50Rnd_792x57_SMK { + ACE_isBelt = 1; +}; diff --git a/addons/compat_spe/CfgMagazines/flamethrower.hpp b/addons/compat_spe/CfgMagazines/flamethrower.hpp new file mode 100644 index 0000000000..fc1d67558d --- /dev/null +++ b/addons/compat_spe/CfgMagazines/flamethrower.hpp @@ -0,0 +1,3 @@ +class SPE_Flamethrower_Mag: CA_Magazine { + type = 256; +}; diff --git a/addons/compat_spe/CfgVehicles.hpp b/addons/compat_spe/CfgVehicles.hpp new file mode 100644 index 0000000000..9ed470ec58 --- /dev/null +++ b/addons/compat_spe/CfgVehicles.hpp @@ -0,0 +1,7 @@ +class CfgVehicles { + #include "CfgVehicles\backpacks.hpp" + #include "CfgVehicles\planes.hpp" + #include "CfgVehicles\spe_boxes.hpp" + #include "CfgVehicles\tracked.hpp" + #include "CfgVehicles\wheeled.hpp" +}; diff --git a/addons/compat_spe/CfgVehicles/backpacks.hpp b/addons/compat_spe/CfgVehicles/backpacks.hpp new file mode 100644 index 0000000000..d7ac57ffdd --- /dev/null +++ b/addons/compat_spe/CfgVehicles/backpacks.hpp @@ -0,0 +1,40 @@ +class B_SPE_US_Backpack; + +class B_SPE_US_Backpack_roll: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Respawn_Tent: B_SPE_US_Backpack_roll { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_HMGAssistantBag: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Backpack_Bandoleer: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Backpack_dday: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Backpack_M43: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Backpack_M43_GP: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Backpack_RocketBag: B_SPE_US_Backpack { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_Backpack_RocketBag_Empty: B_SPE_US_Backpack_RocketBag { + EGVAR(trenches,entrenchingTool) = 1; +}; + +class B_SPE_US_packboard; +class B_SPE_US_packboard_ammo: B_SPE_US_packboard { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_packboard_eng: B_SPE_US_packboard { + EGVAR(trenches,entrenchingTool) = 1; +}; +class B_SPE_US_packboard_mortar: B_SPE_US_packboard { + EGVAR(trenches,entrenchingTool) = 1; +}; diff --git a/addons/compat_spe/CfgVehicles/planes.hpp b/addons/compat_spe/CfgVehicles/planes.hpp new file mode 100644 index 0000000000..8c0c6ed753 --- /dev/null +++ b/addons/compat_spe/CfgVehicles/planes.hpp @@ -0,0 +1,18 @@ +class Plane_Base_F; +class SPE_Plane_base: Plane_Base_F { + EGVAR(refuel,canReceive) = 1; + EGVAR(cargo,hasCargo) = 1; + EGVAR(cargo,space) = 4; +}; + +// ALLIED FORCES +class SPE_US_Plane_base: SPE_Plane_base {}; +class SPE_P47: SPE_US_Plane_base { + EGVAR(refuel,fuelCapacity) = 1155; +}; + +// AXIS FORCES +class SPE_GER_Plane_base: SPE_Plane_base {}; +class SPE_FW190F8: SPE_GER_Plane_base { + EGVAR(refuel,fuelCapacity) = 639; +}; diff --git a/addons/compat_spe/CfgVehicles/spe_boxes.hpp b/addons/compat_spe/CfgVehicles/spe_boxes.hpp new file mode 100644 index 0000000000..ebf70f5518 --- /dev/null +++ b/addons/compat_spe/CfgVehicles/spe_boxes.hpp @@ -0,0 +1,47 @@ + +// dragging carrying items +class ReammoBox_F; +class SPE_ReammoBox_base: ReammoBox_F { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0,1,1}; + EGVAR(dragging,carryDirection) = 0; + + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0,1.2,0}; + EGVAR(dragging,dragDirection) = 0; +}; + +class SPE_Fuel_Barrel_base; +class SPE_Fuel_Barrel_US_01: SPE_Fuel_Barrel_base { + EGVAR(cargo,size) = 2; + EGVAR(cargo,canLoad) = 1; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0,1,1}; + EGVAR(dragging,carryDirection) = 0; + + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0,1.2,0}; + EGVAR(dragging,dragDirection) = 0; + + EGVAR(refuel,fuelCargo) = 208; + EGVAR(refuel,hooks)[] = {{0.2,0,0.22}}; +}; +class SPE_Fuel_Barrel_German_01: SPE_Fuel_Barrel_base { + EGVAR(cargo,size) = 2; //reference SPE_Fuel_Barrel_US_01 + EGVAR(cargo,canLoad) = 1; //reference SPE_Fuel_Barrel_US_01 + + EGVAR(dragging,canCarry) = 1; //reference SPE_Fuel_Barrel_US_01 + EGVAR(dragging,carryPosition)[] = {0,1,1}; //reference SPE_Fuel_Barrel_US_01 + EGVAR(dragging,carryDirection) = 0; //reference SPE_Fuel_Barrel_US_01 + + EGVAR(dragging,canDrag) = 1; //reference SPE_Fuel_Barrel_US_01 + EGVAR(dragging,dragPosition)[] = {0,1.2,0}; //reference SPE_Fuel_Barrel_US_01 + EGVAR(dragging,dragDirection) = 0; //reference SPE_Fuel_Barrel_US_01 + + EGVAR(refuel,fuelCargo) = 208; //reference SPE_Fuel_Barrel_US_01 + EGVAR(refuel,hooks)[] = {{0.32,0,-0.3}}; +}; diff --git a/addons/compat_spe/CfgVehicles/tracked.hpp b/addons/compat_spe/CfgVehicles/tracked.hpp new file mode 100644 index 0000000000..8b0245aa82 --- /dev/null +++ b/addons/compat_spe/CfgVehicles/tracked.hpp @@ -0,0 +1,55 @@ +class Tank_F; +class SPE_Tank_base: Tank_F { + EGVAR(cargo,hasCargo) = 1; + EGVAR(cargo,space) = 4; + EGVAR(refuel,canReceive) = 1; + EGVAR(vehicle_damage,hullDetonationProb) = 0.01; + EGVAR(vehicle_damage,turretDetonationProb) = 0.01; + EGVAR(vehicle_damage,engineDetonationProb) = 0.01; + EGVAR(vehicle_damage,hullFireProb) = 0.2; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 1; +}; + +// ALLIED FORCES +class SPE_M4A1_Sherman_HullMG_base; + +class SPE_M4A1_75: SPE_M4A1_Sherman_HullMG_base { + EGVAR(refuel,fuelCapacity) = 660; +}; + +class SPE_M4A1_76: SPE_M4A1_Sherman_HullMG_base { + EGVAR(refuel,fuelCapacity) = 520; +}; + +class SPE_M4A1_T34_Calliope: SPE_M4A1_Sherman_HullMG_base { + EGVAR(refuel,fuelCapacity) = 520; +}; + +class SPE_M10_base: SPE_Tank_base { + EGVAR(refuel,fuelCapacity) = 620; +}; + +class SPE_M18_Hellcat_Base: SPE_Tank_base { + EGVAR(refuel,fuelCapacity) = 620; +}; + +// AXIS FORCES + +class SPE_Nashorn_base: SPE_Tank_base { + EGVAR(refuel,fuelCapacity) = 470; +}; + +class SPE_PzKpfwVI_H1_base: SPE_Tank_base { + EGVAR(refuel,fuelCapacity) = 540; +}; + +class SPE_PzKpfwIV_G_base: SPE_Tank_base { + EGVAR(refuel,fuelCapacity) = 600; +}; + +class SPE_PzKpfwIII_Base: SPE_Tank_base { + EGVAR(refuel,fuelCapacity) = 320; +}; diff --git a/addons/compat_spe/CfgVehicles/wheeled.hpp b/addons/compat_spe/CfgVehicles/wheeled.hpp new file mode 100644 index 0000000000..6ed68dfbdf --- /dev/null +++ b/addons/compat_spe/CfgVehicles/wheeled.hpp @@ -0,0 +1,71 @@ +class Truck_F; +class SPE_Truck_base: Truck_F { + EGVAR(cargo,hasCargo) = 1; + EGVAR(cargo,space) = 4; + EGVAR(refuel,canReceive) = 1; + EGVAR(refuel,fuelCapacity) = 88; + EGVAR(vehicle_damage,hullDetonationProb) = 0.2; + EGVAR(vehicle_damage,turretDetonationProb) = 0.03; + EGVAR(vehicle_damage,engineDetonationProb) = 0.03; + EGVAR(vehicle_damage,hullFireProb) = 0.6; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 1; +}; +class SPE_WheeledTracked_APC_base: SPE_Truck_base { + EGVAR(refuel,fuelCapacity) = 140; + EGVAR(vehicle_damage,hullDetonationProb) = 0.03; + EGVAR(vehicle_damage,turretDetonationProb) = 0.03; + EGVAR(vehicle_damage,engineDetonationProb) = 0.03; + EGVAR(vehicle_damage,hullFireProb) = 0.3; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 1; +}; + +class SPE_Halftrack_base: SPE_WheeledTracked_APC_base { + EGVAR(refuel,fuelCapacity) = 230; + EGVAR(vehicle_damage,hullDetonationProb) = 0.03; + EGVAR(vehicle_damage,turretDetonationProb) = 0.03; + EGVAR(vehicle_damage,engineDetonationProb) = 0.03; + EGVAR(vehicle_damage,hullFireProb) = 0.3; + EGVAR(vehicle_damage,turretFireProb) = 0.1; + EGVAR(vehicle_damage,engineFireProb) = 0.2; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; + EGVAR(vehicle_damage,canHaveFireRing) = 1; +}; + + +// WHEELED - AXIS +class SPE_OpelBlitz_base: SPE_Truck_base { + EGVAR(refuel,fuelCapacity) = 88; +}; + +class SPE_OpelBlitz_Ambulance: SPE_OpelBlitz_base { + EGVAR(medical,medicClass) = 1; +}; + +class SPE_OpelBlitz_Repair: SPE_OpelBlitz_base { + EGVAR(repair,canRepair) = 1; + EGVAR(rearm,defaultSupply) = 1200; +}; + +class SPE_OpelBlitz_Ammo: SPE_OpelBlitz_base { + EGVAR(rearm,defaultSupply) = 1200; +}; + +// WHEELED - ALLIED FORCES + +class SPE_US_M3_Halftrack_Ambulance: SPE_Halftrack_base { + EGVAR(medical,medicClass) = 1; +}; + +class SPE_US_M3_Halftrack_Repair: SPE_Halftrack_base { + EGVAR(repair,canRepair) = 1; +}; + +class SPE_US_M3_Halftrack_Ammo: SPE_Halftrack_base { + EGVAR(rearm,defaultSupply) = 1200; +}; diff --git a/addons/compat_spe/CfgWeapons.hpp b/addons/compat_spe/CfgWeapons.hpp new file mode 100644 index 0000000000..f6b1532bda --- /dev/null +++ b/addons/compat_spe/CfgWeapons.hpp @@ -0,0 +1,5 @@ +class CfgWeapons { + #include "CfgWeapons\helmets.hpp" + #include "CfgWeapons\launchers.hpp" + #include "CfgWeapons\weapons.hpp" +}; diff --git a/addons/compat_spe/CfgWeapons/helmets.hpp b/addons/compat_spe/CfgWeapons/helmets.hpp new file mode 100644 index 0000000000..54cbfd15b8 --- /dev/null +++ b/addons/compat_spe/CfgWeapons/helmets.hpp @@ -0,0 +1,142 @@ +class H_SPE_HelmetB; +class H_SPE_Hat: H_SPE_HelmetB {}; + +//ALLIED PILOT +class H_SPE_US_Helmet_Pilot: H_SPE_Hat { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_Op: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_Glasses_Up: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_Glasses_Down: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_Respirator: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_Respirator_Glasses_Up: H_SPE_US_Helmet_Pilot_Respirator { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_Respirator_Glasses_Down: H_SPE_US_Helmet_Pilot_Respirator { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_SWDG_Respirator: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Pilot_SWDG_low_Respirator: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15: H_SPE_US_Helmet_Pilot { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_Op: H_SPE_US_Helmet_H15 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_SWDG: H_SPE_US_Helmet_H15 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_SWDG_low: H_SPE_US_Helmet_H15 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_O2: H_SPE_US_Helmet_H15 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_B7_O2: H_SPE_US_Helmet_H15_O2 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_B7_low_O2: H_SPE_US_Helmet_H15_O2 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_SWDG_O2: H_SPE_US_Helmet_H15_O2 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_H15_SWDG_low_O2: H_SPE_US_Helmet_H15_O2 { + HEARING_PROTECTION_EARMUFF; +}; + +//ALLIED TANKER +class H_SPE_US_Helmet_Tank: H_SPE_HelmetB { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_NG: H_SPE_US_Helmet_Tank { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_Nun: H_SPE_US_Helmet_Tank { + HEARING_PROTECTION_OPEN; +}; +class H_SPE_US_Helmet_Tank_M1_OS: H_SPE_US_Helmet_Tank { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_M1_NS: H_SPE_US_Helmet_Tank_M1_OS { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_M1_Scrim: H_SPE_US_Helmet_Tank_M1_OS { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_polar: H_SPE_US_Helmet_Tank { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_polar_tapes: H_SPE_US_Helmet_Tank_polar { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_polar_low: H_SPE_US_Helmet_Tank_polar { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_US_Helmet_Tank_tapes: H_SPE_US_Helmet_Tank { + HEARING_PROTECTION_EARMUFF; +}; + +//AXIS PILOT +class H_SPE_GER_LW_PilotHelmet_base: H_SPE_Hat { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_LW_PilotHelmet: H_SPE_GER_LW_PilotHelmet_base { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_LW_S_PilotHelmet: H_SPE_GER_LW_PilotHelmet_base { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_LW_PilotHelmet_Mask_base: H_SPE_Hat { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_LW_PilotHelmet_Mask: H_SPE_GER_LW_PilotHelmet_Mask_base { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_LW_PilotHelmet_S_Mask: H_SPE_GER_LW_PilotHelmet_Mask_base { + HEARING_PROTECTION_EARMUFF; +}; + +//AXIS TANKER +class H_SPE_GER_TankPrivateCap: H_SPE_Hat { + HEARING_PROTECTION_OPEN; +}; +class H_SPE_GER_TankOfficerCap: H_SPE_Hat { + HEARING_PROTECTION_OPEN; +}; +class H_SPE_GER_Fieldcap: H_SPE_Hat { + HEARING_PROTECTION_OPEN; +}; +class H_SPE_GER_Fieldcap2: H_SPE_GER_Fieldcap { + HEARING_PROTECTION_OPEN; +}; +class H_SPE_GER_TankPrivateCap2: H_SPE_GER_TankPrivateCap { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_TankOffzCap2: H_SPE_GER_TankPrivateCap { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_TankOfficerCap2: H_SPE_GER_TankOfficerCap { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_SPGPrivateCap: H_SPE_Hat { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_ST_Tanker_Cap2: H_SPE_GER_Fieldcap2 { + HEARING_PROTECTION_EARMUFF; +}; +class H_SPE_GER_ST_Tanker_Cap: H_SPE_GER_Fieldcap { + HEARING_PROTECTION_EARMUFF; +}; diff --git a/addons/compat_spe/CfgWeapons/launchers.hpp b/addons/compat_spe/CfgWeapons/launchers.hpp new file mode 100644 index 0000000000..95de9e0e33 --- /dev/null +++ b/addons/compat_spe/CfgWeapons/launchers.hpp @@ -0,0 +1,17 @@ +class Launcher_Base_F; + +// LAUNCHER +class SPE_LAUNCHER: Launcher_Base_F {}; +class SPE_M1A1_Bazooka: SPE_LAUNCHER { + EGVAR(reloadlaunchers,enabled) = 1; + EGVAR(overpressure,angle) = 60; + EGVAR(overpressure,damage) = 0.7; + EGVAR(overpressure,priority) = 1; + EGVAR(overpressure,range) = 10; +}; +class SPE_PzFaust_30m: SPE_LAUNCHER { + EGVAR(overpressure,angle) = 60; + EGVAR(overpressure,damage) = 0.7; + EGVAR(overpressure,priority) = 1; + EGVAR(overpressure,range) = 10; +}; diff --git a/addons/compat_spe/CfgWeapons/weapons.hpp b/addons/compat_spe/CfgWeapons/weapons.hpp new file mode 100644 index 0000000000..52e6ba1dd5 --- /dev/null +++ b/addons/compat_spe/CfgWeapons/weapons.hpp @@ -0,0 +1,195 @@ +// MACHINE GUNS +class SPE_LMG; +class SPE_MG42: SPE_LMG { + ACE_barrelTwist = 304.8; + ACE_barrelLength = 533; + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,closedBolt) = 0; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; +}; +class SPE_MG34: SPE_LMG { + ACE_barrelTwist = 101.6; + ACE_barrelLength = 627; + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,closedBolt) = 0; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; +}; +class SPE_M1919A4: SPE_LMG { + ACE_barrelTwist = 254; + ACE_barrelLength = 610; + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,closedBolt) = 1; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; +}; +class SPE_M1919A6: SPE_M1919A4 { + ACE_barrelTwist = 254; + ACE_barrelLength = 610; + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,closedBolt) = 1; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; +}; +class SPE_M1918A2_BAR: SPE_LMG { + ACE_barrelTwist = 254; // unknown set to 1:10 + ACE_barrelLength = 610; + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,closedBolt) = 0; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 0; + EGVAR(overheating,dispersion) = 0.25; +}; +class SPE_FM_24_M29: SPE_LMG { + ACE_barrelTwist = 254; + ACE_barrelLength = 635; + EGVAR(overheating,mrbs) = 3000; + EGVAR(overheating,closedBolt) = 0; + EGVAR(overheating,slowdownFactor) = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + EGVAR(overheating,dispersion) = 0.25; +}; + +// SELF LOADING RIFLES +class SPE_RIFLE; +class SPE_G43: SPE_RIFLE { + EGVAR(overheating,JamChance) = 0.0003; + ACE_barrelTwist = 254; // unknown set to 1:10 + ACE_barrelLength = 550; +}; +class SPE_K98: SPE_RIFLE { + EGVAR(overheating,JamChance) = 0.0003; + ACE_barrelTwist = 254; // unknown set to 1:10 + ACE_barrelLength = 550; +}; +class SPE_M1_Carbine: SPE_RIFLE { + EGVAR(overheating,JamChance) = 0.0003; + ACE_barrelTwist = 254; // unknown set to 1:10 + ACE_barrelLength = 460; +}; +class SPE_M1_Garand: SPE_RIFLE { + EGVAR(overheating,JamChance) = 0.0003; + ACE_barrelTwist = 254; + ACE_barrelLength = 609.6; +}; +class SPE_M1903A3_Springfield: SPE_RIFLE { + ACE_barrelTwist = 254; + ACE_barrelLength = 610; +}; + +// ASSAULT RIFLE +class SPE_STG44: SPE_RIFLE { + EGVAR(overheating,JamChance) = 0.0015; + ACE_barrelTwist = 254; // unknown set to 1:10 + ACE_barrelLength = 420; +}; + +// BOLT ACTION RIFLES +class SPE_SRIFLE; +class SPE_K98ZF39: SPE_SRIFLE { + ACE_barrelTwist = 240; + ACE_barrelLength = 600; + ACE_scopeZeroRange = 100; + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + ACE_railHeightAboveBore = 1.8; // Distance between center of bore and rail in centimeters + ACE_scopeHeightAboveRail = 3.8; // Distance between center of scope and rail in centimeters +}; +class SPE_M1903A4_Springfield: SPE_SRIFLE { + ACE_barrelTwist = 254; + ACE_barrelLength = 610; + ACE_scopeZeroRange = 100; + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + ACE_railHeightAboveBore = 1.8; + ACE_scopeHeightAboveRail = 3.8; +}; + +// SUB MACHINE GUNS +class SPE_SMG; +class SPE_MP40: SPE_SMG { + ACE_barrelTwist = 203.2; + ACE_barrelLength = 251; + EGVAR(overheating,closedBolt) = 0; +}; +class SPE_Sten_Mk2: SPE_SMG { + ACE_barrelTwist = 254; + ACE_barrelLength = 196; + EGVAR(overheating,closedBolt) = 0; +}; +class SPE_M1A1_Thompson: SPE_SMG { + ACE_barrelTwist = 392; + ACE_barrelLength = 270; + EGVAR(overheating,closedBolt) = 0; +}; +class SPE_M3_GreaseGun: SPE_SMG { + ACE_barrelTwist = 392; + ACE_barrelLength = 270; + EGVAR(overheating,closedBolt) = 0; +}; + +// VESTS +class V_SPE_Vest_Camo_Base; +class V_SPE_GER_VestG43: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_DAK_VestG43: V_SPE_GER_VestG43 { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_GER_SaniVest2: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_GER_VestMG: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_GER_VestKar98: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_GER_VestMP40: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_GER_VestSTG: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_US_Assault_Vest: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_US_Vest_Garand_M43: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_US_Vest_Carbine_m43: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; +}; +class V_SPE_US_Vest_Carbine_pick: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; + ACE_isWirecutter = 1; +}; +class V_SPE_US_Vest_Carbine_eng: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; + ACE_isWirecutter = 1; +}; +class V_SPE_US_Vest_Garand_eng: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; + ACE_isWirecutter = 1; +}; +class V_SPE_GER_PioneerVest: V_SPE_Vest_Camo_Base { + EGVAR(trenches,entrenchingTool) = 1; + ACE_isWirecutter = 1; +}; +class V_SPE_DAK_PioneerVest: V_SPE_GER_PioneerVest { + EGVAR(trenches,entrenchingTool) = 1; + ACE_isWirecutter = 1; +}; diff --git a/addons/compat_spe/XEH_PREP.hpp b/addons/compat_spe/XEH_PREP.hpp new file mode 100644 index 0000000000..3d54401fe3 --- /dev/null +++ b/addons/compat_spe/XEH_PREP.hpp @@ -0,0 +1 @@ +PREP(woundsHandlerIncendiary); diff --git a/addons/compat_spe/XEH_preStart.sqf b/addons/compat_spe/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_spe/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_spe/XEH_preinit.sqf b/addons/compat_spe/XEH_preinit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/compat_spe/XEH_preinit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/compat_spe/compat_spe_csw/ACE_CSW_Groups.hpp b/addons/compat_spe/compat_spe_csw/ACE_CSW_Groups.hpp new file mode 100644 index 0000000000..35758ed533 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/ACE_CSW_Groups.hpp @@ -0,0 +1,50 @@ +class ACE_CSW_Groups { + + // --- Gun Turrets ------------------------------------------------------------- + + class SPE_100Rnd_762x63 { + SPE_100Rnd_762x63 = 1; + }; + + class SPE_100Rnd_762x63_M1 { + SPE_100Rnd_762x63_M1 = 1; + }; + + class SPE_100Rnd_762x63_M2_AP { + SPE_100Rnd_762x63_M2_AP = 1; + }; + + class SPE_100Rnd_792x57 { + SPE_100Rnd_792x57 = 1; + }; + + class SPE_100Rnd_792x57_sS { + SPE_100Rnd_792x57_sS = 1; + }; + + class SPE_100Rnd_792x57_SMK { + SPE_100Rnd_792x57_SMK = 1; + }; + + // --- Mortars ------------------------------------------------------------- + + class SPE_1Rnd_81mmHE_M1_M43A1 { + SPE_1Rnd_81mmHE_M1_M43A1 = 1; + }; + class SPE_1Rnd_81mmWP_M1_M57 { + SPE_1Rnd_81mmWP_M1_M57 = 1; + }; + class SPE_81mm_M1_M57_SmokeShell { + SPE_81mm_M1_M57_SmokeShell = 1; + }; + + class SPE_1Rnd_81mm_FA_Mle_1932_HE { + SPE_1Rnd_81mm_FA_Mle_1932_HE = 1; + }; + class SPE_81mm_FA_Mle_1932_Smoke { + SPE_81mm_FA_Mle_1932_Smoke = 1; + }; + class SPE_81mm_FA_Mle_1932_Illu { + SPE_81mm_FA_Mle_1932_Illu = 1; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp b/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp new file mode 100644 index 0000000000..e0a38aa341 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/CfgVehicles.hpp @@ -0,0 +1,240 @@ +class CfgVehicles { + class All { + class EventHandlers; + }; + class AllVehicles: All {}; + class Land: AllVehicles {}; + class LandVehicle: Land {}; + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + class Turrets { + class MainTurret; + }; + class UserActions; + }; + + // --- Mortars ----------------------------------------------------------------- + class StaticMortar: StaticWeapon { + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; + }; + class SPE_StaticMortar_base: StaticMortar { + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; + class EventHandlers: EventHandlers { + class SPE_StaticWeaponsHandler { + init = ""; + }; + }; + }; + + class SPE_US_Mortar_base: SPE_StaticMortar_base {}; + class SPE_M1_81: SPE_US_Mortar_base { + class Turrets: Turrets { + class MainTurret: MainTurret { + magazines[] = {}; + }; + }; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "zamerny"; + }; + }; + class UserActions { + delete Prepare_WP_Selected; + delete Prepare_WP; + delete Prepare_Smoke_Selected; + delete Prepare_Smoke; + delete Prepare_HE_Selected; + delete Prepare_HE; + delete Reload; + delete Unload; + }; + class ACE_CSW { + enabled = 1; + proxyWeapon = "SPE_M1_81_proxy"; + magazineLocation = "_target selectionPosition 'usti hlavne'"; + disassembleWeapon = "SPE_M1_81_Barrel"; + disassembleTurret = QGVAR(M1_81_baseplate); + ammoLoadTime = 3; + ammoUnloadTime = 3; + desiredAmmo = 1; + }; + }; + + class SPE_FR_Mortar_base: SPE_StaticMortar_base {}; + class SPE_MLE_27_31: SPE_FR_Mortar_base { + class Turrets: Turrets { + class MainTurret: MainTurret { + magazines[] = {}; + }; + }; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "zamerny"; + }; + }; + class UserActions { + delete Prepare_Illu_Selected; + delete Prepare_Illu; + delete Prepare_Smoke_Selected; + delete Prepare_Smoke; + delete Prepare_HE_Selected; + delete Prepare_HE; + delete Reload; + delete Unload; + }; + class ACE_CSW { + enabled = 1; + proxyWeapon = "SPE_MLE_27_31_proxy"; + magazineLocation = "_target selectionPosition 'usti hlavne'"; + disassembleWeapon = "SPE_MLE_27_31_Barrel"; + disassembleTurret = QGVAR(MLE_27_31_baseplate); + ammoLoadTime = 3; + ammoUnloadTime = 3; + desiredAmmo = 1; + }; + }; + + class SPE_GrW278_1: SPE_MLE_27_31 { + class Turrets: Turrets { + class MainTurret: MainTurret { + magazines[] = {}; + }; + }; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = "zamerny"; + }; + }; + class UserActions { + delete Prepare_Illu_Selected; + delete Prepare_Illu; + delete Prepare_Smoke_Selected; + delete Prepare_Smoke; + delete Prepare_HE_Selected; + delete Prepare_HE; + delete Reload; + delete Unload; + }; + class ACE_CSW { + enabled = 1; + proxyWeapon = "SPE_GrW278_1_proxy"; + magazineLocation = "_target selectionPosition 'usti hlavne'"; + disassembleWeapon = "SPE_GrW278_1_Barrel"; + disassembleTurret = QGVAR(GrW278_baseplate); + ammoLoadTime = 3; + ammoUnloadTime = 3; + desiredAmmo = 1; + }; + }; + + + class EGVAR(csw,baseTripod); + + class GVAR(MLE_27_31_baseplate): EGVAR(csw,baseTripod) { + scope = 2; + displayName = "$STR_DN_SPE_MLE_27_31_STAND"; + model = "\WW2\SPE_Assets_m\Weapons\Mortars_m\SPE_M1_Mortar_Stand_Deployed.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_MLE_27_31_Stand_X_ca.paa"; + hiddenSelections[] = {"camo_0","camo_1"}; + hiddenSelectionsTextures[] = {"ww2\spe_assets_t\weapons\mortars_t\m1_mortar\Brandt_81mm_Mortar_French_co.paa","WW2\SPE_Assets_t\Weapons\Mortars_t\M1_Mortar\Brandt_81mm_Sight_French_co.paa"}; + class ACE_CSW { + disassembleTo = "SPE_MLE_27_31_Stand"; + }; + }; + + class GVAR(GrW278_baseplate): EGVAR(csw,baseTripod) { + scope = 2; + displayName = "$STR_DN_SPE_GrW278_1_STAND"; + model = "\WW2\SPE_Assets_m\Weapons\Mortars_m\SPE_M1_Mortar_Stand_Deployed.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_GrW278_1_Stand_X_ca.paa"; + hiddenSelections[] = {"camo_0"}; + hiddenSelectionsTextures[] = {"ww2\spe_assets_t\weapons\mortars_t\m1_mortar\Brandt_81mm_Mortar_Gelb_co.paa"}; + class ACE_CSW { + disassembleTo = "SPE_GrW278_1_Stand"; + }; + }; + + class GVAR(M1_81_baseplate): EGVAR(csw,baseTripod) { + scope = 2; + displayName = "$STR_DN_SPE_M1_81_STAND"; + model = "\WW2\SPE_Assets_m\Weapons\Mortars_m\SPE_M1_Mortar_Stand_Deployed.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_M1_81_Stand_X_ca.paa"; + class ACE_CSW { + disassembleTo = "SPE_M1_81_Stand"; + }; + }; + + + class ACE_SPE_M1_81_Stand_Deployed: EGVAR(csw,baseTripod) { + author = "SPE"; + scope = 2; + displayName = "$STR_DN_SPE_M1_81_STAND"; + model = "\WW2\SPE_Assets_m\Weapons\Mortars_m\SPE_M1_Mortar_Stand_Deployed.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_M1_81_Stand_X_ca.paa"; + class assembleInfo { + base = ""; + primary = 0; + displayName = ""; + assembleTo = ""; + class SPE_M1_81_Barrel { + deployTime = 0; + assembleTo = ""; + }; + }; + class ACE_CSW { + disassembleTo = "SPE_M1_81_Stand"; + }; + }; + class ACE_SPE_GrW278_1_Stand_Deployed: EGVAR(csw,baseTripod) { + author = "SPE"; + scope = 2; + displayName = "$STR_DN_SPE_GrW278_1_STAND"; + model = "\WW2\SPE_Assets_m\Weapons\Mortars_m\SPE_M1_Mortar_Stand_Deployed.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_GrW278_1_Stand_X_ca.paa"; + hiddenSelectionsTextures[] = {"ww2\spe_assets_t\weapons\mortars_t\m1_mortar\Brandt_81mm_Mortar_Gelb_co.paa","WW2\SPE_Assets_t\Weapons\Mortars_t\M1_Mortar\Brandt_81mm_Sight_Gelb_co.paa"}; + class assembleInfo { + base = ""; + primary = 0; + displayName = ""; + assembleTo = ""; + class SPE_GrW278_1_Barrel { + deployTime = 0; + assembleTo = ""; + }; + }; + class ACE_CSW { + disassembleTo = "SPE_GrW278_1_Stand"; + }; + }; + class ACE_SPE_MLE_27_31_Stand_Deployed: EGVAR(csw,baseTripod) { + author = "SPE"; + scope = 2; + displayName = "$STR_DN_SPE_MLE_27_31_STAND"; + model = "\WW2\SPE_Assets_m\Weapons\Mortars_m\SPE_M1_Mortar_Stand_Deployed.p3d"; + picture = "\WW2\SPE_Assets_t\Weapons\Equipment_t\Weapons\Launchers\Gear_MLE_27_31_Stand_X_ca.paa"; + hiddenSelections[] = {"camo_0","camo_1"}; + hiddenSelectionsTextures[] = {"ww2\spe_assets_t\weapons\mortars_t\m1_mortar\Brandt_81mm_Mortar_French_co.paa","WW2\SPE_Assets_t\Weapons\Mortars_t\M1_Mortar\Brandt_81mm_Sight_French_co.paa"}; + class assembleInfo { + base = ""; + primary = 0; + displayName = ""; + assembleTo = ""; + class SPE_MLE_27_31_Barrel { + deployTime = 0; + assembleTo = ""; + }; + }; + class ACE_CSW { + disassembleTo = "SPE_MLE_27_31_Stand"; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/CfgWeapons.hpp b/addons/compat_spe/compat_spe_csw/CfgWeapons.hpp new file mode 100644 index 0000000000..db090c7708 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/CfgWeapons.hpp @@ -0,0 +1,84 @@ +class CfgWeapons { + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + class SPE_Slung_Static_Weapon_Base: Launcher_Base_F {}; + + class SPE_M1_81; + class SPE_M1_81_proxy: SPE_M1_81 { + magazineReloadTime = 0.5; + }; + + class SPE_M1_81_Stand: SPE_Slung_Static_Weapon_Base { + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(M1_81_baseplate); + }; + }; + class SPE_M1_81_Barrel: SPE_Slung_Static_Weapon_Base { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + GVAR(M1_81_baseplate) = "SPE_M1_81"; + EGVAR(csw,mortarBaseplate) = "SPE_M1_81"; + }; + }; + }; + + class SPE_MLE_27_31; + class SPE_MLE_27_31_proxy: SPE_MLE_27_31 { + magazineReloadTime = 0.5; + }; + + class SPE_MLE_27_31_Stand: SPE_Slung_Static_Weapon_Base { + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(MLE_27_31_baseplate); + }; + }; + class SPE_MLE_27_31_Barrel: SPE_Slung_Static_Weapon_Base { + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + GVAR(MLE_27_31_baseplate) = "SPE_MLE_27_31"; + EGVAR(csw,mortarBaseplate) = "SPE_MLE_27_31"; + }; + }; + }; + + class SPE_GrW278_1; + class SPE_GrW278_1_proxy: SPE_GrW278_1 { + magazineReloadTime = 0.5; + }; + + class SPE_GrW278_1_Stand: SPE_MLE_27_31_Stand { + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(GrW278_baseplate); + }; + }; + + class SPE_GrW278_1_Barrel: SPE_MLE_27_31_Barrel { + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + GVAR(GrW278_baseplate) = "SPE_GrW278_1"; + EGVAR(csw,mortarBaseplate) = "SPE_GrW278_1"; + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_csw/config.cpp b/addons/compat_spe/compat_spe_csw/config.cpp new file mode 100644 index 0000000000..6ff669629b --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/config.cpp @@ -0,0 +1,29 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ww2_spe_assets_c_weapons_infantryweapons_c", + "ww2_spe_assets_c_vehicles_staticweapons_c", + "ww2_spe_assets_c_vehicles_weapons_c", + "ww2_spe_core_f_system_staticweapons_f", + "ww2_spe_core_c_core_c_eventhandlers", + "ace_csw" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "ACE_CSW_Groups.hpp" +// Todo: https://github.com/acemod/ACE3/pull/9292#discussion_r1327738181 +// #include "CfgVehicles.hpp" +// #include "CfgWeapons.hpp" diff --git a/addons/compat_spe/compat_spe_csw/script_component.hpp b/addons/compat_spe/compat_spe_csw/script_component.hpp new file mode 100644 index 0000000000..1f7ace46a9 --- /dev/null +++ b/addons/compat_spe/compat_spe_csw/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT csw +#define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons +#include "..\script_component.hpp" diff --git a/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp b/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..7c1945fcb8 --- /dev/null +++ b/addons/compat_spe/compat_spe_explosives/CfgMagazines.hpp @@ -0,0 +1,210 @@ +class CfgMagazines { + class SPE_Mine_Magazine; + class SPE_US_TNT_4pound_mag: SPE_Mine_Magazine { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(4LBTNT); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class SPE_US_TNT_half_pound_mag: SPE_Mine_Magazine { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(halfLBTNT); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class SPE_US_Bangalore_mag: SPE_Mine_Magazine { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bangalore); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class SPE_Ladung_Small_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(smallLadung); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class SPE_Ladung_Big_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,DelayTime) = 1; + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(bigLadung); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "FireCord", "LIB_LadungPM"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class SPE_US_M1A1_ATMINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(M1A1at); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.062; + }; + }; + }; + class SPE_US_M3_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(M3ap); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.04; + }; + }; + }; + class SPE_US_M3_Pressure_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(M3Pressure); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.18; + }; + }; + }; + + class SPE_Shg24x7_Improvised_Mine_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(Shg24x7); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.13; + }; + }; + }; + + class SPE_TMI_42_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(TMI42); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.09; + }; + }; + }; + + class SPE_SMI_35_1_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(SMI35_1); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.1; + }; + }; + }; + + class SPE_SMI_35_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(SMI35); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.04; + }; + }; + }; + + class SPE_SMI_35_Pressure_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(SMI35Pressure); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.19; + }; + }; + }; + + class SPE_STMI_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(STMI); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Tripwire"}; + class Tripwire { + digDistance = 0.04; + }; + }; + }; + + class SPE_shumine_42_MINE_mag: SPE_Mine_Magazine { + EGVAR(explosives,Placeable) = 1; + EGVAR(explosives,SetupObject) = QEXPLOSIVES_PLACE(shumine42); + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp b/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..d4d5737bb2 --- /dev/null +++ b/addons/compat_spe/compat_spe_explosives/CfgVehicles.hpp @@ -0,0 +1,173 @@ +class CfgVehicles { + class Items_base_F; + class EGVAR(explosives,Place): Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + // 4 Pound TNT Charge + class EXPLOSIVES_PLACE(4LBTNT): EGVAR(explosives,Place) { + displayName = "4 Pound TNT Charge"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_TNT_4pound"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // Half Pound TNT Charge + class EXPLOSIVES_PLACE(halfLBTNT): EGVAR(explosives,Place) { + displayName = "Half Pound TNT Charge"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_TNT_Half_Pound"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // M1A1 Bangalore Torpedo + class EXPLOSIVES_PLACE(bangalore): EGVAR(explosives,Place) { + displayName = "M1A1 Bangalore Torpedo"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Bangalore"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // 1 Kg Charge + class EXPLOSIVES_PLACE(smallLadung): EGVAR(explosives,Place) { + displayName = "1 Kg Charge"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Ladung"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // 3 Kg Charge + class EXPLOSIVES_PLACE(bigLadung): EGVAR(explosives,Place) { + displayName = "3 Kg Charge"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Ladung_Big"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // M1A1 AT Mine + class EXPLOSIVES_PLACE(M1A1at): EGVAR(explosives,Place) { + displayName = "M1A1 AT Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_M1A1_AT"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // M1A1 AT Mine + class EXPLOSIVES_PLACE(Shg24x7): EGVAR(explosives,Place) { + displayName = "M1A1 AT Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_GER_Improvised_Mine"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // M1A1 AT Mine + class EXPLOSIVES_PLACE(TMI42): EGVAR(explosives,Place) { + displayName = "M1A1 AT Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Tmi42"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // M3 AP Tripwire Mine + class EXPLOSIVES_PLACE(M3ap): EGVAR(explosives,Place) { + displayName = "M3 AP Tripwire Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_M3_AP"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // M3 AP Mine + class EXPLOSIVES_PLACE(M3Pressure): EGVAR(explosives,Place) { + displayName = "M3 AP Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_M3_AP_Pressure"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // SMi-35 AP Mine + class EXPLOSIVES_PLACE(SMI35Pressure): EGVAR(explosives,Place) { + displayName = "SMi-35 AP Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Smi35"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // SMi-35 Tripwire Mine + class EXPLOSIVES_PLACE(SMI35): EGVAR(explosives,Place) { + displayName = "SMi-35 Tripwire Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Smi35_1"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // SMi-35 Tripwire (x2) Mine + class EXPLOSIVES_PLACE(SMI35_1): EGVAR(explosives,Place) { + displayName = "SMi-35 Tripwire (x2) Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Smi35_2"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // StMi Mine + class EXPLOSIVES_PLACE(STMI): EGVAR(explosives,Place) { + displayName = "StMi Mine"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Stmi"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; + + // Schuetzenmine 42 + class EXPLOSIVES_PLACE(shumine42): EGVAR(explosives,Place) { + displayName = "Schuetzenmine 42"; + model = "\WW2\SPE_Assets_m\Weapons\Mines_m\SPE_Shumine42"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.002, 0.022, 0.02]"; + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_explosives/config.cpp b/addons/compat_spe/compat_spe_explosives/config.cpp new file mode 100644 index 0000000000..81e0bc7811 --- /dev/null +++ b/addons/compat_spe/compat_spe_explosives/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ww2_spe_assets_c_weapons_infantryweapons_c", + "ww2_spe_assets_c_vehicles_staticweapons_c", + "ww2_spe_assets_c_vehicles_weapons_c", + "ww2_spe_core_f_system_staticweapons_f", + "ww2_spe_core_c_core_c_eventhandlers", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" +#include "CfgMagazines.hpp" diff --git a/addons/compat_spe/compat_spe_explosives/script_component.hpp b/addons/compat_spe/compat_spe_explosives/script_component.hpp new file mode 100644 index 0000000000..926f441c1f --- /dev/null +++ b/addons/compat_spe/compat_spe_explosives/script_component.hpp @@ -0,0 +1,6 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" + +#define EXPLOSIVES_PLACE(CLASS) EGVAR(explosives,DOUBLES(Place,CLASS)) +#define QEXPLOSIVES_PLACE(CLASS) QUOTE(EXPLOSIVES_PLACE(CLASS)) diff --git a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..fc1ebc9b4e --- /dev/null +++ b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp @@ -0,0 +1,12 @@ +class CfgVehicles { + class SPE_Halftrack_base; + class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { + EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; + EGVAR(refuel,fuelCargo) = 2000; + }; + class SPE_OpelBlitz_base; + class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { + EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; + EGVAR(refuel,fuelCargo) = 2000; + }; +}; diff --git a/addons/compat_spe/compat_spe_refuel/config.cpp b/addons/compat_spe/compat_spe_refuel/config.cpp new file mode 100644 index 0000000000..077e06bdd0 --- /dev/null +++ b/addons/compat_spe/compat_spe_refuel/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ww2_spe_assets_c_weapons_infantryweapons_c", + "ww2_spe_assets_c_vehicles_staticweapons_c", + "ww2_spe_assets_c_vehicles_weapons_c", + "ww2_spe_core_f_system_staticweapons_f", + "ww2_spe_core_c_core_c_eventhandlers", + "ace_refuel" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_spe/compat_spe_refuel/script_component.hpp b/addons/compat_spe/compat_spe_refuel/script_component.hpp new file mode 100644 index 0000000000..b58db9432d --- /dev/null +++ b/addons/compat_spe/compat_spe_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED Refuel +#include "..\script_component.hpp" diff --git a/addons/compat_spe/config.cpp b/addons/compat_spe/config.cpp new file mode 100644 index 0000000000..5c1ba718d6 --- /dev/null +++ b/addons/compat_spe/config.cpp @@ -0,0 +1,37 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ace_common", + "ww2_spe_assets_c_weapons_infantryweapons_c", + "ww2_spe_assets_c_vehicles_staticweapons_c", + "ww2_spe_assets_c_vehicles_weapons_c", + "ww2_spe_core_f_system_staticweapons_f", + "ww2_spe_core_c_core_c_eventhandlers" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = { + "sancron", + "nomisum", + "coldfront15/Henderson", + "BrettMayson" + }; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "ACE_Medical_Injuries.hpp" +#include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgGlasses.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf b/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf new file mode 100644 index 0000000000..d2b0cb165c --- /dev/null +++ b/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Custom wound handler for SOG: PF explosive incendiary ammunition. + * Determines if the unit should be ignited and passes the damage to other wound handlers. + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * Input + * + * Example: + * [player, [[0.5, "Body", 5]]] call ace_compat_spe_fnc_woundsHandlerIncendiary + * + * Public: No + */ + +params ["_unit", "_damages"]; +TRACE_2("woundsHandlerIncendiary",_unit,_damages); + +private _fireDamage = 0; +{ + _x params ["", "", "_damage"]; + _fireDamage = _fireDamage + _damage; +} forEach _damages; + +private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true]; +TRACE_2("",_intensity,_fireDamage); + +// Let fire handle if unit is set ablaze or not +[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent; + +_this // return diff --git a/addons/compat_spe/script_component.hpp b/addons/compat_spe/script_component.hpp new file mode 100644 index 0000000000..2a5a172596 --- /dev/null +++ b/addons/compat_spe/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_spe +#define COMPONENT_BEAUTIFIED Spearhead 1944 Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_ws/$PBOPREFIX$ b/addons/compat_ws/$PBOPREFIX$ new file mode 100644 index 0000000000..a025a8275e --- /dev/null +++ b/addons/compat_ws/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_ws diff --git a/addons/compat_ws/CfgWeapons.hpp b/addons/compat_ws/CfgWeapons.hpp new file mode 100644 index 0000000000..a8b27fb1f3 --- /dev/null +++ b/addons/compat_ws/CfgWeapons.hpp @@ -0,0 +1,86 @@ +class CfgWeapons { + // AA40 + class Rifle_Base_F; + class sgun_aa40_base_lxWS: Rifle_Base_F { + ACE_barrelLength = 457; + ACE_barrelTwist = 0.0; + ACE_twistDirection = 0; + }; + + // Galat Arm + class arifle_Galat_base_lxWS: Rifle_Base_F { + ACE_barrelLength = 535; + ACE_barrelTwist = 304.8; + ACE_twistDirection = 1; + }; + + // SA-77 + class Rifle_Long_Base_F; + class LMG_S77_base_lxWS: Rifle_Long_Base_F { + ACE_barrelLength = 550; + ACE_barrelTwist = 304.8; + ACE_twistDirection = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + }; + class LMG_S77_Compact_base_lxWS: LMG_S77_base_lxWS { + ACE_barrelLength = 500; + ACE_barrelTwist = 304.8; + ACE_twistDirection = 1; + EGVAR(overheating,allowSwapBarrel) = 1; + }; + + // SLR + class DMR_06_base_F; + class arifle_SLR_lxWS: DMR_06_base_F { + ACE_barrelLength = 533; + ACE_barrelTwist = 279.4; + ACE_twistDirection = 1; + }; + + class arifle_SLR_V_lxWS; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + ACE_barrelLength = 266.7; + }; + + // Velko R4/R5 + class arifle_Velko_base_lxWS: arifle_Galat_base_lxWS { + ACE_barrelLength = 460; + ACE_barrelTwist = 304.8; + ACE_twistDirection = 1; + }; + class arifle_VelkoR5_lxWS: arifle_Velko_base_lxWS { + ACE_barrelLength = 332; + ACE_barrelTwist = 304.8; + ACE_twistDirection = 1; + }; + + // XMS - Weird off-shoot from the XM8 rifles so there is no data for barrel lengths or twists. Used the vanilla CTAR as a baseline for the values. + class arifle_SPAR_01_base_F; + class arifle_XMS_Base_lxWS: arifle_SPAR_01_base_F { + ACE_barrelLength = 406.4; + ACE_barrelTwist = 178.0; + ACE_twistDirection = 1; + }; + + // Headgear + // ION Cap (Headphones) + class lxWS_H_CapB_rvs_blk; + class lxWS_H_CapB_rvs_blk_ION: lxWS_H_CapB_rvs_blk { + ace_hearing_protection = 0.75; + ace_hearing_lowerVolume = 0.2; + }; + + // Tank helmet + class HelmetBase; + class lxWS_H_Tank_tan_F: HelmetBase { + ace_hearing_protection = 0.85; + ace_hearing_lowerVolume = 0.6; + }; + + // Headphones, inherited hearing protection + class H_Cap_headphones; + class lxWS_H_Headset: H_Cap_headphones { + ace_hearing_protection = 0; + ace_hearing_lowerVolume = 0; + }; +}; diff --git a/addons/compat_ws/compat_ws_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_ws/compat_ws_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 0000000000..8158db66cd --- /dev/null +++ b/addons/compat_ws/compat_ws_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,167 @@ +// Generated using ace_nouniformrestrictions_fnc_exportConfig +class CfgVehicles { + class I_SFIA_soldier_lxWS; + class I_SFIA_Soldier_universal_lxWS; + class I_SFIA_Soldier_TL_lxWS; + class I_SFIA_Soldier_GL_lxWS; + class I_SFIA_Soldier_AR_lxWS; + class I_SFIA_officer_lxWS; + class I_SFIA_sharpshooter_lxWS; + class I_SFIA_crew_lxWS; + class I_SFIA_pilot_lxWS; + class I_SFIA_soldier_at_lxWS; + class I_SFIA_soldier_aa_lxWS; + class I_SFIA_medic_lxWS; + class I_SFIA_exp_lxWS; + class I_SFIA_repair_lxWS; + class I_SFIA_soldier_unarmed_lxWS; + class I_SFIA_survivor_lxWS; + class I_SFIA_Soldier_AAT_lxWS; + class I_SFIA_Soldier_AAA_lxWS; + class I_C_Soldier_Bandit_5_F; + class I_C_Soldier_Bandit_4_F; + class I_C_Soldier_Para_2_F; + class I_C_Soldier_Bandit_2_F; + class I_C_Soldier_Bandit_1_F; + class I_Tura_HeavyGunner_lxWS; + class B_D_Soldier_universal_lxWS; + + class O_SFIA_soldier_lxWS: I_SFIA_soldier_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_Soldier_universal_lxWS: I_SFIA_Soldier_universal_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_Soldier_TL_lxWS: I_SFIA_Soldier_TL_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_Soldier_GL_lxWS: I_SFIA_Soldier_GL_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_Soldier_AR_lxWS: I_SFIA_Soldier_AR_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_officer_lxWS: I_SFIA_officer_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_sharpshooter_lxWS: I_SFIA_sharpshooter_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_crew_lxWS: I_SFIA_crew_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_pilot_lxWS: I_SFIA_pilot_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_soldier_at_lxWS: I_SFIA_soldier_at_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_soldier_aa_lxWS: I_SFIA_soldier_aa_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_medic_lxWS: I_SFIA_medic_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_exp_lxWS: I_SFIA_exp_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_repair_lxWS: I_SFIA_repair_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_soldier_unarmed_lxWS: I_SFIA_soldier_unarmed_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_survivor_lxWS: I_SFIA_survivor_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_Soldier_AAT_lxWS: I_SFIA_Soldier_AAT_lxWS { + modelSides[] = {6}; + }; + class O_SFIA_Soldier_AAA_lxWS: I_SFIA_Soldier_AAA_lxWS { + modelSides[] = {6}; + }; + class I_SFIA_scout_lxWS: I_C_Soldier_Bandit_5_F { + modelSides[] = {6}; + }; + class I_SFIA_watcher_lxWS: I_C_Soldier_Bandit_4_F { + modelSides[] = {6}; + }; + class I_SFIA_enforcer_lxWS: I_C_Soldier_Para_2_F { + modelSides[] = {6}; + }; + class I_SFIA_hireling_lxWS: I_C_Soldier_Bandit_2_F { + modelSides[] = {6}; + }; + class I_SFIA_medic2_lxWS: I_C_Soldier_Bandit_1_F { + modelSides[] = {6}; + }; + class I_SFIA_thug_lxWS: I_SFIA_scout_lxWS { + modelSides[] = {6}; + }; + class I_SFIA_deserter_lxWS: I_SFIA_soldier_lxWS { + modelSides[] = {6}; + }; + class I_Tura_deserter_lxWS: I_SFIA_deserter_lxWS { + modelSides[] = {6}; + }; + class I_SFIA_defector_lxWS: I_SFIA_soldier_lxWS { + modelSides[] = {6}; + }; + class O_Tura_scout_lxWS: I_SFIA_scout_lxWS { + modelSides[] = {6}; + }; + class O_Tura_watcher_lxWS: I_SFIA_watcher_lxWS { + modelSides[] = {6}; + }; + class O_Tura_enforcer_lxWS: I_SFIA_enforcer_lxWS { + modelSides[] = {6}; + }; + class O_Tura_hireling_lxWS: I_SFIA_hireling_lxWS { + modelSides[] = {6}; + }; + class O_Tura_medic2_lxWS: I_SFIA_medic2_lxWS { + modelSides[] = {6}; + }; + class O_Tura_thug_lxWS: I_SFIA_thug_lxWS { + modelSides[] = {6}; + }; + class O_Tura_deserter_lxWS: I_SFIA_deserter_lxWS { + modelSides[] = {6}; + }; + class O_Tura_defector_lxWS: I_SFIA_defector_lxWS { + modelSides[] = {6}; + }; + class B_Tura_scout_lxWS: I_SFIA_scout_lxWS { + modelSides[] = {6}; + }; + class B_Tura_watcher_lxWS: I_SFIA_watcher_lxWS { + modelSides[] = {6}; + }; + class B_Tura_enforcer_lxWS: I_SFIA_enforcer_lxWS { + modelSides[] = {6}; + }; + class B_Tura_hireling_lxWS: I_SFIA_hireling_lxWS { + modelSides[] = {6}; + }; + class B_Tura_medic2_lxWS: I_SFIA_medic2_lxWS { + modelSides[] = {6}; + }; + class B_Tura_thug_lxWS: I_SFIA_thug_lxWS { + modelSides[] = {6}; + }; + class B_Tura_deserter_lxWS: I_SFIA_deserter_lxWS { + modelSides[] = {6}; + }; + class B_Tura_defector_lxWS: I_SFIA_defector_lxWS { + modelSides[] = {6}; + }; + class B_Tura_HeavyGunner_lxWS: I_Tura_HeavyGunner_lxWS { + modelSides[] = {6}; + }; + class O_Tura_HeavyGunner_lxWS: I_Tura_HeavyGunner_lxWS { + modelSides[] = {6}; + }; + class B_ALC_Soldier_universal_lxWS: B_D_Soldier_universal_lxWS { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_ws/compat_ws_nouniformrestrictions/config.cpp b/addons/compat_ws/compat_ws_nouniformrestrictions/config.cpp new file mode 100644 index 0000000000..899c7f74af --- /dev/null +++ b/addons/compat_ws/compat_ws_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "data_f_lxWS_Loadorder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_nouniformrestrictions/script_component.hpp b/addons/compat_ws/compat_ws_nouniformrestrictions/script_component.hpp new file mode 100644 index 0000000000..0b98185fa0 --- /dev/null +++ b/addons/compat_ws/compat_ws_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp new file mode 100644 index 0000000000..95801e04e9 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp @@ -0,0 +1,75 @@ +class optic_Arco; +class optic_arco_hex_lxWS: optic_Arco { + displayName = SUBCSTRING(arco_hex_Name); +}; + +class optic_Holosight; +class optic_Holosight_snake_lxWS: optic_Holosight { + displayName = SUBCSTRING(holosight_snake_Name); +}; + +class optic_Holosight_smg; +class optic_Holosight_smg_snake_lxWS: optic_Holosight_smg { + displayName = SUBCSTRING(holosight_snake_smg_Name); +}; + +class optic_Hamr; +class optic_Hamr_arid_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_arid_Name); +}; +class optic_Hamr_lush_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_lush_Name); +}; +class optic_Hamr_sand_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_sand_Name); +}; +class optic_Hamr_snake_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_snake_Name); +}; + +class ItemCore; +class optic_r1_high_lxWS: ItemCore { + displayName = SUBCSTRING(r1_high_black_Name); +}; +class optic_r1_high_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_khaki_Name); +}; +class optic_r1_high_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_sand_Name); +}; +class optic_r1_high_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_snake_Name); +}; +class optic_r1_high_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_arid_Name); +}; +class optic_r1_high_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_lush_Name); +}; +class optic_r1_high_black_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_black_sand_Name); +}; + +class optic_r1_low_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_black_Name); +}; +class optic_r1_low_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_khaki_Name); +}; +class optic_r1_low_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_sand_Name); +}; +class optic_r1_low_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_snake_Name); +}; +class optic_r1_low_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_arid_Name); +}; +class optic_r1_low_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_lush_Name); +}; + +class optic_DMS; +class optic_DMS_snake_lxWS: optic_DMS { + displayName = SUBCSTRING(dms_snake_Name); +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp new file mode 100644 index 0000000000..fe1aed7e17 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp @@ -0,0 +1,60 @@ +class CfgVehicles { + class APC_Wheeled_01_base_F; + class APC_Wheeled_01_atgm_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_atgm_Name); + }; + class APC_Wheeled_01_command_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_command_Name); + }; + class APC_Wheeled_01_mortar_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_mortar_Name); + }; + + class Truck_02_base_F; + class Truck_02_aa_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_aa_Name); + }; + class Truck_02_cargo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_cargo_Name); + }; + class Truck_02_box_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_repair_Name); + }; + class C_Truck_02_racing_lxWS: Truck_02_box_base_lxWS { + displayName = SUBCSTRING(truck_02_racing_Name); + }; + class Truck_02_Ammo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_ammo_Name); + }; + class Truck_02_flatbed_base_lxWS: Truck_02_cargo_base_lxWS { + displayName = SUBCSTRING(truck_02_flatbed_Name); + }; + + class Heli_Transport_02_base_F; + class B_UN_Heli_Transport_02_lxWS: Heli_Transport_02_base_F { + displayName = SUBCSTRING(heli_transport_02_Name); + }; + + class O_APC_Tracked_02_cannon_F; + class O_APC_Tracked_02_30mm_lxWS: O_APC_Tracked_02_cannon_F { + displayName = SUBCSTRING(apc_tracked_02_Name); + }; + + class APC_Wheeled_02_base_v2_F; + class APC_Wheeled_02_hmg_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_hmg_Name); + }; + class APC_Wheeled_02_unarmed_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_unarmed_Name); + }; + + class O_Heli_Light_02_dynamicLoadout_F; + class B_ION_Heli_Light_02_dynamicLoadout_lxWS: O_Heli_Light_02_dynamicLoadout_F { + displayName = SUBCSTRING(heli_light_02_armed_Name); + }; + + class O_Heli_Light_02_unarmed_F; + class B_ION_Heli_Light_02_unarmed_lxWS: O_Heli_Light_02_unarmed_F { + displayName = SUBCSTRING(heli_light_02_unarmed_Name); + }; +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp new file mode 100644 index 0000000000..e9cf3c6934 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp @@ -0,0 +1,179 @@ +class CfgWeapons { + #include "Attachments.hpp" + + // AA12 + class sgun_aa40_base_lxWS; + class sgun_aa40_lxWS: sgun_aa40_base_lxWS { + displayName = SUBCSTRING(AA40_Name); + }; + class sgun_aa40_tan_lxWS: sgun_aa40_base_lxWS { + displayName = SUBCSTRING(AA40_Tan_Name); + }; + class sgun_aa40_snake_lxWS: sgun_aa40_base_lxWS { + displayName = SUBCSTRING(AA40_Snake_Name); + }; + + // Galil ARM + class arifle_Galat_base_lxWS; + class arifle_Galat_lxWS: arifle_Galat_base_lxWS { + displayName = SUBCSTRING(Galat_Name); + }; + class arifle_Galat_worn_lxWS: arifle_Galat_lxWS { + displayName = SUBCSTRING(Galat_Old_Name); + }; + + // GLX 160 + class glaunch_GLX_base_lxWS; + class glaunch_GLX_lxWS: glaunch_GLX_base_lxWS { + displayName = SUBCSTRING(GLX_Name); + }; + class glaunch_GLX_snake_lxWS: glaunch_GLX_base_lxWS { + displayName = SUBCSTRING(GLX_Snake_Name); + }; + class glaunch_GLX_hex_lxWS: glaunch_GLX_base_lxWS { + displayName = SUBCSTRING(GLX_Hex_Name); + }; + class glaunch_GLX_ghex_lxWS: glaunch_GLX_base_lxWS { + displayName = SUBCSTRING(GLX_GreenHex_Name); + }; + class glaunch_GLX_camo_lxWS: glaunch_GLX_base_lxWS { + displayName = SUBCSTRING(GLX_Camo_Name); + }; + class glaunch_GLX_tan_lxWS: glaunch_GLX_base_lxWS { + displayName = SUBCSTRING(GLX_Tan_Name); + }; + + // Mk14 Mod 1 EBR + class srifle_EBR_F; + class srifle_EBR_blk_lxWS: srifle_EBR_F { + displayName = SUBCSTRING(EBR_Black_Name); + }; + class srifle_EBR_snake_lxWS: srifle_EBR_F { + displayName = SUBCSTRING(EBR_Snake_Name); + }; + + // Vektor SS-77 + class LMG_S77_base_lxWS; + class LMG_S77_lxWS: LMG_S77_base_lxWS { + displayName = SUBCSTRING(S77_Name); + }; + class LMG_S77_AAF_lxWS: LMG_S77_base_lxWS { + displayName = SUBCSTRING(S77_AAF_Name); + }; + class LMG_S77_Hex_lxWS: LMG_S77_base_lxWS { + displayName = SUBCSTRING(S77_Hex_Name); + }; + class LMG_S77_GHex_lxWS: LMG_S77_base_lxWS { + displayName = SUBCSTRING(S77_GreenHex_Name); + }; + class LMG_S77_Desert_lxWS: LMG_S77_base_lxWS { + displayName = SUBCSTRING(S77_Desert_Name); + }; + + // Vektor SS-77 (Compact) + class LMG_S77_Compact_base_lxWS; + class LMG_S77_Compact_lxWS: LMG_S77_Compact_base_lxWS { + displayName = SUBCSTRING(S77_Compact_Name); + }; + class LMG_S77_Compact_Snakeskin_lxWS: LMG_S77_Compact_base_lxWS { + displayName = SUBCSTRING(S77_Compact_Snake_Name); + }; + + // FN FAL (Wood) - Closest match is the 50.00 + class DMR_06_base_F; + class arifle_SLR_lxWS: DMR_06_base_F { + displayName = SUBCSTRING(SLR_Wood_Name); + }; + class arifle_SLR_GL_lxWS: arifle_SLR_lxWS { + displayName = SUBCSTRING(SLR_GL_Wood_Name); + }; + + // FN FAL + class arifle_SLR_V_lxWS: arifle_SLR_lxWS { + displayName = SUBCSTRING(SLR_Name); + }; + class arifle_SLR_V_GL_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_GL_Name); + }; + class arifle_SLR_D_lxWS: arifle_SLR_lxWS { + displayName = SUBCSTRING(SLR_Desert_Name); + }; + class arifle_SLR_V_camo_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_Camo_Name); + }; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class arifle_SLR_Para_snake_lxWS: arifle_SLR_Para_lxWS { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; + + // Vektor R4/R5 + class arifle_Velko_base_lxWS; + class arifle_Velko_lxWS: arifle_Velko_base_lxWS { + displayName = SUBCSTRING(Velko_R4_Name); + }; + class arifle_VelkoR5_lxWS: arifle_Velko_base_lxWS { + displayName = SUBCSTRING(Velko_R5_Name); + }; + class arifle_VelkoR5_GL_lxWS: arifle_VelkoR5_lxWS { + displayName = SUBCSTRING(Velko_R5_GL_Name); + }; + class arifle_VelkoR5_snake_lxWS: arifle_VelkoR5_lxWS { + displayName = SUBCSTRING(Velko_R5_Snake_Name); + }; + class arifle_VelkoR5_GL_snake_lxWS: arifle_VelkoR5_GL_lxWS { + displayName = SUBCSTRING(Velko_R5_GL_Snake_Name); + }; + + // XMS has no realistic name as it's a make believe hybrid of the XM8/VHS-K2: XM8+VHS = XMS, this just removes the 5.56 mm from the name. + class arifle_SPAR_01_base_F; + class arifle_XMS_Base_lxWS: arifle_SPAR_01_base_F { + displayName = SUBCSTRING(XMS_Name); + }; + class arifle_XMS_Base_khk_lxWS: arifle_XMS_Base_lxWS { + displayName = SUBCSTRING(XMS_Khaki_Name); + }; + class arifle_XMS_Base_Sand_lxWS: arifle_XMS_Base_lxWS { + displayName = SUBCSTRING(XMS_Sand_Name); + }; + class arifle_XMS_GL_lxWS: arifle_XMS_Base_lxWS { + displayName = SUBCSTRING(XMS_GL_Name); + }; + class arifle_XMS_GL_khk_lxWS: arifle_XMS_GL_lxWS { + displayName = SUBCSTRING(XMS_GL_Khaki_Name); + }; + class arifle_XMS_GL_Sand_lxWS: arifle_XMS_GL_lxWS { + displayName = SUBCSTRING(XMS_GL_Sand_Name); + }; + class arifle_XMS_Shot_lxWS: arifle_XMS_Base_lxWS { + displayName = SUBCSTRING(XMS_SG_Name); + }; + class arifle_XMS_Shot_khk_lxWS: arifle_XMS_Shot_lxWS { + displayName = SUBCSTRING(XMS_SG_Khaki_Name); + }; + class arifle_XMS_Shot_Sand_lxWS: arifle_XMS_Shot_lxWS { + displayName = SUBCSTRING(XMS_SG_Sand_Name); + }; + class arifle_XMS_M_lxWS: arifle_XMS_Base_lxWS { + displayName = SUBCSTRING(XMS_SW_Name); + }; + class arifle_XMS_M_khk_lxWS: arifle_XMS_M_lxWS { + displayName = SUBCSTRING(XMS_SW_Khaki_Name); + }; + class arifle_XMS_M_Sand_lxWS: arifle_XMS_M_lxWS { + displayName = SUBCSTRING(XMS_SW_Sand_Name); + }; + + // GM6 Lynx + class srifle_GM6_F; + class srifle_GM6_snake_lxWS: srifle_GM6_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class launch_RPG32_F; + class launch_RPG32_tan_lxWS: launch_RPG32_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/config.cpp b/addons/compat_ws/compat_ws_realisticnames/config.cpp new file mode 100644 index 0000000000..0eb75926a8 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "data_f_lxWS_Loadorder", + "ace_realisticnames" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/script_component.hpp b/addons/compat_ws/compat_ws_realisticnames/script_component.hpp new file mode 100644 index 0000000000..b8d0682fa4 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT realisticnames +#define SUBCOMPONENT_BEAUTIFIED Realistic Names +#include "..\script_component.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml new file mode 100644 index 0000000000..606bbb7932 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -0,0 +1,732 @@ + + + + + AA12 + AA-12 + AA12 + AA12 + AA12 + AA12 + AA12 + AA12 + + + AA12 (Sand) + AA-12 (모래) + AA12 (Sand) + AA12 (Sabbia) + AA12 (サンド) + AA12 (Песочный) + AA12 (Sable) + AA12 (Arena) + + + AA12 (Snake) + AA-12 (뱀 위장) + AA12 (Schlange) + AA12 (Serpe) + AA12 (ヘビ柄迷彩) + AA12 (Змея) + AA12 (Serpiente) + + + Galil ARM + 갈릴 ARM + Galil ARM + Galil ARM + ガリル ARM + Galil ARM + Galil ARM + Galil ARM + + + Galil ARM (Old) + 갈릴 ARM (낡음) + Galil ARM (Alt) + Galil ARM (Vecchio) + ガリル ARM (古びた) + Galil ARM (Старый) + Galil ARM (Ancien) + Galil ARM (Vieja) + + + GLX 160 + GLX-160 + GLX 160 + GLX-160 + GLX 160 + GLX 160 + GLX 160 + GLX 160 + + + GLX 160 (Snake) + GLX-160 (뱀 위장) + GLX 160 (Schlange) + GLX-160 (Serpe) + GLX 160 (ヘビ柄迷彩) + GLX 160 (Змея) + GLX 160 (Serpiente) + + + GLX 160 (Hex) + GLX-160 (육각) + GLX 160 (Hex) + GLX-160 (Hex) + GLX 160 (六角形迷彩) + GLX 160 (Гекс) + GLX 160 (Hex) + GLX 160 (Hex) + + + GLX 160 (Green Hex) + GLX-160 (초록육각) + GLX 160 (Grün Hex) + GLX-160 (Hex Verde) + GLX 160 (緑六角形迷彩) + GLX 160 (Зеленый Гекс) + GLX 160 (Vert Hex) + GLX 160 (Hex Verde) + + + GLX 160 (Camo) + GLX-160 (위장) + GLX 160 (Tarn) + GLX-160 (Mimetica) + GLX 160 (AAF迷彩) + GLX 160 (Камуфляж) + GLX 160 (Camo) + GLX 160 (Camo) + + + GLX 160 (Sand) + GLX-160 (모래) + GLX 160 (Sand) + GLX-160 (Sabbia) + GLX 160 (サンド) + GLX 160 (Песочный) + GLX 160 (Sable) + GLX 160 (Arena) + + + Mk14 Mod 1 EBR (Black) + Mk.14 Mod 1 EBR (검정) + Mk14 Mod 1 EBR (Schwarz) + Mk14 Mod 1 EBR (Nero) + Mk14 Mod 1 EBR (ブラック) + Mk14 Mod 1 EBR (Черный) + Mk14 Mod 1 EBR (Noir) + Mk14 Mod 1 EBR (Negra) + + + Mk14 Mod 1 EBR (Snake) + Mk.14 Mod 1 EBR (뱀 위장) + Mk14 Mod 1 EBR (Schlange) + Mk14 Mod 1 EBR (Serpe) + Mk14 Mod 1 EBR (ヘビ柄迷彩) + Mk14 Mod 1 EBR (Змея) + Mk14 Mod 1 EBR (Serpiente) + + + Vektor SS-77 + 벡터 SS-77 + Vektor SS-77 + ヴェクター SS-77 + Vektor SS-77 + Vektor SS-77 + Vektor SS-77 + + + Vektor SS-77 (Camo) + 벡터 SS-77 (위장) + Vektor SS-77 (Tarn) + Vektor SS-77 (Mimetica) + ヴェクター SS-77 (AAF迷彩) + Vektor SS-77 (Камуфляж) + Vektor SS-77 (Camo) + Vektor SS-77 (Camo) + + + Vektor SS-77 (Hex) + 벡터 SS-77 (육각) + Vektor SS-77 (Hex) + Vektor SS-77 (Hex) + ヴェクター SS-77 (六角形迷彩) + Vektor SS-77 (гекс) + Vektor SS-77 (Hex) + Vektor SS-77 (Hex) + + + Vektor SS-77 (Green Hex) + 벡터 SS-77 (초록육각) + Vektor SS-77 (Grün Hex) + Vektor SS-77 (Hex Verde) + ヴェクター SS-77 (緑六角形迷彩) + Vektor SS-77 (зеленый гекс) + Vektor SS-77 (VertHex) + Vektor SS-77 (Hex Verde) + + + Vektor SS-77 (Desert) + 벡터 SS-77 (사막) + Vektor SS-77 (Wüste) + Vektor SS-77 (Deserto) + ヴェクター SS-77 (砂漠迷彩) + Vektor SS-77 (песочныйt) + Vektor SS-77 (Désert) + Vektor SS-77 (Desierto) + + + Vektor SS-77 Compact + 벡터 SS-77 단축형 + Vektor SS-77 Kompakt + Vektor SS-77 Compatto + ヴェクター SS-77 コンパクト + Vektor SS-77 Compact + Vektor SS-77 Compacte + Vektor SS-77 Compacta + + + Vektor SS-77 Compact (Snake) + 벡터 SS-77 단축형 (뱀 위장) + Vektor SS-77 Compact (Schlange) + Vektor SS-77 Compatto (Serpe) + ヴェクター SS-77 コンパクト (ヘビ柄迷彩) + Vektor SS-77 Compact (змея) + Vektor SS-77 Compacta (Serpiente) + + + FN FAL 50.00 (Wood) + FN FAL 50.00 (목재) + FN FAL 50.00 (Holz) + FN FAL 50.00 (Legno) + FN FAL 50.00 (木製) + FN FAL 50.00 (лесной) + FN FAL 50.00 (Bois) + FN FAL 50.00 (Madera) + + + FN FAL 50.00 GL (Wood) + FN FAL 50.00 GL (목재) + FN FAL 50.00 GL (Holz) + FN FAL 50.00 GL (Legno) + FN FAL 50.00 GL (木製) + FN FAL 50.00 GL (лесной) + FN FAL 50.00 GL (Bois) + FN FAL 50.00 GL (Madera) + + + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + + + FN FAL 50.00 GL + FN FAL 50.00 GL + FN FAL 50.00 GL + FN FAL 50.00 GL + FN FAL 50.00 GL + FN FAL 50.00 GL + FN FAL 50.00 GL + FN FAL 50.00 GL + + + FN FAL 50.00 (Desert) + FN FAL 50.00 (사막) + FN FAL 50.00 (Wüstet) + FN FAL 50.00 (Deserto) + FN FAL 50.00 (砂漠迷彩) + FN FAL 50.00 (песочный) + FN FAL 50.00 (Désert) + FN FAL 50.00 (Desierto) + + + FN FAL 50.00 (Jungle) + FN FAL 50.00 (정글) + FN FAL 50,00 (Dschungel) + FN FAL 50,00 (Giungla) + FN FAL 50.00 (熱帯迷彩) + FN FAL 50.00 (джунгли) + FN FAL 50.00 (Jungle) + FN FAL 50.00 (Jungla) + + + FN FAL OSW Para + FN FAL OSW パラ + FN FAL OSW 파라 + FN FAL OSW Fallschirmjäger + FN FAL OSW Para + + + FN FAL OSW Para (Snake) + FN FAL OSW パラ (ヘビ柄迷彩) + FN FAL OSW 파라 (뱀 위장) + FN FAL OSW Fallschirmjäger (Schlange) + FN FAL OSW Para (Serpe) + + + Vektor R4 + 벡터 R4 + Vektor R4 + Vektor R4 + ヴェクター R4 + Vektor R4 + Vektor R4 + Vektor R4 + + + Vektor R5 Carbine + 벡터 R5 카빈 + Vektor R5 Carbine + Vektor R5 Carabina + ヴェクター R5 カービン + Vektor R5 Carbine + Vektor R5 Carbine + Vektor R5 Carabina + + + Vektor R5 Carbine GL + 벡터 R5 카빈 GL + Vektor R5 Carbine GL + Vektor R5 Carabina GL + ヴェクター R5 カービン GL + Vektor R5 Carbine GL + Vektor R5 Carbine GL + Vektor R5 Carabina GL + + + Vektor R5 Carbine (Snake) + 벡터 R5 카빈 (뱀 위장) + Vektor R5 Carbine (Schlange) + Vektor R5 Carabina (Serpe) + ヴェクター R5 カービン (ヘビ柄迷彩) + Vektor R5 Carbine (Змея) + Vektor R5 Carabina (Serpiente) + + + Vektor R5 Carbine GL (Snake) + 벡터 R5 카빈 GL (뱀 위장) + Vektor R5 Carbine GL (Schlange) + Vektor R5 Carabina GL (Serpe) + ヴェクター R5 カービン GL (ヘビ柄迷彩) + Vektor R5 Carbine GL (Змея) + Vektor R5 Carabina GL (Serpiente) + + + XMS + XMS + XMS + XMS + XMS + XMS + XMS + XMS + XMS + XMS + + + XMS (Khaki) + XMS (kaki) + XMS (khaki) + XMS (Cachi) + XMS (Cáqui) + XMS (caqui) + XMS(卡其色) + XMS (хаки) + XMS (카키) + XMS (カーキ) + + + XMS (Sand) + XMS (sable) + XMS (Sand) + XMS (Sabbia) + XMS (Areia) + XMS (arena) + XMS(沙色) + XMS (песочный) + XMS (모래) + XMS (サンド) + + + XMS GL + XMS GL + XMS GL + XMS GL + XMS GL + XMS GL + XMS GL + XMS GL + XMS GL + XMS GL + + + XMS GL (Khaki) + XMS GL (kaki) + XMS GL (khaki) + XMS GL (Cachi) + XMS GL (Cáqui) + XMS GL (caqui) + XMS GL(卡其色) + XMS GL (хаки) + XMS GL (카키) + XMS GL (カーキ) + + + XMS GL (Sand) + XMS GL (sable) + XMS GL (Sand) + XMS GL (Sabbia) + XMS GL (Areia) + XMS GL (arena) + XMS GL(沙色) + XMS GL (песочный) + XMS GL (모래) + XMS GL (サンド) + + + XMS SG + XMS SG + XMS SG + XMS SG + XMS SG + XMS SG + XMS SG + XMS SG + XMS SG + XMS SG + + + XMS SG (Khaki) + XMS SG (kaki) + XMS SG (khaki) + XMS SG (Cachi) + XMS SG (Cáqui) + XMS SG (caqui) + XMS SG(卡其色) + XMS SG (хаки) + XMS SG (카키) + XMS SG (カーキ) + + + XMS SG (Sand) + XMS SG (sable) + XMS SG (Sand) + XMS SG (Sabbia) + XMS SG (Areia) + XMS SG (arena) + XMS SG(沙色) + XMS SG (песочный) + XMS SG (모래) + XMS SG (サンド) + + + XMS SW + XMS SW + XMS SW + XMS SW + XMS SW + XMS SW + XMS SW + XMS SW + XMS SW + XMS SW + + + XMS SW (Khaki) + XMS SW (kaki) + XMS SW (khaki) + XMS SW (Cachi) + XMS SW (Cáqui) + XMS SW (caqui) + XMS SW(卡其色) + XMS SW (хаки) + XMS SW (카키) + XMS SW (カーキ) + + + XMS SW (Sand) + XMS SW (sable) + XMS SW (Sand) + XMS SW (Sabbia) + XMS SW (Areia) + XMS SW (arena) + XMS SW(沙色) + XMS SW (песочный) + XMS SW (모래) + XMS SW (サンド) + + + GM6 Lynx (Snake) + GM6 リンクス (ヘビ柄迷彩) + GM6 링스 (뱀 위장) + GM6 Lynx (Schlange) + GM6 Lynx (Serpe) + + + RPG-32 (Sand) + RPG-32 (サンド) + RPG-32 (모래) + RPG-32 (Sand) + RPG-32 (Sabbia) + + + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (六角形迷彩) + 엘칸 스펙터OS (육각) + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (Hex) + + + EOTech XPS3 (Snake) + EOTech XPS3 (ヘビ柄迷彩) + 이오텍 XPS3 (뱀 위장) + EOTech XPS3 (Schlange) + EOTech XPS3 (Serpe) + + + EOTech XPS3 SMG (Snake) + EOTech XPS3 SMG (ヘビ柄迷彩) + 이오텍 XPS3 SMG (뱀 위장) + EOTech XPS3 SMG (Schlange) + EOTech XPS3 SMG (Serpe) + + + Leupold Mark 4 HAMR (Arid) + Leupold Mark 4 HAMR (乾燥地帯迷彩) + 류폴드 마크 4 HAMR (건조) + Leupold Mark 4 HAMR (Trocken) + Leupold Mark 4 HAMR (Arido) + + + Leupold Mark 4 HAMR (Lush) + Leupold Mark 4 HAMR (緑地迷彩) + 류폴드 마크 4 HAMR (초목) + Leupold Mark 4 HAMR (Grün) + Leupold Mark 4 HAMR (Verdeggiante) + + + Leupold Mark 4 HAMR (Sand) + Leupold Mark 4 HAMR (サンド) + 류폴드 마크 4 HAMR (모래) + Leupold Mark 4 HAMR (Sand) + Leupold Mark 4 HAMR (Sabbia) + + + Leupold Mark 4 HAMR (Snake) + Leupold Mark 4 HAMR (ヘビ柄迷彩) + 류폴드 마크 4 HAMR (뱀 위장) + Leupold Mark 4 HAMR (Schlange) + Leupold Mark 4 HAMR (Serpe) + + + Aimpoint Micro R-1 (High, Black) + Aimpoint マイクロ R-1 (ハイマウント、ブラック) + 에임포인트 마이크로 R-1 (높음, 검정) + Aimpoint Micro R-1 (Hoch, Schwarz) + Aimpoint Micro R-1 (Alto, Nero) + + + Aimpoint Micro R-1 (High, Khaki) + Aimpoint マイクロ R-1 (ハイマウント、カーキ) + 에임포인트 마이크로 R-1 (높음, 카키) + Aimpoint Micro R-1 (Hoch, Khaki) + Aimpoint Micro R-1 (Alto, Cachi) + + + Aimpoint Micro R-1 (High, Sand) + Aimpoint マイクロ R-1 (ハイマウント、サンド) + 에임포인트 마이크로 R-1 (높음, 모래) + Aimpoint Micro R-1 (Hoch, Sand) + Aimpoint Micro R-1 (Alto, Sabbia) + + + Aimpoint Micro R-1 (High, Snake) + Aimpoint マイクロ R-1 (ハイマウント、ヘビ柄迷彩) + 에임포인트 마이크로 R-1 (높음, 뱀 위장) + Aimpoint Micro R-1 (Hoch, Schlange) + Aimpoint Micro R-1 (Alto, Serpe) + + + Aimpoint Micro R-1 (High, Arid) + Aimpoint マイクロ R-1 (ハイマウント、乾燥地帯迷彩) + 에임포인트 마이크로 R-1 (높음, 건조) + Aimpoint Micro R-1 (Hoch, Trocken) + Aimpoint Micro R-1 (Alto, Arido) + + + Aimpoint Micro R-1 (High, Lush) + Aimpoint マイクロ R-1 (ハイマウント、緑地迷彩) + 에임포인트 마이크로 R-1 (높음, 초목) + Aimpoint Micro R-1 (Hoch, Grün) + Aimpoint Micro R-1 (Alto, Verdeggiante) + + + Aimpoint Micro R-1 (High, Black/Sand) + Aimpoint マイクロ R-1 (ハイマウント、ブラック/サンド) + 에임포인트 마이크로 R-1 (높음, 검정/모래) + Aimpoint Micro R-1 (Hoch, Schwarz/Sand) + Aimpoint Micro R-1 (Alto, Nero/Sabbia) + + + Aimpoint Micro R-1 (Low, Black) + Aimpoint マイクロ R-1 (ローマウント、ブラック) + 에임포인트 마이크로 R-1 (낮음, 검정) + Aimpoint Micro R-1 (Tief, Schwarz) + Aimpoint Micro R-1 (Basso, Nero) + + + Aimpoint Micro R-1 (Low, Khaki) + Aimpoint マイクロ R-1 (ローマウント、カーキ) + 에임포인트 마이크로 R-1 (낮음, 카키) + Aimpoint Micro R-1 (Tief, Khaki) + Aimpoint Micro R-1 (Basso, Cachi) + + + Aimpoint Micro R-1 (Low, Sand) + Aimpoint マイクロ R-1 (ローマウント、サンド) + 에임포인트 마이크로 R-1 (낮음, 모래) + Aimpoint Micro R-1 (Tief, Sand) + Aimpoint Micro R-1 (Basso, Sabbia) + + + Aimpoint Micro R-1 (Low, Snake) + Aimpoint マイクロ R-1 (ローマウント、ヘビ柄迷彩) + 에임포인트 마이크로 R-1 (낮음, 뱀 위장) + Aimpoint Micro R-1 (Tief, Schlange) + Aimpoint Micro R-1 (Basso, Serpe) + + + Aimpoint Micro R-1 (Low, Arid) + Aimpoint マイクロ R-1 (ローマウント、乾燥地帯迷彩) + 에임포인트 마이크로 R-1 (낮음, 건조) + Aimpoint Micro R-1 (Tief, Trocken) + Aimpoint Micro R-1 (Basso, Arido) + + + Aimpoint Micro R-1 (Low, Lush) + Aimpoint マイクロ R-1 (ローマウント、緑地迷彩) + 에임포인트 마이크로 R-1 (낮음, 초목) + Aimpoint Micro R-1 (Tief, Grün) + Aimpoint Micro R-1 (Basso, Verdeggiante) + + + Burris XTR II (Snake) + Burris XTR II (ヘビ柄迷彩) + 버리스 XTR II (뱀 위장) + Burris XTR II (Schlange) + Burris XTR II (Serpe) + + + Badger IFV (ATGM) + バジャー IFV (ATGM) + 뱃져 보병전투차 (대전차미사일) + Badger IFV (PzAbw) + Badger IFV (ATGM) + + + Badger IFV (Command) + バジャー IFV (指揮) + 뱃져 보병전투차 (지휘) + Badger IFV (Kommando) + Badger IFV (Comando) + + + Badger IFV (Mortar) + バジャー IFV (迫撃砲) + 뱃져 보병전투차 (자주박격포) + Badger IFV (Mörser) + Badger IFV (Mortaio) + + + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + 카마즈 (ZU-23-2) + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + + + KamAZ Cargo + KamAZ 貨物 + 카마즈 화물 + KamAZ Fracht + KamAZ Carico + + + KamAZ Repair + KamAZ 修理 + 카마즈 정비 + KamAZ Instandsetzung + KamAZ Riparazione + + + KamAZ Racing + KamAZ レース仕様 + 카마즈 경주용 + KamAZ Rennlaster + KamAZ da corsa + + + KamAZ Ammo + KamAZ 弾薬 + 카마즈 탄약 + KamAZ Munition + KamAZ Munizioni + + + KamAZ Flatbed + KamAZ フラットベッド + 카마즈 플랫베드 + KamAZ Flachbett + KamAZ Pianale + + + AW101 Merlin + AW101 マーリン + AW101 멀린 + AW101 Merlin + AW101 Merlin + + + BM-2T Stalker (Bumerang-BM) + BM-2T ストーカー (ブーメランク-BM) + BM-2T 스토커 (부메랑-BM) + BM-2T Stalker (Bumerang-BM) + BM-2T Stalker (Bumerang-BM) + + + Otokar ARMA (HMG) + オトカ アルマ (HMG) + 오토카르 아르마 APC (중기관총) + Otokar ARMA (HMG) + Otokar ARMA (HMG) + + + Otokar ARMA (Unarmed) + オトカ アルマ (非武装) + 오토카르 아르마 APC (비무장) + Otokar ARMA (Unbewaffnet) + Otokar ARMA (Disarmato) + + + Ka-60 Kasatka (UP) + Ka-60 カサートカ (UP) + Ka-60 카사트카 (UP) + Ka-60 Kasatka (UP) + Ka-60 Kasatka (UP) + + + Ka-60 Kasatka (UP, Unarmed) + Ka-60 カサートカ (UP、非武装) + Ka-60 카사트카 (UP, 비무장)) + Ka-60 Kasatka (UP, Unbewaffnet) + Ka-60 Kasatka (UP, Disarmato) + + + diff --git a/addons/compat_ws/config.cpp b/addons/compat_ws/config.cpp new file mode 100644 index 0000000000..32a3f6f73c --- /dev/null +++ b/addons/compat_ws/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"data_f_lxWS_Loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_ws/script_component.hpp b/addons/compat_ws/script_component.hpp new file mode 100644 index 0000000000..7607cd056b --- /dev/null +++ b/addons/compat_ws/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_ws +#define COMPONENT_BEAUTIFIED Western Sahara Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/concertina_wire/CfgEventHandlers.hpp b/addons/concertina_wire/CfgEventHandlers.hpp index 18883ae839..b1d111b15e 100644 --- a/addons/concertina_wire/CfgEventHandlers.hpp +++ b/addons/concertina_wire/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/concertina_wire/CfgVehicles.hpp b/addons/concertina_wire/CfgVehicles.hpp index 0bc5a31e59..0983f636c2 100644 --- a/addons/concertina_wire/CfgVehicles.hpp +++ b/addons/concertina_wire/CfgVehicles.hpp @@ -34,22 +34,22 @@ class CfgVehicles { source = "user"; animPeriod = 1e-007; }; - class wire_3: wire_2{}; - class wire_4: wire_2{}; - class wire_5: wire_2{}; - class wire_6: wire_2{}; - class wire_7: wire_2{}; - class wire_8: wire_2{}; - class wire_9: wire_2{}; - class wire_10: wire_2{}; - class wire_11: wire_2{}; - class wire_12: wire_2{}; - class wire_13: wire_2{}; - class wire_14: wire_2{}; - class wire_15: wire_2{}; - class wire_16: wire_2{}; - class wire_17: wire_2{}; - class wire_18: wire_2{}; + class wire_3: wire_2 {}; + class wire_4: wire_2 {}; + class wire_5: wire_2 {}; + class wire_6: wire_2 {}; + class wire_7: wire_2 {}; + class wire_8: wire_2 {}; + class wire_9: wire_2 {}; + class wire_10: wire_2 {}; + class wire_11: wire_2 {}; + class wire_12: wire_2 {}; + class wire_13: wire_2 {}; + class wire_14: wire_2 {}; + class wire_15: wire_2 {}; + class wire_16: wire_2 {}; + class wire_17: wire_2 {}; + class wire_18: wire_2 {}; class wire_2_1: wire_2 { animPeriod = 8; @@ -74,7 +74,8 @@ class CfgVehicles { }; class ACE_ConcertinaWire: ACE_ConcertinaWireNoGeo { scope = 2; - displayName = $STR_ACE_CONCERTINA_WIRE; + displayName = CSTRING(DisplayName); + editorPreview = QPATHTOF(data\preview_concertina_wire.jpg); model = QPATHTOF(data\ACE_ConcertinaWire.p3d); EGVAR(logistics_wirecutter,isFence) = 1; class ACE_Actions { @@ -84,7 +85,7 @@ class CfgVehicles { condition = "true"; class ACE_Dismount { selection = ""; - displayName = "$STR_ACE_UNROLLWIRE"; + displayName = CSTRING(UnrollWire); distance = 5; condition = "alive _target"; statement = QUOTE([ARR_2(_target,_player)] call FUNC(dismount)); @@ -103,8 +104,10 @@ class CfgVehicles { }; scope = 2; - displayName = $STR_ACE_CONCERTINA_WIRECOIL; + displayName = CSTRING(Coil_DisplayName); + editorPreview = QPATHTOF(data\preview_concertina_wire_coil.jpg); model = QPATHTOF(data\ACE_ConcertinaWireCoil.p3d); + icon = "iconObject_circle"; mapsize = 0.5; animated = 0; nameSound = "fence"; @@ -129,11 +132,11 @@ class CfgVehicles { condition = "true"; class ACE_Deploy { selection = ""; - displayName = "$STR_ACE_ROLLWIRE"; + displayName = CSTRING(RollWire); distance = 4; condition = "true"; //wait a frame to handle "Do When releasing action menu key" option: - statement = QUOTE([ARR_2({_this call FUNC(deploy)}, [ARR_2(_target,_player)])] call CBA_fnc_execNextFrame); + statement = QUOTE([ARR_2({_this call FUNC(deploy)},[ARR_2(_target,_player)])] call CBA_fnc_execNextFrame); showDisabled = 0; exceptions[] = {}; icon = QPATHTOF(UI\icon_sandbag_ca.paa); diff --git a/addons/concertina_wire/README.md b/addons/concertina_wire/README.md index e1e6530f5b..e21a61d291 100644 --- a/addons/concertina_wire/README.md +++ b/addons/concertina_wire/README.md @@ -2,10 +2,3 @@ ace_concertina_wire =============== Adds concertina wire. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/concertina_wire/XEH_postInit.sqf b/addons/concertina_wire/XEH_postInit.sqf index 7cb8909c81..bb3f022534 100644 --- a/addons/concertina_wire/XEH_postInit.sqf +++ b/addons/concertina_wire/XEH_postInit.sqf @@ -10,4 +10,4 @@ GVAR(deployPFH) = -1; }; }] call CBA_fnc_addEventHandler; -[QGVAR(vehicleDamage), {_this call FUNC(vehicleDamage)}] call CBA_fnc_addEventHandler; +[QGVAR(vehicleDamage), LINKFUNC(vehicleDamage)] call CBA_fnc_addEventHandler; diff --git a/addons/concertina_wire/data/preview_concertina_wire.jpg b/addons/concertina_wire/data/preview_concertina_wire.jpg new file mode 100644 index 0000000000..82780eabf0 Binary files /dev/null and b/addons/concertina_wire/data/preview_concertina_wire.jpg differ diff --git a/addons/concertina_wire/data/preview_concertina_wire_coil.jpg b/addons/concertina_wire/data/preview_concertina_wire_coil.jpg new file mode 100644 index 0000000000..30b2b66ef7 Binary files /dev/null and b/addons/concertina_wire/data/preview_concertina_wire_coil.jpg differ diff --git a/addons/concertina_wire/functions/fnc_deploy.sqf b/addons/concertina_wire/functions/fnc_deploy.sqf index 6ff782fb8e..c915109e1b 100644 --- a/addons/concertina_wire/functions/fnc_deploy.sqf +++ b/addons/concertina_wire/functions/fnc_deploy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * @@ -22,7 +22,7 @@ params ["_wirecoil", "_unit"]; private _wireNoGeo = "ACE_ConcertinaWireNoGeo" createVehicle [0,0,0]; { _wireNoGeo animate [_x, 1]; -} count WIRE_FAST; +} forEach WIRE_FAST; GVAR(placer) = _unit; private _dir = getDir _unit; @@ -51,7 +51,7 @@ GVAR(deployPFH) = [{ private _wire = "ACE_ConcertinaWire" createvehicle [0, 0, 0]; { _wire animate [_x, _anim]; - } count WIRE_FAST; + } forEach WIRE_FAST; [{ params ["_args", "_idPFH"]; @@ -74,10 +74,10 @@ GVAR(deployPFH) = [{ _wireNoGeo setDir _dir; { _wireNoGeo animate [_x, _anim]; - } count WIRE_FAST; + } forEach WIRE_FAST; }, 0, [_wireNoGeo, _wireNoGeoPos, _unit]] call CBA_fnc_addPerFrameHandler; -[localize "STR_ACE_ROLLWIRE", "", ""] call EFUNC(interaction,showMouseHint); +[LLSTRING(RollWire), "", ""] call EFUNC(interaction,showMouseHint); [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); diff --git a/addons/concertina_wire/functions/fnc_dismount.sqf b/addons/concertina_wire/functions/fnc_dismount.sqf index 487c5685a4..b73deb6cf5 100644 --- a/addons/concertina_wire/functions/fnc_dismount.sqf +++ b/addons/concertina_wire/functions/fnc_dismount.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * @@ -25,7 +25,7 @@ if (uiNamespace getVariable [QEGVAR(interact_menu,cursorMenuOpened),false]) exit }; params ["_wire", "_unit"]; -private _config = (configFile >> "CfgVehicles" >> typeOf _unit); +private _config = (configOf _unit); private _delay = [45, 30] select ([_unit] call EFUNC(common,isEngineer) || {[_unit] call EFUNC(common,isEOD)}); // TODO: Animation? @@ -34,7 +34,7 @@ private _delay = [45, 30] select ([_unit] call EFUNC(common,isEngineer) || {[_un [_wire], {(_this select 0) call FUNC(dismountSuccess)}, {}, - localize "STR_ACE_UNROLLWIRE", + LLSTRING(UnrollWire), {true}, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf index 4611aea0f3..86aac9e8bf 100644 --- a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf +++ b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * @@ -20,7 +20,7 @@ params ["_wire"]; { _wire animate [_x, 1]; -} count WIRE_FAST; +} forEach WIRE_FAST; [{ params ["_args", "_idPFH"]; diff --git a/addons/concertina_wire/functions/fnc_handleDamage.sqf b/addons/concertina_wire/functions/fnc_handleDamage.sqf index 958354250b..f5f1177df5 100644 --- a/addons/concertina_wire/functions/fnc_handleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_handleDamage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * @@ -22,7 +22,7 @@ params ["_wire", "", "_damage", "_source", ""]; if (_damage < 0.5) exitWith { 0 }; -if (!(isNull _source)) then { +if (!isNull _source) then { _wire setVariable [QGVAR(lastDamager), _source]; }; diff --git a/addons/concertina_wire/functions/fnc_handleInit.sqf b/addons/concertina_wire/functions/fnc_handleInit.sqf index a602281af1..444fdcf54a 100644 --- a/addons/concertina_wire/functions/fnc_handleInit.sqf +++ b/addons/concertina_wire/functions/fnc_handleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko * Handles wire Init diff --git a/addons/concertina_wire/functions/fnc_handleKilled.sqf b/addons/concertina_wire/functions/fnc_handleKilled.sqf index 33f00ebe13..507deb7a4c 100644 --- a/addons/concertina_wire/functions/fnc_handleKilled.sqf +++ b/addons/concertina_wire/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko * diff --git a/addons/concertina_wire/functions/fnc_vehicleDamage.sqf b/addons/concertina_wire/functions/fnc_vehicleDamage.sqf index 6482ea718a..b3ebb7f77c 100644 --- a/addons/concertina_wire/functions/fnc_vehicleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_vehicleDamage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko * Handles vehicle damage from hitting wire @@ -96,8 +96,8 @@ if (_mode == 1) then { if (canMove _vehicle) then { { private _selectionPart = "hit" + _x; - if (isText(configFile >> "CfgVehicles" >> typeOf _vehicle >> "hitpoints" >> _selectionPart >> "name")) then { - private _selection = getText(configFile >> "CfgVehicles" >> typeOf _vehicle >> "hitpoints" >> _selectionPart >> "name"); + if (isText(configOf _vehicle >> "hitpoints" >> _selectionPart >> "name")) then { + private _selection = getText(configOf _vehicle >> "hitpoints" >> _selectionPart >> "name"); // TODO: Only the tires that have touched the wire should burst. _vehicle setHit [_selection, 1]; }; diff --git a/addons/concertina_wire/functions/script_component.hpp b/addons/concertina_wire/functions/script_component.hpp deleted file mode 100644 index 5ec20093ef..0000000000 --- a/addons/concertina_wire/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\concertina_wire\script_component.hpp" \ No newline at end of file diff --git a/addons/concertina_wire/stringtable.xml b/addons/concertina_wire/stringtable.xml index 78170d90b6..0ea44fc063 100644 --- a/addons/concertina_wire/stringtable.xml +++ b/addons/concertina_wire/stringtable.xml @@ -1,23 +1,24 @@ - - + + Concertina Wire NATO-Draht Колючая проволока Koncentrina Alambre de espino - Fill barbelé + Fil barbelé Ostnatý drát - Filo a concertina + Filo spinato NATO Concertina wire Arame farpado 鉄条網 철조망 鐵絲網 铁丝网 + Bıçaklı Tel - + Concertina Wire Coil NATO-Draht Rolle Колючая проволока (моток) @@ -25,31 +26,33 @@ Bobina de alambre de espino Bobine de fil barbelé Svitek ostnatého drátu - Bobina di filo a concertina + Bobina di filo spinato NATO Concertina wire coil Bobina de arame farpado 鉄条網コイル - 윤형 철조망 + 코일형 철조망 鐵絲網捲 铁丝网卷 + Bıçaklı Tel Rulo - + Dismount Concertina Wire NATO-Draht abbauen Демонтировать колючую проволоку Zwiń koncentrinę Desmontar alambre de espino - Démonter le fil barbelé + Démontage du fil barbelé... Svinout ostnatý drát - Smonta il filo a concertina + Smonta il filo spinato NATO Dismount Concertina wire Desmontar arame farpado 鉄条網をほどく 철조망 해체 卸下鐵絲網 卸下铁丝网 + Bıçaklı Telleri Sök - + Deploy Concertina Wire NATO-Draht verlegen Монтировать колючую проволоку @@ -57,13 +60,14 @@ Desplegar alambre de espino Mettre en place le fil barbelé Rozvinout ostnatý drát - Piazza il filo a concertina + Piazza il filo spinato NATO Deploy Concertina wire Colocar arame farpado 鉄条網を置く 철조망 배치 佈署鐵絲網 - 布署铁丝网 + 部署铁丝网 + Bıçaklı Telleri Yerleştir diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index ba4447dba9..37594bed51 100644 --- a/addons/cookoff/ACE_Settings.hpp +++ b/addons/cookoff/ACE_Settings.hpp @@ -1,12 +1,8 @@ - class ACE_Settings { - class GVAR(enable) { - movedToSqf = 1; - }; class GVAR(enableAmmobox) { movedToSQF = 1; }; - class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0) + class GVAR(enableAmmoCookoff) { movedToSQF = 1; }; class GVAR(ammoCookoffDuration) { diff --git a/addons/cookoff/CfgCloudlets.hpp b/addons/cookoff/CfgCloudlets.hpp index c167177705..a328451a7b 100644 --- a/addons/cookoff/CfgCloudlets.hpp +++ b/addons/cookoff/CfgCloudlets.hpp @@ -1,4 +1,3 @@ - class CfgCloudlets { class GVAR(CookOff) { interval = 0.004; diff --git a/addons/cookoff/CfgEden.hpp b/addons/cookoff/CfgEden.hpp index caffc6b90b..f973ef4026 100644 --- a/addons/cookoff/CfgEden.hpp +++ b/addons/cookoff/CfgEden.hpp @@ -1,28 +1,27 @@ - class Cfg3DEN { class Object { class AttributeCategories { class ace_attributes { class Attributes { - class GVAR(enable) { - property = QGVAR(enable); + class GVAR(enable) { // setting was previously GVAR(enable), so maintain for backwards compatiblity with missions + property = QGVAR(enable); // same as above control = "Checkbox"; - displayName = CSTRING(enable_hd_name); - tooltip = CSTRING(enable_hd_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + displayName = CSTRING(enableFire_name); + tooltip = CSTRING(enableFire_tooltip); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectVehicle"; - defaultValue = QUOTE(GETMVAR(QGVAR(enable),true)); + defaultValue = QUOTE(GETMVAR(QGVAR(enableFire),true)); }; class GVAR(enableAmmoCookoff) { property = QGVAR(enableAmmoCookoff); control = "Checkbox"; displayName = CSTRING(enableAmmoCookoff_name); tooltip = CSTRING(enableAmmoCookoff_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectHasInventoryCargo"; - defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); + defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then {GETMVAR(QGVAR(enableAmmobox),true)} else {GETMVAR(QGVAR(enableAmmoCookoff),true)}); }; }; }; diff --git a/addons/cookoff/CfgEventHandlers.hpp b/addons/cookoff/CfgEventHandlers.hpp index becf395052..f6503c2479 100644 --- a/addons/cookoff/CfgEventHandlers.hpp +++ b/addons/cookoff/CfgEventHandlers.hpp @@ -1,18 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/cookoff/CfgSFX.hpp b/addons/cookoff/CfgSFX.hpp index 0d670ead86..24329862fc 100644 --- a/addons/cookoff/CfgSFX.hpp +++ b/addons/cookoff/CfgSFX.hpp @@ -1,4 +1,3 @@ - class CfgSFX { class GVAR(CookOff_low) { name = QGVAR(cookoff_low); diff --git a/addons/cookoff/CfgSounds.hpp b/addons/cookoff/CfgSounds.hpp new file mode 100644 index 0000000000..70d752d613 --- /dev/null +++ b/addons/cookoff/CfgSounds.hpp @@ -0,0 +1,66 @@ +#define VOLUME 2 +#define PITCH 1 + +#define SHOTSOUND(type,dist,N,maxDistance)\ +class GVAR(TRIPLES(type,dist,N)) {\ + sound[] = {QPATHTOF(sounds\type\DOUBLES(dist,N).wss), VOLUME, PITCH, maxDistance};\ + titles[] = {};\ +} + +#define SHOTSOUNDCLASS(type,dist,maxDistance)\ +SHOTSOUND(type,dist,1,maxDistance);\ +SHOTSOUND(type,dist,2,maxDistance);\ +SHOTSOUND(type,dist,3,maxDistance) + +#define SHOTSOUNDCLASSTYPE(type,maxDistance)\ +SHOTSOUNDCLASS(type,close,maxDistance);\ +SHOTSOUNDCLASS(type,mid,maxDistance);\ +SHOTSOUNDCLASS(type,far,maxDistance) + +// Allows other mods to change sounds for cook-off +class CfgSounds { + // These macros set up the sounds for the various classes + SHOTSOUNDCLASSTYPE(shotbullet,1250); + SHOTSOUNDCLASSTYPE(shotrocket,1600); + SHOTSOUNDCLASSTYPE(shotshell,1300); + + // Missiles use the same sounds as rockets + class GVAR(shotmissile_close_1): GVAR(shotrocket_close_1) {}; + class GVAR(shotmissile_close_2): GVAR(shotrocket_close_2) {}; + class GVAR(shotmissile_close_3): GVAR(shotrocket_close_3) {}; + class GVAR(shotmissile_mid_1): GVAR(shotrocket_mid_1) {}; + class GVAR(shotmissile_mid_2): GVAR(shotrocket_mid_2) {}; + class GVAR(shotmissile_mid_3): GVAR(shotrocket_mid_3) {}; + class GVAR(shotmissile_far_1): GVAR(shotrocket_far_1) {}; + class GVAR(shotmissile_far_2): GVAR(shotrocket_far_2) {}; + class GVAR(shotmissile_far_3): GVAR(shotrocket_far_3) {}; + + // Submunitions have the same sound as bullets, but a higher maxDistance + class GVAR(shotsubmunitions_close_1): GVAR(shotbullet_close_1) { + sound[] = {QPATHTOF(sounds\shotbullet\close_1.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_close_2): GVAR(shotbullet_close_2) { + sound[] = {QPATHTOF(sounds\shotbullet\close_2.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_close_3): GVAR(shotbullet_close_3) { + sound[] = {QPATHTOF(sounds\shotbullet\close_3.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_mid_1): GVAR(shotbullet_mid_1) { + sound[] = {QPATHTOF(sounds\shotbullet\mid_1.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_mid_2): GVAR(shotbullet_mid_2) { + sound[] = {QPATHTOF(sounds\shotbullet\mid_2.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_mid_3): GVAR(shotbullet_mid_3) { + sound[] = {QPATHTOF(sounds\shotbullet\mid_3.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_far_1): GVAR(shotbullet_far_1) { + sound[] = {QPATHTOF(sounds\shotbullet\far_1.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_far_2): GVAR(shotbullet_far_2) { + sound[] = {QPATHTOF(sounds\shotbullet\far_2.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_far_3): GVAR(shotbullet_far_3) { + sound[] = {QPATHTOF(sounds\shotbullet\far_3.wss), VOLUME, PITCH, 1600}; + }; +}; diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 7a682ca9d0..4451d12080 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class Sound; class GVAR(Sound_low): Sound { @@ -7,7 +6,6 @@ class CfgVehicles { scope = 1; sound = QGVAR(CookOff_low); }; - class GVAR(Sound_mid): GVAR(Sound_low) { sound = QGVAR(CookOff_mid); }; @@ -15,74 +13,16 @@ class CfgVehicles { sound = QGVAR(CookOff_high); }; - class ThingX; - class GVAR(Turret_MBT_01): ThingX { - author = ECSTRING(common,ACETeam); - _generalMacro = QGVAR(Turret_MBT_01); - scope = 1; - displayName = CSTRING(generic_turret_wreck); - model = "\A3\Structures_F\Wrecks\Wreck_Slammer_turret_F.p3d"; - icon = "\A3\armor_f_gamma\MBT_01\Data\ui\map_slammer_mk4_ca.paa"; - }; - class GVAR(Turret_MBT_02): ThingX { - author = ECSTRING(common,ACETeam); - _generalMacro = QGVAR(Turret_MBT_02); - scope = 1; - displayName = CSTRING(generic_turret_wreck); - model = "\A3\Structures_F\Wrecks\Wreck_T72_turret_F.p3d"; - icon = "\A3\armor_f_gamma\MBT_02\Data\UI\map_MBT_02_ca.paa"; - }; - class Tank; class Tank_F: Tank { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.5; - }; - class MBT_02_base_F: Tank_F { - GVAR(ammoLocation) = "HitTurret"; }; class Car_F; class Wheeled_APC_F: Car_F { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.8; - // big explosions for wheeled APCs (same as for tanks) + // Big explosions for wheeled APCs (same as for tanks) explosionEffect = "FuelExplosionBig"; }; - - class APC_Wheeled_02_base_F: Wheeled_APC_F { // Otokar ARMA - RCWS Turret - GVAR(ignoreTurret) = 1; - }; - class APC_Tracked_01_base_F: Tank_F { // Namera, Nemmera - RCWS Turret - GVAR(ignoreTurret) = 1; - }; - - class B_MBT_01_base_F; - class B_MBT_01_cannon_F: B_MBT_01_base_F { - GVAR(turret)[] = {QGVAR(Turret_MBT_01),{0,-1,0.5}}; - }; - - class O_MBT_02_base_F; - class O_MBT_02_cannon_F: O_MBT_02_base_F { - GVAR(turret)[] = {QGVAR(Turret_MBT_02),{0,-1,0}}; - }; - - class MRAP_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_02_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_03_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class Quadbike_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,1,0}; - }; }; diff --git a/addons/cookoff/XEH_PREP.hpp b/addons/cookoff/XEH_PREP.hpp index f1deb8eaed..9405908953 100644 --- a/addons/cookoff/XEH_PREP.hpp +++ b/addons/cookoff/XEH_PREP.hpp @@ -1,8 +1,12 @@ - -PREP(handleDamage); -PREP(engineFire); -PREP(cookOff); -PREP(cookOffBox); -PREP(blowOffTurret); -PREP(detonateAmmunition); +PREP(cookOffBoxLocal); +PREP(cookOffBoxServer); +PREP(cookOffLocal); +PREP(cookOffServer); +PREP(detonateAmmunitionServer); +PREP(detonateAmmunitionServerLoop); +PREP(engineFireLocal); +PREP(engineFireServer); PREP(getVehicleAmmo); +PREP(handleDamageBox); +PREP(isMagazineFlare); +PREP(smoke); diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index fad901982d..63e1486c82 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -1,110 +1,100 @@ #include "script_component.hpp" -[QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler; -[QGVAR(cookOff), FUNC(cookOff)] call CBA_fnc_addEventHandler; -[QGVAR(cookOffBox), FUNC(cookOffBox)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffBoxLocal), LINKFUNC(cookOffBoxLocal)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffLocal), LINKFUNC(cookOffLocal)] call CBA_fnc_addEventHandler; +[QGVAR(engineFireLocal), LINKFUNC(engineFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(smoke), LINKFUNC(smoke)] call CBA_fnc_addEventHandler; -GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace; - -// cookoff and burning engine -["Tank", "init", { - params ["_vehicle"]; - - private _typeOf = typeOf _vehicle; - - if (isNil {GVAR(cacheTankDuplicates) getVariable _typeOf}) then { - private _hitpoints = (getAllHitPointsDamage _vehicle param [0, []]) apply {toLower _x}; - private _duplicateHitpoints = []; - - { - if ((_x != "") && {_x in (_hitpoints select [0,_forEachIndex])}) then { - _duplicateHitpoints pushBack _forEachIndex; - }; - } forEach _hitpoints; - - TRACE_2("dupes",_typeOf,_duplicateHitpoints); - GVAR(cacheTankDuplicates) setVariable [_typeOf, _duplicateHitpoints]; - }; - - _vehicle addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then { - ["tank", _this] call FUNC(handleDamage); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; - -["Wheeled_APC_F", "init", { - params ["_vehicle"]; - - private _typeOf = typeOf _vehicle; - - if (isNil {GVAR(cacheTankDuplicates) getVariable _typeOf}) then { - private _hitpoints = (getAllHitPointsDamage _vehicle param [0, []]) apply {toLower _x}; - private _duplicateHitpoints = []; - - { - if ((_x != "") && {_x in (_hitpoints select [0,_forEachIndex])}) then { - _duplicateHitpoints pushBack _forEachIndex; - }; - } forEach _hitpoints; - - TRACE_2("dupes",_typeOf,_duplicateHitpoints); - GVAR(cacheTankDuplicates) setVariable [_typeOf, _duplicateHitpoints]; - }; - - _vehicle addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then { - ["tank", _this] call FUNC(handleDamage); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; - -["Car", "init", { - params ["_vehicle"]; - - _vehicle addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then { - ["car", _this] call FUNC(handleDamage); - }; - }]; -}, nil, ["Wheeled_APC_F"], true] call CBA_fnc_addClassEventHandler; - -["ReammoBox_F", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { - ["box", _this] call FUNC(handleDamage); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; - -// secondary explosions -["AllVehicles", "killed", { - params ["_vehicle"]; - if (_vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)]) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_vehicle, _mags, _total] call FUNC(detonateAmmunition); - }; -}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler; - -// blow off turret effect -["Tank", "killed", { - if ((_this select 0) getVariable [QGVAR(enable),GVAR(enable)]) then { - if (random 1 < 0.15) then { - (_this select 0) call FUNC(blowOffTurret); - }; - }; -}] call CBA_fnc_addClassEventHandler; - -// event to add a turret to a curator if the vehicle already belonged to that curator if (isServer) then { - [QGVAR(addTurretToEditable), { - params ["_vehicle", "_turret"]; + [QGVAR(cookOffBoxServer), LINKFUNC(cookOffBoxServer)] call CBA_fnc_addEventHandler; + [QGVAR(cookOffServer), LINKFUNC(cookOffServer)] call CBA_fnc_addEventHandler; + [QGVAR(detonateAmmunitionServer), LINKFUNC(detonateAmmunitionServer)] call CBA_fnc_addEventHandler; + [QGVAR(engineFireServer), LINKFUNC(engineFireServer)] call CBA_fnc_addEventHandler; +}; - { - if (_vehicle in curatorEditableObjects _x) then { - _x addCuratorEditableObjects [[_turret], false]; - }; - } forEach allCurators; +// Handle cleaning up effects when objects are deleted mid cook-off +["AllVehicles", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; + +["ReammoBox_F", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Raised when the flames have subsided or after the ammo of a box has finished cooking off +[QGVAR(cleanupEffects), { + params ["_object"]; + + { + deleteVehicle _x; + } forEach (_object getVariable [QGVAR(effects), []]); + + _object setVariable [QGVAR(effects), nil]; +}] call CBA_fnc_addEventHandler; + +// Ammo box damage handling +["ReammoBox_F", "init", { + // Calling this function inside curly brackets allows the usage of "exitWith", which would be broken with "HandleDamage" otherwise + (_this select 0) addEventHandler ["HandleDamage", {_this call FUNC(handleDamageBox)}]; +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Vehicle ammo cook-off (secondary explosions) +["AllVehicles", "Killed", { + if (!GVAR(enableAmmoCookoff) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + + params ["_vehicle", "", "", "_useEffects"]; + + if (_useEffects && {_vehicle getVariable [QGVAR(enableAmmoCookoff), true]}) then { + // We don't need to pass source and instigator, as vehicle is already dead + [QGVAR(detonateAmmunitionServer), [ + _vehicle, + false, + objNull, + objNull, + random [MIN_AMMO_DETONATION_START_DELAY, (MIN_AMMO_DETONATION_START_DELAY + MAX_AMMO_DETONATION_START_DELAY) / 2, MAX_AMMO_DETONATION_START_DELAY] + ]] call CBA_fnc_serverEvent; + }; +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; + +if (hasInterface) then { + // Plays a sound locally, so that different sounds can be used for various distances + [QGVAR(playCookoffSound), { + params ["_object", "_sound"]; + + if (isNull _object) exitWith {}; + + private _distance = _object distance (positionCameraToWorld [0, 0, 0]); + + TRACE_2("",_object,_sound); + + // 3 classes of distances: close, mid and far, each having different sound files + private _classDistance = switch (true) do { + case (_distance < DISTANCE_CLOSE): {"close"}; + case (_distance < DISTANCE_MID): {"mid"}; + default {"far"}; + }; + + _sound = format [QGVAR(%1_%2_%3), _sound, _classDistance, floor (random 3) + 1]; + + TRACE_1("",_sound); + + // Allows other mods to change sounds for cook-off + _sound = getArray (configFile >> "CfgSounds" >> _sound >> "sound"); + + if (_sound isEqualTo []) exitWith {}; + + _sound params ["_sound", "_volume", "_pitch", "_maxDistance"]; + + if (_distance > _maxDistance) exitWith {}; + + // Make sure file exists, so RPT isn't spammed with non-existent entry errors + if (!fileExists _sound) exitWith {}; + + // Obeys speed of sound and takes doppler effects into account + playSound3D [_sound, objNull, false, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/cookoff/XEH_preInit.sqf b/addons/cookoff/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/cookoff/XEH_preInit.sqf +++ b/addons/cookoff/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/cookoff/config.cpp b/addons/cookoff/config.cpp index 0673efaffe..dc7a472855 100644 --- a/addons/cookoff/config.cpp +++ b/addons/cookoff/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {QGVAR(Sound),QGVAR(Turret_MBT_01),QGVAR(Turret_MBT_02)}; + units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; @@ -21,4 +21,5 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgCloudlets.hpp" #include "CfgSFX.hpp" +#include "CfgSounds.hpp" #include "CfgVehicles.hpp" diff --git a/addons/cookoff/functions/fnc_blowOffTurret.sqf b/addons/cookoff/functions/fnc_blowOffTurret.sqf deleted file mode 100644 index 2d76463e8d..0000000000 --- a/addons/cookoff/functions/fnc_blowOffTurret.sqf +++ /dev/null @@ -1,36 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Blow off turret effect. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * (vehicle player) call ace_cookoff_fnc_blowOffTurret - * - * Public: No - */ - -// delayed so the object is spawned after the model changes to a wreck -// the sudden change in the model would cause nearby physx objects to get stuck -[{ - params ["_vehicle"]; - - private _config = _vehicle call CBA_fnc_getObjectConfig; - getArray (_config >> QGVAR(turret)) params [["_model", "", [""]], ["_offset", [0,0,0], [[]], 3]]; - - if (_model isEqualTo "") exitWith {}; - - private _position = _vehicle modelToWorld _offset; - private _turret = createVehicle [_model, _position, [], 0, "CAN_COLLIDE"]; - - _turret setVectorUp [random 1, random 1, 1]; - _turret setVelocity [random 7, random 7, 8 + random 5]; - - // add turret to all curators that already own the wreck - [QGVAR(addTurretToEditable), [_vehicle, _turret]] call CBA_fnc_serverEvent; -}, _this, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf deleted file mode 100644 index c19f968c47..0000000000 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ /dev/null @@ -1,140 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Start a cook-off in the given vehicle. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * [(vehicle player)] call ace_cookoff_fnc_cookOff - * - * Public: No - */ - -params ["_vehicle"]; - -if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_vehicle setVariable [QGVAR(isCookingOff), true]; - -if (local _vehicle) then { - [QGVAR(cookOff), _vehicle] call CBA_fnc_remoteEvent; -}; - -[{ - params ["_vehicle"]; - - private _config = _vehicle call CBA_fnc_getObjectConfig; - private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {!((_vehicle selectionPosition _x) isEqualTo [0,0,0])}; - - if (_positions isEqualTo []) then { - WARNING_1("no valid selection for cookoff found. %1", typeOf _vehicle); - _positions pushBack "#noselection"; - }; - - private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret; - private _positionBarrelEnd = getText (_turretConfig >> "gunBeg"); - - // smoke out of cannon and hatches - private _smokeBarrel = "#particlesource" createVehicleLocal [0,0,0]; - _smokeBarrel setParticleClass "MediumDestructionSmoke"; - _smokeBarrel attachTo [_vehicle, [0,0,0], _positionBarrelEnd]; - - private _effects = [_smokeBarrel]; - - { - private _position = [0,-2,0]; - - if !(_x isEqualTo "#noselection") then { - _position = _vehicle selectionPosition _x; - }; - - private _smoke = "#particlesource" createVehicleLocal [0,0,0]; - _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; - _smoke attachTo [_vehicle, _position]; - - _effects pushBack _smoke; - } forEach _positions; - - [{ - params ["_vehicle", "_effects", "_positions"]; - - // this shit is busy being on fire, can't go driving around all over the place - if (local _vehicle) then { - _vehicle setFuel 0; - }; - - private _light = "#lightpoint" createVehicleLocal [0,0,0]; - _light setLightBrightness 0.7; - _light setLightAmbient [1,0.4,0.15]; - _light setLightColor [1,0.4,0.15]; - _light lightAttachObject [_vehicle, [0,0,4]]; - - _effects pushBack _light; - - // cookoffs - { - private _position = [0,-2,0]; - - if !(_x isEqualTo "#noselection") then { - _position = _vehicle selectionPosition _x; - }; - - private _fire = "#particlesource" createVehicleLocal [0,0,0]; - _fire setParticleClass QGVAR(CookOff); - _fire attachTo [_vehicle, _position]; - - _effects pushBack _fire; - } forEach _positions; - - if (isServer) then { - private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; - // TODO - Players in the vehicle hear no sound (even after exiting the vehicle) - private _sound = createSoundSource [_soundName, position _vehicle, [], 0]; - - _effects pushBack _sound; - }; - - // indicator for the crew - yo, your shit's on fire - private _fnc_FlameEffect = { - params ["_vehicle", "_fnc_FlameEffect", "_counter"]; - - if (_vehicle == cameraOn) then { - [] call BIS_fnc_flamesEffect; - }; - - DEC(_counter); - - if (_counter > 0) then { - [_fnc_FlameEffect, [_vehicle, _fnc_FlameEffect, _counter], FLAME_EFFECT_DELAY] call CBA_fnc_waitAndExecute - }; - }; - - // Recursive function, occurs for duration of cookoff - [_vehicle, _fnc_FlameEffect, ceil(COOKOFF_TIME/FLAME_EFFECT_DELAY)] call _fnc_FlameEffect; - - private _randomPosition = _vehicle getPos [100, random 360]; - - { - if (local _x && {!(_x call EFUNC(common,isPlayer))}) then { - _x leaveVehicle _vehicle; - _x doMove _randomPosition; - }; - } forEach crew _vehicle; - - [{ - params ["_vehicle", "_effects"]; - - { - deleteVehicle _x; - } forEach _effects; - - if (local _vehicle) then { - _vehicle setDamage 1; - }; - }, [_vehicle, _effects], COOKOFF_TIME] call CBA_fnc_waitAndExecute; // TODO: Randomise cook off time with locality in mind - }, [_vehicle, _effects, _positions], SMOKE_TIME] call CBA_fnc_waitAndExecute; -}, _vehicle, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf deleted file mode 100644 index 8f6ef7f2f0..0000000000 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ /dev/null @@ -1,74 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, commy2, SilentSpike - * Start a cook-off in the given ammo box. - * - * Arguments: - * 0: Ammo box - * - * Return Value: - * None - * - * Example: - * [_box] call ace_cookoff_fnc_cookOffBox - * - * Public: No - */ - -params ["_box"]; - -if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_box setVariable [QGVAR(isCookingOff), true]; - -if (local _box) then { - [QGVAR(cookOffBox), _box] call CBA_fnc_remoteEvent; -}; - -[{ - params ["_box"]; - - // Box will start smoking - private _smoke = "#particlesource" createVehicleLocal [0,0,0]; - _smoke setParticleClass "AmmoSmokeParticles2"; - _smoke attachTo [_box, [0,0,0]]; - - private _effects = [_smoke]; - - if (isServer) then { - private _sound = createSoundSource ["Sound_Fire", position _box, [], 0]; - _effects pushBack _sound; - }; - - [{ - params ["_box", "_effects"]; - - // These functions are smart and do all the cooking off work - if (local _box) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_box, _mags, _total] call FUNC(detonateAmmunition); - - // This shit is busy being on fire, magazines aren't accessible/usable - clearMagazineCargoGlobal _box; - }; - - // Light the fire (also handles lighting) - private _fire = "#particlesource" createVehicleLocal [0,0,0]; - _fire setParticleClass "AmmoBulletCore"; - _fire attachTo [_box, [0,0,0]]; - - _effects pushBack _fire; - - [{ - params ["_box", "_effects"]; - - { - deleteVehicle _x; - } forEach _effects; - - if (local _box) then { - _box setDamage 1; - }; - }, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind - }, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute; -}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf new file mode 100644 index 0000000000..8285104daf --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Spawns local cook-off effects for ammo boxes. + * + * Arguments: + * 0: Box + * 1: Source + * 2: Instigator + * 3: Start time of the cook-off + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player, CBA_missionTime + 10] call ace_cookoff_fnc_cookOffBoxLocal + * + * Public: No + */ + +params ["", "", "", "_startTime"]; + +[{ + params ["_box", "_source", "_instigator"]; + + // If box was deleted before smoke could be spawned, just exit + if (isNull _box) exitWith {}; + + private _boxPos = ASLToAGL getPosASL _box; + private _effects = []; + + // Box will start smoking + if (hasInterface) then { + private _smoke = createVehicleLocal ["#particlesource", _boxPos, [], 0, "CAN_COLLIDE"]; + _smoke setParticleClass "AmmoSmokeParticles2"; + _smoke attachTo [_box]; + + _effects pushBack _smoke; + }; + + if (isServer) then { + private _sound = createSoundSource ["Sound_Fire", _boxPos, [], 0]; + _sound attachTo [_box]; + + _effects pushBack _sound; + + // Detonate the ammunition + [QGVAR(detonateAmmunitionServer), [_box, true, _source, _instigator, random [DETONATION_DELAY / 2, DETONATION_DELAY, DETONATION_DELAY / 2 * 3]]] call CBA_fnc_localEvent; + }; + + _box setVariable [QGVAR(effects), _effects]; +}, _this, (_startTime - CBA_missionTime) max 0] call CBA_fnc_waitAndExecute; // This delay allows for synchronisation for JIP players diff --git a/addons/cookoff/functions/fnc_cookOffBoxServer.sqf b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf new file mode 100644 index 0000000000..10d57876a7 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Start an ammo cook-off in the given ammo box. + * + * Arguments: + * 0: Ammo box + * 1: Source (default: objNull) + * 2: Instigator (default: objNull) + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_cookOffBoxServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + +params ["_box", ["_source", objNull], ["_instigator", objNull]]; + +// Make sure it's a box (important, because deleted EH is assigned to ReammoBox_F only in postInit) +if !(_box isKindOf "ReammoBox_F") exitWith {}; + +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +// Allow only 1 cook-off per box at a time +if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_box setVariable [QGVAR(isCookingOff), true, true]; + +private _delay = random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3]; + +// Spawn cook-off effects on all connected machines and JIP +private _jipID = [QGVAR(cookOffBoxLocal), [ + _box, + _source, + _instigator, + CBA_missionTime + _delay // Generate a globally synced timestamp +]] call CBA_fnc_globalEventJIP; + +[_jipID, _box] call CBA_fnc_removeGlobalEventJIP; + +_box setVariable [QGVAR(cookoffBoxJipID), _jipID]; + +// API +[QGVAR(cookOffBox), [_box, _source, _instigator, _delay]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_cookOffLocal.sqf b/addons/cookoff/functions/fnc_cookOffLocal.sqf new file mode 100644 index 0000000000..cbd160bba1 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffLocal.sqf @@ -0,0 +1,229 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawn cook-off fire effects. + * + * Arguments: + * 0: Vehicle + * 1: Spawn fire jet + * 2: Spawn fire ring + * 3: What selection fire will originate from + * 4: Cookoff intensity value + * 5: Start time + * 6: Duration of effect (max 20 seconds) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, false, "commander_turret", 6, CBA_missionTime, 15] call ace_cookoff_fnc_cookOffLocal + * + * Public: No + */ + +#define FLAME_SIZE 1.5 +#define FIRE_INTENSITY 20 + +params ["_vehicle", "_jet", "_ring", "_fireSelection", "_intensity", "_startTime", "_duration"]; + +// Check if still valid for JIP players +if (isNull _vehicle || {CBA_missionTime - _startTime >= _duration}) exitWith {}; + +// Spawn light +private _light = objNull; + +if (hasInterface) then { + _light = "#lightpoint" createVehicleLocal [0, 0, 0]; + _light setLightBrightness 5; + _light setLightAmbient [0.8, 0.6, 0.2]; + _light setLightColor [1, 0.5, 0.2]; + _light lightAttachObject [_vehicle, [0, 0, 0]]; +}; + +_duration = 0 max _duration min 20; + +private _sound = objNull; +private _fireKey = ""; + +if (isServer) then { + // Spawn sound effect + if (_jet || _ring) then { + private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; + _sound = createSoundSource [_soundName, ASLToAGL getPosASL _vehicle, [], 0]; + _sound attachTo [_vehicle]; + }; + + // Make the ring a source of fire + if (_ring && {["ace_fire"] call EFUNC(common,isModLoaded)}) then { + _fireKey = format [QGVAR(cookoffFire_%1), hashValue _vehicle]; + + [QEGVAR(fire,addFireSource), [_vehicle, FLAME_SIZE * ((boundingBoxReal _vehicle) select 2), FIRE_INTENSITY, _fireKey]] call CBA_fnc_localEvent; + }; +}; + +[{ + (_this select 0) params ["_vehicle", "_jet", "_ring", "_startTime", "_duration", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"]; + + private _elapsedTime = CBA_missionTime - _startTime; + + // Clean up effects once effects have finished or vehicle has been deleted + if (isNull _vehicle || {_elapsedTime >= _duration}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _light; + + if (isServer) then { + deleteVehicle _sound; + + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(fire,removeFireSource), _fireKey] call CBA_fnc_localEvent; + }; + }; + }; + + private _factor = 1 + (_elapsedTime / 2) min 2; + + if (_elapsedTime > _duration * 3 / 4) then { + _factor = _factor * linearConversion [_duration * 3 / 4, _duration, _elapsedTime, 1, 0.5]; + }; + + // Make flame push object into ground to make effect seem more "alive" + if (_jet && !isGamePaused && {local _vehicle} && {_vehicle getVariable [QGVAR(nextForceTime), 0] <= CBA_missionTime}) then { + private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _vehicle; + _vehicle addForce [_force, vectorUpVisual _vehicle]; + _vehicle setVariable [QGVAR(nextForceTime), CBA_missionTime + 0.01]; // This prevents bad behaviour when setAccTime is small + }; + + // Don't spawn visual effects on machines without interfaces + if (!hasInterface) exitWith {}; + + _light setLightBrightness _factor; + + if (_jet) then { + private _particlePosition = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", + "Billboard", + 1, + (0.1 + random 0.2) * _factor, + _particlePosition, + [0, 0, 15 * (_factor / 2)], + 0, + 10, + 7.9, + 0.075, + [1.25 * _factor, 2.5 * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], + 1, + 0, + "", + "", + _vehicle + ]; + }; + + if (_ring) then { + private _ringOrigin = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, 20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, -20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + [-0.1 + random 0.2, -0.1 + random 0.2, -1], + [-20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + private _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = -20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, -_dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [-_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + }; + + (getVehicleTIPars _vehicle) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; + + // Formula is designed to have the temperature ramp up quickly and then level out + _vehicle setVehicleTIPars [ + (_tiEngine + _intensity * 0.01) / 1.005, + (_tiWheels + _intensity * 0.004) / 1.002, // Wheels/tracks are further away from burning parts + (_tiWeapon + _intensity * 0.01) / 1.005 + ]; +}, 0, [_vehicle, _jet, _ring, _startTime, _duration, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffServer.sqf b/addons/cookoff/functions/fnc_cookOffServer.sqf new file mode 100644 index 0000000000..05111d7e69 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffServer.sqf @@ -0,0 +1,202 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Start a cook-off in the given vehicle. + * Spews flames in multiple directions at the same time (ring) or from the turret towards the sky (jet). + * + * Arguments: + * 0: Vehicle + * 1: Intensity of fire + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Delay between smoke and fire enabled (default: true) + * 5: Ammo detonation chance (default: 0) + * 6: Detonate after cook-off (default: false) + * 7: Selection for fire source (default: "") + * 8: Can spawn fire ring (default: true) + * 9: Can spawn fire jet (default: true) + * 10: Maximum intensity (default: MAX_COOKOFF_INTENSITY) + * + * Return Value: + * None + * + * Example: + * [cursorObject, 3] call ace_cookoff_fnc_cookOffServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableFire) || {GVAR(cookoffDuration) == 0}) exitWith {}; + +params [ + "_vehicle", + "_intensity", + ["_source", objNull], + ["_instigator", objNull], + ["_delayBetweenSmokeAndFire", true], + ["_ammoDetonationChance", 0], + ["_detonateAfterCookoff", false], + ["_fireSelection", ""], + ["_canRing", true], + ["_canJet", true], + ["_maxIntensity", MAX_COOKOFF_INTENSITY] +]; + +// Make sure it's a vehicle (important, because deleted EH is assigned to AllVehicles only in postInit) +if !(_vehicle isKindOf "AllVehicles") exitWith {}; + +if (_vehicle isKindOf "CAManBase" || {_vehicle isKindOf "StaticWeapon"}) exitWith {}; + +// If under water, ignore +// underwater is not very reliable, so use model center instead +if (underwater _vehicle || {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}}) exitWith {}; + +// Check if cook-off is disabled on vehicle specifically +if !(_vehicle getVariable [QGVAR(enable), true]) exitWith {}; // QGVAR(enable) is API + +TRACE_3("cooking off",_vehicle,_intensity,_maxIntensity); +TRACE_8("",_source,_instigator,_delayBetweenSmokeAndFire,_ammoDetonationChance,_detonateAfterCookoff,_fireSelection,_canRing,_canJet); + +if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isCookingOff), true, true]; + +// Limit maximum value of intensity to prevent very long cook-off times +_intensity = _intensity min _maxIntensity; + +private _selections = getArray (configOf _vehicle >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]}; + +if (_selections isEqualTo []) then { + WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); + + { + if ((_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]) then { + _selections pushBack _x; + }; + } forEach DEFAULT_COMMANDER_HATCHES; + + if (_selections isEqualTo []) then { + _selections pushBack "#noselection"; + }; +}; + +// Not guaranteed to be active/used, but reserve it nonetheless +private _fireJipID = format [QGVAR(cookOffLocal_%1), hashValue _vehicle]; +[_fireJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Spawn smoke +private _smokeJipID = [QGVAR(smoke), [_vehicle, _selections]] call CBA_fnc_globalEventJIP; +[_smokeJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Save intensity for looping purposes +_vehicle setVariable [QGVAR(intensity), _intensity]; + +private _delay = 0; + +if (_delayBetweenSmokeAndFire) then { + _delay = random [SMOKE_DELAY, 1.5 * SMOKE_DELAY, 2 * SMOKE_DELAY]; +}; + +[{ + [{ + (_this select 0) params ["_vehicle", "_selections", "_ammoDetonationChance", "_detonateAfterCookoff", "_source", "_instigator", "_fireSelection", "_canRing", "_canJet", "_smokeJipID", "_fireJipID"]; + + if ( + isNull _vehicle || + !GVAR(enableFire) || + {!(_vehicle getVariable [QGVAR(enable), true])} || // QGVAR(enable) is API + {GVAR(cookoffDuration) == 0} || + {underwater _vehicle} || + {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}} // Underwater is not very reliable, so use model center instead + ) exitWith { + // Effects are deleted when vehicle is deleted + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; + + if (_intensity <= 1) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + // Wait until the previous flame has finished + private _nextFlameTime = (_vehicle getVariable [QGVAR(endCurrentFlame), CBA_missionTime]) - CBA_missionTime + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES); + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + [{ + params ["_vehicle", "_source", "_instigator", "_detonateAfterCookoff", "_fireSelection", "_smokeJipID", "_fireJipID"]; + + // Effects are deleted when vehicle is deleted + if (isNull _vehicle) exitWith {}; + + // Remove effects from JIP + _smokeJipID call CBA_fnc_removeGlobalEventJIP; + _fireJipID call CBA_fnc_removeGlobalEventJIP; + + // Remove effects + [QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent; + + // Reset variable, so it can cook-off again + _vehicle setVariable [QGVAR(isCookingOff), nil, true]; + + if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setDamage [1, true, _source, _instigator]; // Because it's running on the server, source and instigator can be set + }; + }, [_vehicle, _source, _instigator, _detonateAfterCookoff, _fireSelection, _smokeJipID, _fireJipID], _nextFlameTime] call CBA_fnc_waitAndExecute; + }; + + // Wait until we are ready for the next flame + if ((_vehicle getVariable [QGVAR(nextFlame), 0]) <= CBA_missionTime) then { + private _ring = false; + + if (_canRing) then { + _ring = 0.2 > random 1; + + if (!_ring && {_intensity >= 2}) then { + _ring = 0.7 > random 1; + }; + }; + + private _duration = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + // Sync for JIP players + [QGVAR(cookOffLocal), [_vehicle, _canJet, _ring, _fireSelection, _intensity, CBA_missionTime, _duration], _fireJipID] call CBA_fnc_globalEventJIP; + + // If there are any crew, burn them + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + // Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens + { + [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); + }; + + _intensity = (_intensity - (0.5 max random 1) / GVAR(cookoffDuration)) max 0; + + _vehicle setVariable [QGVAR(intensity), _intensity]; + _vehicle setVariable [QGVAR(endCurrentFlame), CBA_missionTime + _duration]; + _vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _duration + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; + }; + + if (_ammoDetonationChance > random 1 && {_vehicle getVariable [QGVAR(nextExplosiveDetonation), 0] <= CBA_missionTime}) then { + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setVariable [QGVAR(nextExplosiveDetonation), CBA_missionTime + random 60]; + }; + }, 0.25, _this] call CBA_fnc_addPerFrameHandler; +}, [_vehicle, _selections, _ammoDetonationChance, _detonateAfterCookoff, _source, _instigator, _fireSelection, _canRing, _canJet, _smokeJipID, _fireJipID], _delay] call CBA_fnc_waitAndExecute; + +// API +[QGVAR(cookoff), [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSelection, _canRing, _maxIntensity, _canJet]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf deleted file mode 100644 index 0d944958d2..0000000000 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ /dev/null @@ -1,133 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Detonates ammunition from a vehicle until no ammo left - * - * Arguments: - * 0: vehicle - * 1: Ammo Array - * 0: Magazine Classname - * 1: Ammo Count - * 2: Total Ammo Count - * - * Return Value: - * None - * - * Example: - * [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition - * - * Public: No - */ -#define MAX_TIME_BETWEEN_AMMO_DET 25 - -params ["_vehicle", "_magazines", "_totalAmmo"]; - -if (isNull _vehicle) exitWith {}; // vehicle got deleted -if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore -if (underwater _vehicle) exitWith {}; - -private _magazineIndex = floor random(count _magazines); -private _magazine = _magazines select _magazineIndex; -_magazine params ["_magazineClassname", "_amountOfMagazines"]; - -if (_amountOfMagazines > 0) exitWith { - private _removed = _amountOfMagazines min floor(1 + random(6 / GVAR(ammoCookoffDuration))); - - _amountOfMagazines = _amountOfMagazines - _removed; - if (_amountOfMagazines <= 0) then { - _magazines deleteAt _magazineIndex; - } else { - _magazine set [1, _amountOfMagazines]; // clear out the magazine - }; - private _timeBetweenAmmoDetonation = (((random 10) / (sqrt _totalAmmo)) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; - TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); - _totalAmmo = _totalAmmo - _removed; - - private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo"); - private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; - - private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed"); - private _simType = getText (_ammoCfg >> "simulation"); - - private _effect2pos = _vehicle selectionPosition "destructionEffect2"; - - private _spawnProjectile = { - params ["_vehicle", "_ammo", "_speed", "_flyAway"]; - - private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3]; - if (_spawnPos select 2 < 0) then { - _spawnPos set [2, 0]; - }; - - private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; - if (_flyAway) then { - private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)]; - private _velVec = _vectorAmmo vectorMultiply _speed; - _projectile setVectorDir _velVec; - _projectile setVelocity _velVec; - } else { - _projectile setDamage 1; - }; - - _projectile; - }; - - private _speed = random (_speedOfAmmo / 10) max 1; - - if (toLower _simType == "shotbullet") then { - private _sound = selectRandom [QUOTE(PATHTO_R(sounds\light_crack_close.wss)), QUOTE(PATHTO_R(sounds\light_crack_close_filtered.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))]; - playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1250]; - - if (random 1 < 0.6) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - if (toLower _simType == "shotshell") then { - private _sound = selectRandom [QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))]; - playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1300]; - - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - if (toLower _simType == "shotgrenade") then { - if (random 1 < 0.9) then { - _speed = 0; - }; - [_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile; - }; - if (toLower _simType in ["shotrocket", "shotmissile", "shotsubmunitions"]) then { - if (random 1 < 0.1) then { - private _sound = selectRandom [QUOTE(PATHTO_R(sounds\cannon_crack_close.wss)), QUOTE(PATHTO_R(sounds\cannon_crack_close_filtered.wss))]; - playSound3D [_sound, objNull, false, (getPosASL _vehicle), 3, 1, 1600]; - - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - } else { - createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - if (toLower _simType in ["shotdirectionalbomb", "shotmine"]) then { - if (random 1 < 0.5) then { - // Not all explosives detonate on destruction, some have scripted alternatives - private _scripted = getNumber (_ammoCfg >> "triggerWhenDestroyed") == 1; - if !(_scripted) then { - _ammo = getText (_ammoCfg >> "ace_explosives_Explosive"); - }; - - // If a scripted alternative doesn't exist use generic explosion - if (_ammo != "") then { - [_vehicle, _ammo, 0, false] call _spawnProjectile; - } else { - createvehicle ["SmallSecondary", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - }; - if (toLower _simType == "shotilluminating") then { - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - }; - }; - - [FUNC(detonateAmmunition), [_vehicle, _magazines, _totalAmmo], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; -}; -ERROR_1("mag with no ammo - %1", _magazine); diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf new file mode 100644 index 0000000000..43ac730e09 --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf @@ -0,0 +1,54 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Starts detonating ammunition from an object (e.g. vehicle or crate). + * + * Arguments: + * 0: Object + * 1: Destroy when finished (default: false) + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Initial delay (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_cookoff_fnc_detonateAmmunitionServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_object", ["_destroyWhenFinished", false], ["_source", objNull], ["_instigator", objNull], ["_initialDelay", 0]]; + +if (isNull _object) exitWith {}; + +// Check if the object can cook its ammo off +if ( + underwater _object || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith {}; + +// Don't have an object detonate its ammo twice +if (_object getVariable [QGVAR(isAmmoDetonating), false]) exitWith {}; + +_object setVariable [QGVAR(isAmmoDetonating), true, true]; + +_object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)]; + +// TODO: When setMagazineTurretAmmo and magazineTurretAmmo are fixed (https://feedback.bistudio.com/T79689), +// we can add gradual ammo removal during cook-off +if (GVAR(removeAmmoDuringCookoff)) then { + clearMagazineCargoGlobal _object; + + { + [QEGVAR(common,removeMagazinesTurret), [_object, _x select 0, _x select 1], _object, _x select 1] call CBA_fnc_turretEvent; + } forEach (magazinesAllTurrets _object); +}; + +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _initialDelay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf new file mode 100644 index 0000000000..7fdcedda51 --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf @@ -0,0 +1,181 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, johnb43 + * Detonates ammunition from an object (e.g. vehicle or crate) until no ammo is left. + * + * Arguments: + * 0: Object + * 1: Destroy when finished + * 2: Source + * 3: Instigator + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, player, player] call ace_cookoff_fnc_detonateAmmunitionServerLoop + * + * Public: No + */ + +params ["_object", "_destroyWhenFinished", "_source", "_instigator"]; + +if (isNull _object) exitWith {}; + +(_object getVariable QGVAR(cookoffMagazines)) params ["_magazines", "_totalAmmo"]; + +private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []}; + +// If the cook-off has finished or been interrupted, clean up the effects for boxes (no vehicle effects) +if ( + _hasFinished || + {underwater _object} || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith { + // Box cook-off fire ends after the ammo has detonated (vehicle cook-off fire does not depend on the ammo detonation) + if (_object isKindOf "ReammoBox_F") then { + [QGVAR(cleanupEffects), _object] call CBA_fnc_globalEvent; + + // Reset variable, so the box can cook-off again + _object setVariable [QGVAR(isCookingOff), nil, true]; + + // Remove cook-off effects from box + private _jipID = _object getVariable QGVAR(cookoffBoxJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _object setVariable [QGVAR(cookoffBoxJipID), nil]; + }; + + // Reset variables, so the object can detonate its ammo again + _object setVariable [QGVAR(cookoffMagazines), nil]; + _object setVariable [QGVAR(isAmmoDetonating), nil, true]; + + // If done, destroy the object if necessary + if (_hasFinished && _destroyWhenFinished) then { + _object setDamage [1, true, _source, _instigator]; + }; +}; + +private _magazineIndex = floor random (count _magazines); +private _magazine = _magazines select _magazineIndex; +_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile"]; + +// Make sure ammo is at least 0 +_ammoCount = _ammoCount max 0; + +// Remove some ammo, which will be detonated +private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration))); + +_ammoCount = _ammoCount - _removed; + +if (_ammoCount <= 0) then { + _magazines deleteAt _magazineIndex; +} else { + _magazine set [1, _ammoCount]; // remove ammo that was detonated +}; + +private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; +TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); +_totalAmmo = _totalAmmo - _removed; + +_object setVariable [QGVAR(cookoffMagazines), [_magazines, _totalAmmo]]; + +// Get magazine info, which is used to spawn projectiles +private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname; +private _ammo = getText (_configMagazine >> "ammo"); +private _configAmmo = configFile >> "CfgAmmo" >> _ammo; + +private _simType = toLower getText (_configAmmo >> "simulation"); +private _speed = linearConversion [0, 1, random 1, 1, 20, true]; +private _effect2pos = _object selectionPosition "destructionEffect2"; + +// Spawns the projectiles, making them either fly in random directions or explode +private _fnc_spawnProjectile = { + // If the magazines are inside of the cargo (inventory), don't let their projectiles escape the interior of the vehicle + if (!_spawnProjectile) exitWith {}; + + params ["_object", "_ammo", "_speed", "_flyAway"]; + + private _spawnPos = _object modelToWorld [-0.2 + random 0.4, -0.2 + random 0.4, random 3]; + + if (_spawnPos select 2 < 0) then { + _spawnPos set [2, 0]; + }; + + private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; + + if (_flyAway) then { + private _vectorAmmo = [-1 + random 2, -1 + random 2, -0.2 + random 1]; + private _vectorVelocity = _vectorAmmo vectorMultiply _speed; + + _projectile setVectorDir _vectorVelocity; + _projectile setVelocity _vectorVelocity; + } else { + _projectile setDamage 1; + }; +}; + +switch (_simType) do { + case "shotbullet": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.6) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotshell": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.15) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotgrenade": { + if (random 1 < 0.9) then { + _speed = 0; + }; + + [_object, _ammo, _speed, random 1 < 0.5] call _fnc_spawnProjectile; + }; + case "shotrocket"; + case "shotmissile"; + case "shotsubmunitions": { + if (random 1 < 0.1) then { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + } else { + createVehicle ["ACE_ammoExplosionLarge", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + case "shotdirectionalbomb"; + case "shotmine": { + if (random 1 < 0.5) then { + // Not all explosives detonate on destruction, some have scripted alternatives + if (getNumber (_configAmmo >> "triggerWhenDestroyed") != 1) then { + _ammo = getText (_configAmmo >> QEGVAR(explosives,explosive)); + }; + + // If a scripted alternative doesn't exist use generic explosion + if (_ammo != "") then { + [_object, _ammo, 0, false] call _fnc_spawnProjectile; + } else { + createVehicle ["SmallSecondary", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + }; + case "shotilluminating": { + if (random 1 < 0.15) then { + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + }; + }; +}; + +// Detonate the remaining ammo after a delay +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_engineFire.sqf b/addons/cookoff/functions/fnc_engineFire.sqf deleted file mode 100644 index 6ed6920b7c..0000000000 --- a/addons/cookoff/functions/fnc_engineFire.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Start fire in engine block of a car. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * (vehicle player) call ace_cookoff_fnc_engineFire - * - * Public: No - */ - -params ["_vehicle"]; - -if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; -_vehicle setVariable [QGVAR(isEngineSmoking), true]; - -if (local _vehicle) then { - [QGVAR(engineFire), _vehicle] call CBA_fnc_remoteEvent; -}; - -private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset)); - -if (_offset isEqualTo []) then { - _offset = [0,0,0]; -}; - -private _position = [ - 0, - (boundingBoxReal _vehicle select 1 select 1) - 2, - (boundingBoxReal _vehicle select 0 select 2) + 2 -] vectorAdd _offset; - -private _smoke = "#particlesource" createVehicleLocal [0,0,0]; -_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; -_smoke attachTo [_vehicle, _position]; - -[{ - (_this select 0) params ["_vehicle", "_smoke", "_time"]; - - if (!alive _vehicle || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then { - deleteVehicle _smoke; - _vehicle setVariable [QGVAR(isEngineSmoking), false]; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; -}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireLocal.sqf b/addons/cookoff/functions/fnc_engineFireLocal.sqf new file mode 100644 index 0000000000..afd6827d6b --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireLocal.sqf @@ -0,0 +1,81 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * 1: End time + * + * Return Value: + * None + * + * Example: + * [cursorObject, CBA_missionTime + 10] call ace_cookoff_fnc_engineFireLocal + * + * Public: No + */ + +params ["_vehicle", "_endTime"]; + +// For JIP players and if the time wasn't set properly +if (_endTime < CBA_missionTime) exitWith {}; + +private _smoke = objNull; + +if (hasInterface) then { + private _hitPoints = getAllHitPointsDamage _vehicle; + + // Get hitpoint for engine + private _index = (_hitPoints select 0) findIf {_x == "hitengine"}; + + // Get corresponding selection + private _position = if (_index != -1) then { + _vehicle selectionPosition [(_hitPoints select 1) select _index, "HitPoints", "AveragePoint"] + } else { + [0, 0, 0] + }; + + if (_position isEqualTo [0, 0, 0]) then { + // Get offset for engine smoke if there is one + private _offset = getArray (configOf _vehicle >> QGVAR(engineSmokeOffset)); + + if (_offset isEqualTo []) then { + _offset = [0, 0, 0]; + }; + + _position = [ + 0, + (boundingBoxReal _vehicle select 1 select 1) - 2, + (boundingBoxReal _vehicle select 0 select 2) + 2 + ] vectorAdd _offset; + }; + + // Spawn smoke + _smoke = createVehicleLocal ["#particlesource", ASLToAGL getPosASL _vehicle, [], 0, "CAN_COLLIDE"];; + _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; + _smoke attachTo [_vehicle, _position]; +}; + +[{ + (_this select 0) params ["_vehicle", "_smoke", "_endTime"]; + + if (alive _vehicle && {_vehicle getHitPointDamage "HitEngine" >= 0.9} && {CBA_missionTime < _endTime}) exitWith {}; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _smoke; + + if (!isServer || {isNull _vehicle}) exitWith {}; + + // Reset variable, so engine can smoke again in the future + _vehicle setVariable [QGVAR(isEngineSmoking), nil, true]; + + private _jipID = _vehicle getVariable QGVAR(engineFireJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _vehicle setVariable [QGVAR(engineFireJipID), nil]; +}, 5, [_vehicle, _smoke, _endTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireServer.sqf b/addons/cookoff/functions/fnc_engineFireServer.sqf new file mode 100644 index 0000000000..0d435029b8 --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireServer.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_engineFireServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_vehicle"]; + +// If already smoking, stop +if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isEngineSmoking), true, true]; + +// Spawn engine fire effects on all connected machines +private _jipID = [QGVAR(engineFireLocal), [_vehicle, CBA_missionTime + random [ENGINE_FIRE_TIME / 2, ENGINE_FIRE_TIME, ENGINE_FIRE_TIME / 2 * 3]]] call CBA_fnc_globalEventJIP; +[_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +_vehicle setVariable [QGVAR(engineFireJipID), _jipID]; + +// API +[QGVAR(engineFire), [_vehicle]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf index 810084fe71..df4385d30d 100644 --- a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -1,61 +1,77 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Gets all magazines inside of a vehicle. + * Gets all magazines inside of an object. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: - * 0: Ammo Array - * 0: Magazine Classname - * 1: Ammo Count - * 1: Total Ammo Count + * 0: Ammo array + * - 0: Magazine classname + * - 1: Ammo count + * - 2: If a projectile should be spawned upon detonation + * 1: Total ammo count * * Example: - * [vehicle player] call ace_cookoff_fnc_getVehicleAmmo + * cursorObject call ace_cookoff_fnc_getVehicleAmmo * * Public: No */ -params ["_vehicle"]; -TRACE_1("getVehicleAmmo",_vehicle); +params ["_object"]; +TRACE_1("getVehicleAmmo",_object); private _ammoToDetonate = []; private _totalAmmo = 0; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _ammo = ""; // Get ammo from turrets { - _x params ["_mag", "", "_count"]; - if (_count > 0) then { - private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo"); - private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model"); - if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);}; - _ammoToDetonate pushBack [_mag, _count]; + // If the turret is an FFV seat, it takes magazines from the soldier + _x params ["_magazine", "", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammo = getText (_cfgMagazines >> _magazine >> "ammo"); + + if (getText (_cfgAmmo >> _ammo >> "model") == "\A3\weapons_f\empty") then { + TRACE_2("skipping",_magazine,_ammo); + + continue; + }; + + _ammoToDetonate pushBack [_magazine, _count, true]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAllTurrets _vehicle); +} forEach (magazinesAllTurrets [_object, true]); // Get ammo from cargo space { - _x params ["_mag", "_count"]; - if (_count > 0) then { - _ammoToDetonate pushBack [_mag, _count]; + _x params ["_magazine", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammoToDetonate pushBack [_magazine, _count, false]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAmmoCargo _vehicle); +} forEach (magazinesAmmoCargo _object); // Get ammo from transportAmmo / ace_rearm -private _vehCfg = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _configVehicle = configOf _object; +private _configSupply = (getNumber (_configVehicle >> "transportAmmo")) max (getNumber (_configVehicle >> QEGVAR(rearm,defaultSupply))); -private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply))); -if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then { - TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle); +if (_object getVariable [QEGVAR(rearm,isSupplyVehicle), _configSupply > 0]) then { + TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _object); - _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000]; + _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000, false]; _totalAmmo = _totalAmmo + 2000; - _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100]; + + _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100, true]; _totalAmmo = _totalAmmo + 100; + + _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10, true]; + _totalAmmo = _totalAmmo + 10; }; [_ammoToDetonate, _totalAmmo] diff --git a/addons/cookoff/functions/fnc_handleDamage.sqf b/addons/cookoff/functions/fnc_handleDamage.sqf deleted file mode 100644 index e9765805cb..0000000000 --- a/addons/cookoff/functions/fnc_handleDamage.sqf +++ /dev/null @@ -1,129 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Handles all incoming damage for tanks (including wheeled APCs). - * - * Arguments: - * HandleDamage EH - * - * Return Value: - * Damage to be inflicted. - * - * Example: - * _this call ace_cookoff_fnc_handleDamage - * - * Public: No - */ - -params ["_simulationType", "_thisHandleDamage"]; -_thisHandleDamage params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"]; - -// it's already dead, who cares? -if (damage _vehicle >= 1) exitWith {}; - -// get hitpoint name -private _hitpoint = "#structural"; - -if (_hitIndex != -1) then { - _hitpoint = toLower ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); -}; - -// get change in damage -private _oldDamage = 0; - -if (_hitpoint isEqualTo "#structural") then { - _oldDamage = damage _vehicle; -} else { - _oldDamage = _vehicle getHitIndex _hitIndex; -}; - -private _newDamage = _damage - _oldDamage; - -// handle different types of vehicles -// note: exitWith only works here, because this is not the main scope of handleDamage -// you cannot use the return value together with exitWith in the main scope, it's a bug -// also, we add this event handler with the addEventHandler SQF command, -// because the config version ignores the return value completely -if (_simulationType == "car") exitWith { - // prevent destruction, let cook-off handle it if necessary - if (_hitpoint in ["hithull", "hitfuel", "#structural"] && {!IS_EXPLOSIVE_AMMO(_ammo)}) then { - _damage min 0.89 - } else { - if (_hitpoint isEqualTo "hitengine" && {_damage > 0.9}) then { - _vehicle call FUNC(engineFire); - }; - _damage - }; -}; - -if (_simulationType == "tank") exitWith { - // determine ammo storage location - private _ammoLocationHitpoint = getText (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ammoLocation)); - - if (_hitIndex in (GVAR(cacheTankDuplicates) getVariable (typeOf _vehicle))) then { - _hitpoint = "#subturret"; - }; - - // ammo was hit, high chance for cook-off - if (_hitpoint == _ammoLocationHitpoint) then { - if (_damage > 0.5) then { - // get cookoff probability for vehicle - private _probability = [_vehicle call CBA_fnc_getObjectConfig >> QGVAR(probability), "number", 0.7] call CBA_fnc_getConfigEntry; - // probability multiplied by coef for global probability control (higher coef = more probable cookoff) - if (GVAR(probabilityCoef) > 1) then { - _probability = 1 - (1 - _probability) / GVAR(probabilityCoef); - } else { - _probability = _probability * GVAR(probabilityCoef); - }; - if (random 1 < _probability) then { - _vehicle call FUNC(cookOff); - }; - }; - } else { - if (_hitpoint in ["hithull", "hitturret", "#structural"] && {_newDamage > 0.8 + random 0.2}) then { - if ((_hitpoint == "hitturret") && {(getNumber (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ignoreTurret))) == 1}) exitWith {}; // ignore turrets like RCWS - _vehicle setDamage 1; - }; - }; - - // prevent destruction, let cook-off handle it if necessary - if (_hitpoint in ["hithull", "hitfuel", "#structural"]) then { - _damage min 0.89 - } else { - _damage - }; -}; - -if (_simulationType == "box") exitWith { - if (_hitpoint == "#structural" && _damage > 0.5) then { - // Almost always catch fire when hit by an explosive - if (IS_EXPLOSIVE_AMMO(_ammo)) then { - _vehicle call FUNC(cookOffBox); - } else { - // Need magazine to check for tracers - private _mag = ""; - if (_source == _shooter) then { - _mag = currentMagazine _source; - } else { - _mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath); - }; - private _magCfg = configFile >> "CfgMagazines" >> _mag; - - // Magazine could have changed during flight time (just ignore if so) - if (getText (_magCfg >> "ammo") == _ammo) then { - // If magazine's tracer density is high enough then low chance for cook off - private _tracers = getNumber (_magCfg >> "tracersEvery"); - if (_tracers >= 1 && {_tracers <= 4}) then { - if (random 1 < _oldDamage*0.05) then { - _vehicle call FUNC(cookOffBox); - }; - }; - }; - }; - - // prevent destruction, let cook-off handle it if necessary - _damage min 0.89 - } else { - _damage - }; -}; diff --git a/addons/cookoff/functions/fnc_handleDamageBox.sqf b/addons/cookoff/functions/fnc_handleDamageBox.sqf new file mode 100644 index 0000000000..2d55db0fd0 --- /dev/null +++ b/addons/cookoff/functions/fnc_handleDamageBox.sqf @@ -0,0 +1,62 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Handles all incoming damage for boxes. + * + * Arguments: + * HandleDamage EH + * + * Return Value: + * Damage to be inflicted (can be nil) + * + * Example: + * _this call ace_cookoff_fnc_handleDamageBox + * + * Public: No + */ + +// If cookoff for boxes is disabled, exit +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + +params ["_box", "", "_damage", "_source", "_ammo", "", "_instigator", "_hitPoint"]; + +if (!local _box) exitWith {}; + +// If it's already dead, ignore +if (!alive _box) exitWith {}; + +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +if !(_hitPoint == "" && {_damage > 0.5}) exitWith {}; // "" means structural damage + +private _ammoConfig = _ammo call CBA_fnc_getObjectConfig; + +// Catch fire when hit by an explosive or incendiary round +if ((getNumber (_ammoConfig >> "explosive") >= 0.5) || {getNumber (_ammoConfig >> QEGVAR(vehicle_damage,incendiary)) > random 1}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; +} else { + // There is a small chance of cooking a box off if it's shot by tracer ammo + if (random 1 >= _damage * 0.05) exitWith {}; + + // Need magazine to check for tracers + private _magazine = if (_source == _instigator) then { + currentMagazine _source + } else { + _source currentMagazineTurret (_source unitTurret _instigator) + }; + + private _configMagazine = configFile >> "CfgMagazines" >> _magazine; + + // Magazine could have changed during flight time (just ignore if so) + if (getText (_configMagazine >> "ammo") == _ammo) then { + // If magazine's tracer density is high enough then low chance for cook off + private _tracers = getNumber (_configMagazine >> "tracersEvery"); + + if (_tracers >= 1 && {_tracers <= 4}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; + }; + }; +}; + +// Prevent destruction, let cook-off handle it if necessary +_damage min 0.89 diff --git a/addons/cookoff/functions/fnc_isMagazineFlare.sqf b/addons/cookoff/functions/fnc_isMagazineFlare.sqf new file mode 100644 index 0000000000..f856b21a9a --- /dev/null +++ b/addons/cookoff/functions/fnc_isMagazineFlare.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Cyruz + * Checks if the magazine's ammo are flares. + * + * Arguments: + * 0: Magazine + * + * Return Value: + * If magazine is type of flare + * + * Example: + * "3Rnd_UGL_FlareWhite_F" call ace_cookoff_fnc_isMagazineFlare + * + * Public: No + */ + +params ["_magazine"]; + +private _configAmmo = configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); + +getNumber (_configAmmo >> "intensity") != 0 || {getNumber (_configAmmo >> QEGVAR(grenades,flare)) == 1} diff --git a/addons/cookoff/functions/fnc_smoke.sqf b/addons/cookoff/functions/fnc_smoke.sqf new file mode 100644 index 0000000000..94055041de --- /dev/null +++ b/addons/cookoff/functions/fnc_smoke.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Starts vehicle barrel smoke effect. + * + * Arguments: + * 0: Vehicle + * 1: Selections for smoke to come out of + * + * Return Value: + * None + * + * Example: + * [vehicle player, ["commander_turret"]] call ace_cookoff_fnc_smoke + * + * Public: No + */ + +params ["_vehicle", "_selections"]; + +private _positionBarrelEnd = getText ([_vehicle, [0]] call CBA_fnc_getTurret >> "gunBeg"); + +// Smoke out of cannon and hatches +private _smokeBarrel = "#particlesource" createVehicleLocal [0, 0, 0]; +_smokeBarrel setParticleClass "MediumDestructionSmoke"; +_smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; + +private _effects = [_smokeBarrel]; + +{ + private _position = if (_x != "#noselection") then { + _vehicle selectionPosition _x + } else { + [0, -2, 0] + }; + + private _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; + _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; + _smoke attachTo [_vehicle, _position]; + + _effects pushBack _smoke; +} forEach _selections; + +_vehicle setVariable [QGVAR(effects), _effects]; diff --git a/addons/cookoff/functions/script_component.hpp b/addons/cookoff/functions/script_component.hpp deleted file mode 100644 index d72f77978f..0000000000 --- a/addons/cookoff/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\cookoff\script_component.hpp" diff --git a/addons/cookoff/initSettings.inc.sqf b/addons/cookoff/initSettings.inc.sqf new file mode 100644 index 0000000000..c7f1be8ffd --- /dev/null +++ b/addons/cookoff/initSettings.inc.sqf @@ -0,0 +1,71 @@ +[ + QGVAR(enableFire), + "CHECKBOX", + [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(cookoffDuration), + "SLIDER", + [LSTRING(cookoffDuration_name), LSTRING(cookoffDuration_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(probabilityCoef), + "SLIDER", + [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(destroyVehicleAfterCookoff), + "CHECKBOX", + [LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)], + LSTRING(category_displayName), + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableAmmoCookoff), + "CHECKBOX", + [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableAmmobox), + "CHECKBOX", + [LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(ammoCookoffDuration), + "SLIDER", + [LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(removeAmmoDuringCookoff), + "CHECKBOX", + [LSTRING(removeAmmoDuringCookoff_name), LSTRING(removeAmmoDuringCookoff_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/cookoff/initSettings.sqf b/addons/cookoff/initSettings.sqf deleted file mode 100644 index b29d213427..0000000000 --- a/addons/cookoff/initSettings.sqf +++ /dev/null @@ -1,51 +0,0 @@ -// CBA Settings [ADDON: ace_cookoff]: - -[ - QGVAR(enable), "CHECKBOX", - [LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)], - LSTRING(category_displayName), - false, // default value - true, // isGlobal - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(enableAmmobox), "CHECKBOX", - [LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmobox), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(enableAmmoCookoff), "CHECKBOX", - [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(ammoCookoffDuration), "SLIDER", - [LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)], - LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(ammoCookoffDuration), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(probabilityCoef), "SLIDER", - [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], - LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(probabilityCoef), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index 5daa0e8330..bf8fd62dd5 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -16,14 +16,22 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) - // Stages of cookoff in order (in seconds) -// Should be no un-synced randomness in these as the effects must be ran on each client -#define IGNITE_TIME 3 -#define SMOKE_TIME 10.5 +// Should be no un-synced randomness in these as the effects must be run on each client +#define SMOKE_DELAY 10.5 +#define DETONATION_DELAY 3 #define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files -#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn +#define ENGINE_FIRE_TIME 240 +#define MIN_TIME_BETWEEN_FLAMES 5 +#define MAX_TIME_BETWEEN_FLAMES 15 +#define MAX_TIME_BETWEEN_AMMO_DET 25 +#define MAX_COOKOFF_INTENSITY 10 -// Delay between flame effect for players in a cooking off vehicle -#define FLAME_EFFECT_DELAY 0.4 +#define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff +#define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff + +// Common commander hatch defines for default vehicles +#define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"] + +#define DISTANCE_CLOSE 235 +#define DISTANCE_MID 952 diff --git a/addons/cookoff/sounds/cannon_crack_close.wss b/addons/cookoff/sounds/cannon_crack_close.wss deleted file mode 100644 index b45ea96ab0..0000000000 Binary files a/addons/cookoff/sounds/cannon_crack_close.wss and /dev/null differ diff --git a/addons/cookoff/sounds/cannon_crack_close_filtered.wss b/addons/cookoff/sounds/cannon_crack_close_filtered.wss deleted file mode 100644 index 4ddb18539b..0000000000 Binary files a/addons/cookoff/sounds/cannon_crack_close_filtered.wss and /dev/null differ diff --git a/addons/cookoff/sounds/heavy_crack_close.wss b/addons/cookoff/sounds/heavy_crack_close.wss deleted file mode 100644 index 95cc68d90e..0000000000 Binary files a/addons/cookoff/sounds/heavy_crack_close.wss and /dev/null differ diff --git a/addons/cookoff/sounds/heavy_crack_close_filtered.wss b/addons/cookoff/sounds/heavy_crack_close_filtered.wss deleted file mode 100644 index 1b4520cd4a..0000000000 Binary files a/addons/cookoff/sounds/heavy_crack_close_filtered.wss and /dev/null differ diff --git a/addons/cookoff/sounds/light_crack_close.wss b/addons/cookoff/sounds/light_crack_close.wss deleted file mode 100644 index ef284f24ef..0000000000 Binary files a/addons/cookoff/sounds/light_crack_close.wss and /dev/null differ diff --git a/addons/cookoff/sounds/light_crack_close_filtered.wss b/addons/cookoff/sounds/light_crack_close_filtered.wss deleted file mode 100644 index b1c76fa8ed..0000000000 Binary files a/addons/cookoff/sounds/light_crack_close_filtered.wss and /dev/null differ diff --git a/addons/cookoff/sounds/shotbullet/close_1.wss b/addons/cookoff/sounds/shotbullet/close_1.wss new file mode 100644 index 0000000000..19f07503bf Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/close_1.wss differ diff --git a/addons/cookoff/sounds/shotbullet/close_2.wss b/addons/cookoff/sounds/shotbullet/close_2.wss new file mode 100644 index 0000000000..bf83c29599 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/close_2.wss differ diff --git a/addons/cookoff/sounds/shotbullet/close_3.wss b/addons/cookoff/sounds/shotbullet/close_3.wss new file mode 100644 index 0000000000..dcf4198acd Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/close_3.wss differ diff --git a/addons/cookoff/sounds/shotbullet/far_1.wss b/addons/cookoff/sounds/shotbullet/far_1.wss new file mode 100644 index 0000000000..07cd30e15b Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/far_1.wss differ diff --git a/addons/cookoff/sounds/shotbullet/far_2.wss b/addons/cookoff/sounds/shotbullet/far_2.wss new file mode 100644 index 0000000000..795581517a Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/far_2.wss differ diff --git a/addons/cookoff/sounds/shotbullet/far_3.wss b/addons/cookoff/sounds/shotbullet/far_3.wss new file mode 100644 index 0000000000..d7e5538150 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/far_3.wss differ diff --git a/addons/cookoff/sounds/shotbullet/mid_1.wss b/addons/cookoff/sounds/shotbullet/mid_1.wss new file mode 100644 index 0000000000..b02a481b42 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/mid_1.wss differ diff --git a/addons/cookoff/sounds/shotbullet/mid_2.wss b/addons/cookoff/sounds/shotbullet/mid_2.wss new file mode 100644 index 0000000000..1e184cc1ef Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/mid_2.wss differ diff --git a/addons/cookoff/sounds/shotbullet/mid_3.wss b/addons/cookoff/sounds/shotbullet/mid_3.wss new file mode 100644 index 0000000000..10606bf138 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/mid_3.wss differ diff --git a/addons/cookoff/sounds/shotrocket/close_1.wss b/addons/cookoff/sounds/shotrocket/close_1.wss new file mode 100644 index 0000000000..31ff1cbe38 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/close_1.wss differ diff --git a/addons/cookoff/sounds/shotrocket/close_2.wss b/addons/cookoff/sounds/shotrocket/close_2.wss new file mode 100644 index 0000000000..8ef09dcf04 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/close_2.wss differ diff --git a/addons/cookoff/sounds/shotrocket/close_3.wss b/addons/cookoff/sounds/shotrocket/close_3.wss new file mode 100644 index 0000000000..5410c359e4 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/close_3.wss differ diff --git a/addons/cookoff/sounds/shotrocket/far_1.wss b/addons/cookoff/sounds/shotrocket/far_1.wss new file mode 100644 index 0000000000..e71990476b Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/far_1.wss differ diff --git a/addons/cookoff/sounds/shotrocket/far_2.wss b/addons/cookoff/sounds/shotrocket/far_2.wss new file mode 100644 index 0000000000..bae24fa78e Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/far_2.wss differ diff --git a/addons/cookoff/sounds/shotrocket/far_3.wss b/addons/cookoff/sounds/shotrocket/far_3.wss new file mode 100644 index 0000000000..093e841277 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/far_3.wss differ diff --git a/addons/cookoff/sounds/shotrocket/mid_1.wss b/addons/cookoff/sounds/shotrocket/mid_1.wss new file mode 100644 index 0000000000..f927d7f174 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/mid_1.wss differ diff --git a/addons/cookoff/sounds/shotrocket/mid_2.wss b/addons/cookoff/sounds/shotrocket/mid_2.wss new file mode 100644 index 0000000000..785dd5b603 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/mid_2.wss differ diff --git a/addons/cookoff/sounds/shotrocket/mid_3.wss b/addons/cookoff/sounds/shotrocket/mid_3.wss new file mode 100644 index 0000000000..7fb384421d Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/mid_3.wss differ diff --git a/addons/cookoff/sounds/shotshell/close_1.wss b/addons/cookoff/sounds/shotshell/close_1.wss new file mode 100644 index 0000000000..aa9a0bc718 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/close_1.wss differ diff --git a/addons/cookoff/sounds/shotshell/close_2.wss b/addons/cookoff/sounds/shotshell/close_2.wss new file mode 100644 index 0000000000..355d061d01 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/close_2.wss differ diff --git a/addons/cookoff/sounds/shotshell/close_3.wss b/addons/cookoff/sounds/shotshell/close_3.wss new file mode 100644 index 0000000000..3847fa870f Binary files /dev/null and b/addons/cookoff/sounds/shotshell/close_3.wss differ diff --git a/addons/cookoff/sounds/shotshell/far_1.wss b/addons/cookoff/sounds/shotshell/far_1.wss new file mode 100644 index 0000000000..262b037c12 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/far_1.wss differ diff --git a/addons/cookoff/sounds/shotshell/far_2.wss b/addons/cookoff/sounds/shotshell/far_2.wss new file mode 100644 index 0000000000..38e0e1eb81 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/far_2.wss differ diff --git a/addons/cookoff/sounds/shotshell/far_3.wss b/addons/cookoff/sounds/shotshell/far_3.wss new file mode 100644 index 0000000000..781f86e4b8 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/far_3.wss differ diff --git a/addons/cookoff/sounds/shotshell/mid_1.wss b/addons/cookoff/sounds/shotshell/mid_1.wss new file mode 100644 index 0000000000..76c68cdee1 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/mid_1.wss differ diff --git a/addons/cookoff/sounds/shotshell/mid_2.wss b/addons/cookoff/sounds/shotshell/mid_2.wss new file mode 100644 index 0000000000..f84b579bc4 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/mid_2.wss differ diff --git a/addons/cookoff/sounds/shotshell/mid_3.wss b/addons/cookoff/sounds/shotshell/mid_3.wss new file mode 100644 index 0000000000..990a583a04 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/mid_3.wss differ diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 452b213fe9..15d2d2adec 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -2,137 +2,168 @@ - ACE Cook off - ACE Esplosione + ACE Cook-off + ACE Detonación inducida por calor + ACE Esplosioni di Munizioni ACE 殉爆效果 ACE 殉爆效果 ACE 誘爆 - ACE 쿡오프 + ACE 유폭 ACE Durchzündung - ACE Cook off + ACE Auto-inflammation ACE Samozapłon - ACE Возгорание + ACE Детонация + ACE Cook off + ACE Vznícení munice - - Damage handling and turret effects - Schadensberechnung und Geschützturmeffekte - 損傷処理と砲塔の効果 - Обработка урона и эффектов срыва башни + + Enable vehicle cook-off fire + 車両の誘爆火災を有効化 + Вкл. возгорание техники + 차량 유폭 화재를 활성화합니다 + Abilita incendio dei veicoli + Aktiviert Fahrzeug Munitionsbrand - - Changes damage handling for cook off and turret explosion effects - Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes - 誘爆の損傷処理と砲塔の爆発効果を変更します。 - Изменяет обработку урона для возгорания и эффекта срыва башни + + Enables vehicle cook-off fire effects.\nThis doesn't include ammunition detonations. + 車両の誘爆火災エフェクトを有効化します。\nこれには弾薬の爆発は含まれません。 + Вкл. эффект горения техники. \nНе включает детонацию боекомплекта + 차량 유폭 효과를 활성화합니다.\n여기엔 탄약 유폭이 포함되지 않습니다. + Abilita effetti di incendio del veicolo dovuto all'esplosione delle munizioni.\nQuesto non include gli effetti di esplosione. + Aktiviert Fahrzeug Brandeffekte durch Durchzündung.\nExplosionseffekte sind nicht mit einbegriffen. - - Wreck (Turret) - Épave (tourelle) - Restos (torreta) - Rottami (torretta) - Wrak (wieżyczka) - Обломки (башня) - Wrack (Geschützturm) - Vrak (věž) - Ruínas (torre) - 잔해(포탑) - 残骸 (砲塔) - 殘骸 (砲塔) - 残骸 (炮塔) + + Vehicle cook-off fire duration multiplier + 車両の誘爆火災の持続時間倍率 + Увел. продолжительности горения техники + 차량 유폭 화재 지속 시간 계수 + Coefficiente di durata incendio dei veicoli + Fahrzeugbrand Dauer-Multiplikator - - Enable ammo box cook off - 弾薬箱に誘爆を有効化 - Durchzündung für Munitionskisten ermöglichen - 탄약 상자 쿡오프 현상 활성화 - Aktywuj samozapłon skrzyń z amunicją - Cook off de caisses de munitions - Abilita esplosione cassa munizioni - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Разрешить возгорание ящиков с боеприпасами - - - Enables cooking off of ammo boxes. - 弾薬箱が誘爆するようになります。 - Ermöglicht Durchzündung von Munitionskisten. - 탄약 상자에 쿡오프 현상을 적용합니다. - Aktywuje samozapłon skrzyń z amunicją - Active le cook off sur toutes les caisses de munitions. - Abilita l'esplosione della cassa di munizioni. - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Активирует возгорание ящиков с боеприпасами - - - Enable Ammunition cook off - 弾薬の誘爆を有効化 - Durchzündung für Munition ermöglichen - 탄약 쿡오프 현상 활성화 - Aktywuj samozapłon amunicji - Activer le cook off des munitions - Abilita Esplosione munizioni - 開啟彈藥殉爆效果 - 开启弹药殉爆效果 - Разрешить детонацию боекомплекта - - - Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. - 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 - Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. - Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję. - Mets à feu les munitions lorsqu'un véhicule est en feu et contient des munitions. - Abilita l'esplosione delle munizioni. Spara munizioni di proiettili quando il veicolo va a fuoco e contiene munizioni. - 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果 - 开启弹药殉爆效果。当一台载有弹药的载具起火时, 将会有殉爆的效果。 - 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어있는 동안 주변에 발사체를 발사합니다. - Активирует возгорание и детонацию боекомплекта в горящей технике - - - Ammunition cook off duration - Munitionsdurchzündungsdauer - Czas trwania samozapłonu amunicji - 弾薬の誘爆持続時間 - Durée de cook off des munitions - Durata esplosione munizioni - 彈藥殉爆效果持續時間 - 弹药殉爆效果持续时间 - 쿡오프 지속 시간 - Длительность возгорания боеприпасов - - - Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] - Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren] - Multiplicateur de la durée du cook off des munitions [Une valeur de 0 désactive l'effet] - Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu] - 誘爆の持続時間を乗数で設定します。[0 に設定で誘爆を無効化] - Moltiplicatore della durata dell'esplosione [Impostare 0 disabiliterà l'esplosione delle munizioni] - 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] - 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] - 쿡오프 지속 시간의 배수 [0 이면 비활성] - Множитель длительности возгорания [0 - отключает возгорание боеприпасов] + + Multiplier for how long vehicle cook-off fire lasts.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災の持続時間をどのくらいの長さにするかの倍率。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. продолжительности горения техники. \nУстановка значения на 0 выключает возгорание техники. + 차량 유폭 화재가 지속되는 시간에 대한 계수입니다.\n0으로 설정하면 차량 쿸오프 화재가 비활성화됩니다. + Coefficiente di durata degli incendi dei veicoli.\nImpostarlo su 0 disabilita incendi dei veicoli. + Multiplikator der Fahrzeugbrand Dauer.\nIhn auf 0 zu setzen wird Munitionsbrände deaktivieren. - Cook-off probability coefficient - 誘爆の可能性係数 - Coefficiente probabilità esplosione - Faktor für Wahrscheinlichkeit der Durchzündung - 殉爆發生機率係數 - 殉爆发生机率系数 - Coefficient de probabilité du cook off - Współczynnik prawdopodobieństwa samozapłonu - Коэффициент вероятности возгорания + Vehicle cook-off fire probability multiplier + 車両の誘爆火災の可能性倍率 + Возможность усиления пожара при детонации техники + 차량 유폭 화재 확률 계수 + Probabilità di incendio dei veicoli + Fahrzeug Munitionsbrand Wahrscheinlichkeit-Multiplikator - Multiplier for cook-off probability. Higher value results in higher cook-off probability - 誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。 - Moltiplicatore per la probabilità dell'esplosione. Un valore più alto aumenta la probabilità dell'esplosione - Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit. - 調整殉爆發生機率係數。值越高代表越容易發生殉爆 - 调整殉爆发生机率系数。值越高代表越容易发生殉爆。 - Multiplicateur 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 - Множитель коэффициента вероятности возгорания. Чем выше значение, тем выше вероятность. + Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off probability.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災がどのくらいの可能性で発生するかの倍率。高い数値は高い誘爆の可能性につながります。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. вероятности возникновения возгорания техники. Большое значение указывает на высокую вероятность детонации. \nУстановка значения 0 предотвращает возгорание техники. + 차량 유폭 화재 확률에 대한 계수입니다. 값이 높을 수록 유폭 확률이 높아집니다.\n0으로 설정하면 차량 유폭 화재가 비활성화됩니다. + Coefficiente di probabilità degli incendi dei veicoli.\nValori maggiori aumentano la probabilità di incendi.\nImpostarlo su 0 disabilita incendi dei veicoli. + Multiplikator der Fahrzeugbrand Wahrscheinlichkeit.\nHöhere Werte erhöhen die Wahrscheinlichkeit.\nEin Null-Wert wird Munitionsbrände deaktivieren. + + + Destroy vehicles after cook-off + 유폭 후 차량 파괴 + 殉爆发生后摧毁载具 + Уничтожать технику после детонации + Destruir vehículos tras la detonación inducida por calor + 誘爆後に車両を破壊する + Zniszcz Pojazdy po Zakończeniu Samozapłonu + Zerstöre Fahrzeuge nach der Durchzündung + Distruggi Veicoli dopo Esplosione Munizioni + Destruction des véhicules après auto-inflammation + Destruir veículos após cozinhamento + + + Controls whether vehicles will always be destroyed after cooking off. + 誘爆の終了後に車両を必ず完全破壊するかどうかを設定します。 + Kontroluje, czy pojazdy będą zawsze niszczone po samozapłonie. + Steuert, ob Fahrzeuge nach dem Durchzünden immer zerstört werden. + Determina se veicoli saranno sempre distrutti dall'esplosione delle munizioni. + 유폭 후 차량이 항상 파괴되는지 여부를 조정합니다. + Contrôle si les véhicules seront toujours détruits après l'auto-inflammation. + Define se os veículos serão sempre destruídos após cozinhamento. + Определяет, всегда ли транспортные средства будут уничтожаться после детонации. + Controla si los vehículos siempre será destruidos despues de la detonación inducida por calor. + + + Enable vehicle ammo cook-off + 車両弾薬の誘爆を有効化 + Вкл. детонацию боеприпасов в технике. + 차량 내 탄약 유폭 활성화 + Abilita esplosioni delle munizioni dei veicoli + Aktiviert Fahrzeug Munitionsdurchzündung + + + Enables cooking off of vehicle ammunition. Fires ammunition projectiles while vehicle has ammunition remaining.\nThis doesn't include fire effects. + 車両弾薬の誘爆を有効化します。車両に積載されたままの弾薬と弾頭が発射されます。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию боеприпасов на технике. Боеприпасы и боеголовки, которые остаются заряженными на транспортном средстве, будут приведены в действие. \nЭто не включает эффекты пожара. + 차량 내 탄약 유폭을 활성화합니다. 차량에 탄약이 남아 있는 동안 탄약 발사체를 발사합니다.\n여기엔 화재 효과가 포함되지 않습니다. + Abilita l'esplosione delle munizioni dei veicoli. Spara via pezzi di munizioni se il veicolo ha ancora munizioni rimanenti.\nNon include gli effetti di fuoco. + Aktiviert Durchzündung von Fahrzeugmunition. Schleudert Munitionsfragmente umher wenn das Fahrzeug noch Munition an Bord hat.\nBrandeffekte sind nicht mit einbegriffen. + + + Enable ammo box cook-off + Habilitar detonación inducida por calor en las cajas de munición + 弾薬箱の誘爆を有効化 + Durchzündung für Munitionskisten ermöglichen + 탄약 상자 유폭 현상 활성화 + Aktywuj samozapłon skrzyń z amunicją + Auto-inflammation des caisses de munitions + Abilita esplosione casse munizioni + 開啟彈藥箱殉爆效果 + 开启弹药箱殉爆效果 + Разрешить детонацию ящиков с боеприпасами + Permitir cozinhar caixas de munição + Povolit vynícení munice v krabicích + + + Enables cooking off of ammo boxes.\nThis doesn't include fire effects. + 弾薬箱の誘爆を有効化します。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию ящика с боеприпасами. \nЭто не включает эффекты огня. + 탄약 상자 유폭을 활성화합니다.\n여기엔 화재 효과가 포함되지 않습니다. + Abilita esplosioni delle casse di munizioni.\nNon include effetti di fuoco. + Aktiviert Munitionskisten Durchzündung.\nBrandeffekte sind nicht mit einbegriffen. + + + Ammo cook-off duration multiplier + 弾薬の誘爆の持続時間倍率 + Увеличение продолжительности детонации боеприпасов. + 탄약 유폭 시간 계수 + Coefficiente di durata esplisioni di munizioni + Fahrzeug Munitionsdurchzündung Dauer-Multiplikator + + + Multiplier for how long ammunition cook-off lasts, for both vehicles and ammo boxes.\nSetting to 0 will disable ammo cook-off for both vehicles and ammo boxes. + 弾薬の誘爆の持続時間をどのくらいの長さにするかの倍率。車両弾薬と弾薬箱どちらにも影響します。\n0に設定すると弾薬の誘爆が無効化されます。 + Увеличение продолжительности детонации боеприпасов. Это влияет как на боеприпасы в технике, так и на ящики с боеприпасами. \nУстановка значения 0 отключает детонацию боеприпасов. + 차량과 탄약 상자 모두에 대해 탄약 유폭이 지속되는 시간에 대한 계수입니다.\n0으로 설정하면 차량과 탄약 상자 모두에 대해 탄약 유폭이 비활성화됩니다. + Coefficiente della durata di esplosioni delle munizioni, sia per veicoli che casse.\nImpostarlo su 0 disabilita esplosioni di veicoli e casse. + Multiplikator der Munitionsdurchzündungs-Dauer, gilt für Fahrzeuge und Munitionskisten.\nIhn auf 0 zu setzen wird Durchzünden deaktivieren. + + + Enable ammo removal during cook-off + 誘爆による弾薬の除去を有効化 + Retirer les munitions durant l'auto-inflammation + Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden + Abilita rimozione munizioni dopo l'esplosione + Włącz/Wyłącz usuwanie amunicji podczas samozapłonu + 启用/禁用殉爆过程中的弹药移除功能 + 유폭 시 탄약 제거 활성화/비활성화 + Вкл. удаление боеприпасов из-за детонации + Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor + + + Removes all ammo during cook-off. + Retire des munitions des véhicules durant une auto-inflammation. + Entfernt Munition während dem Durchzünden der Munition eines Fahrzeuges. + 誘爆によって全ての弾薬を除去します。 + Все боеприпасы уничтожаются путем подрыва. + 유폭 중 모든 탄약을 제거합니다. + Rimuovi le munizioni dal veicolo durante le esplosioni. diff --git a/addons/csw/Cfg3den.hpp b/addons/csw/Cfg3den.hpp deleted file mode 100644 index dfac0f5475..0000000000 --- a/addons/csw/Cfg3den.hpp +++ /dev/null @@ -1,38 +0,0 @@ -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 index afe6392a7c..2a3f71f852 100644 --- a/addons/csw/CfgEventHandlers.hpp +++ b/addons/csw/CfgEventHandlers.hpp @@ -1,15 +1,15 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE( call COMPILE_FILE(XEH_postInit) ); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/csw/CfgMagazineGroups.hpp b/addons/csw/CfgMagazineGroups.hpp index 697403f963..b3995210a2 100644 --- a/addons/csw/CfgMagazineGroups.hpp +++ b/addons/csw/CfgMagazineGroups.hpp @@ -74,7 +74,7 @@ class GVAR(groups) { 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; @@ -83,4 +83,3 @@ class GVAR(groups) { 1Rnd_GAA_missiles = 1; }; }; - diff --git a/addons/csw/CfgMagazines.hpp b/addons/csw/CfgMagazines.hpp index 6102fa48f4..86ad73c58f 100644 --- a/addons/csw/CfgMagazines.hpp +++ b/addons/csw/CfgMagazines.hpp @@ -9,6 +9,7 @@ class CfgMagazines { 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); @@ -19,6 +20,7 @@ class CfgMagazines { 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); @@ -29,6 +31,7 @@ class CfgMagazines { 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); @@ -50,7 +53,7 @@ class CfgMagazines { mass = 50; ACE_isBelt = 1; }; - + class 40Rnd_20mm_G_belt; class GVAR(20Rnd_20mm_G_belt): 40Rnd_20mm_G_belt { author = ECSTRING(common,ACETeam); diff --git a/addons/csw/CfgVehicles.hpp b/addons/csw/CfgVehicles.hpp index c1b8f11d3f..724d5ed513 100644 --- a/addons/csw/CfgVehicles.hpp +++ b/addons/csw/CfgVehicles.hpp @@ -4,7 +4,7 @@ class CfgVehicles { class ACE_SelfActions { class GVAR(deploy) { displayName = CSTRING(PlaceTripod_displayName); - condition = QUOTE(call FUNC(assemble_canDeployTripod)); + condition = QUOTE(call FUNC(canDeployTripod)); statement = QUOTE(call FUNC(assemble_deployTripod)); exceptions[] = {}; }; @@ -36,7 +36,7 @@ class CfgVehicles { condition = "true"; class GVAR(pickUp) { displayName = CSTRING(Pickup_displayName); - condition = QUOTE(call FUNC(assemble_canPickupTripod)); + condition = QUOTE(call FUNC(canPickupTripod)); statement = QUOTE(call FUNC(assemble_pickupTripod)); }; class GVAR(mountWeapon) { @@ -52,6 +52,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); scope = 2; model = QPATHTOEF(apl,ACE_CSW_m3_tripod.p3d); + editorPreview = QPATHTOF(data\ace_csw_m3Tripod.jpg); displayName = CSTRING(m3Tripod_displayName); class ADDON { disassembleTo = QGVAR(m3CarryTripod); @@ -66,6 +67,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); scope = 2; model = QPATHTOEF(apl,ace_csw_tripod_kord.p3d); + editorPreview = QPATHTOF(data\ace_csw_kordTripod.jpg); displayName = CSTRING(kordTripod_displayName); class ADDON { disassembleTo = QGVAR(kordCarryTripod); @@ -80,6 +82,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); scope = 2; model = QPATHTOEF(apl,ace_csw_tripod_ags30.p3d); + editorPreview = QPATHTOF(data\ace_csw_sag30Tripod.jpg); displayName = CSTRING(sag30Tripod_displayName); class ADDON { disassembleTo = QGVAR(sag30CarryTripod); @@ -89,6 +92,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); scope = 2; model = QPATHTOEF(apl,ace_csw_tripod_m220.p3d); + editorPreview = QPATHTOF(data\ace_csw_m220Tripod.jpg); displayName = CSTRING(m220Tripod_displayName); class ADDON { disassembleTo = QGVAR(m220CarryTripod); @@ -98,6 +102,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); scope = 2; model = QPATHTOEF(apl,ace_csw_tripod_spg9.p3d); + editorPreview = QPATHTOF(data\ace_csw_spg9Tripod.jpg); displayName = CSTRING(spg9_Tripod); class ADDON { disassembleTo = QGVAR(spg9CarryTripod); @@ -107,6 +112,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); scope = 2; model = QPATHTOEF(apl,ACE_CSW_mortarBaseplate.p3d); + editorPreview = QPATHTOF(data\ace_csw_mortarBaseplate.jpg); displayName = CSTRING(mortarBaseplate_displayName); class ADDON { disassembleTo = QGVAR(carryMortarBaseplate); @@ -119,10 +125,11 @@ class CfgVehicles { class StaticWeapon: LandVehicle { class ACE_Actions { class ACE_MainActions { + // Workaround for static weapons' Get In memory point being at the front of the gun class GVAR(getIn) { displayName = CSTRING(GetIn_displayName); condition = QUOTE(call FUNC(canGetIn)); - statement = QUOTE(call FUNC(getIn)); + statement = QUOTE(_player moveInTurret [ARR_2(_target,[0])]); }; }; }; @@ -131,7 +138,6 @@ class CfgVehicles { class StaticMGWeapon: StaticWeapon {}; class HMG_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(HMG_Static); @@ -163,10 +169,34 @@ class CfgVehicles { }; }; + class HMG_02_base_F: StaticMGWeapon { + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(HMG_M2_Mounted); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticM2ShieldCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3TripodLow); // turret [CfgVehicles] + desiredAmmo = 100; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + class HMG_02_high_base_F: HMG_02_base_F { + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(HMG_M2_Mounted); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticM2ShieldCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles] + desiredAmmo = 100; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + 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] @@ -200,7 +230,6 @@ class CfgVehicles { class AT_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(Titan_AT_Static); @@ -214,7 +243,6 @@ class CfgVehicles { }; class AA_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(Titan_AA_Static); // Weapon Proxy (Shorter Reload Time) [CfgWeapons] @@ -230,7 +258,6 @@ class CfgVehicles { class StaticMortar: StaticWeapon {}; class Mortar_01_base_F: StaticMortar { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; magazineLocation = ""; @@ -241,5 +268,15 @@ class CfgVehicles { ammoUnloadTime = 3; }; }; + // Ammo holder for returning ammo + class ReammoBox_F; + class GVAR(ammo_holder): ReammoBox_F { + EGVAR(cargo,canLoad) = 0; + EGVAR(cargo,noRename) = 1; + EGVAR(dragging,canCarry) = 1; // Allow this to be moved alongside the weapon + EGVAR(dragging,canDrag) = 1; + scope = 1; + maximumLoad = 0; // don't allow anything to be placed inside, only removed + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + }; }; - diff --git a/addons/csw/CfgWeapons.hpp b/addons/csw/CfgWeapons.hpp index fd7a67d6f0..80f8706376 100644 --- a/addons/csw/CfgWeapons.hpp +++ b/addons/csw/CfgWeapons.hpp @@ -4,7 +4,6 @@ class CfgWeapons { class WeaponSlotsInfo; }; - // Tripods: class GVAR(m3CarryTripod): Launcher_Base_F { class ADDON { @@ -28,6 +27,7 @@ class CfgWeapons { deploy = QGVAR(m3TripodLow); }; displayName = CSTRING(m3TripodLowFolded_displayName); + author = ECSTRING(common,ACETeam); }; class GVAR(kordCarryTripod): Launcher_Base_F { @@ -53,6 +53,7 @@ class CfgWeapons { deploy = QGVAR(kordTripodLow); }; displayName = CSTRING(kordTripodFoldedLow_displayName); + author = ECSTRING(common,ACETeam); }; class GVAR(m220CarryTripod): Launcher_Base_F { @@ -127,8 +128,6 @@ class CfgWeapons { picture = QPATHTOF(UI\Tripod_Icon.paa); // todo }; - - // Weapons: class GVAR(staticATCarry): Launcher_Base_F { class ADDON { @@ -151,23 +150,13 @@ class CfgWeapons { }; class GVAR(staticAACarry): GVAR(staticATCarry) { - class ADDON { - type = "weapon"; - deployTime = 15; - pickupTime = 20; + class ADDON: ADDON { 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 { @@ -190,6 +179,20 @@ class CfgWeapons { modes[] = {}; picture = QPATHTOF(UI\StaticHGMG_Icon.paa); }; + class GVAR(staticM2ShieldCarry): GVAR(staticHMGCarry) { + class ADDON: ADDON { + class assembleTo { + GVAR(m3Tripod) = "B_HMG_02_high_F"; + GVAR(m3TripodLow) = "B_HMG_02_F"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 1000; + }; + displayName = CSTRING(StaticM2ShieldBag_displayName); + author = ECSTRING(common,ACETeam); + picture = QPATHTOF(UI\StaticM2Shield_Icon_ca.paa); + }; class GVAR(staticGMGCarry): Launcher_Base_F { class ADDON { @@ -212,7 +215,6 @@ class CfgWeapons { picture = QPATHTOF(UI\StaticHGMG_Icon.paa); }; - class GVAR(staticMortarCarry): Launcher_Base_F { class ADDON { type = "weapon"; @@ -230,11 +232,12 @@ class CfgWeapons { scope = 2; model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); modes[] = {}; - picture = QPATHTOF(UI\StaticHGMG_Icon.paa); + picture = QPATHTOF(UI\StaticMortarTube_Icon.paa); }; // Proxy Weapons CREATE_CSW_PROXY(HMG_Static); + CREATE_CSW_PROXY(HMG_M2_Mounted); CREATE_CSW_PROXY(GMG_20mm); class missiles_titan_static; @@ -243,11 +246,10 @@ class CfgWeapons { EGVAR(javelin,enabled) = 1; // needs to be explicitly enabled magazineReloadTime = 0.5; }; - class GVAR(Titan_AA_Static) : missiles_titan_static { + class GVAR(Titan_AA_Static): missiles_titan_static { magazineReloadTime = 0.5; }; - /* class GVAR(staticAutoHMGCarry): Launcher_Base_F { class ADDON { @@ -270,7 +272,6 @@ class CfgWeapons { picture = QPATHTOF(UI\StaticHGMG_Icon.paa); }; - class GVAR(staticAutoGMGCarry): Launcher_Base_F { class GVAR(options) { assembleTo = QGVAR(staticAutoGMGWeapon); @@ -291,4 +292,3 @@ class CfgWeapons { */ }; - diff --git a/addons/csw/README.md b/addons/csw/README.md index 8729a7fa31..b47a978e79 100644 --- a/addons/csw/README.md +++ b/addons/csw/README.md @@ -2,11 +2,3 @@ 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/StaticM2Shield_Icon_ca.paa b/addons/csw/UI/StaticM2Shield_Icon_ca.paa new file mode 100644 index 0000000000..ba1788f787 Binary files /dev/null and b/addons/csw/UI/StaticM2Shield_Icon_ca.paa differ diff --git a/addons/csw/UI/StaticMortarTube_Icon.paa b/addons/csw/UI/StaticMortarTube_Icon.paa new file mode 100644 index 0000000000..2420ce7e4f Binary files /dev/null and b/addons/csw/UI/StaticMortarTube_Icon.paa differ diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 7bde8c3c0f..fed4120c86 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -3,10 +3,12 @@ TRACE_1("",QUOTE(ADDON)); PREP(aceRearmGetCarryMagazines); PREP(ai_handleFired); +PREP(ai_handleGetIn); +PREP(ai_reload); -PREP(assemble_canDeployTripod); +PREP(canDeployTripod); PREP(assemble_canDeployWeapon); -PREP(assemble_canPickupTripod); +PREP(canPickupTripod); PREP(assemble_canPickupWeapon); PREP(assemble_deployTripod); PREP(assemble_deployWeapon); @@ -15,12 +17,12 @@ PREP(assemble_pickupTripod); PREP(assemble_pickupWeapon); PREP(canGetIn); -PREP(getIn); +PREP(getCarryMagazine); PREP(proxyWeapon); -PREP(reload_actionsLoad); -PREP(reload_actionsUnload); +PREP(getLoadActions); +PREP(getUnloadActions); PREP(reload_canLoadMagazine); PREP(reload_canUnloadMagazine); PREP(reload_getLoadableMagazines); @@ -30,5 +32,5 @@ PREP(reload_handleRemoveTurretMag); PREP(reload_handleReturnAmmo); PREP(reload_loadMagazine); -PREP(staticWeaponInit); +PREP(initVehicle); PREP(staticWeaponInit_unloadExtraMags); diff --git a/addons/csw/XEH_postInit.sqf b/addons/csw/XEH_postInit.sqf index 69137296c5..87196f3377 100644 --- a/addons/csw/XEH_postInit.sqf +++ b/addons/csw/XEH_postInit.sqf @@ -1,26 +1,32 @@ #include "script_component.hpp" -GVAR(vehicleMagCache) = call CBA_fnc_createNamespace; +GVAR(vehicleMagCache) = createHashMap; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling)); - ["StaticWeapon", "init", LINKFUNC(staticWeaponInit), true, [], true] call CBA_fnc_addClassEventHandler; + ["StaticWeapon", "Init", { + // needs a small delay for network syncing, or we end up with duplicate mags with ammo handling + [LINKFUNC(initVehicle), _this, 1] call CBA_fnc_waitAndExecute; + }, true, [], true] call CBA_fnc_addClassEventHandler; + + GVAR(quickmountEnabled) = ( + missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && + {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} + ); }] call CBA_fnc_addEventHandler; +["CBA_SettingChanged", { + GVAR(quickmountEnabled) = ( + missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && + {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} + ); +}] call CBA_fnc_addEventHandler; // Event handlers: -[QGVAR(disableVanillaAssembly), { - params ["_staticWeapon"]; - TRACE_1("disableVanillaAssembly eh",_staticWeapon); - _staticWeapon enableWeaponDisassembly false; -}] call CBA_fnc_addEventHandler; - [QGVAR(addTurretMag), LINKFUNC(reload_handleAddTurretMag)] call CBA_fnc_addEventHandler; [QGVAR(removeTurretMag), LINKFUNC(reload_handleRemoveTurretMag)] call CBA_fnc_addEventHandler; [QGVAR(returnAmmo), LINKFUNC(reload_handleReturnAmmo)] call CBA_fnc_addEventHandler; - - #ifdef DEBUG_MODE_FULL call compile preprocessFileLineNumbers QPATHTOF(dev\checkStaticWeapons.sqf); #endif diff --git a/addons/csw/XEH_preInit.sqf b/addons/csw/XEH_preInit.sqf index 6ecb2a0c2f..2cef0dfd2c 100644 --- a/addons/csw/XEH_preInit.sqf +++ b/addons/csw/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(initializedStaticTypes) = []; diff --git a/addons/csw/config.cpp b/addons/csw/config.cpp index 9478e7e798..aab2b0416f 100644 --- a/addons/csw/config.cpp +++ b/addons/csw/config.cpp @@ -4,8 +4,8 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; - weapons[] = {"ace_csw_carryTripod", "ace_csw_staticATWeapon"}; + units[] = {QGVAR(m3Tripod),QGVAR(m3TripodLow),QGVAR(kordTripod),QGVAR(kordTripodLow),QGVAR(sag30Tripod),QGVAR(m220Tripod),QGVAR(spg9Tripod),QGVAR(mortarBaseplate)}; + weapons[] = {QGVAR(m3CarryTripod),QGVAR(m3CarryTripodLow),QGVAR(kordCarryTripod),QGVAR(kordCarryTripodLow),QGVAR(m220CarryTripod),QGVAR(spg9CarryTripod),QGVAR(sag30CarryTripod),QGVAR(carryMortarBaseplate),QGVAR(staticATCarry),QGVAR(staticAACarry),QGVAR(staticHMGCarry),QGVAR(staticM2ShieldCarry),QGVAR(staticGMGCarry),QGVAR(staticMortarCarry)}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); @@ -15,10 +15,8 @@ class CfgPatches { }; }; -#include "Cfg3den.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "CfgMagazines.hpp" #include "CfgMagazineGroups.hpp" - diff --git a/addons/csw/data/ace_csw_kordTripod.jpg b/addons/csw/data/ace_csw_kordTripod.jpg new file mode 100644 index 0000000000..3ada21fea9 Binary files /dev/null and b/addons/csw/data/ace_csw_kordTripod.jpg differ diff --git a/addons/csw/data/ace_csw_m220Tripod.jpg b/addons/csw/data/ace_csw_m220Tripod.jpg new file mode 100644 index 0000000000..51bf226c70 Binary files /dev/null and b/addons/csw/data/ace_csw_m220Tripod.jpg differ diff --git a/addons/csw/data/ace_csw_m3Tripod.jpg b/addons/csw/data/ace_csw_m3Tripod.jpg new file mode 100644 index 0000000000..0908470ce6 Binary files /dev/null and b/addons/csw/data/ace_csw_m3Tripod.jpg differ diff --git a/addons/csw/data/ace_csw_mortarBaseplate.jpg b/addons/csw/data/ace_csw_mortarBaseplate.jpg new file mode 100644 index 0000000000..4f5b579756 Binary files /dev/null and b/addons/csw/data/ace_csw_mortarBaseplate.jpg differ diff --git a/addons/csw/data/ace_csw_sag30Tripod.jpg b/addons/csw/data/ace_csw_sag30Tripod.jpg new file mode 100644 index 0000000000..d8000e57ee Binary files /dev/null and b/addons/csw/data/ace_csw_sag30Tripod.jpg differ diff --git a/addons/csw/data/ace_csw_spg9Tripod.jpg b/addons/csw/data/ace_csw_spg9Tripod.jpg new file mode 100644 index 0000000000..1944c26b73 Binary files /dev/null and b/addons/csw/data/ace_csw_spg9Tripod.jpg differ diff --git a/addons/csw/data/model.cfg b/addons/csw/data/model.cfg index 7adabdac10..2104dca5a5 100644 --- a/addons/csw/data/model.cfg +++ b/addons/csw/data/model.cfg @@ -20,37 +20,37 @@ class CfgModels { sections[] = {}; skeletonName = ""; }; - class ACE_CSW_Tripod : Default { + class ACE_CSW_Tripod: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ACE_CSW_Tripod_Skeleton"; }; - class ACE_CSW_M3_Tripod : Default { + class ACE_CSW_M3_Tripod: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ACE_CSW_M3_Tripod_Skeleton"; }; - class ace_csw_tripod_ags30 : Default { + class ace_csw_tripod_ags30: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ace_csw_tripod_ags30_Skeleton"; }; - class ace_csw_tripod_kord : Default { + class ace_csw_tripod_kord: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ace_csw_tripod_kord_Skeleton"; }; - class ace_csw_tripod_m122 : Default { + class ace_csw_tripod_m122: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ace_csw_tripod_m122_Skeleton"; }; - class ace_csw_tripod_m220 : Default { + class ace_csw_tripod_m220: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ace_csw_tripod_m220_Skeleton"; }; - class ace_csw_tripod_spg9 : Default { + class ace_csw_tripod_spg9: Default { sectionsInherit = ""; sections[] = {}; skeletonName = "ace_csw_tripod_spg9_Skeleton"; diff --git a/addons/csw/dev/checkStaticWeapons.sqf b/addons/csw/dev/checkStaticWeapons.sqf index 6ad8985b98..7d9917daa7 100644 --- a/addons/csw/dev/checkStaticWeapons.sqf +++ b/addons/csw/dev/checkStaticWeapons.sqf @@ -1,5 +1,5 @@ #define DEBUG_MODE_FULL -#include "\z\ace\addons\csw\script_component.hpp" +#include "..\script_component.hpp" // Dev only function to search for weapons used by static weapons // and check if their magazinese are compatible @@ -7,14 +7,14 @@ INFO("Checking static weapons"); private _staticWeaponConfigs = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(configName _x) isKindOf 'StaticWeapon'}", true]; private _staticPublic = _staticWeaponConfigs select {(getNumber (_x >> "scope")) == 2}; -INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic, {(getNumber (_x >> "ace_csw" >> "enabled")) == 1} count _staticPublic); +INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic,{(getNumber (_x >> QUOTE(ADDON) >> "enabled")) == 1} count _staticPublic); INFO("------ Checking static weapons inheritance ------"); private _explicitBases = []; private _inherited = []; { private _config = _x; - private _configEnabled = (getNumber (_config >> "ace_csw" >> "enabled")) == 1; + private _configEnabled = (getNumber (_config >> QUOTE(ADDON) >> "enabled")) == 1; if (_configEnabled) then { private _configExplicit = (count configProperties [_config, "configName _x == 'ace_csw'", false]) == 1; if (_configExplicit) then { @@ -42,7 +42,7 @@ private _inherited = []; INFO("------ Logging static magazines with no carry version -------"); -private _hash = [] call CBA_fnc_hashCreate; +private _hash = createHashMap; // private _logAll = true; // logs all possible weapon magazines (even if not used in a static weapon) private _logAll = false; { @@ -54,23 +54,22 @@ private _logAll = false; private _weapMags = getArray (configFile >> "CfgWeapons" >> _x >> "magazines"); { private _xMag = _x; - private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups)); + private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" 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 = [];}; + private _vehs = _hash getOrDefault [_xMag, []]; if (_xMag in _loadedMags) then { _vehs pushBack _vehicleType; }; - [_hash, _xMag, _vehs] call CBA_fnc_hashSet; + _hash set [_xMag, _vehs]; }; } 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; +{ + //IGNORE_PRIVATE_WARNING ["_x", "_y"]; + INFO_2("[%1] has no carry variant - Used in %2",_x,_y); +} forEach _hash; INFO("------ End -------"); diff --git a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf index ac64f636e8..5230fccf52 100644 --- a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf +++ b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Helper function for ace_rearm; Gets magazines that should be loaded by csw @@ -18,33 +18,33 @@ 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 _return = [[], []]; + +if !(_vehicle isKindOf "StaticWeapon") exitWith {_return}; // 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 {_return}; + +private _turretMagsCSW = _return select 0; +private _allCarryMags = _return select 1; + +private _turrets = allTurrets _vehicle; +if (_targetTurret isNotEqualTo true) then { + _turrets = _turrets select {_x isEqualTo _targetTurret}; +}; -private _turretMagsCSW = []; -private _allCarryMags = []; { private _turretPath = _x; - if ((_targetTurret isEqualTo true) || {_turretPath isEqualTo _targetTurret}) then { + { + private _weapon = _x; { - 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); + private _xMag = _x; + private _carryMag = _xMag call FUNC(getCarryMagazine); + if (_carryMag != "") then { + _turretMagsCSW pushBackUnique _xMag; + _allCarryMags pushBackUnique _carryMag; + }; + } forEach (compatibleMagazines _weapon); + } forEach (_vehicle weaponsTurret _turretPath); +} forEach _turrets; -[_turretMagsCSW, _allCarryMags] +_return diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index f85c74fd20..d92e517091 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -1,96 +1,23 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Initializes weapon to disable weapon disassembling + * Handles AI Fired EH * * Arguments: - * 0: Weapon + * Fired EH * * 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); +params ["_vehicle", "_weapon", "", "", "", "_magazine", "", "_gunner"]; +TRACE_4("firedEH:",_vehicle,_weapon,_magazine,_gunner); +if (someAmmo _vehicle) exitWith {}; if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; -if (someAmmo _staticWeapon) exitWith {}; -TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); +TRACE_1("need ammo",magazinesAllTurrets _vehicle); -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; +[_vehicle, _gunner, _weapon, _magazine] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf new file mode 100644 index 0000000000..f14a4ccbc7 --- /dev/null +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Grim + * Handles AI GetIn on an empty weapon + * + * Arguments: + * GetIn EH + * + * Return Value: + * None + * + * Public: No + */ + +params ["_vehicle", "", "_gunner"]; +TRACE_2("getInEH:",_vehicle,_gunner); + +if (someAmmo _vehicle) exitWith {}; +if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; + +TRACE_1("need ammo",magazinesAllTurrets _vehicle); + +[_vehicle, _gunner, currentWeapon _vehicle] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf new file mode 100644 index 0000000000..4d6234f94a --- /dev/null +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -0,0 +1,96 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, modified by Grim + * Handles AI reloading + * + * Arguments: + * 0: Static Weapon + * 1: Gunner + * 2: Weapon + * 3: Magazine (default: "") + * + * Return Value: + * None + * + * Public: No + */ + +params ["_staticWeapon", "_gunner", "_weapon", ["_magazine", ""]]; + +private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); +private _reloadSource = objNull; +private _reloadMag = ""; +private _reloadNeededAmmo = -1; + +private _cfgMagGroups = configFile >> QGVAR(groups); + +private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { + isNull (group _x) || + {!([_x] call EFUNC(common,isPlayer)) && {[side group _gunner, side group _x] call BIS_fnc_sideIsFriendly}} +}); + +// Find if there is anything we can reload with +{ + scopeName "findSource"; + private _xSource = _x; + + private _cswMagazines = []; + { + _cswMagazines pushBackUnique _x; + } forEach ((magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}); + TRACE_2("",_xSource,_cswMagazines); + + private _compatibleMags = compatibleMagazines _weapon; + if (_magazine != "") then { + _compatibleMags insert [0, [_magazine]]; + }; + + { + private _xWeaponMag = _x; + { + if ((getNumber (_cfgMagGroups >> _x >> _xWeaponMag)) == 1) then { + private _loadInfo = [_staticWeapon, _turretPath, _x, _xSource] 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 _nearSupplies; +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 +[_reloadSource, _reloadMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); + +private _timeToLoad = 1; +if (!isNull(configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime")) then { + _timeToLoad = getNumber(configOf _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 deleted file mode 100644 index a890e746ea..0000000000 --- a/addons/csw/functions/fnc_assemble_canDeployTripod.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: TCVM - * Checks if the player can deploy the tripod. - * - * Arguments: - * 0: Unit - * - * Return Value: - * Can deploy - * - * Example: - * [player] call ace_csw_fnc_canDeployTripod - * - * Public: No - */ - -params ["_player"]; - -(getText(configFile >> "CfgWeapons" >> (secondaryWeapon _player) >> QUOTE(ADDON) >> "type") == "mount") - diff --git a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf index b0659e2f01..65dd81cc41 100644 --- a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * Checks if you can deploy a weapon on the tripod * * Arguments: * 0: Target Tripod - * 0: Player + * 1: Player * * Return Value: * Wether or not you can deploy the weapon @@ -16,10 +16,8 @@ * Public: No */ -params ["_target", "_player", "", "_carryWeaponClassname"]; -if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player }; +params ["_target", "_player"]; // If the current launcher has a config-value that defines the tripod, it is a CSW (alive _target) && -{(getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target))) != ""} - +{(getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> QUOTE(ADDON) >> "assembleTo" >> typeOf _target)) != ""} diff --git a/addons/csw/functions/fnc_assemble_canPickupTripod.sqf b/addons/csw/functions/fnc_assemble_canPickupTripod.sqf deleted file mode 100644 index a5cd0d5c0c..0000000000 --- a/addons/csw/functions/fnc_assemble_canPickupTripod.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "script_component.hpp" -/* - * Author: TCVM - * Checks if the player can pick-up the tripod. - * - * Arguments: - * 0: Tripod - * 1: Unit - * - * Return Value: - * Can pickup - * - * Example: - * [tripod, player] call ace_csw_fnc_assemble_canPickupTripod - * - * Public: No - */ - -params ["_tripod", "_player"]; - -((secondaryWeapon _player) isEqualTo "") && {alive _tripod} - diff --git a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf index ef40e03b3c..0d508bfa89 100644 --- a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * If the CSW is mounted or in use this will not allow you to dismount the weapon * * Arguments: @@ -19,8 +19,5 @@ params ["_staticWeapon"]; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 3]); -private _notCrewed = (crew _staticWeapon) isEqualTo []; -private _deadCrew = !(alive (gunner _staticWeapon)); // need to eject body??? - -_assemblyMode && {_notCrewed || _deadCrew} +_assemblyMode && {alive _staticWeapon} && {((crew _staticWeapon) findIf {alive _x && {!unitIsUAV _x}}) == -1} // return diff --git a/addons/csw/functions/fnc_assemble_deployTripod.sqf b/addons/csw/functions/fnc_assemble_deployTripod.sqf index ba7f15777a..29cc4b5876 100644 --- a/addons/csw/functions/fnc_assemble_deployTripod.sqf +++ b/addons/csw/functions/fnc_assemble_deployTripod.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * Deploys the tripod * * Arguments: @@ -19,14 +19,20 @@ params ["_player"]; TRACE_1("assemble_deployTripod",_player); + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) + private _secondaryWeaponInfo = (getUnitLoadout _player) select 1; + private _secondaryWeaponClassname = _secondaryWeaponInfo deleteAt 0; + + // Remove empty entries + _secondaryWeaponInfo = _secondaryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}}; + // Remove the tripod from the launcher slot - private _secondaryWeaponClassname = secondaryWeapon _player; - _player removeWeaponGlobal (secondaryWeapon _player); + _player removeWeaponGlobal _secondaryWeaponClassname; private _onFinish = { params ["_args"]; - _args params ["_player", "_secondaryWeaponClassname"]; - TRACE_2("deployTripod finish",_player,_secondaryWeaponClassname); + _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"]; + TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponInfo); private _tripodClassname = getText(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy"); @@ -34,9 +40,26 @@ private _cswTripod = createVehicle [_tripodClassname, [0, 0, 0], [], 0, "NONE"]; // Because the tripod can be a "full weapon" we disable any data that will allow it to be loaded _cswTripod setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set enabled&unload assembly mode and broadcast + + private _secondaryWeaponMagazines = []; + + { + // Magazines + if (_x isEqualType []) then { + _secondaryWeaponMagazines pushBack _x; + } else { + // Items + [_player, _x, true] call CBA_fnc_addItem; + }; + } forEach _secondaryWeaponInfo; + + // Only add magazines once the weapon is fully ready + if (_secondaryWeaponMagazines isNotEqualTo []) then { + _cswTripod setVariable [QGVAR(secondaryWeaponMagazines), _secondaryWeaponMagazines, true]; + }; + if (!GVAR(defaultAssemblyMode)) then { - TRACE_1("global disableVanillaAssembly event",_cswTripod); // handles it being assembled when setting is disabled - [QGVAR(disableVanillaAssembly), [_cswTripod]] call CBA_fnc_globalEvent; + [_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; private _posATL = _player getRelPos [2, 0]; @@ -49,7 +72,7 @@ [_player, "PutDown"] call EFUNC(common,doGesture); // drag after deploying - if ((missionNamespace getVariable [QGVAR(dragAfterDeploying), false]) && {["ACE_dragging"] call EFUNC(common,isModLoaded)}) then { + if ((missionNamespace getVariable [QGVAR(dragAfterDeploy), false]) && {["ace_dragging"] call EFUNC(common,isModLoaded)}) then { if ([_player, _cswTripod] call EFUNC(dragging,canCarry)) then { TRACE_1("starting carry",_cswTripod); [_player, _cswTripod] call EFUNC(dragging,startCarry); @@ -61,12 +84,18 @@ private _onFailure = { params ["_args"]; - _args params ["_player", "_secondaryWeaponClassname"]; - TRACE_2("deployTripod failure",_player,_secondaryWeaponClassname); + _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"]; + TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponInfo); - _player addWeaponGlobal _secondaryWeaponClassname; + // Add tripod back + [_player, _secondaryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + // Add all attachments back + { + _player addWeaponItem [_secondaryWeaponClassname, _x, true]; + } forEach _secondaryWeaponInfo; }; private _deployTime = getNumber(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); - [TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname], _onFinish, _onFailure, localize LSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname, _secondaryWeaponInfo], _onFinish, _onFailure, LLSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/csw/functions/fnc_assemble_deployWeapon.sqf b/addons/csw/functions/fnc_assemble_deployWeapon.sqf index 12b5938bb9..974bf03431 100644 --- a/addons/csw/functions/fnc_assemble_deployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -1,39 +1,54 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * Deploys the current CSW * * Arguments: - * 0: Unit + * 0: Target + * 1: Unit + * 2: Args + * 3: Action Data * * Return Value: * None * * Example: - * [player] call ace_csw_fnc_assemble_deployWeapon + * [cursorObject, player] call ace_csw_fnc_assemble_deployWeapon * * Public: No */ [{ - params ["_tripod", "_player", "", "_carryWeaponClassname"]; - if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player }; + params ["_tripod", "_player"]; + + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) + private _carryWeaponInfo = (getUnitLoadout _player) select 1; + private _carryWeaponClassname = _carryWeaponInfo deleteAt 0; + + // Remove empty entries + _carryWeaponInfo = _carryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}}; + TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname); private _tripodClassname = typeOf _tripod; + private _weaponConfig = configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON); + private _assembledClassname = getText (_weaponConfig >> "assembleTo" >> _tripodClassname); + + if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);}; + _player removeWeaponGlobal _carryWeaponClassname; - private _assembledClassname = getText(configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); - private _deployTime = getNumber(configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); - if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);}; + private _deployTime = getNumber (_weaponConfig >> "deployTime"); TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime); private _onFinish = { params ["_args"]; - _args params ["_tripod", "_player", "_assembledClassname"]; + _args params ["_tripod", "_player", "_assembledClassname", "", "_carryWeaponInfo"]; TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname); + private _secondaryWeaponMagazines = _tripod getVariable [QGVAR(secondaryWeaponMagazines), []]; + private _tripodPos = getPosATL _tripod; private _tripodDir = getDir _tripod; deleteVehicle _tripod; @@ -41,37 +56,59 @@ _tripodPos set [2, (_tripodPos select 2) + 0.1]; // Delay a frame so tripod has a chance to be deleted [{ - params ["_assembledClassname", "_tripodDir", "_tripodPos"]; + params ["_assembledClassname", "_tripodDir", "_tripodPos", "_player", "_carryWeaponInfo", "_secondaryWeaponMagazines"]; private _csw = createVehicle [_assembledClassname, [0, 0, 0], [], 0, "NONE"]; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] _csw setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set advanced assembly mode + unload, and broadcast + + { + // Magazines + if (_x isEqualType []) then { + _secondaryWeaponMagazines pushBack _x; + } else { + // Items + [_player, _x, true] call CBA_fnc_addItem; + }; + } forEach _carryWeaponInfo; + + // Only add magazines once the weapon is fully ready + if (_secondaryWeaponMagazines isNotEqualTo []) then { + _csw setVariable [QGVAR(secondaryWeaponMagazines), _secondaryWeaponMagazines, true]; + }; + if (!GVAR(defaultAssemblyMode)) then { - TRACE_1("global disableVanillaAssembly event",_csw); // handles it being assembled when setting is disabled - [QGVAR(disableVanillaAssembly), [_csw]] call CBA_fnc_globalEvent; + [_csw, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; _csw setDir _tripodDir; _csw setPosATL _tripodPos; if ((_tripodPos select 2) < 0.5) then { _csw setVectorUp (surfaceNormal _tripodPos); }; + [QGVAR(deployWeaponSucceeded), [_csw]] call CBA_fnc_localEvent; TRACE_2("csw placed",_csw,_assembledClassname); - }, [_assembledClassname, _tripodDir, _tripodPos]] call CBA_fnc_execNextFrame; + }, [_assembledClassname, _tripodDir, _tripodPos, _player, _carryWeaponInfo, _secondaryWeaponMagazines]] call CBA_fnc_execNextFrame; }; private _onFailure = { params ["_args"]; - _args params ["", "_player", "", "_carryWeaponClassname"]; + _args params ["", "_player", "", "_carryWeaponClassname", "_carryWeaponInfo"]; TRACE_2("deployWeapon failure",_player,_carryWeaponClassname); - _player addWeaponGlobal _carryWeaponClassname; + // Add weapon back + [_player, _carryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + // Add all attachments back + { + _player addWeaponItem [_carryWeaponClassname, _x, true]; + } forEach _carryWeaponInfo; }; - private _codeCheck = { + private _condition = { params ["_args"]; _args params ["_tripod"]; - !isNull _tripod; + + alive _tripod }; - [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname], _onFinish, _onFailure, localize LSTRING(AssembleCSW_progressBar), _codeCheck] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname, _carryWeaponInfo], _onFinish, _onFailure, LLSTRING(AssembleCSW_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; - diff --git a/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf index b1b89d8f09..85b1346415 100644 --- a/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Modifies interaction for deploying weapon diff --git a/addons/csw/functions/fnc_assemble_pickupTripod.sqf b/addons/csw/functions/fnc_assemble_pickupTripod.sqf index 0167254795..0996c0f3d3 100644 --- a/addons/csw/functions/fnc_assemble_pickupTripod.sqf +++ b/addons/csw/functions/fnc_assemble_pickupTripod.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * Picks up the tripod and adds it to the player launcher slot * * Arguments: @@ -11,7 +11,7 @@ * None * * Example: - * [tripod, player] call ace_csw_fnc_assemble_pickupTripod + * [cursorObject, player] call ace_csw_fnc_assemble_pickupTripod * * Public: No */ @@ -20,28 +20,55 @@ params ["_tripod", "_player"]; TRACE_2("assemble_pickupTripod",_tripod,_player); - private _tripodClassname = getText(configFile >> "CfgVehicles" >> (typeof _tripod) >> QUOTE(ADDON) >> "disassembleTo"); - private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime"); + private _tripodClassname = getText (configOf _tripod >> QUOTE(ADDON) >> "disassembleTo"); + private _pickupTime = getNumber (configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime"); private _onFinish = { params ["_args"]; _args params ["_tripod", "_player", "_tripodClassname"]; TRACE_3("assemble_pickupTripod finish",_tripod,_player,_tripodClassname); + // Save tripod position before it's deleted + private _tripodPos = getPosATL _tripod; + + // Eject dead units (all crew are dead at this point, otherwise condition would have failed), but ignore UAV units + { + if (unitIsUAV _x) then { + _tripod deleteVehicleCrew _x; + } else { + moveOut _x; + }; + } forEach (crew _tripod); + deleteVehicle _tripod; - _player addWeaponGlobal _tripodClassname; + [_player, "PutDown"] call EFUNC(common,doGesture); + + // If the player has space, give it to him + if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { + [_player, _tripodClassname] call CBA_fnc_addWeaponWithoutItems; + }; + + // Try to find existing weapon holders + private _weaponHolder = nearestObject [_tripodPos, "WeaponHolder"]; + + // If there are none or too far away, make a new one + if (isNull _weaponHolder || {_tripodPos distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _weaponHolder setDir random [0, 180, 360]; + _weaponHolder setVehiclePosition [_tripodPos, [], 0, "CAN_COLLIDE"]; // places object on surface below + }; + + _weaponHolder addWeaponCargoGlobal [_tripodClassname, 1]; }; private _condition = { params ["_args"]; - _args params ["_tripod", "_player"]; - - !(isNull _tripod) && { (secondaryWeapon _player) isEqualTo "" } + _args params ["_tripod"]; + _tripod call FUNC(canPickupTripod) }; TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname); - [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, LLSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; - diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf index 1b131d4a3b..468f385efa 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -1,16 +1,17 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * Dismounts the weapon from the tripod and drops its backpack beside * * Arguments: * 0: Static Weapon + * 1: Unit * * Return Value: * None * * Example: - * [weapon] call ace_csw_fnc_assemble_pickupWeapon + * [cursorObject, player] call ace_csw_fnc_assemble_pickupWeapon * * Public: No */ @@ -19,34 +20,45 @@ 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);}; + private _weaponConfig = configOf _staticWeapon >> QUOTE(ADDON); + private _carryWeaponClassname = getText (_weaponConfig >> "disassembleWeapon"); + + if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith { + ERROR_1("bad weapon classname [%1]",_carryWeaponClassname); + }; + + private _turretClassname = getText (_weaponConfig >> "disassembleTurret"); + // Turret classname can equal nothing if the deploy bag is the "whole" weapon. e.g Kornet, Metis, other ATGMs - if (!(_turretClassname isEqualTo "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith {ERROR_1("bad turret classname [%1]",_turretClassname);}; + if ((_turretClassname != "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith { + ERROR_1("bad turret classname [%1]",_turretClassname); + }; + + private _onDisassembleFunc = getText (_weaponConfig >> "disassembleFunc"); + + private _pickupTime = getNumber (configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime"); + TRACE_4("",typeOf _staticWeapon,_carryWeaponClassname,_turretClassname,_pickupTime); private _onFinish = { params ["_args"]; _args params ["_staticWeapon", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"]; TRACE_4("disassemble finish",_staticWeapon,_player,_carryWeaponClassname,_turretClassname); - private _weaponPos = getPosATL _staticWeapon; - _weaponPos set [2, (_weaponPos select 2) + 0.1]; + private _weaponPos = (getPosATL _staticWeapon) vectorAdd [0, 0, 0.1]; private _weaponDir = getDir _staticWeapon; + private _carryWeaponMag = []; + private _carryWeaponMags = compatibleMagazines _carryWeaponClassname; LOG("remove ammo"); { _x params ["_xMag", "", "_xAmmo"]; + if (_xAmmo == 0) then {continue}; - 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); + private _carryMag = _xMag call FUNC(getCarryMagazine); + if (_carryWeaponMag isEqualTo [] && {_carryMag in _carryWeaponMags}) then { + TRACE_3("Adding mag to secondary weapon",_xMag,_xAmmo,_carryMag); + _carryWeaponMag = [_carryMag, _xAmmo]; + DEC(_xAmmo); }; if ((_xAmmo > 0) && {_carryMag != ""}) then { TRACE_2("Removing ammo",_xMag,_carryMag); @@ -54,7 +66,7 @@ }; } forEach (magazinesAllTurrets _staticWeapon); - if !(_turretClassname isEqualTo "") then { + if (_turretClassname isNotEqualTo "") then { private _cswTripod = createVehicle [_turretClassname, [0, 0, 0], [], 0, "NONE"]; // Delay a frame so weapon has a chance to be deleted [{ @@ -68,18 +80,40 @@ }; [{ - params ["_player", "_weaponPos", "_carryWeaponClassname"]; + params ["_player", "_weaponPos", "_carryWeaponClassname", "_carryWeaponMag", "_turretClassname"]; + + // Give the weapon to the player if possible if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { - _player addWeapon _carryWeaponClassname; + [_player, _carryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + if (_carryWeaponMag isNotEqualTo []) then { + _player addWeaponItem [_carryWeaponClassname, _carryWeaponMag, true]; + }; }; - private _weaponRelPos = _weaponPos getPos RELATIVE_DIRECTION(90); - private _weaponHolder = createVehicle ["groundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; + + // If there is no turret, place the ground holder where the turret was + if (_turretClassname != "") then { + _weaponPos = _weaponPos getPos RELATIVE_DIRECTION(90); + }; + + // Create a new weapon holder (don't try to get an existing one, as no guarantee where it could be) + private _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "CAN_COLLIDE"]; _weaponHolder setDir random [0, 180, 360]; - _weaponHolder setPosATL [_weaponRelPos select 0, _weaponRelPos select 1, _weaponPos select 2]; - _weaponHolder addWeaponCargoGlobal [_carryWeaponClassname, 1]; - }, [_player, _weaponPos, _carryWeaponClassname]] call CBA_fnc_execNextFrame; + _weaponHolder setVehiclePosition [_weaponPos, [], 0, "CAN_COLLIDE"]; // places object on surface below + _weaponHolder addWeaponWithAttachmentsCargoGlobal [[_carryWeaponClassname, "", "", "", _carryWeaponMag, [], ""], 1]; + }, [_player, _weaponPos, _carryWeaponClassname, _carryWeaponMag, _turretClassname]] call CBA_fnc_execNextFrame; LOG("delete weapon"); + + // Eject dead units (all crew are dead or UAV at this point, otherwise condition would have failed), but ignore UAV units + { + if (unitIsUAV _x) then { + _staticWeapon deleteVehicleCrew _x; + } else { + moveOut _x; + }; + } forEach (crew _staticWeapon); + deleteVehicle _staticWeapon; LOG("end"); @@ -88,9 +122,9 @@ private _condition = { params ["_args"]; _args params ["_staticWeapon"]; - ((crew _staticWeapon) isEqualTo []) && (alive _staticWeapon) + + _staticWeapon call FUNC(assemble_canPickupWeapon) }; - [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, LLSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; - diff --git a/addons/csw/functions/fnc_canDeployTripod.sqf b/addons/csw/functions/fnc_canDeployTripod.sqf new file mode 100644 index 0000000000..8969758e4d --- /dev/null +++ b/addons/csw/functions/fnc_canDeployTripod.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks if the unit can deploy a tripod + * + * Arguments: + * 0: Unit + * + * Return Value: + * Can deploy + * + * Example: + * player call ace_csw_fnc_canDeployTripod + * + * Public: No + */ + +params ["_unit"]; + +private _secondaryWeapon = secondaryWeapon _unit; + +_secondaryWeapon != "" && {getText (configFile >> "CfgWeapons" >> _secondaryWeapon >> QUOTE(ADDON) >> "type") == "mount"} // return diff --git a/addons/csw/functions/fnc_canGetIn.sqf b/addons/csw/functions/fnc_canGetIn.sqf index 92b05b1c2c..16446c4fb2 100644 --- a/addons/csw/functions/fnc_canGetIn.sqf +++ b/addons/csw/functions/fnc_canGetIn.sqf @@ -1,28 +1,23 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM - * Checks if the player can get in the weapon + * Author: tcvm + * Checks if it's possible to get in the CSW * * Arguments: - * 0: Static Weapon + * 0: Vehicle * * Return Value: * None * * Example: - * [cursorObject] call ace_csw_fnc_canGetIn + * cursorObject call ace_csw_fnc_canGetIn * * Public: No */ -// hide this action if quick mount is enabled -if ((missionNamespace getVariable [QEGVAR(quickmount,enabled), false]) && {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1, 3]}) exitWith { - false -}; +// Hide this action if quick mount is enabled +if (GVAR(quickmountEnabled)) exitWith {false}; -params ["_staticWeapon"]; +params ["_vehicle"]; -alive _staticWeapon -&& {!(alive (gunner _staticWeapon))} -&& {(locked _staticWeapon) < 2} -&& {0.3 < ((vectorUp _staticWeapon) select 2)} +alive _vehicle && {!(alive (gunner _vehicle))} && {(locked _vehicle) < 2} && {!(_vehicle lockedTurret [0])} && {0.3 < ((vectorUp _vehicle) select 2)} // return diff --git a/addons/csw/functions/fnc_canPickupTripod.sqf b/addons/csw/functions/fnc_canPickupTripod.sqf new file mode 100644 index 0000000000..2ec3b065da --- /dev/null +++ b/addons/csw/functions/fnc_canPickupTripod.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks if the unit can pickup the tripod + * + * Arguments: + * 0: Tripod + * 1: Unit (not used) + * + * Return Value: + * Can pickup + * + * Example: + * [cursorObject, player] call ace_csw_fnc_canPickupTripod + * + * Public: No + */ + +params ["_tripod"]; + +alive _tripod && {((crew _tripod) findIf {alive _x && {!unitIsUAV _x}}) == -1} // return diff --git a/addons/csw/functions/fnc_getCarryMagazine.sqf b/addons/csw/functions/fnc_getCarryMagazine.sqf new file mode 100644 index 0000000000..81e07c6f10 --- /dev/null +++ b/addons/csw/functions/fnc_getCarryMagazine.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, Dystopian + * Gets magazine that the player can carry, suitable to vehicle magazine + * + * Arguments: + * 0: Vehicle Magazine + * + * Return Value: + * Carry Magazine + * + * Example: + * "1Rnd_GAT_missiles" call ace_csw_fnc_getCarryMagazine + * + * Public: No + */ + +params ["_vehicleMag"]; + +private _carryMag = GVAR(vehicleMagCache) get _vehicleMag; +if (isNil "_carryMag") then { + private _groups = "getNumber (_x >> _vehicleMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups)); + _carryMag = configName (_groups param [0, configNull]); + GVAR(vehicleMagCache) set [_vehicleMag, _carryMag]; + TRACE_2("setting cache",_vehicleMag,_carryMag); +}; + +_carryMag diff --git a/addons/csw/functions/fnc_getIn.sqf b/addons/csw/functions/fnc_getIn.sqf deleted file mode 100644 index 338d17e03e..0000000000 --- a/addons/csw/functions/fnc_getIn.sqf +++ /dev/null @@ -1,24 +0,0 @@ -#include "script_component.hpp" -/* - * Author: TCVM - * An action for the player to get in the CSW - * Due to the fact that the default static weapons "Get In" memory point is at the front of - * the gun and can't be acssesed from the back, I am implementing this to get around that issue. - * - * Arguments: - * 0: Static Weapon - * 1: Unit - * - * Return Value: - * None - * - * Example: - * [cursorObject, player] call ace_csw_fnc_getIn - * - * Public: No - */ - -params ["_staticWeapon", "_player"]; -TRACE_2("getIn",_staticWeapon,_player); - -_player moveInTurret [_staticWeapon, [0]]; diff --git a/addons/csw/functions/fnc_getLoadActions.sqf b/addons/csw/functions/fnc_getLoadActions.sqf new file mode 100644 index 0000000000..e505c7f50f --- /dev/null +++ b/addons/csw/functions/fnc_getLoadActions.sqf @@ -0,0 +1,57 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gets sub actions for what the unit can load into the CSW + * + * Arguments: + * 0: Vehicle + * 1: Unit + * + * Return Value: + * Actions + * + * Example: + * [cursorObject, player] call ace_csw_fnc_getLoadActions + * + * Public: No + */ + +params ["_vehicle", "_unit"]; + +private _loadableMagazines = [_vehicle, _unit] call FUNC(reload_getLoadableMagazines); +if (_loadableMagazines isEqualTo []) exitWith {[]}; + +private _statement = { + params ["_target", "_player", "_args"]; + _args params ["_carryMag", "_turretPath", "", "_magSource"]; + + [_target, _turretPath, _carryMag, _magSource, _player] call FUNC(reload_loadMagazine); +}; + +private _condition = { + params ["_target", "_player", "_args"]; + _args params ["_carryMag", "_turretPath", "", "_magSource"]; + + ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0 +}; + +private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization +private _actions = []; +{ + _x params ["_carryMag", "", "_loadInfo"]; + _loadInfo params ["", "", "", "_isBeltLinking"]; + + private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); + private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); + private _text = if (_isBeltLinking) then { + format [LLSTRING(actionLink), _displayName]; + } else { + format [LLSTRING(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_getUnloadActions.sqf b/addons/csw/functions/fnc_getUnloadActions.sqf new file mode 100644 index 0000000000..dd119b0622 --- /dev/null +++ b/addons/csw/functions/fnc_getUnloadActions.sqf @@ -0,0 +1,75 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gets sub actions for what can be unloaded from the CSW + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Actions + * + * Example: + * cursorObject call ace_csw_fnc_getUnloadActions + * + * Public: No + */ + +params ["_vehicle"]; + +private _statement = { + params ["_target", "_player", "_args"]; + _args params ["_vehMag", "_turretPath", "_carryMag"]; + TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag); + + private _timeToUnload = 1; + private _config = configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime"; + if (!isNull _config) then { + _timeToUnload = getNumber _config; + }; + + [ + TIME_PROGRESSBAR(_timeToUnload), + [_target, _turretPath, _player, _carryMag, _vehMag], + { + (_this select 0) params ["_target", "_turretPath", "", "_carryMag", "_vehMag"]; + TRACE_5("unload progressBar finish",_target,_turretPath,_carryMag,_vehMag,_player); + [QGVAR(removeTurretMag), [_target, _turretPath, _carryMag, _vehMag, _player]] call CBA_fnc_globalEvent; + }, + {TRACE_1("unload progressBar fail",_this);}, + format [LLSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")], + {(_this select 0) call FUNC(reload_canUnloadMagazine)}, + ["isNotInside"] + ] call EFUNC(common,progressBar); +}; + +private _condition = { + params ["_target", "_player", "_args"]; + _args params ["_vehMag", "_turretPath", "_carryMag"]; + [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) +}; + +private _actions = []; +private _handledMagTypes = []; + +private _cfgMagazines = configFile >> "CfgMagazines"; + +// Go through magazines on static weapon and check if any are unloadable +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if ((_xAmmo > 0) && {!(_xMag in _handledMagTypes)}) then { + _handledMagTypes pushBack _xMag; + private _carryMag = _xMag call FUNC(getCarryMagazine); + if (_carryMag == "") exitWith {}; + + private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); + private _text = format [LLSTRING(unloadX), _displayName]; + private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); + private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _vehicle]; + }; +} forEach (magazinesAllTurrets _vehicle); + +TRACE_1("unloadActions",count _actions); +_actions diff --git a/addons/csw/functions/fnc_initVehicle.sqf b/addons/csw/functions/fnc_initVehicle.sqf new file mode 100644 index 0000000000..2d7241029f --- /dev/null +++ b/addons/csw/functions/fnc_initVehicle.sqf @@ -0,0 +1,102 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Initializes CSW systems on vehicle + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_csw_fnc_initVehicle + * + * Public: No + */ + +params ["_vehicle"]; +if (!alive _vehicle) exitWith { WARNING_1("%1 not alive",_vehicle); }; +if (!simulationEnabled _vehicle) exitWith { + [{simulationEnabled _this}, FUNC(initVehicle), _vehicle] call CBA_fnc_waitUntilAndExecute; +}; + +private _typeOf = typeOf _vehicle; +private _configOf = configOf _vehicle; +private _configEnabled = (getNumber (_configOf >> QUOTE(ADDON) >> "enabled")) == 1; +private _assemblyConfig = _configEnabled && {(getText (_configOf >> QUOTE(ADDON) >> "disassembleWeapon")) != ""}; +TRACE_4("initVehicle",_vehicle,_typeOf,_configEnabled,_assemblyConfig); + +if (_configEnabled && {GVAR(ammoHandling) == 2}) then { + TRACE_1("adding AI fired handler",_vehicle); + _vehicle addEventHandler ["Fired", LINKFUNC(ai_handleFired)]; + _vehicle addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo +}; + +TRACE_2("",local _vehicle,_vehicle turretLocal [0]); +if (_configEnabled && {_vehicle turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon + [{ + params ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; + // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] + private _assemblyModeIndex = _vehicle getVariable [QGVAR(assemblyMode), 3]; + private _emptyWeapon = _assemblyModeIndex isEqualTo 2; + private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select _assemblyModeIndex; + TRACE_2("turretLocal",_vehicle,_assemblyMode); + [_vehicle, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon); + [_vehicle, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags); + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly +}; + +if (_assemblyConfig) then { + [{ + params ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; + private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]); + TRACE_2("assemblyConfig present",_vehicle,_assemblyMode); + if (_assemblyMode) then { // Disable vanilla assembly if assemblyMode enabled + [_vehicle, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + }; + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly +}; + +// Add interactions for players +if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { + GVAR(initializedStaticTypes) pushBack _typeOf; + TRACE_1("Adding Actions",_typeOf); + + if (_assemblyConfig) then { + private _disassembleAction = [QGVAR(disassemble), LLSTRING(DisassembleCSW_displayName), "", LINKFUNC(assemble_pickupWeapon), LINKFUNC(assemble_canPickupWeapon)] call EFUNC(interact_menu,createAction); + [_typeOf, 0, ["ACE_MainActions"], _disassembleAction] call EFUNC(interact_menu,addActionToClass); + }; + + + private _ammoActionPath = []; + private _magazineLocation = getText (_configOf >> QUOTE(ADDON) >> "magazineLocation"); + private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + // If magazine handling is enabled or weapon assembly/disassembly is enabled we enable ammo handling + if ((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false }; + [_player, _target, ["isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith) + }; + private _childenCode = { + BEGIN_COUNTER(getActions); // can remove for final release + private _ret = (call FUNC(getLoadActions)) + (call FUNC(getUnloadActions)); + END_COUNTER(getActions); + _ret + }; + if (_configEnabled && {_magazineLocation != ""}) then { + private _positionCode = compile _magazineLocation; + private _ammoAction = [QGVAR(magazine), LLSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode, [], _positionCode, 4] call EFUNC(interact_menu,createAction); + _ammoActionPath = [_typeOf, 0, [], _ammoAction] call EFUNC(interact_menu,addActionToClass); + } else { + private _ammoAction = [QGVAR(magazine), LLSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode] call EFUNC(interact_menu,createAction); + _ammoActionPath = [_typeOf, 0, ["ACE_MainActions"], _ammoAction] call EFUNC(interact_menu,addActionToClass); + }; + + if (["ace_reload"] call EFUNC(common,isModLoaded)) then { + // move reload's check ammo action to the ammo handling point (remove and re-add) + [_typeOf, 0, ["ACE_MainActions", QEGVAR(reload,CheckAmmo)]] call EFUNC(interact_menu,removeActionFromClass); + private _checkAmmoAction = [QGVAR(checkAmmo), LELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), EFUNC(reload,canCheckAmmo)] call EFUNC(interact_menu,createAction); + [_typeOf, 0, _ammoActionPath, _checkAmmoAction] call EFUNC(interact_menu,addActionToClass); + }; +}; diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index 3e47fddadd..fedd1d412b 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM), PabstMirror - * Handles the use of proxy weapons to fix engine-reload times + * Author: tcvm, PabstMirror + * Handles the use of proxy weapons to bypass engine reload times * * Arguments: - * 0: Weapon + * 0: Vehicle * 1: Turret * 2: Proxy weapon needed * 2: Weapon should be emptied @@ -13,32 +13,34 @@ * None * * Example: - * [weapon, [0], true, false] call ace_csw_fnc_proxyWeapon + * [cursorObject, [0], true, false] call ace_csw_fnc_proxyWeapon * * Public: No */ -params ["_staticWeapon", "_turret", "_needed", "_emptyWeapon"]; -TRACE_4("proxyWeapon",_staticWeapon,_turret,_needed,_emptyWeapon); +params ["_vehicle", "_turret", "_needed", "_emptyWeapon"]; +TRACE_4("proxyWeapon",_vehicle,_turret,_needed,_emptyWeapon); -if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); }; +if (_vehicle getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _vehicle); }; -private _typeOf = typeOf _staticWeapon; -private _proxyWeapon = getText(configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "proxyWeapon"); +private _proxyWeapon = getText (configOf _vehicle >> QUOTE(ADDON) >> "proxyWeapon"); -TRACE_2("",_typeOf,_proxyWeapon); +TRACE_2("",typeOf _vehicle,_proxyWeapon); if (_proxyWeapon == "") exitWith {}; -private _currentWeapon = (_staticWeapon weaponsTurret [0]) param [0, "#none"]; +private _currentWeapon = (_vehicle weaponsTurret [0]) param [0, "#none"]; if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then { // check if string is a function TRACE_1("Calling proxyWeapon function",_proxyWeapon); // This function may replace magazines or do other things to the static weapon - _proxyWeapon = [_staticWeapon, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); + _proxyWeapon = [_vehicle, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); _needed = _proxyWeapon != ""; }; if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; +// Rearm compatibility, prevent reloading entire static and breaking CSW +_vehicle setVariable [QEGVAR(rearm,scriptedLoadout), true, true]; + TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon); -_staticWeapon removeWeaponTurret [_currentWeapon, _turret]; -_staticWeapon addWeaponTurret [_proxyWeapon, _turret]; -_staticWeapon setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true]; +_vehicle removeWeaponTurret [_currentWeapon, _turret]; +_vehicle addWeaponTurret [_proxyWeapon, _turret]; +_vehicle setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true]; diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf deleted file mode 100644 index c5e7a3b574..0000000000 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ /dev/null @@ -1,56 +0,0 @@ -#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 deleted file mode 100644 index 34b77b3c6b..0000000000 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ /dev/null @@ -1,81 +0,0 @@ -#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 index 505c920333..70c673299a 100644 --- a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: PabstMirror & TCVM + * 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 + * 3: Supplier * * Return Value: * [CanLoad, LoadedMag, AmmoNeeded, IsBeltLinking] @@ -18,17 +18,31 @@ * Public: No */ -params ["_vehicle", "_turret", "_carryMag", ["_unit", objNull]]; -// TRACE_4("reload_canLoadMagazine",_vehicle,_turret,_carryMag,_unit); +params ["_vehicle", "_turret", "_carryMag", ["_magSource", objNull]]; +// TRACE_4("reload_canLoadMagazine",_vehicle,_turret,_carryMag,_magSource); + +private _return = [false, "", -2, false]; // 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] }; +if (!alive _vehicle) exitWith { _return }; +// Verify holder has carry magazine +if ( + (!isNull _magSource) && + {!((_magSource isKindOf "Bag_Base") || {_magSource isKindOf "ContainerSupply"})} && // hacky workaround for magazines within dropped backpacks + { + ((_vehicle distance _magSource) > 10) || + {((magazineCargo _magSource) findIf {_x == _carryMag}) == -1} + } +) exitWith { _return }; -private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "desiredAmmo"); +// solve config lookups +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgMagazinesCarryMag = _cfgMagazines >> _carryMag; +private _cfgGroupsCarryMag = configFile >> QGVAR(groups) >> _carryMag; + +private _desiredAmmo = getNumber (configOf _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 _ammoNeeded = _desiredAmmo min getNumber (_cfgMagazinesCarryMag >> "count"); // assume it needs full carry mag private _loadedMag = ""; private _isBeltLinking = false; @@ -40,13 +54,13 @@ scopeName "main"; _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 { + if (getNumber (_cfgGroupsCarryMag >> _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 { + if (getNumber (_cfgMagazinesCarryMag >> "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"); + private _maxMagazineAmmo = _desiredAmmo min getNumber (_cfgMagazines >> _xMag >> "count"); if (_xAmmo >= _maxMagazineAmmo) exitWith { [false, _loadedMag, -6, false] breakOut "main"; // Already at capicity }; diff --git a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf index 2ce6b6e591..4e03625a29 100644 --- a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Tests if unit can unload a magazine from a static weapon. diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 8e6f3ce500..724ee4d09c 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Gets magazines that the player is carrying that can be loaded into the static weapon @@ -9,7 +9,7 @@ * * Return Value: * Mags - * [Carry Magazine , Turret Path , Ammo Needed ] + * [Carry Magazine , Turret Path , Load Info , Magazine Source ] * * Example: * [cursorObject, player] call ace_csw_fnc_reload_getLoadableMagazines @@ -19,15 +19,37 @@ params ["_vehicle", "_player"]; -private _carriedMagazines = []; +private _magGroupsConfig = configFile >> QGVAR(groups); // so we don't solve in loop every time +private _availableMagazines = createHashMap; // slower than array, still needed for setting source of magazine + +// filter enemy & player units while allowing pulling from friendly AI, crates, etc +private _nearSupplies = ((_vehicle nearSupplies 10) select { + isNull (group _x) || + {!([_x] call EFUNC(common,isPlayer)) && {[side group _player, side group _x] call BIS_fnc_sideIsFriendly}} +}); + +// backpacks/uniforms/etc need to be added manually. +// array can't be modified while iterating, use copy +{ + { + _x params ["_classname", "_container"]; + _nearSupplies pushBack _container; + } forEach (everyContainer _x); +} forEach ((+_nearSupplies) select {(everyContainer _x) isNotEqualTo []}); + +// add caller to list of sources +_nearSupplies = [_player] + _nearSupplies; { - if (isClass (configFile >> QGVAR(groups) >> _x)) then { - _carriedMagazines pushBackUnique _x; - }; -} forEach (magazines _player); + private _xSource = _x; + private _mags = magazineCargo _xSource; -if (_carriedMagazines isEqualTo []) exitWith { [] }; // fast exit if no carry mags + { + _availableMagazines set [_x, _xSource]; + } forEach (_mags select {isClass (_magGroupsConfig >> _x)}); +} forEach _nearSupplies; + +if (_availableMagazines isEqualTo createHashMap) exitWith { [] }; // fast exit if no available mags private _loadInfo = []; private _return = []; @@ -37,14 +59,19 @@ private _return = []; { private _weapon = _x; { + //IGNORE_PRIVATE_WARNING ["_x", "_y"]; private _carryMag = _x; - private _carryGroup = configFile >> QGVAR(groups) >> _carryMag; + private _magSource = _y; + private _carryGroup = _magGroupsConfig >> _carryMag; { - if (((getNumber (_carryGroup >> _x)) == 1) && {_loadInfo = [_vehicle, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine); _loadInfo select 0}) exitWith { - _return pushBack [_carryMag, _turretPath, _loadInfo]; + if ( + ((getNumber (_carryGroup >> _x)) == 1) && + {_loadInfo = [_vehicle, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine); _loadInfo select 0} + ) exitWith { + _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource]; }; - } forEach ([_weapon] call CBA_fnc_compatibleMagazines); - } forEach _carriedMagazines; + } forEach (compatibleMagazines _weapon); + } forEach _availableMagazines; } forEach (_vehicle weaponsTurret _turretPath); } forEach (allTurrets _vehicle); // Note: these nested forEach's looks terrible, but most only have one element diff --git a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf index b6265852c9..6b5b77efee 100644 --- a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf +++ b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf @@ -1,11 +1,12 @@ -#include "script_component.hpp" +#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 + * 0: Vehicle + * 1: Turret + * 2: Magazine that is carryable * * Return Value: * Vehicle Magazine @@ -20,7 +21,7 @@ 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"); +private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); if (_desiredAmmo == 0) then { _desiredAmmo = 100; }; private _bestMag = "#"; diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index 841192864a..d7af22d319 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -1,15 +1,16 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM, PabstMirror + * Author: tcvm, PabstMirror * Handles adding ammo to a turret * Called from a global event but only runs where turret is local * * Arguments: * 0: Static Weapon * 1: Turret Path - * 2: Unit doing action + * 2: Source of magazine * 3: Vehicle Magazine * 4: Ammo in magazine + * 5: Unit or object to return ammo to * * Return Value: * None @@ -20,18 +21,18 @@ * Public: No */ -params ["_vehicle", "_turret", "_unit", "_carryMag" ,"_ammoRecieved"]; -TRACE_5("reload_handleAddTurretMag",_vehicle,_turret,_unit,_carryMag,_ammoRecieved); +params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_returnTo", _magSource]]; +TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); -TRACE_2("",local _vehicle, _vehicle turretLocal _turret); -if (!(_vehicle turretLocal _turret)) exitWith {}; +TRACE_2("",local _vehicle,_vehicle turretLocal _turret); +if !(_vehicle turretLocal _turret) exitWith {}; ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"]; TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking); -private _ammoRemaining = _ammoRecieved; +private _ammoRemaining = _ammoReceived; if (_canAdd) then { - private _ammoUsed = _neededAmmo min _ammoRecieved; + private _ammoUsed = _neededAmmo min _ammoReceived; _ammoRemaining = _ammoRemaining - _ammoUsed; if (_isBeltLinking) then { @@ -42,11 +43,10 @@ if (_canAdd) then { // setMagazineTurretAmmo is broken on split locality, use setAmmo for now (this may not work for multi turret vehicles) private _weapon = (_vehicle weaponsTurret _turret) param [0, ""]; - TRACE_3("setAmmo",_vehicle,_weapon, _currentAmmo); + TRACE_3("setAmmo",_vehicle,_weapon,_currentAmmo); _vehicle setAmmo [_weapon, _currentAmmo]; private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret]; - if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1", _this); }; - + if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1",_this); }; } else { if (_loadedMag != "") then { TRACE_1("Removing emtpy mag",_loadedMag); @@ -60,7 +60,6 @@ if (_canAdd) then { }; if (_ammoRemaining > 0) then { - TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemaining); - [QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemaining], _unit] call CBA_fnc_targetEvent; + TRACE_3("Returning ammo",_returnTo,_carryMag,_ammoRemaining); + [QGVAR(returnAmmo), [_returnTo, _carryMag, _ammoRemaining], _returnTo] call CBA_fnc_targetEvent; }; - diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index 1e64bf82f5..51036b525a 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM + * Author: tcvm * Handles removing ammo from a turret * Called from a global event but only runs where turret is local * @@ -9,7 +9,7 @@ * 1: Turret Path * 2: Magainze Unit Can Carry * 3: Magazine To Remove From Static - * 4: Unit to unload to + * 4: Unit or container to unload to * * Return Value: * None @@ -20,11 +20,11 @@ * Public: No */ -params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unit"]; -TRACE_6("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unit); +params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unloadTo"]; +TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unloadTo); -TRACE_3("",local _vehicle, _vehicle turretLocal _turretPath,local _unit); -if (!(_vehicle turretLocal _turretPath)) exitWith {}; +TRACE_3("",local _vehicle,_vehicle turretLocal _turretPath,local _unloadTo); +if !(_vehicle turretLocal _turretPath) exitWith {}; private _magsInWeapon = []; // Check how much ammo it has now: { @@ -37,7 +37,7 @@ TRACE_1("",_magsInWeapon); // Remove any empty mags from start: private _ammoInFirstMag = 0; -while {(!(_magsInWeapon isEqualTo [])) && {_ammoInFirstMag = _magsInWeapon deleteAt 0; (_ammoInFirstMag == 0)}} do { +while {(_magsInWeapon isNotEqualTo []) && {_ammoInFirstMag = _magsInWeapon deleteAt 0; (_ammoInFirstMag == 0)}} do { TRACE_1("Removing empty mag",_ammoInFirstMag); _vehicle removeMagazineTurret [_vehMag, _turretPath]; }; @@ -55,10 +55,10 @@ if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag > _ammoRemoved}) then { // setMagazineTurretAmmo is broken on split locality, use setAmmo for now private _weapon = (_vehicle weaponsTurret _turretPath) param [0, ""]; - TRACE_3("setAmmo",_vehicle,_weapon, _ammoLeft); + TRACE_3("setAmmo",_vehicle,_weapon,_ammoLeft); _vehicle setAmmo [_weapon, _ammoLeft]; private _currentAmmo = _vehicle magazineTurretAmmo [_vehMag, _turretPath]; - if ((_weapon == "") || {_currentAmmo != _ammoLeft}) then { ERROR_1("failed to setAmmo - %1", _this); }; + if ((_weapon == "") || {_currentAmmo != _ammoLeft}) then { ERROR_1("failed to setAmmo - %1",_this); }; } else { @@ -75,5 +75,5 @@ if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag > _ammoRemoved}) then { } forEach _magsInWeapon; }; -TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemoved); -[QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemoved], _unit] call CBA_fnc_targetEvent; +TRACE_3("Returning ammo",_unloadTo,_carryMag,_ammoRemoved); +[QGVAR(returnAmmo), [_unloadTo, _carryMag, _ammoRemoved], _unloadTo] call CBA_fnc_targetEvent; diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index 0cb632bdcb..ca445400b0 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: TCVM and PabstMirror + * Author: tcvm and PabstMirror * Handles returned ammo (either from unloading or leftovers from linking) * * Arguments: @@ -25,11 +25,11 @@ private _fullMagazines = floor (_ammo / _carryMaxAmmo); private _bulletsRemaining = _ammo % _carryMaxAmmo; if (_unloadTo isKindOf "CaManBase") then { - while {(_fullMagazines > 0) && {_unloadTo canAdd _carryMag}} do { + while {(_fullMagazines > 0) && {[_unloadTo, _carryMag] call CBA_fnc_canAddItem}} do { _unloadTo addMagazine [_carryMag, _carryMaxAmmo]; _fullMagazines = _fullMagazines - 1; }; - if ((_bulletsRemaining > 0) && {_unloadTo canAdd _carryMag}) then { + if ((_bulletsRemaining > 0) && {[_unloadTo, _carryMag] call CBA_fnc_canAddItem}) then { _unloadTo addMagazine [_carryMag, _bulletsRemaining]; _bulletsRemaining = 0; }; @@ -39,19 +39,18 @@ 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 ((_container distance _unloadTo) > 10) then { _container = objNull; }; if (isNull _container) then { - _container = (nearestObjects [_unloadTo, ["groundWeaponHolder"], 4]) param [0, objNull]; + _container = (nearestObjects [_unloadTo, [["GroundWeaponHolder"], [QGVAR(ammo_holder)]] select GVAR(handleExtraMagazinesType), 10]) param [0, objNull]; }; if (isNull _container) then { - // Create ground weapon holder container + // Create ammo storage 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 = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "NONE"]; + _unloadTo setVariable [QGVAR(container), _container, true]; _container setDir random [0, 180, 360]; _container setPosATL _weaponRelPos; if ((_weaponRelPos select 2) < 0.5) then { diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 25032a08f4..50081a87a5 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -1,38 +1,40 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Loads a magazine into a static weapon from a magazine carried by the player. + * Loads a magazine into a static weapon from a magazine carried by or next to the player. * * Arguments: * 0: Vehicle * 1: Turret * 2: Unit Carried Magazine - * 3: Player + * 3: Magazine source + * 4: Unit doing the action * * Return Value: * None * * Example: - * [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_loadMagazine + * [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", player, player] call ace_csw_fnc_reload_loadMagazine * * Public: No */ -params ["_vehicle", "_turret", "_carryMag", "_unit"]; -TRACE_4("loadMagazine",_vehicle,_turret,_carryMag,_unit); +params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; +TRACE_5("loadMagazine",_vehicle,_turret,_carryMag,_magSource,_unit); private _timeToLoad = 1; -if (!isNull(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "ammoLoadTime")) then { - _timeToLoad = getNumber(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "ammoLoadTime"); +private _config = configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime"; +if (!isNull _config) then { + _timeToLoad = getNumber _config; }; -private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; +private _displayName = format [LLSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; private _onFinish = { - (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_unit"]; - TRACE_4("load progressBar finish",_vehicle,_turret,_carryMag,_unit); + (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; + TRACE_5("load progressBar finish",_vehicle,_turret,_carryMag,_magSource,_unit); - ([_vehicle, _turret, _carryMag, _unit] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""]; + ([_vehicle, _turret, _carryMag, _magSource] 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 @@ -44,23 +46,23 @@ private _onFinish = { _bestAmmoToSend = _xAmmo; }; }; - } forEach (magazinesAmmo _unit); + } forEach (if (_magSource isKindOf "CAManBase") then {magazinesAmmo _magSource} else {magazinesAmmoCargo _magSource}); if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);}; - [_unit, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); + [_magSource, _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; + TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend,_unit); + [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] 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"] + TIME_PROGRESSBAR(_timeToLoad), + [_vehicle, _turret, _carryMag, _magSource], + _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 deleted file mode 100644 index 4ce86f3c49..0000000000 --- a/addons/csw/functions/fnc_staticWeaponInit.sqf +++ /dev/null @@ -1,95 +0,0 @@ -#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 index bd73df878c..98200840a3 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM), PabstMirror + * Author: tcvm, PabstMirror * Dumps ammo to container * * Arguments: @@ -20,7 +20,7 @@ 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 _desiredAmmo = getNumber (configOf _staticWeapon >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); if (_emptyWeapon) then { _desiredAmmo = 0; @@ -36,13 +36,7 @@ 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); - }; + private _carryMag = _xMag call FUNC(getCarryMagazine); if (_carryMag != "") then { if ((_desiredAmmo > 0) && {_loadedMagazineInfo isEqualTo []}) then { private _loadedMagAmmo = _desiredAmmo min _xAmmo; @@ -74,6 +68,39 @@ TRACE_1("Remove all loaded magazines",_magsToRemove); }; } forEach _magsToRemove; +private _secondaryWeaponMagazines = _staticWeapon getVariable [QGVAR(secondaryWeaponMagazines), []]; + +if (_secondaryWeaponMagazines isNotEqualTo []) then { + // Check if the static weapon can take magazines + private _turret = (allTurrets _staticWeapon) param [0, []]; + private _compatibleMagazinesTurret = flatten ((_staticWeapon weaponsTurret _turret) apply {compatibleMagazines _x}); + private _container = objNull; + + { + private _vehicleMag = [_staticWeapon, _turret, _x select 0] call FUNC(reload_getVehicleMagazine); + TRACE_3("Re-add previous mag",_x select 0,_turret,_vehicleMag); + + // If the magazine can be added to the static weapon, do it now + if (_vehicleMag in _compatibleMagazinesTurret) then { + _staticWeapon addMagazineTurret [_vehicleMag, _turret, _x select 1]; + } else { + // Find a suitable container to place items in if necessary + if (isNull _container) then { + _container = (nearestObjects [_staticWeapon, ["GroundWeaponHolder"], 10]) param [0, objNull]; + + // Create ammo storage container + if (isNull _container) then { + _container = createVehicle ["GroundWeaponHolder", getPosATL _staticWeapon, [], 0, "NONE"]; + }; + }; + + // If the mag can't be added to the static weapon, add it to the ground holder + _container addMagazineAmmoCargo [_x select 0, 1, _x select 1]; + }; + } forEach _secondaryWeaponMagazines; + + _staticWeapon setVariable [QGVAR(secondaryWeaponMagazines), nil, true]; +}; if (_storeExtraMagazines) then { TRACE_1("saving extra mags to container",_containerMagazineCount); diff --git a/addons/csw/functions/script_component.hpp b/addons/csw/functions/script_component.hpp deleted file mode 100644 index 7e8eaa8954..0000000000 --- a/addons/csw/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\csw\script_component.hpp" diff --git a/addons/csw/initSettings.inc.sqf b/addons/csw/initSettings.inc.sqf new file mode 100644 index 0000000000..bc157e1164 --- /dev/null +++ b/addons/csw/initSettings.inc.sqf @@ -0,0 +1,56 @@ +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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(handleExtraMagazinesType), "LIST", + [LSTRING(handleExtraMagazinesType_displayName), LSTRING(handleExtraMagazinesType_description)], + _categoryArray, + [[0, 1], [LSTRING(handleExtraMagazinesType_weaponHolder), LSTRING(handleExtraMagazinesType_ammoBox)], 0], + true, // isGlobal + {[QGVAR(handleExtraMagazinesType), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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 +] call CBA_fnc_addSetting; + +[ + QGVAR(dragAfterDeploy), "CHECKBOX", + [LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)], + _categoryArray, + false // default value +] call CBA_fnc_addSetting; diff --git a/addons/csw/initSettings.sqf b/addons/csw/initSettings.sqf deleted file mode 100644 index 868597f94c..0000000000 --- a/addons/csw/initSettings.sqf +++ /dev/null @@ -1,43 +0,0 @@ -// 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; diff --git a/addons/csw/script_config_macros_csw.hpp b/addons/csw/script_config_macros_csw.hpp index 1a0e1b3be5..6701159f29 100644 --- a/addons/csw/script_config_macros_csw.hpp +++ b/addons/csw/script_config_macros_csw.hpp @@ -1,15 +1 @@ #define CREATE_CSW_PROXY(weapon) class ##weapon; class GVAR(weapon): ##weapon { magazineReloadTime = 0.5; } - -// Need to be careful about breaking Attributes inheritance, doesn't seem to be any standard -#define ENABLE_CSW_ATTRIBUTE class Attributes { \ - class EGVAR(CSW,assemblyMode) { \ - property = QEGVAR(CSW,assemblyMode); \ - control = QEGVAR(CSW,assemblyModeControl); \ - displayName = ECSTRING(CSW,eden_enableCSW); \ - tooltip = ECSTRING(CSW,eden_enableCSW_tooltip); \ - expression = QUOTE( if (_value != 3) then {_this setVariable [ARR_3('%s',_value,true)]} ); \ - typeName = "NUMBER"; \ - condition = "objectVehicle"; \ - defaultValue = 3; \ - }; \ - } diff --git a/addons/csw/stringtable.xml b/addons/csw/stringtable.xml index b16543e55a..da794376ab 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -3,236 +3,1139 @@ Crew Served Weapons + Crew Served Weapons + Crew Served Weapons (CSW) + Armes statiques + 共用火器 (CSW) + 班組支援武器 + 班组支援武器 + Armi servite dall'equipaggio + Posádkou obsluhované zbraně (CSW) + Broń ciężka (CSW) + Armas provistas por la tripulación + Групповое вооружение (CSW) + 공용화기(CSW) Place Tripod + Platziere Dreibein + Montar Tripé + Placer le trépied + 三脚を設置 + 設置三腳架 + 安放三脚架 + Piazza treppiede + Položit trojnožku + Rozłóż Trójnóg + Colocar trípode + Üçayağı Yerleştir + Разложить треногу + 삼각대 설치하기 Disassemble Rozložit Démonter - %1 demontieren - Disassemblare + Auseinandernehmen + Disassembla Złóż Desmontar Разобрать Desmonta + 解体 + 拆解 + 拆解 + Sök + 분해하기 Get In Nastup - Embarquer + Entrer Einsteigen - A bordo + Entra Wsiadać Entrar Войти Entrar + 乗り込む + 進入 + 进入 + Bin + 탑승하기 Load %1 Lade %1 - Load %1 + Cargar %1 Nabít %1 - Load %1 + Charger %1 Załaduj %1 - Load %1 + Carica %1 Загрузить %1 Load %1 + Carregar %1 + %1 を装填 + 裝填 %1 + 装填 %1 + Yükle %1 + %1 싣기 Unload %1 Entlade %1 - Unload %1 + Descargar %1 Vytáhnout zásobník z %1 - Unload %1 + Décharger %1 Rozładuj %1 - Unload %1 + Scarica %1 Разгрузить %1 Unload %1 + Descarregar %1 + %1 を除去 + 卸載 %1 + 卸载 %1 + Boşalt %1 + %1 내리기 Link %1 + Verbinde %1 + Conectar %1 + Connecter %1 + %1 を接続 + 聯結至 %1 + 连接 %1 + Collega %1 + Spojit %1 + Połącz %1 + Conectar %1 + Соединить %1 + %1 연결 - Advanced assembly + Advanced Assembly + Erweiterter Zusammenbau + Montagem Avançada + Assemblage avancé + 高度な組み立て + 進階組裝 + 高级组装 + Montaggio avanzato + Pokročilé skládání + Zaawansowane składanie + Ensamblado avanzado + Продвинутая сборка + 고급 조립 - Use ace for Assemble/Disassemble of supported static weapons. Loaded ammo is reduced to a single magazine. + Use ACE for Assemble/Disassemble of supported static weapons. Loaded ammo is reduced to a single magazine. + Benutze ACE um unterstützte statische Waffen zu montieren/demontieren. Geladene Munition ist auf ein einzelnes Magazin reduziert. + Usar o ACE para Montar/Desmontar armas estáticas suportadas. Munição carregada é reduzida para um único carregador. + Utilise ACE pour l'assemblage/le désassemblage des armes statiques supportées.\nLes munitions chargées sont réduites à un seul chargeur. + 対応している設置型火器に ACE の設置と解体を使用します。装填済みの弾倉は1つの弾倉のみに減少します。 + 使用ACE來組裝/拆解固定型武器。上膛的限制為單個彈匣。 + 使用 ACE 来组装/拆解固定式武器。限制弹药为一个弹匣。 + Utilizza ACE per assemblaggio/smontaggio di armi statiche supportate. Le munizioni caricate sono ridotte ad un solo caricatore. + Použít ACE pro složení/rozložení podporovaných statických zbraní. Nabitá munice je snížená na jeden zásobník. + Użyj ACE do składania/rozkładania broni statycznych. Załadowana amunicja zostaje zredukowana do jednego magazynku. + Usar el ACE para el ensamblado/desamblado de armas estáticas soportadas. La munición cargada es reducida a un sólo cargador + Использовать ACE для сборки/разборки поддерживаемого статического оружия. Заряженные боеприпасы будут сокращены в единственный магазин. + ACE의 조립/분해 기능을 사용하여 공용화기를 다룹니다. 장전된 탄은 한 탄창으로 제한됩니다. - Save extra ammo + Save Extra Ammo + Spare extra Munition + Economizar munição extra + Conserver le surplus de munitions + 追加の弾薬を保持 + 保存額外彈藥 + 保存额外弹药 + Conserva munizioni extra + Uložit munici navíc. + Zapisz dodatkową amunicje + Guardar munición extra + Сохранить дополнительные боеприпасы + 남은 탄약 저장 Store extra magazines next to static weapon + Lager extra Magazine neben der statischen Waffe + Carregar munições extras próximo à arma estática + Range les chargeurs en surplus auprès de l'arme statique. + 追加の弾倉を固定火器の横に保管します。 + 在固定型武器旁存放額外彈匣 + 在固定式武器旁边存放额外的弹匣 + Conserva i caricatori extra accanto all'arma statica + Ukládat munici navíc vedle statické zbraně. + Dodatkowe magazynki przechowuj obok broni statycznej + Almacenar cargadores extra junto al arma estática + Хранить дополнительные магазины рядом со статическим оружием + 공용화기 옆에 남은 탄들을 저장합니다. + + + Ammo Storage + Munitionslager + Scorta di munizioni + 탄약 보관 + Magazyn amunicji + 弾薬保管位置 + 弹药存储 + Хранилище боеприпасов + Almacenamiento de munición + Stockage des munitions + Armazenamento de Munição + + + Determines whether extra magazines are stored on the ground or inside an ammo box + Legt fest, ob zusätzliche Magazine auf dem Boden oder in einer Munitionskiste aufbewahrt werden + Determina se ulteriori caricatori verranno stoccati sul suolo o in una cassa di munizioni. + 여분의 탄약을 지면 또는 탄약 상자에 넣을 지 결정합니다. + Decyduje, czy dodatkowe magazynki przechowywane są na ziemi, czy w skrzynce z amunicją. + 追加の弾倉を地面に直接配置するか、弾薬箱内に保管するかを設定します。 + 设置多余的弹夹是存放在地面上还是弹药箱内 + Определяет будут ли дополнительные магазины лежать на земле или внутри хранилища + Determina si los cargadores extra son almacenados en el suelo o en una caja de munición + Détermine si les chargeurs supplémentaires sont stockés par terre ou dans une caisse de munitions. + Determina se munições extras são armazenadas no chão ou dentro de uma caixa de munição + + + Ground + Boden + Suolo + 지면 + Ziemia + 地面 + 地面 + Земля + Suelo + Sol + Solo + + + Ammo Box + Munitionskiste + Cassa di munizioni + 탄약 상자 + Skrzynka amunicyjna + 弾薬箱 + 弹药箱 + Коробка с боеприпасами + Caja de munición + Caisse de munitions + Caixa de Munição Ammo handling + Munitionsmanagement + Manipulação de Munições + Manipulation des munitions + 弾薬の処理 + 彈藥處理 + 弹药处置 + Gestione delle munizioni + Manipulace s municí + Obsługa amunicji + Manejo de munición + Обслуживание боеприпасов + 탄약 취급 Allow loading and unloading magazines + Erlaubt es Magazine zu- und entladen. + Permite carregamento e descarregamento de munições + Définit qui peut charger et décharger les chargeurs. + 弾薬の装填と除去を許可します。 + 允許裝填或卸載彈匣 + 允许装卸弹匣 + Permetti caricamento e scaricamento delle munizioni + Povolit nabíjení a vybíjení zásobníků. + Zezwalaj na ładowanie i rozładowywanie magazynków + Permitir la carga y descarga de cargadores + Разрешить загрузку и разгрузку магазинов + 탄을 장전하고 빼는 걸 가능하게 합니다. Interaction Time Coefficent + Interaktionsdauerkoeffizient + Coeficiente de tempo para a interação + Coefficient du temps d'interaction + インタラクションの所要時間係数 + 互動時間係數 + 交互时间系数 + Coefficiente per il tempo di interazione + Koeficient času interakce + Współczynnik czasu interakcji + Coeficiente de tiempo de interacción + Коэф. времени взаимодействия + 상호작용 시간 계수 Scales time required to assemble and reload static weapons + Skaliert die Zeit die benötigt wird um statische Waffen aufzubauen und nachzuladen. + Escala o tempo requerido para montar e recarregar armas estáticas. + Définit l'échelle de temps nécessaire à l'assemblage et au rechargement des armes statiques. + 設置型火器の設置と再装填の所要時間を管理できます。 + 設置組裝及裝填組裝固定型武器 + 衡量组装和重新装填固定式武器所需的时间 + Tempo necessario per assemblare e ricaricare le armi statiche + Škáluje čas potřebný ke skládání a přebíjení statických zbraní. + Definiuje czas potrzebny do złożenia i przeładowania broni statycznej + Escala el tiempo requerida para ensamblar y recargar el arma estática + Изменяет время, необходимое для сборки и перезарядки статического оружия + 공용화기의 조립 및 재장전 속도를에 관여하는 계수입니다. + + + Drag Tripods after Deploying + Ziehe Dreibeine nach Aufbau + Arrastar tripés após montar + Glisser le trépied après déploiement + 設置後に三脚を引きずる + 在佈置三腳架後拖拉 + 部署后拖动三脚架 + Trascina i treppiedi dopo il montaggio + Tahat trojnožku po položení + Przeciągnij statyw po rozmieszczeniu + Arrastrar trípodes despues de desplegarlos + Тащить треногу после развертывания + 조립 후 삼각대 끌기 + + + After deploying a tripod, start dragging it to a precise location + Ziehe das Dreibein zu einer exakten Position nachdem es aufgestellt wurde. + Assim que montar um tripé, automaticamente começa a arrastá-lo para um posicionamento mais preciso + Aussitôt après avoir déployé un trépied, le joueur commence automatiquement à le glisser pour le positionner plus précisément. + 三脚を設置後、動かせるよう三脚を引きずるようにします。 + 在部署三腳架後,開始拖動它使其在你所要的精準位置 + 部署好三脚架后,开始拖动它到一个精确的位置 + Dopo aver montato un treppiede, inizia a trascinarlo su una posizione precisa + Po položení trojnožky začít automaticky tahání pro lepší polohu. + Po rozłożeniu trójnogu zacznij od przeciągania go w określone miejsce + Después de desplegar un trípode, comenzar a arrastrarlo hacia la ubicación precisa + После развертывания начать тащить треногу на другое место + 조립 후 위치선정을 위해 배치하지 않고 끌고 다닙니다. Pickup Tripod + Dreibein aufnehmen + Carregar Tripé + Récupérer le trépied + 三脚を拾う + 撿起三腳架 + 捡起三脚架 + Recupera treppiede + Složit trojnožku + Podnieś Trójnóg + Recoger trípode + Подобрать треногу + 삼각대 줍기 Mount Weapon + Waffe montieren + Montar Arma + Monter l'arme + 火器を乗せる + 裝載武器 + 装载武器 + Monta l'arma + Připevnit zbraň + Zamontuj Broń + Montar arma + Установить оружие + 무기 거치하기 Disassembling Gun... + Nehme Waffe auseinander... + Desmontando Arma... + Désassemblage de l'arme... + 火器を解体中です・・・ + 拆裝武器中... + 正在拆卸武器... + Smontaggio arma... + Rozkládám zbraň... + Rozkładanie Broni... + Desensamblando arma... + Разборка оружия... + 공용화기 분해 중... Assembling Gun... + Montiere Waffe... + Montando Arma... + Assemblage de l'arme... + 火器を組み立て中です・・・ + 組裝武器中... + 正在组装武器... + Montaggio arma... + Skládám zbraň... + Składanie Broni... + Ensamblando arma... + Сборка оружия... + 공용화기 조립 중... Picking Up Tripod... + Nehme Dreibein auf... + Carregando Tripé... + Récupération du trépied... + 三脚を回収中・・・ + 撿起三腳架... + 捡起三脚架... + Recupero treppiede... + Zvedám trojnožku... + Podnoszenie Trójnogu... + Recogiendo trípode... + Поднятие треноги... + 삼각대 줍는 중... Placing Tripod... + Platziere Dreibein... + Montando Tripé... + Installation du trépied... + 三脚を設置中です・・・ + 部署三腳架... + 部署三脚架... + Piazzamento treppiede... + Pokládám trojnožku... + Rozmieszczanie Trójnogu... + Ubicando trípode... + Размещение треноги... + 삼각대 설치 중... Enable CSW + Aktiviere CSW + Ativar CSW + Activer CSW + CSW 有効化 + 啟用CSW(班用支援武器) + 启用班组支援武器 + Attiva CSW + Povolit posádkou obsluhované zbraně (CSW) + Włącz CSW + Habilitar CSW + Включить CSW + 공용화기 활성화 Enables Crew Served ability on this weapon + Ermögliche CSW auf dieser Waffe + Ativar funções de CSW nessa arma + Active les fonctions CSW sur cette arme. + この火器で共用火器を有効化します。 + 對此武器啟用班組支援能力 + 在该武器上启用班组支援能力 + Abilita il servizio da equipaggio su quest'arma + Zapne CSW funkce na této zbrani + Włącza opcje systemu CSW na tej broni + Habilitar el manejo de uso colectivo para esta arma + Включает CSW на этом оружии + 이 무기에 공용화기 특성을 적용합니다. Enabled and Leave Weapon Empty + Aktiviere und lasse diese Waffe leer + Ativado e deixar arma vazia + Activer et laisser l'arme vide + 有効にして火器を空のままにする + 啟用並不裝填武器 + 启用并不装填武器 + Abilita e lascia l'arma vuota + Povolit a nechat zbraň prázdnou + Włącz i pozostaw broń pustą + Habilitar y dejar el arma vacía + Включено и оставить оружие пустым + 활성화 및 자리 비우기 - Tripod - Trépied - Trípode - Treppiede - Trójnóg - Dreibein - Üçayak + Tripod + Trépied + Trípode + Treppiede + Trójnóg + Dreibein + Üçayak + Tripé + 三脚 + 三腳架 + 三脚架 + Trojnožka + Тренога + 삼각대 [CSW] Static Mini-Spike Launcher (AT) + [CSW] Lanzador estático Mini-Spike (AT) + [CSW] Statische Lenkwaffe "Mini-Spike" (AT) + [CSW] Lançador Estático - Mini-Spike (AT) + [CSW] Lanceur statique Mini-Spike (AT) + [CSW] 設置型ミニ スパイク ランチャー (AT) + [CSW] 固定型 "迷你長釘"導彈發射器(對地) + [班组] 固定式"迷你长钉"导弹发射器(反坦) + [CSW] Lanciatore Mini-Spike (AT) Statico + [CSW] Statický raketomet Mini-Spike (protitankový) + [CSW] Static Mini-Spike Launcher (AT) + [CSW] Mini-Spike Przeciwpancerny pocisk rakietowy + [CSW] Станковый Mini-Spike (ПТРК) + [CSW] 거치형 Mini-Spike 발사기 (대전차) [CSW] Static Mini-Spike Launcher (AA) + [CSW] Lanzador estático Mini-Spike (AA) + [CSW] Statische Lenkwaffe "Mini-Spike" (AA) + [CSW] Lançador Estático - Mini-Spike (AA) + [CSW] Lanceur statique Mini-Spike (AA) + [CSW] 設置型ミニ スパイク ランチャー (AA) + [CSW] 固定型 "迷你長釘"導彈發射器(對空) + [班组] 固定式"迷你长钉"导弹发射器(防空) + [CSW] Lanciatore Mini-Spike (AA) Statico + [CSW] Statický raketomet Mini-Spike (protiletadlový) + [CSW] Static Mini-Spike Launcher (AA) + [CSW] Mini-Spike Przeciwlotniczy pocisk rakietowy + [CSW] Станковый Mini-Spike (ЗРК) + [CSW] 거치형 Mini-Spike 발사기 (대공) [CSW] Static XM312 Gun + [CSW] Arma estática XM312 + [CSW] Statische XM312 + [CSW] Arma Estática - XM312 + [CSW] Mitrailleuse statique XM312 + [CSW] 設置型 XM312 + [CSW] 固定型 XM312重機槍 + [班组] 固定式 XM312 重机枪 + [CSW] XM312 Statico + [CSW] Statická zbraň XM312 + [CSW] Static XM312 Gun + [CSW] Statyczny karabin maszynowy XM312 + [CSW] Станковый XM312 пулемёт + [CSW] 거치형 XM312 + + + [CSW] Static M2 w/ Shield + [CSW] M2 estática con escudo + [CSW] Statická zbraň M2 se štítem + [CSW] Mitrailleuse statique M2 ac. bouclier + [CSW] Statyczny karabin maszynowy M2 z tarczą + [CSW] Станковый M2 со щитом + [CSW] 設置型 防盾付き M2 + [CSW] Statisches M2 mit Schild + [CSW] M2 Statico con Scudo + [班组] 固定式防盾型 M2 重机枪 + [CSW] 거치형 M2 (방패) + [CSW] Arma Estática - M2 com Escudo [CSW] Static XM312 Gun (Autonomous) + [CSW] Arma estática XM312 (Autónoma) + [CSW] Statische XM312 (Autonom) + [CSW] Arma Estática - XM312 (Autônoma) + [CSW] Mitrailleuse statique XM312 (Autonome) + [CSW] 設置型 XM312 (自律型) + [CSW] 固定型 XM312重機槍(自主型) + [班组] 固定式 XM312 重机枪(自主) + [CSW] XM312 Statico (Autonomo) + [CSW] Statická zbraň XM312 (autonomická) + [CSW] Static XM312 Gun (Autonomous) + [CSW] Statyczny karabin maszynowy XM312 (Dron) + [CSW] Станковый XM312 пулемёт (автономный) + [CSW] 거치형 XM312 (자동화) [CSW] Static XM307 Gun + [CSW] Arma estática XM307 + [CSW] Statische XM307 + [CSW] Arma Estática - XM307 + [CSW] Lance-grenades statique XM307 + [CSW] 設置型 XM307 + [CSW] 固定型XM307榴彈機槍 + [班组] 固定式 XM307 榴弹发射器 + [CSW] XM307 Statico + [CSW] Statická zbraň XM307 + [CSW] Static XM307 Gun + [CSW] Statyczny granatnik automatyczny XM307 + [CSW] Станковый XM307 гранатомёт + [CSW] 거치형 XM307 [CSW] Static XM307 Gun (Autonomous) + [CSW] Arma estática XM307 (Autónoma) + [CSW] Statische XM307 (Autonom) + [CSW] Arma Estática - XM307 (Autônoma) + [CSW] Lance-grenades statique XM307 (Autonome) + [CSW] 設置型 XM307 (自律型) + [CSW] 固定型 XM307榴彈機槍(自主型) + [班组] 固定式 XM307 榴弹发射器(自主) + [CSW] XM307 Statico (Autonomo) + [CSW] Statická zbraň XM307 (autonomická) + [CSW] Static XM307 Gun (Autonomous) + [CSW] Statyczny granatnik automatyczny XM307 (Dron) + [CSW] Станковый XM307 гранатомёт (автономный) + [CSW] 거치형 XM307 (자동화) [CSW] 12.7x108mm HMG Belt + [CSW] Cinta de munición 12.7x108mm HMG + [CSW] 12.7x108mm HMG-Gurt + [CSW] Cinto de Munição - 12.7x108mm HMG + [CSW] Bande 12,7x108 mm HMG + [CSW] 12.7x108 mm HMG ベルト + [CSW]12.7x108毫米 重機槍彈鏈 + [班组] 12.7x108 mm 重机枪弹链 + [CSW] Nastro da HMG 12.7x108mm + [CSW] Pás 12.7×108mm pro těžký kulomet + [CSW] 12.7x108mm HMG Belt + [CSW] Taśma 12.7x108mm CKM + [CSW] 12.7x108 мм пулемётная лента + [CSW] 12.7x108mm 중기관총 탄띠 [CSW] 12.7x99mm HMG Belt + [CSW] Cinta de munición 12.7x99mm HMG + [CSW] 12.7x99mm HMG-Gurt + [CSW] Cinto de Munição - 12.7x99mm HMG + [CSW] Bande 12,7x99 mm HMG + [CSW] 12.7x99 mm HMG ベルト + [CSW]12.7x99毫米 重機槍彈鏈 + [班组] 12.7x99 mm 重机枪弹链 + [CSW] Nastro da HMG 12.7x99mm + [CSW] Pás 12.7×99mm pro těžký kulomet + [CSW] 12.7x99mm HMG Belt + [CSW] Taśma 12.7x99mm CKM + [CSW] 12.7x99 мм пулемётная лента + [CSW] 12.7x99mm 중기관총 탄띠 [CSW] 12.7x99mm Tracer HMG Belt (Red) + [CSW] Cinta de munición 12.7x99mm HMG Trazadora (Roja) + [CSW] 12.7x99mm Leuchtspur HMG-Gurt (Rot) + [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Vermelho) + [CSW] Bande 12,7x99 mm HMG traçantes (Rouges) + [CSW] 12.7x99 mm HMG トレーサーベルト (赤) + [CSW] 12.7x99毫米 重機槍曳光彈鏈(紅色) + [班组] 12.7x99 mm 重机枪弹链(曳光,红) + [CSW] Nastro da HMG 12.7x99mm Traccianti (Red) + [CSW] Pás 12.7×99mm pro těžký kulomet (červená stopovka) + [CSW] 12.7x99mm Tracer HMG Belt (Red) + [CSW] Taśma 12.7x99mm CKM Smugowa (Czerwona) + [CSW] 12.7x99 мм трасс. пулемётная лента (красные) + [CSW] 12.7x99mm 예광탄 중기관총 탄띠 (빨강) [CSW] 12.7x99mm Tracer HMG Belt (Green) + [CSW] Cinta de munición 12.7x99mm HMG Trazadora (Verde) + [CSW] 12.7x99mm Leuchtspur HMG-Gurt (Grün) + [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Verde) + [CSW] Bande 12,7x99 mm HMG traçantes (Vertes) + [CSW] 12.7x99 mm HMG トレーサーベルト (緑) + [CSW] 12.7x99毫米 重機槍曳光彈鏈(綠色) + [班组] 12.7x99 mm 重机枪弹链(曳光,绿) + [CSW] Nastro da HMG 12.7x99mm Traccianti (Green) + [CSW] Pás 12.7×99mm pro těžký kulomet (zelená stopovka) + [CSW] 12.7x99mm Tracer HMG Belt (Green) + [CSW] Taśma 12.7x99mm CKM Smugowa (Zielona) + [CSW] 12.7x99 мм трасс. пулемётная лента (зелёные) + [CSW] 12.7x99mm 예광탄 중기관총 탄띠 (초록) [CSW] 12.7x99mm Tracer HMG Belt (Yellow) + [CSW] Cinta de munición 12.7x99mm HMG Trazadora (Amarilla) + [CSW] 12.7x99mm Leuchtspur HMG-Gurt (Gelb) + [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Amarelo) + [CSW] Bande 12,7x99 mm HMG traçantes (Jaunes) + [CSW] 12.7x99 mm HMG トレーサーベルト (黄) + [CSW] 12.7x99毫米 重機槍曳光彈鏈(黃色) + [班组] 12.7x99 mm 重机枪弹链(曳光,黄) + [CSW] Nastro da HMG 12.7x99mm Traccianti (Yellow) + [CSW] Pás 12.7×99mm pro těžký kulomet (žlutá stopovka) + [CSW] 12.7x99mm Tracer HMG Belt (Yellow) + [CSW] Taśma 12.7x99mm CKM Smugowa (Żółta) + [CSW] 12.7x99 мм трасс. пулемётная лента (жёлтые) + [CSW] 12.7x99mm 예광탄 중기관총 탄띠 (노랑) [CSW] 20mm Grenade GMG Belt + [CSW] Cinta de munición de granadas 20mm GMG + [CSW] 20mm Granate GMG-Gurt + [CSW] Cinto de Munição - Granada 20mm GMG + [CSW] Bande grenades 20 mm GMG + [CSW] 20 mm 擲弾 GMG ベルト + [CSW]20毫米 榴彈 榴彈機槍彈鏈 + [班组] 20 mm 榴弹发射器弹链 + [CSW] Nastro di Granate 20mm da GMG + [CSW] Pás 20mm granátů pro granátomet + [CSW] 20mm Grenade GMG Belt + [CSW] Taśma 20mm do granatnika + [CSW] Лента 20-мм гранат для ст. гранатомёта + [CSW] 20mm 고속유탄발사기 탄띠 M3 Tripod + Trípode M3 + M3 Dreibein + Tripé M3 + Trépied M3 + M3 三脚 + M3 三腳架 + M3 三脚架 + Treppiede M3 + M3 trojnožka + M3 Tripod + Trójnóg M3 + Станок M3 + M3 삼각대 [CSW] 6P57 Deployable Tripod + [CSW] Trípode desplegable 6P57 + [CSW] 6P57 aufstellbares Dreibein + [CSW] 6P57 Tripé Ajustável + [CSW] 6P57 Trépied déployable + [CSW] 6P57 設置型三脚 + [CSW] 6P57 部署型三腳架 + [班组] 6P57 部署型三脚架 + [CSW] Treppiede 6P57 piazzabile + [CSW] 6P57 trojnožka + [CSW] 6P57 Deployable Tripod + [CSW] Trójnóg Rozkładany 6P57 + [CSW] 6P67 Развертываемая тренога + [CSW] 6P57 배치형 삼각대 [CSW] 6P57 Deployable Tripod (Low) + [CSW] Trípode desplegable 6P57 (Bajo) + [CSW] 6P57 aufstellbares Dreibein (Niedrig) + [CSW] 6P57 Tripé Ajustável (Baixo) + [CSW] 6P57 Trépied déployable (Bas) + [CSW] 6P57 設置型三脚 (低座) + [CSW] 6P57 部署型(低位) + [班组] 6P57 部署型(低) + [CSW] Treppiede 6P57 piazzabile (Basso) + [CSW] 6P57 trojnožka (nízká) + [CSW] 6P57 Deployable Tripod (Low) + [CSW] Trójnóg Rozkładany 6P57 (Niski) + [CSW] 6P67 Развертываемая тренога (низкая) + [CSW] 6P57 배치형 삼각대 (낮음) [CSW] M220 Deployable Tripod + [CSW] Trípode desplegable M220 + [CSW] M220 aufstellbares Dreibein + [CSW] M220 Tripé Ajustável + [CSW] M220 Trépied déployable + [CSW] M220 設置型三脚 + [CSW] M220 部署型三腳架 + [班组] M220 部署型三脚架 + [CSW] Treppiede M220 piazzabile + [CSW] M220 trojnožka + [CSW] M220 Deployable Tripod + [CSW] Trójnóg Rozkładany M220 + [CSW] M220 Развертываемая тренога + [CSW] M220 배치형 삼각대 [CSW] SAG-30 Deployable Tripod + [CSW] Trípode desplegable SAG-30 + [CSW] SAG-30 aufstellbares Dreibein + [CSW] SAG-30 Tripé Ajustável + [CSW] SAG-30 Trépied déployable + [CSW] SAG-30 設置型三脚 + [CSW] SAG-30 部署型三腳架 + [班组] SAG-30 部署型三脚架 + [CSW] Treppiede SAG-30 piazzabile + [CSW] SAG-30 trojnožka + [CSW] SAG-30 Deployable Tripod + [CSW] Trójnóg Rozkładany SAG-30 + [CSW] SAG-30 Развертываемая тренога + [CSW] SAG-30 배치형 삼각대 6P57 Tripod + Trípode desplegable 6P57 + 6P57 Dreibein + Tripé 6P57 + Trépied 6P57 + 6P57 三脚 + 6P57 三腳架 + 6P57 三脚架 + Treppiede 6P57 + 6P57 trojnožka + 6P57 Tripod + Trójnóg 6P57 + 6P67 Тренога + 6P57 삼각대 SAG-30 Tripod + Trípode SAG-30 + SAG-30 Dreibein + Tripe SAG-30 + Trépied SAG-30 + SAG-30 三脚 + SAG-30 三腳架 + SAG-30 三脚架 + Treppiede SAG-30 + SAG-30 trojnožka + SAG-30 Tripod + Trójnóg SAG-30 + SAG-30 Тренога + SAG-30 삼각대 M220 Tripod + Trípode M220 + M220 Dreibein + Tripé M220 + Trépied M220 + M220 三脚 + M220 三腳架 + M220 三脚架 + Treppiede M220 + M220 trojnožka + M220 Tripod + Trójnóg M220 + M220 Тренога + M220 삼각대 [CSW] M3 Deployable Tripod + [CSW] Trípode desplegable M3 + [CSW] M3 aufstellbares Dreibein + [CSW] Tripe Ajustável M3 + [CSW] M3 Trépied déployable + [CSW] M3 設置型三脚 + [CSW] M3 部屬型三腳架 + [班组] M3 部属型三脚架 + [CSW] Treppiede M3 piazzabile + [CSW] M3 trojnožka + [CSW] M3 Deployable Tripod + [CSW] Trójnóg Rozkładany M3 + [CSW] M3 Развертываемая тренога + [CSW] M3 배치형 삼각대 [CSW] M3 Deployable Tripod (Low) + [CSW] Trípode desplegable M3 (Bajo) + [CSW] M3 aufstellbares Dreibein (Niedrig) + [CSW] M3 Tripe Ajustável (Baixo) + [CSW] M3 Trépied déployable (Bas) + [CSW] M3 設置型三脚 (低座) + [CSW] M3 部署型三腳架(低位) + [班组] M3 部署型三脚架(低) + [CSW] Treppiede M3 piazzabile (Basso) + [CSW] M3 trojnožka (nízká) + [CSW] M3 Deployable Tripod (Low) + [CSW] Trójnóg Rozkładany M3 (Niski) + [CSW] M3 Развертываемая тренога (низкая) + [CSW] M3 배치형 삼각대 (낮음) [CSW] Mortar Baseplate + [CSW] Placa base de mortero + [CSW] M3 Mörsergrundplatte + [CSW] Placa base de Morteiro + [CSW] Plaque de base pour mortier + [CSW] 迫撃砲基盤 + [CSW] 迫擊炮基座 + [班组] 迫击炮底座 + [CSW] Base di Mortaio + [CSW] Podstavec pro minomet + [CSW] Mortar Baseplate + [CSW] Podstawa Moździerza + [CSW] Миномётная плита + [CSW] 포판 Mortar Baseplate + Placa base de mortero + Mörsergrundplatte + Placa base de Morteiro + Plaque de base pour mortier + 迫撃砲基盤 + 迫擊炮基座 + 迫击炮底座 + Base di Mortaio + Podstavec pro minomet + Mortar Baseplate + Podstawa Moździerza + Миномётная плита + 포판 [CSW] Mk6 Mortar Tube + [CSW] Mk6 Tubo de mortero + [CSW] Mk6 Mörserrohr + [CSW] Tubo de Morteiro - Mk6 + [CSW] Tube mortier Mk6 + [CSW] Mk6 迫撃砲発射筒 + [CSW] Mk6 迫擊炮炮管 + [班组] Mk6 迫击炮管 + [CSW] Tubo di Mortaio Mk6 + [CSW] Minomet Mk6 hlaveň + [CSW] Mk6 Mortar Tube + [CSW] Rura Moździerza Mk6 + [CSW] Сумка с Mk6 трубой + [CSW] Mk6 박격포 포신 [CSW] M252 Tube Bag + [CSW] M252 Tubo de mortero + [CSW] M252 Mörser Rohr Transporttasche + [CSW] Tubo de Morteiro - M252 + [CSW] Sac tube M252 + [CSW] M252 発射筒バッグ + [CSW] M252 炮管袋 + [班组] M252 炮管包 + [CSW] Borsa per Tubo M252 + [CSW] M252 minometná hlaveň v pouzdře + [CSW] M252 Tube Bag + [CSW] Torba na M252 + [CSW] Сумка с M252 орудием + [CSW] M252 박격포 포신 [CSW] M2 Gun Bag + [CSW] M2 Bolsa de arma + [CSW] M2 Waffentasche + [CSW] Bolsa de Arma - M2 + [CSW] Sac M2 + [CSW] M2 ガン バッグ + [CSW] M2槍械袋 + [班组] M2 枪械包 + [CSW] Borsa per Mitra M2 + [CSW] M2 zbraň v pouzdře + [CSW] M2 Gun Bag + [CSW] Torba na M2 + [CSW] Сумка с M2 орудием + [CSW] M2 총가방 [CSW] MK19 Gun Bag + [CSW] MK19 Bolsa de arma + [CSW] MK19 Waffentasche + [CSW] Bolsa de Arma - MK19 + [CSW] Sac MK19 + [CSW] Mk19 ガン バッグ + [CSW] Mk19槍械袋 + [班组] Mk19 枪械包 + [CSW] Borsa per Mitra MK19 + [CSW] MK19 zbraň v pouzdře + [CSW] MK19 Gun Bag + [CSW] Torba na MK19 + [CSW] Сумка с MK19 орудием + [CSW] MK19 총가방 [CSW] BGM-71 TOW Launcher Bag + [CSW] BGM-71 TOW Bolsa de lanzador + [CSW] BGM-71 TOW Werfer Transporttasche + [CSW] Bolsa de Lançador - BGM-71 TOW + [CSW] Sac lanceur BGM-71 TOW + [CSW] BGM-71 TOW ランチャー バッグ + [CSW] BGM-71 拖式飛彈發射器袋 + [班组] BGM-71 陶式导弹发射器包 + [CSW] Borsa per Lanciatore BGM-71 TOW + [CSW] BGM-71 TOW raketomet v pouzdře + [CSW] BGM-71 TOW Launcher Bag + [CSW] Torba na BGM-71 TOW + [CSW] Сумка с BGM-71 TOW установкой + [CSW] BGM-71 토우 발사기 가방 [CSW] DSHK Gun Bag + [CSW] DSHK Bolsa de arma + [CSW] DSHK Waffentasche + [CSW] Bolsa de Arma - DSHK + [CSW] Sac DSHK + [CSW] DShK ガン バッグ + [CSW]DShK 槍械袋 + [班组] DShK 枪械包 + [CSW] Borsa per Mitra DSHK + [CSW] DSHK zbraň v pouzdře + [CSW] DSHK Gun Bag + [CSW] Torba na DSzK + [CSW] Сумка с ДШК орудием + [CSW] DSHK 총가방 [CSW] 2B14 Tube Bag + [CSW] 2B14 Tubo de mortero + [CSW] 2B14 Werfer Transporttasche + [CSW] Bolsa de Arma - 2B14 + [CSW] Sac tube 2B14 + [CSW] 2B14 発射筒バッグ + [CSW] 2B14 炮管袋 + [班组] 2B14 炮管包 + [CSW] Borsa per Tubo 2B14 + [CSW] 2B14 minometná hlaveň v pouzdře + [CSW] 2B14 Tube Bag + [CSW] Torba na 2B14 + [CSW] Сумка с 2Б14 трубой + [CSW] 2B14 박격포 가방 [CSW] NSV Gun Bag + [CSW] NSV Bolsa de arma + [CSW] NSV Waffentasche + [CSW] Bolsa de Arma - NSV + [CSW] Sac NSV + [CSW] NSV ガン バッグ + [CSW] NSV 槍械袋 + [班组] NSV 枪械包 + [CSW] Borsa per Mitra NSV + [CSW] NSV zbraň v pouzdře + [CSW] NSV Gun Bag + [CSW] Torba na NSV + [CSW] Сумка с НСВ орудием + [CSW] NSV 총가방 [CSW] KORD Gun Bag + [CSW] KORD Bolsa de arma + [CSW] KORD Waffentasche + [CSW] Bolsa de Arma - KORD + [CSW] Sac KORD + [CSW] KORD ガン バッグ + [CSW] KORD 槍械袋 + [班组] KORD 枪械包 + [CSW] Borsa per Mitra KORD + [CSW] KORD zbraň v pouzdře + [CSW] KORD Gun Bag + [CSW] Torba na KORD + [CSW] Сумка с Корд орудием + [CSW] KORD 총가방 [CSW] AGS-30 Gun Bag + [CSW] AGS-30 Bolsa de arma + [CSW] AGS-30 Waffentasche + [CSW] Bolsa de Arma - AGS-30 + [CSW] Sac AGS-30 + [CSW] AGS-30 バッグ + [CSW] AGS-30 槍械袋 + [班组] AGS-30 枪械包 + [CSW] Borsa per GMG AGS-30 + [CSW] ASG-30 zbraň v pouzdře + [CSW] AGS-30 Gun Bag + [CSW] Torba na AGS-30 + [CSW] Сумка с АГС-30 орудием + [CSW] AGS-30 총가방 - [CSW] 9k115 Metis Launcher Bag + [CSW] 9K115 Metis Launcher Bag + [CSW] 9K115 Metis Bolsa de lanzador + [CSW] 9K115 Metis Werfer Transporttasche + [CSW] Bolsa de Arma - 9K115 Metis + [CSW] Sac lanceur 9K115 Metis + [CSW] 9K115 メティス ランチャー バッグ + [CSW] 9K115 麥士蒂索人發射器袋 + [班组] 9K115 麦士蒂索人反坦克发射器包 + [CSW] Borsa per Lanciatore 9K115 Metis + [CSW] 9K115 Metis raketomet v pouzdře + [CSW] Torba na 9K115 Metis + [CSW] 9k115 Metis Launcher Bag + [CSW] Сумка с 9К115 Метис установкой + [CSW] 9K115 메티스 발사기 가방 - [CSW] 9m113 Kornet Launcher + [CSW] 9M113 Kornet Launcher + [CSW] 9M113 Kornet Bolsa de lanzador + [CSW] 9M113 Kornet Werfer + [CSW] Bolsa de Arma - 9M113 Kornet + [CSW] Sac lanceur 9M113 Kornet + [CSW] 9M113 コルネット ランチャー バッグ + [CSW] 9M113 短號發射器 + [班组] 9M113 短号发射器 + [CSW] Borsa per Lanciatore 9M113 Kornet + [CSW] 9M113 Kornet raketomet + [CSW] Wyrzutnia 9M113 Kornet + [CSW] 9m113 Kornet Launcher + [CSW] Сумка с 9К135 Корнет установкой + [CSW] 9M113 코넷 발사기 가방 SPG-9 Tripod + SPG-9 Trípode + SPG-9 Dreibein + Tripé SPG-9 + Trépied SPG-9 + SPG-9 三脚 + SPG-9 三腳架 + SPG-9 三脚架 + Treppiede SPG-9 + SPG-9 trojnožka + SPG-9 Tripod + Trójnóg SPG-9 + СПГ-9 Тренога + SPG-9 삼각대 [CSW] SPG-9 Deployable Tripod + [CSW] SPG-9 Trípode desplegable + [CSW] SPG-9 aufstellbares Dreibein + [CSW] SPG-9 Tripe Ajustável (Baixo) + [CSW] SPG-9 Trépied déployable + [CSW] SPG-9 設置型三脚 + [CSW] SPG-9 部署型三腳架 + [班组] SPG-9 部署型三脚架 + [CSW] Treppiede SPG-9 piazzabile + [CSW] SPG-9 trojnožka + [CSW] SPG-9 Deployable Tripod + [CSW] Trójnóg rozkładany SPG-9 + [CSW] СПГ-9 Развертываемая тренога + [CSW] SPG-9 배치형 삼각대 [CSW] SPG-9 Launcher Bag + [CSW] SPG-9 Bolsa de lanzador + [CSW] SPG-9 Werfer Transporttasche + [CSW] Bolsa de Lançador - SPG-9 + [CSW] Sac lanceur SPG-9 + [CSW] SPG-9 ランチャー バッグ + [CSW] SPG-9 發射器袋 + [班组] SPG-9 发射器包 + [CSW] Borsa per Lanciatore SPG-9 + [CSW] SPG-9 raketomet v pouzdře + [CSW] SPG-9 Launcher Bag + [CSW] Torba na SPG-9 + [CSW] Сумка с СПГ-9 орудием + [CSW] SPG-9 발사기 가방 [CSW] SPG-9M Launcher Bag + [CSW] SPG-9M Bolsa de lanzador + [CSW] SPG-9M Werfer Transporttasche + [CSW] Bolsa de Lançador - SPG-9M + [CSW] Sac lanceur SPG-9M + [CSW] SPG-9M ランチャー バッグ + [CSW] SPG-9M 發射器袋 + [班组] SPG-9M 发射器包 + [CSW] Borsa per Lanciatore SPG-9M + [CSW] SPG-9M raketomet v pouzdře + [CSW] SPG-9M Launcher Bag + [CSW] Torba na SPG-9M + [CSW] Сумка с СПГ-9М орудием + [CSW] SPG-9M 발사기 가방 + + + + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[班组\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] diff --git a/addons/dagr/CfgEventHandlers.hpp b/addons/dagr/CfgEventHandlers.hpp index 7694c8e745..851e58197c 100644 --- a/addons/dagr/CfgEventHandlers.hpp +++ b/addons/dagr/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; -}; \ No newline at end of file +}; diff --git a/addons/dagr/CfgVehicles.hpp b/addons/dagr/CfgVehicles.hpp index 6b0188a178..562aeaa53e 100644 --- a/addons/dagr/CfgVehicles.hpp +++ b/addons/dagr/CfgVehicles.hpp @@ -9,7 +9,7 @@ class CfgVehicles { statement = QUOTE(call FUNC(menuInit)); showDisabled = 0; icon = QPATHTOF(UI\DAGR_Icon.paa); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; class GVAR(toggle) { displayName = CSTRING(ToggleDAGR); condition = QUOTE([ARR_2(_player,'ACE_DAGR')] call EFUNC(common,hasItem)); diff --git a/addons/dagr/CfgWeapons.hpp b/addons/dagr/CfgWeapons.hpp index 55692e7f9a..d114fa448c 100644 --- a/addons/dagr/CfgWeapons.hpp +++ b/addons/dagr/CfgWeapons.hpp @@ -12,6 +12,7 @@ class CfgWeapons { picture = QPATHTOF(UI\DAGR_Icon.paa); icon = "iconObject_circle"; mapSize = 0.034; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; diff --git a/addons/dagr/Dialog.hpp b/addons/dagr/Dialog.hpp index 52e3a8f683..6ed57d4d12 100644 --- a/addons/dagr/Dialog.hpp +++ b/addons/dagr/Dialog.hpp @@ -139,7 +139,7 @@ class DAGR_Menu_Text { class DAGR_Menu { idd = 266860; - movingEnable = false; + movingEnable = 0; duration = 100000; fadein = 0; fadeout = 0; @@ -152,7 +152,7 @@ class DAGR_Menu { "DAGR_MENU_SELECTION3", "DAGR_MENU_SELECTION4", "DAGR_MENU_Main_Text", "DAGR_MENU_PSELECTION1", "DAGR_MENU_PSELECTION2", "DAGR_MENU_PSELECTION3", "DAGR_MENU_PSELECTION4", "DAGR_MENU_PSELECTION5", "DAGR_MENU_PSELECTION6","DAGR_MENU_PSELECTION7", "DAGR_MENU_PSELECTION8"}; - class DAGR_MENU_UI : DAGR_Menu_Pic { + class DAGR_MENU_UI: DAGR_Menu_Pic { idc = 266861; x = 0.175; y = -0.173; @@ -160,28 +160,28 @@ class DAGR_Menu { sizeEx = 0.1; }; - class DAGR_PWR_Button : DAGR_Button { + class DAGR_PWR_Button: DAGR_Button { idc = 266863; action = QUOTE(GVAR(PWR) = true); x = 0.40; y = 0.65; }; - class DAGR_UP_Button : DAGR_Button { + class DAGR_UP_Button: DAGR_Button { idc = 266864; action = QUOTE(GVAR(UP) = true); x = 0.50; y = 0.675; }; - class DAGR_DOWN_Button : DAGR_Button { + class DAGR_DOWN_Button: DAGR_Button { idc = 266865; action = QUOTE(GVAR(DOWN) = true); x = 0.50; y = 0.81; }; - class DAGR_LEFT_Button : DAGR_Button { + class DAGR_LEFT_Button: DAGR_Button { idc = 266866; action = QUOTE(GVAR(LEFT) = true); x = 0.40; @@ -190,7 +190,7 @@ class DAGR_Menu { h = 0.07; }; - class DAGR_RIGHT_Button : DAGR_Button { + class DAGR_RIGHT_Button: DAGR_Button { idc = 266867; action = QUOTE(GVAR(RIGHT) = true); x = 0.62; @@ -199,14 +199,13 @@ class DAGR_Menu { h = 0.07; }; - class DAGR_NEXT_Button : DAGR_Button { + class DAGR_NEXT_Button: DAGR_Button { idc = 266868; - action = QUOTE(DAGR_NEXT = true); x = 0.60; y = 0.65; }; - class DAGR_SEL_Button : DAGR_Button { + class DAGR_SEL_Button: DAGR_Button { idc = 266869; action = QUOTE(GVAR(SEL) = true); x = 0.54; @@ -215,7 +214,7 @@ class DAGR_Menu { h = 0.06; }; - class DAGR_MENU_Button : DAGR_Button { + class DAGR_MENU_Button: DAGR_Button { idc = 266870; action = QUOTE(GVAR(MENU_B) = true); x = 0.46; @@ -224,47 +223,47 @@ class DAGR_Menu { h = 0.06; }; - class DAGR_F1_Button : DAGR_Button { + class DAGR_F1_Button: DAGR_Button { idc = 266871; action = QUOTE(GVAR(F1) = true); x = 0.40; y = 0.575; }; - class DAGR_F2_Button : DAGR_Button { + class DAGR_F2_Button: DAGR_Button { idc = 266872; action = QUOTE(GVAR(F2) = true); x = 0.495; y = 0.575; }; - class DAGR_F3_Button : DAGR_Button { + class DAGR_F3_Button: DAGR_Button { idc = 266873; action = QUOTE(GVAR(F3) = true); x = 0.59; y = 0.575; }; - class DAGR_F1_Text : DAGR_Menu_Text { + class DAGR_F1_Text: DAGR_Menu_Text { idc = 266874; x = 0.388; y = 0.38; text = ""; }; - class DAGR_F2_Text : DAGR_Menu_Text { + class DAGR_F2_Text: DAGR_Menu_Text { idc = 266875; x = 0.506; y = 0.38; }; - class DAGR_F3_Text : DAGR_Menu_Text { + class DAGR_F3_Text: DAGR_Menu_Text { idc = 266876; x = 0.612; y = 0.38; }; - class DAGR_MENU_OPTION0 : DAGR_Menu_Text { + class DAGR_MENU_OPTION0: DAGR_Menu_Text { idc = 2668777; style = 0x02; sizeEx = 0.035; @@ -272,7 +271,7 @@ class DAGR_Menu { y = 0.19; }; - class DAGR_MENU_OPTION1 : DAGR_Menu_Text { + class DAGR_MENU_OPTION1: DAGR_Menu_Text { idc = 2668778; style = 0x02; sizeEx = 0.035; @@ -280,7 +279,7 @@ class DAGR_Menu { y = 0.225; }; - class DAGR_MENU_OPTION2 : DAGR_Menu_Text { + class DAGR_MENU_OPTION2: DAGR_Menu_Text { idc = 2668779; style = 0x02; sizeEx = 0.035; @@ -288,7 +287,7 @@ class DAGR_Menu { y = 0.26; }; - class DAGR_MENU_OPTION3 : DAGR_Menu_Text { + class DAGR_MENU_OPTION3: DAGR_Menu_Text { idc = 2668780; style = 0x02; sizeEx = 0.035; @@ -296,14 +295,14 @@ class DAGR_Menu { y = 0.295; }; - class DAGR_MENU_OPTION4 : DAGR_Menu_Text { + class DAGR_MENU_OPTION4: DAGR_Menu_Text { idc = 2668781; style = 0x02; sizeEx = 0.035; x = 0.43; y = 0.33; }; - class DAGR_MENU_SELECTION0 : DAGR_Menu_Pic { + class DAGR_MENU_SELECTION0: DAGR_Menu_Pic { idc = 2668783; x = 0.42; y = 0.246; @@ -312,7 +311,7 @@ class DAGR_Menu { sizeEx = 0.05; }; - class DAGR_MENU_SELECTION1 : DAGR_Menu_Pic { + class DAGR_MENU_SELECTION1: DAGR_Menu_Pic { idc = 2668784; x = 0.42; y = 0.281; @@ -321,7 +320,7 @@ class DAGR_Menu { sizeEx = 0.05; }; - class DAGR_MENU_SELECTION2 : DAGR_Menu_Pic { + class DAGR_MENU_SELECTION2: DAGR_Menu_Pic { idc = 2668785; x = 0.42; y = 0.316; @@ -330,7 +329,7 @@ class DAGR_Menu { sizeEx = 0.05; }; - class DAGR_MENU_SELECTION3 : DAGR_Menu_Pic { + class DAGR_MENU_SELECTION3: DAGR_Menu_Pic { idc = 2668786; x = 0.42; y = 0.351; @@ -339,7 +338,7 @@ class DAGR_Menu { sizeEx = 0.05; }; - class DAGR_MENU_SELECTION4 : DAGR_Menu_Pic { + class DAGR_MENU_SELECTION4: DAGR_Menu_Pic { idc = 2668787; x = 0.42; y = 0.386; @@ -348,7 +347,7 @@ class DAGR_Menu { sizeEx = 0.05; }; - class DAGR_MENU_Main_Text : DAGR_Menu_Text { + class DAGR_MENU_Main_Text: DAGR_Menu_Text { idc = 2668782; style = ST_CENTER; x = 0.38; @@ -358,67 +357,68 @@ class DAGR_Menu { sizeEx = 0.04; }; - class DAGR_MENU_PSELECTION1 : DAGR_Menu_Pic { +//Waypoint adding and modification digits underline + class DAGR_MENU_PSELECTION1: DAGR_Menu_Pic { idc = 2668788; - x = 0.451; - y = 0.352; - w = 0.01; - h = 0.003; - }; - - class DAGR_MENU_PSELECTION2 : DAGR_Menu_Pic { - idc = 2668789; x = 0.465; y = 0.352; w = 0.01; h = 0.003; }; - class DAGR_MENU_PSELECTION3 : DAGR_Menu_Pic { + class DAGR_MENU_PSELECTION2: DAGR_Menu_Pic { + idc = 2668789; + x = 0.475; + y = 0.352; + w = 0.01; + h = 0.003; + }; + + class DAGR_MENU_PSELECTION3: DAGR_Menu_Pic { idc = 2668790; - x = 0.479; + x = 0.485; y = 0.352; w = 0.01; h = 0.003; }; - class DAGR_MENU_PSELECTION4 : DAGR_Menu_Pic { + class DAGR_MENU_PSELECTION4: DAGR_Menu_Pic { idc = 2668791; - x = 0.493; + x = 0.495; y = 0.352; w = 0.01; h = 0.003; }; - class DAGR_MENU_PSELECTION5 : DAGR_Menu_Pic { + class DAGR_MENU_PSELECTION5: DAGR_Menu_Pic { idc = 2668792; - x = 0.507; + x = 0.505; y = 0.352; w = 0.01; h = 0.003; }; - class DAGR_MENU_PSELECTION6 : DAGR_Menu_Pic { + class DAGR_MENU_PSELECTION6: DAGR_Menu_Pic { idc = 2668793; - x = 0.521; + x = 0.515; y = 0.352; w = 0.01; h = 0.003; }; - class DAGR_MENU_PSELECTION7 : DAGR_Menu_Pic { + class DAGR_MENU_PSELECTION7: DAGR_Menu_Pic { idc = 2668794; + x = 0.525; + y = 0.352; + w = 0.01; + h = 0.003; + }; + + class DAGR_MENU_PSELECTION8: DAGR_Menu_Pic { + idc = 2668795; x = 0.535; y = 0.352; w = 0.01; h = 0.003; }; - - class DAGR_MENU_PSELECTION8 : DAGR_Menu_Pic { - idc = 2668795; - x = 0.549; - y = 0.352; - w = 0.01; - h = 0.003; - }; }; diff --git a/addons/dagr/README.md b/addons/dagr/README.md index eb502e7a24..7de32ecec2 100644 --- a/addons/dagr/README.md +++ b/addons/dagr/README.md @@ -2,10 +2,3 @@ ace_dagr =============== Adds Defense Advanced GPS Receiver. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/dagr/RscTitles.hpp b/addons/dagr/RscTitles.hpp index ab70517c9a..609b546af4 100644 --- a/addons/dagr/RscTitles.hpp +++ b/addons/dagr/RscTitles.hpp @@ -32,7 +32,7 @@ class RscTitles { class DAGR_Display { idd = 266850; - movingEnable = false; + movingEnable = 0; duration = 100000; fadein = 0; fadeout = 0; @@ -40,13 +40,13 @@ class RscTitles { onLoad="uiNamespace setVariable ['DAGR_Display', _this select 0]"; controls[] = {"DAGR_UI", "DAGR_Grid", "DAGR_Speed", "DAGR_Elevation", "DAGR_Heading", "DAGR_Time", "DAGR_WP", "DAGR_Bearing", "DAGR_DIST"}; - class DAGR_UI : DAGR_Pic { + class DAGR_UI: DAGR_Pic { idc = 266856; x = "(SafeZoneW + SafeZoneX) - 0.45"; y = "(SafeZoneH + SafeZoneY) - 0.47"; }; - class DAGR_Grid : DAGR_Text { + class DAGR_Grid: DAGR_Text { idc = 266851; x = "(SafeZoneW + SafeZoneX) - 0.370";// 0.830 y = "(SafeZoneH + SafeZoneY)- 0.250";// 0.845 @@ -54,39 +54,39 @@ class RscTitles { h = 0.06; sizeEx = 0.07; }; - class DAGR_Speed : DAGR_Text { + class DAGR_Speed: DAGR_Text { idc = 266852; x = "(SafeZoneW + SafeZoneX) - 0.388"; //0.812 y = "(SafeZoneH + SafeZoneY) - 0.181"; //0.914 }; - class DAGR_Elevation : DAGR_Text { + class DAGR_Elevation: DAGR_Text { idc = 266853; x = "(SafeZoneW + SafeZoneX) - 0.270"; //0.930 y = "(SafeZoneH + SafeZoneY) - 0.181"; //0.914 }; - class DAGR_Heading : DAGR_Text { + class DAGR_Heading: DAGR_Text { idc = 266854; x = "(SafeZoneW + SafeZoneX) - 0.413"; //0.787 y = "(SafeZoneH + SafeZoneY) - 0.1294"; //0.9656 }; - class DAGR_Time : DAGR_Text { + class DAGR_Time: DAGR_Text { idc = 266855; x = "(SafeZoneW + SafeZoneX) - 0.275"; //0.925 y = "(SafeZoneH + SafeZoneY) - 0.129"; //0.965 }; - class DAGR_WP : DAGR_Text { + class DAGR_WP: DAGR_Text { idc = 266857; x = "(SafeZoneW + SafeZoneX) - 0.235"; //0.965 y = "(SafeZoneH + SafeZoneY) - 0.181"; //0.914 }; - class DAGR_Bearing : DAGR_Text { + class DAGR_Bearing: DAGR_Text { idc = 266858; x = "(SafeZoneW + SafeZoneX) - 0.413"; //0.787 y = "(SafeZoneH + SafeZoneY) - 0.181"; //0.914 }; - class DAGR_DIST : DAGR_Text { + class DAGR_DIST: DAGR_Text { idc = 266859; x = "(SafeZoneW + SafeZoneX) - 0.265"; //0.935 y = "(SafeZoneH + SafeZoneY) - 0.129"; //0.965 diff --git a/addons/dagr/XEH_postInit.sqf b/addons/dagr/XEH_postInit.sqf index 4c3fce167d..34dc981843 100644 --- a/addons/dagr/XEH_postInit.sqf +++ b/addons/dagr/XEH_postInit.sqf @@ -2,7 +2,7 @@ if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" GVAR(outputPFH) = -1; @@ -30,4 +30,4 @@ GVAR(vectorConnected) = false; GVAR(noVectorData) = true; GVAR(vectorGrid) = "00000000"; -[QEGVAR(vector,rangefinderData), FUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; diff --git a/addons/dagr/functions/fnc_handleRangeFinderData.sqf b/addons/dagr/functions/fnc_handleRangeFinderData.sqf index 4d9447240b..19f6dd9171 100644 --- a/addons/dagr/functions/fnc_handleRangeFinderData.sqf +++ b/addons/dagr/functions/fnc_handleRangeFinderData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rosuto, Ruthberg * Handles incoming data packets from the Vectronix Vector LRF diff --git a/addons/dagr/functions/fnc_menuInit.sqf b/addons/dagr/functions/fnc_menuInit.sqf index c535ac1349..fc05185638 100644 --- a/addons/dagr/functions/fnc_menuInit.sqf +++ b/addons/dagr/functions/fnc_menuInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rosuto, Ruthberg * Creates the DAGR menu dialog @@ -10,6 +10,7 @@ * None * * Example: + * [] call ace_dagr_fnc_menuInit * * Public: No */ @@ -540,7 +541,7 @@ GVAR(menuRun) = true; }; case "options": { (__dsp displayCtrl __Option0) ctrlSetText "Signal Delay"; - (__dsp displayCtrl __Option1) ctrlSetText (if (GVAR(useDegrees)) then { "Direction: Deg" } else { "Direction: MIL" }); + (__dsp displayCtrl __Option1) ctrlSetText (["Direction: MIL", "Direction: Deg"] select GVAR(useDegrees)); (__dsp displayCtrl (__Selection0 + GVAR(selection))) ctrlSetText QPATHTOF(UI\DAGR_Selection.paa); if (GVAR(SEL)) then { GVAR(vectorConnected) = false; @@ -596,7 +597,6 @@ GVAR(menuRun) = true; GVAR(F1) = false; GVAR(MENU_B) = false; GVAR(SEL) = false; - DAGR_NEXT = false; GVAR(RIGHT) = false; GVAR(LEFT) = false; GVAR(UP) = false; diff --git a/addons/dagr/functions/fnc_outputData.sqf b/addons/dagr/functions/fnc_outputData.sqf index a5816e472d..b7064ce248 100644 --- a/addons/dagr/functions/fnc_outputData.sqf +++ b/addons/dagr/functions/fnc_outputData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rosuto * DAGR data output loop @@ -65,10 +65,10 @@ GVAR(outputPFH) = [{ private _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; // Output - __gridControl ctrlSetText format ["%1", _dagrGrid]; - __speedControl ctrlSetText format ["%1", _dagrSpeed]; - __elevationControl ctrlSetText format ["%1", _dagrElevation]; - __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1 �", _dagrHeading] }); - __timeControl ctrlSetText format ["%1", _dagrTime]; + __gridControl ctrlSetText _dagrGrid; + __speedControl ctrlSetText _dagrSpeed; + __elevationControl ctrlSetText _dagrElevation; + __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { str _dagrHeading } else { format ["%1 �", _dagrHeading] }); + __timeControl ctrlSetText _dagrTime; }, GVAR(updateInterval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dagr/functions/fnc_outputVector.sqf b/addons/dagr/functions/fnc_outputVector.sqf index ce2ca2a04c..e9bd0ea6c3 100644 --- a/addons/dagr/functions/fnc_outputVector.sqf +++ b/addons/dagr/functions/fnc_outputVector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rosuto * DAGR vector output loop @@ -89,8 +89,8 @@ private _dagrDist = str GVAR(LAZDIST) + "m"; GVAR(vectorGrid) = _dagrGrid; // OUTPUT -__gridControl ctrlSetText format ["%1", _dagrGrid]; -__speedControl ctrlSetText format ["%1", _dagrDist]; -__elevationControl ctrlSetText format ["%1", _dagrElevation]; -__headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _bearing] } else { format ["%1°", _bearing] }); -__timeControl ctrlSetText format ["%1", _dagrTime]; +__gridControl ctrlSetText _dagrGrid; +__speedControl ctrlSetText _dagrDist; +__elevationControl ctrlSetText _dagrElevation; +__headingControl ctrlSetText (if (!GVAR(useDegrees)) then { str _bearing } else { format ["%1°", _bearing] }); +__timeControl ctrlSetText _dagrTime; diff --git a/addons/dagr/functions/fnc_outputWP.sqf b/addons/dagr/functions/fnc_outputWP.sqf index 41518a0560..27944f0bb9 100644 --- a/addons/dagr/functions/fnc_outputWP.sqf +++ b/addons/dagr/functions/fnc_outputWP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rosuto * DAGR waypoint output loop @@ -85,10 +85,10 @@ GVAR(outputPFH) = [{ }); // Output - __gridControl ctrlSetText format ["%1", _dagrGrid]; - __speedControl ctrlSetText format ["%1", _bearing]; - __elevationControl ctrlSetText format ["%1", _dagrGrid2]; - __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1°", _dagrHeading] }); - __timeControl ctrlSetText format ["%1", _dagrDistance]; + __gridControl ctrlSetText _dagrGrid; + __speedControl ctrlSetText str _bearing; + __elevationControl ctrlSetText _dagrGrid2; + __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { str _dagrHeading } else { format ["%1°", _dagrHeading] }); + __timeControl ctrlSetText _dagrDistance; }, GVAR(updateInterval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dagr/functions/fnc_toggleOverlay.sqf b/addons/dagr/functions/fnc_toggleOverlay.sqf index c0e229d745..cc875f9a70 100644 --- a/addons/dagr/functions/fnc_toggleOverlay.sqf +++ b/addons/dagr/functions/fnc_toggleOverlay.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rosuto, Ruthberg * Toggles the DAGR overlay diff --git a/addons/dagr/functions/script_component.hpp b/addons/dagr/functions/script_component.hpp deleted file mode 100644 index 18b02deaee..0000000000 --- a/addons/dagr/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\dagr\script_component.hpp" \ No newline at end of file diff --git a/addons/dagr/initKeybinds.inc.sqf b/addons/dagr/initKeybinds.inc.sqf new file mode 100644 index 0000000000..fb9d8dd771 --- /dev/null +++ b/addons/dagr/initKeybinds.inc.sqf @@ -0,0 +1,58 @@ + +["ACE3 Equipment", QGVAR(MenuKey), localize LSTRING(ConfigureDAGR), +{ + // Conditions: canInteract + if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith {false}; + + // Statement + if (!GVAR(menuRun)) then { + [] call FUNC(menuInit); + } else { + GVAR(PWR) = true; // Simulate pressing the power button + }; + true +}, +{false}, +[0, [false, true, false]], false] call CBA_fnc_addKeybind; // (empty default key) + +["ACE3 Equipment", QGVAR(ToggleKey), localize LSTRING(ToggleDAGR), +{ + // Conditions: canInteract + if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith {false}; + + // Statement + [] call FUNC(toggleOverlay); + true +}, +{false}, +[0, [false, false, false]], false] call CBA_fnc_addKeybind; // (empty default key) + +//Add deviceKey entry: +private _conditonCode = { + ([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)); +}; +private _toggleCode = { + // Conditions: canInteract + if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + // Statement + [] call FUNC(toggleOverlay); + if (!GVAR(run)) then { + [] call FUNC(menuInit); + }; +}; +private _closeCode = { + // Statement + if (GVAR(run)) then { + //If dispaly is open, close it: + [] call FUNC(toggleOverlay); + }; + if (dialog && GVAR(menuRun)) then { + //If dialog is open, close it: + GVAR(menuRun) = false; + closeDialog 0; + }; +}; +["DAGR", QPATHTOF(UI\DAGR_Icon.paa), _conditonCode, _toggleCode, _closeCode] call EFUNC(common,deviceKeyRegisterNew); diff --git a/addons/dagr/initKeybinds.sqf b/addons/dagr/initKeybinds.sqf deleted file mode 100644 index d99e0f15c7..0000000000 --- a/addons/dagr/initKeybinds.sqf +++ /dev/null @@ -1,58 +0,0 @@ - -["ACE3 Equipment", QGVAR(MenuKey), localize LSTRING(ConfigureDAGR), -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if !([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith {false}; - - // Statement - if (!GVAR(menuRun)) then { - [] call FUNC(menuInit); - } else { - GVAR(PWR) = true; // Simulate pressing the power button - }; - true -}, -{false}, -[0, [false, true, false]], false] call CBA_fnc_addKeybind; // (empty default key) - -["ACE3 Equipment", QGVAR(ToggleKey), localize LSTRING(ToggleDAGR), -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if !([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith {false}; - - // Statement - [] call FUNC(toggleOverlay); - true -}, -{false}, -[0, [false, false, false]], false] call CBA_fnc_addKeybind; // (empty default key) - -//Add deviceKey entry: -private _conditonCode = { - ([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)); -}; -private _toggleCode = { - // Conditions: canInteract - if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {}; - - // Statement - [] call FUNC(toggleOverlay); - if (!GVAR(run)) then { - [] call FUNC(menuInit); - }; -}; -private _closeCode = { - // Statement - if (GVAR(run)) then { - //If dispaly is open, close it: - [] call FUNC(toggleOverlay); - }; - if (dialog && GVAR(menuRun)) then { - //If dialog is open, close it: - GVAR(menuRun) = false; - closeDialog 0; - }; -}; -["DAGR", QPATHTOF(UI\DAGR_Icon.paa), _conditonCode, _toggleCode, _closeCode] call EFUNC(common,deviceKeyRegisterNew); diff --git a/addons/dagr/stringtable.xml b/addons/dagr/stringtable.xml index c364eedabe..3251052002 100644 --- a/addons/dagr/stringtable.xml +++ b/addons/dagr/stringtable.xml @@ -14,7 +14,8 @@ DAGR DAGR 軍用GPS接收器 - 军用GPS接收器 + 军用 GPS 接收器 + DAGR Configure DAGR @@ -29,22 +30,24 @@ DAGR を設定 DAGR 설정 設定軍用GPS接收器 - 设定军用GPS接收器 + 设定军用 GPS 接收器 + DAGR'ı yapılandır Toggle DAGR DAGR umschalten Przełącz DAGR Mostrar DAGR - Вкл./выкл. DAGR + Переключить DAGR Mostrar DAGR Přepnout DAGR - Apri DAGR - Activer/Desactiver le DAGR - DAGR を常に表示 + Apri/Chiudi DAGR + Activer/Désactiver le DAGR + DAGR 表示切替 DAGR 토글 切換軍用GPS接收器 - 切换军用GPS接收器 + 切换军用 GPS 接收器 + DAGR'yi aç / kapat Defense Advanced GPS Receiver @@ -56,10 +59,11 @@ Defense Advanced GPS Receiver Defense Advanced GPS Receiver Defense Advanced GPS Receiver - アドバンスド DAGR の受信を定義します + 国防のための高度なGPS受信機 (Defense Advanced GPS Receiver) 국방 고급위성항법시스템 수신기 軍用高級防禦GPS接收器 - 军用高级防御GPS接收器 + 军用高级防御 GPS 接收器 + Gelişmiş Savunma GPS Alıcısı diff --git a/addons/disarming/CfgEventHandlers.hpp b/addons/disarming/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/disarming/CfgEventHandlers.hpp +++ b/addons/disarming/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/disarming/README.md b/addons/disarming/README.md index 0423aa48bd..bcca67231e 100644 --- a/addons/disarming/README.md +++ b/addons/disarming/README.md @@ -1,11 +1,4 @@ ace_disarming ============ -Adds ability to make units drop items/weapons/magazines. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) +Adds ability to make units drop items/weapons/magazines. diff --git a/addons/disarming/XEH_postInit.sqf b/addons/disarming/XEH_postInit.sqf index 6944f8b146..5b123af297 100644 --- a/addons/disarming/XEH_postInit.sqf +++ b/addons/disarming/XEH_postInit.sqf @@ -1,4 +1,4 @@ #include "script_component.hpp" -[QGVAR(dropItems), FUNC(eventTargetStart)] call CBA_fnc_addEventHandler; -[QGVAR(debugCallback), FUNC(eventCallerFinish)] call CBA_fnc_addEventHandler; +[QGVAR(dropItems), LINKFUNC(eventTargetStart)] call CBA_fnc_addEventHandler; +[QGVAR(debugCallback), LINKFUNC(eventCallerFinish)] call CBA_fnc_addEventHandler; diff --git a/addons/disarming/functions/fnc_canBeDisarmed.sqf b/addons/disarming/functions/fnc_canBeDisarmed.sqf index ab41729f6a..4fde1597c4 100644 --- a/addons/disarming/functions/fnc_canBeDisarmed.sqf +++ b/addons/disarming/functions/fnc_canBeDisarmed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * @@ -29,7 +29,6 @@ if (_putDownAnim != "") exitWith { false }; (alive _target) && {(abs (speed _target)) < 1} && -{(vehicle _target) == _target} && {(_target getVariable ["ACE_isUnconscious", false]) || {_target getVariable [QEGVAR(captives,isHandcuffed), false]} || {_target getVariable [QEGVAR(captives,isSurrendering), false]}} diff --git a/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf b/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf index 2468e454fd..989dd7f4df 100644 --- a/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf +++ b/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * diff --git a/addons/disarming/functions/fnc_disarmDropItems.sqf b/addons/disarming/functions/fnc_disarmDropItems.sqf index 4c8fb3bf2d..6e842e739a 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * @@ -30,7 +30,7 @@ private _fncSumArray = { }; //Sanity Checks -if (!([_target] call FUNC(canBeDisarmed))) exitWith { +if !([_target] call FUNC(canBeDisarmed)) exitWith { [_caller, _target, "Debug: Cannot disarm target"] call FUNC(eventTargetFinish); }; if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) > 0}) exitWith { @@ -39,13 +39,18 @@ if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) private _holder = objNull; +// if _target is in a vehicle, use vehicle inventory as container +if (!isNull objectParent _target) then { + _holder = objectParent _target; +}; + //If not dropping ammo, don't use an existing container if (!_doNotDropAmmo) then { { if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; }; - } count ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); + } forEach ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); }; //Create a new weapon holder @@ -69,7 +74,6 @@ if (_holder getVariable [QGVAR(holderInUse), false]) exitWith { }; _holder setVariable [QGVAR(holderInUse), true]; - //Remove Magazines private _targetMagazinesStart = magazinesAmmo _target; private _holderMagazinesStart = magazinesAmmoCargo _holder; @@ -91,8 +95,7 @@ if (({((_x select 0) in _listOfItemsToRemove) && {(getNumber (configFile >> "Cfg [_caller, _target, "Debug: Didn't Remove Magazines"] call FUNC(eventTargetFinish); }; //Verify holder has mags unit had -if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved))) then { - ERR = [_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd]; +if !([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved)) then { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Crate Magazines not in holder"] call FUNC(eventTargetFinish); }; @@ -220,7 +223,7 @@ if (_holderIsEmpty) then { }; //If we added a dummy item, remove it now - if (_holderIsEmpty && {!((getItemCargo _holder) isEqualTo [[DUMMY_ITEM],[1]])}) exitWith { + if (_holderIsEmpty && {(getItemCargo _holder) isNotEqualTo [[DUMMY_ITEM],[1]]}) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Holder should only have dummy item"] call FUNC(eventTargetFinish); }; @@ -234,11 +237,11 @@ if (_holderIsEmpty) then { [_caller, _target, "Debug: Drop Actions Timeout"] call FUNC(eventTargetFinish); }; //If target lost disarm status: - if (!([_target] call FUNC(canBeDisarmed))) exitWith { + if !([_target] call FUNC(canBeDisarmed)) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Target cannot be disarmed"] call FUNC(eventTargetFinish); }; - if (_needToRemoveVest && {!((vestItems _target) isEqualTo [])}) exitWith { + if (_needToRemoveVest && {(vestItems _target) isNotEqualTo []}) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Vest Not Empty"] call FUNC(eventTargetFinish); }; @@ -246,7 +249,7 @@ if (_holderIsEmpty) then { _holder addItemCargoGlobal [(vest _target), 1]; removeVest _target; }; - if (_needToRemoveUniform && {!((uniformItems _target) isEqualTo [])}) exitWith { + if (_needToRemoveUniform && {(uniformItems _target) isNotEqualTo []}) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Uniform Not Empty"] call FUNC(eventTargetFinish); }; diff --git a/addons/disarming/functions/fnc_eventCallerFinish.sqf b/addons/disarming/functions/fnc_eventCallerFinish.sqf index 60629b221f..bc9033fee5 100644 --- a/addons/disarming/functions/fnc_eventCallerFinish.sqf +++ b/addons/disarming/functions/fnc_eventCallerFinish.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * diff --git a/addons/disarming/functions/fnc_eventTargetFinish.sqf b/addons/disarming/functions/fnc_eventTargetFinish.sqf index b750fd51b1..792a41d06d 100644 --- a/addons/disarming/functions/fnc_eventTargetFinish.sqf +++ b/addons/disarming/functions/fnc_eventTargetFinish.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * diff --git a/addons/disarming/functions/fnc_eventTargetStart.sqf b/addons/disarming/functions/fnc_eventTargetStart.sqf index e63289cf20..a7154ce2e4 100644 --- a/addons/disarming/functions/fnc_eventTargetStart.sqf +++ b/addons/disarming/functions/fnc_eventTargetStart.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * @@ -32,7 +32,7 @@ private _itemsToAdd = []; } forEach _listOfObjectsToRemove; { - if (!(_x in _listOfObjectsToRemove)) then { + if !(_x in _listOfObjectsToRemove) then { _listOfObjectsToRemove pushBack _x; }; } forEach _itemsToAdd; diff --git a/addons/disarming/functions/fnc_getAllGearContainer.sqf b/addons/disarming/functions/fnc_getAllGearContainer.sqf index be46d66e5e..ea954a39d5 100644 --- a/addons/disarming/functions/fnc_getAllGearContainer.sqf +++ b/addons/disarming/functions/fnc_getAllGearContainer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * diff --git a/addons/disarming/functions/fnc_getAllGearUnit.sqf b/addons/disarming/functions/fnc_getAllGearUnit.sqf index db066ad5d8..b47d2aca70 100644 --- a/addons/disarming/functions/fnc_getAllGearUnit.sqf +++ b/addons/disarming/functions/fnc_getAllGearUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index 0b66009949..6cf15f4cad 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * @@ -16,11 +16,14 @@ * * Public: No */ + params ["_caller", "_target"]; -#define DEFUALTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + +#define DEFAULTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + //Sanity Checks if (_caller != ACE_player) exitWith {ERROR("Player isn't caller?");}; -if (!([_player, _target] call FUNC(canPlayerDisarmUnit))) exitWith {ERROR("Can't Disarm Unit");}; +if !([_player, _target] call FUNC(canPlayerDisarmUnit)) exitWith {ERROR("Can't Disarm Unit");}; if (dialog) then {ERROR("Dialog open when trying to open disarm dialog"); closeDialog 0;}; disableSerialization; @@ -40,8 +43,15 @@ GVAR(disarmTarget) = _target; if (isNull GVAR(disarmTarget)) exitWith {ERROR("disarmTarget is null");}; + private _textRight = ""; + for "_i" from 0 to (lbSize _idc) - 1 do { + if (lbData [_idc, _i] isEqualTo _data) exitWith { + _textRight = lbTextRight [_idc, _i]; + }; + }; + TRACE_2("Debug: Droping %1 from %2",_data,GVAR(disarmTarget)); - [QGVAR(dropItems), [ACE_player, GVAR(disarmTarget), [_data]], [GVAR(disarmTarget)]] call CBA_fnc_targetEvent; + [QGVAR(dropItems), [ACE_player, GVAR(disarmTarget), [_data], parseNumber _textRight], [GVAR(disarmTarget)]] call CBA_fnc_targetEvent; false //not sure what this does }]; @@ -67,8 +77,8 @@ GVAR(disarmTarget) = _target; private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - private _icon = format [DEFUALTPATH, toLower (rank _target)]; - if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; + private _icon = format [DEFAULTPATH, toLowerANSI (rank _target)]; + if (_icon isEqualTo DEFAULTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); @@ -86,7 +96,7 @@ GVAR(disarmTarget) = _target; if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; }; - } count ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); + } forEach ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); //If a holder exists, show it's inventory if (!isNull _holder) then { diff --git a/addons/disarming/functions/fnc_showItemsInListbox.sqf b/addons/disarming/functions/fnc_showItemsInListbox.sqf index fadbb2d914..11d7bd470b 100644 --- a/addons/disarming/functions/fnc_showItemsInListbox.sqf +++ b/addons/disarming/functions/fnc_showItemsInListbox.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * @@ -51,11 +51,11 @@ params ["_listBoxCtrl", "_itemsCountArray"]; _picture = getText (_configPath >> _classname >> "picture"); }; default { - ERROR(format ["[%1] - bad classname", _classname]); + ERROR_1("[%1] - bad classname",_classname); }; }; - _listBoxCtrl lbAdd format ["%1", _displayName]; + _listBoxCtrl lbAdd _displayName; _listBoxCtrl lbSetData [((lbSize _listBoxCtrl) - 1), _classname]; _listBoxCtrl lbSetPicture [((lbSize _listBoxCtrl) - 1), _picture]; _listBoxCtrl lbSetTextRight [((lbSize _listBoxCtrl) - 1), str _count]; diff --git a/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf b/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf index 60d851b973..68da57dcda 100644 --- a/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf +++ b/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * diff --git a/addons/disarming/functions/script_component.hpp b/addons/disarming/functions/script_component.hpp deleted file mode 100644 index 38e082ee0e..0000000000 --- a/addons/disarming/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\disarming\script_component.hpp" \ No newline at end of file diff --git a/addons/disarming/gui_disarm.hpp b/addons/disarming/gui_disarm.hpp index 1863eb9b0b..4c8ce53e6c 100644 --- a/addons/disarming/gui_disarm.hpp +++ b/addons/disarming/gui_disarm.hpp @@ -17,10 +17,10 @@ class RscListBox; #define W_MAKEITBIGGA(num) (num * (safeZoneH / 40)) #define H_MAKEITBIGGA(num) (num * (safeZoneH / 30)) -#define X_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), X_BIS(num), X_MAKEITBIGGA(num))]) -#define Y_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), Y_BIS(num), Y_MAKEITBIGGA(num))]) -#define W_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), W_BIS(num), W_MAKEITBIGGA(num))]) -#define H_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), H_BIS(num), H_MAKEITBIGGA(num))]) +#define X_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)),0)]),X_BIS(num),X_MAKEITBIGGA(num))]) +#define Y_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)),0)]),Y_BIS(num),Y_MAKEITBIGGA(num))]) +#define W_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)),0)]),W_BIS(num),W_MAKEITBIGGA(num))]) +#define H_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)),0)]),H_BIS(num),H_MAKEITBIGGA(num))]) class GVAR(remoteInventory) { idd = -1; diff --git a/addons/disarming/stringtable.xml b/addons/disarming/stringtable.xml index 30f9fa4b85..0ae879fd60 100644 --- a/addons/disarming/stringtable.xml +++ b/addons/disarming/stringtable.xml @@ -15,7 +15,8 @@ インベントリを開く 소지품 열기 開啟裝備 - 开启装备 + 开启物品栏 + Envanteri Aç diff --git a/addons/disposable/CfgEventHandlers.hpp b/addons/disposable/CfgEventHandlers.hpp deleted file mode 100644 index a7c50f3247..0000000000 --- a/addons/disposable/CfgEventHandlers.hpp +++ /dev/null @@ -1,33 +0,0 @@ - -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)); - }; -}; - -class Extended_DisplayLoad_EventHandlers { - class RscDisplayInventory { - ADDON = QUOTE([ARR_2(ACE_player, _this select 0)] call FUNC(updateInventoryDisplay)); - }; -}; - -// handle preloaded missile -class Extended_InitPost_EventHandlers { - class CAManBase { - class ADDON { - init = QUOTE([_this select 0] call FUNC(takeLoadedATWeapon)); - }; - }; -}; diff --git a/addons/disposable/CfgMagazines.hpp b/addons/disposable/CfgMagazines.hpp deleted file mode 100644 index 6204b330e4..0000000000 --- a/addons/disposable/CfgMagazines.hpp +++ /dev/null @@ -1,15 +0,0 @@ -class CfgMagazines { - class NLAW_F; - class ACE_PreloadedMissileDummy: NLAW_F { // The dummy magazine - author = ECSTRING(common,ACETeam); - scope = 1; - scopeArsenal = 1; - displayName = CSTRING(PreloadedMissileDummy); - picture = "\a3\ui_f\data\IGUI\Cfg\Targeting\Empty_ca.paa"; - weaponPoolAvailable = 0; - mass = 0; - }; - class ACE_FiredMissileDummy: ACE_PreloadedMissileDummy { - count = 0; - }; -}; diff --git a/addons/disposable/CfgVehicles.hpp b/addons/disposable/CfgVehicles.hpp index 0ad3ff51c0..0b4d739dc6 100644 --- a/addons/disposable/CfgVehicles.hpp +++ b/addons/disposable/CfgVehicles.hpp @@ -1,146 +1,8 @@ class CfgVehicles { - #define MACRO_NONLAW \ - class TransportMagazines { \ - class _xx_NLAW_F { \ - count = 0; \ - }; \ + class Launcher_Base_F; + class Weapon_launch_NLAW_F: Launcher_Base_F { + class TransportMagazines { + delete NLAW_F; }; - - class ReammoBox_F; - class NATO_Box_Base: ReammoBox_F {}; - class Box_NATO_Ammo_F: NATO_Box_Base { - MACRO_NONLAW }; - class Box_NATO_WpsLaunch_F: NATO_Box_Base { - MACRO_NONLAW - }; - - class IND_Box_Base: ReammoBox_F {}; - class Box_IND_WpsLaunch_F: IND_Box_Base { - MACRO_NONLAW - }; - class Box_IND_Ammo_F: IND_Box_Base { - MACRO_NONLAW - }; - - class B_supplyCrate_F: ReammoBox_F { - MACRO_NONLAW - }; - class I_supplyCrate_F: B_supplyCrate_F { - MACRO_NONLAW - }; - class C_supplyCrate_F: ReammoBox_F { - MACRO_NONLAW - }; - - class B_AssaultPack_rgr; - class B_AssaultPack_rgr_LAT: B_AssaultPack_rgr { - MACRO_NONLAW - }; - class B_AssaultPack_rgr_ReconLAT: B_AssaultPack_rgr { - MACRO_NONLAW - }; - - class B_Carryall_mcamo; - class B_AssaultPack_mcamo_Ammo: B_Carryall_mcamo { - MACRO_NONLAW - }; - class B_Carryall_oli; - class I_Fieldpack_oli_Ammo: B_Carryall_oli { - MACRO_NONLAW - }; - - class B_AssaultPack_dgtl; - class I_Fieldpack_oli_LAT: B_AssaultPack_dgtl { - MACRO_NONLAW - }; - - class CargoNet_01_ammo_base_F; - class B_CargoNet_01_ammo_F: CargoNet_01_ammo_base_F { - MACRO_NONLAW - }; - class I_CargoNet_01_ammo_F: CargoNet_01_ammo_base_F { - MACRO_NONLAW - }; - - class Slingload_01_Base_F; - class B_Slingload_01_Cargo_F: Slingload_01_Base_F { - MACRO_NONLAW - }; - - class Tank_F; - class APC_Tracked_01_base_F: Tank_F { - MACRO_NONLAW - }; - /*class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F { - MACRO_NONLAW - }; - class B_APC_Tracked_01_rcws_F: B_APC_Tracked_01_base_F { - MACRO_NONLAW - }; - class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - MACRO_NONLAW - }; - class B_APC_Tracked_01_AA_F: B_APC_Tracked_01_base_F { - MACRO_NONLAW - };*/ - - class Car_F; - class MRAP_01_base_F: Car_F { - MACRO_NONLAW - }; - /*class MRAP_01_gmg_base_F: MRAP_01_base_F { - MACRO_NONLAW - }; - class MRAP_01_hmg_base_F: MRAP_01_gmg_base_F { - MACRO_NONLAW - }; - class B_MRAP_01_F: MRAP_01_base_F { - MACRO_NONLAW - }; - class B_MRAP_01_gmg_F: MRAP_01_gmg_base_F { - MACRO_NONLAW - }; - class B_MRAP_01_hmg_F: MRAP_01_hmg_base_F { - MACRO_NONLAW - };*/ - - class MRAP_03_base_F: Car_F { - MACRO_NONLAW - }; - /*class MRAP_03_hmg_base_F: MRAP_03_base_F { - MACRO_NONLAW - }; - class MRAP_03_gmg_base_F: MRAP_03_hmg_base_F { - MACRO_NONLAW - }; - class I_MRAP_03_F: MRAP_03_base_F { - MACRO_NONLAW - }; - class I_MRAP_03_hmg_F: MRAP_03_hmg_base_F { - MACRO_NONLAW - }; - class I_MRAP_03_gmg_F: MRAP_03_gmg_base_F { - MACRO_NONLAW - };*/ - - class Wheeled_APC_F: Car_F {}; - class APC_Wheeled_03_base_F: Wheeled_APC_F { - MACRO_NONLAW - }; - class APC_Wheeled_01_base_F: Wheeled_APC_F { - MACRO_NONLAW - }; - /*class B_APC_Wheeled_01_base_F: APC_Wheeled_01_base_F { - MACRO_NONLAW - }; - class B_APC_Wheeled_01_cannon_F: B_APC_Wheeled_01_base_F { - MACRO_NONLAW - }; - class I_APC_Wheeled_03_base_F: APC_Wheeled_03_base_F { - MACRO_NONLAW - }; - class I_APC_Wheeled_03_cannon_F: I_APC_Wheeled_03_base_F { - MACRO_NONLAW - };*/ }; diff --git a/addons/disposable/CfgWeapons.hpp b/addons/disposable/CfgWeapons.hpp index 731910b704..55372421a7 100644 --- a/addons/disposable/CfgWeapons.hpp +++ b/addons/disposable/CfgWeapons.hpp @@ -1,19 +1,54 @@ class CfgWeapons { - class Launcher_Base_F; - class launch_NLAW_F: Launcher_Base_F { - ACE_UsedTube = "ACE_launch_NLAW_Used_F"; // The class name of the used tube. - magazines[] = {"ACE_PreloadedMissileDummy"}; // The dummy magazine + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; }; - class ACE_launch_NLAW_Used_F: launch_NLAW_F { // the used tube should be a sub class of the disposable launcher - EGVAR(nlaw,enabled) = 0; // disable guidance for the disposabled tube - scope = 1; - ACE_isUsedLauncher = 1; + + class launch_NLAW_F: Launcher_Base_F { + scope = 2; + scopeArsenal = 2; + baseWeapon = "launch_NLAW_F"; + + magazineWell[] = {}; // remove magwell, so only the fakeMag can be loaded (inherited by used) + magazines[] = {"CBA_FakeLauncherMagazine"}; + magazineReloadTime = 0.1; + reloadMagazineSound[] = {"",1,1}; + + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 180; // launcher 100, magazine 80 + }; + }; + + class ACE_launch_NLAW_ready_F: launch_NLAW_F { author = ECSTRING(common,ACETeam); + scope = 1; + scopeArsenal = 1; + baseWeapon = "launch_NLAW_F"; + + magazines[] = {"NLAW_F"}; + magazineWell[] = {"NLAW"}; // restore magwell + + class EventHandlers { + fired = "_this call CBA_fnc_firedDisposable"; // this weapon eventhandler is required! + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 100; + }; + }; + + class ACE_launch_NLAW_used_F: launch_NLAW_F { + author = ECSTRING(common,ACETeam); + scope = 1; + scopeArsenal = 1; + baseWeapon = "ACE_launch_NLAW_used_F"; + displayName = CSTRING(UsedTube); descriptionShort = CSTRING(UsedTubeDescription); - magazines[] = {"ACE_FiredMissileDummy"}; // This will disable the used launcher class from being fired again. - //picture = ""; @todo - //model = ""; @todo weaponPoolAvailable = 0; + + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 100; + }; }; }; diff --git a/addons/disposable/README.md b/addons/disposable/README.md index 82281a3c52..d7eee46bc8 100644 --- a/addons/disposable/README.md +++ b/addons/disposable/README.md @@ -1,12 +1,4 @@ ace_disposable ============== -Makes the NLAW a disposable one-shot weapon and provides disposable launchers framework for use by other mods. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [PabstMirror](https://github.com/PabstMirror) +Makes the NLAW a disposable one-shot weapon using the [CBA Disposable Framework](https://github.com/CBATeam/CBA_A3/wiki/Disposable-Launchers). diff --git a/addons/disposable/XEH_PREP.hpp b/addons/disposable/XEH_PREP.hpp deleted file mode 100644 index 8319e582aa..0000000000 --- a/addons/disposable/XEH_PREP.hpp +++ /dev/null @@ -1,4 +0,0 @@ - -PREP(replaceATWeapon); -PREP(takeLoadedATWeapon); -PREP(updateInventoryDisplay); diff --git a/addons/disposable/XEH_postInit.sqf b/addons/disposable/XEH_postInit.sqf deleted file mode 100644 index 4b395c6a64..0000000000 --- a/addons/disposable/XEH_postInit.sqf +++ /dev/null @@ -1,15 +0,0 @@ -// by commy2 -#include "script_component.hpp" - -if (!hasInterface) exitWith {}; - -["loadout", { - params ["_unit"]; - [_unit] call FUNC(takeLoadedATWeapon); - [_unit] call FUNC(updateInventoryDisplay); -}] call CBA_fnc_addPlayerEventHandler; - -// Register fire event handler -// Only for the local player and for AI. Non-local players will handle it themselves -["ace_firedPlayer", DFUNC(replaceATWeapon)] call CBA_fnc_addEventHandler; -["ace_firedNonPlayer", DFUNC(replaceATWeapon)] call CBA_fnc_addEventHandler; diff --git a/addons/disposable/XEH_preStart.sqf b/addons/disposable/XEH_preStart.sqf deleted file mode 100644 index 414ffaea97..0000000000 --- a/addons/disposable/XEH_preStart.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#include "script_component.hpp" - -#include "XEH_PREP.hpp" - -// Show warning for launchers still using disposables -{ - private _nonInheritedCfg = configProperties [_x, "configName _x == 'ACE_UsedTube'", false]; - if ((count _nonInheritedCfg) == 1) then { - private _weapon = configName _x; - if (_weapon != "launch_NLAW_F") then { // ignore the one we modifiy ourselves - WARNING_1("[%1] ACE_disposables functionality will be removed in a future version - switch to CBA Disposables",_weapon); - }; - }; -} forEach ("isText (_x >> 'ACE_UsedTube')" configClasses (configFile >> "CfgWeapons")); diff --git a/addons/disposable/config.cpp b/addons/disposable/config.cpp index 19b02871bc..b4561fd8b3 100644 --- a/addons/disposable/config.cpp +++ b/addons/disposable/config.cpp @@ -4,7 +4,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; - weapons[] = {}; + weapons[] = {"ACE_launch_NLAW_ready_F","ACE_launch_NLAW_used_F"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); @@ -14,7 +14,9 @@ class CfgPatches { }; }; -#include "CfgEventHandlers.hpp" +class CBA_DisposableLaunchers { + ACE_launch_NLAW_ready_F[] = {"launch_NLAW_F","ACE_launch_NLAW_used_F"}; +}; + #include "CfgWeapons.hpp" -#include "CfgMagazines.hpp" #include "CfgVehicles.hpp" diff --git a/addons/disposable/functions/fnc_replaceATWeapon.sqf b/addons/disposable/functions/fnc_replaceATWeapon.sqf deleted file mode 100644 index dcb5d93c1d..0000000000 --- a/addons/disposable/functions/fnc_replaceATWeapon.sqf +++ /dev/null @@ -1,69 +0,0 @@ -#include "script_component.hpp" -/* - * Author: bux, commy2 - * Replace the disposable launcher with the used dummy. Called from the unified fired EH. - * - * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) - * - * Return Value: - * None - * - * Example: - * [fromBisFiredEH] call ace_disposable_fnc_replaceATWeapon; - * - * Public: No - */ - -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); - -if (!local _unit || {_weapon != secondaryWeapon _unit} || {_weapon != _muzzle}) exitWith {}; - -private _replacementTube = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_UsedTube"); -if (_replacementTube == "") exitWith {}; //If no replacement defined just exit - -// Save magazine of spotting muzzle (should be re-added to replacement weapon) -(((getUnitLoadout _unit) select 1) select 5) params [["_spottingMag", ""], ["_spottingRnds", 0]]; -if (_spottingMag != "") then { _unit addMagazine [_spottingMag, _spottingRnds]; }; -//Save array of items attached to launcher -private _items = secondaryWeaponItems _unit; -//Replace the orginal weapon with the 'usedTube' weapon -_unit addWeapon _replacementTube; -//Makes sure the used tube is still equiped -_unit selectWeapon _replacementTube; -//Re-add all attachments to the used tube -{ - if (_x != "") then {_unit addSecondaryWeaponItem _x}; -} count _items; - - -// AI - Remove the ai's missle launcher tube after the missle has exploded -if !([_unit] call EFUNC(common,isPlayer)) then { - [{ - params ["_args","_idPFH"]; - _args params ["_unit", "_tube", "_projectile"]; - - //don't do anything until projectile is null (exploded/max range) - if (isNull _projectile) then { - //Remove PFEH: - [_idPFH] call CBA_fnc_removePerFrameHandler; - - //If (tube is dropped) OR (is dead) OR (is player) just exit - if (secondaryWeapon _unit != _tube || {!alive _unit} || {[_unit] call EFUNC(common,isPlayer)}) exitWith {}; - - //private _items = secondaryWeaponItems _unit; - private _container = createVehicle ["GroundWeaponHolder", position _unit, [], 0, "CAN_COLLIDE"]; - _container setPosAsl (getPosAsl _unit); - _container addWeaponCargoGlobal [_tube, 1]; - - //This will duplicate attachements, because we will be adding a weapon that may already have attachments on it - //We either need a way to add a clean weapon, or a way to add a fully configured weapon to a container: - // { - // if (_x != "") then {_container addItemCargoGlobal [_x, 1];}; - // } forEach _items; - - _unit removeWeaponGlobal _tube; - }; - }, 1, [_unit, _replacementTube, _projectile]] call CBA_fnc_addPerFrameHandler; -}; diff --git a/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf b/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf deleted file mode 100644 index 3f12d610d3..0000000000 --- a/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf +++ /dev/null @@ -1,59 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Handle the take event. Add a dummy magazine if a disposable rocket launcher is taken. - * - * Arguments: - * 0: unit - Object the event handler is assigned to - * - * Return Value: - * None - * - * Example: - * [fromTakeEH] call ace_disposable_fnc_takeLoadedATWeapon; - * - * Public: No - */ - -params ["_unit"]; -TRACE_1("params",_unit); - -if (!local _unit) exitWith {}; - -private _launcher = secondaryWeapon _unit; -private _config = configFile >> "CfgWeapons" >> _launcher; - -if (isClass _config && {getText (_config >> "ACE_UsedTube") != ""} && {getNumber (_config >> "ACE_isUsedLauncher") != 1} && {count secondaryWeaponMagazine _unit == 0}) then { - private _magazine = getArray (_config >> "magazines") select 0; - private _isLauncherSelected = currentWeapon _unit == _launcher; - - _unit removeMagazines _magazine; - - if (backpack _unit == "") then { - _unit addBackpack "ACE_FakeBackpack"; - _unit removeWeapon _launcher; - _unit addMagazine _magazine; - private _didAdd = _magazine in magazines _unit; - _unit addWeapon _launcher; - - if (!_didAdd) then { - TRACE_1("Failed To Add Disposable Magazine Normally, doing backup method (no backpack)",_unit); - _unit addSecondaryWeaponItem _magazine; - }; - removeBackpack _unit; - } else { - _unit removeWeapon _launcher; - _unit addMagazine _magazine; - private _didAdd = _magazine in magazines _unit; - _unit addWeapon _launcher; - - if (!_didAdd) then { - TRACE_2("Failed To Add Disposable Magazine Normally, doing backup method",_unit,(backpack _unit)); - _unit addSecondaryWeaponItem _magazine; - }; - }; - - if (_isLauncherSelected) then { - _unit selectWeapon _launcher; - }; -}; diff --git a/addons/disposable/functions/fnc_updateInventoryDisplay.sqf b/addons/disposable/functions/fnc_updateInventoryDisplay.sqf deleted file mode 100644 index 7ab2d18d75..0000000000 --- a/addons/disposable/functions/fnc_updateInventoryDisplay.sqf +++ /dev/null @@ -1,47 +0,0 @@ -#include "script_component.hpp" -/* - * Author: bux, commy2 - * Hide or show the secondary weapon magazine inventory slot to prevent unloading of dummy magazines. - * - * Arguments: - * 0: unit - Object the event handler is assigned to - * - * Return Value: - * None - * - * Example: - * [player] call ace_disposable_fnc_updateInventoryDisplay; - * - * Public: No - */ - -disableSerialization; -params ["_player", ["_display",(findDisplay 602),[displayNull]]]; -TRACE_2("params",_player,_display); - -_player removeMagazines "ACE_PreloadedMissileDummy"; -_player removeMagazines "ACE_FiredMissileDummy"; - -if (isNull _display) exitWith {}; - -private _launcher = secondaryWeapon _player; - -if (_launcher == "" || {getText (configFile >> "CfgWeapons" >> _launcher >> "ACE_UsedTube") == ""}) then { - private _control = _display displayCtrl 627; - private _config = configFile >> "RscDisplayInventory" >> "controls" >> "SlotSecondaryMagazine"; - _control ctrlSetPosition [getNumber (_config >> "x"), getNumber (_config >> "y"), getNumber (_config >> "w"), getNumber (_config >> "h")]; - _control ctrlCommit 0; - - _control = _display displayCtrl 1251; - _config = configFile >> "RscDisplayInventory" >> "controls" >> "BackgroundSlotSecondaryMagazine"; - _control ctrlSetPosition [getNumber (_config >> "x"), getNumber (_config >> "y"), getNumber (_config >> "w"), getNumber (_config >> "h")]; - _control ctrlCommit 0; -} else { - private _control = _display displayCtrl 627; - _control ctrlSetPosition [0, 0, 0, 0]; - _control ctrlCommit 0; - - _control = _display displayCtrl 1251; - _control ctrlSetPosition [0, 0, 0, 0]; - _control ctrlCommit 0; -}; diff --git a/addons/disposable/functions/script_component.hpp b/addons/disposable/functions/script_component.hpp deleted file mode 100644 index 035e8e6bcc..0000000000 --- a/addons/disposable/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\disposable\script_component.hpp" \ No newline at end of file diff --git a/addons/disposable/stringtable.xml b/addons/disposable/stringtable.xml index f41b2cad88..8878ed6e03 100644 --- a/addons/disposable/stringtable.xml +++ b/addons/disposable/stringtable.xml @@ -13,14 +13,15 @@ Lanciatore usato Tubo utilizado 使用済み - 사용함 + 사용한 발사관 使用過的火箭筒 使用过的火箭筒 + Kullanılmış Tüp Used disposable rocket launcher Benutzter Einweg-Raketenwerfer - Lance-roquette à usage unique utilisé + Lance-roquette à usage unique déjà utilisé Použitý raketomet Zużyta rura granatnika jednorazowego użytku Lanzador desechable utilizado @@ -32,20 +33,21 @@ 사용한 일회용 발사관 使用過的一次性火箭發射器 使用过的一次性火箭发射器 + Tek Kullanımlık Roket Atar Preloaded Missile Dummy Vorgeladene Racketennachbildung - Missile préchargé + Missile inerte préchargé Přednabitá maketa rakety Wstępnie załadowana atrapa pocisku Precargado misil inerte Előtöltött műrakéta Предзаряженная ракетная болванка Missile inerte precaricato - Míssel inerte pré-carregado + Míssil inerte pré-carregado 仮置きのミサイルをあらかじめ装填 - 임시로 미사일을 미리 장전 + 더미 미사일을 미리 장전하기 預裝訓練導彈 预装训练导弹 diff --git a/addons/dogtags/CfgEventHandlers.hpp b/addons/dogtags/CfgEventHandlers.hpp index e90bed419e..2a3f71f852 100644 --- a/addons/dogtags/CfgEventHandlers.hpp +++ b/addons/dogtags/CfgEventHandlers.hpp @@ -1,15 +1,15 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/dogtags/CfgUIGrids.hpp b/addons/dogtags/CfgUIGrids.hpp index f9216ac2ea..78944ccaad 100644 --- a/addons/dogtags/CfgUIGrids.hpp +++ b/addons/dogtags/CfgUIGrids.hpp @@ -5,13 +5,13 @@ class CfgUIGrids { class Variables { GVAR(grid)[] = { { - (safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W, - safeZoneY + 0.175 * safeZoneH, - 8 * GUI_GRID_W, - 8 * GUI_GRID_H + QUOTE((safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W), + QUOTE(safeZoneY + 0.175 * safeZoneH), + QUOTE(8 * GUI_GRID_W), + QUOTE(8 * GUI_GRID_H) }, - GUI_GRID_W, - GUI_GRID_H + QUOTE(GUI_GRID_W), + QUOTE(GUI_GRID_H) }; }; }; diff --git a/addons/dogtags/CfgWeapons.hpp b/addons/dogtags/CfgWeapons.hpp index ec8d9e6ee4..0f795d8d08 100644 --- a/addons/dogtags/CfgWeapons.hpp +++ b/addons/dogtags/CfgWeapons.hpp @@ -1,5 +1,5 @@ #define ACE_DOGTAG_ITEM(DOGTAGBASE,DOGTAGID) \ - class DOGTAGBASE##_##DOGTAGID : DOGTAGBASE { \ + class DOGTAGBASE##_##DOGTAGID: DOGTAGBASE { \ author = ECSTRING(common,ACETeam); \ scope = 1; \ scopeArsenal = 0; \ diff --git a/addons/dogtags/README.md b/addons/dogtags/README.md index 176b60750d..da24dd53d4 100644 --- a/addons/dogtags/README.md +++ b/addons/dogtags/README.md @@ -2,11 +2,3 @@ ace_dogtags ========== Adds options to check and take dog tag from dead or unconscious units - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [SzwedzikPL](https://github.com/SzwedzikPL) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/dogtags/RscTitles.hpp b/addons/dogtags/RscTitles.hpp index 97549c856e..aad72dfc5d 100644 --- a/addons/dogtags/RscTitles.hpp +++ b/addons/dogtags/RscTitles.hpp @@ -13,23 +13,23 @@ class RscTitles { class controls { class background: RscPicture { idc = 1000; - x = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', (safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W]; - y = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', safeZoneY + 0.175 * safeZoneH]; - w = 8 * GUI_GRID_W; - h = 8 * GUI_GRID_H; + x = QUOTE(profileNamespace getVariable [ARR_2('TRIPLES(IGUI,GVAR(grid),X)',(safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W)]); + y = QUOTE(profileNamespace getVariable [ARR_2('TRIPLES(IGUI,GVAR(grid),Y)',safeZoneY + 0.175 * safeZoneH)]); + w = QUOTE(8 * GUI_GRID_W); + h = QUOTE(8 * GUI_GRID_H); text = QPATHTOF(data\dogtagSingle.paa); colorText[] = {1, 1, 1, 1}; }; class nickname: RscStructuredText { idc = 1001; text = ""; - sizeEx = GUI_GRID_H; + sizeEx = QUOTE(GUI_GRID_H); colorText[] = {1, 1, 1, 1}; colorBackground[] = {0, 0, 0, 0}; - x = 1.6 * GUI_GRID_W + (profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', (safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W]); - y = 0.065 * safeZoneH + (profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', safeZoneY + 0.175 * safeZoneH]); - w = 5.9 * GUI_GRID_W; - h = 3 * GUI_GRID_H; + x = QUOTE(1.6 * GUI_GRID_W + (profileNamespace getVariable [ARR_2('TRIPLES(IGUI,GVAR(grid),X)',(safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W)])); + y = QUOTE(0.065 * safeZoneH + (profileNamespace getVariable [ARR_2('TRIPLES(IGUI,GVAR(grid),Y)',safeZoneY + 0.175 * safeZoneH)])); + w = QUOTE(5.9 * GUI_GRID_W); + h = QUOTE(3 * GUI_GRID_H); font = "RobotoCondensed"; class Attributes { font = "RobotoCondensed"; diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index 02d2db862b..dae6b62247 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -1,14 +1,15 @@ #include "script_component.hpp" -[QGVAR(showDogtag), DFUNC(showDogtag)] call CBA_fnc_addEventHandler; -[QGVAR(sendDogtagData), DFUNC(sendDogtagData)] call CBA_fnc_addEventHandler; -[QGVAR(getDogtagItem), DFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; -[QGVAR(addDogtagItem), DFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; +[QGVAR(showDogtag), LINKFUNC(showDogtag)] call CBA_fnc_addEventHandler; +[QGVAR(sendDogtagData), LINKFUNC(sendDogtagData)] call CBA_fnc_addEventHandler; +[QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; +[QGVAR(addDogtagItem), LINKFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; - -//Add actions and event handlers only if ace_medical is loaded +// Add actions and event handlers only if ace_medical is enabled // - Adding actions via config would create a dependency -if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +["CBA_settingsInitialized", { + if !(GETEGVAR(medical,enabled,false)) exitWith {}; + if (hasInterface) then { private _checkTagAction = [ "ACE_CheckDogtag", @@ -18,7 +19,7 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { {!isNil {_target getVariable QGVAR(dogtagData)}} ] call EFUNC(interact_menu,createAction); - ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction] call EFUNC(interact_menu,addActionToClass); + ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction, true] call EFUNC(interact_menu,addActionToClass); private _takeTagAction = [ "ACE_TakeDogtag", @@ -28,12 +29,13 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} ] call EFUNC(interact_menu,createAction); - ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction] call EFUNC(interact_menu,addActionToClass); + ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction, true] call EFUNC(interact_menu,addActionToClass); }; if (isServer) then { ["ace_placedInBodyBag", { - params ["_target", "_bodyBag"]; + params ["_target", "_bodyBag", "_isGrave"]; + if (_isGrave) exitWith {}; TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag); private _dogTagData = [_target] call FUNC(getDogtagData); @@ -44,37 +46,35 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { }; }] call CBA_fnc_addEventHandler; }; -}; +}] call CBA_fnc_addEventHandler; -if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { +// If the arsenal is loaded, show the custom names for dog tags when in the arsenal +if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { [QEGVAR(arsenal,rightPanelFilled), { - params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then { LOG("passed"); private _rightPanel = _display displayCtrl 15; - (lnbSize _rightPanel) params ["_rows", "_columns"]; + private _allDogtags = missionNamespace getVariable [QGVAR(allDogtags), []]; + private _allDogtagsData = missionNamespace getVariable [QGVAR(allDogtagDatas), []]; + private _cfgWeapons = configFile >> "CfgWeapons"; + private _item = ""; + private _dogtagData = []; - private _allDogtags = missionNameSpace getVariable [QGVAR(allDogtags), []]; - private _allDogtagDatas = missionNameSpace getVariable [QGVAR(allDogtagDatas), []]; + for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { + _item = _rightPanel lnbData [_i, 0]; - for "_r" from 0 to (_rows - 1) do { - private _data = _rightPanel lnbData [_r, 0]; + if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { + _dogtagData = _allDogtagsData param [_allDogtags find _item, []]; - if (_data isKindOf ["ACE_dogtag", (configFile >> "CfgWeapons")]) then { - - private _dogtagData = []; - private _index = _allDogtags find _data; - _dogtagData = _allDogtagDatas select _index; - private _dogtagString = [localize LSTRING(itemName), ": ", (_dogtagData select 0)] joinString ""; - - _rightPanel lnbSetText [[_r, 1], _dogtagString]; + // If data doesn't exist, put name as "unknown" + _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _dogtagData param [0, LELSTRING(common,unknown)]] joinString ""]; }; }; }; }] call CBA_fnc_addEventHandler; }; -// disable dogtags for civilians +// Disable dogtags for civilians "CIV_F" call FUNC(disableFactionDogtags); diff --git a/addons/dogtags/XEH_preInit.sqf b/addons/dogtags/XEH_preInit.sqf index a7a080b91e..f5fcb406b1 100644 --- a/addons/dogtags/XEH_preInit.sqf +++ b/addons/dogtags/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(disabledFactions) = [] call CBA_fnc_createNamespace; - +GVAR(disabledFactions) = createHashMap; + ADDON = true; diff --git a/addons/dogtags/functions/fnc_addDogtagActions.sqf b/addons/dogtags/functions/fnc_addDogtagActions.sqf index 2911b27a92..7c7a2e5e8f 100644 --- a/addons/dogtags/functions/fnc_addDogtagActions.sqf +++ b/addons/dogtags/functions/fnc_addDogtagActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL, mharis001 * Returns children actions for checking dogtags in player's inventory. diff --git a/addons/dogtags/functions/fnc_addDogtagItem.sqf b/addons/dogtags/functions/fnc_addDogtagItem.sqf index acecd6b252..970bb1926e 100644 --- a/addons/dogtags/functions/fnc_addDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_addDogtagItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Adds dogtag item to unit (triggered by server). diff --git a/addons/dogtags/functions/fnc_bloodType.sqf b/addons/dogtags/functions/fnc_bloodType.sqf index 46e75ee7f9..5e03c586fa 100644 --- a/addons/dogtags/functions/fnc_bloodType.sqf +++ b/addons/dogtags/functions/fnc_bloodType.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Reports a blood type depending on the units name. diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 8abbf8858d..bec3ef0dfa 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Checks if dogtag can be checked. @@ -21,6 +21,6 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; // check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 8bcad4a73d..c482d74c1c 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Checks if dogtag can be taken. @@ -21,6 +21,6 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; // check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_checkDogtag.sqf b/addons/dogtags/functions/fnc_checkDogtag.sqf index fb722361a4..dcceb8c2c0 100644 --- a/addons/dogtags/functions/fnc_checkDogtag.sqf +++ b/addons/dogtags/functions/fnc_checkDogtag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Checks unit dogtag. @@ -22,7 +22,7 @@ params ["_player", "_target"]; _player call EFUNC(common,goKneeling); // sound -private _position = AGLToASL (_target modelToWorld (_target selectionPosition "neck")); +private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ selectRandom RUSTLING_SOUNDS, diff --git a/addons/dogtags/functions/fnc_checkDogtagItem.sqf b/addons/dogtags/functions/fnc_checkDogtagItem.sqf index 8ce7864774..09526d83ed 100644 --- a/addons/dogtags/functions/fnc_checkDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_checkDogtagItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Check dogtag self menu action. diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf index c299af3a7d..c4642ef4b5 100644 --- a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Disable this faction from using dogtags. @@ -17,4 +17,9 @@ params [["_faction", "", [""]]]; -GVAR(disabledFactions) setVariable [_faction, true]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {}; + +GVAR(disabledFactions) set [_faction, true]; diff --git a/addons/dogtags/functions/fnc_getDogtagData.sqf b/addons/dogtags/functions/fnc_getDogtagData.sqf index d566daf64b..6a850543fc 100644 --- a/addons/dogtags/functions/fnc_getDogtagData.sqf +++ b/addons/dogtags/functions/fnc_getDogtagData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Get unit dogtag data. diff --git a/addons/dogtags/functions/fnc_getDogtagItem.sqf b/addons/dogtags/functions/fnc_getDogtagItem.sqf index 22a0561937..04112bcc94 100644 --- a/addons/dogtags/functions/fnc_getDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_getDogtagItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Server: creates new dogtag item and send it to client. diff --git a/addons/dogtags/functions/fnc_sendDogtagData.sqf b/addons/dogtags/functions/fnc_sendDogtagData.sqf index c43cf04dab..2351e61166 100644 --- a/addons/dogtags/functions/fnc_sendDogtagData.sqf +++ b/addons/dogtags/functions/fnc_sendDogtagData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Server: returns to client data on given dogtag. diff --git a/addons/dogtags/functions/fnc_showDogtag.sqf b/addons/dogtags/functions/fnc_showDogtag.sqf index 8e7bec620c..4865ff7de2 100644 --- a/addons/dogtags/functions/fnc_showDogtag.sqf +++ b/addons/dogtags/functions/fnc_showDogtag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Shows dogtag. diff --git a/addons/dogtags/functions/fnc_ssn.sqf b/addons/dogtags/functions/fnc_ssn.sqf index 3da972ecd8..0ba3499c0b 100644 --- a/addons/dogtags/functions/fnc_ssn.sqf +++ b/addons/dogtags/functions/fnc_ssn.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Reports a social security number generated from the units name. * * Arguments: diff --git a/addons/dogtags/functions/fnc_takeDogtag.sqf b/addons/dogtags/functions/fnc_takeDogtag.sqf index 464f282334..1972c91ee0 100644 --- a/addons/dogtags/functions/fnc_takeDogtag.sqf +++ b/addons/dogtags/functions/fnc_takeDogtag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * If dogtag is not already taken triggers event on server. @@ -23,7 +23,7 @@ params ["_player", "_target"]; _player call EFUNC(common,goKneeling); // sound -private _position = AGLToASL (_target modelToWorld (_target selectionPosition "neck")); +private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ selectRandom RUSTLING_SOUNDS, diff --git a/addons/dogtags/functions/script_component.hpp b/addons/dogtags/functions/script_component.hpp deleted file mode 100644 index 583e76df33..0000000000 --- a/addons/dogtags/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\dogtags\script_component.hpp" diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index 72793fd471..d19c61f505 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -6,26 +6,32 @@ Nieśmiertelnik Жетон Identifikační známka - ドッグ タグ - Hundemarke + ドッグタグ + Erkennungsmarke 군번줄 Plaque d'identification Piastrina 兵籍牌 兵籍牌 + Dog Tag + Placa de identidad + Künye Check Dog Tag Sprawdź nieśmiertelnik Проверить жетон Zkontrolovat známku - ドッグ タグを見る - Hundemarke prüfen + ドッグタグを確認 + Erkennungsmarke prüfen 군번줄 확인 - Vérifier les plaques d'identification + Vérifier la plaque d'identification Controlla Piastrina 檢查兵籍牌 检查兵籍牌 + Verificar Dog Tag + Verificar placa de identidad + Künyeyi Kontrol Et Check @@ -39,54 +45,73 @@ Controlla 檢查 检查 + Verificar + Verificar + Kontrol Et Take Zabierz Взять Vezmi - 取る + 拾う Nehmen 회수 Prendre Prendi 拿取 拿取 + Pegar + Tomar + Al Dogtag taken from %1... Zabrałeś nieśmiertelnik %1... Жетон снят с %1... Sebral jsem známku od %1... - %1からドッグ タグを取っています・・・ - Hundemarke von %1 genommen ... - %1로부터 군번줄을 회수했습니다... - Plaque d'identification pris sur %1... + %1 からドッグタグを回収しています・・・ + Erkennungsmarke von %1 genommen... + %1(으)로부터 군번줄을 회수했습니다... + Plaque d'identification prise sur %1... Piastrina presa da %1... 從%1身上拿取兵籍牌... 从%1身上拿取兵籍牌... + Dogtag pego de %1... + Tomada placa de identidad de %1... + Künye %1 kişisinden alındı Somebody else has already taken the dogtag... Ktoś już zabrał ten nieśmiertelnik... Кто-то уже забрал жетон... Někdo jiný už vzal identifikační známku... - すでにドッグ タグは取られています・・・ - Jemand anderes hat bereits die Hundemarke genommen ... + 既に誰かがドッグタグを回収したようだ・・・ + Jemand anderes hat bereits die Erkennungsmarke genommen... 누군가 이미 군번줄을 회수해갔습니다... - Quelqu'un d'autre a déjâ pris les plaques d'identification... + Quelqu'un d'autre a déjà pris la plaque d'identification... Qualcun altro ha già preso la piastrina... 已經有人把他的兵籍牌拿走了... 已经有人把他的兵籍牌拿走了... + Alguém já pegou essa dogtag... + Alguien más ha tomado la placa de identidad + Başka biri zaten künyeyi almış Onscreen display for checking dogtags - Anzeige um Hundemarke zu überprüfen + Anzeige um Erkennungsmarke zu überprüfen 在畫面中顯示檢查兵籍牌 - 確認中のドッグタグを画面上で表示します - Display su schermo per il controllo delle piastrine + 在画面中显示检查兵籍牌 + 確認中のドッグタグを画面上に表示します + Indicatore su schermo per il controllo delle piastrine Wyświetlacz ekranowy dla sprawdzania nieśmiertelników Экран для проверки жетонов + Tela de Exibição para verificar dogtags + Visualización en pantalla de placa de identidad + Affichage à l'écran pour le contrôle des plaques. + Okno na obrazovce pro kontrolu známek + Künye gösteriliyor + 군번줄 확인 시 화면에 보여줍니다 diff --git a/addons/dragging/CfgEventHandlers.hpp b/addons/dragging/CfgEventHandlers.hpp index 424c2a3fed..d3b43b314a 100644 --- a/addons/dragging/CfgEventHandlers.hpp +++ b/addons/dragging/CfgEventHandlers.hpp @@ -1,46 +1,59 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_Init_EventHandlers { class CAManBase { class ADDON { - init = QUOTE(_this call DFUNC(initPerson)); + init = QUOTE(_this call FUNC(initPerson)); + exclude[] = {"VirtualMan_F"}; }; }; class StaticWeapon { class ADDON { - init = QUOTE(_this call DFUNC(initObject)); + init = QUOTE(_this call FUNC(initObject)); }; }; - class ThingX { + class Thing { class ADDON { - init = QUOTE(_this call DFUNC(initObject)); + init = QUOTE(_this call FUNC(initObject)); + exclude[] = {"ModuleEmpty_F", "ThingEffect", "Wreck"}; }; }; - class Land_PortableLight_single_F { + class NonStrategic { class ADDON { - init = QUOTE(_this call DFUNC(initObject)); + init = QUOTE(_this call FUNC(initObject)); + }; + }; + class WeaponHolder { + class ADDON { + init = QUOTE(_this call FUNC(initObject)); + exclude[] = {"GroundWeaponHolder_Scripted"}; + }; + }; + class WeaponHolderSimulated { + class ADDON { + init = QUOTE(_this call FUNC(initObject)); + exclude[] = {"WeaponHolderSimulated_Scripted"}; }; }; class Land_Camping_Light_F { class ADDON { - init = QUOTE(_this call DFUNC(initObject)); + init = QUOTE(_this call FUNC(initObject)); }; }; }; @@ -48,13 +61,7 @@ class Extended_Init_EventHandlers { class Extended_Killed_EventHandlers { class CAManBase { class ADDON { - killed = QUOTE(_this call DFUNC(handleKilled)); + killed = QUOTE(_this call FUNC(handleKilled)); }; }; }; - -class Extended_DisplayLoad_EventHandlers { - class RscDisplayMission { - ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); - }; -}; diff --git a/addons/dragging/CfgMovesBasic.hpp b/addons/dragging/CfgMovesBasic.hpp index de15271416..cfaa9b7ad0 100644 --- a/addons/dragging/CfgMovesBasic.hpp +++ b/addons/dragging/CfgMovesBasic.hpp @@ -1,8 +1,62 @@ class CfgMovesBasic { + class ManActions { + ACE_dragWithPistol = "ace_dragging"; + ACE_dragWithRifle = "AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_2"; + }; + class Actions { class MoveWithInjuredManDragger; class MoveWithInjuredManDraggerRfl: MoveWithInjuredManDragger { + LimpB = "ace_dragging_rifle_limpB"; + LimpLB = "ace_dragging_rifle_limpB"; + LimpRB = "ace_dragging_rifle_limpB"; Up = "amovpercmstpsraswrfldnon"; }; + + class MoveWithInjuredManDraggerPst; + class ACE_MoveWithInjuredManDraggerPst: MoveWithInjuredManDraggerPst { + Default = "ace_dragging_static"; + FastB = "ace_dragging"; + FastLB = "ace_dragging"; + FastRB = "ace_dragging"; + grabDrag = "ace_dragging_static"; + grabCarry = "Helper_SwitchToCarrynon_pst"; + HandGunOn = "ace_dragging_static"; + LimpB = "ace_dragging_limpB"; + LimpLB = "ace_dragging_limpB"; + LimpRB = "ace_dragging_limpB"; + PlayerSlowB = "ace_dragging"; + PlayerSlowLB = "ace_dragging"; + PlayerSlowRB = "ace_dragging"; + PlayerTactB = "AmovPknlMtacSrasWpstDb"; + PlayerTactF = "AmovPknlMtacSrasWpstDf"; + PlayerTactL = "AmovPknlMtacSrasWpstDl"; + PlayerTactLB = "AmovPknlMtacSrasWpstDbl"; + PlayerTactLF = "AmovPknlMtacSrasWpstDfl"; + PlayerTactR = "AmovPknlMtacSrasWpstDr"; + PlayerTactRB = "AmovPknlMtacSrasWpstDbr"; + PlayerTactRF = "AmovPknlMtacSrasWpstDfr"; + PlayerWalkB = "ace_dragging"; + PlayerWalkLB = "ace_dragging"; + PlayerWalkRB = "ace_dragging"; + released = "ace_dragging_drop"; + SlowB = "ace_dragging"; + SlowLB = "ace_dragging"; + SlowRB = "ace_dragging"; + Stop = "ace_dragging_static"; + StopRelaxed = "ace_dragging_static"; + TactB = "AmovPknlMtacSrasWpstDb"; + TactF = "AmovPknlMtacSrasWpstDf"; + TactL = "AmovPknlMtacSrasWpstDl"; + TactLB = "AmovPknlMtacSrasWpstDbl"; + TactLF = "AmovPknlMtacSrasWpstDfl"; + TactR = "AmovPknlMtacSrasWpstDr"; + TactRB = "AmovPknlMtacSrasWpstDbr"; + TactRF = "AmovPknlMtacSrasWpstDfr"; + Up = "ace_dragging_static"; + WalkB = "ace_dragging"; + WalkLB = "ace_dragging"; + WalkRB = "ace_dragging"; + }; }; }; diff --git a/addons/dragging/CfgMovesMaleSdr.hpp b/addons/dragging/CfgMovesMaleSdr.hpp new file mode 100644 index 0000000000..fb965dd713 --- /dev/null +++ b/addons/dragging/CfgMovesMaleSdr.hpp @@ -0,0 +1,138 @@ +class CfgMovesMaleSdr: CfgMovesBasic { + class InjuredMovedBase; + class AgonyBaseRfl; + class StandBase; + + class States { + class AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon: InjuredMovedBase { + speed = -10; // 1/10 + }; + + class AinjPfalMstpSnonWrflDnon_carried_Up: AgonyBaseRfl { + speed = -10; // 1/10 + }; + + // For dragging with rifles + class AmovPercMstpSlowWrflDnon; + class AmovPercMstpSrasWrflDnon: AmovPercMstpSlowWrflDnon { + ConnectTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + }; + + class AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_1; + class AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_2: AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_1 { + aiming = "aimingDefault"; + aimingBody = "aimingUpDefault"; + aimPrecision = 5; // default: 1 + ConnectTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + InterpolateTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + }; + + class AcinPknlMstpSrasWrflDnon: AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_1 { + ConnectTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + InterpolateTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + }; + + class AcinPknlMwlkSrasWrflDb: AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_1 { + ConnectTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + InterpolateTo[] += { + "ace_dragging_rifle_limpB", + 0.1 + }; + }; + + class ace_dragging_rifle_limpB: AcinPknlMwlkSrasWrflDb { + speed = 0.5; + }; + + // For dragging with pistols + class AmovPercMstpSrasWpstDnon: StandBase { + ConnectTo[] += { + "ace_dragging", + 0.1, + "ace_dragging_limpB", + 0.1, + "ace_dragging_static", + 0.1 + }; + }; + + class DraggerBase; + class ace_dragging: DraggerBase { + actions = "ACE_MoveWithInjuredManDraggerPst"; + aiming = "aimingPistol"; + aimingBody = "aimingPistol"; + aimPrecision = 2; // default: 1 + canPullTrigger = 1; + canReload = 0; + ConnectTo[] = { + "ace_dragging", + 0.1, + "ace_dragging_limpB", + 0.1, + "ace_dragging_drop", + 0.2, + "ace_dragging_static", + 0.1 + }; + disableWeapons = 0; + duty = 0.6; + enableBinocular = 0; + file = QPATHTO_T(anim\ace_dragging.rtm); + InterpolateTo[] = { + "ace_dragging", + 0.1, + "ace_dragging_limpB", + 0.1, + "ace_dragging_drop", + 0.2, + "ace_dragging_static", + 0.1 + }; + interpolationSpeed = 5; + limitGunMovement = 0.2; + looped = 1; + showHandGun = 1; + turnSpeed = 0.5; + }; + + class ace_dragging_limpB: ace_dragging { + speed = 0.5; + }; + + class ace_dragging_static: ace_dragging { + speed = 0; + }; + + class ace_dragging_drop: ace_dragging { + ConnectTo[] = { + "AmovPknlMstpSrasWpstDnon", + 0.1 + }; + file = QPATHTO_T(anim\ace_dragging_drop.rtm); + InterpolateTo[] = { + "Unconscious", + 0.02 + }; + interpolationSpeed = 5; + looped = 0; + }; + }; +}; diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index 4c43dd814e..395133e946 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -1,3 +1,4 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} class CBA_Extended_EventHandlers; @@ -7,11 +8,9 @@ class CfgVehicles { class StaticWeapon: LandVehicle { GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,1.2,0}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1.2,0}; - GVAR(dragDirection) = 0; }; class StaticCannon: StaticWeapon { @@ -19,15 +18,19 @@ class CfgVehicles { GVAR(canDrag) = 0; }; + // Invisible Target Soldier + class TargetSoldierBase: StaticWeapon { + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class StaticMortar; class Mortar_01_base_F: StaticMortar { GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,1.2,0}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1.2,0}; - GVAR(dragDirection) = 0; }; // Big 1.70 and 1.84 Autonomous AA Turrets @@ -69,24 +72,21 @@ class CfgVehicles { GVAR(canDrag) = 0; }; - // ammo boxes + // Ammo boxes class ThingX; class Items_base_F; class ReammoBox_F: ThingX { GVAR(canCarry) = 0; - GVAR(carryPosition)[] = {0,1,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 0; GVAR(dragPosition)[] = {0,1.2,0}; - GVAR(dragDirection) = 0; }; class Slingload_base_F: ReammoBox_F { GVAR(canCarry) = 0; GVAR(canDrag) = 0; }; - //remove actions from Taru Pods + // Remove actions from Taru Pods class Pod_Heli_Transport_04_base_F: Slingload_base_F { GVAR(canCarry) = 0; GVAR(canDrag) = 0; @@ -160,45 +160,29 @@ class CfgVehicles { GVAR(canDrag) = 0; }; - //Plastic and metal case + // Plastic and metal case class PlasticCase_01_base_F: Items_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; GVAR(canCarry) = 1; - GVAR(carryPosition[]) = {0,1,1}; GVAR(carryDirection) = 270; GVAR(canDrag) = 1; - GVAR(dragPosition[]) = {0,1.2,0}; + GVAR(dragPosition)[] = {0,1.2,0}; GVAR(dragDirection) = 270; }; class MetalCase_01_base_F: Items_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; GVAR(canCarry) = 1; - GVAR(carryPosition[]) = {0,1,1}; GVAR(carryDirection) = 270; GVAR(canDrag) = 1; - GVAR(dragPosition[]) = {0,1.2,0}; - GVAR(dragDirection) = 0; + GVAR(dragPosition)[] = {0,1.2,0}; }; // Barrier class RoadCone_F: ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - GVAR(canCarry) = 1; - GVAR(carryPosition)[] = {0,1,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1.2,0}; - GVAR(dragDirection) = 0; }; class RoadBarrier_F: RoadCone_F { @@ -208,59 +192,64 @@ class CfgVehicles { // Misc crates class Constructions_base_F; class Land_WoodenBox_F: Constructions_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; - GVAR(carryPosition[]) = {0,1,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; - GVAR(dragPosition[]) = {0,1.4,0}; - GVAR(dragDirection) = 0; + GVAR(dragPosition)[] = {0,1.4,0}; }; class Land_WoodenCrate_01_F: ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; GVAR(canCarry) = 1; - GVAR(carryPosition[]) = {0,1,1}; GVAR(carryDirection) = 270; GVAR(canDrag) = 1; - GVAR(dragPosition[]) = {0,1.5,0}; GVAR(dragDirection) = 90; }; class Land_PaperBox_01_small_closed_base_F: Items_base_F { GVAR(canCarry) = 1; - GVAR(carryPosition[]) = {0,1,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; - GVAR(dragPosition[]) = {0,1.5,0}; GVAR(dragDirection) = 90; }; class Box_UAV_06_base_F: Items_base_F { GVAR(canCarry) = 1; - GVAR(carryPosition[]) = {0,1,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; - GVAR(dragPosition[]) = {0,1.5,0}; - GVAR(dragDirection) = 0; }; class ACE_RepairItem_Base: ThingX {}; class ACE_Track: ACE_RepairItem_Base { GVAR(canCarry) = 1; - GVAR(carryPosition)[] = {0,1,1}; - GVAR(carryDirection) = 0; }; class ACE_Wheel: ACE_RepairItem_Base { GVAR(canCarry) = 1; - GVAR(carryPosition)[] = {0,1,1}; + }; + + // Weapons dropped from dead body + class WeaponHolderSimulated: ThingX { + GVAR(canCarry) = 1; + GVAR(carryPosition[]) = {0,0.5,1.3}; GVAR(carryDirection) = 0; + + // z-position floats from -1.2 to > 0 + // It's OK for carrying but odd for dragging + // Needs workaround to drag correctly. Disabled ATM + GVAR(canDrag) = 0; + GVAR(dragPosition[]) = {0,1,0}; + GVAR(dragDirection) = 0; + }; + + class ReammoBox; + // Dropped weapons/gear + class WeaponHolder: ReammoBox { + GVAR(canCarry) = 1; + GVAR(carryPosition[]) = {0,0.5,1}; + GVAR(carryDirection) = 0; + + GVAR(canDrag) = 1; + GVAR(dragPosition[]) = {0,1,0}; + GVAR(dragDirection) = 0; }; class Lamps_base_F; @@ -276,21 +265,167 @@ class CfgVehicles { class FloatingStructure_F; class Land_Camping_Light_F: FloatingStructure_F { GVAR(canCarry) = 1; - // if y < 0.9 player gets damage + // If y < 0.9 player gets damaged GVAR(carryPosition)[] = {0,0.9,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,0.7,0}; - GVAR(dragDirection) = 0; }; class Land_Camping_Light_off_F: ThingX { GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.9,1}; - GVAR(carryDirection) = 0; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,0.7,0}; - GVAR(dragDirection) = 0; + }; + + // Flexible Fuel tanks, 300L + class FlexibleTank_base_F: ThingX { + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.65,0}; + + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; + }; + + // Some terrain objects + class Land_CampingTable_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,1,0.5}; + }; + class Land_CampingTable_small_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,1,0.5}; + }; + class Land_GarbageContainer_closed_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragDirection) = 180; + }; + class Land_GarbageContainer_open_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragDirection) = 180; + }; + class Land_Sun_chair_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryDirection) = 90; + + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; + GVAR(dragDirection) = 90; + }; + class Land_TablePlastic_01_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,1,0}; + + GVAR(canDrag) = 1; + }; + class Land_Tyre_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,1}; + }; + class Land_WoodenTable_large_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragDirection) = 90; + }; + class Land_BarrelSand_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; + }; + class Land_BarrelWater_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; + }; + class Land_Bucket_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,1}; + }; + class Land_CanisterPlastic_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,0}; + }; + class Land_GarbageBarrel_01_english_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + }; + class Land_MetalBarrel_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; + }; + class Land_Pallet_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + + GVAR(canDrag) = 1; + }; + class Land_Pallet_vertical_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,0.6}; + GVAR(carryDirection) = 180; + }; + class Land_WheelCart_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + }; + class Land_WorkStand_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,1,0}; + + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; + }; + class Market_base_F; + class Land_Basket_F: Market_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,0.5}; + }; + class Land_WoodenCart_F: Market_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + }; + + + // Static classes need XEH + class NonStrategic; + class Land_Pallets_F: NonStrategic { + XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + }; + class Camping_base_F; + class Land_CampingChair_V1_folded_F: Camping_base_F { + XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,1}; + }; + class Stall_base_F; + class Land_CratesPlastic_F: Stall_base_F { + XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.6,1}; + }; + class House_Small_F; + class Land_MetalBarrel_empty_F: House_Small_F { + XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,1,0}; }; }; diff --git a/addons/dragging/README.md b/addons/dragging/README.md index b69484eccf..48a64bbc7e 100644 --- a/addons/dragging/README.md +++ b/addons/dragging/README.md @@ -2,11 +2,3 @@ ace_dragging ============== Adds ability to drag and carry objects. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Garth "L-H" de Wet](https://github.com/CorruptedHeart) -- [commy2](https://github.com/commy2) diff --git a/addons/dragging/XEH_PREP.hpp b/addons/dragging/XEH_PREP.hpp index b04c15e7ec..0861c9533d 100644 --- a/addons/dragging/XEH_PREP.hpp +++ b/addons/dragging/XEH_PREP.hpp @@ -1,8 +1,8 @@ - PREP(canCarry); PREP(canDrag); PREP(canDrop); PREP(canDrop_carry); +PREP(canRun_carry); PREP(carryObject); PREP(carryObjectPFH); PREP(dragObject); @@ -19,9 +19,15 @@ PREP(handleUnconscious); PREP(initObject); PREP(initPerson); PREP(isObjectOnObject); +PREP(pauseCarry); +PREP(pauseDrag); +PREP(resumeCarry); +PREP(resumeDrag); PREP(setCarryable); PREP(setDraggable); PREP(startCarry); +PREP(startCarryLocal); PREP(startCarryPFH); PREP(startDrag); +PREP(startDragLocal); PREP(startDragPFH); diff --git a/addons/dragging/XEH_missionDisplayLoad.sqf b/addons/dragging/XEH_missionDisplayLoad.sqf deleted file mode 100644 index 289d2f067a..0000000000 --- a/addons/dragging/XEH_missionDisplayLoad.sqf +++ /dev/null @@ -1,5 +0,0 @@ -#include "script_component.hpp" - -params ["_display"]; - -_display displayAddEventHandler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}]; diff --git a/addons/dragging/XEH_postInit.sqf b/addons/dragging/XEH_postInit.sqf index f2cb60c646..ae277bf4d2 100644 --- a/addons/dragging/XEH_postInit.sqf +++ b/addons/dragging/XEH_postInit.sqf @@ -2,8 +2,8 @@ #include "script_component.hpp" if (isServer) then { - // release object on hard disconnection. Function is identical to killed - addMissionEventHandler ["HandleDisconnect", {_this call FUNC(handleKilled)}]; + // Release object on disconnection. Function is identical to killed + addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleKilled)]; }; if (!hasInterface) exitWith {}; @@ -16,40 +16,95 @@ if (isNil "ACE_maxWeightCarry") then { ACE_maxWeightCarry = 600; }; +if (isNil QGVAR(maxWeightCarryRun)) then { + GVAR(maxWeightCarryRun) = 50; +}; + ["isNotDragging", {!((_this select 0) getVariable [QGVAR(isDragging), false])}] call EFUNC(common,addCanInteractWithCondition); ["isNotCarrying", {!((_this select 0) getVariable [QGVAR(isCarrying), false])}] call EFUNC(common,addCanInteractWithCondition); -// release object on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +// Release object on player change. This does work when returning to lobby, but not when hard disconnecting. +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; -["weapon", FUNC(handlePlayerWeaponChanged)] call CBA_fnc_addPlayerEventHandler; +["weapon", LINKFUNC(handlePlayerWeaponChanged)] call CBA_fnc_addPlayerEventHandler; -// handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +// When changing cameras, drop carried and dragged objects +["featureCamera", { + params ["_unit", "_camera"]; -//@todo Captivity? - -//Add Keybind: -["ACE3 Common", QGVAR(drag), (localize LSTRING(DragKeybind)), { - if (!alive ACE_player) exitWith {false}; - if !([ACE_player, objNull, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {false}; - - // If we are drag/carrying something right now then just drop it: - if (ACE_player getVariable [QGVAR(isDragging), false]) exitWith { - [ACE_player, ACE_player getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); - false + // Unit can either drag or carry, functions themselves handle which ones are executed + switch (_camera) do { + // Default camera + case "": { + _unit call FUNC(resumeDrag); + _unit call FUNC(resumeCarry); + }; + // Arsenals make the unit change animations, which makes the unit drop dragged/carried objects regardless + case "arsenal"; + case "ace_arsenal": { + _unit call FUNC(handleKilled); + }; + default { + _unit call FUNC(pauseDrag); + _unit call FUNC(pauseCarry); + }; }; - if (ACE_player getVariable [QGVAR(isCarrying), false]) exitWith { - [ACE_player, ACE_player getVariable [QGVAR(carriedObject), objNull]] call FUNC(dropObject_carry); - false +}] call CBA_fnc_addPlayerEventHandler; + +// Handle waking up dragged unit and falling unconscious while dragging +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; + +// Display event handler +["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}] call CBA_fnc_addDisplayHandler; + +// Handle surrendering and handcuffing +["ace_captiveStatusChanged", { + params ["_unit", "_state"]; + + // If surrended or handcuffed, drop dragged/carried object + if (_state && {local _unit}) then { + _unit call FUNC(handleKilled); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(startCarry), LINKFUNC(startCarryLocal)] call CBA_fnc_addEventHandler; +[QGVAR(startDrag), LINKFUNC(startDragLocal)] call CBA_fnc_addEventHandler; + +[QGVAR(carryingContainerClosed), { + params ["_container", "_owner"]; + TRACE_2("carryingContainerClosed EH",_container,_owner); + if !(_owner getVariable [QGVAR(isCarrying), false]) exitWith { ERROR_1("not carrying - %1",_this) }; + + private _weight = 0; + if !(_container getVariable [QGVAR(ignoreWeightCarry), false]) then { + _weight = [_container] call FUNC(getWeight); }; - private _cursor = cursorObject; - if ((isNull _cursor) || {(_cursor distance ACE_player) > 2.6}) exitWith {false}; - if (!([ACE_player, _cursor] call FUNC(canDrag))) exitWith {false}; + // Drop the object if overweight + if (_weight > ACE_maxWeightCarry) exitWith { + [_owner, _container] call FUNC(dropObject_carry); + }; + private _canRun = [_weight] call FUNC(canRun_carry); - [ACE_player, _cursor] call FUNC(startDrag); - false -}, { - false -}, [-1, [false, false, false]]] call CBA_fnc_addKeybind; // UNBOUND + // Force walking based on weight + [_owner, "forceWalk", QUOTE(ADDON), !_canRun] call EFUNC(common,statusEffect_set); + [_owner, "blockSprint", QUOTE(ADDON), _canRun] call EFUNC(common,statusEffect_set); +}] call CBA_fnc_addEventHandler; + +[QGVAR(draggingContainerClosed), { + params ["_container", "_owner"]; + TRACE_2("draggingContainerClosed EH",_container,_owner); + if !(_owner getVariable [QGVAR(isDragging), false]) exitWith { ERROR_1("not dragging - %1",_this) }; + + private _weight = 0; + if !(_container getVariable [QGVAR(ignoreWeightDrag), false]) then { + _weight = [_container] call FUNC(getWeight); + }; + + // Drop the object if overweight + if (_weight > ACE_maxWeightDrag) exitWith { + [_owner, _container] call FUNC(dropObject); + }; +}] call CBA_fnc_addEventHandler; + +#include "initKeybinds.inc.sqf" diff --git a/addons/dragging/XEH_preInit.sqf b/addons/dragging/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/dragging/XEH_preInit.sqf +++ b/addons/dragging/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/dragging/anim/ace_dragging.rtm b/addons/dragging/anim/ace_dragging.rtm new file mode 100644 index 0000000000..e3f5f6f611 Binary files /dev/null and b/addons/dragging/anim/ace_dragging.rtm differ diff --git a/addons/dragging/anim/ace_dragging_drop.rtm b/addons/dragging/anim/ace_dragging_drop.rtm new file mode 100644 index 0000000000..4d0b1d3a85 Binary files /dev/null and b/addons/dragging/anim/ace_dragging_drop.rtm differ diff --git a/addons/dragon/anim/model.cfg b/addons/dragging/anim/model.cfg similarity index 100% rename from addons/dragon/anim/model.cfg rename to addons/dragging/anim/model.cfg diff --git a/addons/dragging/anim/zDummy.rtm b/addons/dragging/anim/zDummy.rtm new file mode 100644 index 0000000000..dfeb7b7fcc Binary files /dev/null and b/addons/dragging/anim/zDummy.rtm differ diff --git a/addons/dragging/config.cpp b/addons/dragging/config.cpp index c3f5d0dd84..26e5e2c88f 100644 --- a/addons/dragging/config.cpp +++ b/addons/dragging/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); - authors[] = {"Garth 'L-H' de Wet", "commy2", "PiZZADOX"}; + authors[] = {"Garth 'L-H' de Wet", "commy2", "PiZZADOX", "Malbryn"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; @@ -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_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf index b5edbd800c..be3015868b 100644 --- a/addons/dragging/functions/fnc_canCarry.sqf +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Check if unit can carry the object. Doesn't check weight. + * Author: commy2, Dystopian + * Checks if unit can carry the object. Doesn't check weight. * * Arguments: * 0: Unit that should do the carrying @@ -11,20 +11,36 @@ * Can the unit carry the object? * * Example: - * [player, cursorTarget] call ace_dragging_fnc_canCarry; + * [player, cursorTarget] call ace_dragging_fnc_canCarry * * Public: No */ params ["_unit", "_target"]; +if !(alive _target && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false}; + if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; -//#2644 - Units with injured legs cannot bear the extra weight of carrying an object -//The fireman carry animation does not slow down for injured legs, so you could carry and run +// #2644 - Units with injured legs cannot bear the extra weight of carrying an object +// The fireman carry animation does not slow down for injured legs, so you could carry and run if ((_unit getHitPointDamage "HitLegs") >= 0.5) exitWith {false}; -// a static weapon has to be empty for dragging (ignore UAV AI) -if (((typeOf _target) isKindOf "StaticWeapon") && {{(getText (configFile >> "CfgVehicles" >> (typeOf _x) >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; +// Static weapons need to be empty for carrying (ignore UAV AI) +if (_target isKindOf "StaticWeapon") exitWith { + (crew _target) findIf {!unitIsUAV _x} == -1 +}; -alive _target && {vehicle _target isEqualto _target} && {_target getVariable [QGVAR(canCarry), false]} && {animationState _target in ["", "unconscious"] || (_target getVariable ["ACE_isUnconscious", false]) || (_target isKindOf "CAManBase" && {(_target getHitPointDamage "HitLegs") > 0.4})} +// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues +if (_target isKindOf "CAManBase") exitWith { + isAwake _target && // not ragdolled + {lifeState _target == "INCAPACITATED" || + {_target getHitPointDamage "HitLegs" >= 0.5}} +}; + +// Check max items for WeaponHolders +if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith { + (count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS +}; + +true // return diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index dbae83521b..586e23feaf 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Check if unit can drag the object. Doesn't check weight. + * Author: commy2, Dystopian + * Checks if unit can drag the object. Doesn't check weight. * * Arguments: * 0: Unit that should do the dragging @@ -11,16 +11,32 @@ * Can the unit drag the object? * * Example: - * [player, cursorTarget] call ace_dragging_fnc_canDrag; + * [player, cursorTarget] call ace_dragging_fnc_canDrag * * Public: No */ params ["_unit", "_target"]; +if !(alive _target && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false}; + if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; -// a static weapon has to be empty for dragging (ignore UAV AI) -if ((typeOf _target) isKindOf "StaticWeapon" && {{(getText (configFile >> "CfgVehicles" >> (typeOf _x) >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; +// Static weapons need to be empty for dragging (ignore UAV AI) +if (_target isKindOf "StaticWeapon") exitWith { + (crew _target) findIf {!unitIsUAV _x} == -1 +}; -alive _target && {vehicle _target isEqualto _target} && {_target getVariable [QGVAR(canDrag), false]} && {animationState _target in ["", "unconscious"] || (_target getVariable ["ACE_isUnconscious", false]) || (_target isKindOf "CAManBase" && {(_target getHitPointDamage "HitLegs") > 0.4})} +// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues +if (_target isKindOf "CAManBase") exitWith { + isAwake _target && // not ragdolled + {lifeState _target == "INCAPACITATED" || + {_target getHitPointDamage "HitLegs" >= 0.5}} +}; + +// Check max items for WeaponHolders +if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith { + (count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS +}; + +true // return diff --git a/addons/dragging/functions/fnc_canDrop.sqf b/addons/dragging/functions/fnc_canDrop.sqf index 2d42ae6244..9fa5a5b3e5 100644 --- a/addons/dragging/functions/fnc_canDrop.sqf +++ b/addons/dragging/functions/fnc_canDrop.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Check if unit can drop the object. + * Checks if unit can drop the dragged object. * * Arguments: - * 0: Unit that currently drags a object - * 1: Object that is dragged + * 0: Unit that is currently dragging an object + * 1: Object being dragged * * Return Value: * Can the unit drop the object? diff --git a/addons/dragging/functions/fnc_canDrop_carry.sqf b/addons/dragging/functions/fnc_canDrop_carry.sqf index 89be866ea6..8dd2ed528e 100644 --- a/addons/dragging/functions/fnc_canDrop_carry.sqf +++ b/addons/dragging/functions/fnc_canDrop_carry.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Check if unit can drop the carried object. + * Checks if unit can drop the carried object. * * Arguments: - * 0: Unit that currently carries a object - * 1: Object that is carried + * 0: Unit that is currently carrying an object + * 1: Object being carried * * Return Value: * Can the unit drop the object? diff --git a/addons/dragging/functions/fnc_canRun_carry.sqf b/addons/dragging/functions/fnc_canRun_carry.sqf new file mode 100644 index 0000000000..50fd9eb25d --- /dev/null +++ b/addons/dragging/functions/fnc_canRun_carry.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Check if weight can be carried while running + * + * Arguments: + * 0: Weight + * + * Return Value: + * Can the weight be carried while running? + * + * Example: + * [500] call ace_dragging_fnc_canRun_carry + * + * Public: No + */ + +params ["_weight"]; + +GVAR(allowRunWithLightweight) && {_weight <= GVAR(maxWeightCarryRun)} diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf index f7976079b3..4d5ac8b61b 100644 --- a/addons/dragging/functions/fnc_carryObject.sqf +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Carry an object. + * Handles attaching and setting up a carried object. Called from ace_dragging_fnc_startCarryPFH. * * Arguments: * 0: Unit that should do the carrying @@ -19,63 +19,52 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); -// get attachTo offset and direction. - +// Get attachTo offset and direction private _position = _target getVariable [QGVAR(carryPosition), [0, 0, 0]]; private _direction = _target getVariable [QGVAR(carryDirection), 0]; -// handle objects vs persons +// Handle objects vs. persons if (_target isKindOf "CAManBase") then { + [_unit, "AcinPercMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation); + [_target, "AinjPfalMstpSnonWnonDf_carried_dead", 2] call EFUNC(common,doAnimation); - [_unit, "AcinPercMstpSnonWnonDnon", 2, true] call EFUNC(common,doAnimation); - [_target, "AinjPfalMstpSnonWnonDf_carried_dead", 2, true] call EFUNC(common,doAnimation); - - // attach person + // Attach person _target attachTo [_unit, _position, "LeftShoulder"]; - } else { - - // add height offset of model - private _offset = (_target modelToWorldVisual [0, 0, 0] select 2) - (_unit modelToWorldVisual [0, 0, 0] select 2); + // Add height offset of model + private _offset = ((_target modelToWorldVisual [0, 0, 0]) select 2) - ((_unit modelToWorldVisual [0, 0, 0]) select 2); _position = _position vectorAdd [0, 0, _offset]; - // attach object + // Attach object _target attachTo [_unit, _position]; - }; + [QEGVAR(common,setDir), [_target, _direction], _target] call CBA_fnc_targetEvent; _unit setVariable [QGVAR(isCarrying), true, true]; _unit setVariable [QGVAR(carriedObject), _target, true]; -// add drop action -_unit setVariable [QGVAR(ReleaseActionID), [ +// Add drop action +_unit setVariable [QGVAR(releaseActionID), [ _unit, "DefaultAction", {!isNull ((_this select 0) getVariable [QGVAR(carriedObject), objNull])}, - {[_this select 0, (_this select 0) getVariable [QGVAR(carriedObject), objNull]] call FUNC(dropObject_carry)} + {[_this select 0, (_this select 0) getVariable [QGVAR(carriedObject), objNull], true] call FUNC(dropObject_carry)} ] call EFUNC(common,addActionEventHandler)]; -// add anim changed EH -[_unit, "AnimChanged", FUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; +// Add anim changed EH +[_unit, "AnimChanged", LINKFUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; -// show mouse hint -if (_target isKindOf "CAManBase") then { - [localize LSTRING(Drop), "", ""] call EFUNC(interaction,showMouseHint); -} else { - [localize LSTRING(Drop), "", localize LSTRING(LowerRaise)] call EFUNC(interaction,showMouseHint); -}; - -// check everything -[FUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; - -// reset current dragging height. -GVAR(currentHeightChange) = 0; - -// prevent UAVs from firing +// Prevent UAVs from firing private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); -if !(_UAVCrew isEqualTo []) then { - {_target deleteVehicleCrew _x} count _UAVCrew; +if (_UAVCrew isNotEqualTo []) then { + { + _target deleteVehicleCrew _x; + } forEach _UAVCrew; + _target setVariable [QGVAR(isUAV), true, true]; }; + +// Check everything +[LINKFUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dragging/functions/fnc_carryObjectPFH.sqf b/addons/dragging/functions/fnc_carryObjectPFH.sqf index 6204bbae62..fcd0f05376 100644 --- a/addons/dragging/functions/fnc_carryObjectPFH.sqf +++ b/addons/dragging/functions/fnc_carryObjectPFH.sqf @@ -1,20 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * PFH for Carry Object + * PFH for carrying an object. * * Arguments: - * 0: ARGS - * 0: Unit - * 1: Target - * 2: Start time + * 0: Arguments + * - 0: Unit + * - 1: Target + * - 2: Start time * 1: PFEH Id * * Return Value: * None * * Example: - * [[player, target], 20] call ace_dragging_fnc_carryObjectPFH; + * [[player, cursorTarget, CBA_missionTime], _idPFH] call ace_dragging_fnc_carryObjectPFH; * * Public: No */ @@ -28,17 +28,96 @@ _args params ["_unit", "_target", "_startTime"]; if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith { TRACE_2("carry false",_unit,_target); - [_idPFH] call CBA_fnc_removePerFrameHandler; + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; }; -// drop if the crate is destroyed OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_2("dead/distance",_unit,_target); - if ((_unit distance _target > 10) && {(CBA_missionTime - _startTime) < 1}) exitWith { - //attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, - //so wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) - TRACE_3("ignoring bad distance at start",_unit distance _target,_startTime,CBA_missionTime); - }; +// Drop if the target is destroyed +if (!alive _target) exitWith { + TRACE_2("dead",_unit,_target); + [_unit, _target] call FUNC(dropObject_carry); - [_idPFH] call CBA_fnc_removePerFrameHandler; + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop if the target moved away from carrier (e.g. weapon disassembled) +// attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, +// So wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) +if (_unit distance _target > 10 && {(CBA_missionTime - _startTime) >= 1}) exitWith { + TRACE_2("distance",_unit,_target); + + [_unit, _target] call FUNC(dropObject_carry); + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop if the carrier starts limping +if (_unit getHitPointDamage "HitLegs" >= 0.5) exitWith { + TRACE_2("limping",_unit,_target); + + [_unit, _target] call FUNC(dropObject_carry); + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop static if crew is in it (UAV crew deletion may take a few frames) +if (_target isKindOf "StaticWeapon" && {!(_target getVariable [QGVAR(isUAV), false])} && {(crew _target) isNotEqualTo []}) exitWith { + TRACE_2("static weapon crewed",_unit,_target); + + [_unit, _target] call FUNC(dropObject_carry); + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +private _previousHint = _unit getVariable [QGVAR(hint), []]; + +// If paused, don't show mouse button hints +if (_previousHint isEqualType "") exitWith {}; + +// Mouse hint +private _hintLMB = LLSTRING(Drop); +private _cursorObject = cursorObject; + +if ( + !isNull _cursorObject && {[_unit, _cursorObject, ["isNotCarrying"]] call EFUNC(common,canInteractWith)} && + { + if (_target isKindOf "CAManBase") then { + (_unit distance _cursorObject <= MAX_LOAD_DISTANCE_MAN) && {[_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat) isNotEqualTo []} + } else { + ["ace_cargo"] call EFUNC(common,isModLoaded) && + {EGVAR(cargo,enable)} && + {[_target, _cursorObject] call EFUNC(cargo,canLoadItemIn)} + } + } +) then { + _hintLMB = LELSTRING(common,loadObject); +}; + +private _hintMMB = LLSTRING(RaiseLowerRotate); + +if (_target isKindOf "CAManBase") then { + _hintMMB = ""; +}; + +private _hint = [_hintLMB, "", _hintMMB]; + +if (_hint isNotEqualTo _previousHint) then { + _unit setVariable [QGVAR(hint), _hint]; + _hint call EFUNC(interaction,showMouseHint); }; diff --git a/addons/dragging/functions/fnc_dragObject.sqf b/addons/dragging/functions/fnc_dragObject.sqf index 347eb857db..5116f440b3 100644 --- a/addons/dragging/functions/fnc_dragObject.sqf +++ b/addons/dragging/functions/fnc_dragObject.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Drag an object. Called from ace_dragging_fnc_startDrag + * Author: commy2, Malbryn + * Handles attaching and setting up a dragged object. Called from ace_dragging_fnc_startDragPFH. * * Arguments: * 0: Unit that should do the dragging @@ -19,52 +19,68 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); -// get attachTo offset and direction. +// Get attachTo offset and direction. private _position = _target getVariable [QGVAR(dragPosition), [0, 0, 0]]; private _direction = _target getVariable [QGVAR(dragDirection), 0]; -// add height offset of model -private _offset = (_target modelToWorldVisual [0, 0, 0] select 2) - (_unit modelToWorldVisual [0, 0, 0] select 2); +// Add height offset of model +private _offset = ((_target modelToWorldVisual [0, 0, 0]) select 2) - ((_unit modelToWorldVisual [0, 0, 0]) select 2); + if (_target isKindOf "CAManBase") then { _offset = 0; }; + _position = _position vectorAdd [0, 0, _offset]; -// attach object +// Attach object TRACE_3("attaching",_position,_offset,_direction); + _target attachTo [_unit, _position]; + [QEGVAR(common,setDir), [_target, _direction], _target] call CBA_fnc_targetEvent; if (_target isKindOf "CAManBase") then { - [_target, "AinjPpneMrunSnonWnonDb_still", 0, true] call EFUNC(common,doAnimation); + [_target, "AinjPpneMrunSnonWnonDb_still", 0] call EFUNC(common,doAnimation); }; _unit setVariable [QGVAR(isDragging), true, true]; _unit setVariable [QGVAR(draggedObject), _target, true]; -// add drop action -_unit setVariable [QGVAR(ReleaseActionID), [ - _unit, "DefaultAction", - {!isNull ((_this select 0) getVariable [QGVAR(draggedObject), objNull])}, - {[_this select 0, (_this select 0) getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject)} -] call EFUNC(common,addActionEventHandler)]; +// Add drop action +GVAR(unit) = _unit; -// add anim changed EH -[_unit, "AnimChanged", FUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; +GVAR(releaseActionID) = [0xF1, [false, false, false], { + [GVAR(unit), GVAR(unit) getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); +}, "keydown", "", false, 0] call CBA_fnc_addKeyHandler; -// show mouse hint -[localize LSTRING(Drop), ""] call EFUNC(interaction,showMouseHint); +// Show mouse hint +["", LLSTRING(Drop)] call EFUNC(interaction,showMouseHint); -// check everything -[FUNC(dragObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; +// Block firing +if (!GVAR(dragAndFire)) then { + _unit setVariable [QGVAR(blockFire), [ + _unit, "DefaultAction", + {true}, + {} + ] call EFUNC(common,addActionEventHandler)]; +}; -// reset current dragging height. -GVAR(currentHeightChange) = 0; +// Add anim changed EH +[_unit, "AnimChanged", LINKFUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; -// prevent UAVs from firing +// Prevent UAVs from firing private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); -if !(_UAVCrew isEqualTo []) then { - {_target deleteVehicleCrew _x} count _UAVCrew; +if (_UAVCrew isNotEqualTo []) then { + { + _target deleteVehicleCrew _x; + } forEach _UAVCrew; + _target setVariable [QGVAR(isUAV), true, true]; }; + +// Check everything +[LINKFUNC(dragObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; + +// Fixes not being able to move when in combat pace +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index a45a26ae89..7c3a6be307 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -1,20 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * PFH for Drag Object + * PFH for dragging an object. * * Arguments: - * 0: ARGS - * 0: Unit - * 1: Target - * 2: Start time + * 0: Arguments + * - 0: Unit + * - 1: Target + * - 2: Start time * 1: PFEH Id * * Return Value: * None * * Example: - * [[player, target], 20] call ace_dragging_fnc_dragObjectPFH; + * [[player, cursorTarget, CBA_missionTime], _idPFH] call ace_dragging_fnc_dragObjectPFH; * * Public: No */ @@ -28,17 +28,37 @@ _args params ["_unit", "_target", "_startTime"]; if !(_unit getVariable [QGVAR(isDragging), false]) exitWith { TRACE_2("drag false",_unit,_target); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; -// drop if the crate is destroyed OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_2("dead/distance",_unit,_target); - if ((_unit distance _target > 10) && {(CBA_missionTime - _startTime) < 1}) exitWith { - //attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, - //so wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) - TRACE_3("ignoring bad distance at start",_unit distance _target,_startTime,CBA_missionTime); - }; +// Drop if the target is destroyed +if (!alive _target) exitWith { + TRACE_2("dead",_unit,_target); + [_unit, _target] call FUNC(dropObject); - [_idPFH] call CBA_fnc_removePerFrameHandler; + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop if the target moved away from carrier (e.g. weapon disassembled) +// attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, +// So wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) +if (_unit distance _target > 10 && {(CBA_missionTime - _startTime) >= 1}) exitWith { + TRACE_2("distance",_unit,_target); + + [_unit, _target] call FUNC(dropObject); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop static if crew is in it (UAV crew deletion may take a few frames) +if (_target isKindOf "StaticWeapon" && {!(_target getVariable [QGVAR(isUAV), false])} && {(crew _target) isNotEqualTo []}) exitWith { + TRACE_2("static weapon crewed",_unit,_target); + + [_unit, _target] call FUNC(dropObject); + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index 84bbd90342..10cfda1703 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Drop a dragged object. + * Author: commy2, Malbryn + * Drops a dragged object. * * Arguments: * 0: Unit that drags the other object @@ -19,48 +19,56 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); -// remove drop action -[_unit, "DefaultAction", _unit getVariable [QGVAR(ReleaseActionID), -1]] call EFUNC(common,removeActionEventHandler); +// Remove drop action +if (!isNil QGVAR(releaseActionID)) then { + [GVAR(releaseActionID), "keydown"] call CBA_fnc_removeKeyHandler; + GVAR(releaseActionID) = nil; +}; -private _inBuilding = [_unit] call FUNC(isObjectOnObject); +// Stop blocking +if (!GVAR(dragAndFire)) then { + [_unit, "DefaultAction", _unit getVariable [QGVAR(blockFire), -1]] call EFUNC(common,removeActionEventHandler); +}; +private _inBuilding = _unit call FUNC(isObjectOnObject); + +// Play release animation if !(_unit getVariable ["ACE_isUnconscious", false]) then { - // play release animation [_unit, "released"] call EFUNC(common,doGesture); }; -// prevent collision damage +// Prevent collision damage [QEGVAR(common,fixCollision), _unit] call CBA_fnc_localEvent; [QEGVAR(common,fixCollision), _target, _target] call CBA_fnc_targetEvent; -// release object +// Release object detach _target; if (_target isKindOf "CAManBase") then { if (_target getVariable ["ACE_isUnconscious", false]) then { - [_target, "unconscious", 2, true] call EFUNC(common,doAnimation); + [_target, "unconscious", 2] call EFUNC(common,doAnimation); } else { - [_target, "", 2, true] call EFUNC(common,doAnimation); //@todo "AinjPpneMrunSnonWnonDb_release" seems to fall back to unconsciousness anim. + [_target, "", 2] call EFUNC(common,doAnimation); //@todo "AinjPpneMrunSnonWnonDb_release" seems to fall back to unconsciousness anim. }; }; _unit removeWeapon "ACE_FakePrimaryWeapon"; -[_unit, "blockThrow", "ACE_dragging", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); -// prevent object from flipping inside buildings +// Prevent object from flipping inside buildings if (_inBuilding) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); TRACE_2("setPos",getPosASL _unit,getPosASL _target); }; -// hide mouse hint -[] call EFUNC(interaction,hideMouseHint); +// Hide mouse hint +call EFUNC(interaction,hideMouseHint); _unit setVariable [QGVAR(isDragging), false, true]; _unit setVariable [QGVAR(draggedObject), objNull, true]; -// make object accessible for other units +// Make object accessible for other units [objNull, _target, true] call EFUNC(common,claim); if !(_target isKindOf "CAManBase") then { @@ -69,17 +77,27 @@ if !(_target isKindOf "CAManBase") then { }; if (_unit getVariable ["ACE_isUnconscious", false]) then { - [_unit, "unconscious", 2, true] call EFUNC(common,doAnimation); + [_unit, "unconscious", 2] call EFUNC(common,doAnimation); }; -// recreate UAV crew +// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) if (_target getVariable [QGVAR(isUAV), false]) then { - createVehicleCrew _target; + _target setVariable [QGVAR(isUAV), nil, true]; + + [{ + params ["_target"]; + if (!alive _target) exitWith {}; + TRACE_2("restoring uav crew",_target,getPosASL _target); + createVehicleCrew _target; + }, [_target]] call CBA_fnc_execNextFrame; }; -// reset mass +// Fixes not being able to move when in combat pace +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + +// Reset mass private _mass = _target getVariable [QGVAR(originalMass), 0]; if (_mass != 0) then { - [QEGVAR(common,setMass), [_target, _mass], _target] call CBA_fnc_targetEvent; + [QEGVAR(common,setMass), [_target, _mass]] call CBA_fnc_globalEvent; // Force global sync }; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index b6507898ca..7a81d94a05 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -1,11 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Drop a carried object. + * Drops a carried object. * * Arguments: * 0: Unit that carries the other object * 1: Carried object to drop + * 2: Try loading object into vehicle (default: false) * * Return Value: * None @@ -16,55 +17,68 @@ * Public: No */ -params ["_unit", "_target"]; +params ["_unit", "_target", ["_tryLoad", false]]; TRACE_1("params",_this); -// remove drop action -[_unit, "DefaultAction", _unit getVariable [QGVAR(ReleaseActionID), -1]] call EFUNC(common,removeActionEventHandler); +// Remove drop action +[_unit, "DefaultAction", _unit getVariable [QGVAR(releaseActionID), -1]] call EFUNC(common,removeActionEventHandler); +_unit setVariable [QGVAR(releaseActionID), nil]; -private _inBuilding = [_unit] call FUNC(isObjectOnObject); +private _inBuilding = _unit call FUNC(isObjectOnObject); -// prevent collision damage +// Prevent collision damage [QEGVAR(common,fixCollision), _unit] call CBA_fnc_localEvent; [QEGVAR(common,fixCollision), _target, _target] call CBA_fnc_targetEvent; -// release object -detach _target; +private _cursorObject = cursorObject; +_tryLoad = _tryLoad && {!isNull _cursorObject} && {[_unit, _cursorObject, ["isNotCarrying"]] call EFUNC(common,canInteractWith)}; +private _loadCargo = false; -// fix anim when aborting carrying persons +// Don't release object if loading into vehicle (object might be released into vehicle) +if (_tryLoad && {!(_target isKindOf "CAManBase")} && {["ace_cargo"] call EFUNC(common,isModLoaded)} && {[_target, _cursorObject] call EFUNC(cargo,canLoadItemIn)}) then { + _loadCargo = true; +} else { + // Release object + detach _target; +}; + +// Fix anim when aborting carrying persons if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS}) then { - if (vehicle _unit == _unit && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { - [_unit, "", 2, true] call EFUNC(common,doAnimation); + if (isNull objectParent _unit && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + [_unit, "", 2] call EFUNC(common,doAnimation); }; if (_target getVariable ["ACE_isUnconscious", false]) then { - [_target, "unconscious", 2, true] call EFUNC(common,doAnimation); + [_target, "unconscious", 2] call EFUNC(common,doAnimation); } else { - [_target, "", 2, true] call EFUNC(common,doAnimation); //@todo + [_target, "", 2] call EFUNC(common,doAnimation); //@todo }; }; -// properly remove fake weapon +// Properly remove fake weapon _unit removeWeapon "ACE_FakePrimaryWeapon"; -// reselect weapon and re-enable sprint -_unit selectWeapon primaryWeapon _unit; +// Reselect weapon and re-enable sprint +private _previousWeaponIndex = _unit getVariable [QGVAR(previousWeapon), -1]; +_unit setVariable [QGVAR(previousWeapon), nil, true]; -[_unit, "forceWalk", "ACE_dragging", false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", "ACE_dragging", false] call EFUNC(common,statusEffect_set); +if (_previousWeaponIndex != -1) then { + _unit action ["SwitchWeapon", _unit, _unit, _previousWeaponIndex]; +}; -// prevent object from flipping inside buildings +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + +// Prevent object from flipping inside buildings if (_inBuilding) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); }; -// hide mouse hint -[] call EFUNC(interaction,hideMouseHint); - _unit setVariable [QGVAR(isCarrying), false, true]; _unit setVariable [QGVAR(carriedObject), objNull, true]; -// make object accesable for other units +// Make object accessible for other units [objNull, _target, true] call EFUNC(common,claim); if !(_target isKindOf "CAManBase") then { @@ -72,14 +86,41 @@ if !(_target isKindOf "CAManBase") then { [QEGVAR(common,fixFloating), _target, _target] call CBA_fnc_targetEvent; }; -// recreate UAV crew +// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) if (_target getVariable [QGVAR(isUAV), false]) then { - createVehicleCrew _target; + _target setVariable [QGVAR(isUAV), nil, true]; + + [{ + params ["_target"]; + if (!alive _target) exitWith {}; + TRACE_2("restoring uav crew",_target,getPosASL _target); + createVehicleCrew _target; + }, [_target]] call CBA_fnc_execNextFrame; }; -// reset mass +// Reset mass private _mass = _target getVariable [QGVAR(originalMass), 0]; if (_mass != 0) then { - [QEGVAR(common,setMass), [_target, _mass], _target] call CBA_fnc_targetEvent; + [QEGVAR(common,setMass), [_target, _mass]] call CBA_fnc_globalEvent; // Force global sync +}; + +// Reset temp direction +_target setVariable [QGVAR(carryDirection_temp), nil]; + +// (Try) loading into vehicle +if (_loadCargo) then { + [_unit, _target, _cursorObject] call EFUNC(cargo,startLoadIn); +} else { + if (_tryLoad && {_unit distance _cursorObject <= MAX_LOAD_DISTANCE_MAN} && {_target isKindOf "CAManBase"}) then { + private _vehicles = [_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat); + + if ([_cursorObject] isEqualTo _vehicles) then { + if (GETEGVAR(medical,enabled,false)) then { + [_unit, _target, _cursorObject] call EFUNC(medical_treatment,loadUnit); + } else { + [_unit, _target, _cursorObject] call EFUNC(common,loadPerson); + }; + }; + }; }; diff --git a/addons/dragging/functions/fnc_getWeight.sqf b/addons/dragging/functions/fnc_getWeight.sqf index cd06b8a884..f6b93feca0 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -1,45 +1,42 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: L-H, edited by commy2, rewritten by joko // Jonas - * Returns the weight of a crate. + * Author: L-H, edited by commy2, rewritten by joko // Jonas, re-rewritten by mharis001 + * Returns the weight of the given object. + * Weight is calculated from the object's mass, its current inventory, and PhysX mass if applicable. * * Arguments: - * 0: Crate to get weight of + * 0: Object * * Return Value: - * Total Weight + * Weight * * Example: - * [Crate1] call ace_dragging_fnc_getweight; + * [cursorTarget] call ace_dragging_fnc_getWeight * * Public: No -*/ + */ params ["_object"]; -// Initialize the total weight. -private _totalWeight = 0; +// Skip weight checking if it will be 0 +if (GVAR(weightCoefficient) == 0) exitWith {0}; -// Cycle through all item types with their assigned config paths. +private _weight = loadAbs _object; + +if !(GVAR(skipContainerWeight)) then { + // Add the mass of the object itself + // getMass handles PhysX mass, this should be 0 for SupplyX containers and WeaponHolders + // Use originalMass in case we're checking weight for a carried object + _weight = _weight + ((_object getVariable [QGVAR(originalMass), getMass _object])); +}; + +// Contents of backpacks get counted twice (https://github.com/acemod/ACE3/pull/8457#issuecomment-1062522447 and https://feedback.bistudio.com/T167469) +// This is a workaround until that is fixed on BI's end { - _x params ["_items", "_getConfigCode"]; - _items params ["_item", "_count"]; - // Cycle through all items and read their mass out of the config. - { - // Multiply mass with amount of items and add the mass to the total weight. - _totalWeight = _totalWeight + (getNumber ((call _getConfigCode) >> "mass") * (_count select _forEachIndex)); - } forEach _item; - true -} count [ - //IGNORE_PRIVATE_WARNING ["_x"]; - [getMagazineCargo _object, {configFile >> "CfgMagazines" >> _x}], - [getBackpackCargo _object, {configFile >> "CfgVehicles" >> _x}], - [getItemCargo _object, {configFile >> "CfgWeapons" >> _x >> "ItemInfo"}], - [getWeaponCargo _object, {configFile >> "CfgWeapons" >> _x >> "WeaponSlotsInfo"}] -]; + _x params ["", "_container"]; + _weight = _weight - (loadAbs _container); +} forEach (everyContainer _object); -// add Weight of create to totalWeight -_totalWeight = _totalWeight + (getNumber (configFile >> "CfgVehicles" >> typeOf _object >> "mass")); - -// Mass in Arma isn't an exact amount but rather a volume/weight value. This attempts to work around that by making it a usable value. (sort of). -_totalWeight * 0.5 +// Mass in Arma isn't an exact amount but rather a volume/weight value +// This attempts to work around that by making it a usable value (sort of) +GVAR(weightCoefficient) * _weight * 0.5 // return diff --git a/addons/dragging/functions/fnc_handleAnimChanged.sqf b/addons/dragging/functions/fnc_handleAnimChanged.sqf index 7fa242ae16..24b8f58205 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -1,23 +1,21 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Handle the animaion for a Unit for Dragging Module + * Handle the animation for a unit for the dragging module. * * Arguments: * 0: Unit - * 1: animaion + * 1: Animaion * * Return Value: * None * * Example: - * [_unit, "amovpercmstpsnonwnondnon"] call ace_dragging_fnc_handleAnimChanged; + * [player, "amovpercmstpsnonwnondnon"] call ace_dragging_fnc_handleAnimChanged; * * Public: No */ -//IGNORE_PRIVATE_WARNING ["_thisArgs", "_thisID"]; // From CBA_fnc_addBISEventHandler; - params ["_unit", "_anim"]; _thisArgs params ["_realUnit"]; TRACE_4("params",_unit,_anim,_realUnit,_thisID); @@ -28,8 +26,7 @@ if (_unit != _realUnit) exitWith { }; if (_unit getVariable [QGVAR(isDragging), false]) then { - - // drop dragged object when not in valid animation + // Drop dragged object when not in valid animation if (!(_anim in DRAG_ANIMATIONS) && {!(_unit call EFUNC(common,isSwimming))}) then { private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; @@ -39,10 +36,8 @@ if (_unit getVariable [QGVAR(isDragging), false]) then { }; }; } else { - if (_unit getVariable [QGVAR(isCarrying), false]) then { - - // drop carried object when not standing; also some exceptions when picking up crate + // Drop carried object when not standing; also some exceptions when picking up crate if (stance _unit != "STAND" && {_anim != "amovpercmstpsnonwnondnon"}) then { private _carriedObject = _unit getVariable [QGVAR(carriedObject), objNull]; diff --git a/addons/dragging/functions/fnc_handleKilled.sqf b/addons/dragging/functions/fnc_handleKilled.sqf index 672869d3c9..c38ed7dfbe 100644 --- a/addons/dragging/functions/fnc_handleKilled.sqf +++ b/addons/dragging/functions/fnc_handleKilled.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Handle death of the dragger + * Handle death of the dragger/carrier. * * Arguments: * 0: Unit @@ -10,7 +10,7 @@ * None * * Example: - * [_unit] call ace_dragging_fnc_handleKilled; + * [player] call ace_dragging_fnc_handleKilled; * * Public: No */ diff --git a/addons/dragging/functions/fnc_handlePlayerChanged.sqf b/addons/dragging/functions/fnc_handlePlayerChanged.sqf index a404660106..75370d36fe 100644 --- a/addons/dragging/functions/fnc_handlePlayerChanged.sqf +++ b/addons/dragging/functions/fnc_handlePlayerChanged.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Handle player changes. + * Handles player changes. * * Arguments: * 0: New Player Unit diff --git a/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf b/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf index 7d07583ddf..17b876f8f6 100644 --- a/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf +++ b/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Handle the Weapon Changed Event + * Handles the weapon changed event. * * Arguments: * 0: Unit @@ -11,7 +11,7 @@ * None * * Example: - * [_unit, "gun"] call ace_dragging_fnc_handlePlayerWeaponChanged; + * [player, primaryWeapon player] call ace_dragging_fnc_handlePlayerWeaponChanged; * * Public: No */ @@ -20,32 +20,25 @@ params ["_unit", "_weapon"]; TRACE_2("params",_unit,_weapon); if (_unit getVariable [QGVAR(isDragging), false]) then { - - // drop dragged object when selecting a non-primary weapon - if (_weapon != primaryWeapon _unit) then { + // Drop dragged object when changing weapon + if (_weapon != _unit getVariable [QGVAR(currentWeapon), ""]) then { private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; [_unit, _draggedObject] call FUNC(dropObject); }; - }; if (_unit getVariable [QGVAR(isCarrying), false]) then { - private _carriedObject = _unit getVariable [QGVAR(carriedObject), objNull]; if (_carriedObject isKindOf "CAManBase") then { - if (_weapon != primaryWeapon _unit) then { [_unit, _carriedObject] call FUNC(dropObject_carry); }; - } else { - - // drop carried object when selecting any weapon + // Drop carried object when selecting any weapon if (_weapon != "") then { [_unit, _carriedObject] call FUNC(dropObject_carry); }; - }; }; diff --git a/addons/dragging/functions/fnc_handleScrollWheel.sqf b/addons/dragging/functions/fnc_handleScrollWheel.sqf index 9c444add21..c7641a8ffa 100644 --- a/addons/dragging/functions/fnc_handleScrollWheel.sqf +++ b/addons/dragging/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: L-H, commy2 * Handles raising and lowering the dragged weapon to be able to place it on top of objects. @@ -22,30 +22,41 @@ private _unit = ACE_player; // EH is always assigned. Exit and don't overwrite input if not carrying if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith {false}; -// move carried item 15 cm per scroll interval -_scrollAmount = _scrollAmount * 0.15; - private _carriedItem = _unit getVariable [QGVAR(carriedObject), objNull]; -//disabled for persons +// Disabled for persons if (_carriedItem isKindOf "CAManBase") exitWith {false}; -private _position = getPosASL _carriedItem; -private _maxHeight = (_unit modelToWorldVisualWorld [0, 0, 0]) select 2; +if (!CBA_events_control) then { + // Raise/lower + // Move carried item 15 cm per scroll interval + _scrollAmount = _scrollAmount * 0.15; -_position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) max _maxHeight]; + private _position = getPosASL _carriedItem; + private _maxHeight = (_unit modelToWorldVisualWorld [0, 0, 0]) select 2; -// move up/down object and reattach at current position -detach _carriedItem; + _position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) max _maxHeight]; -// Uses this method of selecting position because setPosATL did not have immediate effect -private _positionChange = _position vectorDiff (getPosASL _carriedItem); -private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _carriedItem); -_selectionPosition = _selectionPosition vectorAdd _positionChange; -_carriedItem attachTo [_unit, _selectionPosition]; + // Move up/down object and reattach at current position + detach _carriedItem; -//reset the carry direction -private _direction = _carriedItem getVariable [QGVAR(carryDirection), 0]; -[QEGVAR(common,setDir), [_carriedItem, _direction], _carriedItem] call CBA_fnc_targetEvent; + // Uses this method of selecting position because setPosATL did not have immediate effect + private _positionChange = _position vectorDiff (getPosASL _carriedItem); + private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _carriedItem); + _selectionPosition = _selectionPosition vectorAdd _positionChange; + _carriedItem attachTo [_unit, _selectionPosition]; + + // Reset the carry direction + private _direction = _carriedItem getVariable [QGVAR(carryDirection_temp), _carriedItem getVariable [QGVAR(carryDirection), 0]]; + [QEGVAR(common,setDir), [_carriedItem, _direction], _carriedItem] call CBA_fnc_targetEvent; +} else { + // Rotate + private _direction = _carriedItem getVariable [QGVAR(carryDirection_temp), _carriedItem getVariable [QGVAR(carryDirection), 0]]; + _scrollAmount = _scrollAmount * 10; + _direction = _direction + _scrollAmount; + + [QEGVAR(common,setDir), [_carriedItem, _direction], _carriedItem] call CBA_fnc_targetEvent; + _carriedItem setVariable [QGVAR(carryDirection_temp), _direction]; +}; true diff --git a/addons/dragging/functions/fnc_handleUnconscious.sqf b/addons/dragging/functions/fnc_handleUnconscious.sqf index fd3f95f95d..f79f7327ff 100644 --- a/addons/dragging/functions/fnc_handleUnconscious.sqf +++ b/addons/dragging/functions/fnc_handleUnconscious.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Handle the Unconscious of a Unit while Dragging + * Handles consciousness change of a unit while dragging / carrying. * * Arguments: * 0: Unit @@ -10,7 +10,7 @@ * None * * Example: - * [_unit] call ace_dragging_fnc_handleUnconscious; + * [player] call ace_dragging_fnc_handleUnconscious; * * Public: No */ @@ -20,30 +20,28 @@ params ["_unit"]; private _player = ACE_player; if (_player getVariable [QGVAR(isDragging), false]) then { - private _draggedObject = _player getVariable [QGVAR(draggedObject), objNull]; - // handle falling unconscious + // Handle falling unconscious if (_unit == _player) then { [_unit, _draggedObject] call FUNC(dropObject); }; - // handle waking up dragged unit + // Handle waking up dragged unit if (_unit == _draggedObject) then { [_player, _draggedObject] call FUNC(dropObject); }; }; if (_player getVariable [QGVAR(isCarrying), false]) then { - private _carriedObject = _player getVariable [QGVAR(carriedObject), objNull]; - // handle falling unconscious + // Handle falling unconscious if (_unit == _player) then { [_unit, _carriedObject] call FUNC(dropObject_carry); }; - // handle waking up dragged unit + // Handle waking up dragged unit if (_unit == _carriedObject) then { [_player, _carriedObject] call FUNC(dropObject_carry); }; diff --git a/addons/dragging/functions/fnc_initObject.sqf b/addons/dragging/functions/fnc_initObject.sqf index 8e352a00bb..a21a602634 100644 --- a/addons/dragging/functions/fnc_initObject.sqf +++ b/addons/dragging/functions/fnc_initObject.sqf @@ -1,34 +1,36 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Initialize variables for drag or carryable objects. Called from init EH. + * Initializes variables for draggable / carryable objects. Called from init EH. * * Arguments: - * 0: Any object + * 0: Object * * Return Value: * None * * Example: - * [box] call ace_dragging_fnc_initObject; + * [cursorTarget] call ace_dragging_fnc_initObject; * * Public: No */ params ["_object"]; -private _config = configFile >> "CfgVehicles" >> typeOf _object; +private _config = configOf _object; if (getNumber (_config >> QGVAR(canDrag)) == 1) then { - private _position = getArray (_config >> QGVAR(dragPosition)); + private _position = [_config >> QGVAR(dragPosition), "ARRAY", [0, 1.5, 0]] call CBA_fnc_getConfigEntry; private _direction = getNumber (_config >> QGVAR(dragDirection)); + private _ignoreWeight = getNumber (_config >> QGVAR(ignoreWeight)); - [_object, true, _position, _direction] call FUNC(setDraggable); + [_object, true, _position, _direction, _ignoreWeight > 0] call FUNC(setDraggable); }; if (getNumber (_config >> QGVAR(canCarry)) == 1) then { - private _position = getArray (_config >> QGVAR(carryPosition)); + private _position = [_config >> QGVAR(carryPosition), "ARRAY", [0, 1, 1]] call CBA_fnc_getConfigEntry; private _direction = getNumber (_config >> QGVAR(carryDirection)); + private _ignoreWeight = getNumber (_config >> QGVAR(ignoreWeightCarry)); - [_object, true, _position, _direction] call FUNC(setCarryable); + [_object, true, _position, _direction, _ignoreWeight > 0] call FUNC(setCarryable); }; diff --git a/addons/dragging/functions/fnc_initPerson.sqf b/addons/dragging/functions/fnc_initPerson.sqf index c9365710dd..6ac2b5d569 100644 --- a/addons/dragging/functions/fnc_initPerson.sqf +++ b/addons/dragging/functions/fnc_initPerson.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Initialize variables for drag or carryable persons. Called from init EH. + * Initialize variables for draggable / carryable persons. Called from init EH. * * Arguments: * 0: Unit @@ -16,6 +16,7 @@ */ params ["_unit"]; +if (isNull _unit) exitWith { WARNING_1("%1 became null",_unit) }; -[_unit, true, [0,1.1,0.092], 180] call FUNC(setDraggable); -[_unit, true, [0.4,-0.1,-1.25], 195] call FUNC(setCarryable); // hard-coded selection: "LeftShoulder" +[_unit, true, [0, 1.1, 0.092], 180] call FUNC(setDraggable); +[_unit, true, [0.4, -0.1, -1.25], 195] call FUNC(setCarryable); // Hard-coded selection: "LeftShoulder" diff --git a/addons/dragging/functions/fnc_isObjectOnObject.sqf b/addons/dragging/functions/fnc_isObjectOnObject.sqf index 00c2823e4a..16f169b8fe 100644 --- a/addons/dragging/functions/fnc_isObjectOnObject.sqf +++ b/addons/dragging/functions/fnc_isObjectOnObject.sqf @@ -1,15 +1,15 @@ /* * Author: commy2 - * Check if Object is Overlapping + * Checks if an object is overlapping another object. * * Arguments: * 0: Object * * Return Value: - * Boolean + * If object is overlapping another * * Example: - * [player] call ace_dragging_fnc_isObjectOnObject + * [player] call ace_dragging_fnc_isObjectOnObject; * * Public: No */ diff --git a/addons/dragging/functions/fnc_pauseCarry.sqf b/addons/dragging/functions/fnc_pauseCarry.sqf new file mode 100644 index 0000000000..49c91e166f --- /dev/null +++ b/addons/dragging/functions/fnc_pauseCarry.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Removes user input affecting carrying. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_dragging_fnc_pauseCarry; + * + * Public: No + */ + +params ["_unit"]; + +// If not carrying, don't do anything +if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith {}; + +private _actionID = _unit getVariable QGVAR(releaseActionID); + +// If action has already been removed, don't remove it again +if (isNil "_actionID") exitWith {}; + +// Remove drop action +[_unit, "DefaultAction", _actionID] call EFUNC(common,removeActionEventHandler); +_unit setVariable [QGVAR(releaseActionID), nil]; + +// Hide mouse hint +_unit setVariable [QGVAR(hint), "paused"]; +call EFUNC(interaction,hideMouseHint); diff --git a/addons/dragging/functions/fnc_pauseDrag.sqf b/addons/dragging/functions/fnc_pauseDrag.sqf new file mode 100644 index 0000000000..a06153bf44 --- /dev/null +++ b/addons/dragging/functions/fnc_pauseDrag.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Removes user input affecting dragging. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_dragging_fnc_pauseDrag; + * + * Public: No + */ + +params ["_unit"]; + +// If not dragging, don't do anything +if !(_unit getVariable [QGVAR(isDragging), false]) exitWith {}; + +// If action has already been removed, don't remove it again +if (isNil QGVAR(releaseActionID)) exitWith {}; + +// Remove drop action +[GVAR(releaseActionID), "keydown"] call CBA_fnc_removeKeyHandler; +GVAR(releaseActionID) = nil; + +// Hide mouse hint +call EFUNC(interaction,hideMouseHint); diff --git a/addons/dragging/functions/fnc_resumeCarry.sqf b/addons/dragging/functions/fnc_resumeCarry.sqf new file mode 100644 index 0000000000..e7cdeb5dc6 --- /dev/null +++ b/addons/dragging/functions/fnc_resumeCarry.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Adds user input affecting carrying back. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_dragging_fnc_resumeCarry; + * + * Public: No + */ + +params ["_unit"]; + +// If not carrying, don't do anything +if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith {}; + +// If action is already present, don't add it again +if (!isNil {_unit getVariable QGVAR(releaseActionID)}) exitWith {}; + +// Remove drop action +_unit setVariable [QGVAR(releaseActionID), [ + _unit, "DefaultAction", + {!isNull ((_this select 0) getVariable [QGVAR(carriedObject), objNull])}, + {[_this select 0, (_this select 0) getVariable [QGVAR(carriedObject), objNull], true] call FUNC(dropObject_carry)} +] call EFUNC(common,addActionEventHandler)]; + +// Show mouse hint (done in FUNC(carryObjectPFH)) +_unit setVariable [QGVAR(hint), nil]; diff --git a/addons/dragging/functions/fnc_resumeDrag.sqf b/addons/dragging/functions/fnc_resumeDrag.sqf new file mode 100644 index 0000000000..d0fea988fb --- /dev/null +++ b/addons/dragging/functions/fnc_resumeDrag.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Adds user input affecting dragging back. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_dragging_fnc_resumeDrag; + * + * Public: No + */ + +params ["_unit"]; + +// If not dragging, don't do anything +if !(_unit getVariable [QGVAR(isDragging), false]) exitWith {}; + +// If action is already present, don't add it again +if (!isNil QGVAR(releaseActionID)) exitWith {}; + +// Add drop action +GVAR(releaseActionID) = [0xF1, [false, false, false], { + [GVAR(unit), GVAR(unit) getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); +}, "keydown", "", false, 0] call CBA_fnc_addKeyHandler; + +// Show mouse hint +["", LLSTRING(Drop)] call EFUNC(interaction,showMouseHint); diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf index 6ec0abb466..60b9854f41 100644 --- a/addons/dragging/functions/fnc_setCarryable.sqf +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -1,55 +1,80 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, PiZZADOX - * Enable the object to be carried. + * Enables the object to be carried. * * Arguments: - * 0: Any object - * 1: true to enable carrying, false to disable - * 2: Position offset for attachTo command (default: [0,1,1]) - * 3: Direction in degree to rotate the object after attachTo (default: 0) - * 4: Override weight limit (optional; default: false) + * 0: Object + * 1: True to enable carrying, false to disable + * 2: Position offset for attachTo command (default: [0, 1, 1]) + * 3: Direction in degrees to rotate the object after attachTo (default: 0) + * 4: Override weight limit (default: false) * * Return Value: * None * * Example: - * [object, true, [0,1,1], 0, false] call ace_dragging_fnc_setCarryable; + * [cursorTarget, true, [0, 1, 1], 0, false] call ace_dragging_fnc_setCarryable; * * Public: Yes */ -//IGNORE_PRIVATE_WARNING ["_player", "_target"]; params ["_object", "_enableCarry", "_position", "_direction", ["_ignoreWeightCarry", false, [false]]]; if (isNil "_position") then { - _position = _object getVariable [QGVAR(carryPosition), [0,1,1]]; + _position = _object getVariable [QGVAR(carryPosition), [0, 1, 1]]; }; if (isNil "_direction") then { _direction = _object getVariable [QGVAR(carryDirection), 0]; }; -// update variables +// Update variables _object setVariable [QGVAR(canCarry), _enableCarry]; _object setVariable [QGVAR(carryPosition), _position]; _object setVariable [QGVAR(carryDirection), _direction]; _object setVariable [QGVAR(ignoreWeightCarry), _ignoreWeightCarry]; -// add action to class if it is not already present +// Add action to class if it is not already present private _type = typeOf _object; private _initializedClasses = GETGVAR(initializedClasses_carry,[]); -// do nothing if the class is already initialized +// Do nothing if the class is already initialized if (_type in _initializedClasses) exitWith {}; _initializedClasses pushBack _type; GVAR(initializedClasses_carry) = _initializedClasses; -private _icon = [QUOTE(PATHTOF(UI\icons\box_carry.paa)), QUOTE(PATHTOF(UI\icons\person_carry.paa))] select (_object isKindOf "Man"); +[_type, "ContainerClosed", { + params ["_object"]; + private _owner = _object getVariable [QEGVAR(common,owner), objNull]; + TRACE_2("ContainerClosed-carry",_object,_owner); + if (isNull _owner) exitWith {}; + if (_object isNotEqualTo (_owner getVariable [QGVAR(carriedObject), objNull])) exitWith {}; + [QGVAR(carryingContainerClosed), [_object, _owner], _owner] call CBA_fnc_targetEvent; +}, false] call CBA_fnc_addClassEventHandler; -private _carryAction = [QGVAR(carry), localize LSTRING(Carry), _icon, {[_player, _target] call FUNC(startCarry)}, {[_player, _target] call FUNC(canCarry)}] call EFUNC(interact_menu,createAction); -private _dropAction = [QGVAR(drop_carry), localize LSTRING(Drop), "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}] call EFUNC(interact_menu,createAction); +private _icon = [QPATHTOF(UI\icons\box_carry.paa), QPATHTOF(UI\icons\person_carry.paa)] select (_object isKindOf "CAManBase"); + +private _carryAction = [ + QGVAR(carry), + LLSTRING(Carry), + _icon, + { + [_player, _target] call FUNC(startCarry) + }, { + [_player, _target] call FUNC(canCarry) +}] call EFUNC(interact_menu,createAction); + +private _dropAction = [ + QGVAR(drop_carry), + LLSTRING(Drop), + "", + { + [_player, _target] call FUNC(dropObject_carry) + }, { + [_player, _target] call FUNC(canDrop_carry) +}] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions"], _carryAction] call EFUNC(interact_menu,addActionToClass); [_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_setDraggable.sqf b/addons/dragging/functions/fnc_setDraggable.sqf index 50a07b515b..e024ec5be2 100644 --- a/addons/dragging/functions/fnc_setDraggable.sqf +++ b/addons/dragging/functions/fnc_setDraggable.sqf @@ -1,55 +1,80 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, PiZZADOX - * Enable the object to be dragged. + * Enables the object to be dragged. * * Arguments: - * 0: Any object - * 1: true to enable dragging, false to disable - * 2: Position offset for attachTo command (optional; default: [0,0,0]) - * 3: Direction in degree to rotate the object after attachTo (optional; default: 0) - * 4: Override weight limit (optional; default: false) + * 0: Object + * 1: True to enable dragging, false to disable + * 2: Position offset for attachTo command (optional; default: [0, 1.5, 0]) + * 3: Direction in degrees to rotate the object after attachTo (optional; default: 0) + * 4: Override weight limit (default: false) * * Return Value: * None * * Example: - * [object, true, [0,0,0], 0, false] call ace_dragging_fnc_setDraggable; + * [cursorTarget, true, [0, 0, 0], 0, false] call ace_dragging_fnc_setDraggable; * * Public: Yes */ -//IGNORE_PRIVATE_WARNING ["_player", "_target"]; params ["_object", "_enableDrag", "_position", "_direction", ["_ignoreWeightDrag", false, [false]]]; if (isNil "_position") then { - _position = _object getVariable [QGVAR(dragPosition), [0,0,0]]; + _position = _object getVariable [QGVAR(dragPosition), [0, 1.5, 0]]; }; if (isNil "_direction") then { _direction = _object getVariable [QGVAR(dragDirection), 0]; }; -// update variables +// Update variables _object setVariable [QGVAR(canDrag), _enableDrag]; _object setVariable [QGVAR(dragPosition), _position]; _object setVariable [QGVAR(dragDirection), _direction]; _object setVariable [QGVAR(ignoreWeightDrag), _ignoreWeightDrag]; -// add action to class if it is not already present +// Add action to class if it is not already present private _type = typeOf _object; private _initializedClasses = GETGVAR(initializedClasses,[]); -// do nothing if the class is already initialized +// Do nothing if the class is already initialized if (_type in _initializedClasses) exitWith {}; _initializedClasses pushBack _type; GVAR(initializedClasses) = _initializedClasses; -private _icon = [QUOTE(PATHTOF(UI\icons\box_drag.paa)), QUOTE(PATHTOF(UI\icons\person_drag.paa))] select (_object isKindOf "Man"); +[_type, "ContainerClosed", { + params ["_object"]; + private _owner = _object getVariable [QEGVAR(common,owner), objNull]; + TRACE_2("ContainerClosed-drag",_object,_owner); + if (isNull _owner) exitWith {}; + if (_object isNotEqualTo (_owner getVariable [QGVAR(draggedObject), objNull])) exitWith {}; + [QGVAR(draggingContainerClosed), [_object, _owner], _owner] call CBA_fnc_targetEvent; +}, false] call CBA_fnc_addClassEventHandler; -private _dragAction = [QGVAR(drag), localize LSTRING(Drag), _icon, {[_player, _target] call FUNC(startDrag)}, {[_player, _target] call FUNC(canDrag)}] call EFUNC(interact_menu,createAction); -private _dropAction = [QGVAR(drop), localize LSTRING(Drop), "", {[_player, _target] call FUNC(dropObject)}, {[_player, _target] call FUNC(canDrop)}] call EFUNC(interact_menu,createAction); +private _icon = [QPATHTOF(UI\icons\box_drag.paa), QPATHTOF(UI\icons\person_drag.paa)] select (_object isKindOf "CAManBase"); + +private _dragAction = [ + QGVAR(drag), + LLSTRING(Drag), + _icon, + { + [_player, _target] call FUNC(startDrag) + }, { + [_player, _target] call FUNC(canDrag) +}] call EFUNC(interact_menu,createAction); + +private _dropAction = [ + QGVAR(drop), + LLSTRING(Drop), + "", + { + [_player, _target] call FUNC(dropObject); + }, { + [_player, _target] call FUNC(canDrop) +}] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions"], _dragAction] call EFUNC(interact_menu,addActionToClass); [_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 729fec2a4e..3e2cc17efd 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, PiZZADOX - * Start the carrying process. + * Author: johnb43 + * Starts the carrying process safely. * * Arguments: * 0: Unit that should do the carrying @@ -11,73 +11,11 @@ * None * * Example: - * [player, cursorTarget] call ace_dragging_fnc_startCarry; + * [player, cursorTarget] call ace_dragging_fnc_startCarry * * Public: No */ - params ["_unit", "_target"]; -TRACE_2("params",_unit,_target); -// exempt from weight check if object has override variable set -if (!GETVAR(_target,GVAR(ignoreWeightCarry),false) && { - private _weight = [_target] call FUNC(getWeight); - _weight > GETMVAR(ACE_maxWeightCarry,1E11) -}) exitWith { - // exit if object weight is over global var value - [localize LSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); -}; - -private _timer = CBA_missionTime + 5; - -// handle objects vs persons -if (_target isKindOf "CAManBase") then { - - // add a primary weapon if the unit has none. - if (primaryWeapon _unit isEqualto "") then { - _unit addWeapon "ACE_FakePrimaryWeapon"; - }; - - // select primary, otherwise the drag animation actions don't work. - _unit selectWeapon primaryWeapon _unit; - - // move a bit closer and adjust direction when trying to pick up a person - _target setDir (getDir _unit + 180); - _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit)); - - [_unit, "AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon", 2, true] call EFUNC(common,doAnimation); - [_target, "AinjPfalMstpSnonWrflDnon_carried_Up", 2, true] call EFUNC(common,doAnimation); - - _timer = CBA_missionTime + 15; - -} else { - - // select no weapon and stop sprinting - _unit action ["SwitchWeapon", _unit, _unit, 299]; - [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); - - [_unit, "forceWalk", "ACE_dragging", true] call EFUNC(common,statusEffect_set); - -}; - -[_unit, "blockThrow", "ACE_dragging", true] call EFUNC(common,statusEffect_set); - -// prevent multiple players from accessing the same object -[_unit, _target, true] call EFUNC(common,claim); - - -// prevents draging and carrying at the same time -_unit setVariable [QGVAR(isCarrying), true, true]; - -// required for aborting animation -_unit setVariable [QGVAR(carriedObject), _target, true]; - -[FUNC(startCarryPFH), 0.2, [_unit, _target, _timer]] call CBA_fnc_addPerFrameHandler; - -// disable collisions by setting the physx mass to almost zero -private _mass = getMass _target; - -if (_mass > 1) then { - _target setVariable [QGVAR(originalMass), _mass, true]; - [QEGVAR(common,setMass), [_target, 1e-12], _target] call CBA_fnc_targetEvent; -}; +// Try to claim the object +[QEGVAR(common,claimSafe), [_unit, _target, true, QGVAR(startCarry)]] call CBA_fnc_serverEvent; diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf new file mode 100644 index 0000000000..6ba2c68934 --- /dev/null +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -0,0 +1,95 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, PiZZADOX + * Starts the carrying process. + * + * Arguments: + * 0: Unit that should do the carrying + * 1: Object to carry + * 2: If object was successfully claimed + * + * Return Value: + * None + * + * Example: + * [player, cursorTarget, true] call ace_dragging_fnc_startCarryLocal + * + * Public: No + */ + +params ["_unit", "_target", "_claimed"]; +TRACE_3("params",_unit,_target,_claimed); + +if (!_claimed) exitWith { WARNING_1("already claimed %1",_this) }; + +// Exempt from weight check if object has override variable set +private _weight = 0; + +if !(_target getVariable [QGVAR(ignoreWeightCarry), false]) then { + _weight = _target call FUNC(getWeight); +}; + +// Exit if object weight is over global var value +if (_weight > GETMVAR(ACE_maxWeightCarry,1E11)) exitWith { + // Release claim on object + [objNull, _target, true] call EFUNC(common,claim); + + [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); +}; + +private _timer = CBA_missionTime + 5; + +// Handle objects vs. persons +if (_target isKindOf "CAManBase") then { + private _primaryWeapon = primaryWeapon _unit; + + // Add a primary weapon if the unit has none + if (_primaryWeapon == "") then { + _unit addWeapon "ACE_FakePrimaryWeapon"; + _primaryWeapon = "ACE_FakePrimaryWeapon"; + }; + + // Select primary, otherwise the carry animation actions don't work + _unit selectWeapon _primaryWeapon; + + // Move a bit closer and adjust direction when trying to pick up a person + [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; + _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit)); + + [_unit, "AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon", 2] call EFUNC(common,doAnimation); + [_target, "AinjPfalMstpSnonWrflDnon_carried_Up", 2] call EFUNC(common,doAnimation); + + _timer = CBA_missionTime + 10; +} else { + // Select no weapon and stop sprinting + private _previousWeaponIndex = [_unit] call EFUNC(common,getFiremodeIndex); + _unit setVariable [QGVAR(previousWeapon), _previousWeaponIndex, true]; + + _unit action ["SwitchWeapon", _unit, _unit, 299]; + + [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); + + private _canRun = _weight call FUNC(canRun_carry); + + // Only force walking if we're overweight + [_unit, "forceWalk", QUOTE(ADDON), !_canRun] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), _canRun] call EFUNC(common,statusEffect_set); +}; + +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// Prevents dragging and carrying at the same time +_unit setVariable [QGVAR(isCarrying), true, true]; + +// Required for aborting animation +_unit setVariable [QGVAR(carriedObject), _target, true]; + +[LINKFUNC(startCarryPFH), 0.2, [_unit, _target, _timer]] call CBA_fnc_addPerFrameHandler; + +// Disable collisions by setting the PhysX mass to almost zero +private _mass = getMass _target; + +if (_mass > 1) then { + _target setVariable [QGVAR(originalMass), _mass, true]; + [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync +}; diff --git a/addons/dragging/functions/fnc_startCarryPFH.sqf b/addons/dragging/functions/fnc_startCarryPFH.sqf index f2c5cfb5d2..f928ef942a 100644 --- a/addons/dragging/functions/fnc_startCarryPFH.sqf +++ b/addons/dragging/functions/fnc_startCarryPFH.sqf @@ -1,20 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Carry PFH + * Checks for carrying conditions. If these are met, the unit will start carrying. Called from ace_dragging_fnc_startCarry. * * Arguments: - * 0: ARGS - * 0: Unit - * 1: Target - * 2: Timeout + * 0: Arguments + * - 0: Unit + * - 1: Target + * - 2: Timeout * 1: PFEH Id * * Return Value: * None * * Example: - * [[player, target, 100], 20] call ace_dragging_fnc_startCarryPFH; + * [[player, cursorTarget, 10], _idPFH] call ace_dragging_fnc_startCarryPFH; * * Public: No */ @@ -26,42 +26,44 @@ params ["_args", "_idPFH"]; _args params ["_unit", "_target", "_timeOut"]; -// handle aborting carry +// Handle aborting carry if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith { TRACE_4("carry false",_unit,_target,_timeOut,CBA_missionTime); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; -// same as dragObjectPFH, checks if object is deleted or dead OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_4("dead/distance",_unit,_target,_timeOut,CBA_missionTime); +// Drop if the target is destroyed, if the target moved away from carrier (e.g. weapon disassembled) or if the carrier starts limping +if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage "HitLegs" < 0.5}) exitWith { + TRACE_4("dead/distance/limping",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dropObject_carry); - [_idPFH] call CBA_fnc_removePerFrameHandler; + + _idPFH call CBA_fnc_removePerFrameHandler; }; -// handle persons vs objects +// Handle persons vs. objects if (_target isKindOf "CAManBase") then { + // Carry person after timeout (animation takes a long time to finish) if (CBA_missionTime > _timeOut) exitWith { TRACE_4("Start carry person",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(carryObject); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; } else { + // Timeout: Drop target. CBA_missionTime, because anim length is linked to ingame time if (CBA_missionTime > _timeOut) exitWith { TRACE_4("timeout",_unit,_target,_timeOut,CBA_missionTime); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; - // drop if in timeout - private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; - [_unit, _draggedObject] call FUNC(dropObject_carry); + private _carriedObject = _unit getVariable [QGVAR(carriedObject), objNull]; + [_unit, _carriedObject] call FUNC(dropObject_carry); }; - // wait for the unit to stand up - if (stance _unit isEqualto "STAND") exitWith { + // Wait for the unit to stand up + if (stance _unit == "STAND") exitWith { TRACE_4("Start carry object",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(carryObject); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; }; diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index 7a4c8908d3..8dd6db6dee 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -1,71 +1,21 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, PiZZADOX - * Start the dragging process. + * Author: johnb43 + * Starts the dragging process safely. * * Arguments: - * 0: Unit that should do the dragging + * 0: Unit that should do the carrying * 1: Object to drag * * Return Value: * None * * Example: - * [player, cursorTarget] call ace_dragging_fnc_startDrag; + * [player, cursorTarget] call ace_dragging_fnc_startDrag * * Public: No */ - params ["_unit", "_target"]; -TRACE_2("params",_unit,_target); -// exempt from weight check if object has override variable set -if (!GETVAR(_target,GVAR(ignoreWeightDrag),false) && { - private _weight = [_target] call FUNC(getWeight); - _weight > GETMVAR(ACE_maxWeightDrag,1E11) -}) exitWith { - // exit if object weight is over global var value - [localize LSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); -}; - -// add a primary weapon if the unit has none. -// @todo prevent opening inventory when equipped with a fake weapon -if (primaryWeapon _unit isEqualto "") then { - _unit addWeapon "ACE_FakePrimaryWeapon"; -}; - -// select primary, otherwise the drag animation actions don't work. -_unit selectWeapon primaryWeapon _unit; - -[_unit, "blockThrow", "ACE_dragging", true] call EFUNC(common,statusEffect_set); - -// prevent multiple players from accessing the same object -[_unit, _target, true] call EFUNC(common,claim); - -// can't play action that depends on weapon if it was added the same frame -if !(_unit call EFUNC(common,isSwimming)) then { - [{ - [_this, "grabDrag"] call EFUNC(common,doGesture); - }, _unit] call CBA_fnc_execNextFrame; -}; - -// move a bit closer and adjust direction when trying to pick up a person -if (_target isKindOf "CAManBase") then { - _target setDir (getDir _unit + 180); - _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit vectorMultiply 1.5)); - - [_target, "AinjPpneMrunSnonWnonDb_grab", 2, true] call EFUNC(common,doAnimation); -}; - -// prevents draging and carrying at the same time -_unit setVariable [QGVAR(isDragging), true, true]; - -[FUNC(startDragPFH), 0.2, [_unit, _target, CBA_missionTime + 5]] call CBA_fnc_addPerFrameHandler; - -// disable collisions by setting the physx mass to almost zero -private _mass = getMass _target; - -if (_mass > 1) then { - _target setVariable [QGVAR(originalMass), _mass, true]; - [QEGVAR(common,setMass), [_target, 1e-12], _target] call CBA_fnc_targetEvent; -}; +// Try to claim the object +[QEGVAR(common,claimSafe), [_unit, _target, true, QGVAR(startDrag)]] call CBA_fnc_serverEvent; diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf new file mode 100644 index 0000000000..22c7cecd24 --- /dev/null +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -0,0 +1,107 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, PiZZADOX, Malbryn + * Starts the dragging process. + * + * Arguments: + * 0: Unit that should do the dragging + * 1: Object to drag + * 2: If object was successfully claimed + * + * Return Value: + * None + * + * Example: + * [player, cursorTarget, true] call ace_dragging_fnc_startDragLocal + * + * Public: No + */ + +params ["_unit", "_target", "_claimed"]; +TRACE_3("params",_unit,_target,_claimed); + +if (!_claimed) exitWith { WARNING_1("already claimed %1",_this) }; + +// Exempt from weight check if object has override variable set +private _weight = 0; + +if !(_target getVariable [QGVAR(ignoreWeightDrag), false]) then { + _weight = _target call FUNC(getWeight); +}; + +// Exit if object weight is over global var value +if (_weight > GETMVAR(ACE_maxWeightDrag,1E11)) exitWith { + // Release claim on object + [objNull, _target, true] call EFUNC(common,claim); + + [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); +}; + +private _primaryWeapon = primaryWeapon _unit; + +// Add a primary weapon if the unit has none +if (!GVAR(dragAndFire)) then { + if (_primaryWeapon == "") then { + _unit addWeapon "ACE_FakePrimaryWeapon"; + _primaryWeapon = "ACE_FakePrimaryWeapon"; + }; + + _unit selectWeapon _primaryWeapon; +} else { // Making sure the unit is holding a primary weapon or handgun + private _handgunWeapon = handgunWeapon _unit; + + if !(currentWeapon _unit in [_primaryWeapon, _handgunWeapon]) then { + if (_primaryWeapon != "") then { + // Use primary if possible + _unit selectWeapon _primaryWeapon; + } else { + if (_handgunWeapon != "") then { + // Use pistol if unit has no primary + _unit selectWeapon _handgunWeapon; + } else { + // Add fake weapon if no weapons besides launcher are available + _unit addWeapon "ACE_FakePrimaryWeapon"; + _unit selectWeapon "ACE_FakePrimaryWeapon"; + }; + }; + }; +}; + +// Save the weapon so we can monitor if it changes +_unit setVariable [QGVAR(currentWeapon), currentWeapon _unit]; + +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// Can't play action that depends on weapon if it was added the same frame +if !(_unit call EFUNC(common,isSwimming)) then { + [{ + private _unitWeapon = _this getVariable [QGVAR(currentWeapon), ""]; + + if (_unitWeapon isKindOf ["Pistol", configFile >> "CfgWeapons"]) then { + [_this, "ACE_dragWithPistol"] call EFUNC(common,doGesture); + } else { + [_this, "ACE_dragWithRifle"] call EFUNC(common,doGesture); + }; + }, _unit] call CBA_fnc_execNextFrame; +}; + +// Move a bit closer and adjust direction when trying to pick up a person +if (_target isKindOf "CAManBase") then { + [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; + _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit vectorMultiply 1.5)); + + [_target, "AinjPpneMrunSnonWnonDb_grab", 2] call EFUNC(common,doAnimation); +}; + +// Prevents dragging and carrying at the same time +_unit setVariable [QGVAR(isDragging), true, true]; + +[LINKFUNC(startDragPFH), 0.2, [_unit, _target, CBA_missionTime + 5]] call CBA_fnc_addPerFrameHandler; + +// Disable collisions by setting the physx mass to almost zero +private _mass = getMass _target; + +if (_mass > 1) then { + _target setVariable [QGVAR(originalMass), _mass, true]; + [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync +}; diff --git a/addons/dragging/functions/fnc_startDragPFH.sqf b/addons/dragging/functions/fnc_startDragPFH.sqf index 614b6a8741..daf887c362 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -1,20 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Drag PFH + * Checks for dragging conditions. If these are met, the unit will start dragging. Called from ace_dragging_fnc_startDrag. * * Arguments: - * 0: ARGS - * 0: Unit - * 1: Target - * 2: Timeout + * 0: Arguments + * - 0: Unit + * - 1: Target + * - 2: Timeout * 1: PFEH Id * * Return Value: * None * * Example: - * [[player, target, 100], 20] call ace_dragging_fnc_startDragPFH; + * [[player, cursorTarget, 10], _idPFH] call ace_dragging_fnc_startDragPFH; * * Public: No */ @@ -26,33 +26,34 @@ params ["_args", "_idPFH"]; _args params ["_unit", "_target", "_timeOut"]; -// handle aborting drag +// Handle aborting drag if !(_unit getVariable [QGVAR(isDragging), false]) exitWith { TRACE_4("drag false",_unit,_target,_timeOut,CBA_missionTime); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; -// same as dragObjectPFH, checks if object is deleted or dead OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { +// Drop if the target is destroyed or if the target moved away from carrier (e.g. weapon disassembled) +if (!alive _target || {_unit distance _target > 10}) exitWith { TRACE_4("dead/distance",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dropObject); - [_idPFH] call CBA_fnc_removePerFrameHandler; + + _idPFH call CBA_fnc_removePerFrameHandler; }; -// timeout. Do nothing. Quit. CBA_missionTime, because anim length is linked to ingame time. +// Timeout: Drop target. CBA_missionTime, because anim length is linked to ingame time if (CBA_missionTime > _timeOut) exitWith { TRACE_4("timeout",_unit,_target,_timeOut,CBA_missionTime); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; - // drop if in timeout + // Drop if in timeout private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; [_unit, _draggedObject] call FUNC(dropObject); }; -// unit is ready to start dragging +// Unit is ready to start dragging if (animationState _unit in DRAG_ANIMATIONS || {_unit call EFUNC(common,isSwimming)}) exitWith { TRACE_4("Start Dragging",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dragObject); - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/dragging/functions/script_component.hpp b/addons/dragging/functions/script_component.hpp deleted file mode 100644 index 9d257a69d3..0000000000 --- a/addons/dragging/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\dragging\script_component.hpp" \ No newline at end of file diff --git a/addons/dragging/initKeybinds.inc.sqf b/addons/dragging/initKeybinds.inc.sqf new file mode 100644 index 0000000000..a8792f3576 --- /dev/null +++ b/addons/dragging/initKeybinds.inc.sqf @@ -0,0 +1,58 @@ +// Add Keybinds +["ACE3 Common", QGVAR(drag), LLSTRING(DragKeybind), { + private _player = ACE_player; + + if (!alive _player) exitWith {false}; + if !([_player, objNull, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + // If we are dragging/carrying something right now then just drop it + if (_player getVariable [QGVAR(isDragging), false]) exitWith { + [_player, _player getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); + + false + }; + + if (_player getVariable [QGVAR(isCarrying), false]) exitWith { + [_player, _player getVariable [QGVAR(carriedObject), objNull]] call FUNC(dropObject_carry); + + false + }; + + private _cursorObject = cursorObject; + + if (isNull _cursorObject || {(_cursorObject distance _player) > 2.6}) exitWith {false}; + if !([_player, _cursorObject] call FUNC(canDrag)) exitWith {false}; + + [_player, _cursorObject] call FUNC(startDrag); + + false +}, {}, [-1, [false, false, false]]] call CBA_fnc_addKeybind; // UNBOUND + +["ACE3 Common", QGVAR(carry), LLSTRING(CarryKeybind), { + private _player = ACE_player; + + if (!alive _player) exitWith {false}; + if !([_player, objNull, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + // If we are dragging/carrying something right now then just drop it + if (_player getVariable [QGVAR(isDragging), false]) exitWith { + [_player, _player getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); + + false + }; + + if (_player getVariable [QGVAR(isCarrying), false]) exitWith { + [_player, _player getVariable [QGVAR(carriedObject), objNull], true] call FUNC(dropObject_carry); + + false + }; + + private _cursorObject = cursorObject; + + if (isNull _cursorObject || {(_cursorObject distance _player) > 2.6}) exitWith {false}; + if !([_player, _cursorObject] call FUNC(canCarry)) exitWith {false}; + + [_player, _cursorObject] call FUNC(startCarry); + + false +}, {}, [-1, [false, false, false]]] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/dragging/initSettings.inc.sqf b/addons/dragging/initSettings.inc.sqf new file mode 100644 index 0000000000..37feef4cbc --- /dev/null +++ b/addons/dragging/initSettings.inc.sqf @@ -0,0 +1,34 @@ +[ + QGVAR(weightCoefficient), + "SLIDER", + [LSTRING(weightCoefficient_DisplayName), LSTRING(weightCoefficient_Description)], + LLSTRING(SettingsName), + [0, 2, 1, 2], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(dragAndFire), + "CHECKBOX", + [LSTRING(DragAndFire_DisplayName), LSTRING(DragAndFire_Description)], + LLSTRING(SettingsName), + true +] call CBA_fnc_addSetting; + +[ + QGVAR(allowRunWithLightweight), + "CHECKBOX", + [LSTRING(allowRunWithLightweight_DisplayName), LSTRING(allowRunWithLightweight_Description)], + LLSTRING(SettingsName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(skipContainerWeight), + "CHECKBOX", + [LSTRING(skipContainerWeight_DisplayName), LSTRING(skipContainerWeight_Description)], + LLSTRING(SettingsName), + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/dragging/script_component.hpp b/addons/dragging/script_component.hpp index 01b466972f..4417d5d941 100644 --- a/addons/dragging/script_component.hpp +++ b/addons/dragging/script_component.hpp @@ -2,7 +2,6 @@ #define COMPONENT_BEAUTIFIED Dragging #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_ENABLED_DRAGGING // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -17,5 +16,9 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define DRAG_ANIMATIONS ["amovpercmstpslowwrfldnon_acinpknlmwlkslowwrfldb_2", "amovpercmstpsraswpstdnon_acinpknlmwlksnonwpstdb_2", "amovpercmstpsnonwnondnon_acinpknlmwlksnonwnondb_2", "acinpknlmstpsraswrfldnon", "acinpknlmstpsnonwpstdnon", "acinpknlmstpsnonwnondnon", "acinpknlmwlksraswrfldb", "acinpknlmwlksnonwnondb"] +#define MAX_LOAD_DISTANCE_MAN 5 + +#define DRAG_ANIMATIONS ["amovpercmstpslowwrfldnon_acinpknlmwlkslowwrfldb_2", "amovpercmstpsraswpstdnon_acinpknlmwlksnonwpstdb_2", "amovpercmstpsnonwnondnon_acinpknlmwlksnonwnondb_2", "acinpknlmstpsraswrfldnon", "acinpknlmstpsnonwpstdnon", "acinpknlmstpsnonwnondnon", "acinpknlmwlksraswrfldb", "acinpknlmwlksnonwnondb", "ace_dragging_rifle_limpb", "ace_dragging", "ace_dragging_limpb", "ace_dragging_static", "ace_dragging_drop"] #define CARRY_ANIMATIONS ["acinpercmstpsnonwnondnon", "acinpknlmstpsnonwnondnon_acinpercmrunsnonwnondnon"] + +#define MAX_DRAGGED_ITEMS 3 diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 95a17c60b0..c2f96ce55a 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -7,7 +7,7 @@ Arrastrar Ciągnij Táhnout - Trainer + Traîner Ziehen Arrastar Trascina @@ -15,7 +15,8 @@ 引きずる 끌기 拖拉 - 拖拉 + 拖动 + Sürükle Release @@ -28,26 +29,42 @@ Soltar Lascia Elengedés - はなす + 離す 놓기 放開 放开 + Bırak Drag/Release Object - Тащить/Отпустить Объекты + Тащить/отпустить объект Arrastrar/Soltar Objeto Ciągnij/Puść Obiekt Táhnout/Položit Objekt - Trainer/Lâcher Objets + Traîner/Lâcher un objet Objekt ziehen/loslassen Arrastar/Soltar Objeto Trascina/Lascia Oggetto Húzás/Elengedés Objektum - オブジェクトを引きずる/はなす + オブジェクトを引きずる/離す 물건 끌기/놓기 拖拉/放開物品 - 拖拉/放开物品 + 拖动/放开物品 + Objeyi Sürükle/Bırak + + + Carry/Release Object + Porter/Lâcher un objet + Нести/отпустить объект + Nieś/Puść objekt + オブジェクトを運ぶ/離す + Objeyi Taşı/Bırak + Arrastrar/Soltar Objeto + Objekt tragen/loslassen + Trasporta/Lascia Oggetto + 背负/释放物体 + 물건 업기/놓기 + Carregar/Soltar Objeto Item too heavy @@ -64,6 +81,7 @@ 물체가 너무 무겁습니다 此物品過重 此物品过重 + Eşya çok ağır Carry @@ -80,21 +98,134 @@ 업기 背起 背起 + Taşı - - Raise/Lower - Heben/Senken - Wyżej/Niżej - Levantar/Abaixar - Поднять/Опустить - Zvýšit/Snížit - Alza/Abbassa - Subir/Bajar - Lever/Baisser - 上げる/下げる - 높이기/낮추기 - 提高/下降 - 提高/下降 + + Raise/Lower | (Ctrl + Scroll) Rotate + Heben/Senken | (Strg + Scrollen) Drehen + Alza/Abbassa | (Ctrl + Rotellina) Ruota + Lever/Baisser | (Ctrl + Scroll) Rotation + 上げる/下げる | (Ctrl + スクロール) 回転 + Zvednout/Snížit | (Ctrl + Kolečko myši) Otáčet + Поднять/опустить | (Ctrl + Скролл) Крутить + Wyżej/niżej | (Ctrl + Kółko myszy) obracanie + Yükselt/Alçalt | (Ctrl + Tekerlek) Döndür + Subir/Bajar | (Ctrl + Scroll) Rotar + 抬起/放低 |(Ctrl + 鼠标滚轮)旋转 + 높이기/내리기 | (컨트롤 + 스크롤) 회전 + Subir/Abaixar | (Ctrl + Scroll) Rotacionar + + + ACE Dragging + ACE Traînage d'objets et d'unités + ACE Ziehen + ACE Trascinamento + ACE Húzás + ACE Перетаскивание + ACE Arrastrar + ACE Przeciąganie + ACE ドラッグ + ACE 拖曳 + ACE 끌기 + ACE Arraste + + + Allow firing while dragging + Arme utilisable durant le traînage + Schießen während des Ziehens erlauben + Permetti di sparare durante il trascinamento + Húzás közbeni tüzelés engedélyezése + Стрельба во время перетаскивания + Permitir disparar mientras se arrastra + Pozwól na strzelanie podczas przeciągania + 搬送中に射撃許可 + 允许在拖动时开火 + 끌기 중 사격 가능하게 하기 + Permitir disparar enquanto arrasta + + + Allow the player to fire their gun while dragging. + Cette option permet aux joueurs de faire usage de leur arme pendant qu'ils traînent un objet ou une unité.\nL'arme secondaire est utilisée si le joueur en est équipé. + Erlaubt dem Spieler während des Ziehens das Abfeuern der Waffe. + Permette al giocatore di fare fuoco con la propria arma mentre trascina qualcosa o qualcuno. + Húzás közben a játékos elsütheti a fegyverét. + Позволяет игроку стрелять во время перетаскивания + Permite al jugador disparar mientras está arrastrando. + Pozwala graczom strzelać z broni podczas przeciągania obiektów. + プレイヤーが引きずっている最中でも射撃できるようにします。 + 允许玩家在拖动时开火。 + 플레이어가 뭔가를 끌고 있는 동안에 무기를 사용할 수 있게 합니다. + Permite ao jogador disparar sua arma enquanto arrasta. + + + Allow Running with Lightweight Objects + 軽量物を持って走れるようにする + Permetti la corsa con oggetti leggeri + Zezwól na Bieganie z Lekkimi Obiektami + Erlauben das Sprinten mit leichten Gegenständen + 가벼운 개체 들고 달리기 허용 + Autoriser la course avec des objets légers + Permitir corrida com objetos leves + Позволяет работать с легкими объектами + Permitir correr con objetos ligeros + + + Allow the player to run when carrying lightweight objects. + プレイヤーが軽量オブジェクトを持ち運んでいるときに走れるようにする。 + Permetti al giocatore di correre se l'oggetto trasportato è leggero. + Zezwalaj graczowi na bieganie podczas przenoszenia lekkich przedmiotów. + Erlauben Sie dem Spieler, zu rennen, wenn er leichte Gegenstände trägt. + 가벼운 개체를 들고 다닐 때 플레이어가 뛸 수 있도록 허용합니다. + Autorise le joueur à courir lorsqu'il porte un objet léger. + Permite ao jogador correr enquanto carrega objetos leves. + Разрешите игроку бегать при переноске легких предметов. + Permite al jugador correr cuando porta objetos ligeros. + + + Skip Object Weight + オブジェクトの重量を無視 + Ignora Peso Contenitore + Pomiń Wagę Obiektu + Objektgewicht überspringen + 개체 무게 무시 + Ignorer le poids de l'objet + Ignorar Peso do Objeto + Игнорировать вес объекта + Ignora peso del objeto + + + Determines whether object's weight is added onto weight calculations. + 重量計算にオブジェクトの重量を追加するかどうかを定義します。 + Determina se la massa del contenitore è sommata alla massa del contenuto per i calcoli di peso. + Określa, czy waga obiektu jest dodawana do obliczeń ciężaru. + Legt fest, ob das Gewicht des Objekts zu den Gewichtsberechnungen hinzugefügt wird. + 무게 계산에 개체의 무게를 추가할 지 여부를 결정합니다. + Défini si le poids d'un objet est ajouté aux calculs du poids. + Determina se o peso do objeto é adicionado aos cálculos de peso. + Определяет, добавляется ли вес объекта при расчете веса. + Determina si el peso del objeto es añadido en los cálculos de peso. + + + Max Weight Coefficient + Coefficient de poids maximal + 최대 무게 계수 + Coefficiente di peso massimo + Coeficiente Máximo de Peso + Maximaler Gewichtskoeffizient + 最大重量係数 + Максимальный коэффициент веса + Máximo Coeficiente de Peso + + + Modifies weight limit calculations. Set to 0 to ignore. + Modifie les calculs de limite de poids. Configurer à 0 pour ignorer. + 무게 제한 계산을 수정합니다. 무시하려면 0으로 설정하십시오. + Altera il calcolo di peso massimo trasportabile. Impostalo su 0 per ignorare del tutto il peso. + Modifica os cálculos do limite de peso. Defina como 0 para ignorar. + Ändert die Berechnung der Gewichtsbegrenzung. Zum Ignorieren auf 0 setzen. + 重量制限の計算を変更します。 無視するには 0 に設定します。 + Изменяет расчеты предельного веса. Установите значение 0 для игнорирования. + Modifica el límite de peso de los cálculos. Poner a 0 para que lo ignore. diff --git a/addons/dragon/CfgAmmo.hpp b/addons/dragon/CfgAmmo.hpp index 033239013f..f736e8451b 100644 --- a/addons/dragon/CfgAmmo.hpp +++ b/addons/dragon/CfgAmmo.hpp @@ -35,6 +35,8 @@ class CfgAmmo { simulationStep = 0.005; maxControlRange = 1500; + EGVAR(vehicle_damage,incendiary) = 1.0; + class ace_missileguidance { minDeflection = 0; maxDeflection = 0; @@ -70,7 +72,7 @@ class CfgAmmo { }; }; - class GVAR(super) : GVAR(dragonBase) { + class GVAR(super): GVAR(dragonBase) { submunitionAmmo = QGVAR(penetrator_super); submunitionDirectionType = "SubmunitionModelDirection"; submunitionInitSpeed = 1000; @@ -108,7 +110,7 @@ class CfgAmmo { }; class ShellBase; - class GVAR(serviceCharge) : ShellBase { + class GVAR(serviceCharge): ShellBase { hit = 1; indirectHit = 2; indirectHitRange = 1; diff --git a/addons/dragon/CfgEventHandlers.hpp b/addons/dragon/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/dragon/CfgEventHandlers.hpp +++ b/addons/dragon/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/dragon/CfgMagazines.hpp b/addons/dragon/CfgMagazines.hpp index e4b59a9304..605501376d 100644 --- a/addons/dragon/CfgMagazines.hpp +++ b/addons/dragon/CfgMagazines.hpp @@ -1,6 +1,6 @@ class CfgMagazines { class 1Rnd_GAA_missiles; - class GVAR(super) : 1Rnd_GAA_missiles { + class GVAR(super): 1Rnd_GAA_missiles { sound[] = {}; soundFly[] = {}; soundHit[] = {}; diff --git a/addons/dragon/CfgVehicles.hpp b/addons/dragon/CfgVehicles.hpp index faac05bbe9..13441c6c26 100644 --- a/addons/dragon/CfgVehicles.hpp +++ b/addons/dragon/CfgVehicles.hpp @@ -18,6 +18,7 @@ class CfgVehicles { faction = "BLU_F"; crew = "B_soldier_f"; model = QPATHTOF(models\ace_m47_static.p3d); + editorPreview = QPATHTOF(data\ace_dragon_staticAssembled.jpg); 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"; diff --git a/addons/dragon/README.md b/addons/dragon/README.md index 84a82ad820..8b46440b0d 100644 --- a/addons/dragon/README.md +++ b/addons/dragon/README.md @@ -2,11 +2,3 @@ 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_postInit.sqf b/addons/dragon/XEH_postInit.sqf index 0305fe772a..2360a5bd97 100644 --- a/addons/dragon/XEH_postInit.sqf +++ b/addons/dragon/XEH_postInit.sqf @@ -6,7 +6,7 @@ ["vehicle", { params ["","_vehicle"]; TRACE_2("vehicle change",_vehicle,typeOf _vehicle); - if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {}; + if !(_vehicle isKindOf QGVAR(staticBase)) exitWith {}; _vehicle animate ["rest_rotate", 0]; @@ -14,7 +14,7 @@ [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; private _lastView = cameraView; - if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; }; + if !(_lastView in ["INTERNAL", "EXTERNAL"]) then { _lastView == "INTERNAL"; }; GVAR(pfID) = [{ params ["_args"]; diff --git a/addons/dragon/anim/M47.rtm b/addons/dragon/anim/M47.rtm deleted file mode 100644 index 48f3dfc3c4..0000000000 Binary files a/addons/dragon/anim/M47.rtm and /dev/null differ diff --git a/addons/dragon/config.cpp b/addons/dragon/config.cpp index 78d836936e..2acf1e6c70 100644 --- a/addons/dragon/config.cpp +++ b/addons/dragon/config.cpp @@ -3,12 +3,12 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; - weapons[] = {}; + units[] = {"ace_dragon_staticAssembled"}; + weapons[] = {"ace_dragon_super","ace_dragon_sight"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_hot","ace_csw"}; author = ECSTRING(common,ACETeam); - authors[] = {"Brandon (TCVM)"}; + authors[] = {"tcvm"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; diff --git a/addons/dragon/data/ace_dragon_staticAssembled.jpg b/addons/dragon/data/ace_dragon_staticAssembled.jpg new file mode 100644 index 0000000000..d64bda5930 Binary files /dev/null and b/addons/dragon/data/ace_dragon_staticAssembled.jpg differ diff --git a/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf b/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf index b7adb597f5..58e3844c88 100644 --- a/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf +++ b/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) (Code inspired by NouberNou's Dragon Guidance) + * Author: tcvm (Code inspired by NouberNou's Dragon Guidance) * Attack profile: Dragon Guidance * * Arguments: @@ -30,7 +30,7 @@ if ((_distanceToProjectile > _seekerMaxRangeSqr) || _wireCut || { !alive _shoote // 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]; + playSound3D ["a3\sounds_f\air\sfx\SL_rope_break.wss", objNull, false, _shooter modelToWorldWorld _wireCutSource, 5, 1, 25]; }; if (_serviceChargeCount > 0 && {(_lastTime - CBA_missionTime) <= 0}) then { diff --git a/addons/dragon/functions/fnc_canPickupTripod.sqf b/addons/dragon/functions/fnc_canPickupTripod.sqf index c328c66bd6..a103277972 100644 --- a/addons/dragon/functions/fnc_canPickupTripod.sqf +++ b/addons/dragon/functions/fnc_canPickupTripod.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) + * Author: 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: @@ -21,5 +21,4 @@ params ["_target", "_unit"]; && {!alive (gunner _target)} && {!(_target getVariable [QGVAR(fired), false])} && {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])} -&& EFUNC(csw,assemble_canPickupTripod) - +&& EFUNC(csw,canPickupTripod) diff --git a/addons/dragon/functions/fnc_onFired.sqf b/addons/dragon/functions/fnc_onFired.sqf index 78d9d15b91..4228f5dff0 100644 --- a/addons/dragon/functions/fnc_onFired.sqf +++ b/addons/dragon/functions/fnc_onFired.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) + * Author: tcvm * Runs when Dragon is fired * * Arguments: @@ -23,7 +23,7 @@ _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 _config = configOf _projectile >> "ace_missileguidance"; private _serviceInterval = [_config >> "serviceInterval", "NUMBER", 0.33] call CBA_fnc_getConfigEntry; private _serviceChargeCount = [_config >> "serviceCharges", "NUMBER", 60] call CBA_fnc_getConfigEntry; diff --git a/addons/dragon/functions/fnc_sightAttach.sqf b/addons/dragon/functions/fnc_sightAttach.sqf index 6ad5df2077..de085942b7 100644 --- a/addons/dragon/functions/fnc_sightAttach.sqf +++ b/addons/dragon/functions/fnc_sightAttach.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) + * Author: tcvm * Attaches the sighting unit to the Dragon missile. * * Arguments: @@ -21,7 +21,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightAttach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), true, true]; _target animate ["optic_hide", 0]; _target addWeapon QGVAR(superStatic); diff --git a/addons/dragon/functions/fnc_sightCanAttach.sqf b/addons/dragon/functions/fnc_sightCanAttach.sqf index 9ec742d19b..cce96022b9 100644 --- a/addons/dragon/functions/fnc_sightCanAttach.sqf +++ b/addons/dragon/functions/fnc_sightCanAttach.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) + * Author: tcvm * Determines if you can attach the sighting unit to the Dragon missile. * * Arguments: diff --git a/addons/dragon/functions/fnc_sightCanDetach.sqf b/addons/dragon/functions/fnc_sightCanDetach.sqf index 92c4a9a913..14659230ed 100644 --- a/addons/dragon/functions/fnc_sightCanDetach.sqf +++ b/addons/dragon/functions/fnc_sightCanDetach.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) + * Author: tcvm * Determines if you can attach the sighting unit to the Dragon missile. * * Arguments: diff --git a/addons/dragon/functions/fnc_sightDetach.sqf b/addons/dragon/functions/fnc_sightDetach.sqf index 161a13ba64..a5ac159a33 100644 --- a/addons/dragon/functions/fnc_sightDetach.sqf +++ b/addons/dragon/functions/fnc_sightDetach.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Brandon (TCVM) + * Author: tcvm * Attaches the sighting unit to the Dragon missile. * * Arguments: @@ -23,7 +23,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightDetach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), false, true]; _target animate ["optic_hide", 1]; _target removeWeapon QGVAR(superStatic); diff --git a/addons/dragon/functions/script_component.hpp b/addons/dragon/functions/script_component.hpp deleted file mode 100644 index 386679ecf6..0000000000 --- a/addons/dragon/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#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 index 39a8b6d80a..ac09112e91 100644 Binary files a/addons/dragon/models/ace_m47_magazine.p3d 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 index a0d8af5a78..355c6b04b5 100644 Binary files a/addons/dragon/models/ace_m47_optic.p3d 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 index b14d66d5c7..3c3a6b0731 100644 Binary files a/addons/dragon/models/ace_m47_static.p3d and b/addons/dragon/models/ace_m47_static.p3d differ diff --git a/addons/dragon/stringtable.xml b/addons/dragon/stringtable.xml index e4713c0802..d6269eb82b 100644 --- a/addons/dragon/stringtable.xml +++ b/addons/dragon/stringtable.xml @@ -1,26 +1,113 @@ - - + + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 スーパー ドラゴン + [CSW] M47龍式 + [班组] M47 龙式反坦克导弹 + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + [CSW] M47 슈퍼 드래곤 - + M47 Super-Dragon + M47 Super-Dragon + M47 Super-Dragon + M47 Super-Dragon + M47 スーパー ドラゴン + M47 龍式 + M47 龙式反坦克导弹 + M47 Super-Dragon + M47 Super-Dragon + M47 Super-Dragon + M47 Super-Dragon + M47 Super-Dragon + M47 Super-Dragon + M47 슈퍼 드래곤 - + Attach Sight + Bringe Visier an + Colocar Mira + Monter le viseur + 照準器を取り付ける + 裝上瞄具 + 装上瞄具 + Monta mirino + Připojit puškohled + Dołącz Optykę + Прикрепить прицел + Acoplar visor + 조준경 부착 - + Detach Sight + Nehme Visier ab + Remover Mira + Démonter le viseur + 照準器を外す + 拆下瞄具 + 卸下瞄具 + Smonta mirino + Odpojit puškohled + Odczep Optykę + Открепить прицел + Desacoplar visor + 조준경 분리 - + SU-36/P Daysight + SU-36/P Daysight + SU-36/P Daysight + SU-36/P Daysight + SU-36/P デイサイト + SU-36/P 日間瞄具 + SU-36/P 常规瞄具 + SU-36/P Mirino Diurno + SU-36/P denní puškohled + SU-36/P Celownik dzienny + SU-36/P Daysight + SU-36/P Дневной + Visor diurno SU-36/P + SU-36/P 주간조준기 - + A light, cheap sight used for daytime operations. Contains the guidance computer for the whole system + Ein leichte, billige Visierung for Tageseinsätze. Beinhaltet den Zielsuchcomputer für das ganze System. + Uma mira leve e comum utilizada para operações de dia. Contêm o computador de orientação para todo o sistema. + Un viseur léger et bon marché utilisé pour les opérations de jour.\nContient l'ordinateur de guidage pour tout le système. + 昼間時に使用される軽量で、低価格の照準器。システム全体の誘導コンピュータを備えている。 + 一個輕量,便宜適合日間行動使用的廉價瞄具。內含全套制導電腦系統 + 一种用于日间作战的轻型廉价瞄准具。包含整个系统的制导计算机 + Un mirino leggero ed economico usato per le operazioni diurne. Contiene il computer di guida per l'intero sistema. + Lehký a levný puškohled pro použití za denního světla. Obsahuje navigační počítač pro celý systém. + Lekki, tani celownik używany do działania w trakcie dnia. Zawiera komputer naprowadząjący dla całego systemu + Лёгкий дешёвый прицел, используемый для дневных операций. Содержит компьютер для всей системы + Un visor ligero y barato utilizado en operaciones diurnas. Contiene el ordenador de guiado para todo el sistema. + 싸고 가벼운 주간조준기입니다. 사격을 하기 위한 통제컴퓨터가 포함되있습니다. - + A Wire-Guided SACLOS missile with a unique flight characteristic + Eine Drahtgelenkte SACLOS-Rakete mit einer einzigartigen Flugcharakteristik + Um míssil SACLOS, guiado por fio com uma característica única de vôo + Un missile filoguidé SACLOS, présentant une caractéristique de vol exceptionnelle. + 特徴的な飛行特性を持つ、ワイヤ誘導の SACLOS ミサイルです。 + 一個有線制導半自動指令型飛彈並有著獨特的飛航動作 + 具有独特飞行特性的线导半自动指令型导弹 + Un missile SACLOS filo-guidato con una caratterisca di volo particolare + Drátem naváděná SACLOS raketa s unikátními letovými vlastnostmi + Naprowadzany przewodowo rakietowy pocisk SACLOS o unikalnej charakterystyce lotu + Ракета SACLOS с проводным наведением с уникальной характеристикой полета + Misil SACLOS guiado por hilo con una característica de vuelo única. + 특이한 비행 성질을 가진 반자동 가시선지령 유도미사일입니다. diff --git a/addons/explosives/ACE_Arsenal_Stats.hpp b/addons/explosives/ACE_Arsenal_Stats.hpp index cde27f3bde..821ac65bfd 100644 --- a/addons/explosives/ACE_Arsenal_Stats.hpp +++ b/addons/explosives/ACE_Arsenal_Stats.hpp @@ -6,8 +6,8 @@ class EGVAR(arsenal,stats) { stats[] = {QGVAR(Range)}; displayName = CSTRING(statExploRange); showText = 1; - textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _exploRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)', _exploRangeStat, (_exploRangeStat / 0.3048) toFixed 1)]); - condition = QUOTE(params [ARR_2('', '_config')]; (getNumber (_config >> QQGVAR(Detonator))) > 0); + textStatement = QUOTE(params [ARR_2('_stat','_config')]; private _exploRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)',_exploRangeStat,(_exploRangeStat / 0.3048) toFixed 1)]); + condition = QUOTE(params [ARR_2('','_config')]; (getNumber (_config >> QQGVAR(Detonator))) > 0); tabs[] = {{}, {7}}; }; }; diff --git a/addons/explosives/ACE_Settings.hpp b/addons/explosives/ACE_Settings.hpp index dbde3ea19b..5fce8ac000 100644 --- a/addons/explosives/ACE_Settings.hpp +++ b/addons/explosives/ACE_Settings.hpp @@ -1,23 +1,11 @@ class ACE_Settings { class GVAR(requireSpecialist) { - category = CSTRING(Menu); - displayName = CSTRING(RequireSpecialist_DisplayName); - description = CSTRING(RequireSpecialist_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(punishNonSpecialists) { - category = CSTRING(Menu); - displayName = CSTRING(PunishNonSpecialists_DisplayName); - description = CSTRING(PunishNonSpecialists_Description); - value = 1; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(explodeOnDefuse) { - category = CSTRING(Menu); - displayName = CSTRING(ExplodeOnDefuse_DisplayName); - description = CSTRING(ExplodeOnDefuse_Description); - value = 1; - typeName = "BOOL"; + movedToSQF = 1; }; }; diff --git a/addons/explosives/ACE_Triggers.hpp b/addons/explosives/ACE_Triggers.hpp index e9c717504e..27d63a736d 100644 --- a/addons/explosives/ACE_Triggers.hpp +++ b/addons/explosives/ACE_Triggers.hpp @@ -56,7 +56,7 @@ class ACE_Triggers { isAttachable = 1; displayName = CSTRING(timerName); picture = QPATHTOF(data\UI\Timer.paa); - onPlace = QUOTE([ARR_2(_this select 1, _this select 3 select 0)] call FUNC(startTimer); false); + onPlace = QUOTE([ARR_4(_this select 1,_this select 3 select 0,nil,_this select 0)] call FUNC(startTimer); false); onSetup = QUOTE(_this call FUNC(openTimerUI)); }; class Tripwire { 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/CfgEventHandlers.hpp b/addons/explosives/CfgEventHandlers.hpp index d2137371ec..ae0e5fe541 100644 --- a/addons/explosives/CfgEventHandlers.hpp +++ b/addons/explosives/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; @@ -28,7 +28,7 @@ class Extended_Take_EventHandlers { }; class Extended_Put_EventHandlers { class CAManBase { - GVAR(takeHandler) = QUOTE([ARR_3(_this select 1, _this select 0, _this select 2)] call FUNC(onInventoryChanged)); + GVAR(takeHandler) = QUOTE([ARR_3(_this select 1,_this select 0,_this select 2)] call FUNC(onInventoryChanged)); }; }; diff --git a/addons/explosives/CfgMagazines.hpp b/addons/explosives/CfgMagazines.hpp index 1784e80433..7bb2c6ff02 100644 --- a/addons/explosives/CfgMagazines.hpp +++ b/addons/explosives/CfgMagazines.hpp @@ -86,13 +86,13 @@ class CfgMagazines { GVAR(SetupObject) = "ACE_Explosives_Place_SLAM"; class ACE_Triggers { SupportedTriggers[] = {"IRSensor", "PressurePlate", "Timer", "Command", "MK16_Transmitter"}; - class PressurePlate{ + class PressurePlate { displayName = CSTRING(SLAME_Magnetic); digDistance = 0; ammo = "ACE_SLAMDirectionalMine_Magnetic_Ammo"; pitch = 90; }; - class IRSensor{ + class IRSensor { displayName = CSTRING(SLAME_IRSensor); }; class Timer { diff --git a/addons/explosives/CfgVehicles.hpp b/addons/explosives/CfgVehicles.hpp index 97562dc836..91a708beb8 100644 --- a/addons/explosives/CfgVehicles.hpp +++ b/addons/explosives/CfgVehicles.hpp @@ -11,7 +11,7 @@ class CfgVehicles { exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; showDisabled = 1; icon = QPATHTOF(UI\Explosives_Menu_ca.paa); - insertChildren = QUOTE([_player] call FUNC(addTransmitterActions);); + insertChildren = QUOTE([_player] call FUNC(addTransmitterActions)); class ACE_Place { displayName = CSTRING(Place); statement = ""; @@ -49,7 +49,7 @@ class CfgVehicles { distance = 1; displayName = CSTRING(Defuse); condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDefuse)); - statement = QUOTE([ARR_2(_player,_target)] call FUNC(startDefuse);); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(startDefuse)); exceptions[] = {"isNotSwimming"}; icon = QPATHTOF(UI\Defuse_ca.paa); }; @@ -78,6 +78,7 @@ class CfgVehicles { vehicleClass = "Cargo"; class ACE_Actions { class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); selection = ""; distance = 1.5; condition = "true"; @@ -86,7 +87,7 @@ class CfgVehicles { displayName = CSTRING(TriggerMenu); condition = "true"; statement = ""; - insertChildren = QUOTE([ARR_3(_target getVariable QUOTE(QGVAR(class)),_target,_player)] call FUNC(addTriggerActions);); + insertChildren = QUOTE([ARR_3(_target getVariable QUOTE(QGVAR(class)),_target,_player)] call FUNC(addTriggerActions)); showDisabled = 0; exceptions[] = {"isNotSwimming"}; icon = QPATHTOF(UI\Explosives_Menu_ca.paa); diff --git a/addons/explosives/CfgWeapons.hpp b/addons/explosives/CfgWeapons.hpp index 56ef154661..30e1fb95cb 100644 --- a/addons/explosives/CfgWeapons.hpp +++ b/addons/explosives/CfgWeapons.hpp @@ -2,7 +2,7 @@ class CfgWeapons { class Default; class Put: Default { muzzles[] += {QGVAR(muzzle)}; - class PutMuzzle: Default{}; + class PutMuzzle: Default {}; class GVAR(muzzle): PutMuzzle { magazines[] = {"ACE_FlareTripMine_Mag"}; }; @@ -26,6 +26,7 @@ class CfgWeapons { GVAR(Range) = 250; GVAR(Detonator) = 1; GVAR(triggerType) = "Command"; + ACE_isTool = 1; class ItemInfo: ACE_ExplosiveItem { mass = 3; @@ -46,6 +47,8 @@ class CfgWeapons { descriptionShort = CSTRING(DefusalKit_description); picture = QPATHTOF(Data\UI\Pliers.paa); model = "\A3\Structures_F\Items\Tools\Pliers_F.p3d"; + ACE_isTool = 1; + GVAR(defusalKit) = 1; class ItemInfo: ACE_ExplosiveItem { mass = 5; @@ -62,6 +65,7 @@ class CfgWeapons { GVAR(Range) = 100; GVAR(Detonator) = 1; GVAR(triggerType) = "DeadManSwitch"; + ACE_isTool = 1; class ItemInfo: ACE_ExplosiveItem { mass = 2; @@ -78,6 +82,7 @@ class CfgWeapons { GVAR(Range) = 15000; GVAR(Detonator) = 1; GVAR(triggerType) = "Cellphone"; + ACE_isTool = 1; class ItemInfo: ACE_ExplosiveItem { mass = 2; diff --git a/addons/explosives/Data/ace_m57.rvmat b/addons/explosives/Data/ace_m57.rvmat index 628e9bfe55..565bd53e79 100644 --- a/addons/explosives/Data/ace_m57.rvmat +++ b/addons/explosives/Data/ace_m57.rvmat @@ -6,7 +6,7 @@ diffuse[] = {1,1,1,1}; forcedDiffuse[] = {0,0,0,0}; emmisive[] = {0,0,0,1}; specular[] = {0.3,0.3,0.3,1}; -specularPower = 3b0; +specularPower = 3; PixelShaderID = "Super"; VertexShaderID = "Super"; class Stage1 { diff --git a/addons/explosives/ExplosivesUI.hpp b/addons/explosives/ExplosivesUI.hpp index cd06abff5b..ef32c0c04b 100644 --- a/addons/explosives/ExplosivesUI.hpp +++ b/addons/explosives/ExplosivesUI.hpp @@ -13,9 +13,9 @@ class Rsc_ACE_CallScreen_Edit: RscEdit { style = "0x00 + 0x40 + 0x200"; shadow = 1; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 20) * 1)"; - x = 0.288594 * safezoneW + safezoneX; - w = 0.0825 * safezoneW; - h = 0.044 * safezoneH; + x = "0.288594 * safezoneW + safezoneX"; + w = "0.0825 * safezoneW"; + h = "0.044 * safezoneH"; }; class Rsc_ACE_HiddenButton: RscButton { colorText[] = {0, 0, 0, 0}; @@ -40,175 +40,175 @@ class Rsc_ACE_PhoneInterface { class RscPicture_1200: RscPicture { idc = 1200; text = QPATHTOF(Data\UI\Cellphone_Background.paa); - x = 0.231875 * safezoneW + safezoneX; - y = 0.104 * safezoneH + safezoneY; - w = 0.195937 * safezoneW; - h = 0.704 * safezoneH; + x = "0.231875 * safezoneW + safezoneX"; + y = "0.104 * safezoneH + safezoneY"; + w = "0.195937 * safezoneW"; + h = "0.704 * safezoneH"; }; class numkey_1: Rsc_ACE_NumKeyButton { idc = 1600; - x = 0.278281 * safezoneW + safezoneX; - y = 0.533 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.278281 * safezoneW + safezoneX"; + y = "0.533 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "1"; action = "ctrlSetText [1400,((ctrlText 1400) + '1')];"; }; class numkey_2: Rsc_ACE_NumKeyButton { idc = 1601; - x = 0.314375 * safezoneW + safezoneX; - y = 0.533 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.314375 * safezoneW + safezoneX"; + y = "0.533 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "2"; action = "ctrlSetText [1400,((ctrlText 1400) + '2')];"; }; class numkey_3: Rsc_ACE_NumKeyButton { idc = 1602; - x = 0.350469 * safezoneW + safezoneX; - y = 0.533 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.350469 * safezoneW + safezoneX"; + y = "0.533 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "3"; action = "ctrlSetText [1400,((ctrlText 1400) + '3')];"; }; class numkey_4: Rsc_ACE_NumKeyButton { idc = 1603; - x = 0.278281 * safezoneW + safezoneX; - y = 0.577 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.278281 * safezoneW + safezoneX"; + y = "0.577 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "4"; action = "ctrlSetText [1400,((ctrlText 1400) + '4')];"; }; class numkey_5: Rsc_ACE_NumKeyButton { idc = 1604; - x = 0.314375 * safezoneW + safezoneX; - y = 0.577 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.314375 * safezoneW + safezoneX"; + y = "0.577 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "5"; action = "ctrlSetText [1400,((ctrlText 1400) + '5')];"; }; class numkey_6: Rsc_ACE_NumKeyButton { idc = 1605; - x = 0.350469 * safezoneW + safezoneX; - y = 0.577 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.350469 * safezoneW + safezoneX"; + y = "0.577 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "6"; action = "ctrlSetText [1400,((ctrlText 1400) + '6')];"; }; class numkey_7: Rsc_ACE_NumKeyButton { idc = 1606; - x = 0.278281 * safezoneW + safezoneX; - y = 0.621 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.278281 * safezoneW + safezoneX"; + y = "0.621 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "7"; action = "ctrlSetText [1400,((ctrlText 1400) + '7')];"; }; class numkey_8: Rsc_ACE_NumKeyButton { idc = 1607; - x = 0.314375 * safezoneW + safezoneX; - y = 0.621 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.314375 * safezoneW + safezoneX"; + y = "0.621 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "8"; action = "ctrlSetText [1400,((ctrlText 1400) + '8')];"; }; class numkey_9: Rsc_ACE_NumKeyButton { idc = 1608; - x = 0.350469 * safezoneW + safezoneX; - y = 0.621 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.350469 * safezoneW + safezoneX"; + y = "0.621 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "9"; action = "ctrlSetText [1400,((ctrlText 1400) + '9')];"; }; class numkey_0: Rsc_ACE_NumKeyButton { idc = 1609; - x = 0.314375 * safezoneW + safezoneX; - y = 0.676 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.314375 * safezoneW + safezoneX"; + y = "0.676 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = "0"; action = "ctrlSetText [1400,((ctrlText 1400) + '0')];"; }; class speedDialAdd: Rsc_ACE_NumKeyButton { idc = 1610; - x = 0.278281 * safezoneW + safezoneX; - y = 0.676 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.033 * safezoneH; + x = "0.278281 * safezoneW + safezoneX"; + y = "0.676 * safezoneH + safezoneY"; + w = "0.0309375 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = CSTRING(Phone_AddToSpeedDial); - action = QUOTE([ARR_2(ctrlText 1401,ctrlText 1400)] call FUNC(addToSpeedDial);); + action = QUOTE([ARR_2(ctrlText 1401,ctrlText 1400)] call FUNC(addToSpeedDial)); }; class clear: Rsc_ACE_HiddenButton { idc = 1610; - x = 0.278281 * safezoneW + safezoneX; - y = 0.445 * safezoneH + safezoneY; - w = 0.020625 * safezoneW; - h = 0.033 * safezoneH; + x = "0.278281 * safezoneW + safezoneX"; + y = "0.445 * safezoneH + safezoneY"; + w = "0.020625 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = CSTRING(Clear); action = QUOTE(ctrlSetText [ARR_2(1400,'')];[ctrlText 1401] call FUNC(removeFromSpeedDial);ctrlSetText [ARR_2(1401,'')];); }; class dial: Rsc_ACE_HiddenButton { idc = 1611; - x = 0.309219 * safezoneW + safezoneX; - y = 0.445 * safezoneH + safezoneY; - w = 0.04125 * safezoneW; - h = 0.033 * safezoneH; + x = "0.309219 * safezoneW + safezoneX"; + y = "0.445 * safezoneH + safezoneY"; + w = "0.04125 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = CSTRING(Phone_Dial); - action = QUOTE([ARR_2(ace_player,ctrlText 1400)] call FUNC(dialPhone);); + action = QUOTE([ARR_2(ace_player,ctrlText 1400)] call FUNC(dialPhone)); }; class up: Rsc_ACE_HiddenButton { idc = 1612; - x = 0.360781 * safezoneW + safezoneX; - y = 0.445 * safezoneH + safezoneY; - w = 0.020625 * safezoneW; - h = 0.033 * safezoneH; + x = "0.360781 * safezoneW + safezoneX"; + y = "0.445 * safezoneH + safezoneY"; + w = "0.020625 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = CSTRING(Phone_Up); action = QUOTE([true] call FUNC(setSpeedDial)); }; class down: Rsc_ACE_HiddenButton { idc = 1613; - x = 0.345312 * safezoneW + safezoneX; - y = 0.485 * safezoneH + safezoneY; - w = 0.020625 * safezoneW; - h = 0.033 * safezoneH; + x = "0.345312 * safezoneW + safezoneX"; + y = "0.485 * safezoneH + safezoneY"; + w = "0.020625 * safezoneW"; + h = "0.033 * safezoneH"; tooltip = CSTRING(Phone_Down); action = QUOTE([false] call FUNC(setSpeedDial)); }; class speedDial_Text: RscText { idc = 1405; - y = 0.302 * safezoneH + safezoneY; + y = "0.302 * safezoneH + safezoneY"; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 22) * 1)"; - x = 0.288594 * safezoneW + safezoneX; - w = 0.0825 * safezoneW; - h = 0.044 * safezoneH; + x = "0.288594 * safezoneW + safezoneX"; + w = "0.0825 * safezoneW"; + h = "0.044 * safezoneH"; text = "Name"; }; class speedDial_edit: Rsc_ACE_CallScreen_Edit { idc = 1401; - y = 0.302 * safezoneH + safezoneY; - x = 0.318 * safezoneW + safezoneX; - w = 0.1; + y = "0.302 * safezoneH + safezoneY"; + x = "0.318 * safezoneW + safezoneX"; + w = "0.1"; }; class numberEdit_Text: RscText { idc = 1406; - y = 0.348 * safezoneH + safezoneY; + y = "0.348 * safezoneH + safezoneY"; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 22) * 1)"; - x = 0.288594 * safezoneW + safezoneX; - w = 0.0825 * safezoneW; - h = 0.044 * safezoneH; + x = "0.288594 * safezoneW + safezoneX"; + w = "0.0825 * safezoneW"; + h = "0.044 * safezoneH"; text = "#"; }; class number_edit: Rsc_ACE_CallScreen_Edit { canModify = 0; idc = 1400; - y = 0.348 * safezoneH + safezoneY; - x = 0.3 * safezoneW + safezoneX; + y = "0.348 * safezoneH + safezoneY"; + x = "0.3 * safezoneW + safezoneX"; }; }; }; diff --git a/addons/explosives/GUI_VirtualAmmo.hpp b/addons/explosives/GUI_VirtualAmmo.hpp index ba288f019b..ace807dc44 100644 --- a/addons/explosives/GUI_VirtualAmmo.hpp +++ b/addons/explosives/GUI_VirtualAmmo.hpp @@ -5,7 +5,7 @@ class RscTitles { duration = 9999999; fadein = 0; fadeout = 0; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(virtualAmmoDisplay), _this select 0)]); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(virtualAmmoDisplay),_this select 0)]); class controls {}; class objects { class TheObject { diff --git a/addons/explosives/README.md b/addons/explosives/README.md index 5e85f19427..9f136b6735 100644 --- a/addons/explosives/README.md +++ b/addons/explosives/README.md @@ -2,11 +2,3 @@ ace_explosives ============== Completely replaces the vanilla explosives system, allowing precise placement and different trigger types. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [CorruptedHeart](https://github.com/CorruptedHeart) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/explosives/TimerDialog.hpp b/addons/explosives/TimerDialog.hpp index a3ab96af06..5bc4954fbf 100644 --- a/addons/explosives/TimerDialog.hpp +++ b/addons/explosives/TimerDialog.hpp @@ -2,24 +2,24 @@ class GVAR(timerUI) { idd = -1; movingEnable = 1; enableSimulation = 1; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(timerDisplay), _this select 0)]); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(timerDisplay),_this select 0)]); class controlsBackground { class Header: RscText { idc = -1; text = CSTRING(ExplosiveTimer); - x = 13.5 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 5 * GUI_GRID_H + GUI_GRID_CENTER_Y; - w = 13 * GUI_GRID_W; - h = GUI_GRID_H; + x = QUOTE(13.5 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(5 * GUI_GRID_H + GUI_GRID_CENTER_Y); + w = QUOTE(13 * GUI_GRID_W); + h = QUOTE(GUI_GRID_H); colorBackground[] = GUI_BCG_COLOR; moving = 1; }; class Background: RscText { idd = -1; - x = 13.5 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 6.1 * GUI_GRID_H + GUI_GRID_CENTER_Y; - w = 13 * GUI_GRID_W; - h = 6.5 * GUI_GRID_H; + x = QUOTE(13.5 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(6.1 * GUI_GRID_H + GUI_GRID_CENTER_Y); + w = QUOTE(13 * GUI_GRID_W); + h = QUOTE(6.5 * GUI_GRID_H); colorBackground[] = {0, 0, 0, 0.8}; }; }; @@ -27,24 +27,24 @@ class GVAR(timerUI) { class DigitBackground_1: RscPicture { idc = -1; text = QPATHTOF(UI\seven_segment_8.paa); - x = 14 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 6.6 * GUI_GRID_H + GUI_GRID_CENTER_Y; - w = 4 * GUI_GRID_W; - h = 4 * GUI_GRID_H; + x = QUOTE(14 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(6.6 * GUI_GRID_H + GUI_GRID_CENTER_Y); + w = QUOTE(4 * GUI_GRID_W); + h = QUOTE(4 * GUI_GRID_H); colorText[] = {0.3, 0.3, 0.3, 0.5}; }; class DigitBackground_2: DigitBackground_1 { - x = 16.4 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(16.4 * GUI_GRID_W + GUI_GRID_CENTER_X); }; class DigitBackground_3: DigitBackground_1 { - x = 19.7 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(19.7 * GUI_GRID_W + GUI_GRID_CENTER_X); }; class DigitBackground_4: DigitBackground_1 { - x = 22.1 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(22.1 * GUI_GRID_W + GUI_GRID_CENTER_X); }; class DigitSeparator: DigitBackground_1 { text = QPATHTOF(UI\seven_segment_separator.paa); - x = 18.025 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(18.025 * GUI_GRID_W + GUI_GRID_CENTER_X); colorText[] = {1, 0.05, 0.05, 1}; }; class Digit_1: DigitBackground_1 { @@ -54,22 +54,22 @@ class GVAR(timerUI) { }; class Digit_2: Digit_1 { idc = IDC_TIMER_DIGIT_2; - x = 16.4 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(16.4 * GUI_GRID_W + GUI_GRID_CENTER_X); }; class Digit_3: Digit_1 { idc = IDC_TIMER_DIGIT_3; - x = 19.7 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(19.7 * GUI_GRID_W + GUI_GRID_CENTER_X); }; class Digit_4: Digit_1 { idc = IDC_TIMER_DIGIT_4; - x = 22.1 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(22.1 * GUI_GRID_W + GUI_GRID_CENTER_X); }; class Slider: ctrlXSliderH { idc = IDC_TIMER_SLIDER; - x = 14 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 11.1 * GUI_GRID_H + GUI_GRID_CENTER_Y; - w = 12 * GUI_GRID_W; - h = GUI_GRID_H; + x = QUOTE(14 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(11.1 * GUI_GRID_H + GUI_GRID_CENTER_Y); + w = QUOTE(12 * GUI_GRID_W); + h = QUOTE(GUI_GRID_H); color[] = {0.3, 0.3, 0.3, 0.7}; colorActive[] = {0.3, 0.3, 0.3, 0.7}; sliderRange[] = {TIMER_VALUE_MIN, TIMER_VALUE_MAX}; @@ -79,10 +79,10 @@ class GVAR(timerUI) { idc = -1; text = CSTRING(Cancel); onButtonClick = QUOTE(closeDialog 0); - x = 13.5 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 12.7 * GUI_GRID_H + GUI_GRID_CENTER_Y; - w = 5 * GUI_GRID_W; - h = GUI_GRID_H; + x = QUOTE(13.5 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(12.7 * GUI_GRID_H + GUI_GRID_CENTER_Y); + w = QUOTE(5 * GUI_GRID_W); + h = QUOTE(GUI_GRID_H); colorActive[] = {0, 0, 0, 1}; colorBackground[] = {0, 0, 0, 0.8}; colorFocused[] = {0, 0, 0, 0.8}; @@ -91,7 +91,7 @@ class GVAR(timerUI) { idc = IDC_TIMER_CONFIRM; text = CSTRING(SetTime); onButtonClick = ""; - x = 21.5 * GUI_GRID_W + GUI_GRID_CENTER_X; + x = QUOTE(21.5 * GUI_GRID_W + GUI_GRID_CENTER_X); }; }; }; diff --git a/addons/explosives/XEH_PREP.hpp b/addons/explosives/XEH_PREP.hpp index c04e0d3133..444b9db2ea 100644 --- a/addons/explosives/XEH_PREP.hpp +++ b/addons/explosives/XEH_PREP.hpp @@ -10,6 +10,7 @@ PREP(cancelPlacement); PREP(canDefuse); PREP(canDetonate); PREP(connectExplosive); +PREP(cycleActiveTrigger); PREP(defuseExplosive); PREP(detonateExplosive); PREP(detonateExplosiveAll); @@ -37,3 +38,6 @@ PREP(spawnFlare); PREP(startDefuse); PREP(startTimer); PREP(triggerType); +PREP(allowDefuse); +PREP(isAllowedDefuse); +PREP(checkDetonateHandlers); diff --git a/addons/explosives/XEH_postInit.sqf b/addons/explosives/XEH_postInit.sqf index 76d3e44bd1..81ab1b5406 100644 --- a/addons/explosives/XEH_postInit.sqf +++ b/addons/explosives/XEH_postInit.sqf @@ -16,8 +16,18 @@ */ //Event for setting explosive placement angle/pitch: -[QGVAR(place), {_this call FUNC(setPosition)}] call CBA_fnc_addEventHandler; -[QGVAR(startDefuse), FUNC(startDefuse)] call CBA_fnc_addEventHandler; +[QGVAR(place), { + params ["_explosive", "", "", "_unit"]; + + _this call FUNC(setPosition); + + if (isServer) then { + if (missionNamespace getVariable [QGVAR(setShotParents), true]) then { + _explosive setShotParents [_unit, _unit]; + }; + }; +}] call CBA_fnc_addEventHandler; +[QGVAR(startDefuse), LINKFUNC(startDefuse)] call CBA_fnc_addEventHandler; //When getting knocked out in medical, trigger deadman explosives: //Event is global, only run on server (ref: ace_medical_fnc_setUnconscious) @@ -25,7 +35,9 @@ if (isServer) then { [QGVAR(detonate), { params ["_unit", "_explosive", "_delay"]; TRACE_3("server detonate EH",_unit,_explosive,_delay); - _explosive setShotParents [_unit, _unit]; + if (missionNamespace getVariable [QGVAR(setShotParents), true]) then { + _explosive setShotParents [_unit, _unit]; + }; [{ params ["_explosive"]; TRACE_1("exploding",_explosive); @@ -38,13 +50,15 @@ if (isServer) then { ["ace_unconscious", { params ["_unit", "_isUnconscious"]; if (!_isUnconscious) exitWith {}; - TRACE_1("Knocked Out, Doing Deadman", _unit); + TRACE_1("Knocked Out, Doing Deadman",_unit); [_unit] call FUNC(onIncapacitated); }] call CBA_fnc_addEventHandler; }; if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + GVAR(PlacedCount) = 0; GVAR(Setup) = objNull; GVAR(pfeh_running) = false; @@ -60,3 +74,13 @@ GVAR(CurrentSpeedDial) = 0; _this call FUNC(interactEH); }] call CBA_fnc_addEventHandler; + +["unit", { + params ["_player"]; + [_player, QGVAR(explosiveActions)] call EFUNC(common,eraseCache); +}] call CBA_fnc_addPlayerEventHandler; + +["ace_allowDefuse", { + params["_mine", "_allow"]; + [_mine, _allow] call FUNC(allowDefuse); +}] call CBA_fnc_addEventHandler; diff --git a/addons/explosives/XEH_preInit.sqf b/addons/explosives/XEH_preInit.sqf index d9a8d39ff4..e39270f0bb 100644 --- a/addons/explosives/XEH_preInit.sqf +++ b/addons/explosives/XEH_preInit.sqf @@ -8,6 +8,13 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +GVAR(activeTrigger) = ""; + GVAR(detonationHandlers) = []; +GVAR(excludedMines) = []; + +GVAR(defusalKits) = keys (uiNamespace getVariable QGVAR(defusalKits)); ADDON = true; diff --git a/addons/explosives/XEH_preStart.sqf b/addons/explosives/XEH_preStart.sqf index 022888575e..4eb48f6388 100644 --- a/addons/explosives/XEH_preStart.sqf +++ b/addons/explosives/XEH_preStart.sqf @@ -1,3 +1,6 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +private _defusalKits = (QUOTE(getNumber (_x >> QQGVAR(defusalKit)) > 0) configClasses (configFile >> "CfgWeapons") apply {configName _x}); +uiNamespace setVariable [QGVAR(defusalKits), compileFinal (_defusalKits createHashMapFromArray [])]; diff --git a/addons/explosives/config.cpp b/addons/explosives/config.cpp index 3d2077ff1d..b60186ab68 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" @@ -40,10 +41,13 @@ class CfgActions { class ActivateMine: None { show = 0; }; - class Deactivate:None { + class Deactivate: None { show = 0; }; - class DeactivateMine:None { + class DeactivateMine: None { + show = 0; + }; + class UseContainerMagazine: None { show = 0; }; }; diff --git a/addons/explosives/dev/test_magazines.sqf b/addons/explosives/dev/test_magazines.sqf new file mode 100644 index 0000000000..ca9744f08d --- /dev/null +++ b/addons/explosives/dev/test_magazines.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +// call compileScript ["z\ace\addons\explosives\dev\test_magazines.sqf"]; + +INFO("--- Checking Explosive Mags ---"); + +private _explosivesMags = compatibleMagazines "Put"; +private _setupHash = createHashMap; +{ + private _mag = _x; + private _cfg = configFile >> "CfgMagazines" >> _mag; + private _scope = getNumber (_cfg >> "scope"); + + private _setupObject = getText (_cfg >> QGVAR(SetupObject)); + if (_setupObject == "") then { + WARNING_2("[%1](scope %2) has no setupObject",_mag,_scope); + continue + }; + if (!isClass (configFile >> "CfgVehicles" >> _setupObject)) then { + ERROR_2("[%1](scope %2) has invalid setup object",_mag,_scope); + }; + if ((((_setupHash getOrDefault [_setupObject, [], true]) pushBack _mag) > 0)) then { + INFO_2("[%1] setupObject has multiple mags %2",_setupObject,_setupHash get _setupObject); + }; +} forEach _explosivesMags; diff --git a/addons/explosives/functions/fnc_addCellphoneIED.sqf b/addons/explosives/functions/fnc_addCellphoneIED.sqf index d9ae19892c..d35b303fc1 100644 --- a/addons/explosives/functions/fnc_addCellphoneIED.sqf +++ b/addons/explosives/functions/fnc_addCellphoneIED.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds an IED to the cellphone list @@ -29,10 +29,10 @@ private _hasRequired = true; private _detonators = [_unit] call FUNC(getDetonators); { - if !(_x in _detonators) exitWith{ + if !(_x in _detonators) exitWith { _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; private _code = ""; while {true} do { diff --git a/addons/explosives/functions/fnc_addClacker.sqf b/addons/explosives/functions/fnc_addClacker.sqf index 684161d7ee..794aec0a10 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds an explosive as a clacker item to the passed unit if the unit has the required item. @@ -31,7 +31,7 @@ private _detonators = [_unit] call FUNC(getDetonators); if !(_x in _detonators) exitWith{ _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; if !(_hasRequired) exitWith {}; private _config = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; @@ -46,3 +46,5 @@ _unit setVariable [QGVAR(Clackers), _clacker, true]; //display clacker code message: [format [localize LSTRING(DetonateCode), GVAR(PlacedCount)]] call EFUNC(common,displayTextStructured); + +[QGVAR(clackerAdded), [_unit, _explosive, GVAR(PlacedCount)]] call CBA_fnc_localEvent; diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index f1dff4fc9f..d950278c35 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Opens the UI for explosive detonation selection @@ -49,18 +49,43 @@ private _explosivesList = []; }; }; } forEach _result; -if (_detonator != "ACE_DeadManSwitch") then { - // Add action to detonate all explosives tied to the detonator - if (count _explosivesList > 0) then { - _children pushBack [ + +// If the detonator is not active, is a clacker and has assigned explosives, generate an interaction to make it the active detonator for use with the "trigger all" keybind +if ( + _detonator != GVAR(activeTrigger) && + {_detonator != "Cellphone"} && + { + _explosivesList isNotEqualTo [] || + {_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}} + } +) then { + _children pushBack [ [ - "Explosive_All", - localize LSTRING(DetonateAll), - getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"), - {(_this select 2) call FUNC(detonateExplosiveAll);}, + QGVAR(setActiveTrigger), + LLSTRING(SetActiveTrigger), + "", + {GVAR(activeTrigger) = (_this select 2) select 0;}, {true}, {}, - [_unit,_range,_explosivesList, _detonator] + [_detonator] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; +}; + +if (_detonator != "ACE_DeadManSwitch") then { + // Add action to detonate all explosives tied to the detonator + if (count _explosivesList > 1) then { + _children pushBack [ + [ + "Explosive_All", + LLSTRING(DetonateAll), + getText (configFile >> "CfgWeapons" >> _detonator >> "picture"), + {(_this select 2) call FUNC(detonateExplosiveAll);}, + {true}, + {}, + [_unit, _range, _explosivesList, _detonator] ] call EFUNC(interact_menu,createAction), [], _unit @@ -69,15 +94,15 @@ if (_detonator != "ACE_DeadManSwitch") then { } else { //Add action to detonate all explosives (including the inventory explosive): _children pushBack [ - [ - "Explosive_All_Deadman", - localize LSTRING(DetonateAll), - getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"), - {[_player] call FUNC(onIncapacitated)}, - {true} - ] call EFUNC(interact_menu,createAction), - [], - _unit + [ + "Explosive_All_Deadman", + LLSTRING(DetonateAll), + getText (configFile >> "CfgWeapons" >> _detonator >> "picture"), + {[_player] call FUNC(onIncapacitated)}, + {true} + ] call EFUNC(interact_menu,createAction), + [], + _unit ]; //Adds actions for the explosives you can connect to the deadman switch. @@ -89,7 +114,7 @@ if (_detonator != "ACE_DeadManSwitch") then { _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - //Add the disconect action + //Add the disconnect action private _magConfig = configFile >> "CfgMagazines" >> _connectedInventoryExplosive; private _name = if ((getText (_magConfig >> "displayNameShort")) != "") then { getText (_magConfig >> "displayNameShort") @@ -99,24 +124,27 @@ if (_detonator != "ACE_DeadManSwitch") then { private _picture = getText (_magConfig >> "picture"); _children pushBack [ - ([ - "Deadman_disconnect", - format ["%1 %2", localize "str_disp_disconnect", _name], - _picture, - { - params ["_player"]; - TRACE_1("clear",_player); - _player setVariable [QGVAR(deadmanInvExplosive), "", true]; - }, - {true} - ] call EFUNC(interact_menu,createAction)), [], _unit]; + ([ + "Deadman_disconnect", + format ["%1 %2", localize "str_disp_disconnect", _name], + _picture, + { + params ["_player"]; + TRACE_1("clear",_player); + _player setVariable [QGVAR(deadmanInvExplosive), "", true]; + }, + {true} + ] call EFUNC(interact_menu,createAction)), + [], + _unit + ]; } else { //Add all magazines that would work with the deadman switch private _procressedMags = []; { private _mag = _x; - if (!(_mag in _procressedMags)) then { + if !(_mag in _procressedMags) then { _procressedMags pushBack _x; private _magConfig = configFile >> "CfgMagazines" >> _mag; private _supportedTriggers = getArray (_magConfig >> "ACE_Triggers" >> "SupportedTriggers"); diff --git a/addons/explosives/functions/fnc_addDetonateHandler.sqf b/addons/explosives/functions/fnc_addDetonateHandler.sqf index b227b96d07..5ca0d924b5 100644 --- a/addons/explosives/functions/fnc_addDetonateHandler.sqf +++ b/addons/explosives/functions/fnc_addDetonateHandler.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Add a explosive detonation handler. * Should be called on all machines. * Code needs to return BOOL: true(allowed) / false(blocked) - * See https://ace3mod.com/wiki/framework/explosives-framework.html for an example. + * See https://ace3.acemod.org/wiki/framework/explosives-framework.html for an example. * * Arguments: * 0: Code diff --git a/addons/explosives/functions/fnc_addExplosiveActions.sqf b/addons/explosives/functions/fnc_addExplosiveActions.sqf index 281aebf048..480ecd2701 100644 --- a/addons/explosives/functions/fnc_addExplosiveActions.sqf +++ b/addons/explosives/functions/fnc_addExplosiveActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, CAA-Picard, mharis001 * Returns children actions for explosive magazines in the player's inventory. diff --git a/addons/explosives/functions/fnc_addToSpeedDial.sqf b/addons/explosives/functions/fnc_addToSpeedDial.sqf index 5b7d828d53..4ccc23696e 100644 --- a/addons/explosives/functions/fnc_addToSpeedDial.sqf +++ b/addons/explosives/functions/fnc_addToSpeedDial.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets the speed dial for the UI. diff --git a/addons/explosives/functions/fnc_addTransmitterActions.sqf b/addons/explosives/functions/fnc_addTransmitterActions.sqf index d39b9fd731..043c9db661 100644 --- a/addons/explosives/functions/fnc_addTransmitterActions.sqf +++ b/addons/explosives/functions/fnc_addTransmitterActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Opens the UI for selecting the transmitter diff --git a/addons/explosives/functions/fnc_addTriggerActions.sqf b/addons/explosives/functions/fnc_addTriggerActions.sqf index 6e534a19ae..b6b6e0ce41 100644 --- a/addons/explosives/functions/fnc_addTriggerActions.sqf +++ b/addons/explosives/functions/fnc_addTriggerActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Opens the UI for explosive trigger selection @@ -31,7 +31,7 @@ private _children = []; if !(_x in _detonators) exitWith { _hasRequiredItems = false; }; - } count _required; + } forEach _required; if (_hasRequiredItems && {(!_isAttached) || {(getNumber (_x >> "isAttachable")) == 1}}) then { _children pushBack [ diff --git a/addons/explosives/functions/fnc_allowDefuse.sqf b/addons/explosives/functions/fnc_allowDefuse.sqf new file mode 100644 index 0000000000..1a7a399d13 --- /dev/null +++ b/addons/explosives/functions/fnc_allowDefuse.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Walthzer + * Sets if a dynamic defuse action is allowed to be added to a mine. + * + * Arguments: + * 0: Mine + * 1: Allow defusal + * + * Return Value: + * Succes + * + * Example: + * [_mine, false] call ace_explosives_fnc_allowDefuse + * + * Public: Yes + */ + +params [["_mine", objNull, [objNull]], ["_allow", true, [true]]]; +TRACE_2("params",_mine,_allow); + +if !(_mine in allMines) exitWith {false}; + +if (_allow && {!([_mine] call FUNC(isAllowedDefuse))}) exitWith { + GVAR(excludedMines) = GVAR(excludedMines) - [_mine]; + true +}; + +if (!_allow) exitWith { + GVAR(excludedMines) pushBackUnique _mine != -1 +}; + +false diff --git a/addons/explosives/functions/fnc_canDefuse.sqf b/addons/explosives/functions/fnc_canDefuse.sqf index f42764ee38..54bf8477bc 100644 --- a/addons/explosives/functions/fnc_canDefuse.sqf +++ b/addons/explosives/functions/fnc_canDefuse.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Whether a unit can perform the defuse action * * Arguments: * 0: Unit - * 0: Target (ACE_DefuseObject) + * 1: Target (ACE_DefuseObject) * * Return Value: * Able to defuse @@ -24,7 +24,7 @@ if (isNull _explosive) exitWith { deleteVehicle _target; false }; -if (vehicle _unit != _unit || {!("ACE_DefusalKit" in (_unit call EFUNC(common,uniqueItems)))}) exitWith {false}; +if (!isNull objectParent _unit || {(_unit call EFUNC(common,uniqueItems)) findAny GVAR(defusalKits) == -1}) exitWith {false}; if (GVAR(RequireSpecialist) && {!([_unit] call EFUNC(Common,isEOD))}) exitWith {false}; diff --git a/addons/explosives/functions/fnc_canDetonate.sqf b/addons/explosives/functions/fnc_canDetonate.sqf index a81103ce13..7c1112a69f 100644 --- a/addons/explosives/functions/fnc_canDetonate.sqf +++ b/addons/explosives/functions/fnc_canDetonate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Whether the unit is able to detonate explosives diff --git a/addons/explosives/functions/fnc_cancelPlacement.sqf b/addons/explosives/functions/fnc_cancelPlacement.sqf index eaefcfcc07..99ce808615 100644 --- a/addons/explosives/functions/fnc_cancelPlacement.sqf +++ b/addons/explosives/functions/fnc_cancelPlacement.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Cancels explosives placement. diff --git a/addons/explosives/functions/fnc_checkDetonateHandlers.sqf b/addons/explosives/functions/fnc_checkDetonateHandlers.sqf new file mode 100644 index 0000000000..f056db7800 --- /dev/null +++ b/addons/explosives/functions/fnc_checkDetonateHandlers.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, Whigital + * Check if there is a handler blocking detonation + * + * Arguments: + * 0: Unit + * 1: Max range (-1 to ignore) + * 2: Explosive + * 3: Fuse time + * 4: Trigger Item Classname + * + * Return Value: + * Detonation Allowed + * + * Example: + * [player, -1, Explosive, 1, "ACE_Cellphone"] call ACE_Explosives_fnc_checkDetonateHandlers; + * + * Public: No + */ + +params ["_unit", "_range", "_explosive", "_fuseTime", ["_triggerClassname", "#unknown", [""]]]; +TRACE_5("checkDetonateHandlers",_unit,_range,_explosive,_fuseTime,_triggerClassname); + +private _detonationAllowed = true; + +{ + // Pass [Unit, MaxRange , Explosive , FuzeTime , TriggerItem ] + private _handlerResult = [_unit, _range, _explosive, _fuseTime, _triggerClassname] call _x; + + if (_handlerResult isEqualTo false) then { + TRACE_1("Handler Blocking",_forEachIndex); + _detonationAllowed = false; + break; + }; +} forEach GVAR(detonationHandlers); + +_detonationAllowed diff --git a/addons/explosives/functions/fnc_connectExplosive.sqf b/addons/explosives/functions/fnc_connectExplosive.sqf index 964966f224..df52ee8fad 100644 --- a/addons/explosives/functions/fnc_connectExplosive.sqf +++ b/addons/explosives/functions/fnc_connectExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Add preplaced explosives to a unit's detonator. diff --git a/addons/explosives/functions/fnc_cycleActiveTrigger.sqf b/addons/explosives/functions/fnc_cycleActiveTrigger.sqf new file mode 100644 index 0000000000..e5226c6165 --- /dev/null +++ b/addons/explosives/functions/fnc_cycleActiveTrigger.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: mrschick + * Cycles the "Active Trigger" of a unit and shows a CBA Hint that displays the new Active Trigger. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [ACE_player] call ace_explosives_fnc_cycleActiveTrigger; + * + * Public: No + */ + +params ["_unit"]; +TRACE_1("params",_unit); + +private _detonators = _unit call FUNC(getDetonators); + +// Remove ACE_Cellphone from list, as it should never be the active trigger due to having its own keybind +_detonators deleteAt (_detonators findIf {_x == "ACE_Cellphone"}); + +// Reset Active Trigger if none available +if (_detonators isEqualTo []) exitWith { + GVAR(activeTrigger) = ""; +}; + +private _activeTrigger = GVAR(activeTrigger); +private _index = _detonators findIf {_x == _activeTrigger}; +private _count = count _detonators; + +if (_activeTrigger != "" && {_index != -1} && {_count > 1}) then { + // If active trigger is set and among current detonators, switch to the next one + if (_index < _count - 1) then { + _index = _index + 1; + } else { + _index = 0; + }; + _activeTrigger = _detonators select _index; +} else { + // Assign first detonator in list as the active one + _activeTrigger = _detonators select 0; +}; + +GVAR(activeTrigger) = _activeTrigger; +private _triggerConfig = configFile >> "CfgWeapons" >> _activeTrigger; +private _triggerName = getText (_triggerConfig >> "displayName"); +private _triggerIcon = getText (_triggerConfig >> "picture"); + +[format ["%1: %2", LLSTRING(ActiveTrigger), _triggerName], _triggerIcon] call EFUNC(common,displayTextPicture); diff --git a/addons/explosives/functions/fnc_defuseExplosive.sqf b/addons/explosives/functions/fnc_defuseExplosive.sqf index 24f74a580e..049fff8846 100644 --- a/addons/explosives/functions/fnc_defuseExplosive.sqf +++ b/addons/explosives/functions/fnc_defuseExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Causes the unit to defuse the passed explosive. diff --git a/addons/explosives/functions/fnc_detonateExplosive.sqf b/addons/explosives/functions/fnc_detonateExplosive.sqf index 8edc83f0ff..5e276745b5 100644 --- a/addons/explosives/functions/fnc_detonateExplosive.sqf +++ b/addons/explosives/functions/fnc_detonateExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Causes the unit to detonate the passed explosive. @@ -7,8 +7,8 @@ * 0: Unit * 1: Max range (-1 to ignore) * 2: Explosive - * 0: Explosive - * 1: Fuse time + * - 0: Explosive + * - 1: Fuse time * 3: Trigger Item Classname * * Return Value: @@ -28,12 +28,8 @@ private _ignoreRange = (_range == -1); if (!_ignoreRange && {(_unit distance (_item select 0)) > _range}) exitWith {TRACE_1("out of range",_range); false}; private _result = true; -{ - // Pass [Unit, MaxRange , Explosive , FuzeTime , TriggerItem ] - private _handlerResult = [_unit, _range, _item select 0, _item select 1, _triggerClassname] call _x; - if (_handlerResult isEqualTo false) then {TRACE_1("Handler Failed",_forEachIndex); _result = false}; -} forEach GVAR(detonationHandlers); -if (!_result) exitWith {false}; + +if !([_unit, _range, _item select 0, _item select 1, _triggerClassname] call FUNC(checkDetonateHandlers)) exitWith {false}; if (getNumber (ConfigFile >> "CfgAmmo" >> typeOf (_item select 0) >> "TriggerWhenDestroyed") == 0) then { private _previousExp = _item select 0; diff --git a/addons/explosives/functions/fnc_detonateExplosiveAll.sqf b/addons/explosives/functions/fnc_detonateExplosiveAll.sqf index ec1f1e661a..356d4c4e6e 100644 --- a/addons/explosives/functions/fnc_detonateExplosiveAll.sqf +++ b/addons/explosives/functions/fnc_detonateExplosiveAll.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Causes the unit to detonate all passed explosives. @@ -7,8 +7,8 @@ * 0: Unit * 1: Range (-1 to ignore) * 2: Explosives to detonate - * 0: Explosive - * 1: Fuse time + * - 0: Explosive + * - 1: Fuse time * 3: Trigger Item Classname * * Return Value: diff --git a/addons/explosives/functions/fnc_dialPhone.sqf b/addons/explosives/functions/fnc_dialPhone.sqf index c7b5848e52..f0609e2b0d 100644 --- a/addons/explosives/functions/fnc_dialPhone.sqf +++ b/addons/explosives/functions/fnc_dialPhone.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Dials the number passed and detonates the explosive. @@ -30,14 +30,20 @@ for "_i" from 1 to _ran do { }; if (_unit == ace_player) then { ctrlSetText [1400,"Calling"]; - [FUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); + [LINKFUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); } else { private _explosive = [_code] call FUNC(getSpeedDialExplosive); if ((count _explosive) > 0) then { [{ - playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)),objNull, false, getPosASL (_this select 1),3.16228,1,75]; - (_this select 0) setVariable [QGVAR(Dialing), false, true]; - }, [_unit,_explosive select 0], 0.25 * (count _arr - 4)] call CBA_fnc_waitAndExecute; - [_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2), "ACE_Cellphone"] call FUNC(startTimer); + params ["_unit", "_item"]; + + if ([_unit, -1, (_item # 0), (_item # 2), "ACE_Cellphone"] call FUNC(checkDetonateHandlers)) then { + playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)), objNull, false, (getPosASL (_item # 0)), 3.16228, 1, 75]; + }; + + _unit setVariable [QGVAR(Dialing), false, true]; + }, [_unit, _explosive], 0.25 * (count _arr - 4)] call CBA_fnc_waitAndExecute; + + [_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2), "ACE_Cellphone", _unit] call FUNC(startTimer); }; }; diff --git a/addons/explosives/functions/fnc_dialingPhone.sqf b/addons/explosives/functions/fnc_dialingPhone.sqf index 9fd1184150..40b7bb21c5 100644 --- a/addons/explosives/functions/fnc_dialingPhone.sqf +++ b/addons/explosives/functions/fnc_dialingPhone.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Performs the dial tones and detonation of explosive. @@ -13,7 +13,7 @@ * None * * Example: - * [FUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); + * [ace_explosives_fnc_dialingPhone, 0.25, [_unit,4,_arr,_code]] call CBA_fnc_addPerFrameHandler; * * Public: No */ @@ -22,7 +22,8 @@ params ["_args", "_pfID"]; _args params ["_unit", "_i", "_arr", "_code"]; if ((_i mod 4) == 0) then { - playSound3D [QUOTE(PATHTO_R(Data\Audio\DialTone.wss)), objNull, false, (_unit modelToWorldVisual [0,0.2,2]), 15,1,2.5]; + private _pos = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand"); + playSound3D [QUOTE(PATHTO_R(Data\Audio\DialTone.wss)), objNull, false, _pos, 5, 1, 5]; }; ctrlSetText [1400,format["Calling%1",_arr select (_i - 4)]]; @@ -38,9 +39,14 @@ if (_i >= (count _arr + 2)) then { ctrlSetText [1400,"Call Ended!"]; }; }; + if (_i == (count _arr)) then { - if ((count _explosive) > 0) then { - playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)),objNull, false, getPosASL (_explosive select 0),3.16228,1,75]; + if ( + ((count _explosive) > 0) && + {[_unit, -1, (_explosive # 0), (_explosive # 2), "ACE_Cellphone"] call FUNC(checkDetonateHandlers)} + ) then { + playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)), objNull, false, (getPosASL (_explosive # 0)), 3.16228, 1, 75]; }; }; + _args set [1, _i + 1]; diff --git a/addons/explosives/functions/fnc_getDetonators.sqf b/addons/explosives/functions/fnc_getDetonators.sqf index 3c4d3085ce..de1f711e86 100644 --- a/addons/explosives/functions/fnc_getDetonators.sqf +++ b/addons/explosives/functions/fnc_getDetonators.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, mharis001 * Returns all detonators the given unit has. diff --git a/addons/explosives/functions/fnc_getPlacedExplosives.sqf b/addons/explosives/functions/fnc_getPlacedExplosives.sqf index 8b1135717d..867bae2275 100644 --- a/addons/explosives/functions/fnc_getPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_getPlacedExplosives.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Gets all placed explosives by unit, optionally filtered by specific trigger type. diff --git a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf index 84e2ab6ad8..0f4e5d923f 100644 --- a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf +++ b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Gets the explosive from the speed dial entry. @@ -24,7 +24,6 @@ private _explosive = []; if ((_x select 1) == _code) exitWith { _explosive = _x; }; - false -} count GVAR(CellphoneIEDs); +} forEach GVAR(CellphoneIEDs); _explosive diff --git a/addons/explosives/functions/fnc_handleScrollWheel.sqf b/addons/explosives/functions/fnc_handleScrollWheel.sqf index 674769a496..019fb3c962 100644 --- a/addons/explosives/functions/fnc_handleScrollWheel.sqf +++ b/addons/explosives/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Handles rotating of Explosives diff --git a/addons/explosives/functions/fnc_hasExplosives.sqf b/addons/explosives/functions/fnc_hasExplosives.sqf index 0c824a87b2..0121eb515d 100644 --- a/addons/explosives/functions/fnc_hasExplosives.sqf +++ b/addons/explosives/functions/fnc_hasExplosives.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, mharis001 * Checks if given unit has any placeable explosives on them. diff --git a/addons/explosives/functions/fnc_hasPlacedExplosives.sqf b/addons/explosives/functions/fnc_hasPlacedExplosives.sqf index 3bb3f03340..c697afb371 100644 --- a/addons/explosives/functions/fnc_hasPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_hasPlacedExplosives.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Whether the passed unit has placed any explosives or has a clacker that was used when explosives were placed. diff --git a/addons/explosives/functions/fnc_interactEH.sqf b/addons/explosives/functions/fnc_interactEH.sqf index 59ddaff432..194dc7414b 100644 --- a/addons/explosives/functions/fnc_interactEH.sqf +++ b/addons/explosives/functions/fnc_interactEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, mharis001 * Dynamically adds "Defuse" actions to nearby mines when interact_menu is opened. @@ -25,7 +25,7 @@ TRACE_1("Explosives interactEH",_interactionType); if ( _interactionType != 0 || {vehicle ACE_player != ACE_player} - || {!("ACE_DefusalKit" in (ACE_player call EFUNC(common,uniqueItems)))} + || {(ACE_player call EFUNC(common,uniqueItems)) findAny GVAR(defusalKits) == -1} ) exitWith {}; [{ @@ -47,7 +47,7 @@ if ( if (_playerPos distanceSqr _setPosition > 25) then { private _cfgAmmo = configFile >> "CfgAmmo"; { - if (_x distanceSqr _player < 225 && {!(_x in _minesHelped)} && {!(getModelInfo _x select 0 isEqualTo "empty.p3d")}) then { + if (_x distanceSqr _player < 225 && {!(_x in _minesHelped)} && {!(_x in GVAR(excludedMines))} && {getModelInfo _x select 0 isNotEqualTo "empty.p3d"}) then { private _config = _cfgAmmo >> typeOf _x; private _size = getNumber (_config >> QGVAR(size)); private _defuseClass = ["ACE_DefuseObject", "ACE_DefuseObject_Large"] select (_size == 1); diff --git a/addons/explosives/functions/fnc_isAllowedDefuse.sqf b/addons/explosives/functions/fnc_isAllowedDefuse.sqf new file mode 100644 index 0000000000..7fa24cf077 --- /dev/null +++ b/addons/explosives/functions/fnc_isAllowedDefuse.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: Walthzer + * Check if a mine is allowed to recieve a dynamic defuse action. + * + * Arguments: + * 0: Mine + * + * Return Value: + * Allowed + * + * Example: + * [_mine] call ace_explosives_fnc_isAllowedDefuse + * + * Public: Yes + */ + +params [["_mine", objNull, [objNull]]]; +TRACE_1("params",_mine); + +!(_mine in GVAR(excludedMines)) diff --git a/addons/explosives/functions/fnc_module.sqf b/addons/explosives/functions/fnc_module.sqf index 6fa61b401a..c1a9273e61 100644 --- a/addons/explosives/functions/fnc_module.sqf +++ b/addons/explosives/functions/fnc_module.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Initialises the explosives module diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 74d99d2faa..5e7b8797e1 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Detonates all attached deadman's switched triggered explosives. @@ -37,7 +37,7 @@ TRACE_2("placed",_deadman,_range); //Handle deadman connected to explosive in inventory private _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - if (!(_connectedInventoryExplosive in (magazines _unit))) exitWith {}; + if !(_connectedInventoryExplosive in (magazines _unit)) exitWith {}; //Remove mag and reset variable _unit removeMagazine _connectedInventoryExplosive; diff --git a/addons/explosives/functions/fnc_onInventoryChanged.sqf b/addons/explosives/functions/fnc_onInventoryChanged.sqf index 874ae3394f..7cf01c2a14 100644 --- a/addons/explosives/functions/fnc_onInventoryChanged.sqf +++ b/addons/explosives/functions/fnc_onInventoryChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * When a take/put event handler fires and a detonator is changed hands. diff --git a/addons/explosives/functions/fnc_openTimerUI.sqf b/addons/explosives/functions/fnc_openTimerUI.sqf index b7715d08a2..0a490a096d 100644 --- a/addons/explosives/functions/fnc_openTimerUI.sqf +++ b/addons/explosives/functions/fnc_openTimerUI.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Opens the Explosive Timer UI for given explosive. @@ -15,9 +15,6 @@ * Public: No */ -#define TIMER_VALUE_MIN_CUSTOM (missionNamespace getVariable [QGVAR(customTimerMin), TIMER_VALUE_MIN]) -#define TIMER_VALUE_MAX_CUSTOM (missionNamespace getVariable [QGVAR(customTimerMax), TIMER_VALUE_MAX]) - params ["_explosive"]; TRACE_1("Opening timer UI",_explosive); @@ -26,8 +23,8 @@ private _display = uiNamespace getVariable [QGVAR(timerDisplay), displayNull]; // Update slider speed to 1s (_display displayCtrl IDC_TIMER_SLIDER) sliderSetSpeed [1, 1]; -(_display displayCtrl IDC_TIMER_SLIDER) sliderSetRange [TIMER_VALUE_MIN_CUSTOM, TIMER_VALUE_MAX_CUSTOM]; -(_display displayCtrl IDC_TIMER_SLIDER) sliderSetPosition (TIMER_VALUE_DEFAULT max TIMER_VALUE_MIN_CUSTOM min TIMER_VALUE_MAX_CUSTOM); +(_display displayCtrl IDC_TIMER_SLIDER) sliderSetRange [GVAR(customTimerMin), GVAR(customTimerMax)]; +(_display displayCtrl IDC_TIMER_SLIDER) sliderSetPosition (GVAR(customTimerDefault) max GVAR(customTimerMin) min GVAR(customTimerMax)); // Add confirm button action @@ -58,7 +55,7 @@ _display displayAddEventHandler ["MouseZChanged", { if (cba_events_control) then {_change = _change * 10}; private _slider = _display displayCtrl IDC_TIMER_SLIDER; - private _value = (sliderPosition _slider + _change) max TIMER_VALUE_MIN_CUSTOM min TIMER_VALUE_MAX_CUSTOM; + private _value = (sliderPosition _slider + _change) max GVAR(customTimerMin) min GVAR(customTimerMax); _slider sliderSetPosition _value; }]; diff --git a/addons/explosives/functions/fnc_placeExplosive.sqf b/addons/explosives/functions/fnc_placeExplosive.sqf index df8f3ab89c..ec19a6f6fd 100644 --- a/addons/explosives/functions/fnc_placeExplosive.sqf +++ b/addons/explosives/functions/fnc_placeExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Places an explosive at the requested position. diff --git a/addons/explosives/functions/fnc_removeFromSpeedDial.sqf b/addons/explosives/functions/fnc_removeFromSpeedDial.sqf index 998bc492d0..39319bc3c5 100644 --- a/addons/explosives/functions/fnc_removeFromSpeedDial.sqf +++ b/addons/explosives/functions/fnc_removeFromSpeedDial.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes the specified speed dial from unit's speed dial. diff --git a/addons/explosives/functions/fnc_scriptedExplosive.sqf b/addons/explosives/functions/fnc_scriptedExplosive.sqf index 6b4aedd6a3..d070517079 100644 --- a/addons/explosives/functions/fnc_scriptedExplosive.sqf +++ b/addons/explosives/functions/fnc_scriptedExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Detonate explosives via script, for use in triggers or mission scripts to detonate editor-placed explosives. diff --git a/addons/explosives/functions/fnc_selectTrigger.sqf b/addons/explosives/functions/fnc_selectTrigger.sqf index 549754aab2..7c7d5e58d4 100644 --- a/addons/explosives/functions/fnc_selectTrigger.sqf +++ b/addons/explosives/functions/fnc_selectTrigger.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Selects a trigger for an explosive. @@ -22,6 +22,15 @@ TRACE_3("params",_explosive,_magazine,_trigger); private _config = ConfigFile >> "ACE_Triggers" >> _trigger; +// Make selected trigger the active one (for keybind) if it's the first to be connected +private _activeTrigger = GVAR(activeTrigger); +if ( + _activeTrigger == "" && + {(["Command", "MK16_Transmitter", "DeadManSwitch"] findIf {_x == _trigger}) != -1} +) then { + GVAR(activeTrigger) = getArray (_config >> "requires") select 0; +}; + // If the onSetup function returns true, it is handled elsewhere if (isText(_config >> "onSetup") && {[_explosive,_magazine] call compile getText (_config >> "onSetup")}) exitWith { TRACE_2("onSetup returned true",_explosive,_trigger); diff --git a/addons/explosives/functions/fnc_setPosition.sqf b/addons/explosives/functions/fnc_setPosition.sqf index 7d4235b8d2..a97eb9f462 100644 --- a/addons/explosives/functions/fnc_setPosition.sqf +++ b/addons/explosives/functions/fnc_setPosition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets the Dir and pitch of passed object diff --git a/addons/explosives/functions/fnc_setSpeedDial.sqf b/addons/explosives/functions/fnc_setSpeedDial.sqf index 7d836015a4..be50753b09 100644 --- a/addons/explosives/functions/fnc_setSpeedDial.sqf +++ b/addons/explosives/functions/fnc_setSpeedDial.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets the speed dial for the UI. diff --git a/addons/explosives/functions/fnc_setupExplosive.sqf b/addons/explosives/functions/fnc_setupExplosive.sqf index a85580f672..918bbb0c33 100644 --- a/addons/explosives/functions/fnc_setupExplosive.sqf +++ b/addons/explosives/functions/fnc_setupExplosive.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Starts the setup process for the passed explosive. Player only. @@ -24,7 +24,7 @@ params ["_vehicle", "_unit", "_magClassname"]; TRACE_3("params",_vehicle,_unit,_magClassname); //Get setup object vehicle and model: -private _setupObjectClass = getText(ConfigFile >> "CfgMagazines" >> _magClassname >> QGVAR(SetupObject)); +private _setupObjectClass = getText (configFile >> "CfgMagazines" >> _magClassname >> QGVAR(SetupObject)); if (!isClass (configFile >> "CfgVehicles" >> _setupObjectClass)) exitWith {ERROR("Bad Vehicle");}; private _p3dModel = getText (configFile >> "CfgVehicles" >> _setupObjectClass >> "model"); if (_p3dModel == "") exitWith {ERROR("No Model");}; //"" - will crash game! @@ -80,7 +80,7 @@ GVAR(TweakedAngle) = 0; #ifdef DEBUG_MODE_FULL drawLine3d [(eyePos _unit) call EFUNC(common,ASLToPosition), (_testPos) call EFUNC(common,ASLToPosition), [1,0,0,1]]; #endif - if (lineIntersects [eyePos _unit, _testPos, _unit]) exitWith {_return = false;}; + if ((lineIntersectsSurfaces [eyePos _unit, _testPos, _unit]) isNotEqualTo []) exitWith {_return = false;}; } forEach [[0,0], [-1,-1], [1,-1], [-1,1], [1,1]]; _return }; @@ -94,8 +94,8 @@ GVAR(TweakedAngle) = 0; private _testBase = _basePosASL vectorAdd _lookDirVector; { private _testPos = _testBase vectorAdd [0.1 * (_x select 0) * (cos _cameraAngle), 0.1 * (_x select 0) * (sin _cameraAngle), 0.1 * (_x select 1)]; - private _intersectsWith = lineIntersectsWith [eyePos _unit, _testPos, _unit]; - if (count _intersectsWith == 1) exitWith {_attachVehicle = (_intersectsWith select 0);}; + private _intersectObject = ((lineIntersectsSurfaces [eyePos _unit, _testPos, _unit]) param [0, objNull]) param [3, objNull]; + if (_intersectObject isNotEqualTo objNull) exitWith {_attachVehicle = _intersectObject}; } forEach [[0,0], [-1,-1], [1,-1], [-1,1], [1,1]]; if ((!isNull _attachVehicle) && {[PLACE_RANGE_MIN] call _testPositionIsValid} && {(_attachVehicle isKindOf "Car") || {_attachVehicle isKindOf "Tank"} || {_attachVehicle isKindOf "Air"} || {_attachVehicle isKindOf "Ship"}}) then { @@ -161,7 +161,7 @@ GVAR(TweakedAngle) = 0; private _placeAngle = 0; private _expSetupVehicle = _setupObjectClass createVehicle (_virtualPosASL call EFUNC(common,ASLToPosition)); - TRACE_1("Planting Mass", (getMass _expSetupVehicle)); + TRACE_1("Planting Mass",(getMass _expSetupVehicle)); //If the object is too heavy, it can kill a player if it colides if ((getMass _expSetupVehicle) > 5) then {_expSetupVehicle setMass 5;}; @@ -187,6 +187,7 @@ GVAR(TweakedAngle) = 0; _unit setVariable [QGVAR(PlantingExplosive), true]; [{_this setVariable [QGVAR(PlantingExplosive), false]}, _unit, 1.5] call CBA_fnc_waitAndExecute; + [QGVAR(setup), [_expSetupVehicle, _magClassname, _unit]] call CBA_fnc_globalEvent; }; } else { private _screenPos = worldToScreen (_virtualPosASL call EFUNC(common,ASLToPosition)); diff --git a/addons/explosives/functions/fnc_spawnFlare.sqf b/addons/explosives/functions/fnc_spawnFlare.sqf index 5c6038c2e2..7730ed39a9 100644 --- a/addons/explosives/functions/fnc_spawnFlare.sqf +++ b/addons/explosives/functions/fnc_spawnFlare.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Spawns a flare on the ground for tripflare trigger diff --git a/addons/explosives/functions/fnc_startDefuse.sqf b/addons/explosives/functions/fnc_startDefuse.sqf index 96b3b3eac2..e023592547 100644 --- a/addons/explosives/functions/fnc_startDefuse.sqf +++ b/addons/explosives/functions/fnc_startDefuse.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Starts defusing an explosive diff --git a/addons/explosives/functions/fnc_startTimer.sqf b/addons/explosives/functions/fnc_startTimer.sqf index 484171ec6e..a4829a0ebd 100644 --- a/addons/explosives/functions/fnc_startTimer.sqf +++ b/addons/explosives/functions/fnc_startTimer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Starts a timer for an explosive. @@ -7,6 +7,7 @@ * 0: Explosive * 1: Time till detonate * 2: Trigger classname (default: "#timer") + * 3: Unit * * Return Value: * None @@ -17,13 +18,13 @@ * Public: Yes */ -params ["_explosive", "_delay", ["_trigger", "#timer", [""]]]; -TRACE_3("Starting timer",_explosive,_delay,_trigger); +params ["_explosive", "_delay", ["_trigger", "#timer", [""]], ["_unit", objNull, [objNull]]]; +TRACE_4("Starting timer",_explosive,_delay,_trigger,_unit); [{ - params ["_explosive", "_trigger"]; + params ["_explosive", "_trigger", "_unit"]; TRACE_1("Explosive detonating from timer",_explosive); if (!isNull _explosive) then { - [_explosive, -1, [_explosive, 0], _trigger] call FUNC(detonateExplosive); + [_unit, -1, [_explosive, 0], _trigger] call FUNC(detonateExplosive); }; -}, [_explosive, _trigger], _delay] call CBA_fnc_waitAndExecute; +}, [_explosive, _trigger, _unit], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/explosives/functions/fnc_triggerType.sqf b/addons/explosives/functions/fnc_triggerType.sqf index 6bcbf775d3..0fba459491 100644 --- a/addons/explosives/functions/fnc_triggerType.sqf +++ b/addons/explosives/functions/fnc_triggerType.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Gets the types of triggers associated with the explosive diff --git a/addons/explosives/functions/script_component.hpp b/addons/explosives/functions/script_component.hpp deleted file mode 100644 index 438330c587..0000000000 --- a/addons/explosives/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\explosives\script_component.hpp" diff --git a/addons/explosives/initKeybinds.inc.sqf b/addons/explosives/initKeybinds.inc.sqf new file mode 100644 index 0000000000..c01d39795c --- /dev/null +++ b/addons/explosives/initKeybinds.inc.sqf @@ -0,0 +1,50 @@ +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +["ACE3 Equipment", QGVAR(openCellphone), LLSTRING(cellphone_displayName), { + if ( + !([ACE_player, "ACE_Cellphone"] call EFUNC(common,hasItem)) || + !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) + ) exitWith {}; + + closeDialog 0; + createDialog "Rsc_ACE_PhoneInterface"; + + true +}] call CBA_fnc_addKeybind; // Unbound + +["ACE3 Equipment", QGVAR(detonateActiveClacker), LLSTRING(DetonateAllOnActive), { + // Prevent use of keybind while surrendering or captive + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; + + private _detonator = GVAR(activeTrigger); + if (_detonator == "" || !(_detonator in ([ACE_player] call FUNC(getDetonators)))) exitWith {}; + + // When using a Dead Man's Switch, skip all other logic and just call fnc_onIncapacitated, since it already handles everything that is required to detonate all connected explosives + if (_detonator == "ACE_DeadManSwitch") exitWith { + [ACE_player] call FUNC(onIncapacitated); + }; + + private _range = getNumber (configFile >> "CfgWeapons" >> _detonator >> QGVAR(Range)); + + private _explosivesList = []; + { + if (!isNull (_x select 0)) then { + private _required = getArray (configFile >> "ACE_Triggers" >> _x select 4 >> "requires"); + if (_detonator in _required) then { + _explosivesList pushBack _x; + }; + }; + } forEach ([ACE_player] call FUNC(getPlacedExplosives)); + + [ACE_player, _range, _explosivesList, _detonator] call FUNC(detonateExplosiveAll); + + true +}] call CBA_fnc_addKeybind; // Unbound + +["ACE3 Equipment", QGVAR(cycleActiveClacker), LLSTRING(CycleActiveTrigger), { + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; + + [ACE_player] call FUNC(cycleActiveTrigger); + + true +}] call CBA_fnc_addKeybind; // Unbound diff --git a/addons/explosives/initSettings.inc.sqf b/addons/explosives/initSettings.inc.sqf new file mode 100644 index 0000000000..bdbd488550 --- /dev/null +++ b/addons/explosives/initSettings.inc.sqf @@ -0,0 +1,56 @@ +private _categoryStr = format ["ACE %1", LLSTRING(Menu)]; + +[ + QGVAR(requireSpecialist), + "CHECKBOX", + [LLSTRING(RequireSpecialist_DisplayName),LLSTRING(RequireSpecialist_Description)], + _categoryStr, + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(punishNonSpecialists), + "CHECKBOX", + [LLSTRING(PunishNonSpecialists_DisplayName),LLSTRING(PunishNonSpecialists_Description)], + _categoryStr, + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(explodeOnDefuse), + "CHECKBOX", + [LLSTRING(ExplodeOnDefuse_DisplayName),LLSTRING(ExplodeOnDefuse_Description)], + _categoryStr, + true, + true +] call CBA_fnc_addSetting; + +// Variable names to preserve https://github.com/acemod/ACE3/pull/6882 +[ + QGVAR(customTimerMin), + "TIME", + [LLSTRING(TimerMin_DisplayName), LLSTRING(TimerMin_Description)], + [_categoryStr, LLSTRING(ExplosiveTimer)], + [0, 5999, TIMER_VALUE_MIN], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(customTimerMax), + "TIME", + [LLSTRING(TimerMax_DisplayName), LLSTRING(TimerMax_Description)], + [_categoryStr, LLSTRING(ExplosiveTimer)], + [0, 5999, TIMER_VALUE_MAX], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(customTimerDefault), + "TIME", + [LLSTRING(TimerDefault_DisplayName), LLSTRING(TimerDefault_Description)], + [_categoryStr, LLSTRING(ExplosiveTimer)], + [0, 5999, TIMER_VALUE_DEFAULT], + false +] call CBA_fnc_addSetting; diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 810d74bf92..168a830254 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -16,6 +16,7 @@ 폭발물 炸药 炸藥 + Patlayıcılar Place @@ -32,6 +33,7 @@ 설치 放置 放置 + Yerleştir Detonate @@ -44,10 +46,11 @@ Robbantás Detonar Подрыв - 点火 + 起爆 폭파 引爆 引爆 + Patlat Detonate All @@ -59,17 +62,58 @@ Detona Tutti Tout détoner Detonar Tudo - すべて点火 + 全て起爆 모두 폭파 引爆全部 引爆全部 + Hepsini Patlat + + + Detonate All on Active Clacker + Alle auf Standardzünder zünden + Detona Tutti sul Detonatore Attivo + Подрыв всех на активном детонаторе + 選択した点火装置を全て起爆 + 활성화된 격발기의 모든 것을 폭파 + Détoner tout sur le détonateur actif + Detonar Todos al Activar el detonador + + + Set Active Clacker + Als Standardzünder wählen + Imposta Detonatore Attivo + Установить активный детонатор + この点火装置を選択 + 격발기 활성 설정 + Définir le détonateur actif + Establecer el Detonador Activo + + + Cycle Active Clacker + Standardzünder wechseln + Cambia Detonatore Attivo + Цикл активного детонатора + 点火装置を切り替え + 격발기 활성 전환 + Modifier le détonateur actif + Ciclar el Detonador Activo + + + Active Clacker + Standardzünder + Detonatore Attivo + Активный детонатор + 選択中の点火装置 + 격발기 활성 + Détonateur actif + Activar Detonador Explosive code: %1 Sprengstoffcode: %1 Código del explosivo: %1 Kod ładunku: %1 - Code de l'explosif: %1 + Code de l'explosif : %1 Kód výbušniny: %1 Robbanóanyag kódja: %1 Código do explosivo: %1 @@ -77,8 +121,9 @@ Codice esplosivo: %1 爆破コード: %1 폭파 코드: %1 - 炸药代码: %1 - 炸藥代碼: %1 + 炸药代码:%1 + 炸藥代號: %1 + Patlayıcı Kodu: %1 Place @@ -95,6 +140,7 @@ 설치 放置 放置 + Yerleştir Attach @@ -111,6 +157,7 @@ 부착 连接 連接 + Bağla Blocked @@ -126,6 +173,7 @@ 막힘 断开 斷開 + Bloke Edilmiş Cancel @@ -142,6 +190,7 @@ 취소 取消 取消 + Iptal Rotate @@ -158,6 +207,7 @@ 회전 旋转 旋轉 + Döndür Turn On Thor III @@ -174,6 +224,7 @@ Thor III 켜기 开启索尔三型 開啟索爾三型 + Thor III ü aç Turn Off Thor III @@ -190,6 +241,7 @@ Thor III 끄기 关闭索尔三型 關閉索爾三型 + Thor III ü kapat Cellphone @@ -206,22 +258,24 @@ 휴대전화 手机 手機 + Cep Telefonu Used to remotely trigger explosives Wird benutzt um Sprengstoffe fernzuzünden Usado para detonar remotamente explosivos Używany do zdalnego detonowania ładunków wybuchowych - Utilisé pour déclencher des explosifs à distance + Utilisé pour déclencher des explosifs à distance. Používaný ke vzdálenému odpalování výbušnin - Usato per l'attivazione a distanza degli esplosivi + Usato per l'innesco a distanza degli esplosivi Robbanóanyagok távoli robbantásához való Usado para acionar explosivos remotamente Используется для удаленной детонации СВУ 爆発物を遠隔で起爆させるのに使います 원격으로 폭발물을 폭파시킬때 씁니다. - 用于远端引爆炸药 + 用于远程引爆炸药 用於遠端引爆炸藥 + Bombaları uzaktan patlatmak için kullanılır M57 Firing Device @@ -234,26 +288,28 @@ M57 Gyújtóeszköz M57 Dispositivo de Detonação Взрыватель M57 - M57 起爆装置 - M57 격발기 + M57 点火装置 + 격발기 (M57) M57 引爆装置 M57 引爆裝置 + M57 Ateşleme Cihazı Used to remotely trigger explosives Wird benutzt um Sprengstoffe fernzuzünden Usado para detonar remotamente explosivos Używany do zdalnego detonowania ładunków wybuchowych - Utilisé pour déclencher des explosifs à distance + Utilisé pour déclencher des explosifs à distance. Používané ke vzdálenému odpalování výbušnin - Usato per l'attivazione a distanza degli esplosivi + Usato per l'innesco a distanza degli esplosivi Robbanóanyagok távoli robbantásához Usado para acionar explosivos remotamente Используется для удаленной детонации зарядов 爆発物を遠隔で起爆させるのに使います 원격으로 폭발물을 폭파시킬때 씁니다. - 用于远端引爆炸药 + 用于远程引爆炸药 用於遠端引爆炸藥 + Patlayıcıları uzaktan tetiklemek için kullanılır M152 Firing Device @@ -266,10 +322,11 @@ M152 Gyújtóeszköz M152 Dispositivo de Detonação Взрыватель M152 - M152 起爆装置 - M152 격발기 + M152 点火装置 + 격발기 (M152) M152 引爆装置 M152 引爆裝置 + M152 Ateşleme Cihazı M152 RAMS @@ -284,8 +341,9 @@ M152 RAMS M152 RAMS M152 RAMS - M152 远端炸药引爆系统 + M152 远程炸药引爆系统 M152 遠端炸藥引爆系統 + M152 RAMS Defusal Kit @@ -302,31 +360,33 @@ 해체 장비 拆弹工具 拆彈工具 + Imha Kiti Allows defusing of explosives Erlaubt die Entschärfung von Sprengstoffen Permite desactivar explosivos Umożliwia rozbrajanie ładunków wybuchowych - Permet de désamorçer des explosifs + Outils nécessaires au désamorçage des explosifs. Dovoluje zneškodňování výbušnin - Consente la disattivazione degli ordigni esplosivi + Consente il disinnesco degli ordigni esplosivi Robbanóanyagok hatástalanítását teszi lehetővé Permite o desarme de explosivos Позволяет обезвреживать взрывчатку 爆発物を無力化できます 폭발물을 해체할 수 있게 해줍니다 - 可以用来拆除炸弹 + 可以用来拆除爆炸物 可以用來拆除炸彈 + Patlayıcıların etkisiz hale gelmesini sağlar. Add to Speed Dial Zur Schnellauswahl hinzufügen Añadir a marcado rápido Dodaj do szybkiego wybierania - Ajouter à la composition rapide + Ajouter à la numérotation rapide Přidat jako rychlou volbu - Aggiungi alla selezione rapida + Aggiungi alle chiamate rapide Hozzáadás a gyorstárcsázóhoz Adicionar à ligação rápida Добавить в быстрый вызов @@ -334,6 +394,7 @@ 단축키에 지정 增加到快速拨号 增加到快速撥號 + Hızlı Aramaya Ekle Clear @@ -350,6 +411,7 @@ 삭제 清除 清除 + Temiz Dial @@ -358,7 +420,7 @@ Wybierz numer Composer Vytočit - Composizione numero + Componi numero Tárcsázás Discar Hабрать @@ -366,6 +428,7 @@ 다이얼 拨号 撥號 + Numarayı Çevir Up @@ -374,7 +437,7 @@ W górę Haut Nahoru - Sopra + Su Fel Cima Вызов @@ -382,6 +445,7 @@ + Yukarı Down @@ -390,7 +454,7 @@ W dół Bas Dolu - Sotto + Giù Le Baixo Сброс @@ -398,6 +462,7 @@ 아래 + Aşağı Cancel @@ -414,6 +479,7 @@ 취소 取消 取消 + Iptal Detonate Menu @@ -428,8 +494,9 @@ Меню подрыва 点火メニュー 폭파 메뉴 - 引爆选单 + 引爆菜单 引爆選單 + Patlatma Menüsü Place Menu @@ -438,21 +505,22 @@ Menu umieszczania Menu de placement Menu umístění - Menù di collocamento + Menù di piazzamento Elhelyezési menü Menu de posicionamento Меню установки 設置メニュー 설치 메뉴 - 放置选单 + 放置菜单 放置選單 + Yerleştirme Menüsü Defuse Entschärfen Desactivar Rozbrój - Désamorçer + Désamorcer Zneškodnit Disinnesca Hatástalanítás @@ -462,22 +530,24 @@ 해체 拆除 拆除 + Imha Defusing Explosive... Entschärfe Sprengstoff... Desactivando explosivo... Rozbrajanie ładunku... - Désamorçage des explosifs... + Désamorçage de l'explosif... Zneškodňuji Výbušninu... - Esposivo in fase di disattivazione... + Disinnescando l'Esplosivo... Robbanóanyag hatástalanítása... Desarmando Explosivo... Обезвреживание... 爆発物を無力化しています・・・ - 폭발물 해체중... - 炸弹拆除中... + 폭발물 해체 중... + 正在拆除爆炸物... 炸彈拆除中... + Patlayıcı Imha Ediliyor... Timer @@ -486,7 +556,7 @@ Czasomierz Minuteur Časovač - Cronometro + Spoletta a tempo Időzítő Timer Таймер @@ -494,6 +564,7 @@ 타이머 计时器 計時器 + Zamanlayıcı Time: %1m %2s @@ -506,35 +577,37 @@ Idő: %1m %2s Tempo: %1m %2s Время: %1m %2c - 設定時間: %1分 %2秒 + タイマー: %1分 %2秒 시간: %1분 %2초 - 时间: %1分%2秒 + 时间:%1分%2秒 時間: %1分%2秒 + Süre: %1m %2s Set Time Zeit einstellen Configurar tiempo Ustaw czas - Régler le minuteur + Valider la durée Nastavit čas - Modifica il conto alla rovescia + Imposta tempo della spoletta Idő beállítása Configurar Tempo Установить время - 時間を設定 + タイマーを設定 시간 설정 设定时间 設定時間 + Süreyi Ayarla Select a Trigger Wähle einen Zünder Seleccionar un detonador Wybierz zapalnik - Sélectionner une mise à feu + Sélectionner un déclencheur Zvolit detonátor - Seleziona un attivatore + Seleziona la spoletta Gyújtóeszköz kiválasztása Selecionar um Gatilho Выберите детонатор @@ -542,6 +615,7 @@ 작동방식 선택 选择一个触发器 選擇一個觸發器 + Tetikleyici seç Select @@ -558,6 +632,7 @@ 선택 选择 選擇 + Seç Pressure Plate @@ -574,13 +649,14 @@ 압력식 压力盘 壓力盤 + Basınç Plakası Tripwire Linka naciągu Cable trampa Stolperdraht - Fil de détente + Fil piège Nástražný drát Filo a inciampo Botlódrót @@ -590,6 +666,7 @@ 인계철선 绊线 絆線 + Telli tuzak IR Sensor @@ -606,15 +683,16 @@ 적외선 센서 红外线感应器 紅外線感應器 + IR Sensörü No triggers available for %1 Brak dostępnych zapalników dla %1 No hay detonadores disponibles para %1 Keine Auslöser für %1 vorhanden - Pas de détonateur disponible pour %1 + Pas de déclencheur disponible pour %1. Žádný detonátor k dispozici pro %1 - Nessun attivatore disponibile per %1 + Nessuna spoletta disponibile per %1 Nincs elérhető gyújtóeszköz ide: %1 Nenhum gatilho disponível para %1 Нет доступных взрывателей для %1 @@ -622,6 +700,7 @@ %1(을)를 작동할 장치가 없습니다. 没有适合%1的触发器 沒有適合%1的觸發器 + % 1 için tetikleyici yok IR Sensor (Side Attack) @@ -636,7 +715,7 @@ ИК сенсор (детонация вбок) 赤外線感知式 (側面攻撃) 적외선 센서 (측면 공격) - 红外线感应器 (侧边攻击) + 红外线感应器(侧边攻击) 紅外線感應器 (側邊攻擊) @@ -646,13 +725,13 @@ Magnetfeldsensor (Bodenangriff) Capteur magnétique (par le bas) Magnetický Senzor (Výbuch ze spoda) - Sensore Magnetico di Prossimità (attacco inferiore) + Sensore Magnetico di Prossimità (attacco dal basso) Mágneses mező érzékelő (Bottom Attack) Influência magnética (ataque inferior) Магнитный сенсор (детонация вверх) 磁気感知式 (底面攻撃) 자기장 감지센서 (바닥 공격) - 磁性感应器 (底部攻击) + 磁性感应器(底部攻击) 磁性感應器 (底部攻擊) @@ -670,6 +749,7 @@ 격발기에 등록된 폭발물이 없습니다. 触发器上并没有炸药 觸發器上並沒有炸藥 + Tetikte patlayıcı yok. Dead Man's Switch @@ -684,13 +764,13 @@ Detonatore a rilascio 自爆装置 자폭 장치 - 自杀炸弹客引爆器 + 自杀炸弹手引爆器 自殺炸彈客引爆器 Used to remotely trigger explosives when released. Zündet Sprengladungen wenn losgelassen. - Utilisé pour déclencher des explosifs à distance quand relaché. + Utilisé pour déclencher des explosifs à distance quand relâché. Používaný k vzdálenému odpálení, při uvolnění odpálí výbušniny Używany w celu zdalnej detonacji ładunków, kiedy jego operator zostanie zabity. Utilizado para detonar explosivos remotamente al soltarlo. @@ -698,10 +778,11 @@ Usado para detonar remotamente o explosivo quando solto. Используется для дистанционного подрыва, после смерти оператора. Usato per attivare a distanza esplosivi al momento del rilascio - 点火装置から遠隔から起爆したい時に使います。 + 放した時に爆発物を遠隔で起爆させるためのデッドマンスイッチ。 압력이 해제될때 원격으로 폭발시킵니다. - 当放开按钮时, 将会引爆炸弹. + 当放开按钮时,将会引爆炸弹。 當放開按鈕時, 將會引爆炸彈. + Patlayıcıları serbest bırakıldığında uzaktan tetiklemek için kullanılır. Pick up @@ -718,6 +799,7 @@ 줍기 捡起 撿起 + Al Explosive System @@ -734,6 +816,7 @@ 폭발물 시스템 炸药系统 炸藥系統 + Patlayıcı Sistemi Require specialists? @@ -742,14 +825,15 @@ Benötigt Sprengstoffexperten? Vyžadovat specialistu? Requer especialista? - Requiert un spécialiste ? + Spécialiste requis Specialisták igénylése? Требуется специалист? Richiedi specialisti? - 特技兵を必要としますか? + 専門兵特性を必須にするか? 전문가가 필요합니까? - 需要专家? + 需要专家? 需要專家? + Uzmanlara ihtiyaç var mı? Require explosive specialists to disable explosives? Default: No @@ -758,14 +842,15 @@ Benötige Sprengstoffexperte um Sprengladungen zu entschärfen? Standard: Nein Vyžadovat specialistu na zneškodnění výbušniny? Výchozí: Ne Requer especialista em explosivos para desativar explosivos? Padrão: Não - Le désarmoçage d'explosif requiert un spécialiste ? Défaut : non + Seul un spécialiste peut désamorcer des explosifs. Szükséges-e egy specialista a robbanóanyagok hatástalanításához? Alapértelmezett: Nem - Требуется ли специалист по минному делу для обезвреживания взрывчатки? По-умолчанию: Нет - Richiedi specialisti esplosivi per disabilitare esplosivi? Default: No - 爆発物を無効化するには、爆発物の特技兵を必要としますか? 標準: 無効化 + Требуется ли специалист по минному делу для обезвреживания взрывчатки? По умолчанию: Нет + Richiedi specialisti esplosivi per disabilitare esplosivi? Predefinito: No + 爆発物を無効にするために爆発物専門兵の特性を必要としますか? デフォルト: 不要 폭발물을 해제하기 위해서는 전문가가 필요합니까? 기본설정: 아니요 - 需要炸弹专家才能拆除炸弹? 预设: 否 + 需要爆破专业兵才能拆除爆炸物? 预设:否 需要炸彈專家才能拆除炸彈? 預設: 否 + Patlayıcı uzmanlarının patlayıcıları etkisiz hale getirmesini ister misiniz? Varsayılan: Hayır Punish non-specialists? @@ -774,13 +859,13 @@ Bestrafe Nicht-Sprengstoffexperten? Potrestat, pokud není specialista? Punir não especialistas? - Punir les non-spécialistes ? + Pénaliser les non-spécialistes Nem-specialisták büntetése? Штраф не-специалистам? Punisci non-specialisti? - 非特技兵へ足かせを与えますか? - 비-전문가에 불이익을 줍니까? - 折磨非专业人员? + 非専門兵にペナルティを与える? + 비전문가에게 불이익을 줍니까? + 惩罚非专业人士? 折磨非專業人員? @@ -790,13 +875,13 @@ Entschärfungszeit für Nicht-Sprengstoffexperten erhöhen? Standard: Ja Zvýšit čas potřebný k dokončení akce pokud není specialista? Výchozí: Ano Aumentar o tempo necessário para completar ações por não especialistas? Padrão: Sim - Augmenter le temps nécessaire au désarmoçage pour les non-spécialistes ? Défaut : oui + Augmente le temps nécessaire au désamorçage pour les unités non spécialisées. Nem-specialisták esetén több ideig tartson a cselekvés befejezése? Alapértelmezett: Igen - Увеличивать время завершения действий для не-специалистов? По-умолчанию: Нет - Aumenta il tempo richiesto per completare azioni per non-specialisti? Default: Si - 非特技兵へ動作完了までの時間を増加させますか? 標準: 有効化 - 비-전문가가 폭발물을 해제시 더욱 많은 시간을 소요합니까? 기본설정: 예 - 增加非专业人员相关操作的时间? 预设: 是 + Увеличивать время завершения действий для не-специалистов? По умолчанию: Нет + Aumenta il tempo richiesto per completare azioni per non-specialisti? Predefinito: Si + 専門兵以外がアクション完了するのに必要な時間を増加しますか? デフォルト: 有効 + 비전문가가 폭발물을 해제 시 더욱 많은 시간을 소요합니까? 기본설정: 예 + 增加非专业人员相关操作的时间? 预设:是 增加非專業人員相關操作的時間? 預設: 是 @@ -806,13 +891,13 @@ Eksplozja przy rozbrajaniu? Explodovat při zneškodňování? Explotar al desactivar? - Explosion au désamorçage ? + Explosion au désamorçage Robbanás hatástalanításkor? - Взрыв при разминир.? - Fai esplodere quando disarmato? - 解除中に爆発させますか? - 해제시 폭발합니까? - 拆除时引爆? + Взрыв при разминировании? + Detona se disarmati? + 解除中に爆発するか? + 해제 시 폭발합니까? + 拆除时引爆? 拆除時引爆? @@ -822,13 +907,13 @@ Spraw, aby niektóre ładunki wybuchowe eksplodowały przy próbie ich rozbrojenia? Domyślnie:Tak Umožnit u některých výbušnin explozi při pokusu je zneškodnit? Výchozí: Ano ¿Habilitar ciertos explosivos para estallar al desactivar? Por defecto: Sí - Permet à certains explosifs d'exploser au désamorçage ? Défaut : oui + Certains explosifs exploseront durant le désamorçage. Valeur par défaut : activé. Meghatározott robbanóanyagok felrobbanjanak-e hatástalanításkor? Alapértelmezett: Igen - Разрешить определенным взрывным устройствам взрываться при разминировании? По-умолчанию: Да - Abilita alcuni esplosivi per esplosione al disarmo? Default: Si - 特定の爆発物を解除中に爆発させますか? 標準: 有効化 - 특정 폭발물이 해제시 폭발하게 합니까? 기본설정: 예 - 启用后, 某些炸弹会在拆除时引爆? 预设: 是 + Разрешить определенным взрывным устройствам взрываться при разминировании? По умолчанию: Да + Permettere ad alcuni esplosivi di esplodere quando si tenta il disinnesco? Predefinito: Si + 特定の爆発物を解除中に爆発可能にしますか? デフォルト: 有効 + 특정 폭발물이 해제 시 폭발하게 합니까? 기본설정: 예 + 启用后,某些爆炸物会在拆除时引爆? 预设:是 啟用後, 某些炸彈會在拆除時引爆? 預設: 是 @@ -842,141 +927,99 @@ Этот модуль управляет настройками, связанными со взрывными устройствами Este módulo ajusta las configuraciones relacionadas con explosivos. Questo modulo cambia le impostazioni relative agli esplosivi - モジュールを調節し爆発物に設定を反映させます。 + このモジュールは爆発物に関する設定を調整します。 이 모듈은 폭발물에 관한 설정을 수정할 수 있게합니다. 此模块用来调整炸药的相关设定 此模塊用來調整炸藥的相關設定 M6 SLAM Mine (Bottom Attack) - - + Mine M6 SLAM (par le bas) M6-SLAM-Mine (Bodenangriff) - - - - - Mina M6 SLAM (atak od dołu) Mina M6 SLAM (Ataque Inferior) - Mine M6 SLAM (par le bas) - Mina M6 SLAM (base) + Mina M6 SLAM (Da Sotto) M6 SLAM (Útok zespoda) Mina M6 SLAM (Ataque Inferior) Мина M6 SLAM (направлена вверх) M6 SLAM 地雷 (底面攻撃) M6 SLAM 지뢰 (바닥 공격) - M6指向性反装甲地雷 (底部攻击) + M6指向性反装甲地雷(底部攻击) M6指向性反裝甲地雷 (底部攻擊) M6 SLAM Mine (Side Attack) - - + Mine M6 SLAM (de flanc) M6-SLAM-Mine (Seitenangriff) - - - - - Mina M6 SLAM (atak od boku) Mina M6 SLAM (Ataque Lateral) - Mine M6 SLAM (de flanc) - Mina M6 SLAM (Laterale) + Mina M6 SLAM (Dal Lato) M6 SLAM (Útok do strany) Mina M6 SLAM (Ataque Lateral) Мина M6 SLAM (направлена вбок) M6 SLAM 地雷 (側面攻撃) M6 SLAM 지뢰 (측면 공격) - M6指向性反装甲地雷 (侧边攻击) + M6指向性反装甲地雷(侧边攻击) M6指向性反裝甲地雷 (側邊攻擊) Large IED (Urban, Pressure Plate) - - + Grand EEI (urbain, plaque de pression) Große USBV (Stadt, Druckplatte) - - - - - Duży IED (miejski, płyta naciskowa) IED Grande (Urbano, Placa de presión) - Grand EEI (Urbain, plaque de pression) - IED grande (urbano, a pressione) + IED grande (Urbano, a pressione) IED, Velké (Městské, Nášlapné) IED Grande (Urbano, Placa de pressão) Большое СВУ (городское, нажимного действия) 大きな IED (市街地用、圧力感知) - 대형 급조폭발물 (시가지, 압력식) - 大型简易爆炸装置 (地表上, 压力盘) + 급조폭발물 (대형, 시가지, 압력식) + 大型 IED(地表上,压力盘) 大型簡易爆炸裝置 (地表上, 壓力盤) Large IED (Dug-in, Pressure Plate) - - + Grand EEI (enterré, plaque de pression) Große USBV (Eingegraben, Druckplatte) - - - - - Duży IED (zakopany, płyta naciskowa) IED Grande (Enterrado, Placa de presión) - Grand EEI (Enterré, plaque de pression) - IED grande (interrato, a pressione) + IED grande (Interrato, a pressione) IED, Velké (Zakopané, Nášlapné) IED Grande (Enterrado, Placa de pressão) Большое СВУ (закопанное, нажимного действия) 大きな IED (埋め込み型、圧力感知) - 대형 급조폭발물 (묻힘, 압력식) - 大型简易爆炸装置 (地表下, 压力盘) + 급조폭발물 (대형, 묻힘, 압력식) + 大型 IED(地表下,压力盘) 大型簡易爆炸裝置 (地表下, 壓力盤) Small IED (Urban, Pressure Plate) - - + Petit EEI (Urbain, plaque de pression) Kleine USBV (Stadt, Druckplatte) - - - - - Mały IED (miejski, płyta naciskowa) IED Pequeño (Urbano, Placa de presión) - Petit EEI (Urbain, plaque de pression) - IED piccolo (urbano, a pressione) + IED piccolo (Urbano, a pressione) IED, Malé (Městské, Nášlapné) IED Pequeno(Urbano, Placa de pressão) Малое СВУ (городское, нажимного действия) 小さな IED (市街地用、圧力感知) - 소형 급조폭발물 (시가지, 압력식) - 小型简易爆炸装置 (地表上, 压力盘) + 급조폭발물 (소형, 시가지, 압력식) + 小型 IED(地表上,压力盘) 小型簡易爆炸裝置 (地表上, 壓力盤) Small IED (Dug-in, Pressure Plate) - - + Petit EEI (Enterré, plaque de pression) Kleine USBV (Eingegraben, Druckplatte) - - - - - Mały IED (zakopany, płyta naciskowa) IED Pequeño (Enterrado, Placa de presión) - Petit EEI (Enterré, plaque de pression) - IED piccolo (interrato, a pressione) + IED piccolo (Interrato, a pressione) IED, Malé (Zakopané, Nášlapné) IED Pequeno (Enterrado, Placa de pressão) Малое СВУ (закопанное, нажимного действия) 小さな IED (埋め込み型、圧力感知) - 소형 급조폭발물 (묻힘, 압력식) - 小型简易爆炸装置 (地表下, 压力盘) + 급조폭발물 (소형, 묻힘, 압력식) + 小型 IED(地表下,压力盘) 小型簡易爆炸裝置 (地表下, 壓力盤) @@ -988,36 +1031,43 @@ Podłącz do %1 Connecter %1 Csatlakozás %1 - Collega a %1 + Collega a %1 Conectar à %1 %1 へ接続 - %1에 연결중 + %1에 연결 중 连接到%1 連接到%1 + Bağlandı %1 Tripwire Flare Сигнальная растяжка - 仕掛け型照明地雷 + 仕掛け線照明地雷 Flara na linkę Stolperdraht-Leuchtrakete 조명지뢰 - Fusée éclairante avec fil de détente - Cavo d'innesco - 绊线闪光地雷 + Fusée éclairante avec fil piège + Bengala a filo d'inciampo + 绊线信号弹 絆線閃光地雷 + Tripwire (Sinalizador) + Světlice na nástražném drátu + Bengala con cable trampa Type: Tripwire flare - Ignites a non-lethal flare when triggered.<br />Rounds: 1<br />Used on: Ground Тип: Сигнальная растяжка - При срабатывании выпускает несмертельную сигнальную вспышку.<br />Зарядов: 1<br />Используется на: Земле - 種類: 仕掛け型照明地雷 - 発動したとき、非致死性の照明を発炎します。<br />装填数: 1<br />次で使用: 地表 + 種類: 仕掛け線照明地雷 - 発動したとき、非致死性の照明を発炎します。<br />装填数: 1<br />次で使用: 地表 Typ: Flara na linkę - Wystrzeliwuje nieszkodliwą flarę przy nadepnięciu linki.<br/>Pociski: 1<br/>Używane na: ziemia Typ: Stolperdraht-Leuchtrakete - Schießt bei Auslösung eine nicht-tödliche Leuchtrakete ab.<br />Ladungen: 1<br />Benutzt auf: Boden 종류: 조명지뢰 - 작동시 무해한 조명을 사출합니다.<br />장탄수: 1<br />사용처: 지면 - Type : Fusée éclairante avec fil de détente - Allume une fusée éclairante lorsque déclenché. <br />Coups : 1<br />Utilisé sur : le sol - Tipo: Cavo d'innesco - Sfocio un abbaglio non letale quanto attivato. <br />Rimanenti: 1<br />Usato: A terra - 类型: 绊线闪光地雷 - 触发后产生非致命性的强光.<br />发数: 1<br />使用于: 地面 + Type : Fusée éclairante avec fil piège - Allume une fusée éclairante lorsque déclenchée.<br />Coups : 1<br />Utilisé sur : le sol + Tipo: Bengala a cavo d'innesco - Accende un bengala abbagliante non letale quando innescato. <br />Rimanenti: 1<br />Usato: A terra + 类型:绊线信号弹—触发后产生非致命性的强光。<br />发数:1<br />使用于:地面 類型: 絆線閃光地雷 - 觸發後產生非致命性的強光.<br />發數: 1<br />使用於: 地面 + Tipo: Flare de Tripwire - Acende um sinalizador não letal quando acionado.<br/>Usos: 1<br/>Usado em: Chão + Typ: Světlice na nástražném drátu - Zapálí světlici při aktivaci.<br/>Pouze 1 použití<br/>Použít na zem + Tipo: Bengala con cable trampa - Enciende una bengala no letal cuando es activado.<br />Rondas: 1<br />Usado en: Tierra Explosive range @@ -1029,6 +1079,11 @@ Raggio di detonazione Zasięg wybuchu Дальность подрыва + Alcance do explosivo + Dosah exploze + Patlayıcı menzili + Alcance explosivo + 폭발 범위 Explosive Timer @@ -1037,6 +1092,122 @@ 爆発タイマー Czasomierz Wybuchu Таймер взрывчатки + Timer de explosão + Minuteur pour explosifs + 引爆倒數 + 定时爆炸 + Časovač exploze + Patlayıcı Zamanlayıcı + Temporizador de explosivo + 폭발 타이머 + + + Is EOD + Kampfmittelbeseitigung + EODにする + Spécialiste en explosifs + 是EOD + 爆破专家 + è EOD + Je specilista na výbušniny (EOD) + Jest EOD + Сапёр + ¿Es EOD? + 폭발물 처리반 + É EOD + + + Controls whether the unit is an explosive specialist. + Steuert, ob die Einheit ein Sprengstoffspezialist ist. + ユニットが爆発物専門兵であるかどうかを定義します。 + Définit si l'unité est un spécialiste en explosifs. + 控制該單位是否是爆裂物處置專家 + 控制该单位是否是爆破专家 + Controlla se l'unità è uno specialista di esplosivi. + Určuje jestli je jednotka specialista na výbušniny. + Kontroluje, czy jednostka jest specjalistą od materiałów wybuchowych. + Определяет, является ли юнит сапёром. + Controla si la unidad es un especialista en explosivos + 유닛이 폭발물 처리반인지 결정합니다 + Controla se a unidade é um especialista em explosivos. + + + Minimum Time + Мин. время + Durée minimale + タイマーの最短時間 + Tiempo mínimo + Minimalny czas + Minimale Zeit + Tempo Minimo + 最短时间 + 최소 시간 + Tempo Mínimo + + + Maximum Time + Макс. время + Durée maximale + タイマーの最長時間 + Tiempo máximo + Maksymalny czas + Maximale Zeit + Tempo Massimo + 最长时间 + 최대 시간 + Tempo Máximo + + + Default Time + Стандартное время + Durée par défaut + タイマーの標準時間 + Tiempo por defecto + Domyślny czas + Standardmäßige Zeit + Tempo Predefinito + 默认时间 + 기본 시간 + Tempo Padrão + + + Minimum time value (in seconds) for the explosive timer. + Минимальное время до взрыва в секундах + Définit la durée minimale paramétrable sur le minuteur. + 起爆タイマーの最短時間 (秒単位) を設定します。 + Tiempo mínimo (en segundos) para el temporizador del explosivo. + Minimalna wartość czasomierza dla ładunku (w sekundach). + Minimale Zeit (in Sekunden) für den Zeitzünder. + Tempo minimo (in secondi) per le spolette a tempo. + 定时爆炸的最短时间(单位:秒) + 초 단위로, 폭발 타이머의 최소 시간을 정합니다 + Tempo mínimo (em segundos) para o temporizador do explosivo. + + + Maximum time value (in seconds) for the explosive timer. + Макисмальное время до взрыва в секундах + Définit la durée maximale paramétrable sur le minuteur. + 起爆タイマーの最長時間 (秒単位) を設定します。 + Tiempo máximo (en segundos) para el temporizador del explosivo. + Maksymalna wartość czasomierza dla ładunku (w sekundach). + Maximale Zeit (in Sekunden) für den Zeitzünder. + Tempo massimo (in secondi) per le spolette a tempo. + 定时爆炸的最长时间(单位:秒) + 초 단위로, 폭발 타이머의 최대 시간을 정합니다 + Tempo máximo (em segundos) para o temporizador do explosivo. + + + Default time value (in seconds) for the explosive timer. + Стандартное время до взрыва в секундах + Définit la durée paramétrée par défaut sur le minuteur. + 起爆タイマーの標準時間 (秒単位) を設定します。 + Tiempo por defecto (en segundos) para el temporizador del explosivo. + Domyślna wartość czasomierza dla ładunku (w sekundach). + Standardmäßige Zeit (in Sekunden) für den Zeitzünder. + Tempo predefinito (in secondi) per le spolette a tempo. + 定时爆炸的默认时间(单位:秒) + 초 단위로, 기본 폭발 타이머 시간을 정합니다 + Tempo padrão (em segundos) para o temporizador do explosivo. diff --git a/addons/fastroping/CfgEventHandlers.hpp b/addons/fastroping/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/fastroping/CfgEventHandlers.hpp +++ b/addons/fastroping/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/fastroping/CfgSounds.hpp b/addons/fastroping/CfgSounds.hpp index 97479ecafb..a93c4ba032 100644 --- a/addons/fastroping/CfgSounds.hpp +++ b/addons/fastroping/CfgSounds.hpp @@ -9,4 +9,4 @@ class CfgSounds { sound[] = {QUOTE(PATHTOF(data\sounds\fastroping_thud.ogg)), 10, 1.0}; titles[] = {}; }; -}; \ No newline at end of file +}; diff --git a/addons/fastroping/CfgVehicles.hpp b/addons/fastroping/CfgVehicles.hpp index 408db14b99..ef2483e05b 100644 --- a/addons/fastroping/CfgVehicles.hpp +++ b/addons/fastroping/CfgVehicles.hpp @@ -1,16 +1,3 @@ -#define EQUIP_FRIES_ATTRIBUTE class Attributes { \ - class GVAR(equipFRIES) { \ - property = QGVAR(equipFRIES); \ - control = "Checkbox"; \ - displayName = CSTRING(Eden_equipFRIES); \ - tooltip = CSTRING(Eden_equipFRIES_Tooltip); \ - expression = QUOTE(if (_value) then {[_this] call FUNC(equipFRIES)}); \ - typeName = "BOOL"; \ - condition = "objectVehicle"; \ - defaultValue = "(false)"; \ - }; \ -} - class CfgVehicles { class Logic; class Module_F: Logic { @@ -48,35 +35,46 @@ class CfgVehicles { condition = QUOTE([_target] call FUNC(canStowFRIES)); statement = QUOTE([_target] call FUNC(stowFRIES)); }; + class ACE_deployRopes3 { + displayName = CSTRING(Interaction_deployRopes3); + condition = QUOTE([ARR_3(_target,_player,'ACE_rope3')] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope3')])] call CBA_fnc_serverEvent); + }; + class ACE_deployRopes6 { + displayName = CSTRING(Interaction_deployRopes6); + condition = QUOTE([ARR_3(_target,_player,'ACE_rope6')] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope6')])] call CBA_fnc_serverEvent); + }; class ACE_deployRopes12 { displayName = CSTRING(Interaction_deployRopes12); - condition = QUOTE([ARR_3(_target, _player, 'ACE_rope12')] call FUNC(canDeployRopes)); - statement = QUOTE([ARR_2(QUOTE(QGVAR(deployRopes)), [ARR_3(_target, _player, 'ACE_rope12'))]] call CBA_fnc_serverEvent); + condition = QUOTE([ARR_3(_target,_player,'ACE_rope12')] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope12')])] call CBA_fnc_serverEvent); }; class ACE_deployRopes15 { displayName = CSTRING(Interaction_deployRopes15); - condition = QUOTE([ARR_3(_target, _player, 'ACE_rope15')] call FUNC(canDeployRopes)); - statement = QUOTE([ARR_2(QUOTE(QGVAR(deployRopes)), [ARR_3(_target, _player, 'ACE_rope15'))]] call CBA_fnc_serverEvent); + condition = QUOTE([ARR_3(_target,_player,'ACE_rope15')] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope15')])] call CBA_fnc_serverEvent); }; class ACE_deployRopes18 { displayName = CSTRING(Interaction_deployRopes18); - condition = QUOTE([ARR_3(_target, _player, 'ACE_rope18')] call FUNC(canDeployRopes)); - statement = QUOTE([ARR_2(QUOTE(QGVAR(deployRopes)), [ARR_3(_target, _player, 'ACE_rope18'))]] call CBA_fnc_serverEvent); + condition = QUOTE([ARR_3(_target,_player,'ACE_rope18')] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope18')])] call CBA_fnc_serverEvent); }; class ACE_deployRopes27 { displayName = CSTRING(Interaction_deployRopes27); - condition = QUOTE([ARR_3(_target, _player, 'ACE_rope27')] call FUNC(canDeployRopes)); - statement = QUOTE([ARR_2(QUOTE(QGVAR(deployRopes)), [ARR_3(_target, _player, 'ACE_rope27'))]] call CBA_fnc_serverEvent); + condition = QUOTE([ARR_3(_target,_player,'ACE_rope27')] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope27')])] call CBA_fnc_serverEvent); }; class ACE_deployRopes36 { displayName = CSTRING(Interaction_deployRopes36); - condition = QUOTE([ARR_4(_target, _player, 'ACE_rope36', true)] call FUNC(canDeployRopes)); - statement = QUOTE([ARR_2(QUOTE(QGVAR(deployRopes)), [ARR_3(_target, _player, 'ACE_rope36'))]] call CBA_fnc_serverEvent); + condition = QUOTE([ARR_4(_target,_player,'ACE_rope36',true)] call FUNC(canDeployRopes)); + statement = QUOTE([ARR_2(QQGVAR(deployRopes),[ARR_3(_target,_player,'ACE_rope36')])] call CBA_fnc_serverEvent); }; class ACE_cutRopes { displayName = CSTRING(Interaction_cutRopes); - condition = QUOTE(true); - statement = ""; + condition = QUOTE([_target] call FUNC(canCutRopes)); + // should not be empty to work with EGVAR(interact_menu,consolidateSingleChild) setting + statement = QUOTE(true); class confirmCutRopes { displayName = ECSTRING(common,confirm); condition = QUOTE([_target] call FUNC(canCutRopes)); @@ -85,8 +83,8 @@ class CfgVehicles { }; class ACE_fastRope { displayName = CSTRING(Interaction_fastRope); - condition = [_player, _target] call FUNC(canFastRope); - statement = [_player, _target] call FUNC(fastRope); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canFastRope)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(fastRope)); }; }; }; @@ -179,6 +177,7 @@ class CfgVehicles { author = "KoffeinFlummi"; scope = 1; model = QPATHTOF(data\helper.p3d); + destrType = "DestructNo"; class ACE_Actions {}; class Turrets {}; class TransportItems {}; @@ -210,7 +209,9 @@ class CfgVehicles { GVAR(friesAttachmentPoint)[] = {0.035, 2.2, -0.15}; GVAR(onPrepare) = QFUNC(onPrepareCommon); GVAR(onCut) = QFUNC(onCutCommon); - EQUIP_FRIES_ATTRIBUTE; + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; }; class Heli_Transport_02_base_F: Helicopter_Base_H { GVAR(enabled) = 1; @@ -221,7 +222,7 @@ class CfgVehicles { class UserActions { class Ramp_Open; class Ramp_Close: Ramp_Open { - condition = QUOTE([ARR_5(this,'CargoRamp_Open',[[0],[1],[2]])] call FUNC(canCloseRamp)); + condition = QUOTE([ARR_3(this,'CargoRamp_Open',[ARR_3([0],[1],[2])])] call FUNC(canCloseRamp)); }; }; }; @@ -234,7 +235,7 @@ class CfgVehicles { class UserActions { class Ramp_Open; class Ramp_Close: Ramp_Open { - condition = QUOTE([ARR_5(this,'Door_rear_source',[[0],[3],[4]])] call FUNC(canCloseRamp)); + condition = QUOTE([ARR_3(this,'Door_rear_source',[ARR_3([0],[3],[4])])] call FUNC(canCloseRamp)); }; }; }; @@ -243,14 +244,19 @@ class CfgVehicles { GVAR(ropeOrigins)[] = {"ropeOriginRight", "ropeOriginLeft"}; GVAR(friesType) = "ACE_friesGantryReverse"; GVAR(friesAttachmentPoint)[] = {-1.04, 2.5, -0.34}; - EQUIP_FRIES_ATTRIBUTE; + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; }; class Heli_light_03_unarmed_base_F: Heli_light_03_base_F { GVAR(enabled) = 2; GVAR(ropeOrigins)[] = {"ropeOriginRight", "ropeOriginLeft"}; GVAR(friesType) = "ACE_friesGantry"; GVAR(friesAttachmentPoint)[] = {1.07, 2.5, -0.5}; - EQUIP_FRIES_ATTRIBUTE; + + class Attributes { + EQUIP_FRIES_ATTRIBUTE; + }; }; class Heli_Transport_04_base_F: Helicopter_Base_H { class UserActions; @@ -268,7 +274,7 @@ class CfgVehicles { class UserActions: UserActions { class CloseDoor_6; class Ramp_Close: CloseDoor_6 { - condition = QUOTE([ARR_6(this,'Door_6_source',[[0],[1],[2],[3]])] call FUNC(canCloseRamp)); + condition = QUOTE([ARR_3(this,'Door_6_source',[ARR_4([0],[1],[2],[3])])] call FUNC(canCloseRamp)); }; }; }; @@ -279,6 +285,7 @@ class CfgVehicles { accuracy = 1000; displayName = CSTRING(Ropesupply); model = "\A3\Weapons_F\AmmoBoxes\Box_NATO_AmmoVeh_F.p3d"; + editorPreview = "\A3\EditorPreviews_F\Data\CfgVehicles\Box_NATO_AmmoVeh_F.jpg"; author = "Pokertour"; class TransportItems { MACRO_ADDITEM(ACE_rope12,15); diff --git a/addons/fastroping/CfgWeapons.hpp b/addons/fastroping/CfgWeapons.hpp deleted file mode 100644 index 116497c6fa..0000000000 --- a/addons/fastroping/CfgWeapons.hpp +++ /dev/null @@ -1,60 +0,0 @@ -class CfgWeapons { - class ACE_ItemCore; - class CBA_MiscItem_ItemInfo; - - class ACE_rope12: ACE_ItemCore { - scope = 2; - GVAR(ropeLength) = 12.2; - picture = QPATHTOF(data\m_rope_ca); - model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; - displayName = CSTRING(Rope_12_Display); - descriptionShort = CSTRING(descriptionShort); - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 36; - }; - }; - class ACE_rope15: ACE_ItemCore { - scope = 2; - GVAR(ropeLength) = 15.2; - picture = QPATHTOF(data\m_rope_ca); - model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; - displayName = CSTRING(Rope_15_Display); - descriptionShort = CSTRING(descriptionShort); - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 45; - }; - }; - class ACE_rope18: ACE_ItemCore { - scope = 2; - GVAR(ropeLength) = 18.3; - picture = QPATHTOF(data\m_rope_ca); - model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; - displayName = CSTRING(Rope_18_Display); - descriptionShort = CSTRING(descriptionShort); - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 54; - }; - }; - class ACE_rope27: ACE_ItemCore { - scope = 2; - GVAR(ropeLength) = 27.4; - picture = QPATHTOF(data\m_rope_ca); - model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; - displayName = CSTRING(Rope_27_Display); - descriptionShort = CSTRING(descriptionShort); - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 81; - }; - }; - class ACE_rope36: ACE_ItemCore { - scope = 2; - GVAR(ropeLength) = 36.6; - picture = QPATHTOF(data\m_rope_ca); - model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; - displayName = CSTRING(Rope_36_Display); - descriptionShort = CSTRING(descriptionShort); - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 108; - }; - }; -}; diff --git a/addons/fastroping/README.md b/addons/fastroping/README.md index 49fcf00960..51b1a41375 100644 --- a/addons/fastroping/README.md +++ b/addons/fastroping/README.md @@ -3,9 +3,3 @@ ace_fastroping Introducing the ability to fastrope out of heliocopters. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [BaerMitUmlaut](https://github.com/BaerMitUmlaut) -- [KoffeinFlummi](https://github.com/KoffeinFlummi) diff --git a/addons/fastroping/XEH_postInit.sqf b/addons/fastroping/XEH_postInit.sqf index 72ded1b267..0ba9231215 100644 --- a/addons/fastroping/XEH_postInit.sqf +++ b/addons/fastroping/XEH_postInit.sqf @@ -1,17 +1,15 @@ #include "script_component.hpp" -[QGVAR(deployRopes), { - _this call FUNC(deployRopes); -}] call CBA_fnc_addEventHandler; +[QGVAR(deployRopes), LINKFUNC(deployRopes)] call CBA_fnc_addEventHandler; [QGVAR(startFastRope), { - [FUNC(fastRopeServerPFH), 0, _this] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(fastRopeServerPFH), 0, _this] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; // Keybinds ["ACE3 Vehicles", QGVAR(fastRope), localize LSTRING(Interaction_fastRope), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([ACE_player, vehicle ACE_player] call FUNC(canFastRope)) then { [ACE_player, vehicle ACE_player] call FUNC(fastRope); true @@ -22,7 +20,7 @@ ["ACE3 Vehicles", QGVAR(cutRopes), localize LSTRING(Interaction_cutRopes), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([vehicle ACE_player] call FUNC(canCutRopes)) then { [vehicle ACE_player] call FUNC(cutRopes); true @@ -32,10 +30,21 @@ }, {false}] call CBA_fnc_addKeybind; +if (isServer) then { + ["Helicopter", "init", { + if (!GVAR(autoAddFRIES)) exitWith {}; + params ["_vehicle"]; + if (isNumber (configOf _vehicle >> QGVAR(enabled)) && {isNil {_vehicle getVariable [QGVAR(FRIES), nil]}}) then { + [_vehicle] call FUNC(equipFRIES); + }; + }, true, ["ACE_friesBase"], true] call CBA_fnc_addClassEventHandler; +}; + + #ifdef DRAW_FASTROPE_INFO addMissionEventHandler ["Draw3D", { - if (!(cursorObject isKindOf "Helicopter")) exitWith {}; - private _config = configFile >> "CfgVehicles" >> (typeOf cursorObject); + if !(cursorObject isKindOf "Helicopter") exitWith {}; + private _config = configOf cursorObject; private _enabled = getNumber (_config >> QGVAR(enabled)); drawIcon3D ["", [.5,.5,1,1], (ASLtoAGL getPosASL cursorObject), 0.5, 0.5, 0, format ["%1 = %2", typeOf cursorObject, _enabled], 0.5, 0.025, "TahomaB"]; if (_enabled > 0) then { diff --git a/addons/fastroping/XEH_preInit.sqf b/addons/fastroping/XEH_preInit.sqf index 9361d05015..b750275167 100644 --- a/addons/fastroping/XEH_preInit.sqf +++ b/addons/fastroping/XEH_preInit.sqf @@ -6,6 +6,12 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +if (isServer) then { + ["Helicopter", "Deleted", LINKFUNC(unequipFRIES)] call CBA_fnc_addClassEventHandler; +}; + +["Helicopter", "Killed", LINKFUNC(unequipFRIES)] call CBA_fnc_addClassEventHandler; ADDON = true; diff --git a/addons/fastroping/config.cpp b/addons/fastroping/config.cpp index 98dfd26742..dbf1f35e6a 100644 --- a/addons/fastroping/config.cpp +++ b/addons/fastroping/config.cpp @@ -3,12 +3,12 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; + units[] = {"ACE_fastropingSupplyCrate"}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_interaction"}; + requiredAddons[] = {"ace_interaction","ace_logistics_rope"}; author = ECSTRING(common,ACETeam); - authors[] = {"KoffeinFlummi", "BaerMitUmlaut", "Pokertour"}; + authors[] = {"KoffeinFlummi", "BaerMitUmlaut", "Pokertour", "veteran29"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; @@ -19,4 +19,4 @@ class CfgPatches { #include "CfgSounds.hpp" #include "CfgVehicles.hpp" #include "CfgWaypoints.hpp" -#include "CfgWeapons.hpp" + diff --git a/addons/fastroping/functions/fnc_canCloseRamp.sqf b/addons/fastroping/functions/fnc_canCloseRamp.sqf index 969d719796..9416bb51ea 100644 --- a/addons/fastroping/functions/fnc_canCloseRamp.sqf +++ b/addons/fastroping/functions/fnc_canCloseRamp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the player can close the ramp of the given helo. diff --git a/addons/fastroping/functions/fnc_canCutRopes.sqf b/addons/fastroping/functions/fnc_canCutRopes.sqf index 8107b8066b..922cafbaa6 100644 --- a/addons/fastroping/functions/fnc_canCutRopes.sqf +++ b/addons/fastroping/functions/fnc_canCutRopes.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can cut deployed ropes. @@ -18,5 +18,5 @@ params ["_vehicle"]; private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; -!(_deployedRopes isEqualTo []) && +(_deployedRopes isNotEqualTo []) && {{(_x select 5)} count (_deployedRopes) == 0} diff --git a/addons/fastroping/functions/fnc_canDeployRopes.sqf b/addons/fastroping/functions/fnc_canDeployRopes.sqf index 26b514368b..a27db7f1b3 100644 --- a/addons/fastroping/functions/fnc_canDeployRopes.sqf +++ b/addons/fastroping/functions/fnc_canDeployRopes.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can deploy ropes from the helicopter. @@ -19,7 +19,7 @@ */ params ["_vehicle", "_player", "_ropeClass", ["_defaultOption", false]]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; (driver _vehicle != _player) && {getPos _vehicle select 2 > 2} && { diff --git a/addons/fastroping/functions/fnc_canFastRope.sqf b/addons/fastroping/functions/fnc_canFastRope.sqf index b4f5e20474..e5e4513d46 100644 --- a/addons/fastroping/functions/fnc_canFastRope.sqf +++ b/addons/fastroping/functions/fnc_canFastRope.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can fast rope from the helicopter. @@ -20,6 +20,6 @@ params ["_unit", "_vehicle"]; private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; ((driver _vehicle != _unit) && -{!(_deployedRopes isEqualTo [])} && +{_deployedRopes isNotEqualTo []} && {{!(_x select 5) && !(_x select 6)} count (_deployedRopes) > 0} && {getPos _vehicle select 2 > 2}) diff --git a/addons/fastroping/functions/fnc_canPrepareFRIES.sqf b/addons/fastroping/functions/fnc_canPrepareFRIES.sqf index 881996b5a1..c5ac466729 100644 --- a/addons/fastroping/functions/fnc_canPrepareFRIES.sqf +++ b/addons/fastroping/functions/fnc_canPrepareFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can prepare the helicopters FRIES. @@ -16,7 +16,7 @@ */ params ["_vehicle"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; ((getNumber (_config >> QGVAR(enabled)) == 1) || {!(isNull (_vehicle getVariable [QGVAR(FRIES), objNull]))}) && {(_vehicle getVariable [QGVAR(deploymentStage), 0]) == 0} && diff --git a/addons/fastroping/functions/fnc_canStowFRIES.sqf b/addons/fastroping/functions/fnc_canStowFRIES.sqf index 6f26fc1ed5..7036d142c8 100644 --- a/addons/fastroping/functions/fnc_canStowFRIES.sqf +++ b/addons/fastroping/functions/fnc_canStowFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can stow the helicopters FRIES. @@ -16,7 +16,7 @@ */ params ["_vehicle"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; (_vehicle getVariable [QGVAR(deploymentStage), 0]) == 2 && {getText (_config >> QGVAR(onCut)) != ""} diff --git a/addons/fastroping/functions/fnc_cutRopes.sqf b/addons/fastroping/functions/fnc_cutRopes.sqf index ae1b58638a..40d2416049 100644 --- a/addons/fastroping/functions/fnc_cutRopes.sqf +++ b/addons/fastroping/functions/fnc_cutRopes.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Cut deployed ropes. @@ -25,7 +25,7 @@ private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; private _attachedObjects = attachedObjects _dummy; //Rope is considered occupied when it's broken as well, so check if array is empty //Note: ropes are not considered attached objects by Arma - if !(_attachedObjects isEqualTo []) then { + if (_attachedObjects isNotEqualTo []) then { detach ((attachedObjects _dummy) select 0); }; }; @@ -34,11 +34,11 @@ private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; //Only delete the hook first so the rope falls down. //Note: ropeDetach was used here before, but the command seems a bit broken. deleteVehicle _hook; - [{{deleteVehicle _x} count _this}, [_ropeTop, _ropeBottom, _dummy], 60] call CBA_fnc_waitAndExecute; -} count _deployedRopes; + [{{deleteVehicle _x} forEach _this}, [_ropeTop, _ropeBottom, _dummy], 60] call CBA_fnc_waitAndExecute; +} forEach _deployedRopes; _vehicle setVariable [QGVAR(deployedRopes), [], true]; // Set new state (0 if no FRIES, 2 if FRIES for manual stowing) -private _newState = [0, 2] select (isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(onCut))); +private _newState = [0, 2] select (isText (configOf _vehicle >> QGVAR(onCut))); _vehicle setVariable [QGVAR(deploymentStage), _newState, true]; diff --git a/addons/fastroping/functions/fnc_deployAI.sqf b/addons/fastroping/functions/fnc_deployAI.sqf index f6f3915181..01aa363afb 100644 --- a/addons/fastroping/functions/fnc_deployAI.sqf +++ b/addons/fastroping/functions/fnc_deployAI.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Auomatically deploy a helicopter filled with AI units. @@ -26,7 +26,7 @@ if (isNull _vehicle || {!(_vehicle isKindOf "Helicopter")}) exitWith { ERROR('FUNC(deployAI): deployAI was called with an invalid or non-existant vehicle.'); }; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _configEnabled = getNumber (_config >> QGVAR(enabled)); if (_configEnabled == 0) exitWith { if (hasInterface) then { @@ -59,10 +59,13 @@ if (_createDeploymentGroup) then { }; private _deployTime = 0; + if (getText (_config >> QGVAR(onPrepare)) != "") then { _deployTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onPrepare)))); }; -[{[_this] call FUNC(deployRopes)}, _vehicle, _deployTime] call CBA_fnc_waitAndExecute; + +[FUNC(deployRopes), _vehicle, _deployTime] call CBA_fnc_waitAndExecute; + driver _vehicle disableAI "MOVE"; DFUNC(deployAIRecursive) = { @@ -72,7 +75,7 @@ DFUNC(deployAIRecursive) = { unassignVehicle _unit; [_unit, _vehicle] call FUNC(fastRope); - if !(_unitsToDeploy isEqualTo []) then { + if (_unitsToDeploy isNotEqualTo []) then { [{ [{ params ["_vehicle"]; diff --git a/addons/fastroping/functions/fnc_deployAIWaypoint.sqf b/addons/fastroping/functions/fnc_deployAIWaypoint.sqf index 20e3f704f6..83bd8a34cf 100644 --- a/addons/fastroping/functions/fnc_deployAIWaypoint.sqf +++ b/addons/fastroping/functions/fnc_deployAIWaypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Waypoint function for the fast rope waypoint. @@ -11,7 +11,7 @@ * true * * Example: - * [_group, [6560, 12390, 0]] call ace_fastroping_fnc_deployAIWayoint + * [_group, [6560, 12390, 0]] call ace_fastroping_fnc_deployAIWaypoint * * Public: No */ @@ -24,7 +24,7 @@ private _speedMode = speedMode _group; // - Approach ----------------------------------------------------------------- if (_vehicle distance2D _position > 50) then { _group setSpeedMode "LIMITED"; - _vehicle flyInHeight 20; + _vehicle flyInHeight [20, true]; _commander doMove _position; waitUntil {_vehicle distance2D _position < 50}; waitUntil {vectorMagnitude (velocity _vehicle) < 3}; @@ -33,7 +33,7 @@ if (_vehicle distance2D _position > 50) then { // - Deployment --------------------------------------------------------------- [_vehicle] call FUNC(deployAI); -waitUntil {!((_vehicle getVariable [QGVAR(deployedRopes), []]) isEqualTo [])}; +waitUntil {(_vehicle getVariable [QGVAR(deployedRopes), []]) isNotEqualTo []}; waitUntil {(_vehicle getVariable [QGVAR(deployedRopes), []]) isEqualTo []}; _group setSpeedMode _speedMode; diff --git a/addons/fastroping/functions/fnc_deployRopes.sqf b/addons/fastroping/functions/fnc_deployRopes.sqf index 2873e5bee1..eea81a7746 100644 --- a/addons/fastroping/functions/fnc_deployRopes.sqf +++ b/addons/fastroping/functions/fnc_deployRopes.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Deploy ropes from the helicopter. @@ -16,19 +16,26 @@ * * Public: No */ -params ["_vehicle", "_player", "_ropeClass"]; + +params ["_vehicle", ["_player", objNull], ["_ropeClass", ""]]; TRACE_3("deployRopes",_vehicle,_player,_ropeClass); -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _ropeOrigins = getArray (_config >> QGVAR(ropeOrigins)); private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; private _hookAttachment = _vehicle getVariable [QGVAR(FRIES), _vehicle]; -private _ropeLength = getNumber (configfile >> "CfgWeapons" >> _ropeClass >> QGVAR(ropeLength)); +private _ropeLength = getNumber (configfile >> "CfgWeapons" >> _ropeClass >> QEGVAR(logistics_rope,length)); + +if (_ropeLength <= 0) then { + _ropeLength = DEFAULT_ROPE_LENGTH; +}; + TRACE_3("",_ropeClass,_ropeLength,GVAR(requireRopeItems)); -if (GVAR(requireRopeItems)) then { - if (_ropeClass in (items _player)) then { + +if (GVAR(requireRopeItems) && {_ropeClass != ""}) then { + if (_ropeClass in (_player call EFUNC(common,uniqueItems))) then { _player removeItem _ropeClass; } else { _vehicle removeItem _ropeClass; @@ -60,9 +67,7 @@ if (GVAR(requireRopeItems)) then { //deployedRopes format: attachment point, top part of the rope, bottom part of the rope, attachTo helper object, occupied, broken _deployedRopes pushBack [_ropeOrigin, _ropeTop, _ropeBottom, _dummy, _hook, false, false]; - - false -} count _ropeOrigins; +} forEach _ropeOrigins; _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; _vehicle setVariable [QGVAR(deploymentStage), 3, true]; diff --git a/addons/fastroping/functions/fnc_equipFRIES.sqf b/addons/fastroping/functions/fnc_equipFRIES.sqf index 7b1002db20..615840cb75 100644 --- a/addons/fastroping/functions/fnc_equipFRIES.sqf +++ b/addons/fastroping/functions/fnc_equipFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Equips the given helicopter with a FRIES. @@ -14,18 +14,21 @@ * * Public: Yes */ -params ["_vehicle"]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; -if !(isNumber (_config >> QGVAR(enabled))) then { - ["%1 has not been configured for ACE_Fastroping.", getText (_config >> "DisplayName")] call BIS_fnc_error; -} else { - if (getNumber (_config >> QGVAR(enabled)) == 2) then { - private _fries = (getText (_config >> QGVAR(friesType))) createVehicle [0, 0, 0]; - _fries attachTo [_vehicle, (getArray (_config >> QGVAR(friesAttachmentPoint)))]; - _vehicle setVariable [QGVAR(FRIES), _fries, true]; +[{ + params ["_vehicle"]; - _vehicle addEventHandler ["Killed", FUNC(unequipFRIES)]; - _vehicle addEventHandler ["Deleted", FUNC(unequipFRIES)]; + if (!alive _vehicle) exitWith { WARNING_1("bad vehicle %1",_this); }; + if (alive (_vehicle getVariable [QGVAR(FRIES),objNull])) exitWith { WARNING_1("already equiped %1",_this); }; + + private _config = configOf _vehicle; + if !(isNumber (_config >> QGVAR(enabled))) then { + ["%1 has not been configured for ACE_Fastroping.", getText (_config >> "displayName")] call BIS_fnc_error; + } else { + if (getNumber (_config >> QGVAR(enabled)) == 2) then { + private _fries = (getText (_config >> QGVAR(friesType))) createVehicle [0, 0, 0]; + _fries attachTo [_vehicle, getArray (_config >> QGVAR(friesAttachmentPoint))]; + _vehicle setVariable [QGVAR(FRIES), _fries, true]; + }; }; -}; +}, _this] call CBA_fnc_execNextFrame; diff --git a/addons/fastroping/functions/fnc_fastRope.sqf b/addons/fastroping/functions/fnc_fastRope.sqf index 39f7cc38c9..430c8d86ca 100644 --- a/addons/fastroping/functions/fnc_fastRope.sqf +++ b/addons/fastroping/functions/fnc_fastRope.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Lets the unit fast rope. @@ -36,4 +36,4 @@ _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; //Start server PFH asap [QGVAR(startFastRope), [_unit, _vehicle, _usableRope, _usableRopeIndex, false]] call CBA_fnc_serverEvent; moveOut _unit; -[FUNC(fastRopeLocalPFH), 0, [_unit, _vehicle, _usableRope, _usableRopeIndex, diag_tickTime]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(fastRopeLocalPFH), 0, [_unit, _vehicle, _usableRope, _usableRopeIndex, diag_tickTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf index c46e919bc5..b1fec908a5 100644 --- a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Local PerFrameHandler during fast roping. @@ -20,7 +20,7 @@ _arguments params ["_unit", "", "_rope", "", "_timeToPlayRopeSound"]; _rope params ["", "", "", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; // dummy lost hook if (isNull _hook) exitWith { diff --git a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf index 16df3f3e95..716c0ab43e 100644 --- a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Server PerFrameHandler during fast roping. @@ -20,7 +20,7 @@ _arguments params ["_unit", "_vehicle", "_rope", "_ropeIndex", "_hasBeenAttached _rope params ["_attachmentPoint", "_ropeTop", "_ropeBottom", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; //Prevent teleport if hook has been deleted due to rope cut if (isNull _hook) exitWith { @@ -28,7 +28,7 @@ if (isNull _hook) exitWith { [_pfhHandle] call CBA_fnc_removePerFrameHandler; }; -private _ropeLength = _vehicle getVariable [QGVAR(ropeLength), 34.5]; +private _ropeLength = _vehicle getVariable [QGVAR(ropeLength), DEFAULT_ROPE_LENGTH]; //Start fast roping if (getMass _dummy != 80) exitWith { diff --git a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf index 33975168a6..892997bf80 100644 --- a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf +++ b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Equips synched helicopters with a FRIES. @@ -22,5 +22,4 @@ private _synchedUnits = synchronizedObjects _module; _x = vehicle _x; }; [_x] call FUNC(equipFRIES); - false -} count _synchedUnits; +} forEach _synchedUnits; diff --git a/addons/fastroping/functions/fnc_onCutCommon.sqf b/addons/fastroping/functions/fnc_onCutCommon.sqf index 1a32739eaa..e9209e4fa1 100644 --- a/addons/fastroping/functions/fnc_onCutCommon.sqf +++ b/addons/fastroping/functions/fnc_onCutCommon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Function for closing doors and retracting the hook for most vanilla and older Arma helos. @@ -10,7 +10,7 @@ * Amount of time to wait before cutting ropes * * Example: - * [_vehicle] call ace_fastroping_fnc_onCutRopesCommon + * [_vehicle] call ace_fastroping_fnc_onCutCommon * * Public: No */ diff --git a/addons/fastroping/functions/fnc_onPrepareCommon.sqf b/addons/fastroping/functions/fnc_onPrepareCommon.sqf index 76665dea71..93501ccf40 100644 --- a/addons/fastroping/functions/fnc_onPrepareCommon.sqf +++ b/addons/fastroping/functions/fnc_onPrepareCommon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Function for opening doors and extending the hook for most vanilla and older Arma helos. @@ -10,7 +10,7 @@ * Amount of time to wait before deploying ropes * * Example: - * [_vehicle] call ace_fastroping_fnc_onDeployRopesCommon + * [_vehicle] call ace_fastroping_fnc_onPrepareCommon * * Public: No */ diff --git a/addons/fastroping/functions/fnc_onRopeBreak.sqf b/addons/fastroping/functions/fnc_onRopeBreak.sqf index 023e53f762..de9c49b6b8 100644 --- a/addons/fastroping/functions/fnc_onRopeBreak.sqf +++ b/addons/fastroping/functions/fnc_onRopeBreak.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles ropes breaking when deployed. @@ -42,7 +42,7 @@ private _unit = { if (_x isKindOf "CAManBase") exitWith {_x}; } forEach (attachedObjects (_brokenRope select 3)); -if !(isNil "_unit") then { +if (!isNil "_unit") then { if (_part == "top") then { detach _unit; } else { diff --git a/addons/fastroping/functions/fnc_prepareFRIES.sqf b/addons/fastroping/functions/fnc_prepareFRIES.sqf index c5bac4deb1..0eb4bffcf8 100644 --- a/addons/fastroping/functions/fnc_prepareFRIES.sqf +++ b/addons/fastroping/functions/fnc_prepareFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Prepares the helicopters FRIES. @@ -19,7 +19,7 @@ params ["_vehicle"]; //Stage indicator: 0 - travel mode; 1 - preparing/stowing FRIES; 2 - FRIES ready; 3 - ropes deployed _vehicle setVariable [QGVAR(deploymentStage), 1, true]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _waitTime = 0; if (isText (_config >> QGVAR(onPrepare))) then { _waitTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onPrepare)))); diff --git a/addons/fastroping/functions/fnc_stowFRIES.sqf b/addons/fastroping/functions/fnc_stowFRIES.sqf index 3b18a6dbe1..9ad54796bd 100644 --- a/addons/fastroping/functions/fnc_stowFRIES.sqf +++ b/addons/fastroping/functions/fnc_stowFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Stows the helicopters FRIES. @@ -19,7 +19,7 @@ params ["_vehicle"]; //Stage indicator: 0 - travel mode; 1 - preparing/stowing FRIES; 2 - FRIES ready; 3 - ropes deployed _vehicle setVariable [QGVAR(deploymentStage), 1, true]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configOf _vehicle; private _waitTime = 0; if (isText (_config >> QGVAR(onCut))) then { _waitTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onCut)))); diff --git a/addons/fastroping/functions/fnc_unequipFRIES.sqf b/addons/fastroping/functions/fnc_unequipFRIES.sqf index e89cacec9e..8483322cef 100644 --- a/addons/fastroping/functions/fnc_unequipFRIES.sqf +++ b/addons/fastroping/functions/fnc_unequipFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Removes FRIES from helicopter. @@ -14,11 +14,12 @@ * * Public: Yes */ + params ["_vehicle"]; deleteVehicle (_vehicle getVariable [QGVAR(FRIES), objNull]); _vehicle setVariable [QGVAR(FRIES), nil, true]; -if !((_vehicle getVariable [QGVAR(deployedRopes), []] isEqualTo [])) then { +if (_vehicle getVariable [QGVAR(deployedRopes), []] isNotEqualTo []) then { [_vehicle] call FUNC(cutRopes); }; diff --git a/addons/fastroping/functions/script_component.hpp b/addons/fastroping/functions/script_component.hpp deleted file mode 100644 index 00e1b5bb76..0000000000 --- a/addons/fastroping/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\fastroping\script_component.hpp" diff --git a/addons/fastroping/initSettings.inc.sqf b/addons/fastroping/initSettings.inc.sqf new file mode 100644 index 0000000000..cde4a32b47 --- /dev/null +++ b/addons/fastroping/initSettings.inc.sqf @@ -0,0 +1,17 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(setting_categoryMenu_displayName)]; + +[ + QGVAR(requireRopeItems), "CHECKBOX", + [LSTRING(setting_requireRopeItems_displayName)], + _category, + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(autoAddFRIES), "CHECKBOX", + [LSTRING(setting_autoAddFRIES_displayName), LSTRING(setting_autoAddFRIES_description)], + _category, + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/fastroping/initSettings.sqf b/addons/fastroping/initSettings.sqf deleted file mode 100644 index d88a6982d0..0000000000 --- a/addons/fastroping/initSettings.sqf +++ /dev/null @@ -1,11 +0,0 @@ -// CBA Settings [ADDON: ace_fastroping]: - -[ - QGVAR(requireRopeItems), "CHECKBOX", - [LSTRING(setting_requireRopeItems_displayName)], - ["ACE Uncategorized", QUOTE(COMPONENT_BEAUTIFIED)], - false, // default value - true, // isGlobal - {[QGVAR(requireRopeItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // needRestart -] call CBA_settings_fnc_init; diff --git a/addons/fastroping/script_component.hpp b/addons/fastroping/script_component.hpp index 77c8168f8d..a9a07e2f02 100644 --- a/addons/fastroping/script_component.hpp +++ b/addons/fastroping/script_component.hpp @@ -16,7 +16,9 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" +#include "script_macros.hpp" +#define DEFAULT_ROPE_LENGTH 34.5 #define ANIMS_HOOK ["extendHookRight", "extendHookLeft"] #define ANIMS_ANIMATEDOOR ["door_R", "door_L", "CargoRamp_Open", "Door_rear_source", "Door_6_source", "CargoDoorR", "CargoDoorL"] diff --git a/addons/fastroping/script_macros.hpp b/addons/fastroping/script_macros.hpp new file mode 100644 index 0000000000..baaa10c338 --- /dev/null +++ b/addons/fastroping/script_macros.hpp @@ -0,0 +1,10 @@ +#define EQUIP_FRIES_ATTRIBUTE class EGVAR(fastroping,equipFRIES) { \ + property = QEGVAR(fastroping,equipFRIES); \ + control = "Checkbox"; \ + displayName = ECSTRING(fastroping,Eden_equipFRIES); \ + tooltip = ECSTRING(fastroping,Eden_equipFRIES_Tooltip); \ + expression = QUOTE(if (_value) then {[_this] call EFUNC(fastroping,equipFRIES)}); \ + typeName = "BOOL"; \ + condition = "objectVehicle"; \ + defaultValue = "false"; \ +} diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index 5fe476a336..10ea50a7c5 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -5,14 +5,14 @@ Equip FRIES Rüste FRIES aus Wyposaż FRIES - Equiper le FRIES + Équiper le FRIES Equipar FRIES Equipaggia il FRIES Vybavit FRIES Equipar FRIES Десантирование по канатам FRIES を装備 - FRIES 장착 + 패스트로프 시스템 장착 启用快速绳降及撤离系统 啟用快速繩降及撤離系統 @@ -20,9 +20,9 @@ Equips compatible helicopters with a Fast Rope Insertion Extraction System. Rüstet kompatible Helikopter mit einem Fast Rope Insertion Extraction System aus. Wyposaża kompatybilne helikoptery w zestaw Fast Rope Insertion Extraction System. - Equipe les hélicoptères compatibles avec un Module Fast Rope Insertion Extraction System. - Equipar helicoptero compatible con un Sistema de Inserción Extracción Fast Rope. - Equipagga l'elicottero compatibile con il Fast Rope Insertion Extraction System + Équipe les hélicoptères compatibles avec un FRIES (Fast Rope Insertion Extraction System). + Equipar helicoptero compatible con un Sistema de Inserción/Extracción Rápida por Cuerda. + Equipagga elicotteri compatibili con il Fast Rope Insertion Extraction System Vybavit kompatibilní vrtulníky systémem Fast Rope Insertion Extraction (FRIES). Equipa um helicóptero compatível com o Fast Rope Insertion Exctraction System. Снаряжает совместимые вертолеты оборудованием для спуска десанта по канатам. @@ -35,27 +35,33 @@ Prepare fast roping system Bereite "Fast Roping"-System vor Przygotuj system zjazdu na linach - Préparer le système de corde lisse - Preparar el sistema fast roping + Préparer le système d'hélicordage + Preparar el sistema de Cuerda Rápida Prepara le corde Připravit systém slaňování Prepara sistema de descida rápida Подготовить канаты - ファスト ロープのシステムを準備 + ファストロープ システムを準備 패스트로프 준비 准备快速绳降系统 準備快速繩降系統 + Halatla inme sistemini hazırla Stow fast roping system Verstaue "Fast Roping"-System Arrotola le corde - ファスト ロープのシステムを収容 + ファストロープ システムを収容 收起快速繩降系統 收起快速绳降系统 - 패스트 로프 시스템 보관 + 패스트로프 시스템 보관 Schowaj system zjazdu na linach Спрятать систему спуска + Recolher o sistema de descida rápida + Désactiver le système d'hélicordage + Odložit systém slaňování + Recoger sistema de Cuerda Rápida + Halatla inme sistemini yerleştir Deploy ropes @@ -68,30 +74,32 @@ Jogar cordas Зацепить канаты ロープを展開 - 줄 배치 + 줄 내리기 部属绳索 部屬繩索 + Halatları sal Fast rope Abseilen Zjedź na linie - Descendre à la corde + Hélicordage - Descendre en rappel Descender por la cuerda Scendi dalla corda SLANIT Descida rápida Спуститься по канату - ファスト ロープをする - 강하하기 + ファストロープする + 패스트로프 快速绳降 快速繩降 + Halatla in Cut ropes Seile abwerfen Odetnij liny - Détacher les cordes + Hélicordage - Couper les cordes Cortar cuerdas Taglia le corde Odříznout lano @@ -101,19 +109,20 @@ 줄 자르기 剪掉绳索 剪掉繩索 + Halatı Kes Equip helicopter with FRIES Rüste Helicopter mit FRIES aus Wyposaż helikopter w FRIES - Equiper l'hélicoptère avec le FRIES + Équiper l'hélicoptère d'un FRIES Equipar helicoptero con FRIES Equipaggia l'elicottero con il FRIES Vybavit vrtulník pomocí FRIES Equipar helicóptero com FRIES Снарядить вертолет канатами для спуска ヘリコプターへ FRIES を装備 - 헬리콥터에 FRIES 장착 + 헬리콥터에 패스트로프 시스템 장착 启用快速绳降及撤离系统给指定的直升机 啟用快速繩降及撤離系統給指定的直升機 @@ -121,8 +130,8 @@ Equips the selected helicopter with a Fast Rope Insertion Extraction System Rüstet den ausgewählten Helicopter mit einem Fast Rope Insertion Extraction System aus Wyposaża wybrany helikopter w zestaw Fast Rope Insertion Extraction System - Equipe l'hélicoptère sélectionné avec un Fast Rope Insertion Extraction System - Equipa el helicoptero seleccionado con un Sistema de Inserción Extracción Fast Rope + Équipe l'hélicoptère sélectionné avec un Fast Rope Insertion Extraction System (système d'hélicordage). + Equipa el helicoptero seleccionado con un Sistema de Inserción/Extracción Rápida por Cuerda Equipaggia l'elicottero selezionato con il Fast Rope Insertion Extraction System Vybavit vybraný vrtulník systémem Fast Rope Insertion Extraction (FRIES) Equipa um helicóptero selecionado com um sistema de Fast Rope Insertion Extraction System @@ -135,55 +144,129 @@ LET UNITS FAST ROPE EINHEITEN ABSEILEN LASSEN - SCENDI DALLE CORDE + FAI SCENDERE CON FASTROPE Equipa o helicóptero selecionado com o Fast Rope Insertion Extraction System - LAISSER LES UNITES UTILISER LA CORDE + LAISSER LES UNITÉS UTILISER LA CORDE ДЕСАНТИРОВАНИЕ ПО КАНАТУ - ユニットへファスト ロープをさせる + ユニットへファストロープをさせる ZJAZD NA LINACH 让单位快速绳降 讓單位快速繩降 - 패스트 로프를 놓음 + 유닛 패스트로프 시키기 + UMOŽNIT JEDNOTKÁM SLAŇOVAT + INDICAR A LAS UNIDADES DESCENDER POR LA CUERDA + + + Deploy 3m ropes + 3m Seile einsetzen + Déployer les cordes de 3 m + Wysuń linę o długości 3 m. + Выпустить 3 м канат + Jogar cordas (3m) + Dispiega corde da 3m + Připravit 3m lana + 3m halat sal + Desplegar cuerdas de 3m + 3m ロープを展開 + 部屬3公尺長之繩索 + 部署3米长的绳索 + 3m 줄 내리기 + + + Deploy 6m ropes + 6m Seile einsetzen + Déployer les cordes de 6 m + Wysuń linę o długości 6 m. + Выпустить 6 м канат + Jogar cordas (6m) + Dispiega corde da 6m + Připravit 6m lana + 6m halat sal + Desplegar cuerdas de 6m + 6m ロープを展開 + 部屬6公尺長之繩索 + 部署6米长的绳索 + 6m 줄 내리기 Deploy 12m ropes 12m Seile einsetzen - Déployer les cordes 12m + Déployer les cordes de 12 m 12m ロープを展開 Wysuń linę o długości 12 m. Выпустить 12 м канат + Jogar cordas (12m) + 部屬12公尺長之繩索 + 部署12米长的绳索 + Dispiega corde da 12m + Připravit 12m lana + 12m halat sal + Desplegar cuerdas de 12m + 12m 줄 내리기 Deploy 15m ropes 15m Seile einsetzen - Déployer les cordes 15m + Déployer les cordes de 15 m 15m ロープを展開 Wysuń linę o długości 15 m. Выпустить 15 м канат + Jogar cordas (15m) + 部屬15公尺長之繩索 + 部署15米长的绳索 + Dispiega corde da 15m + Připravit 15m lana + 15m halat sal + Desplegar cuerdas de 15m + 15m 줄 내리기 Deploy 18m ropes 18m Seile einsetzen - Déployer les cordes 18m + Déployer les cordes de 18 m 18m ロープを展開 Wysuń linę o długości 18 m. Выпустить 18 м канат + Jogar cordas (18m) + 部屬18公尺長之繩索 + 部署18米长的绳索 + Dispiega corde da 18m + Připravit 18m lana + 18m halat sal + Desplegar cuerdas de 18m + 18m 줄 내리기 Deploy 27m ropes 27m Seile einsetzen - Déployer les cordes 27m + Déployer les cordes de 27 m 27m ロープを展開 Wysuń linę o długości 27 m. Выпустить 27 м канат + Jogar cordas (27m) + 部屬27公尺長之繩索 + 部署27米长的绳索 + Dispiega corde da 27m + Připravit 27m lana + 27m halat sal + Desplegar cuerdas de 27m + 27m 줄 내리기 Deploy 36m ropes 36m Seile einsetzen - Déployer les cordes 36m + Déployer les cordes de 36 m 36m ロープを展開 Wysuń linę o długości 36 m. Выпустить 36 м канат + Jogar cordas (36m) + 部屬36公尺長之繩索 + 部署36米长的绳索 + Dispiega corde da 36m + Připravit 36m lana + 36m halat sal + Desplegar cuerdas de 36m + 36m 줄 내리기 [ACE] Ropes Supply crate @@ -192,62 +275,69 @@ [ACE] ロープ収納箱 Skrzynia z linami ACE [ACE] Ящик с канатами + [ACE] Suprimento de cordas + [ACE] 繩索補充箱 + [ACE] 绳索补给箱 + [ACE] Cassa Corde + [ACE] Bedna s lany + [ACE] Halat Sandığı + [ACE] Caja de suministros - cuerdas + [ACE] 하강줄 보급 상자 - - 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 - Используется для выпуска канатов с совместимого вертолета - - - Rope 12.2 meters - 12.2 Meter Seil - Corde 12.2 mètres - ロープ (12.2 メートル) - Lina, długość 12,2 m. - Канат 12.2 метров - - - Rope 15.2 meters - 15.2 Meter Seil - Corde 15.2 mètres - ロープ (15.2 メートル) - Lina, długość 15,2 m. - Канат 15.2 метров - - - Rope 18.3 meters - 18.3 Meter Seil - Corde 18.3 mètres - ロープ (18.3 メートル) - Lina, długość 18,3 m. - Канат 18.3 метров - - - Rope 27.4 meters - 27.4 Meter Seil - Corde 27.4 mètres - ロープ (27.4 メートル) - Lina, długość 27,4 m. - Канат 27.4 метров - - - Rope 36.6 meters - 36.6 Meter Seil - Corde 36.6 mètres - ロープ (36.6 メートル) - Lina, długość 36,6 m. - Канат 36.6 метров + + Fast-roping + Hélicordage + 快速繩降 + 快速索降 + ファストロープ + Cuerdas rápidas + Zjazd na linach + Halatla Kayma + Slaňování + Спуск по канату + Schnelles-Abseilen + Fast Rope + 패스트로프 Require rope item to deploy Seil-Item zum aufbauen benötigt - Exiger une corde pour déployer + Corde requise pour le déploiement 展開にはロープ アイテムを必須に Wymaga przedmiotu typu lina Требуется канат + Requer uma corda para jogar + 需要繩索來部屬 + 需要绳索来部署 + Richiede una corda per il dispigamento + Požadovat předmět lana pro slaňování + Requiere una cuerda para desplegar + Halatla kaymak için halat gerekli + 줄이 필요합니다 + + + Auto-Equip FRIES + Automatycznie Zamontuj FRIES + FRIESの自動装備 + FRIES automatisch ausrüsten + Auto-Aggiungi FRIES + FRIES 로프 자동 장착 + Equipement automatique FRIES + Auto-equipar FRIES + Авто-подготовка канатов + Auto-Equipar FRIES + + + Automatically add FRIES to helicopters that support them. + Automatycznie dodawaj FRIES do śmigłowców które je wspierają. + FRIESをサポートするヘリコプターに自動的にFRIESを追加します。 + FRIES automatisch Helikoptern hinzufügen, die es unterstützen + Aggiunge il sistema FRIES in automatico su elicotteri compatibili. + 로프를 지원하는 헬기에 자동으로 FRIES 로프를 추가합니다. + Ajoute automatiquement des FRIES aux hélicoptères qui les supportent. + Adiciona automaticamente FRIES a helicópteros que os suportam. + Автоматически добавляйте канаты в вертолеты, которые их поддерживают. + Añadir automáticamente el FRIES a los helicópteros que lo soporten. diff --git a/addons/fcs/ACE_UI.hpp b/addons/fcs/ACE_UI.hpp index c285248b83..98f4073122 100644 --- a/addons/fcs/ACE_UI.hpp +++ b/addons/fcs/ACE_UI.hpp @@ -1,7 +1,7 @@ class ACE_UI { class gunnerZeroing { class conditions { - ADDON = QUOTE(getNumber ([ARR_2(vehicle ACE_player, ACE_player call CBA_fnc_turretPath)] call CBA_fnc_getTurret >> 'ace_fcs_enabled') != 1); + ADDON = QUOTE(getNumber ([ARR_2(vehicle ACE_player,ACE_player call CBA_fnc_turretPath)] call CBA_fnc_getTurret >> 'ace_fcs_enabled') != 1); }; }; }; diff --git a/addons/fcs/CfgEventHandlers.hpp b/addons/fcs/CfgEventHandlers.hpp index 9c5c368307..d82354ea52 100644 --- a/addons/fcs/CfgEventHandlers.hpp +++ b/addons/fcs/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/fcs/CfgVehicles.hpp b/addons/fcs/CfgVehicles.hpp index 8461fcc05a..a8b9660393 100644 --- a/addons/fcs/CfgVehicles.hpp +++ b/addons/fcs/CfgVehicles.hpp @@ -27,7 +27,7 @@ class CfgVehicles { class ResetFCS { displayName = CSTRING(ResetFCS); condition = QUOTE(_player call FUNC(canResetFCS)); - statement = QUOTE([ARR_2(vehicle _player,[_player] call DEFUNC(common,getTurretIndex))] call DFUNC(reset);); + statement = QUOTE([ARR_2(vehicle _player,[_player] call DEFUNC(common,getTurretIndex))] call DFUNC(reset)); showDisabled = 0; icon = ""; }; @@ -39,7 +39,7 @@ class CfgVehicles { class ResetFCS { displayName = CSTRING(ResetFCS); condition = QUOTE(_player call FUNC(canResetFCS)); - statement = QUOTE([ARR_2(vehicle _player,[_player] call DEFUNC(common,getTurretIndex))] call DFUNC(reset);); + statement = QUOTE([ARR_2(vehicle _player,[_player] call DEFUNC(common,getTurretIndex))] call DFUNC(reset)); showDisabled = 0; icon = ""; }; diff --git a/addons/fcs/README.md b/addons/fcs/README.md index c4abbe3253..abe08d726e 100644 --- a/addons/fcs/README.md +++ b/addons/fcs/README.md @@ -2,11 +2,3 @@ ace_fcs ======= Adds a fire control system to armoured vehicles and helicopters, allowing precise engagement of stationary and moving targets. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/fcs/XEH_postInit.sqf b/addons/fcs/XEH_postInit.sqf index 08bb3fe1de..a63b03c5d9 100644 --- a/addons/fcs/XEH_postInit.sqf +++ b/addons/fcs/XEH_postInit.sqf @@ -6,7 +6,7 @@ GVAR(position) = [0,0,0]; if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" ["ace_infoDisplayChanged", { if (!isNull ((_this select 0) displayCtrl 1713151)) then { @@ -18,6 +18,12 @@ if (!hasInterface) exitWith {}; // Register event for global updates [QGVAR(forceUpdate), {[ACE_player] call FUNC(onForceUpdate)}] call CBA_fnc_addEventHandler; +[QGVAR(addFiredEH), { + TRACE_1("Adding firedEH",_this); + ["ace_firedPlayerVehicle", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; +}] call CBA_fnc_addEventHandler; + #ifdef DEBUG_MODE_FULL call compile preprocessFileLineNumbers QPATHTOF(dev\test_debugConfigs.sqf); #endif 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/fcs/dev/test_debugConfigs.sqf b/addons/fcs/dev/test_debugConfigs.sqf index 89fa6b0d31..c373912363 100644 --- a/addons/fcs/dev/test_debugConfigs.sqf +++ b/addons/fcs/dev/test_debugConfigs.sqf @@ -30,7 +30,7 @@ private _problemUIs = []; }; } forEach _weapons; - if (!(_weapons isEqualTo [])) then { + if (_weapons isNotEqualTo []) then { private _fcsMsg = switch (true) do { // case ((!_vanillaFCS) && {!_aceFCS}): {"No FCS"}; // case ((_vanillaFCS) && {_aceFCS}): {"CONFLICT FCS"}; diff --git a/addons/fcs/functions/fnc_adjustRange.sqf b/addons/fcs/functions/fnc_adjustRange.sqf index cb0e00c9c1..96cfa35364 100644 --- a/addons/fcs/functions/fnc_adjustRange.sqf +++ b/addons/fcs/functions/fnc_adjustRange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Adjusts the currently zeroed distance. @@ -19,7 +19,7 @@ params ["_vehicle", "_turret", "_delta"]; -private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); +private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); private _min = getNumber (_turretConfig >> QGVAR(MinDistance)); private _max = getNumber (_turretConfig >> QGVAR(MaxDistance)); diff --git a/addons/fcs/functions/fnc_calculateSolution.sqf b/addons/fcs/functions/fnc_calculateSolution.sqf index 8ceb0c62cf..b0cb2ea1c4 100644 --- a/addons/fcs/functions/fnc_calculateSolution.sqf +++ b/addons/fcs/functions/fnc_calculateSolution.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: VKing * Calculate FCS solution @@ -23,7 +23,7 @@ TRACE_4("params",_vehicle,_turret,_distance,_angleTarget); private _FCSInitSpeed = []; private _FCSMagazines = []; private _FCSElevation = []; -private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); +private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); { private _magazine = _x; @@ -44,14 +44,13 @@ private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret if (_x != "this") then { _weaponMagazines append getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); }; - false - } count _muzzles; + } forEach _muzzles; // Fix the `in` operator being case sensitive and BI fucking up the spelling of their own classnames - private _weaponMagazinesCheck = _weaponMagazines apply {toLower _x}; + private _weaponMagazinesCheck = _weaponMagazines apply {toLowerANSI _x}; // Another BIS fix: ShotBullet simulation uses weapon initSpeed, others ignore it - if (toLower _magazine in _weaponMagazinesCheck && {_bulletSimulation == "shotBullet"}) exitWith { + if (toLowerANSI _magazine in _weaponMagazinesCheck && {_bulletSimulation == "shotBullet"}) exitWith { private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); if (_initSpeedCoef < 0) then { @@ -62,8 +61,7 @@ private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret _initSpeed = _initSpeedCoef; }; }; - false - } count (_vehicle weaponsTurret _turret); + } forEach (_vehicle weaponsTurret _turret); private _offset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, _angleTarget, _distance]; _offset = parseNumber _offset; @@ -72,8 +70,7 @@ private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret _FCSMagazines pushBack _magazine; _FCSElevation pushBack _offset; }; - false -} count (_vehicle magazinesTurret _turret); +} forEach (_vehicle magazinesTurret _turret); [_vehicle, format ["%1_%2", QGVAR(Distance), _turret], _distance] call EFUNC(common,setVariablePublic); [_vehicle, format ["%1_%2", QGVAR(InitSpeed), _turret], _FCSInitSpeed] call EFUNC(common,setVariablePublic); diff --git a/addons/fcs/functions/fnc_canResetFCS.sqf b/addons/fcs/functions/fnc_canResetFCS.sqf index 21811d9fd3..95e6d09a7f 100644 --- a/addons/fcs/functions/fnc_canResetFCS.sqf +++ b/addons/fcs/functions/fnc_canResetFCS.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Called from config. Can player reset FCS? diff --git a/addons/fcs/functions/fnc_canUseFCS.sqf b/addons/fcs/functions/fnc_canUseFCS.sqf index a246d51f0c..4ebe28f3be 100644 --- a/addons/fcs/functions/fnc_canUseFCS.sqf +++ b/addons/fcs/functions/fnc_canUseFCS.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called from config. Returns true if the player is a gunner and the players current vehicle has a FCS. @@ -15,7 +15,7 @@ * Public: No */ -getNumber ([configFile >> "CfgVehicles" >> typeOf vehicle ACE_player, [ACE_player] call EFUNC(common,getTurretIndex)] call EFUNC(common,getTurretConfigPath) >> QGVAR(Enabled)) == 1 +getNumber ([configOf vehicle ACE_player, [ACE_player] call EFUNC(common,getTurretIndex)] call EFUNC(common,getTurretConfigPath) >> QGVAR(Enabled)) == 1 && {cameraView == "GUNNER"} && {!([ACE_player] call CBA_fnc_canUseWeapon)} //Not Turned Out && {cameraOn != (getConnectedUAV ACE_player)} //Not Controlling a UAV diff --git a/addons/fcs/functions/fnc_canUseRangefinder.sqf b/addons/fcs/functions/fnc_canUseRangefinder.sqf index b558240363..ea9d65556e 100644 --- a/addons/fcs/functions/fnc_canUseRangefinder.sqf +++ b/addons/fcs/functions/fnc_canUseRangefinder.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns true if the laser distance measurement can be read from the engine. diff --git a/addons/fcs/functions/fnc_firedEH.sqf b/addons/fcs/functions/fnc_firedEH.sqf index 0959708bb0..e99416593a 100644 --- a/addons/fcs/functions/fnc_firedEH.sqf +++ b/addons/fcs/functions/fnc_firedEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Adjusts the direction of a shell. Called from the unified fired EH only if the gunner is a player. @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); private _FCSMagazines = _vehicle getVariable [format ["%1_%2", QGVAR(Magazines), _turret], []]; @@ -39,7 +39,7 @@ private _initSpeed = 0; private _zeroDistance = currentZeroing _gunner; if (_zeroDistance > 0) then { private _weaponCombo = [_weapon, _magazine, _ammo, _zeroDistance]; - if !(_weaponCombo isEqualTo (_gunner getVariable [QGVAR(lastWeaponCombo), []])) then { + if (_weaponCombo isNotEqualTo (_gunner getVariable [QGVAR(lastWeaponCombo), []])) then { private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); private _antiOffset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, 0, _zeroDistance]; _antiOffset = parseNumber _antiOffset; @@ -50,7 +50,7 @@ if (_zeroDistance > 0) then { private _antiOffset = _gunner getVariable QGVAR(lastAntiOffset); _offset = _offset - _antiOffset; - TRACE_4("fired",_gunner, currentZeroing _gunner, _antiOffset, _offset); + TRACE_4("fired",_gunner,currentZeroing _gunner,_antiOffset,_offset); }; [_projectile, (_vehicle getVariable format ["%1_%2", QGVAR(Azimuth), _turret]), _offset, 0] call EFUNC(common,changeProjectileDirection); @@ -72,5 +72,5 @@ if (getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(Airburst)) == 1) then { if (_zeroing < 50) exitWith {}; if (_zeroing > 1500) exitWith {}; - [FUNC(handleAirBurstAmmunitionPFH), 0, [_vehicle, _projectile, _zeroing]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(handleAirBurstAmmunitionPFH), 0, [_vehicle, _projectile, _zeroing]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/fcs/functions/fnc_getAngle.sqf b/addons/fcs/functions/fnc_getAngle.sqf index 05add960fb..9a856d46c9 100644 --- a/addons/fcs/functions/fnc_getAngle.sqf +++ b/addons/fcs/functions/fnc_getAngle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Calculates the angle offset necessary to hit the current target. diff --git a/addons/fcs/functions/fnc_getRange.sqf b/addons/fcs/functions/fnc_getRange.sqf index 0512359d1e..7b24e61445 100644 --- a/addons/fcs/functions/fnc_getRange.sqf +++ b/addons/fcs/functions/fnc_getRange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Read laser distance measurement from engine. diff --git a/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf b/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf index a2fe8a2b7f..f90231b371 100644 --- a/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf +++ b/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle Air burst ammunition. Called from per frame handler. @@ -10,7 +10,7 @@ * None * * Example: - * [[array]] call ace_fcs_fnc_handleAirBurstAummunitionPFH + * [[array]] call ace_fcs_fnc_handleAirBurstAmmunitionPFH * * Public: No */ diff --git a/addons/fcs/functions/fnc_keyDown.sqf b/addons/fcs/functions/fnc_keyDown.sqf index 0e141c0968..9137100b84 100644 --- a/addons/fcs/functions/fnc_keyDown.sqf +++ b/addons/fcs/functions/fnc_keyDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Starts watching the target for sideways correction. @@ -18,7 +18,7 @@ params ["_vehicle", "_turret"]; -private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); +private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); // Update display for infantry rangefinders if (_vehicle == ACE_player) exitWith {[5,5500,25,true] call FUNC(getRange)}; diff --git a/addons/fcs/functions/fnc_keyUp.sqf b/addons/fcs/functions/fnc_keyUp.sqf index fb3ce99974..f7b9d88c8f 100644 --- a/addons/fcs/functions/fnc_keyUp.sqf +++ b/addons/fcs/functions/fnc_keyUp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Calculates the offsets for all weapons needed to hit the current target. @@ -19,7 +19,7 @@ params ["_vehicle", "_turret", "_distance", ["_showHint", false], ["_playSound", true]]; TRACE_5("params",_vehicle,_turret,_distance,_showHint,_playSound); -private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); +private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); if (isNil "_distance") then { _distance = [ diff --git a/addons/fcs/functions/fnc_onForceUpdate.sqf b/addons/fcs/functions/fnc_onForceUpdate.sqf index ddf426d293..b1e3f0c4bd 100644 --- a/addons/fcs/functions/fnc_onForceUpdate.sqf +++ b/addons/fcs/functions/fnc_onForceUpdate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * diff --git a/addons/fcs/functions/fnc_reset.sqf b/addons/fcs/functions/fnc_reset.sqf index 4cbc4ee7b2..437d5577d3 100644 --- a/addons/fcs/functions/fnc_reset.sqf +++ b/addons/fcs/functions/fnc_reset.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Resets the FCS to default. diff --git a/addons/fcs/functions/fnc_updateRangeHUD.sqf b/addons/fcs/functions/fnc_updateRangeHUD.sqf index a00de5fc67..29e23ee05c 100644 --- a/addons/fcs/functions/fnc_updateRangeHUD.sqf +++ b/addons/fcs/functions/fnc_updateRangeHUD.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Update compatible info elements. diff --git a/addons/fcs/functions/fnc_vehicleInit.sqf b/addons/fcs/functions/fnc_vehicleInit.sqf index 4647677f8a..f2d9d8192a 100644 --- a/addons/fcs/functions/fnc_vehicleInit.sqf +++ b/addons/fcs/functions/fnc_vehicleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Checks if a vehicle is equipped with an FCS and if so, adds the fired event handler. Execute on server. @@ -18,14 +18,12 @@ params ["_vehicle"]; { - private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _x] call EFUNC(common,getTurretConfigPath); + private _turretConfig = [configOf _vehicle, _x] call EFUNC(common,getTurretConfigPath); if (getNumber (_turretConfig >> QGVAR(Enabled)) == 1) then { - if (missionNamespace getVariable [QGVAR(needToAddFiredEH), true]) then { - ["ace_firedPlayerVehicle", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicleNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; - GVAR(needToAddFiredEH) = false; - TRACE_1("Registered fired event handlers for all vehicles",GVAR(needToAddFiredEH)); + if (isNil QGVAR(jipID)) then { + GVAR(jipID) = [QGVAR(addFiredEH), [], QGVAR(addFiredEH)] call CBA_fnc_globalEventJIP; + TRACE_1("Adding fired EH for players",GVAR(jipID)); }; _vehicle setVariable [format ["%1_%2", QGVAR(Distance), _x], 0, true]; @@ -48,5 +46,4 @@ params ["_vehicle"]; _vehicle setVariable [format ["%1_%2", QGVAR(ViewDiff), _x], 0, true]; }; }; - false -} count allTurrets _vehicle; +} forEach allTurrets _vehicle; diff --git a/addons/fcs/functions/script_component.hpp b/addons/fcs/functions/script_component.hpp deleted file mode 100644 index 179c66c15e..0000000000 --- a/addons/fcs/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\fcs\script_component.hpp" \ No newline at end of file diff --git a/addons/fcs/initKeybinds.sqf b/addons/fcs/initKeybinds.inc.sqf similarity index 100% rename from addons/fcs/initKeybinds.sqf rename to addons/fcs/initKeybinds.inc.sqf diff --git a/addons/fcs/stringtable.xml b/addons/fcs/stringtable.xml index 93d8121058..2f3ae894b1 100644 --- a/addons/fcs/stringtable.xml +++ b/addons/fcs/stringtable.xml @@ -4,17 +4,17 @@ Lase Target / Measure Distance Ziel anlasern / Entfernung messen - Télémétrer la cible + SCT - Illuminer la cible/Mesurer la distance Naświetl cel / Zmierz odległość Označit cíl / Změřit vzdálenost Iluminar objetivo / Medir distancia Подсветить цель / Замерить расстояние Célpont lézerezése / Távolság Bemérése - Misura la distanza + Telemetra bersaglio / Rileva distanza Marcar com laser / Medir Distância レーザー ターゲット / 計測距離 목표까지 거리를 레이저로 취득 - 雷射指示目标 / 测量距离 + 激光照射目标/测量距离 雷射指示目標 / 測量距離 @@ -23,14 +23,14 @@ Ajustado a Wyzerowany na Nastaveno na - Remise à zéro à + Zéroté à Выставлено на Nullázási táv Fixado em - Azzeramento a + Azzerato a 次にゼロイン 영점 조절 - 归零到 + 已归零到 歸零到 @@ -39,14 +39,14 @@ Zwiększ zasięg SKO Ajustar distancia del FCS (arriba) Nastavit FCS Náměr (Nahoru) - Augmenter la distance du SCT + SCT - Augmenter la portée FCS tartomány állítása (Fel) Ajustar distância do FCS (Acima) - Aumentare la distanza dell'FCS - Диапазон СУО (Выше) - FCS による距離を調節 (上げ) + Aumenta la portata dell'FCS + Диапазон СУО (выше) + FCS 距離を調節 (上げ) 사통장치 거리 조정 (위로) - 调整火控系统距离 (上) + 调整火控系统距离(上调) 調整火控系統距離 (上) @@ -55,14 +55,14 @@ Zmniejsz zasięg SKO Ajustar distancia del FCS (abajo) Nastavit FCS Náměr (Dolů) - Réduire la distance du SCT + SCT - Réduire la portée FCS tartomány állítása (Le) Ajustar distância do FCS (Abaixo) - Ridurre la distanza dell'FCS - Диапазон СУО (Ниже) - FCS による距離を調節 (下げ) + Riduci la portata dell'FCS + Диапазон СУО (ниже) + FCS 距離を調節 (下げ) 사통장치 거리 조정 (아래로) - 调整火控系统距离 (下) + 调整火控系统距离(下调) 調整火控系統距離 (下) @@ -85,7 +85,7 @@ FCS has been reset. FLS wurde zurückgesetzt. FCS reiniciado - SCT réinitialisé. + SCT réinitialisé SKO został zresetowany. FCS byl resetován. FCS visszaállítva. diff --git a/addons/field_rations/$PBOPREFIX$ b/addons/field_rations/$PBOPREFIX$ new file mode 100644 index 0000000000..26d4a0f4b6 --- /dev/null +++ b/addons/field_rations/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\field_rations diff --git a/addons/field_rations/Cfg3DEN.hpp b/addons/field_rations/Cfg3DEN.hpp new file mode 100644 index 0000000000..af25bbd021 --- /dev/null +++ b/addons/field_rations/Cfg3DEN.hpp @@ -0,0 +1,24 @@ +#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) +#define DEFAULT_WATER_SUPPLY GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQXGVAR(waterSupply),REFILL_WATER_DISABLED) + +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class XGVAR(waterSupply) { + displayName = CSTRING(WaterSupply_3DEN_DisplayName); + tooltip = CSTRING(WaterSupply_3DEN_Description); + property = QXGVAR(waterSupply); + control = "EditShort"; + expression = QUOTE(if (_value != DEFAULT_WATER_SUPPLY) then {_this setVariable [ARR_3(QQGVAR(currentWaterSupply),_value,true)]}); + defaultValue = QUOTE(DEFAULT_WATER_SUPPLY); + validate = "NUMBER"; + condition = "(1 - objectBrain) * (1 - objectAgent)"; + typeName = "NUMBER"; + }; + }; + }; + }; + }; +}; diff --git a/addons/field_rations/CfgEventHandlers.hpp b/addons/field_rations/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/field_rations/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/field_rations/CfgMoves.hpp b/addons/field_rations/CfgMoves.hpp new file mode 100644 index 0000000000..dd0a23b829 --- /dev/null +++ b/addons/field_rations/CfgMoves.hpp @@ -0,0 +1,67 @@ +class CfgMovesBasic; +class CfgMovesMaleSdr: CfgMovesBasic { + class States { + class CutSceneAnimationBase; + class GVAR(drinkStand): CutSceneAnimationBase { + file = QPATHTOF(anim\drink_stand.rtm); + actions = "CivilStandActions"; + speed = 0.1; + disableWeapons = 1; + disableWeaponsLong = 1; + canReload = 0; + canPullTrigger = 0; + showWeaponAim = 0; + looped = 0; + head = "headNo"; + aiming = "aimingNo"; + legs = "legsNo"; + connectTo[] = {"AmovPercMstpSnonWnonDnon", 0.1}; + interpolateFrom[] = {"AmovPercMstpSnonWnonDnon", 0.1}; + interpolateTo[] = {"Unconscious", 0.1}; + }; + class GVAR(drinkCrouch): GVAR(drinkStand) { + file = QPATHTOF(anim\drink_crouch.rtm); + actions = "CivilKneelActions"; + connectTo[] = {"AmovPknlMstpSnonWnonDnon", 0.1}; + interpolateFrom[] = {"AmovPknlMstpSnonWnonDnon", 0.1}; + }; + class GVAR(drinkProne): GVAR(drinkStand) { + file = QPATHTOF(anim\drink_prone.rtm); + actions = "CivilProneActions"; + connectTo[] = {"AmovPpneMstpSnonWnonDnon", 0.1}; + interpolateFrom[] = {"AmovPpneMstpSnonWnonDnon", 0.1}; + }; + class GVAR(drinkStandCan): GVAR(drinkStand) { + file = QPATHTOF(anim\drink_stand_can.rtm); + speed = "1/9"; + }; + class GVAR(drinkCrouchCan): GVAR(drinkCrouch) { + file = QPATHTOF(anim\drink_crouch_can.rtm); + speed = "1/9"; + }; + class GVAR(drinkProneCan): GVAR(drinkProne) { + file = QPATHTOF(anim\drink_prone_can.rtm); + speed = "1/9"; + }; + class GVAR(drinkFromSource): GVAR(drinkStand) { + file = QPATHTOF(anim\drink_source.rtm); + speed = "1/8"; + }; + class GVAR(drinkFromSourceHigh): GVAR(drinkFromSource) { + file = QPATHTOF(anim\drink_source_high.rtm); + }; + class GVAR(drinkFromSourceLow): GVAR(drinkFromSource) { + file = QPATHTOF(anim\drink_source_low.rtm); + }; + class GVAR(drinkFromSourceSquat): GVAR(drinkFromSource) { + file = QPATHTOF(anim\drink_source_squat.rtm); + interpolateFrom[] = {"AmovPercMstpSnonWnonDnon", 0.1, "AmovPknlMstpSnonWnonDnon", 0.1}; + }; + class GVAR(drinkFromSourceSquatHigh): GVAR(drinkFromSourceSquat) { + file = QPATHTOF(anim\drink_source_squat_high.rtm); + }; + class GVAR(drinkFromSourceSquatLow): GVAR(drinkFromSourceSquat) { + file = QPATHTOF(anim\drink_source_squat_low.rtm); + }; + }; +}; diff --git a/addons/field_rations/CfgSounds.hpp b/addons/field_rations/CfgSounds.hpp new file mode 100644 index 0000000000..ca937d5e54 --- /dev/null +++ b/addons/field_rations/CfgSounds.hpp @@ -0,0 +1,22 @@ +class CfgSounds { + class GVAR(drink1) { + name = QGVAR(drink1); + sound[] = {QPATHTOF(sounds\drink1.ogg), 1, 1}; + titles[] = {}; + }; + class GVAR(drink2) { + name = QGVAR(drink2); + sound[] = {QPATHTOF(sounds\drink2.ogg), 1, 1}; + titles[] = {}; + }; + class GVAR(drinkCan1) { + name = QGVAR(drinkCan1); + sound[] = {QPATHTOF(sounds\drink_can1.ogg), 1, 1}; + titles[] = {}; + }; + class GVAR(drinkCan2) { + name = QGVAR(drinkCan2); + sound[] = {QPATHTOF(sounds\drink_can2.ogg), 1, 1}; + titles[] = {}; + }; +}; diff --git a/addons/field_rations/CfgUIGrids.hpp b/addons/field_rations/CfgUIGrids.hpp new file mode 100644 index 0000000000..9c02c00945 --- /dev/null +++ b/addons/field_rations/CfgUIGrids.hpp @@ -0,0 +1,29 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + XGVAR(grid)[] = { + { + QUOTE(safeZoneX + safeZoneW - 4.2 * GUI_GRID_W), + QUOTE(safeZoneY + safeZoneH - 2.2 * GUI_GRID_H), + QUOTE(4 * GUI_GRID_W), + QUOTE(2 * GUI_GRID_H) + }, + QUOTE(GUI_GRID_W), + QUOTE(GUI_GRID_H) + }; + }; + }; + }; + class Variables { + class XGVAR(grid) { + displayName = CSTRING(IGUI_DisplayName); + description = CSTRING(IGUI_Description); + preview = QPATHTOF(ui\igui_preview.paa); + saveToProfile[] = {0, 1}; + canResize = 0; + }; + }; + }; +}; diff --git a/addons/field_rations/CfgVehicles.hpp b/addons/field_rations/CfgVehicles.hpp new file mode 100644 index 0000000000..680a55afbc --- /dev/null +++ b/addons/field_rations/CfgVehicles.hpp @@ -0,0 +1,294 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ADDON { + displayName = CSTRING(MainInteractionText); + condition = QUOTE(XGVAR(enabled)); + exceptions[] = {"isNotInside"}; + statement = QUOTE(GVAR(hudInteractionHover) = true; [] call FUNC(handleHUD)); + runOnHover = 1; + insertChildren = QUOTE(_player call FUNC(getConsumableChildren)); + icon = QPATHTOF(ui\icon_survival.paa); + }; + }; + }; + + class ACE_LogicDummy; + class GVAR(helper): ACE_LogicDummy {}; + + class Items_base_F; + class Land_WaterBarrel_F: Items_base_F { + XGVAR(waterSupply) = 200; + XGVAR(offset)[] = {0, 0, 0.6}; + }; + class Land_BarrelWater_F: Items_base_F { + XGVAR(waterSupply) = 160; + XGVAR(offset)[] = {0, 0, 0.25}; + }; + class Land_BarrelWater_grey_F: Items_base_F { + XGVAR(waterSupply) = 160; + XGVAR(offset)[] = {0, 0, 0.25}; + }; + class Land_WaterTank_F: Items_base_F { + XGVAR(waterSupply) = 600; + XGVAR(offset)[] = {1.15, 0, 0.65}; + }; + class Land_WaterCooler_01_new_F: Items_base_F { + XGVAR(waterSupply) = 20; + XGVAR(offset)[] = {0, -0.13, 0.1}; + }; + + class Infrastructure_base_F; + class Land_WaterTank_01_F: Infrastructure_base_F { + XGVAR(waterSupply) = 2400; + XGVAR(offset)[] = {0, -1.42, -0.78}; + }; + class Land_WaterTank_02_F: Infrastructure_base_F { + XGVAR(waterSupply) = 2400; + XGVAR(offset)[] = {-0.09, -1.45, 0.53}; + }; + class Land_WaterTank_03_F: Infrastructure_base_F { + XGVAR(waterSupply) = 200; + XGVAR(offset)[] = {0, 0, 0.44}; + }; + class Land_WaterTank_04_F: Infrastructure_base_F { + XGVAR(waterSupply) = 200; + XGVAR(offset)[] = {-0.155, -0.72, 0.37}; + }; + + class Stall_base_F; + class Land_StallWater_F: Stall_base_F { + XGVAR(waterSupply) = 250; + XGVAR(offset)[] = {0, -0.33, 0.4}; + }; + + class StorageBladder_base_F; + class Land_StorageBladder_02_F: StorageBladder_base_F { + XGVAR(offset)[] = {-2.02, 1.47, -0.02}; + }; + class StorageBladder_02_water_forest_F: Land_StorageBladder_02_F { + XGVAR(waterSupply) = 10000; + }; + class StorageBladder_02_water_sand_F: Land_StorageBladder_02_F { + XGVAR(waterSupply) = 10000; + }; + + class NonStrategic; + class Land_Water_source_F: NonStrategic { + XGVAR(waterSupply) = REFILL_WATER_INFINITE; + XGVAR(offset)[] = {0, -0.12, -0.25}; + }; + class House_Small_F; + class Land_ConcreteWell_02_F: House_Small_F { + XGVAR(waterSupply) = REFILL_WATER_INFINITE; + XGVAR(offset)[] = {0, 0, -0.25}; + }; + class Land_WaterPump_01_F; + class WaterPump_01_forest_F: Land_WaterPump_01_F { + XGVAR(waterSupply) = REFILL_WATER_INFINITE; + XGVAR(offset)[] = {0, -1.8, 0.06}; + }; + class WaterPump_01_sand_F: Land_WaterPump_01_F { + XGVAR(waterSupply) = REFILL_WATER_INFINITE; + XGVAR(offset)[] = {0, -1.8, 0.06}; + }; + + class Truck_02_water_base_F; + class C_IDAP_Truck_02_water_F: Truck_02_water_base_F { + XGVAR(waterSupply) = 10000; + XGVAR(offset)[] = {-0.03, -3.72, -1.05}; + }; + + class Item_Base_F; + class ACE_WaterBottle_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(WaterBottle_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_WaterBottle,1); + }; + }; + class ACE_WaterBottle_Half_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(WaterBottleHalf_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_WaterBottle_Half,1); + }; + }; + class ACE_WaterBottle_Empty_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(WaterBottleEmpty_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_WaterBottle_Empty,1); + }; + }; + class ACE_Canteen_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(Canteen_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Canteen,1); + }; + }; + class ACE_Canteen_Half_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(CanteenHalf_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Canteen_Half,1); + }; + }; + class ACE_Canteen_Empty_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(CanteenEmpty_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Canteen_Empty,1); + }; + }; + class ACE_Can_Spirit_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = "$STR_a3_cfgvehicles_land_can_v1_f0"; + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Can_Spirit,1); + }; + }; + class ACE_Can_Franta_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = "$STR_a3_cfgvehicles_land_can_v2_f0"; + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Can_Franta,1); + }; + }; + class ACE_Can_RedGull_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = "$STR_a3_cfgvehicles_land_can_v3_f0"; + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Can_RedGull,1); + }; + }; + class ACE_MRE_LambCurry_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_LambCurry_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_LambCurry,1); + }; + }; + class ACE_MRE_BeefStew_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_BeefStew_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_BeefStew,1); + }; + }; + class ACE_MRE_CreamTomatoSoup_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_CreamTomatoSoup_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_CreamTomatoSoup,1); + }; + }; + class ACE_MRE_CreamChickenSoup_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_CreamChickenSoup_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_CreamChickenSoup,1); + }; + }; + class ACE_MRE_ChickenTikkaMasala_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_ChickenTikkaMasala_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_ChickenTikkaMasala,1); + }; + }; + class ACE_MRE_SteakVegetables_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_SteakVegetables_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_SteakVegetables,1); + }; + }; + class ACE_MRE_MeatballsPasta_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_MeatballsPasta_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_MeatballsPasta,1); + }; + }; + class ACE_MRE_ChickenHerbDumplings_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(MRE_ChickenHerbDumplings_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_MRE_ChickenHerbDumplings,1); + }; + }; + class ACE_Humanitarian_Ration_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(Humanitarian_Ration_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Humanitarian_Ration,1); + }; + }; + class ACE_Sunflower_Seeds_Item: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(SunflowerSeeds_DisplayName); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_Sunflower_Seeds,1); + }; + }; +}; diff --git a/addons/field_rations/CfgWeapons.hpp b/addons/field_rations/CfgWeapons.hpp new file mode 100644 index 0000000000..b100ba4e90 --- /dev/null +++ b/addons/field_rations/CfgWeapons.hpp @@ -0,0 +1,249 @@ +class CfgWeapons { + /* + * Consumable Items Config Entries: + * -------------------------------- + * XGVAR(consumeText) - Text displayed for consumption progress bar + * XGVAR(consumeTime) - Time in seconds to consume item + * XGVAR(consumeAnims) - Array of animations [stand, crouch, prone] + * XGVAR(consumeSounds) - Array of sounds [stand, crouch, prone] + * XGVAR(thirstQuenched) - Thirst quenched on consumption + * XGVAR(hungerSatiated) - Hunger satiated on consumption + * XGVAR(replacementItem) - Replacement item on consumption (if any) + * XGVAR(refillItem) - Item added when refilled (makes item refillable) + * XGVAR(refillAmount) - Amount of water required to refill item + * XGVAR(refillTime) - Time in seconds to refill item + */ + + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + class ACE_Banana: ACE_ItemCore { + XGVAR(consumeTime) = 10; + XGVAR(hungerSatiated) = 3; + XGVAR(consumeText) = CSTRING(EatingX); + }; + + // - Water Bottles -------------------------------------------------------- + class ACE_WaterBottle: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(WaterBottle_DisplayName); + descriptionShort = CSTRING(WaterBottle_Description); + model = "\a3\structures_f_epa\items\food\bottleplastic_v2_f.p3d"; + picture = QPATHTOF(ui\item_waterbottle_full_co.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 5; + }; + XGVAR(consumeTime) = 10; + XGVAR(thirstQuenched) = 10; + XGVAR(consumeText) = CSTRING(DrinkingFromX); + XGVAR(replacementItem) = "ACE_WaterBottle_Half"; + XGVAR(consumeAnims)[] = {QGVAR(drinkStand), QGVAR(drinkCrouch), QGVAR(drinkProne)}; + XGVAR(consumeSounds)[] = {QGVAR(drink1), QGVAR(drink1), QGVAR(drink2)}; + ACE_isFieldRationItem = 1; + }; + + class ACE_WaterBottle_Half: ACE_WaterBottle { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(WaterBottleHalf_DisplayName); + descriptionShort = CSTRING(WaterBottleHalf_Description); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 3; + }; + XGVAR(replacementItem) = "ACE_WaterBottle_Empty"; + XGVAR(refillItem) = "ACE_WaterBottle"; + XGVAR(refillAmount) = 0.5; + XGVAR(refillTime) = 8; + }; + + class ACE_WaterBottle_Empty: ACE_WaterBottle { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(WaterBottleEmpty_DisplayName); + descriptionShort = CSTRING(WaterBottleEmpty_Description); + picture = QPATHTOF(ui\item_waterbottle_empty_co.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 1; + }; + XGVAR(thirstQuenched) = 0; + XGVAR(replacementItem) = ""; + XGVAR(refillItem) = "ACE_WaterBottle"; + XGVAR(refillAmount) = 1; + XGVAR(refillTime) = 8; + }; + + // - Canteens ------------------------------------------------------------- + class ACE_Canteen: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(Canteen_DisplayName); + descriptionShort = CSTRING(Canteen_Description); + model = "\a3\structures_f_epa\items\food\canteen_f.p3d"; + picture = QPATHTOF(ui\item_canteen_co.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 5; + }; + XGVAR(consumeTime) = 10; + XGVAR(thirstQuenched) = 10; + XGVAR(consumeText) = CSTRING(DrinkingFromX); + XGVAR(replacementItem) = "ACE_Canteen_Half"; + XGVAR(consumeAnims)[] = {QGVAR(drinkStand), QGVAR(drinkCrouch), QGVAR(drinkProne)}; + XGVAR(consumeSounds)[] = {QGVAR(drink1), QGVAR(drink1), QGVAR(drink2)}; + ACE_isFieldRationItem = 1; + }; + + class ACE_Canteen_Half: ACE_Canteen { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(CanteenHalf_DisplayName); + descriptionShort = CSTRING(CanteenHalf_Description); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 3; + }; + XGVAR(replacementItem) = "ACE_Canteen_Empty"; + XGVAR(refillItem) = "ACE_Canteen"; + XGVAR(refillAmount) = 0.5; + XGVAR(refillTime) = 8; + }; + + class ACE_Canteen_Empty: ACE_Canteen { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(CanteenEmpty_DisplayName); + descriptionShort = CSTRING(CanteenEmpty_Description); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 1; + }; + XGVAR(thirstQuenched) = 0; + XGVAR(replacementItem) = ""; + XGVAR(refillItem) = "ACE_Canteen"; + XGVAR(refillAmount) = 1; + XGVAR(refillTime) = 8; + }; + + // - Soda Cans ------------------------------------------------------------ + class ACE_Can_Spirit: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = "$STR_a3_cfgvehicles_land_can_v1_f0"; + descriptionShort = CSTRING(Can_Spirit_Description); + model = "\a3\structures_f\items\food\can_v1_f.p3d"; + picture = QPATHTOF(ui\icon_can_spirit_ca.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 3; + }; + XGVAR(consumeTime) = 10; + XGVAR(thirstQuenched) = 5; + XGVAR(consumeText) = CSTRING(DrinkingX); + XGVAR(consumeAnims)[] = {QGVAR(drinkStandCan), QGVAR(drinkCrouchCan), QGVAR(drinkProneCan)}; + XGVAR(consumeSounds)[] = {QGVAR(drinkCan1), QGVAR(drinkCan1), QGVAR(drinkCan2)}; + ACE_isFieldRationItem = 1; + }; + + class ACE_Can_Franta: ACE_Can_Spirit { + author = ECSTRING(common,ACETeam); + displayName = "$STR_a3_cfgvehicles_land_can_v2_f0"; + descriptionShort = CSTRING(Can_Franta_Description); + model = "\a3\structures_f\items\food\can_v2_f.p3d"; + picture = QPATHTOF(ui\icon_can_franta_ca.paa); + }; + + class ACE_Can_RedGull: ACE_Can_Spirit { + author = ECSTRING(common,ACETeam); + displayName = "$STR_a3_cfgvehicles_land_can_v3_f0"; + descriptionShort = CSTRING(Can_RedGull_Description); + model = "\a3\structures_f\items\food\can_v3_f.p3d"; + picture = QPATHTOF(ui\icon_can_redgull_ca.paa); + }; + + // - MREs ----------------------------------------------------------------- + class ACE_MRE_LambCurry: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(MRE_LambCurry_DisplayName); + descriptionShort = CSTRING(MRE_LambCurry_Description); + model = QPATHTOF(data\mre_type1.p3d); + picture = QPATHTOF(ui\item_mre_type1_co.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 5; + }; + XGVAR(consumeTime) = 10; + XGVAR(hungerSatiated) = 20; + XGVAR(consumeText) = CSTRING(EatingX); + ACE_isFieldRationItem = 1; + }; + + class ACE_MRE_BeefStew: ACE_MRE_LambCurry { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_BeefStew_DisplayName); + descriptionShort = CSTRING(MRE_BeefStew_Description); + model = QPATHTOF(data\mre_type2.p3d); + picture = QPATHTOF(ui\item_mre_type2_co.paa); + }; + + class ACE_MRE_CreamTomatoSoup: ACE_MRE_LambCurry { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_CreamTomatoSoup_DisplayName); + descriptionShort = CSTRING(MRE_CreamTomatoSoup_Description); + model = QPATHTOF(data\mre_type3.p3d); + picture = QPATHTOF(ui\item_mre_type3_co.paa); + }; + + class ACE_MRE_CreamChickenSoup: ACE_MRE_CreamTomatoSoup { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_CreamChickenSoup_DisplayName); + descriptionShort = CSTRING(MRE_CreamChickenSoup_Description); + }; + + class ACE_MRE_ChickenTikkaMasala: ACE_MRE_LambCurry { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_ChickenTikkaMasala_DisplayName); + descriptionShort = CSTRING(MRE_ChickenTikkaMasala_Description); + model = QPATHTOF(data\mre_type4.p3d); + picture = QPATHTOF(ui\item_mre_type4_co.paa); + }; + + class ACE_MRE_SteakVegetables: ACE_MRE_LambCurry { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_SteakVegetables_DisplayName); + descriptionShort = CSTRING(MRE_SteakVegetables_Description); + model = QPATHTOF(data\mre_type5.p3d); + picture = QPATHTOF(ui\item_mre_type5_co.paa); + }; + + class ACE_MRE_MeatballsPasta: ACE_MRE_LambCurry { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_MeatballsPasta_DisplayName); + descriptionShort = CSTRING(MRE_MeatballsPasta_Description); + model = QPATHTOF(data\mre_type6.p3d); + picture = QPATHTOF(ui\item_mre_type6_co.paa); + }; + + class ACE_MRE_ChickenHerbDumplings: ACE_MRE_MeatballsPasta { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(MRE_ChickenHerbDumplings_DisplayName); + descriptionShort = CSTRING(MRE_ChickenHerbDumplings_Description); + }; + + class ACE_Humanitarian_Ration: ACE_MRE_LambCurry { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Humanitarian_Ration_DisplayName); + descriptionShort = CSTRING(Humanitarian_Ration_Description); + model = QPATHTOF(data\mre_human.p3d); + picture = QPATHTOF(ui\item_mre_human_co.paa); + }; + + // - Misc Food ------------------------------------------------------------ + class ACE_Sunflower_Seeds: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(SunflowerSeeds_DisplayName); + descriptionShort = CSTRING(SunflowerSeeds_Description); + model = QPATHTOF(data\sunflower_seeds.p3d); + picture = QPATHTOF(ui\item_sunflowerseeds_co.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 3; + }; + XGVAR(consumeTime) = 10; + XGVAR(hungerSatiated) = 10; + XGVAR(consumeText) = CSTRING(EatingX); + ACE_isFieldRationItem = 1; + }; +}; diff --git a/addons/field_rations/README.md b/addons/field_rations/README.md new file mode 100644 index 0000000000..b178343e99 --- /dev/null +++ b/addons/field_rations/README.md @@ -0,0 +1,13 @@ +ace_field_rations +================== + +Provides a survival style, hunger and thirst system. +Adds consumable items such as MREs. + +## ACEX Conversion - things still using acex prefix +- All settings +- CfgUIGrids Entry +- CfgWeapon Configs (e.g. `acex_field_rations_thirstQuenched`) +- CfgVehicles Configs (e.g. `acex_field_rations_waterSupply`) +- Events (`acex_rationConsumed`, `acex_rationRefilled`) +- Player setVars for thirst/hunger (e.g. `player getVariable "acex_field_rations_thirst"`) diff --git a/addons/field_rations/RscTitles.hpp b/addons/field_rations/RscTitles.hpp new file mode 100644 index 0000000000..e156766ac7 --- /dev/null +++ b/addons/field_rations/RscTitles.hpp @@ -0,0 +1,80 @@ +class RscPicture; +class RscControlsGroupNoScrollbars; + +class RscTitles { + class GVAR(hudColoredIcons) { + idd = -1; + fadeIn = 0.5; + fadeOut = 0.5; + duration = 999999; + movingEnable = 0; + onLoad = QUOTE(SETUVAR(QGVAR(hudDisplay),_this select 0)); + class controls { + class Thirst: RscPicture { + idc = IDC_COLORED_HUD_THIRST; + x = QUOTE(profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),X))),safeZoneX + safeZoneW - 4.2 * GUI_GRID_W)]); + y = QUOTE(profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),Y))),safeZoneY + safeZoneH - 2.2 * GUI_GRID_H)]); + w = QUOTE(2 * GUI_GRID_W); + h = QUOTE(2 * GUI_GRID_H); + text = QPATHTOF(ui\icon_hud_thirststatus.paa); + }; + class Hunger: Thirst { + idc = IDC_COLORED_HUD_HUNGER; + x = QUOTE(2 * GUI_GRID_W + (profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),X))),safeZoneX + safeZoneW - 4.2 * GUI_GRID_W)])); + text = QPATHTOF(ui\icon_hud_hungerstatus.paa); + }; + }; + }; + class GVAR(hudDrainingIcons) { + idd = -1; + fadeIn = 0.5; + fadeOut = 0.5; + duration = 999999; + movingEnable = 0; + onLoad = QUOTE(SETUVAR(QGVAR(hudDisplay),_this select 0)); + class controlsBackground { + class Thirst: RscPicture { + idc = -1; + x = QUOTE(profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),X))),safeZoneX + safeZoneW - 4.2 * GUI_GRID_W)]); + y = QUOTE(profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),Y))),safeZoneY + safeZoneH - 2.2 * GUI_GRID_H)]); + w = QUOTE(2 * GUI_GRID_W); + h = QUOTE(2 * GUI_GRID_H); + text = QPATHTOF(ui\icon_hud_thirststatus.paa); + colorText[] = {1, 1, 1, 0.2}; + }; + class Hunger: Thirst { + x = QUOTE(2 * GUI_GRID_W + (profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),X))),safeZoneX + safeZoneW - 4.2 * GUI_GRID_W)])); + text = QPATHTOF(ui\icon_hud_hungerstatus.paa); + }; + }; + class controls { + class ThirstGroup: RscControlsGroupNoScrollbars { + idc = IDC_DRAINING_HUD_THIRST_GROUP; + x = QUOTE(profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),X))),safeZoneX + safeZoneW - 4.2 * GUI_GRID_W)]); + y = QUOTE(profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),Y))),safeZoneY + safeZoneH - 2.2 * GUI_GRID_H)]); + w = QUOTE(2 * GUI_GRID_W); + h = QUOTE(2 * GUI_GRID_H); + class controls { + class Icon: RscPicture { + idc = IDC_DRAINING_HUD_THIRST_ICON; + x = 0; + y = 0; + w = QUOTE(2 * GUI_GRID_W); + h = QUOTE(2 * GUI_GRID_H); + text = QPATHTOF(ui\icon_hud_thirststatus.paa); + }; + }; + }; + class HungerGroup: ThirstGroup { + idc = IDC_DRAINING_HUD_HUNGER_GROUP; + x = QUOTE(2 * GUI_GRID_W + (profileNamespace getVariable [ARR_2(QUOTE(QUOTE(TRIPLES(IGUI,XGVAR(grid),X))),safeZoneX + safeZoneW - 4.2 * GUI_GRID_W)])); + class controls: controls { + class Icon: Icon { + idc = IDC_DRAINING_HUD_HUNGER_ICON; + text = QPATHTOF(ui\icon_hud_hungerstatus.paa); + }; + }; + }; + }; + }; +}; diff --git a/addons/field_rations/XEH_PREP.hpp b/addons/field_rations/XEH_PREP.hpp new file mode 100644 index 0000000000..2035345f47 --- /dev/null +++ b/addons/field_rations/XEH_PREP.hpp @@ -0,0 +1,19 @@ +ACEX_PREP(addStatusModifier); +ACEX_PREP(addWaterSourceInteractions); +ACEX_PREP(canDrinkFromSource); +ACEX_PREP(canRefillItem); +ACEX_PREP(checkWater); +ACEX_PREP(consumeItem); +ACEX_PREP(drinkFromSource); +ACEX_PREP(getActionOffset); +ACEX_PREP(getConsumableChildren); +ACEX_PREP(getDrinkAnimation); +ACEX_PREP(getRefillChildren); +ACEX_PREP(getRemainingWater); +ACEX_PREP(handleEffects); +ACEX_PREP(handleHUD); +ACEX_PREP(handleRespawn); +ACEX_PREP(refillItem); +ACEX_PREP(scanFieldRations); +ACEX_PREP(setRemainingWater); +ACEX_PREP(update); diff --git a/addons/field_rations/XEH_postInit.sqf b/addons/field_rations/XEH_postInit.sqf new file mode 100644 index 0000000000..9fc8406aba --- /dev/null +++ b/addons/field_rations/XEH_postInit.sqf @@ -0,0 +1,143 @@ +#include "script_component.hpp" + +if !(hasInterface) exitWith {}; + +["ace_settingsInitialized", { + // Exit if not enabled + if (!XGVAR(enabled)) exitWith {}; + + // Add Advanced Fatigue duty factor + if (XGVAR(affectAdvancedFatigue) && {missionNamespace getVariable [QEGVAR(advanced_fatigue,enabled), false]}) then { + [QUOTE(ADDON), { + linearConversion [50, 100, _this getVariable [QXGVAR(thirst), 0], 1, 1.4, true] * linearConversion [50, 100, _this getVariable [QXGVAR(hunger), 0], 1, 1.1, true] + }] call EFUNC(advanced_fatigue,addDutyFactor); + TRACE_1("Added duty factor",XGVAR(affectAdvancedFatigue)); + }; + + // Compile water source actions + private _mainAction = [ + QGVAR(waterSource), + LLSTRING(WaterSource), + QPATHTOF(ui\icon_water_tap.paa), + {true}, + { + private _waterSource = _target getVariable [QGVAR(waterSource), objNull]; + + alive _waterSource + && {XGVAR(waterSourceActions) != 0} + && {_waterSource call FUNC(getRemainingWater) != REFILL_WATER_DISABLED} + && {[_player, _waterSource] call EFUNC(common,canInteractWith)} + }, + { + private _waterSource = _target getVariable [QGVAR(waterSource), objNull]; + [_waterSource, _player] call FUNC(getRefillChildren); + }, + [], + {[0, 0, 0]}, + 2, + [false, false, false, false, true] + ] call EFUNC(interact_menu,createAction); + + private _subActions = [ + [ + QGVAR(checkWater), + LLSTRING(CheckWater), + QPATHTOF(ui\icon_water_tap.paa), + { + private _waterSource = _target getVariable [QGVAR(waterSource), objNull]; + [_player, _waterSource] call FUNC(checkWater); + }, + { + private _waterSource = _target getVariable [QGVAR(waterSource), objNull]; + (_waterSource call FUNC(getRemainingWater)) != REFILL_WATER_INFINITE + } + ] call EFUNC(interact_menu,createAction), + [ + QGVAR(drinkFromSource), + LLSTRING(DrinkFromSource), + QPATHTOF(ui\icon_water_tap.paa), + { + private _waterSource = _target getVariable [QGVAR(waterSource), objNull]; + [_player, _waterSource] call FUNC(drinkFromSource); + }, + { + private _waterSource = _target getVariable [QGVAR(waterSource), objNull]; + [_player, _waterSource] call FUNC(canDrinkFromSource); + } + ] call EFUNC(interact_menu,createAction) + ]; + + // Add water source actions to helper + [QGVAR(helper), 0, [], _mainAction] call EFUNC(interact_menu,addActionToClass); + { + [QGVAR(helper), 0, [QGVAR(waterSource)], _x] call EFUNC(interact_menu,addActionToClass); + } forEach _subActions; + + // Add inventory context menu option to consume items + ["ACE_ItemCore", ["CONTAINER"], LSTRING(EatDrink), [], QPATHTOF(ui\icon_survival.paa), + [ + {true}, + { + params ["", "", "_item"]; + + XGVAR(enabled) && { + private _config = configFile >> "CfgWeapons" >> _item; + getNumber (_config >> QXGVAR(thirstQuenched)) > 0 + || {getNumber (_config >> QXGVAR(hungerSatiated)) > 0} + } + } + ], + { + params ["_unit", "", "_item"]; + private _itemConfig = configFile >> "CfgWeapons" >> _item; + [objNull, _unit, [_item, _itemConfig, false]] call FUNC(consumeItem); + false + } + ] call CBA_fnc_addItemContextMenuOption; + + // Add water source helpers when interaction menu is opened + ["ace_interactMenuOpened", LINKFUNC(addWaterSourceInteractions)] call CBA_fnc_addEventHandler; + + // Add status modifiers + if (GETEGVAR(medical,enabled,false)) then { + [0, { + if (_this getVariable [QEGVAR(medical,isBleeding), false]) exitWith { + 0.5 + }; + -1 * count (_this getVariable [QEGVAR(medical,ivBags), []]); + }] call FUNC(addStatusModifier); + }; + + if (["ace_weather"] call EFUNC(common,isModLoaded)) then { + [0, { + linearConversion [40, 60, missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25], 0, 1.5, true]; + }] call FUNC(addStatusModifier); + }; + + if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { + [2, { + if (_this getVariable [QEGVAR(dragging,isDragging), false] || {_this getVariable [QEGVAR(dragging,isCarrying), false]}) exitWith { + 1 + }; + 0 + }] call FUNC(addStatusModifier); + }; + + // Handle returning to normal transparency once interaction menu is closed + GVAR(hudInteractionHover) = false; + + ["ace_interactMenuClosed", { + GVAR(hudInteractionHover) = false; + }] call CBA_fnc_addEventHandler; + + // Add respawn eventhandler to reset necessary variables, done through script so only added if field rations is enabled + ["CAManBase", "respawn", LINKFUNC(handleRespawn)] call CBA_fnc_addClassEventHandler; + + // Start update loop + [LINKFUNC(update), CBA_missionTime + MP_SYNC_INTERVAL, 1] call CBA_fnc_waitAndExecute; + + #ifdef DEBUG_MODE_FULL + ["ACE_player thirst", {ACE_player getVariable [QXGVAR(thirst), 0]}, [true, 0, 100]] call EFUNC(common,watchVariable); + ["ACE_player hunger", {ACE_player getVariable [QXGVAR(hunger), 0]}, [true, 0, 100]] call EFUNC(common,watchVariable); + #endif +}] call CBA_fnc_addEventHandler; diff --git a/addons/field_rations/XEH_preInit.sqf b/addons/field_rations/XEH_preInit.sqf new file mode 100644 index 0000000000..e74e4086ca --- /dev/null +++ b/addons/field_rations/XEH_preInit.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +#define ARSENAL_CATEGORY_ICON QPATHTOF(ui\icon_survival.paa) + +// Init arrays of status modifiers +GVAR(thirstModifiers) = []; +GVAR(hungerModifiers) = []; + +private _cache = call (uiNamespace getVariable [QGVAR(cacheP3Ds), {ERROR("no cache")}]); // cache built at preStart +// List of p3d water sources (case sensitive) for objects that report `typeOf == ""` +GVAR(waterSourceP3Ds) = _cache select 0; +// List of refill action offsets corresponding to the p3ds in the array above +GVAR(waterSourceOffsets) = _cache select 1; + +// Custom Arsenal Tab +if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [keys FIELD_RATIONS_ITEMS, LLSTRING(DisplayName), ARSENAL_CATEGORY_ICON, -1, true] call EFUNC(arsenal,addRightPanelButton); +}; + +ADDON = true; diff --git a/addons/field_rations/XEH_preStart.sqf b/addons/field_rations/XEH_preStart.sqf new file mode 100644 index 0000000000..ebb22b6ee8 --- /dev/null +++ b/addons/field_rations/XEH_preStart.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" + +// List of p3d water sources (case sensitive) for objects that report `typeOf == ""` +private _waterSourceP3Ds = [ + "misc_wellpump.p3d" // [11899, 9150, 0] on chenarus +]; + +// List of refill action offsets corresponding to the p3ds in the array above +private _waterSourceOffsets = [ + [0, 0, 0] +]; + +// Fill water source arrays from CfgVehicles +{ + private _split = (getText (_x >> "model")) splitString "\"; + private _string = toLowerANSI (_split param [((count _split) - 1), ""]); + + // Append extension if necessary + if ((_string select [count _string - 4]) != ".p3d") then { + _string = _string + ".p3d" + }; + + private _index = _waterSourceP3Ds pushBackUnique _string; + if (_index != -1) then { + _waterSourceOffsets pushBack ([_x >> QXGVAR(offset), "ARRAY", [0, 0, 0]] call CBA_fnc_getConfigEntry); + }; +} forEach (QUOTE(isNumber (_x >> 'XGVAR(waterSupply)') && {(getNumber (_x >> 'XGVAR(waterSupply)')) != REFILL_WATER_DISABLED}) configClasses (configFile >> "CfgVehicles")); + +uiNamespace setVariable [QGVAR(cacheP3Ds), compileFinal str [_waterSourceP3Ds, _waterSourceOffsets]]; +TRACE_1("compiled",count _waterSourceP3Ds); + +call FUNC(scanFieldRations); diff --git a/addons/field_rations/anim/drink_crouch.rtm b/addons/field_rations/anim/drink_crouch.rtm new file mode 100644 index 0000000000..4d8930355a Binary files /dev/null and b/addons/field_rations/anim/drink_crouch.rtm differ diff --git a/addons/field_rations/anim/drink_crouch_can.rtm b/addons/field_rations/anim/drink_crouch_can.rtm new file mode 100644 index 0000000000..bed20d6392 Binary files /dev/null and b/addons/field_rations/anim/drink_crouch_can.rtm differ diff --git a/addons/field_rations/anim/drink_prone.rtm b/addons/field_rations/anim/drink_prone.rtm new file mode 100644 index 0000000000..6c3eb26ccc Binary files /dev/null and b/addons/field_rations/anim/drink_prone.rtm differ diff --git a/addons/field_rations/anim/drink_prone_can.rtm b/addons/field_rations/anim/drink_prone_can.rtm new file mode 100644 index 0000000000..150cae95e5 Binary files /dev/null and b/addons/field_rations/anim/drink_prone_can.rtm differ diff --git a/addons/field_rations/anim/drink_source.rtm b/addons/field_rations/anim/drink_source.rtm new file mode 100644 index 0000000000..dcbf78800a Binary files /dev/null and b/addons/field_rations/anim/drink_source.rtm differ diff --git a/addons/field_rations/anim/drink_source_high.rtm b/addons/field_rations/anim/drink_source_high.rtm new file mode 100644 index 0000000000..8053834a85 Binary files /dev/null and b/addons/field_rations/anim/drink_source_high.rtm differ diff --git a/addons/field_rations/anim/drink_source_low.rtm b/addons/field_rations/anim/drink_source_low.rtm new file mode 100644 index 0000000000..a97e9373b3 Binary files /dev/null and b/addons/field_rations/anim/drink_source_low.rtm differ diff --git a/addons/field_rations/anim/drink_source_squat.rtm b/addons/field_rations/anim/drink_source_squat.rtm new file mode 100644 index 0000000000..574c4e1f16 Binary files /dev/null and b/addons/field_rations/anim/drink_source_squat.rtm differ diff --git a/addons/field_rations/anim/drink_source_squat_high.rtm b/addons/field_rations/anim/drink_source_squat_high.rtm new file mode 100644 index 0000000000..b91cf4d2a9 Binary files /dev/null and b/addons/field_rations/anim/drink_source_squat_high.rtm differ diff --git a/addons/field_rations/anim/drink_source_squat_low.rtm b/addons/field_rations/anim/drink_source_squat_low.rtm new file mode 100644 index 0000000000..33e71498c3 Binary files /dev/null and b/addons/field_rations/anim/drink_source_squat_low.rtm differ diff --git a/addons/field_rations/anim/drink_stand.rtm b/addons/field_rations/anim/drink_stand.rtm new file mode 100644 index 0000000000..005399a79d Binary files /dev/null and b/addons/field_rations/anim/drink_stand.rtm differ diff --git a/addons/field_rations/anim/drink_stand_can.rtm b/addons/field_rations/anim/drink_stand_can.rtm new file mode 100644 index 0000000000..c68a6ba5e2 Binary files /dev/null and b/addons/field_rations/anim/drink_stand_can.rtm differ diff --git a/addons/field_rations/anim/model.cfg b/addons/field_rations/anim/model.cfg new file mode 100644 index 0000000000..0359a94284 --- /dev/null +++ b/addons/field_rations/anim/model.cfg @@ -0,0 +1,124 @@ +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", + //Head skeleton in hierarchy + "Neck","Spine3", + "Neck1","Neck", + "Head","Neck1", + + //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/field_rations/anim/zDummy.rtm b/addons/field_rations/anim/zDummy.rtm new file mode 100644 index 0000000000..dfeb7b7fcc Binary files /dev/null and b/addons/field_rations/anim/zDummy.rtm differ diff --git a/addons/field_rations/config.cpp b/addons/field_rations/config.cpp new file mode 100644 index 0000000000..d4d8674b80 --- /dev/null +++ b/addons/field_rations/config.cpp @@ -0,0 +1,66 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = { + "ACE_WaterBottle_Item", + "ACE_WaterBottle_Half_Item", + "ACE_WaterBottle_Empty_Item", + "ACE_Canteen_Item", + "ACE_Canteen_Half_Item", + "ACE_Canteen_Empty_Item", + "ACE_Can_Spirit_Item", + "ACE_Can_Franta_Item", + "ACE_Can_RedGull_Item", + "ACE_MRE_LambCurry_Item", + "ACE_MRE_BeefStew_Item", + "ACE_MRE_CreamTomatoSoup_Item", + "ACE_MRE_CreamChickenSoup_Item", + "ACE_MRE_ChickenTikkaMasala_Item", + "ACE_MRE_SteakVegetables_Item", + "ACE_MRE_MeatballsPasta_Item", + "ACE_MRE_ChickenHerbDumplings_Item", + "ACE_Humanitarian_Ration_Item", + "ACE_Sunflower_Seeds_Item" + }; + weapons[] = { + "ACE_WaterBottle", + "ACE_WaterBottle_Half", + "ACE_WaterBottle_Empty", + "ACE_Canteen", + "ACE_Canteen_Half", + "ACE_Canteen_Empty", + "ACE_Can_Spirit", + "ACE_Can_Franta", + "ACE_Can_RedGull", + "ACE_MRE_LambCurry", + "ACE_MRE_BeefStew", + "ACE_MRE_CreamTomatoSoup", + "ACE_MRE_CreamChickenSoup", + "ACE_MRE_ChickenTikkaMasala", + "ACE_MRE_SteakVegetables", + "ACE_MRE_MeatballsPasta", + "ACE_MRE_ChickenHerbDumplings", + "ACE_Humanitarian_Ration", + "ACE_Sunflower_Seeds" + }; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interact_menu"}; + author = ECSTRING(common,ACETeam); + authors[] = {"mharis001", "Glowbal", "PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; + + BWC_CONFIG(XADDON); +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" +#include "CfgSounds.hpp" +#include "CfgMoves.hpp" +#include "Cfg3DEN.hpp" +#include "RscTitles.hpp" +#include "CfgUIGrids.hpp" diff --git a/addons/field_rations/data/mre.rvmat b/addons/field_rations/data/mre.rvmat new file mode 100644 index 0000000000..296e544f1f --- /dev/null +++ b/addons/field_rations/data/mre.rvmat @@ -0,0 +1,28 @@ +ambient[] = {1,1,1,1}; +diffuse[] = {0.5,0.5,0.5,1}; +forcedDiffuse[] = {0.5,0.5,0.5,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.30000001,0.30000001,0.30000001,0}; +specularPower = 17; +PixelShaderID = "NormalMapSpecularDIMap"; +VertexShaderID = "NormalMap"; +class Stage1 { + texture = "z\ace\addons\field_rations\data\mre_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 = "z\ace\addons\field_rations\data\mre_smdi.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/field_rations/data/mre_human.p3d b/addons/field_rations/data/mre_human.p3d new file mode 100644 index 0000000000..089b90bd55 Binary files /dev/null and b/addons/field_rations/data/mre_human.p3d differ diff --git a/addons/field_rations/data/mre_human_co.paa b/addons/field_rations/data/mre_human_co.paa new file mode 100644 index 0000000000..e713006bb3 Binary files /dev/null and b/addons/field_rations/data/mre_human_co.paa differ diff --git a/addons/field_rations/data/mre_nohq.paa b/addons/field_rations/data/mre_nohq.paa new file mode 100644 index 0000000000..6972636a3d Binary files /dev/null and b/addons/field_rations/data/mre_nohq.paa differ diff --git a/addons/field_rations/data/mre_smdi.paa b/addons/field_rations/data/mre_smdi.paa new file mode 100644 index 0000000000..f450605958 Binary files /dev/null and b/addons/field_rations/data/mre_smdi.paa differ diff --git a/addons/field_rations/data/mre_type1.p3d b/addons/field_rations/data/mre_type1.p3d new file mode 100644 index 0000000000..f65c2ec3e3 Binary files /dev/null and b/addons/field_rations/data/mre_type1.p3d differ diff --git a/addons/field_rations/data/mre_type1_co.paa b/addons/field_rations/data/mre_type1_co.paa new file mode 100644 index 0000000000..27c94eaf2b Binary files /dev/null and b/addons/field_rations/data/mre_type1_co.paa differ diff --git a/addons/field_rations/data/mre_type2.p3d b/addons/field_rations/data/mre_type2.p3d new file mode 100644 index 0000000000..aa322a3d92 Binary files /dev/null and b/addons/field_rations/data/mre_type2.p3d differ diff --git a/addons/field_rations/data/mre_type3.p3d b/addons/field_rations/data/mre_type3.p3d new file mode 100644 index 0000000000..457ed0e878 Binary files /dev/null and b/addons/field_rations/data/mre_type3.p3d differ diff --git a/addons/field_rations/data/mre_type3_co.paa b/addons/field_rations/data/mre_type3_co.paa new file mode 100644 index 0000000000..367f7e7c9e Binary files /dev/null and b/addons/field_rations/data/mre_type3_co.paa differ diff --git a/addons/field_rations/data/mre_type4.p3d b/addons/field_rations/data/mre_type4.p3d new file mode 100644 index 0000000000..257d5b7b83 Binary files /dev/null and b/addons/field_rations/data/mre_type4.p3d differ diff --git a/addons/field_rations/data/mre_type4_co.paa b/addons/field_rations/data/mre_type4_co.paa new file mode 100644 index 0000000000..34a674c4c0 Binary files /dev/null and b/addons/field_rations/data/mre_type4_co.paa differ diff --git a/addons/field_rations/data/mre_type5.p3d b/addons/field_rations/data/mre_type5.p3d new file mode 100644 index 0000000000..4412262c47 Binary files /dev/null and b/addons/field_rations/data/mre_type5.p3d differ diff --git a/addons/field_rations/data/mre_type6.p3d b/addons/field_rations/data/mre_type6.p3d new file mode 100644 index 0000000000..b2d34d9901 Binary files /dev/null and b/addons/field_rations/data/mre_type6.p3d differ diff --git a/addons/field_rations/data/mre_type6_co.paa b/addons/field_rations/data/mre_type6_co.paa new file mode 100644 index 0000000000..87e97ea62f Binary files /dev/null and b/addons/field_rations/data/mre_type6_co.paa differ diff --git a/addons/field_rations/data/sunflower_seeds.p3d b/addons/field_rations/data/sunflower_seeds.p3d new file mode 100644 index 0000000000..9febd9bba1 Binary files /dev/null and b/addons/field_rations/data/sunflower_seeds.p3d differ diff --git a/addons/field_rations/data/sunflower_seeds_co.paa b/addons/field_rations/data/sunflower_seeds_co.paa new file mode 100644 index 0000000000..d0d1c0421e Binary files /dev/null and b/addons/field_rations/data/sunflower_seeds_co.paa differ diff --git a/addons/field_rations/functions/fnc_addStatusModifier.sqf b/addons/field_rations/functions/fnc_addStatusModifier.sqf new file mode 100644 index 0000000000..39d2388680 --- /dev/null +++ b/addons/field_rations/functions/fnc_addStatusModifier.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Adds a status modifier. Should be called on all machines. + * Code must return a NUMBER which will be applied additively with other status changes. + * + * Arguments: + * 0: Status to modify (0 - Thirst, 1 - Hunger, 2 - Both) + * 1: Code (is passed the unit ) + * + * Return Value: + * None + * + * Example: + * [0, {}] call ace_field_rations_fnc_addStatusModifier + * + * Public: Yes + */ + +params [["_type", -1, [0]], ["_code", {}, [{}]]]; + +if (_type isEqualTo -1 || {_code isEqualTo {}}) exitWith {}; + +if (_type isEqualTo 2) then { + GVAR(thirstModifiers) pushBack _code; + GVAR(hungerModifiers) pushBack _code; +} else { + private _modifierArray = [GVAR(thirstModifiers), GVAR(hungerModifiers)] select _type; + _modifierArray pushBack _code; +}; diff --git a/addons/field_rations/functions/fnc_addWaterSourceInteractions.sqf b/addons/field_rations/functions/fnc_addWaterSourceInteractions.sqf new file mode 100644 index 0000000000..d45ea877ca --- /dev/null +++ b/addons/field_rations/functions/fnc_addWaterSourceInteractions.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Dynamically adds actions to nearby water sources when interact_menu is opened. + * Called by the "ace_interactMenuOpened" event. + * + * Arguments: + * Interact Menu Type (0 - World, 1 - Self) + * + * Return Value: + * None + * + * Example: + * [0] call ace_field_rations_fnc_addWaterSourceInteractions + * + * Public: No + */ + +params ["_interactionType"]; + +// Ignore when self-interaction, mounted vehicle interaction, or water source actions are disabled +if ( + _interactionType != 0 + || {vehicle ACE_player != ACE_player} + || {XGVAR(waterSourceActions) == 0} +) exitWith {}; + +TRACE_1("Starting interact PFH",_interactionType); + +[{ + BEGIN_COUNTER(interactEH); + params ["_args", "_pfhID"]; + _args params ["_setPosition", "_addedHelpers", "_sourcesHelped"]; + + if (!EGVAR(interact_menu,keyDown)) then { + TRACE_1("Ending interact PFH",_pfhID); + {detach _x; deleteVehicle _x} forEach _addedHelpers; + [_pfhID] call CBA_fnc_removePerFrameHandler; + } else { + // Prevent rare error when ending mission with interact key down + if (isNull ACE_player) exitWith {}; + + // Rescan if player has moved more than 5 meters from last position + if (getPosASL ACE_player distanceSqr _setPosition > 25) then { + BEGIN_COUNTER(updatePosition); + { + if (!(_x in _sourcesHelped) && {XGVAR(terrainObjectActions) || {!(_x call CBA_fnc_isTerrainObject)}}) then { + private _waterRemaining = [_x] call FUNC(getRemainingWater); + + if (_waterRemaining != REFILL_WATER_DISABLED) then { + private _offset = [_x] call FUNC(getActionOffset); + private _helper = QGVAR(helper) createVehicleLocal [0, 0, 0]; + _helper setVariable [QGVAR(waterSource), _x]; + _helper attachTo [_x, _offset]; + + _addedHelpers pushBack _helper; + _sourcesHelped pushBack _x; + TRACE_3("Added interaction helper",_x,typeOf _x,_waterRemaining); + }; + }; + } forEach nearestObjects [ACE_player, [], 15]; + + _args set [0, getPosASL ACE_player]; + END_COUNTER(updatePosition); + }; + }; + END_COUNTER(interactEH); +}, 0.5, [getPosASL ACE_player vectorAdd [-100, 0, 0], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/field_rations/functions/fnc_canDrinkFromSource.sqf b/addons/field_rations/functions/fnc_canDrinkFromSource.sqf new file mode 100644 index 0000000000..c970214aeb --- /dev/null +++ b/addons/field_rations/functions/fnc_canDrinkFromSource.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Checks if the player can drink directly from the given water source. + * + * Arguments: + * 0: Player + * 1: Water Source + * + * Return Value: + * Can Drink From Source + * + * Example: + * [_player, _source] call ace_field_rations_fnc_canDrinkFromSource + * + * Public: No + */ + +params ["_player", "_source"]; + +XGVAR(waterSourceActions) == 2 && { + private _water = _source call FUNC(getRemainingWater); + _water == REFILL_WATER_INFINITE || {_water >= DRINK_FROM_SOURCE_AMOUNT} +} diff --git a/addons/field_rations/functions/fnc_canRefillItem.sqf b/addons/field_rations/functions/fnc_canRefillItem.sqf new file mode 100644 index 0000000000..3b7ac1e7f4 --- /dev/null +++ b/addons/field_rations/functions/fnc_canRefillItem.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Checks whether the player can refill an item from given water source. + * + * Arguments: + * 0: Water source + * 1: Player + * 2: Item data + * 0: Item classname + * 1: Item config + * 2: Is item magazine + * + * Return Value: + * Can refill item + * + * Example: + * [_source, _player, ["ACE_WaterBottle_Empty", configFile >> "CfgWeapons" >> "ACE_WaterBottle_Empty", false]] call ace_field_rations_fnc_canRefillItem + * + * Public: No + */ + +params ["_source", "_player", "_itemData"]; +_itemData params ["_item", "_itemConfig", "_isMagazine"]; + +alive _source +&& {XGVAR(waterSourceActions) != 0} +&& { + (_isMagazine && {_item in magazines _player}) + || {_item in (_player call EFUNC(common,uniqueItems))} +} +&& { + private _water = _source call FUNC(getRemainingWater); + _water == REFILL_WATER_INFINITE || {_water >= getNumber (_itemConfig >> QXGVAR(refillAmount))} +} diff --git a/addons/field_rations/functions/fnc_checkWater.sqf b/addons/field_rations/functions/fnc_checkWater.sqf new file mode 100644 index 0000000000..32167e6114 --- /dev/null +++ b/addons/field_rations/functions/fnc_checkWater.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Displays the remaining water in the given water source. + * + * Arguments: + * 0: Player + * 1: Water source + * + * Return Value: + * None + * + * Example: + * [_player, _source] call ace_field_rations_fnc_checkWater + * + * Public: No + */ + +params ["_player", "_source"]; + +[ + CHECK_WATER_TIME, + [_player, _source], + { + params ["_args"]; + _args params ["_player", "_source"]; + + private _water = _source call FUNC(getRemainingWater); + + if (_water > 0) then { + [[LSTRING(RemainingWater), _water], 1.5, _player] call EFUNC(common,displayTextStructured); + } else { + [LSTRING(NoWaterRemaining), 1.5, _player] call EFUNC(common,displayTextStructured); + }; + }, + {}, + LLSTRING(CheckingWater) +] call EFUNC(common,progressBar); diff --git a/addons/field_rations/functions/fnc_consumeItem.sqf b/addons/field_rations/functions/fnc_consumeItem.sqf new file mode 100644 index 0000000000..2c3b6f815a --- /dev/null +++ b/addons/field_rations/functions/fnc_consumeItem.sqf @@ -0,0 +1,156 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Consumes an item. Creates a progress bar and handles relevant thirst/hunger values. + * + * Arguments: + * 0: Target (not used) + * 1: Player + * 2: Item data + * 0: Item classname + * 1: Item config + * 2: Is item magazine + * + * Return Value: + * None + * + * Example: + * [objNull, ACE_player, "["ACE_WaterBottle_Empty", configFile >> "CfgWeapons" >> "ACE_WaterBottle_Empty", false]] call ace_field_rations_fnc_consumeItem + * + * Public: No + */ + +params ["", "_player", "_consumeData"]; +_consumeData params ["_consumeItem", "_config", "_isMagazine"]; +TRACE_3("Consume item started",_player,_consumeItem,_config); + +// Get consume time for item +private _consumeTime = getNumber (_config >> QXGVAR(consumeTime)); + +// Get restored values and replacement item +private _thirstQuenched = XGVAR(thirstQuenched) * getNumber (_config >> QXGVAR(thirstQuenched)); +private _hungerSatiated = XGVAR(hungerSatiated) * getNumber (_config >> QXGVAR(hungerSatiated)); +private _replacementItem = getText (_config >> QXGVAR(replacementItem)); + +// Create consume text for item +private _displayName = getText (_config >> "displayName"); +private _consumeText = getText (_config >> QXGVAR(consumeText)); + +if (_consumeText == "") then { + _consumeText = if (_hungerSatiated > 0) then { + LLSTRING(EatingX); + } else { + LLSTRING(DrinkingX); + }; +}; + +// Format displayName onto consume text +// Allows for common strings to be used for multiple items +_consumeText = format [_consumeText, _displayName]; + +// Get consume animation and sound for item +private _stanceIndex = ["STAND", "CROUCH", "PRONE"] find stance _player; + +// Handle in vehicle when stance is UNDEFINED +if (vehicle _player != _player) then {_stanceIndex = 0}; + +private _consumeAnim = getArray (_config >> QXGVAR(consumeAnims)) param [_stanceIndex, "", [""]]; +private _consumeSound = getArray (_config >> QXGVAR(consumeSounds)) param [_stanceIndex, "", [""]]; + +private _soundPlayed = if (_consumeAnim != "" && {vehicle _player == _player && {!(_player call EFUNC(common,isSwimming))}}) then { + // Store current animation for resetting + _player setVariable [QGVAR(previousAnim), animationState _player]; + [_player, _consumeAnim, 1] call EFUNC(common,doAnimation); + false +} else { + // No animation to sync sound to + if (_consumeSound != "") then { + playSound _consumeSound; + }; + true +}; + +private _fnc_onSuccess = { + params ["_args"]; + _args params ["_player", "_consumeItem", "_replacementItem", "_thirstQuenched", "_hungerSatiated", "", "", "", "_isMagazine"]; + TRACE_1("Consume item successful",_args); + + // Remove consumed item + if (_isMagazine) then { + _player removeMagazineGlobal _consumeItem; + } else { + _player removeItem _consumeItem; + }; + + // Add replacement item if needed + if (_replacementItem != "") then { + [_player, _replacementItem] call EFUNC(common,addToInventory); + }; + + // Handle thirst and hunger values + if (_thirstQuenched > 0) then { + private _thirst = _player getVariable [QXGVAR(thirst), 0]; + _player setVariable [QXGVAR(thirst), (_thirst - _thirstQuenched) max 0]; + }; + + if (_hungerSatiated > 0) then { + private _hunger = _player getVariable [QXGVAR(hunger), 0]; + _player setVariable [QXGVAR(hunger), (_hunger - _hungerSatiated) max 0]; + }; + + ["acex_rationConsumed", [_player, _consumeItem, _replacementItem, _thirstQuenched, _hungerSatiated, _isMagazine]] call CBA_fnc_localEvent; + + _player setVariable [QGVAR(previousAnim), nil]; +}; + +private _fnc_onFailure = { + params ["_args"]; + _args params ["_player"]; + TRACE_1("Consume item failed",_args); + + // Reset animation if needed + if (vehicle _player == _player && {!(_player call EFUNC(common,isSwimming))}) then { + private _previousAnim = _player getVariable [QGVAR(previousAnim), ""]; + if (_previousAnim != "") then { + [_player, _previousAnim, 2] call EFUNC(common,doAnimation); + }; + }; + + _player setVariable [QGVAR(previousAnim), nil]; +}; + +private _fnc_condition = { + params ["_args"]; + _args params ["_player", "_consumeItem", "", "", "", "_consumeAnim", "_consumeSound", "_soundPlayed", "_isMagazine"]; + + // Attempt to sync sound with animation start + if (!_soundPlayed && {_consumeSound != "" && {_consumeAnim == "" || {animationState _player == _consumeAnim}}}) then { + playSound _consumeSound; + _args set [7, true]; + }; + + if (_isMagazine) exitWith { + _consumeItem in magazines _player // return + }; + _consumeItem in (_player call EFUNC(common,uniqueItems)) // return +}; + +[ + _consumeTime, + [ + _player, + _consumeItem, + _replacementItem, + _thirstQuenched, + _hungerSatiated, + _consumeAnim, + _consumeSound, + _soundPlayed, + _isMagazine + ], + _fnc_onSuccess, + _fnc_onFailure, + _consumeText, + _fnc_condition, + ["isNotInside"] +] call EFUNC(common,progressBar); diff --git a/addons/field_rations/functions/fnc_drinkFromSource.sqf b/addons/field_rations/functions/fnc_drinkFromSource.sqf new file mode 100644 index 0000000000..cf0d18018b --- /dev/null +++ b/addons/field_rations/functions/fnc_drinkFromSource.sqf @@ -0,0 +1,80 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Makes the player drink directly from the given water source. + * + * Arguments: + * 0: Player + * 1: Water Source + * + * Return Value: + * None + * + * Example: + * [_player, _source] call ace_field_rations_fnc_drinkFromSource + * + * Public: No + */ + +params ["_player", "_source"]; + +// Store current animation for resetting +_player setVariable [QGVAR(previousAnim), animationState _player]; + +private _animation = [_player, _source] call FUNC(getDrinkAnimation); +[_player, _animation, 1] call EFUNC(common,doAnimation); + +private _fnc_onSuccess = { + params ["_args"]; + _args params ["_player", "_source"]; + + // Reduce player thirst + private _thirst = _player getVariable [QXGVAR(thirst), 0]; + _player setVariable [QXGVAR(thirst), (_thirst - (DRINK_FROM_SOURCE_QUENCHED * XGVAR(thirstQuenched))) max 0]; + _player setVariable [QGVAR(previousAnim), nil]; + + // Update remaining water in source + private _waterInSource = _source call FUNC(getRemainingWater); + + if (_waterInSource != REFILL_WATER_INFINITE) then { + [_source, (_waterInSource - DRINK_FROM_SOURCE_AMOUNT) max 0] call FUNC(setRemainingWater); + }; +}; + +private _fnc_onFailure = { + params ["_args"]; + _args params ["_player"]; + + // Reset animation if needed + if (vehicle _player == _player && {!(_player call EFUNC(common,isSwimming))}) then { + private _previousAnim = _player getVariable [QGVAR(previousAnim), ""]; + if (_previousAnim != "") then { + [_player, _previousAnim, 2] call EFUNC(common,doAnimation); + }; + }; + + _player setVariable [QGVAR(previousAnim), nil]; +}; + +private _fnc_condition = { + params ["_args"]; + _args params ["_player", "_source"]; + + [_player, _source] call FUNC(canDrinkFromSource) +}; + +private _sourceConfig = configOf _source; +private _progressText = if (isNull _sourceConfig) then { + LLSTRING(DrinkingFromSource) +} else { + format [LLSTRING(DrinkingFromX), getText (_sourceConfig >> "displayName")] +}; + +[ + DRINK_FROM_SOURCE_TIME, + [_player, _source], + _fnc_onSuccess, + _fnc_onFailure, + _progressText, + _fnc_condition +] call EFUNC(common,progressBar); diff --git a/addons/field_rations/functions/fnc_getActionOffset.sqf b/addons/field_rations/functions/fnc_getActionOffset.sqf new file mode 100644 index 0000000000..dd7658dfda --- /dev/null +++ b/addons/field_rations/functions/fnc_getActionOffset.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Returns the refill action offset for given object. + * + * Arguments: + * 0: Water source + * + * Return Value: + * Action offset + * + * Example: + * [cursorObject] call ace_field_rations_fnc_getActionOffset + * + * Public: No + */ + +params ["_object"]; + +private _configOf = configOf _object; +if !(isNull _configOf) then { + // Check for offset in config since we have valid typeOf + private _offset = getArray (_configOf >> QXGVAR(offset)); + if (_offset isEqualTo []) then {[0, 0, 0]} else {_offset}; +} else { + // Check for offset corresponding to p3d list + GVAR(waterSourceOffsets) param [GVAR(waterSourceP3ds) find (getModelInfo _object select 0), [0, 0, 0], [[]]]; +}; diff --git a/addons/field_rations/functions/fnc_getConsumableChildren.sqf b/addons/field_rations/functions/fnc_getConsumableChildren.sqf new file mode 100644 index 0000000000..9fe422109c --- /dev/null +++ b/addons/field_rations/functions/fnc_getConsumableChildren.sqf @@ -0,0 +1,49 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Returns children actions for consumable items in player's inventory. + * + * Arguments: + * 0: Player + * + * Return Value: + * Actions + * + * Example: + * [_player] call ace_field_rations_fnc_getConsumableChildren + * + * Public: No + */ + +params ["_player"]; + +private _fnc_getActions = { + TRACE_1("Creating consumable item actions",_player); + + private _actions = []; + private _cfgWeapons = configFile >> "CfgWeapons"; + private _cfgMagazines = configFile >> "CfgMagazines"; + + { + _x params ["_config", "_items"]; + private _isMagazine = _config == _cfgMagazines; + { + private _itemConfig = _config >> _x; + if (getNumber (_itemConfig >> QXGVAR(thirstQuenched)) > 0 || {getNumber (_itemConfig >> QXGVAR(hungerSatiated)) > 0}) then { + private _displayName = getText (_itemConfig >> "displayName"); + private _picture = getText (_itemConfig >> "picture"); + + // Exec next frame so closing interaction menu doesn't block progressBar + private _action = [_x, _displayName, _picture, {[FUNC(consumeItem), _this] call CBA_fnc_execNextFrame}, {true}, {}, [_x, _itemConfig, _isMagazine]] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _player]; + }; + } forEach _items; + } forEach [ + [_cfgWeapons, _player call EFUNC(common,uniqueItems)], + [_cfgMagazines, [magazines _player] call EFUNC(common,uniqueElements)] + ]; + + _actions +}; + +[[], _fnc_getActions, _player, QGVAR(consumableActionsCache), 9999, "cba_events_loadoutEvent"] call EFUNC(common,cachedCall); diff --git a/addons/field_rations/functions/fnc_getDrinkAnimation.sqf b/addons/field_rations/functions/fnc_getDrinkAnimation.sqf new file mode 100644 index 0000000000..3d577ef7f9 --- /dev/null +++ b/addons/field_rations/functions/fnc_getDrinkAnimation.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Returns an appropriate animation for drinking directly from the given water source. + * + * Arguments: + * 0: Player + * 1: Water Source + * + * Return Value: + * Animation + * + * Example: + * [_player, _source] call ace_field_rations_fnc_getDrinkAnimation + * + * Public: No + */ + +params ["_player", "_source"]; + +private _offset = _source call FUNC(getActionOffset); +private _actionPos = _source modelToWorld _offset; +private _playerPos = _player modelToWorld [0, 0, 0]; + +private _difference = (_actionPos vectorDiff _playerPos) select 2; + +// Experimentally determined values to try to match height difference to different animations +switch (true) do { + case (_difference < 0.1): {QGVAR(drinkFromSourceSquatLow)}; + case (_difference < 0.4): {QGVAR(drinkFromSourceSquat)}; + case (_difference < 0.8): {QGVAR(drinkFromSourceSquatHigh)}; + case (_difference < 1.2): {QGVAR(drinkFromSourceLow)}; + case (_difference < 1.4): {QGVAR(drinkFromSource)}; + default {QGVAR(drinkFromSourceHigh)}; +}; diff --git a/addons/field_rations/functions/fnc_getRefillChildren.sqf b/addons/field_rations/functions/fnc_getRefillChildren.sqf new file mode 100644 index 0000000000..cb4a607df3 --- /dev/null +++ b/addons/field_rations/functions/fnc_getRefillChildren.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Returns children actions for refillable items in player's inventory for given water source. + * + * Arguments: + * 0: Water source + * 1: Player + * + * Return Value: + * Actions + * + * Example: + * [_source, _player] call ace_field_rations_fnc_getRefillChildren + * + * Public: No + */ + +params ["_source", "_player"]; + +// Exit if disabled or source has no water +private _water = _source call FUNC(getRemainingWater); +if (_water == 0 || {_water == REFILL_WATER_DISABLED}) exitWith {[]}; + +private _actions = []; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; + +{ + _x params ["_config", "_items"]; + private _isMagazine = _config == _cfgMagazines; + { + private _itemConfig = _config >> _x; + if (getText (_itemConfig >> QXGVAR(refillItem)) != "" && {_water == REFILL_WATER_INFINITE || {getNumber (_itemConfig >> QXGVAR(refillAmount)) <= _water}}) then { + private _displayName = format ["%1: %2", LLSTRING(Refill), getText (_itemConfig >> "displayName")]; + private _picture = getText (_itemConfig >> "picture"); + private _action = [_x, _displayName, _picture, FUNC(refillItem), FUNC(canRefillItem), {}, [_x, _itemConfig, _isMagazine]] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _source]; + }; + } forEach _items; +} forEach [ + [_cfgWeapons, _player call EFUNC(common,uniqueItems)], + [_cfgMagazines, [magazines _player] call EFUNC(common,uniqueElements)] +]; + +_actions diff --git a/addons/field_rations/functions/fnc_getRemainingWater.sqf b/addons/field_rations/functions/fnc_getRemainingWater.sqf new file mode 100644 index 0000000000..253fd62285 --- /dev/null +++ b/addons/field_rations/functions/fnc_getRemainingWater.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, PabstMirror + * Returns the remaining water in a source. + * + * Arguments: + * 0: Water source + * + * Return Value: + * Remaining water + * + * Example: + * [_source] call ace_field_rations_fnc_getRemainingWater + * + * Public: Yes + */ + +params [["_source", objNull, [objNull]]]; + +if (!alive _source) exitWith {0}; + +private _water = _source getVariable QGVAR(currentWaterSupply); + +if (isNil "_water") then { + private _configOf = configOf _source; + if !(isNull _configOf) then { + // Check for waterSupply entry since we have valid typeOf + _water = getNumber (_configOf >> QXGVAR(waterSupply)); + if (_water == 0) then {_water = REFILL_WATER_DISABLED}; + + if (_water != REFILL_WATER_DISABLED) then { + if (_source call CBA_fnc_isTerrainObject) then { + _water = REFILL_WATER_INFINITE; + } else { + _source setVariable [QGVAR(currentWaterSupply), _water, true]; + }; + }; + } else { + // Check the p3d name against list + _water = if ((getModelInfo _source select 0) in GVAR(waterSourceP3ds)) then {REFILL_WATER_INFINITE} else {REFILL_WATER_DISABLED}; + }; +}; + +_water diff --git a/addons/field_rations/functions/fnc_handleEffects.sqf b/addons/field_rations/functions/fnc_handleEffects.sqf new file mode 100644 index 0000000000..ad60a743ad --- /dev/null +++ b/addons/field_rations/functions/fnc_handleEffects.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Handles the effects/consequences of high thirst/hunger. + * + * Arguments: + * 0: Player + * 1: Thirst + * 2: Hunger + * + * Return Value: + * None + * + * Example: + * [_player, _thirst, _hunger] call ace_field_rations_fnc_handleEffects + * + * Public: No + */ + +params ["_player", "_thirst", "_hunger"]; + +// Kill unit with max thirst or hunger +if ((_thirst > 99.9 || {_hunger > 99.9}) && {random 1 < 0.5}) exitWith { + [_player, "Hunger/Thirst empty"] call EFUNC(common,setDead); +}; + +// Exit if unit is not awake, below are animation based consequences +if !(_player call EFUNC(common,isAwake)) exitWith {}; + +// Set unit unconscious (chance based on how high thirst/hunger are) +if ( + GETEGVAR(medical,enabled,false) && + {(_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}} +) exitWith { + [_player, true, 5, true] call EFUNC(medical,setUnconscious); +}; + +// Make unit fall if moving fast +if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {isNull objectParent _player}) exitWith { + [_player, "down"] call EFUNC(common,doGesture); +}; diff --git a/addons/field_rations/functions/fnc_handleHUD.sqf b/addons/field_rations/functions/fnc_handleHUD.sqf new file mode 100644 index 0000000000..7bf505e8c8 --- /dev/null +++ b/addons/field_rations/functions/fnc_handleHUD.sqf @@ -0,0 +1,77 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Handles creating and updating the visuals of the HUD. + * + * Arguments: + * 0: Thirst (default: getVariable from ACE_player) + * 1: Hunger (default: getVariable from ACE_player) + * + * Return Value: + * None + * + * Example: + * [_thirst, _hunger] call ace_field_rations_fnc_handleHUD + * + * Public: No + */ + +params [["_thirst", ACE_player getVariable [QXGVAR(thirst), 0]], ["_hunger", ACE_player getVariable [QXGVAR(hunger), 0]]]; + +private _display = uiNamespace getVariable [QGVAR(hudDisplay), displayNull]; + +// Create HUD if display is null +if (isNull _display) then { + private _rscType = [QGVAR(hudColoredIcons), QGVAR(hudDrainingIcons)] select XGVAR(hudType); + QGVAR(hud) cutRsc [_rscType, "PLAIN", -1, false]; + _display = uiNamespace getVariable [QGVAR(hudDisplay), displayNull]; +}; + +if (XGVAR(hudType) == 0) then { + // Get HUD transparency based on setting + private _fade = if (XGVAR(hudTransparency) == -1) then { + linearConversion [0, 70, _thirst max _hunger, 1, 0, true]; + } else { + XGVAR(hudTransparency); + }; + + // Reduce transparency if hovering on interaction + if (GVAR(hudInteractionHover)) then { + _fade = _fade min 0.5; + }; + + // Update HUD icon colors (White -> Yellow -> Orange -> Red) + { + _x params ["_status", "_iconIDC"]; + + private _iconCtrl = _display displayCtrl _iconIDC; + private _color = [1, linearConversion [35, 90, _status, 1, 0, true], linearConversion [0, 40, _status, 1, 0, true], 1]; + _iconCtrl ctrlSetTextColor _color; + _iconCtrl ctrlSetFade _fade; + _iconCtrl ctrlCommit 1; + } forEach [ + [_thirst, IDC_COLORED_HUD_THIRST], + [_hunger, IDC_COLORED_HUD_HUNGER] + ]; +} else { + // Reposition controls group and icon to create draining effect + private _defaultY = profileNamespace getVariable [QUOTE(TRIPLES(IGUI,XGVAR(grid),Y)), safeZoneY + safeZoneH - 2.2 * GUI_GRID_H]; + { + _x params ["_status", "_groupIDC", "_iconIDC"]; + + private _changeY = _status / 50 * GUI_GRID_H; + + private _groupCtrl = _display displayCtrl _groupIDC; + private _groupPos = ctrlPosition _groupCtrl; + _groupPos set [1, _defaultY + _changeY]; + _groupCtrl ctrlSetPosition _groupPos; + _groupCtrl ctrlCommit 0; + + private _iconCtrl = _display displayCtrl _iconIDC; + _iconCtrl ctrlSetPosition [0, -_changeY]; + _iconCtrl ctrlCommit 0; + } forEach [ + [_thirst, IDC_DRAINING_HUD_THIRST_GROUP, IDC_DRAINING_HUD_THIRST_ICON], + [_hunger, IDC_DRAINING_HUD_HUNGER_GROUP, IDC_DRAINING_HUD_HUNGER_ICON] + ]; +}; diff --git a/addons/field_rations/functions/fnc_handleRespawn.sqf b/addons/field_rations/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..70baf23a1b --- /dev/null +++ b/addons/field_rations/functions/fnc_handleRespawn.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Handles the respawning of a unit by resetting necessary variables. + * + * Arguments: + * 0: Unit + * 1: Corpse + * + * Return Value: + * None + * + * Example: + * [newUnit, oldUnit] call ace_field_rations_fnc_handleRespawn + * + * Public: No + */ + +params ["_unit", "_corpse"]; +TRACE_2("Handle Respawn",_unit,_corpse); + +if !(local _unit) exitWith {}; + +_unit setVariable [QXGVAR(thirst), 0]; +_unit setVariable [QXGVAR(hunger), 0]; diff --git a/addons/field_rations/functions/fnc_refillItem.sqf b/addons/field_rations/functions/fnc_refillItem.sqf new file mode 100644 index 0000000000..91542e60b4 --- /dev/null +++ b/addons/field_rations/functions/fnc_refillItem.sqf @@ -0,0 +1,82 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Refills an item from given water source. + * + * Arguments: + * 0: Water source + * 1: Player + * 2: Item data + * 0: Item classname + * 1: Item config + * 2: Is item magazine + * + * Return Value: + * None + * + * Example: + * [_source, _player, ["ACE_WaterBottle_Empty", configFile >> "CfgWeapons" >> "ACE_WaterBottle_Empty", false]] call ace_field_rations_fnc_refillItem + * + * Public: No + */ + +params ["_source", "_player", "_itemData"]; +_itemData params ["_item", "_config", "_isMagazine"]; +TRACE_3("Item refill started",_source,_player,_item); + +// Get config values for refill +private _refillItem = getText (_config >> QXGVAR(refillItem)); +private _refillAmount = getNumber (_config >> QXGVAR(refillAmount)); +private _refillTime = getNumber (_config >> QXGVAR(refillTime)); + +private _fnc_onSuccess = { + params ["_args"]; + _args params ["_source", "_player", "_itemData", "_refillItem", "_refillAmount", "_itemData"]; + _itemData params ["_item", "", "_isMagazine"]; + TRACE_1("Refill item successful",_args); + + // Replace item with refilled one + if (_isMagazine) then { + _player removeMagazineGlobal _item; + } else { + _player removeItem _item; + }; + [_player, _refillItem] call EFUNC(common,addToInventory); + + // Update remaining water in source + private _waterInSource = _source call FUNC(getRemainingWater); + if (_waterInSource != REFILL_WATER_INFINITE) then { + _waterInSource = (_waterInSource - _refillAmount) max 0; + [_source, _waterInSource] call FUNC(setRemainingWater); + }; + + ["acex_rationRefilled", [_source, _player, _item, _refillItem, _refillAmount, _isMagazine]] call CBA_fnc_localEvent; + + // Show refilled item hint + private _picture = getText (configFile >> "CfgWeapons" >> _refillItem >> "picture"); + [LSTRING(ItemRefilled), _picture] call EFUNC(common,displayTextPicture); +}; + +private _fnc_onFailure = { + TRACE_1("Refill item failed",_this); +}; + +private _fnc_condition = { + params ["_args"]; + _args call FUNC(canRefillItem); +}; + +[ + _refillTime, + [ + _source, + _player, + _itemData, + _refillItem, + _refillAmount + ], + _fnc_onSuccess, + _fnc_onFailure, + LLSTRING(Refilling), + _fnc_condition +] call EFUNC(common,progressBar); diff --git a/addons/field_rations/functions/fnc_scanFieldRations.sqf b/addons/field_rations/functions/fnc_scanFieldRations.sqf new file mode 100644 index 0000000000..c5f45d4d4c --- /dev/null +++ b/addons/field_rations/functions/fnc_scanFieldRations.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Caches all item classnames used as field rations + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_field_rations_fnc_scanFieldRations + * + * Public: No + */ + +private _list = createHashMap; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; + +private _fnc_isFieldRationItem = toString { + (getNumber (_x >> "ACE_isFieldRationItem") isEqualTo 1) || {(getNumber (_x >> QXGVAR(thirstQuenched))) > 0} || {(getNumber (_x >> QXGVAR(hungerSatiated))) > 0} || {(getText (_x >> QXGVAR(refillItem))) isNotEqualTo ""} +}; + +{ + _list set [configName _x, ""]; +} forEach (_fnc_isFieldRationItem configClasses _cfgWeapons); + +{ + _list set [configName _x, ""]; +} forEach (_fnc_isFieldRationItem configClasses _cfgMagazines); + +uiNamespace setVariable [QXGVAR(fieldRationItems), compileFinal _list]; diff --git a/addons/field_rations/functions/fnc_setRemainingWater.sqf b/addons/field_rations/functions/fnc_setRemainingWater.sqf new file mode 100644 index 0000000000..6e8fbc4b04 --- /dev/null +++ b/addons/field_rations/functions/fnc_setRemainingWater.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, PabstMirror + * Sets the remaining water supply for given water source. + * + * Arguments: + * 0: Water source + * 1: Amount (-10 - Infinite, -1 - Disabled) + * + * Return Value: + * None + * + * Example: + * [_source, 1000] call ace_field_rations_fnc_setRemainingWater + * + * Public: Yes + */ + +params [["_source", objNull, [objNull]], ["_water", nil, [0]]]; + +if (!alive _source || {isNil "_water"}) exitWith {}; + +_source setVariable [QGVAR(currentWaterSupply), _water, true]; diff --git a/addons/field_rations/functions/fnc_update.sqf b/addons/field_rations/functions/fnc_update.sqf new file mode 100644 index 0000000000..f66573824b --- /dev/null +++ b/addons/field_rations/functions/fnc_update.sqf @@ -0,0 +1,76 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Main looping function that updates thirst/hunger status. + * + * Arguments: + * 0: Next MP sync + * + * Return Value: + * None + * + * Example: + * [60] call ace_field_rations_fnc_update + * + * Public: No + */ + +// 1 sec (update interval) * 100 (max thirst/hunger) / 3600 (sec in hour) = 0.02777778 +#define CHANGE_CONSTANT 0.02777778 + +params ["_nextMpSync"]; + +// Access global variable once +private _player = ACE_player; + +// Exit if player is not alive or a virtual unit +if (!alive _player || {_player isKindOf "VirtualMan_F"}) exitWith { + [LINKFUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; + QGVAR(hud) cutFadeOut 0.5; +}; + +// Get current thirst and hunger +private _thirst = _player getVariable [QXGVAR(thirst), 0]; +private _hunger = _player getVariable [QXGVAR(hunger), 0]; + +// Determine base change based on work multiplier +private _currentWork = 1; +if (vehicle _player == _player && {isTouchingGround _player}) then { + private _speed = vectorMagnitude velocity _player; + _currentWork = linearConversion [2, 7, _speed, 1, 2, true]; +}; + +private _thirstChange = _currentWork * CHANGE_CONSTANT / XGVAR(timeWithoutWater); +private _hungerChange = _currentWork * CHANGE_CONSTANT / XGVAR(timeWithoutFood); + +// Run status modifiers +{_thirstChange = _thirstChange + (_player call _x) * CHANGE_CONSTANT / XGVAR(timeWithoutWater)} forEach GVAR(thirstModifiers); +{_hungerChange = _hungerChange + (_player call _x) * CHANGE_CONSTANT / XGVAR(timeWithoutFood)} forEach GVAR(hungerModifiers); + +// Change thirst and hunger status +_thirst = _thirst + _thirstChange min 100 max 0; +_hunger = _hunger + _hungerChange min 100 max 0; + +// Check if we want to do a MP sync +private _doSync = false; + +if (CBA_missionTime >= _nextMpSync) then { + _doSync = true; + _nextMpSync = CBA_missionTime + MP_SYNC_INTERVAL; +}; + +// Set new thirst and hunger values +_player setVariable [QXGVAR(thirst), _thirst, _doSync]; +_player setVariable [QXGVAR(hunger), _hunger, _doSync]; + +// Handle any effects/consequences of high thirst or hunger +[_player, _thirst, _hunger] call FUNC(handleEffects); + +// Handle showing/updating or hiding of HUD +if (!EGVAR(common,OldIsCamera) && {_thirst > XGVAR(hudShowLevel) || {_hunger > XGVAR(hudShowLevel)} || {GVAR(hudInteractionHover)}}) then { + [_thirst, _hunger] call FUNC(handleHUD); +} else { + QGVAR(hud) cutFadeOut 0.5; +}; + +[LINKFUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/field_rations/initSettings.inc.sqf b/addons/field_rations/initSettings.inc.sqf new file mode 100644 index 0000000000..86bf04aed2 --- /dev/null +++ b/addons/field_rations/initSettings.inc.sqf @@ -0,0 +1,103 @@ +[ + QXGVAR(enabled), + "CHECKBOX", + [ELSTRING(common,Enabled), LSTRING(Enabled_Description)], + LSTRING(DisplayName), + false, + true, + {}, + true // Needs restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(timeWithoutWater), + "SLIDER", + [LSTRING(TimeWithoutWater_DisplayName), LSTRING(TimeWithoutWater_Description)], + LSTRING(DisplayName), + [0.1, 168, 2, 1], + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(timeWithoutFood), + "SLIDER", + [LSTRING(TimeWithoutFood_DisplayName), LSTRING(TimeWithoutFood_Description)], + LSTRING(DisplayName), + [0.1, 504, 2, 1], + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(thirstQuenched), + "SLIDER", + [LSTRING(ThirstQuenched_DisplayName), LSTRING(ThirstQuenched_Description)], + LSTRING(DisplayName), + [0.1, 10, 1, 1], + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(hungerSatiated), + "SLIDER", + [LSTRING(HungerSatiated_DisplayName), LSTRING(HungerSatiated_Description)], + LSTRING(DisplayName), + [0.1, 10, 1, 1], + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(waterSourceActions), + "LIST", + [LSTRING(WaterSourceActions_DisplayName), LSTRING(WaterSourceActions_Description)], + LSTRING(DisplayName), + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(RefillOnly), ELSTRING(common,Enabled)], 2], + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(terrainObjectActions), + "CHECKBOX", + [LSTRING(TerrainObjectActions_DisplayName), LSTRING(TerrainObjectActions_Description)], + LSTRING(DisplayName), + true, + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(affectAdvancedFatigue), + "CHECKBOX", + [LSTRING(AffectAdvancedFatigue_DisplayName), LSTRING(AffectAdvancedFatigue_Description)], + LSTRING(DisplayName), + true, + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(hudType), + "LIST", + [LSTRING(HudType_DisplayName), LSTRING(HudType_Description)], + LSTRING(DisplayName), + [[0, 1], [LSTRING(ColoredIcons), LSTRING(DrainingIcons)], 0], + false, + { + QGVAR(hud) cutFadeOut 0; + } +] call CBA_fnc_addSetting; + +[ + QXGVAR(hudShowLevel), + "LIST", + [LSTRING(HudShowLevel_DisplayName), LSTRING(HudShowLevel_Description)], + LSTRING(DisplayName), + [[0, 10, 20, 30, 40, 50, 60, 70], [LSTRING(Always), "10%", "20%", "30%", "40%", "50%", "60%", "70%"], 0], + false +] call CBA_fnc_addSetting; + +[ + QXGVAR(hudTransparency), + "LIST", + [LSTRING(HudTransparency_DisplayName), LSTRING(HudTransparency_Description)], + LSTRING(DisplayName), + [[-1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8], [LSTRING(Dynamic), "0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", 0], 0], + false +] call CBA_fnc_addSetting; diff --git a/addons/field_rations/script_component.hpp b/addons/field_rations/script_component.hpp new file mode 100644 index 0000000000..534306b6be --- /dev/null +++ b/addons/field_rations/script_component.hpp @@ -0,0 +1,37 @@ +#define COMPONENT field_rations +#define COMPONENT_BEAUTIFIED Field Rations +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_FIELD_RATIONS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_FIELD_RATIONS + #define DEBUG_SETTINGS DEBUG_SETTINGS_FIELD_RATIONS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#include "\a3\ui_f\hpp\defineCommonGrids.inc" + +#define MP_SYNC_INTERVAL (60 + random 60) + +#define REFILL_WATER_INFINITE -10 +#define REFILL_WATER_DISABLED -1 +#define CHECK_WATER_TIME 2 +#define DRINK_FROM_SOURCE_AMOUNT 1 +#define DRINK_FROM_SOURCE_QUENCHED 10 +#define DRINK_FROM_SOURCE_TIME 10 + +#define IDC_COLORED_HUD_THIRST 6740 +#define IDC_COLORED_HUD_HUNGER 6750 +#define IDC_DRAINING_HUD_THIRST_GROUP 7740 +#define IDC_DRAINING_HUD_THIRST_ICON 7750 +#define IDC_DRAINING_HUD_HUNGER_GROUP 7840 +#define IDC_DRAINING_HUD_HUNGER_ICON 7850 + +#define FIELD_RATIONS_ITEMS (uiNamespace getVariable QXGVAR(fieldRationItems)) diff --git a/addons/field_rations/sounds/drink1.ogg b/addons/field_rations/sounds/drink1.ogg new file mode 100644 index 0000000000..eb27f1dda1 Binary files /dev/null and b/addons/field_rations/sounds/drink1.ogg differ diff --git a/addons/field_rations/sounds/drink2.ogg b/addons/field_rations/sounds/drink2.ogg new file mode 100644 index 0000000000..7266e478de Binary files /dev/null and b/addons/field_rations/sounds/drink2.ogg differ diff --git a/addons/field_rations/sounds/drink_can1.ogg b/addons/field_rations/sounds/drink_can1.ogg new file mode 100644 index 0000000000..ea91602284 Binary files /dev/null and b/addons/field_rations/sounds/drink_can1.ogg differ diff --git a/addons/field_rations/sounds/drink_can2.ogg b/addons/field_rations/sounds/drink_can2.ogg new file mode 100644 index 0000000000..d66e03f5fd Binary files /dev/null and b/addons/field_rations/sounds/drink_can2.ogg differ diff --git a/addons/field_rations/stringtable.xml b/addons/field_rations/stringtable.xml new file mode 100644 index 0000000000..2b443ccc3c --- /dev/null +++ b/addons/field_rations/stringtable.xml @@ -0,0 +1,1286 @@ + + + + + ACE Field Rations + ACE 戰地口糧 + ACE 野战军粮 + ACE Poměrové pole + ACE Rations sur le terrain + ACE Feld Rationen + ACE Terepi adagok + ACE Razioni da Campo + ACE フィールド レーション + ACE 전투식량 + ACE Racje polowe + ACE Rações de campo + ACE Полевые рационы + ACE Raciones de campo + ACE Gıda Ihtiyaçları + + + ACE Field Rations HUD + ACE Feldrationen HUD + ACE Razioni da Campo HUD + ACE 戰地口糧界面 + ACE 野战军粮界面 + ACE フィールド レーション HUD + ACE HUD Racji Polowych + Индикаторы жажды и голода + ACE Gıda Göstergesi + ACE 전투식량 HUD + ACE HUD de Raciones de campo + ACE HUD de Rações de Campo + ACE Rations de terrain HUD + + + Indicates current hunger and thirst status. + 顯示目前的飲食需求程度。 + 显示当前的饮食需求状态。 + Označuje aktuální stav hladovění a žízní. + Indique l'état actuel de la faim et de la soif. + Zeigt den aktuellen Hunger- und Durststatus an. + Jelzi az éhínség és a szomjúság állapotát. + Mostra lo stato attuale di fame e sete. + 現在の喉の渇きと空腹度の状態を示します。 + 굶주림과 갈증 정도를 표시합니다. + Wskazuje bieżący status głodu i pragnienia. + Indica o status atual de fome e sede. + Указывают на текущий статус жажды и голода. + Indica el estado actual de hambre y sed. + Mevcut açlık ve susuzluk durumunu gösterir. + + + Survival + 生存 + 生存 + Přežití + Survie + Überleben + Túlélés + Sopravvivenza + サバイバル + 생존 + Przetrwanie + Sobrevivência + Выживание + Supervivencia + Hayatta kalma + + + Eat/Drink + Essen/Trinken + Mangia/Bevi + Jeść/Pić + Есть/Пить + Yeme / Içme + 食べる/飲む + 吃/喝 + 먹기/마시기 + Comer/Beber + Comer/Beber + Manger/Boire + + + Enable/Disable Field Rations + 啟用/禁用戰地口糧。 + 启用/禁用野战军粮 + Povolit / zakázat příděly v polích + Activer / désactiver les rations de champ + Feldrationen aktivieren / deaktivieren + Terepi adagok engedélyezése / letiltása + Abilita / disabilita le razioni da campo + フィールド レーションを有効/無効化します + 전투식량 활성화/비활성화 + Włącz / wyłącz racje polowe + Ativar / Desativar rações de campo + Включение/отключение жажды и голода + Habilitar / deshabilitar las raciones de campo + Gıda Ihtiyaçlarını Etkinleştir/Devre Dışı Bırak + + + Time Without Water + 水份需時 + 脱水时间 + Czas bez wody + Temps sans eau + Zeit ohne Wasser + Víz nélküli idő + Tempo senza acqua + 水分無しでの耐久時間 + 물 없이 생존 가능 시간 + Czas bez wody + Tempo sem água + Время без воды + Tiempo sin agua + Susuz Kalma Süresi + + + How long should a person be able to go without water (hours). + 一個單位脫水之前能支撐多久(單位為小時)。 + 一个单位在脱水的情况下能够支撑多久(小时) + Jak dlouho by měla jednotka jít bez vody (hodiny) + Combien de temps une unité devrait-elle pouvoir se passer d'eau (heures)? + Wie lange sollte eine Einheit ohne Wasser auskommen (Stunden)? + Mennyi ideig kell egy egység víz nélkül (óra) + Per quanto tempo ci si può muovere senza acqua (ore) + ユニットが水分無しでどれくらいの時間耐えられるか (一時間単位) + 물을 안 마시고 얼마나 생존할 수 있는지 정합니다 (시간) + Jak długo jednostka powinna przetrwać bez wody (godziny) + Quanto tempo uma unidade pode passar sem água (horas) + Как долго персонаж может обходиться без воды (часы) + ¿Cuánto tiempo debería una unidad ir sin agua (horas)? + Bir kişi susuz ne kadar süre dayanabilir (saat). + + + Time Without Food + 飢餓需時 + 饥饿时间 + Čas bez jídla + Temps sans nourriture + Zeit ohne Essen + Élelmiszer nélkül + Tempo senza cibo + 食事抜きでの耐久時間 + 밥 없이 생존 가능 시간 + Czas bez jedzenia + Tempo sem comida + Время без еды + Tiempo sin comida + Aç Kalma Süresi + + + How long should a person be able to go without food (hours). + 一個單位挨餓之前能支撐多久(單位為小時)。 + 一个单位挨饿的情况下能够支撑多久(小时) + Jak dlouho by měla jednotka jít bez jídla (hodiny) + Combien de temps une unité doit-elle pouvoir se passer de nourriture (heures)? + Wie lange sollte eine Einheit ohne Essen gehen können (Stunden)? + Mennyi ideig kell egy egység élni nélkül (óra) + Per quanto tempo ci si può muovere senza cibo (ore) + ユニットが食事抜きでどれくらいの時間耐えられるか (一時間単位) + 밥을 안 먹고 얼마나 생존할 수 있는지 정합니다 (시간) + Jak długo jednostka powinna przetrwać bez jedzenia (godziny) + Quanto tempo uma unidade pode ir sem alimentos (horas) + Как долго персонаж может обходиться без пищи (часы) + ¿Cuánto tiempo debería una unidad ir sin comida (horas)? + Bir kişi aç ne kadar süre dayanabilir (saat). + + + Thirst Quenched + Durst gestillt + Sete placata + 止渴程度 + 解渴程度 + 喉の渇き度の満たされ量 + Утоление жажды + Pragnienie zaspokojone + Susuzluk Giderme Katsayısı + 갈증 해소 + Sed saciada + Sede saciada + Soif étanchée + + + Coefficient for the amount of thirst quenched from drinking. + Koeffizient für die Menge des Dursts, der durch Trinken gestillt wird. + Coefficiente che determina la quantità di sete placata bevendo. + 從飲用中能夠攝取多少水份。 + 通过喝水能够补充多少水份。 + 水分補給によって満たされる喉の渇きの量を表す係数。 + Коэффициент утоления жажды от питья + Współczynnik ilości zaspokojnego pragnienia od picia + Bir şey içince, susuzluğunun ne kadar giderileceğini belirler. + 마심으로써 갈증이 얼마나 해소되는지를 정합니다 + Coeficiente del saciamiento de sed por beber. + Coeficiente para a quantidade de sede saciada por beber. + Coefficient déterminant la quantité de soif étanchée par la boisson. + + + Hunger Satiated + Hunger gesättigt + Fame placata + 飽足感 + 饱腹感 + 空腹度の満たされ量 + Утоление голода + Głód Zaspokojony + Açlık Giderme Katsayısı + 배부름 + Hambre saciada + Fome saciada + Faim rassasiée + + + Coefficient for the amount of hunger satiated from eating. + Koeffizient für die Menge des Hungers, der durch essen gesättigt wird. + Coefficiente che determina la quantità di fame placata mangiando. + 從飲食中獲取多少飽食感。 + 通过饮食能够补充多少能量。 + 食事によって満たされる空腹度の量を表す係数。 + Коэффициент утоления голода от принятия пищи + Współczynnik ilosci zaspokojnego głodu od jedzenia + Bir şey yiyince, açlığın ne kadar giderileceğini belirler. + 밥을 먹어서 배고픔이 얼마나 해결되는지를 정합니다 + Coeficiente del saciamiento del hambre por comer. + Coeficiente para a quantidade de fome saciada por comer. + Coefficient déterminant la quantité de faim satisfaite en mangeant. + + + Water Source Actions + Действия с источником воды + Akcje przy źrodle wody + Su Içme Animasyonu + 水源でのアクション + Wasserquellen-Aktionen + Interazioni su sorgenti d'acqua + 水源动作 + 물 근처 행동 + Acciones para suministros de agua + Ações para suprimentos de água + Interactions sur les sources d'eau + + + Controls what actions are available on water sources. + Определяет какие действия будут доступны с источником воды. + Kontroluje jakie akcje są dostępne przy źrodle wody. + Su içerken hangi animasyonu yapacağını belirler + 水源で可能なアクションを設定します。 + Bestimmt, welche Aktionen an Wasserquellen verfügbar sind. + Determina quali azioni sono disponibili presso sorgenti di acqua. + 控制对水源可用的动作。 + 물가에서 어떤 행동을 취할지 정합니다 + Controla qué acciones están disponibles para los suministros de agua. + Controla quais ações estão disponíveis para os suprimentos de água. + Déterminer les stocks disponibles dans les sources d'eau. + + + Refill Only + Только пополнить + Tylko napełnij + Sadece içeceği iç + 水汲みのみ + Nur Befüllen + Solo riempimento + 仅限取水 + 다시 채우기만 가능 + Sólo rellenar + Apenas reabastecer + Remplissage uniquement + + + Terrain Object Actions + Действия с объектами ландшафта + Akcje Objektu terenu + Varsayılan Nesne Animasyonu + 地形オブジェクトでのアクション + Geländeobjekt-Aktionen + Interazioni su oggetti del terreno + 地形物体动作 + 지형 물체 상호작용 + Acciones sobre objetos del terreno + Ações para objetos do terreno + Actions sur les objets du terrain + + + Enables water source actions for terrain objects. + Включает действия с источниками воды для объектов ландшафта. + Umożliwia akcje przy źrodle wody na obiektach terenu. + Varsayılan nesneler için animasyonu etkinleştir + 地形に存在するオブジェクトを水源として動作するよう設定できます。 + Aktiviert Wasserquellen-Aktionen für Geländeobjekte. + Permette le interazioni da sorgenti d'acqua anche su oggetti del terreno. + 为地形物体启用水源动作。 + 지형 물체에서 물을 얻는 게 가능해집니다. + Habilitar acciones de suministros de agua para los objetos en el suelo. + Habilita ações para suprimentos de água para objetos do terreno. + Active les actions relatives aux sources d'eau pour les objets de terrain. + + + Affect Advanced Fatigue + Beeinflusst die erweiterte Ausdauer + Influenza la Fatica Avanzata + 與進階疲勞聯動 + 与进阶疲劳联动 + アドバンスド疲労への影響 + Влияние на продвинутую усталость + Wpływ na zaawansowane zmęczenie + Gelişmiş Yorgunluk + 고급 피로도에 영향을 끼침 + Afecta a la Fatiga Avanzada + Afeta a Fadiga Avançada + Affectation Fatigue avancée + + + Controls if thirst and hunger should affect ACE Advanced Fatigue. + Bestimmt, ob Durst und Hunger ACE Erweiterte Ausdauer beeinflussen sollen. + Determina se fame e sete influenzano la Fatica Avanzata ACE. + 是否讓飲食影響到ACE的進階疲勞。 + 是否让饮食影响到 ACE 的进阶疲劳。 + 喉の渇きと空腹度が ACE アドバンスド疲労へ与える影響を定義します。 + Определяет, будет ли жажда и голод влиять на продвинутую усталость ACE. + Kontroluje czy pragnienie i głód mają wpływ na zaawansowane zmęczenie ACE. + Acıkınca veya susayınca kişinin yorulup yorulmayacağını belirler. + 배고픔과 목마름이 고급 피로도에 영향을 끼칠지를 정합니다 + Controla si la sed y el hambre afectan a la Fatiga Avanzada de ACE + Controla se a sede e a fome afetam a Fadiga Avançada do ACE. + Contrôle si la soif et la faim doivent affecter la fatigue avancée ACE. + + + HUD Type + HUD Typ + Tipo HUD + 界面類型 + 界面类型 + HUD タイプ + Typ HUD + Тип индикаторов + HUD Tipi + HUD 종류 + Tipo de HUD + Tipo de HUD + Type de HUD + + + Selects which HUD style will be used. + Wählt, welcher HUD Stil benutzt wird. + Seleziona lo stile utilizzato per l'HUD. + 選擇妳想使用的界面類型。 + 选择你想使用的界面类型。 + 使用する HUD のタイプを選択できます + Wybierz który styl HUD będzie używany + Выберите какой стиль индикаторов будет использован. + Hangi HUD sitilini kullanılacağını seçer. + 사용될 HUD 스타일을 고르십시오. + Selecciona qué estilo de HUD será utilizado. + Seleciona qual estilo de HUD será usado. + Sélectionne le style HUD à utiliser. + + + Colored Icons + Farbige Icons + Icone colorate + 顏色化圖示 + 彩色图标 + 色付きアイコン + Kolorowe ikony + Цветные иконки + Renkli Ikonlar + 색깔 아이콘 + Iconos coloreados + Ícones coloridos + Icônes de couleur + + + Draining Icons + Farblose Icons + Icone non colorate + 增減化圖示 + 渐化图标 + レベルゲージアイコン + Ubywające ikony + Исчезающие иконки + Içi Boşalan Ikonlar + 빠지는 아이콘 + Iconos de drenado + Ícones de drenagem + Icônes incolores + + + HUD Show Level + HUD zeigen Level + Livello Mostra HUD + 界面顯示程度 + 界面显示程度 + HUD 表示レベル + Widok HUD + Уровень для отображения иконок + HUD Gösterilme Seviyesi + HUD 표시 + Mostrar nivel en HUD + Mostrar nível no HUD + Afficher le niveau dans le HUD + + + Automatically show the HUD when either thirst or hunger are above this level. + Zeigt automatisch das HUD an, sobald Durst oder Hunger über diesem Level sind. + Mostra le icone HUD in automatico quando fame o sete superano questo livello. + 在飲食低於多少程度時顯示界面。 + 在饮食能量低于多少程度时显示界面。 + この値以上に空腹度か喉の渇きを感じると自動的に HUD を表示します + Automatycznie pokaż HUD kiedy pragnienie albo głód przekroczy ten poziom + Автоматически отображает иконки при достижении определенных уровней голода и жажды. + Susuzluk veya açlık belli bir seviyenin altına inince otomatik olarak HUD u göster. + 정한 퍼센트 이하로 내려가면 HUD가 나타나게 합니다. + Mostrar automáticamente el HUD cuando la sed o el hambre están por encima de este nivel. + Mostrar automaticamente o HUD quando a sede ou a fome estão acima deste nível. + Affiche automatiquement le HUD dès que la soif ou la faim sont au-dessus de ce niveau. + + + Always + 總是 + 总是 + Vždy + Toujours + Immer + Mindig + Sempre + 常に + 항상 + Zawsze + Sempre + Всегда + Siempre + Her Zaman + + + Colored Icons - Transparency + Farbige Icons - Transparenz + Icone Colorate - Trasparenza + 顏色化圖示 - 透明度 + 彩色图标—透明度 + 色付きアイコン - 透明度 + Kolorowe ikony - transparentność + Прозрачность цветных иконок + Renkli Ikonlar - Şeffaflaşan + 색깔 아이콘 - 투명도 + Iconos coloreados - Transparencia + Ícones coloridos - Transparência + Icônes de couleur - Transparence + + + Controls the transparency of the Colored Icons HUD. Dynamic setting makes the HUD less transparent as thirst or hunger increase. + Bestimmt die Tranzparenz der farbigen HUD Icons. Die Dynamische Einstellung macht das HUD weniger transparent, wenn Hunger oder Durst steigen. + Determina la trasparenza di icone HUD colorate. L'impostazione 'Dinamico' rende l'HUD meno trasparente quando la fame o sete è maggiore. + 控制顏色化圖示的透明度。設定為動態使其界面透明度與飲食需求一樣,越透明越需要。 + 控制彩色图标 HUD 的透明度。动态设置使 HUD 的透明度随着口渴或饥饿的增加而减弱。 + Kontroluje transparentność kolorowych ikon HUD. Dynamiczne ustawienie zmniejsza przejrzystość wraz z zwiększeniem głodu czy pragnienia. + 色付きアイコンの透明度を制御できます。動的に設定されると、空腹度や喉の渇きが増すにつれて、アイコンの透明度を下げます。 + Настраивает прозрачность цветных иконок. «Динамическая» делает иконки менее прозрачными при увеличении жажды и голода. + Renkli Simgeler Gösterge Paneli'nin şeffaflığını kontrol eder. Dinamik ayar, susuzluk veya açlık arttıkça HUD'yi daha az şeffaf hale getirir. + 색깔 아이콘의 투명도를 조절합니다. 동적 설정의 경우 배고픔이나 목마름이 해결되면 덜 투명하게 바뀝니다. + Controla la transparencia de los Iconos coloreados en el HUD. La opción dinámica muestra el HUD menos transparente cuando la sed o el hambre aumentan. + Controla a transparência dos ícones coloridos no HUD. A configuração dinâmica torna o HUD menos transparente à medida que a sede ou a fome aumentam. + Contrôle la transparence du HUD des icônes colorées. Un réglage dynamique rend le HUD moins transparent lorsque la soif ou la faim augmentent. + + + Dynamic + 動態 + 动态 + Dynamický + Dynamique + Dynamisch + Dinamikus + Dinamico + 動的 + 동적 + Dynamiczny + Dinâmico + Динамическая + Dinámica + Dinamik + + + Water Supply + Wasservorrat + Scorta d'acqua + 飲用水補給 + 饮用水补给 + 水資源量 + Водные ресурсы + Źródło wody + 식수 보급량 + Suministro de agua + Suprimentos de água + Réserve d'eau + + + The amount of water available for ACE Field Rations water source actions (-1 disabled, -10 infinite) + Die Menge des für ACE Feldrationen Wasserquellenaktionen verfügbaren Wassers (-1 ausgeschaltet, -10 unendlich) + La quantità di acqua disponibile per interazioni ACE Razioni da Campo di sorgenti d'acqua (-1 nessuna, -10 infinita) + 水源可供補充飲用水的次數(-1為關閉,-10為無限次)。 + 水源可供取水的次数(-1为关闭,-10为无限次)。 + ACE フィールド レーションで利用できる水源の資源量を設定できます。(-1で無効化、-10で無限) + Количество воды, доступной для использования в ACE Полевые рационы. (-1 - отключено, -10 - бесконечно) + Ilość wody dostępnej dla Akcji ACE Źródła wody (-1 wyłączone, -10 nieskończone) + ACE 전투식량 물 근처 행동에서 얼마나 물을 얻어 갈 수 있는지를 정합니다 (-1은 비활성화, -10은 무한대) + La cantidad de agua disponible para las acciones de suministro de agua de las Raciones de Combate de ACE (-1 deshabilitado, -10 infinito) + A quantidade de água disponível para as ações de suprimentos de água das Rações de Campo do ACE (-1 desativado, -10 infinito) + Quantité d'eau disponible pour les actions relatives aux sources d'eau des rations de campagne ACE (-1 désactivé, -10 infini). + + + Water Source + Wasserquelle + Sorgente d'acqua + 水源 + 水源 + 水源 + Źródło wody + Источник воды + Matara + 수원지 + Suministro de agua + Fonte de água + Source d'eau + + + Check Remaining Water + Überprüfe verbleibendes Wasser + Controlla acqua rimanente + 檢查剩餘飲用水 + 检查剩余饮用水 + 残っている水を確認 + Sprawdź ilość wody + Проверить остаток воды + Kalan Suyu Kontrol Et + 남은 물 확인 + Comprobar agua restante + Verificar água restante + Vérifier l'eau restante + + + Checking remaining water... + Überprüfe verbleibendes Wasser... + Controllando acqua rimanente... + 檢查剩下的飲用水... + 检查剩余饮用水中... + 残っている水量を確認中です・・・ + Sprawdzanie ilości wody + Проверяется остаток воды... + Kalan Su Kontrol Ediliyor... + 남은 물 확인 중... + Comprobando agua restante... + Verificando água restante... + Vérification de l'eau restante... + + + There are %1 litres left. + Es sind %1 Liter übrig. + Ci sono ancora %1 Litri. + 那還有 %1 公升 + 还剩下 %1 升 + あと %1 リットル残っています。 + Pozostało %1 litrów. + Осталось %1 л воды + %1 Litre kaldı. + %1 리터의 물이 남아있습니다. + Quedan %1 litros. + Ainda há %1 litros. + Il reste %1 litres. + + + There is no water left. + Es ist kein Wasser mehr übrig. + Non c'è più acqua rimanente + 水已經用完了 + 水已经喝完了。 + 水は残っていません。 + Nie ma wody + Воды больше не осталось + Hiç su kalmadı. + 물이 한 방울도 없습니다. + No queda agua. + Não há mais água. + Il n'y a plus d'eau. + + + Drink From Source + Trinke direkt + Bevi da sorgente + Выпить из источника + Pij z źródła wody + Mataradan Iç + 水源から飲む + 从水源处喝水 + 수원에서 물 마시기 + Beber desde el suministro + Beber da fonte + Boire à la source + + + Refill + 重新補充 + 重新取水 + Doplňte + Recharge + Nachfüllung + Utántöltés + Riempi + 水を汲む + 다시 채우기 + Uzupełnij + Recarga + Наполнить ёмкость + Rellenar + Yeniden Doldur + + + Refilling... + 補充中... + 取水中... + Doplňování... + Remplissage ... + Nachfüllen... + Utántöltés ... + Riempendo... + 汲んでいます・・・ + 채우는 중... + Uzupełnianie ... + Recarga ... + Наполнение... + Rellenar ... + Yeniden Dolduruluyor... + + + Item Refilled + 物品重新補充 + 物品已重新补充 + Položka je vyplněna + Article rechargé + Artikel nachgefüllt + Újratöltött tétel + Oggetto riempito + 中身がいっぱいになりました + 아이템 채워짐 + Przedmiot uzupełniony + Item Recarregado + Ёмкость наполнена + Artículo Rellenado + Eşya Yeniden Dolduruldu + + + Eating %1... + Esse %1... + Mangiando %1... + 食用 %1... + 食用 %1... + %1 を食べています・・・ + Jedzenie %1... + Поедание %1... + %1 Yeniyor... + %1 먹는 중... + Comiendo %1... + Comendo %1... + Manger %1... + + + Drinking %1... + Trinke %1... + Bevendo %1... + 飲用自 %1... + 饮用 %1... + %1 を飲んでいます・・・ + Picie %1... + Выпивание %1... + %1 Içiliyor... + %1 마시는 중... + Bebiendo %1... + Bebendo %1... + Boire %1... + + + Drinking from %1... + Trinke von %1... + Bevendo da %1... + 飲用%1的水中... + 从%1饮用中... + %1 から飲んでいます・・・ + Picie z %1... + Выпивание из %1... + %1 den içiliyor... + %1 으로 부터 마시는 중... + Bebiendo desde %1... + Bebendo de %1... + Boire à %1... + + + Drinking from source... + Выпивание из источника... + Picie z źródła + Mataradan Içiliyor... + 水源から飲んでいます・・・ + Trinke von Quelle... + Bevendo da sorgente... + 从水源处喝水中... + 수원에서 마시는 중... + Bebiendo desde el suministro... + Bebendo da fonte... + Boire à la source... + + + Water Bottle + 飲用水 + 矿泉水 + Láhev na vodu + Bouteille d'eau + Wasserflasche + Vizesüveg + Bottiglia d'acqua + 水のペットボトル + 물병 + Butelka wody + Garrafa de água + Бутылка воды (полная) + Botella de agua + Su Şişesi + + + A water bottle + 一罐裝滿水的寶特瓶 + 一罐装满水的矿泉水瓶 + Láhev s vodou + Une bouteille d'eau + Eine Wasserflasche + Egy vizes palackot + Una bottiglia d'acqua + 水入りペットボトル + 물병 + Butelka wody + Uma garrafa de água + Полная бутылка с водой + Una botella de agua + Bir Su Şişesi + + + Water Bottle (Half) + 飲用水(半罐) + 矿泉水(半瓶) + Vodní láhev (poloviční) + Bouteille d'eau (la moitié) + Wasserflasche (Hälfte) + Vízpalack (fél) + Bottiglia d'acqua (metà) + 水のペットボトル (半分) + 물병 (절반) + Butelka wody (połowa) + Garrafa de água (meio) + Бутылка воды (половина) + Botella de agua (mitad) + Su Şişesi (Yarım) + + + A half full water bottle + 一罐裝滿半罐水的寶特瓶 + 半瓶矿泉水 + Polní plná láhev s vodou + Une bouteille d'eau à moitié pleine + Eine halbvolle Wasserflasche + Fél-teljes vizes palack + Una bottiglia d'acqua mezza piena o mezza vuota + 半分残っている水入りペットボトル + 절반만 차 있는 물병입니다. + Pół butelki z wodą + Uma garrafa de água meia cheia + Половина бутылки с водой + Una botella de agua media llena + Yarım dolu Su Şişesi + + + Water Bottle (Empty) + 空寶特瓶 + 矿泉水(空) + Láhev s vodou (prázdné) + Bouteille d'eau (vide) + Wasserflasche (leer) + Vízpalack (üres) + Bottiglia d'acqua (vuota) + 水のペットボトル (空) + 물병 (비어 있음) + Butelka na wodę (pusta) + Garrafa de água (vazia) + Бутылка воды (пустая) + Botella de agua (vacía) + Su Şişesi (Boş) + + + An empty water bottle + 一個空寶特瓶 + 一个空的矿泉水瓶 + Prázdná láhev s vodou + Une bouteille d'eau vide + Eine leere Wasserflasche + Egy üres palack + Una bottiglia d'acqua vuota + 空のウォーターボトル + 빈 물병입니다 + Pusta butelka wody + Uma garrafa de água vazia + Пустая бутылка + Una botella de agua vacía + Boş Su Şişesi + + + Canteen + 水壺 + 水壶 + Jídelna + Cantine + Feldflasche + Kantin + Borraccia + 水筒 + 수통 + Manierka + Cantina + Фляга (полная) + Cantina + Matara + + + A canteen filled with water + 一個裝滿水的水壺 + 一个装满水的水壶 + Jídelna naplněná vodou + Une cantine remplie d'eau + Eine Feldflasche mit Wasser gefüllt + Vízzel töltött kantin + Una borraccia piena d'acqua + 水で一杯の水筒 + 물이 가득찬 수통입니다 + Manierka wypełniona wodą + Uma cantina cheia de água + Фляга с водой + Una cantina llena de agua + Su Dolu Matara + + + Canteen (Half) + 水壺(半罐) + 水壶(半壶) + Jídelna (poloviční) + Cantine (Demi) + Feldflasche (halb) + Étkezés (fél) + Borraccia (metà) + 水筒 (半分) + 수통 (절반) + Manierka (połowa) + Cantina (meio) + Фляга (половина) + Cantina (Mitad) + Matara (Yarım) + + + A canteen half filled with water + 剩下一半水的水壺 + 剩一半水的水壶 + Jídelna naplněná vodou + Une cantine à moitié remplie d'eau + Eine Feldflasche zur Hälfte mit Wasser gefüllt + A vízzel töltött kantin + Una borraccia riempita per metà di acqua + 半分入っている水筒 + 반이 차 있는 수통입니다 + Manierka w połowie wypełniona wodą + Uma meia cantina cheia de água + Наполовину заполненая водой фляга + Una cantina medio llena de agua + Yarım Dolu Matara + + + Canteen (Empty) + 水壺(空) + 水壶(空) + Jídelna (prázdné) + Cantine (Vide) + Feldflasche (leer) + Étkezde (üres) + Borraccia (vuota) + 水筒 (空) + 수통 (비어 있음) + Manierka (pusta) + Cantina (vazia) + Фляга (пустая) + Cantina (Vacío) + Matara (Boş) + + + An empty canteen + 一個空的水壺 + 一个空的水壶 + Prázdná jídelna + Une cantine vide + Eine leere Feldflasche + Egy üres kantin + Una borraccia vuota + 空の水筒 + 빈 수통입니다 + Pusta manierka + Uma cantina vazia + Пустая фляга + Una cantina vacía + Boş Matara + + + Refreshing lemon and lime flavored soft drink + Ein erfrischender Softdrink mit Zitronen- und Limettengeschmack. + Una bibita rinfrescante con gusto di limoni e lime. + 清新檸檬以及有著酸橙味的汽水 + 清爽的柠檬和青柠味汽水 + 新鮮なレモンとライムの風味を味わえるソフトドリンク + Odświeżający napój cytronowo-limonkowy + Освежающий напиток со вкусом лимона и лайма + Limon Ve Yeşil Limondan Yapılmış Gazlı Bir Içecek + 상쾌한 레몬라임향의 탄산음료 + Bebida refrescante de sabor lima y limón + Bebida refrescante de sabor limão e lima + Une boisson gazeuse rafraîchissante au goût de citron et de citron vert. + + + Orange flavored soft drink with a tingly, fruity taste + Ein nach Orange schmeckender Softdrink mit einem prickelndem und fruchtigem Geschmack + Una bibita frizzante con gusto di arancia + 有著微微的橘子水果味的汽水 + 橙子味汽水,有刺鼻的水果味 + 口いっぱいに果物を感じるオレンジ風味のソフトドリンク + Napój pomarańczowy + Напиток с апельсиновым вкусом + Gazlı Portakallı Bir Içecek + 오렌지 향의 톡쏘는 탄산음료 + Bebida refrescante de sabor naranja, con un chispeante y afrutado sabor. + Bebida refrescante de sabor laranja, com um sabor frutado e formigante. + Une boisson gazeuse aromatisée à l'orange + + + Red Gull gives you wings + Red Gull verleiht Flügel + Red Gull mette le ali + 紅鷹讓你猛虎添翼 + 红鹰让你猛虎添翼 + レッドガル 翼を授ける + Red Gull doda ci skrzydeł + Рэд Гулл окрыляет! + Red Gull kanatlandırrrrr + 레드굴은 날개를 달아줘요 + Red Gull te da alas + Red Gull te dá asas + Red Gull vous donne des ailes + + + MRE Lamb Curry + 軍糧 羊肉咖哩 + 军粮羊肉咖喱饭 + MRE jehněčí kari + MRE Curry d'agneau + EPA Lamm Curry + MRE bárány Curry + MRE Agnello al curry + MRE ラムカレー + MRE 양고기 카레 + MRE jagnięcina Curry + MRE cordeiro ao Curry + ИРП Ягненок карри + MRE cordero Curry + MRE Kuzu Köri + + + An MRE containing Lamb Curry. Heat for best effect + 含有羊肉咖哩的軍用口糧。加熱以達到最佳效果 + 含有羊肉咖喱饭的军粮。加热以达到最佳效果 + MRE obsahující Lamb Curry. Teplo pro nejlepší efekt + Un MRE contenant du Curry d'agneau. Chaleur pour le meilleur effet + Eine EPA mit Lamm Curry. Für den besten Geschmack erhitzen. + Egy MRE, amely Lamb Curry-t tartalmaz. Hő a legjobb hatás érdekében + Un MRE contenente Agnello al Curry. Riscalda per un sapore migliore. + ラム(羊肉)カレーの MRE。温めるとなお美味しい + 양고기 카레가 들어있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 + MRE zawierające jagnięcine Curry. Podgrzej dla najlepszego efektu + Um MRE contendo Lamb Curry. Calor para melhor efeito + Сухой паёк, содержащий ягнятину карри. Перед употреблением рекомендуется разогреть + Un MRE que contiene cordero al curry. Calentar para mejor efecto. + Kuzu Köri içeren bir MRE. + + + MRE Beef Stew + EPA Rindereintopf + MRE Zuppa di bovino + 軍糧 牛肉燉湯 + 军粮炖牛肉汤 + MRE ビーフシチュー + MRE Gulasz wołowy + ИРП Тушеная говядина + MRE Dana Yahni + MRE 비프스튜 + MRE Estofado de ternera + MRE ensopado de carne + MRE Ragoût de bœuf + + + An MRE containing Beef Stew. Heat for best effect + Eine EPA, welche Rindereintopf beeinhaltet. Für den besten Geschmack erhitzen. + Un MRE contenente zuppa di bovino. Riscalda per un sapore migliore. + 含有牛肉燉湯的軍用口糧。加熱以達到最佳效果 + 含有牛肉炖汤的军粮。加热以达到最佳效果 + ビーフ シチューの MRE。温めるとなお美味しい + MRE zawierające gulasz wołowy. Podgrzej dla najlepszego efektu + Сухой паёк, содержащий тушеную говядину. Перед употреблением рекомендуется разогреть + Sığır Yahni içeren bir MRE. + 비프스튜가 들어있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 + Un MRE que contiene estofado de ternera. Calentar para mejor efecto. + Um MRE contendo ensopado de carne. Aquecer para melhor efeito + Un MRE contenant du ragoût de bœuf. Chauffer pour un meilleur effet + + + MRE Cream Tomato Soup + 軍糧 奶油番茄湯 + 军粮奶油西红柿汤 + MRE krémová rajská polévka + MRE Soupe de tomate crème + EPA Cremige Tomatensuppe + MRE krémes paradicsomleves + MRE Zuppa di pomodoro + MRE クリームトマトスープ + MRE 크림 토마토 수프 + MRE Kremowa Zupa Pomidorowa + MRE Sopa de creme de tomate + ИРП Томатный крем-суп + MRE Sopa de tomate crema + MRE Kremalı Domates Çorbası + + + An MRE containing Cream Tomato Soup. Mix with water and heat for best effect + 含有奶油番茄湯的軍用口糧。 用水和熱混合以獲得最佳效果 + 含有奶油番茄汤的军粮。添水加热以获得最佳效果 + MRE obsahující krémovou rajčatovou polévku. Směs s vodou a teplem pro nejlepší efekt + Un MRE contenant de la soupe à la tomate et à la crème. Mélanger avec de l'eau et chauffer pour obtenir le meilleur effet + Eine EPA mit Creme Tomatensuppe. Für beste Wirkung mit Wasser und Hitze mischen. + Egy krémes paradicsomleveset tartalmazó MRE. Keverjük össze vízzel és hővel a legjobb hatás érdekében + Un MRE contenente zuppa di pomodoro cremosa. Mescolare con acqua e riscaldare per il sapore migliore + クリームトマトスープの MRE。水と混ぜて温めるとなお美味しい + 크림 토마토 수프가 들어 있는 MRE입니다. 물과 섞어 뜨겁게 먹을 때 가장 좋습니다 + MRE zawierające śmietanową zupę pomidorową. Wymieszaj z wodą i podgrzej, aby uzyskać najlepszy efekt + Uma MRE contendo Cream Tomato Soup. Misture com água e calor para melhor efeito + Сухой паёк, содержащий сублимированный томатный крем-суп. Перед употреблением растворить в воде и разогреть + Una MRE que contiene Sopa de Tomate Crema. Mezcle con agua y calor para un mejor efecto + Kremalı Domates Çorbası içeren bir MRE. + + + MRE Cream Chicken Soup + 軍糧 奶油雞湯 + 军粮奶油鸡汤 + MRE krémová kuřecí polévka + MRE Soupe à la crème au poulet + EPA Cream Hühnersuppe + MRE krémes csirke leves + MRE Zuppa di pollo + MRE クリームチキンスープ + MRE 크림 치킨 수프 + MRE Kremowy Rosół + MRE Sopa de creme de galinha + ИРП Куриный крем-суп + MRE Sopa de pollo crema + MRE Kremalı Tavuk Çorbası + + + An MRE containing Chicken Soup. Mix with water and heat for best effect + 含有雞湯的軍用口糧。 用水和熱混合以獲得最佳效果 + 含有鸡汤的军粮。添水加热以获得最佳效果 + MRE obsahující kuřecí polévku. Směs s vodou a teplem pro nejlepší efekt + Un MRE contenant une soupe au poulet. Mélanger avec de l'eau et chauffer pour obtenir le meilleur effet + Eine EPA mit Hühnersuppe. Für beste Wirkung mit Wasser und Hitze mischen. + A csirke leves tartalmú MRE. Keverjük össze vízzel és hővel a legjobb hatás érdekében + Un MRE contenente zuppa di pollo. Mescolare con acqua e riscaldare per il sapore migliore + クリームチキンスープの MRE。水と混ぜて温めるとなお美味しい + 치킨 수프가 들어 있는 MRE입니다. 물과 섞어 뜨겁게 먹을 때 가장 좋습니다 + MRE zawierające rosół. Wymieszaj z wodą i podgrzej, aby uzyskać najlepszy efekt + Um MRE contendo Sopa de Frango. Misture com água e calor para melhor efeito + Сухой паёк, содержащий сублимированный куриный крем-суп. Перед употреблением растворить в воде и разогреть + Un MRE que contiene sopa de pollo. Mezcle con agua y calor para un mejor efecto + Tavuk Çorbası içeren bir MRE. + + + MRE Chicken Tikka Masala + 軍糧 瑪撒拉雞 + 军粮鸡蒂卡 Masala + MRE Kuře Tikka Masala + MRE Poulet Tikka Masala + EPA Huhn Tikka Masala + MRE csirke Tikka Masala + MRE Pollo Tikka Masala + MRE チキン ティッカ マサラ + MRE 치킨 티카 마살라 + MRE kurczak Tikka Masala + MRE frango Tikka Masala + ИРП Курица Тикка Масала + MRE Pollo Tikka Masala + MRE Tikka Masala Soslu Tavuk + + + An MRE with Chicken Tikka Masala. Heat for best effect + 含有瑪撒拉雞的軍用口糧。 用水和熱混合以獲得最佳效果 + 与鸡 Tikka 马萨拉军粮。加热以达到最佳效果 + MRE s kuřecím masem Tikka Masala. Teplo pro nejlepší efekt + Un MRE avec du poulet Tikka Masala. Chaleur pour le meilleur effet + Eine EPA mit Hühnchen Tikka Masala. Für den besten Geschmack erhitzen. + Egy MRE csirkével Tikka Masala. Hő a legjobb hatás érdekében + Un MRE con pollo Tikka Masala. Riscaldare per il sapore migliore + チキン ティッカ マサラの MRE。温めるとなお美味しい + 치킨 티카 마살라 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 + MRE z kurczakiem Tikka Masala. Podgrzej dla najlepszego efektu + Um MRE com Frango Tikka Masala. Calor para melhor efeito + Сухой паёк, содержащий Курицу Тикка Масала. Перед употреблением рекомендуется разогреть + Un ERM con Pollo Tikka Masala. Calor para un mejor efecto + Tikka Masala Soslu Tavuk içeren bir MRE. + + + MRE Steak Vegetables + 軍糧 牛排蔬菜 + 军粮牛排蔬菜 + MRE Steak zelenina + MRE Steak légumes + EPA Steak Gemüse + MRE Steak zöldségek + MRE Bistecca con verdure + MRE 野菜添えステーキ + MRE 스테이크 야채 + MRE Stek Warzywny + MRE bife legumes + ИРП Стейк с овощами + ERM de ternera verduras + MRE Sebzeli Biftek + + + An MRE containing Steak and Vegetables. Heat for best effect + 包含牛排和蔬菜的軍用口糧。 加熱以達到最佳效果 + 包含牛排和蔬菜的军粮。加热以达到最佳效果 + MRE obsahující steak a zeleninu. Teplo pro nejlepší efekt + Un MRE contenant du bifteck et des légumes. Chaleur pour le meilleur effet + Eine EPA mit Steak und Gemüse. Für den besten Geschmack erhitzen. + Egy MRE, amely Steak és Zöldségeket tartalmaz. Hő a legjobb hatás érdekében + Un MRE contenente bistecca e verdure. Riscaldare per il sapore migliore + 野菜とステーキの MRE。温めるとなお美味しい + 스테이크와 채소가 들어 있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 + MRE zawierający stek i warzywa. Podgrzej dla najlepszego efektu + Um MRE contendo Bife e Legumes. Calor para melhor efeito + Сухой паёк, содержащий стейк с овощами. Перед употреблением рекомендуется разогреть + Un MRE que contiene carne y verduras. Calor para el mejor efecto + Sebzeli Biftek içeren bir MRE. + + + MRE Meatballs and Pasta + 軍糧 肉丸和意大利麵 + 军粮肉丸和意大利面 + MRE karbanátky a těstoviny + MRE Pâtes aux boulettes de viande + EPA Frikadellen und Pasta + MRE húsgombóc és tészta + MRE Pasta e polpette + MRE ミートボールとパスタ + MRE 미트볼 파스타 + MRE Klopsiki i makaron + MRE Macarrão com almôndegas + ИРП Макароны с фрикадельками + MRE Albóndigas y pastas + MRE Köfte Ve Makarna + + + An MRE containing Meatballs and Pasta. Heat for best effect + 含有肉丸和意大利麵的軍用口糧。 加熱以達到最佳效果 + 含有肉丸和意大利面的军粮。加热以达到最佳效果 + MRE obsahující maso a těstoviny. Teplo pro nejlepší efekt + Un MRE contenant des boulettes de viande et des pâtes. Chaleur pour le meilleur effet + Eine EPA mit Fleischbällchen und Pasta. Für den besten Geschmack erhitzen. + Húsgombócokat és tésztát tartalmazó MRE. Hő a legjobb hatás érdekében + Un MRE contenente pasta con polpette. Riscaldare per il sapore migliore + ミートボールとパスタの MRE。温めるとなお美味しい + 미트볼과 파스타가 들어 있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 + MRE zawierające klopsiki i makaron. Podgrzej dla najlepszego efektu + Um MRE contendo Meatballs e Pasta. Calor para melhor efeito + Сухой паёк, содержащий макароны с фрикадельками. Перед употреблением рекомендуется разогреть + Un MRE que contiene albóndigas y pasta. Calor para el mejor efecto + Köfte ve makarnadan oluşan bir MRE. + + + MRE Chicken with Herb Dumplings + 軍糧 雞肉香草餃子 + 军粮鸡肉香草饺子 + MRE kuře s bylinkovým knedlíkem + MRE de poulet avec des boulettes aux herbes + EPA Huhn mit Kraut Knödel + MRE csirke Herb galuskával + MRE pollo con gnocchi alle erbe + MRE チキンとハーブ団子 + MRE 허브 치킨 만두 + MRE kurczak z pierogami ziołowymi. + MRE Frango com Dumplings de ervas + ИРП Курица с клёцками + MRE pollo con bolas de masa hervida + MRE Tavuk ve Herb Mantısı + + + An MRE containing Chicken with Herb Dumplings. Heat for best effect + 含有雞肉和香草餃子的軍用口糧。 加熱以達到最佳效果 + 含有鸡肉和香草饺子的军粮。加热以达到最佳效果 + MRE obsahující kuře s bylinkovými knedlíky. Teplo pro nejlepší efekt + Un MRE contenant du poulet et des dumplings aux fines herbes. Chaleur pour le meilleur effet + Eine EPA mit Hühnchen mit Kräuterknödeln. Für den besten Geschmack erhitzen. + Egy MRE, amely csirkét és fűszeres gombócokat tartalmaz. Hő a legjobb hatás érdekében + Un MRE contenente pollo con gnocchi alle erbe. Riscaldare per il sapore migliore + チキンとハーブ団子のMRE。温めるとなお美味しい + 허브 치킨 만두 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 + MRE z kurczakiem i pierogamii ziołowymi. Podgrzej dla najlepszego efektu + Uma MRE que contém Bolinhos De Frango Com Erva. Calor para melhor efeito + Сухой паёк, содержащий курицу с клёцками. Перед употреблением рекомендуется разогреть + Un MRE que contiene pollo con bolas de masa hervida. Calor para el mejor efecto + Tavuk ve Herb Mantısı içeren bir MRE. + + + Humanitarian Ration + 人道主義口糧 + 人道主义口粮 + Humanitární poměr + Ration humanitaire + Humanitäre Ration + Humanitárius értelemben + Razione umanitaria + 人道支援配給レーション + 난민배급식량 + Racja humanitarna + Ração Humanitária + Гуманитарный сухой паёк + Ración humanitaria + + + A Humanitarian Ration intended to serve as a person's food supply during crises + 人道主義口糧意圖在危機期間充當人的食物供應 + 用于危机期间个人食物供应的人道主义口粮。 + Humanitární rada, která má sloužit jako zásobování potravinami během krizí + Une ration humanitaire destinée à servir d'approvisionnement alimentaire en cas de crise + Eine humanitäre Ration, die dazu bestimmt ist, in Krisenzeiten als Nahrung für eine Person zu dienen + Humanitárius eloszlás, amelynek célja az ember élelmezési ellátottsága a válság idején + Una razione umanitaria destinata a fungere come riserva di cibo di una persona in caso di crisi umanitarie + 危機に瀕した人々の供給食としての使用を目的とした人道配給食 + 재난 상황에 식량으로 쓸 수 있는 인도주의 차원의 배급식량입니다 + Racja humanitarna, która ma służyć jako żywność dla danej osoby podczas kryzysów + Uma Ração Humanitária destinada a servir como alimento alimentar de uma pessoa durante as crises + Суточный рацион питания для обеспечения населения районов, охваченных гуманитарной катастрофой или стоящих на ее грани + Una ración humanitaria destinada a servir como el suministro de alimentos de una persona durante las crisis + + + Sunflower Seeds + Sonnenblumenkerne + Semi di girasole + 해바라기씨 + Nasiona Słonecznika + ヒマワリの種 + 葵花籽 + Семечки подсолнуха + Pipas de girasol + Sementes de girassol + Graines de tournesol + + + Roasted And Salted + Geröstet und Gesalzen + Tostati e salati + 굽고 간을 했습니다 + Pieczone i Solone + 炒って塩で味付け済 + 焙烤盐焗 + Поджаренные и солёные + Tostadas y saladas + Torradas e salgadas + Grillé et salé + + + diff --git a/addons/field_rations/ui/icon_can_franta_ca.paa b/addons/field_rations/ui/icon_can_franta_ca.paa new file mode 100644 index 0000000000..ae2605dd35 Binary files /dev/null and b/addons/field_rations/ui/icon_can_franta_ca.paa differ diff --git a/addons/field_rations/ui/icon_can_redgull_ca.paa b/addons/field_rations/ui/icon_can_redgull_ca.paa new file mode 100644 index 0000000000..7c18aedbf9 Binary files /dev/null and b/addons/field_rations/ui/icon_can_redgull_ca.paa differ diff --git a/addons/field_rations/ui/icon_can_spirit_ca.paa b/addons/field_rations/ui/icon_can_spirit_ca.paa new file mode 100644 index 0000000000..9794c7ee15 Binary files /dev/null and b/addons/field_rations/ui/icon_can_spirit_ca.paa differ diff --git a/addons/field_rations/ui/icon_hud_hungerstatus.paa b/addons/field_rations/ui/icon_hud_hungerstatus.paa new file mode 100644 index 0000000000..949dd5a37a Binary files /dev/null and b/addons/field_rations/ui/icon_hud_hungerstatus.paa differ diff --git a/addons/field_rations/ui/icon_hud_thirststatus.paa b/addons/field_rations/ui/icon_hud_thirststatus.paa new file mode 100644 index 0000000000..3f4d901aa7 Binary files /dev/null and b/addons/field_rations/ui/icon_hud_thirststatus.paa differ diff --git a/addons/field_rations/ui/icon_survival.paa b/addons/field_rations/ui/icon_survival.paa new file mode 100644 index 0000000000..aa9299df7f Binary files /dev/null and b/addons/field_rations/ui/icon_survival.paa differ diff --git a/addons/field_rations/ui/icon_water_tap.paa b/addons/field_rations/ui/icon_water_tap.paa new file mode 100644 index 0000000000..0808fc9dde Binary files /dev/null and b/addons/field_rations/ui/icon_water_tap.paa differ diff --git a/addons/field_rations/ui/igui_preview.paa b/addons/field_rations/ui/igui_preview.paa new file mode 100644 index 0000000000..58ffe038bd Binary files /dev/null and b/addons/field_rations/ui/igui_preview.paa differ diff --git a/addons/field_rations/ui/item_canteen_co.paa b/addons/field_rations/ui/item_canteen_co.paa new file mode 100644 index 0000000000..f9b6ad6887 Binary files /dev/null and b/addons/field_rations/ui/item_canteen_co.paa differ diff --git a/addons/field_rations/ui/item_mre_human_co.paa b/addons/field_rations/ui/item_mre_human_co.paa new file mode 100644 index 0000000000..349a133b9a Binary files /dev/null and b/addons/field_rations/ui/item_mre_human_co.paa differ diff --git a/addons/field_rations/ui/item_mre_type1_co.paa b/addons/field_rations/ui/item_mre_type1_co.paa new file mode 100644 index 0000000000..ec397cea4c Binary files /dev/null and b/addons/field_rations/ui/item_mre_type1_co.paa differ diff --git a/addons/field_rations/ui/item_mre_type2_co.paa b/addons/field_rations/ui/item_mre_type2_co.paa new file mode 100644 index 0000000000..3c75c24f2c Binary files /dev/null and b/addons/field_rations/ui/item_mre_type2_co.paa differ diff --git a/addons/field_rations/ui/item_mre_type3_co.paa b/addons/field_rations/ui/item_mre_type3_co.paa new file mode 100644 index 0000000000..5a941e7edf Binary files /dev/null and b/addons/field_rations/ui/item_mre_type3_co.paa differ diff --git a/addons/field_rations/ui/item_mre_type4_co.paa b/addons/field_rations/ui/item_mre_type4_co.paa new file mode 100644 index 0000000000..f90514a1c1 Binary files /dev/null and b/addons/field_rations/ui/item_mre_type4_co.paa differ diff --git a/addons/field_rations/ui/item_mre_type5_co.paa b/addons/field_rations/ui/item_mre_type5_co.paa new file mode 100644 index 0000000000..08fde02f9a Binary files /dev/null and b/addons/field_rations/ui/item_mre_type5_co.paa differ diff --git a/addons/field_rations/ui/item_mre_type6_co.paa b/addons/field_rations/ui/item_mre_type6_co.paa new file mode 100644 index 0000000000..267b8a9b6e Binary files /dev/null and b/addons/field_rations/ui/item_mre_type6_co.paa differ diff --git a/addons/field_rations/ui/item_sunflowerseeds_co.paa b/addons/field_rations/ui/item_sunflowerseeds_co.paa new file mode 100644 index 0000000000..178cea9964 Binary files /dev/null and b/addons/field_rations/ui/item_sunflowerseeds_co.paa differ diff --git a/addons/field_rations/ui/item_waterbottle_empty_co.paa b/addons/field_rations/ui/item_waterbottle_empty_co.paa new file mode 100644 index 0000000000..2ccb6e2607 Binary files /dev/null and b/addons/field_rations/ui/item_waterbottle_empty_co.paa differ diff --git a/addons/field_rations/ui/item_waterbottle_full_co.paa b/addons/field_rations/ui/item_waterbottle_full_co.paa new file mode 100644 index 0000000000..d9f49d2596 Binary files /dev/null and b/addons/field_rations/ui/item_waterbottle_full_co.paa differ diff --git a/addons/fieldmanual/$PBOPREFIX$ b/addons/fieldmanual/$PBOPREFIX$ new file mode 100644 index 0000000000..b080a6d6b7 --- /dev/null +++ b/addons/fieldmanual/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\fieldmanual diff --git a/addons/fieldmanual/CfgEventHandlers.hpp b/addons/fieldmanual/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0afdef638f --- /dev/null +++ b/addons/fieldmanual/CfgEventHandlers.hpp @@ -0,0 +1,5 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; diff --git a/addons/fieldmanual/CfgHintCategories.hpp b/addons/fieldmanual/CfgHintCategories.hpp new file mode 100644 index 0000000000..3a917c9c9c --- /dev/null +++ b/addons/fieldmanual/CfgHintCategories.hpp @@ -0,0 +1,5 @@ +class CfgHintCategories { + class ACE_FieldManual { + displayName = CSTRING(HintCategory_FieldManual_DisplayName); + }; +}; diff --git a/addons/fieldmanual/CfgHints.hpp b/addons/fieldmanual/CfgHints.hpp new file mode 100644 index 0000000000..6f5b0c8efe --- /dev/null +++ b/addons/fieldmanual/CfgHints.hpp @@ -0,0 +1,337 @@ + +/* + Preferred Image Size = 256x256 + Can Embed Images Into Description = 1024x512 + - Shadow = '0' + - Size = '9' +*/ + +// INDENT - %11 +// SELF INTERACT KEYBIND - %12 +// INTERACT KEYBIND - %13 +#define BASE_ARGUMENTS "' '", \ +QUOTE([ARR_2('ACE3 Common',QQEGVAR(interact_menu,selfInteractKey))] call FUNC(getKeybindName)), \ +QUOTE([ARR_2('ACE3 Common',QQEGVAR(interact_menu,interactKey))] call FUNC(getKeybindName)) + +// MEDCIAL MENU KEYBIND - %14 +#define MEDICAL_MENU_KEYBIND QUOTE([ARR_2('ACE3 Common',QQEGVAR(medical_gui,openMedicalMenuKey))] call FUNC(getKeybindName)) + + +class CfgHints { + class ACE_FieldManual_Base { + arguments[] = {BASE_ARGUMENTS}; + image = "\z\ace\addons\common\data\logo_ace3_ca.paa"; + tip = "ACE Wiki"; + }; + class ACE_Items { + displayName = CSTRING(Items_DisplayName); + category = "ACE_FieldManual"; + + class ACE_ATragMX: ACE_FieldManual_Base { + logicalOrder = 1; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_ATragMX' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_ATragMX_ShortName); + description = CSTRING(Items_ATragMX_Description); + tip = "ATragMX Wiki"; + }; + class ACE_BodyBag: ACE_FieldManual_Base { + logicalOrder = 2; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_BodyBag' call FUNC(getItemName)), MEDICAL_MENU_KEYBIND}; + displayName = "%14"; + displayNameShort = CSTRING(Items_BodyBag_ShortName); + description = CSTRING(Items_BodyBag_Description); + }; + class ACE_CableTie: ACE_FieldManual_Base { + logicalOrder = 3; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_CableTie' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_CableTie_ShortName); + description = CSTRING(Items_CableTie_Description); + tip = "Captives Wiki"; + }; + class ACE_Cellphone: ACE_FieldManual_Base { + logicalOrder = 4; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Cellphone' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Cellphone_ShortName); + description = CSTRING(Items_Cellphone_Description); + tip = "Explosives Wiki"; + }; + class ACE_Chemlight_Shield: ACE_FieldManual_Base { + logicalOrder = 5; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Chemlight_Shield' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Chemlight_Shield_ShortName); + description = CSTRING(Items_Chemlight_Shield_Description); + tip = "Chemlights Wiki"; + }; + class ACE_Clackers: ACE_FieldManual_Base { + logicalOrder = 6; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Clacker' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Clackers_ShortName); + description = CSTRING(Items_Clackers_Description); + tip = "Explosives Wiki"; + }; + class ACE_DAGR: ACE_FieldManual_Base { + logicalOrder = 7; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_DAGR' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_DAGR_ShortName); + description = CSTRING(Items_DAGR_Description); + tip = "DAGR Wiki"; + }; + class ACE_DeadManSwitch: ACE_FieldManual_Base { + logicalOrder = 8; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_DeadManSwitch' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_DeadManSwitch_ShortName); + description = CSTRING(Items_DeadManSwitch_Description); + tip = "Explosives Wiki"; + }; + class ACE_DefusalKit: ACE_FieldManual_Base { + logicalOrder = 9; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_DefusalKit' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_DefusalKit_ShortName); + description = CSTRING(Items_DefusalKit_Description); + tip = "Explosives Wiki"; + }; + class ACE_EarPlugs: ACE_FieldManual_Base { + logicalOrder = 10; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_EarPlugs' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_EarPlugs_ShortName); + description = CSTRING(Items_EarPlugs_Description); + tip = "Hearing Wiki"; + }; + class ACE_EntrenchingTool: ACE_FieldManual_Base { + logicalOrder = 11; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_EntrenchingTool' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_EntrenchingTool_ShortName); + description = CSTRING(Items_EntrenchingTool_Description); + }; + class ACE_Flashlights: ACE_FieldManual_Base { + logicalOrder = 12; + displayName = CSTRING(Items_Flashlights_DisplayName); + displayNameShort = CSTRING(Items_Flashlights_ShortName); + description = CSTRING(Items_Flashlights_Description); + tip = "Flashlights Wiki"; + }; + class ACE_FortifyTool: ACE_FieldManual_Base { + logicalOrder = 13; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Fortify' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_FortifyTool_ShortName); + description = CSTRING(Items_FortifyTool_Description); + tip = "Fortify Wiki"; + }; + class ACE_HuntIR_Monitor: ACE_FieldManual_Base { + logicalOrder = 14; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_HuntIR_monitor' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_HuntIR_Monitor_ShortName); + description = CSTRING(Items_HuntIR_Monitor_Description); + tip = "HuntIR Wiki"; + }; + class ACE_IR_Strobe: ACE_FieldManual_Base { + logicalOrder = 15; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_IR_Strobe_Item' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_IR_Strobe_ShortName); + description = CSTRING(Items_IR_Strobe_Description); + }; + class ACE_Kestrel4500: ACE_FieldManual_Base { + logicalOrder = 16; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Kestrel4500' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Kestrel4500_ShortName); + description = CSTRING(Items_Kestrel4500_Description); + tip = "Kestrel 4500 Wiki"; + }; + class ACE_Lockpick: ACE_FieldManual_Base { + logicalOrder = 17; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_key_lockpick' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Lockpick_ShortName); + description = CSTRING(Items_Lockpick_Description); + tip = "Vehicle Lock Wiki"; + }; + class ACE_MapTools: ACE_FieldManual_Base { + logicalOrder = 18; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_MapTools' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_MapTools_ShortName); + description = CSTRING(Items_MapTools_Description); + }; + class ACE_MicroDAGR: ACE_FieldManual_Base { + logicalOrder = 19; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_microDAGR' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_MicroDAGR_ShortName); + description = CSTRING(Items_MicroDAGR_Description); + tip = "MicroDAGR Wiki"; + }; + // Combine all range tables under one roof [mortar, artillery, rifle] + class ACE_RangeTables: ACE_FieldManual_Base { + logicalOrder = 20; + displayName = CSTRING(Items_RangeTables_DisplayName); + displayNameShort = CSTRING(Items_RangeTables_ShortName); + description = CSTRING(Items_RangeTables_Description); + tip = "Rangecard Wiki"; + }; + class ACE_Ropes: ACE_FieldManual_Base { + logicalOrder = 21; + displayName = CSTRING(Items_Ropes_DisplayName); + displayNameShort = CSTRING(Items_Ropes_ShortName); + description = CSTRING(Items_Ropes_Description); + }; + class ACE_Sandbag: ACE_FieldManual_Base { + logicalOrder = 22; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Sandbag_empty' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Sandbag_ShortName); + description = CSTRING(Items_Sandbag_Description); + tip = "Sandbag Wiki"; + }; + class ACE_SpareBarrels: ACE_FieldManual_Base { + logicalOrder = 23; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_SpareBarrel_Item' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_SpareBarrels_ShortName); + description = CSTRING(Items_SpareBarrels_Description); + tip = "Overheating Wiki"; + }; + class ACE_SprayPaint: ACE_FieldManual_Base { + logicalOrder = 24; + displayName = CSTRING(Items_SprayPaint_DisplayName); + displayNameShort = CSTRING(Items_SprayPaint_ShortName); + description = CSTRING(Items_SprayPaint_Description); + tip = "Tagging Wiki"; + }; + class ACE_Tripod: ACE_FieldManual_Base { + logicalOrder = 25; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Tripod' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Tripod_ShortName); + description = CSTRING(Items_Tripod_Description); + tip = "Tripod Wiki"; + }; + class ACE_UAVBattery: ACE_FieldManual_Base { + logicalOrder = 26; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_UAVBattery' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_UAVBattery_ShortName); + description = CSTRING(Items_UAVBattery_Description); + tip = "UAV Battery Wiki"; + }; + class ACE_VehicleKey: ACE_FieldManual_Base { + logicalOrder = 27; + displayName = CSTRING(Items_VehicleKey_DisplayName); + displayNameShort = CSTRING(Items_VehicleKey_ShortName); + description = CSTRING(Items_VehicleKey_Description); + tip = "Vehicle Lock Wiki"; + }; + class ACE_Wirecutter: ACE_FieldManual_Base { + logicalOrder = 28; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_wirecutter' call FUNC(getItemName))}; + displayName = "%14"; + displayNameShort = CSTRING(Items_Wirecutter_ShortName); + description = CSTRING(Items_Wirecutter_Description); + tip = "Wirecutter Wiki"; + }; + }; + // ACE Field Rations + class ACE_Field_Rations { + displayName = CSTRING(Field_Rations_DisplayName); + category = "ACE_FieldManual"; + + class ACE_Field_Rations_Base: ACE_FieldManual_Base { + tip = "Field Rations Wiki"; + }; + + class Hunger: ACE_Field_Rations_Base { + logicalOrder = 1; + displayName = CSTRING(Field_Rations_Hunger_DisplayName); + description = CSTRING(Field_Rations_Hunger_Description); + }; + class Thirst: ACE_Field_Rations_Base { + logicalOrder = 2; + displayName = CSTRING(Field_Rations_Thirst_DisplayName); + description = CSTRING(Field_Rations_Thirst_Description); + }; + }; + // ACE Medical + class ACE_Medical_Treatment { + displayName = CSTRING(Medical_Treatment_DisplayName); + category = "ACE_FieldManual"; + + class ACE_Medical_Treatment_Base: ACE_FieldManual_Base { + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND}; + tip = "Medical Wiki"; + }; + + class ACE_MedicalMenu: ACE_Medical_Treatment_Base { + logicalOrder = 1; + displayName = CSTRING(Medical_Treatment_MedicalMenu_DisplayName); + displayNameShort = CSTRING(Medical_Treatment_MedicalMenu_ShortName); + description = CSTRING(Medical_Treatment_MedicalMenu_Description); + }; + class ACE_Adenosine: ACE_Medical_Treatment_Base { + logicalOrder = 2; + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND, QUOTE('ACE_adenosine' call FUNC(getItemName))}; + displayName = "%15"; + displayNameShort = CSTRING(Medical_Treatment_Adenosine_ShortName); + description = CSTRING(Medical_Treatment_Adenosine_Description); + }; + class ACE_Bandages: ACE_Medical_Treatment_Base { + logicalOrder = 3; + displayName = CSTRING(Medical_Treatment_Bandages_DisplayName); + displayNameShort = CSTRING(Medical_Treatment_Bandages_ShortName); + description = CSTRING(Medical_Treatment_Bandages_Description); + }; + class ACE_Fluids: ACE_Medical_Treatment_Base { + logicalOrder = 4; + displayName = CSTRING(Medical_Treatment_IVFluids_DisplayName); + displayNameShort = CSTRING(Medical_Treatment_IVFluids_ShortName); + description = CSTRING(Medical_Treatment_IVFluids_Description); + }; + class ACE_Epinephrine: ACE_Medical_Treatment_Base { + logicalOrder = 5; + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND, QUOTE('ACE_epinephrine' call FUNC(getItemName))}; + displayName = "%15"; + displayNameShort = CSTRING(Medical_Treatment_Epinephrine_ShortName); + description = CSTRING(Medical_Treatment_Epinephrine_Description); + }; + class ACE_PAK: ACE_Medical_Treatment_Base { + logicalOrder = 6; + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND, QUOTE('ACE_personalAidKit' call FUNC(getItemName))}; + displayName = "%15"; + displayNameShort = CSTRING(Medical_Treatment_PAK_ShortName); + description = CSTRING(Medical_Treatment_PAK_Description); + }; + class ACE_Splint: ACE_Medical_Treatment_Base { + logicalOrder = 7; + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND, QUOTE('ACE_splint' call FUNC(getItemName))}; + displayName = "%15"; + displayNameShort = CSTRING(Medical_Treatment_Splint_ShortName); + description = CSTRING(Medical_Treatment_Splint_Description); + }; + class ACE_SurgicalKit: ACE_Medical_Treatment_Base { + logicalOrder = 8; + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND, QUOTE('ACE_surgicalKit' call FUNC(getItemName))}; + displayName = "%15"; + displayNameShort = CSTRING(Medical_Treatment_SurgicalKit_ShortName); + description = CSTRING(Medical_Treatment_SurgicalKit_Description); + }; + class ACE_Tourniquet: ACE_Medical_Treatment_Base { + logicalOrder = 9; + arguments[] = {BASE_ARGUMENTS, MEDICAL_MENU_KEYBIND, QUOTE('ACE_tourniquet' call FUNC(getItemName))}; + displayName = "%15"; + displayNameShort = CSTRING(Medical_Treatment_CAT_ShortName); + description = CSTRING(Medical_Treatment_CAT_Description); + }; + }; +}; diff --git a/addons/fieldmanual/XEH_PREP.hpp b/addons/fieldmanual/XEH_PREP.hpp new file mode 100644 index 0000000000..425e79b6e9 --- /dev/null +++ b/addons/fieldmanual/XEH_PREP.hpp @@ -0,0 +1,4 @@ +TRACE_1("",QUOTE(ADDON)); + +PREP(getItemName); +PREP(getKeybindName); diff --git a/addons/fieldmanual/XEH_preStart.sqf b/addons/fieldmanual/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/fieldmanual/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/fieldmanual/config.cpp b/addons/fieldmanual/config.cpp new file mode 100644 index 0000000000..19cdbcbf17 --- /dev/null +++ b/addons/fieldmanual/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Hypoxic"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgHintCategories.hpp" +#include "CfgHints.hpp" diff --git a/addons/fieldmanual/functions/fnc_getItemName.sqf b/addons/fieldmanual/functions/fnc_getItemName.sqf new file mode 100644 index 0000000000..ed795ebd2c --- /dev/null +++ b/addons/fieldmanual/functions/fnc_getItemName.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gets item's localized name or indicates if not availabe + * + * Arguments: + * 0: Classname + * + * Return Value: + * + * + * Example: + * "ACE_Banana" call ace_fieldmanual_fnc_getItemName + * + * Public: No + */ +params ["_classname"]; +private _config = configFile >> "CfgWeapons" >> _classname; +if (isClass _config) then { + getText (_config >> "displayName") +} else { + format ["[N/A] - %1", _classname] +}; diff --git a/addons/fieldmanual/functions/fnc_getKeybindName.sqf b/addons/fieldmanual/functions/fnc_getKeybindName.sqf new file mode 100644 index 0000000000..726d411620 --- /dev/null +++ b/addons/fieldmanual/functions/fnc_getKeybindName.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Hypoxic, PabstMirror + * Gets keybind name from CBA + * + * Arguments: + * 0: Addon + * 1: Key Name + * + * Return Value: + * + * + * Example: + * ["ACE3 Common", "ace_interact_menu_selfInteractKey"] call ace_fieldmanual_fnc_getKeybindName + * + * Public: No + */ + +params ["_addon", "_keyName"]; + +private _return = _keyName; +with missionNamespace do { // hint is calling from uiNamespace + private _keyInfo = [_addon, _keyName] call CBA_fnc_getKeybind; + if (!isNil "_keyInfo") then { + private _localizeInfo = _keyInfo select 8 param [0, []]; + if (_localizeInfo isEqualTo []) then { + _return = format ["%1 -> %2", _addon, _keyInfo select 2]; + } else { + _return = format ["%1 -> %2 (%3)", _addon, _keyInfo select 2, _localizeInfo call CBA_fnc_localizeKey]; + }; + }; +}; + +_return diff --git a/addons/fieldmanual/script_component.hpp b/addons/fieldmanual/script_component.hpp new file mode 100644 index 0000000000..35a77d25f9 --- /dev/null +++ b/addons/fieldmanual/script_component.hpp @@ -0,0 +1,19 @@ +#define COMPONENT fieldmanual +#define COMPONENT_BEAUTIFIED Field Manual +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_FIELDMANUAL + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_FIELDMANUAL + #define DEBUG_SETTINGS DEBUG_SETTINGS_FIELDMANUAL +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#include "\a3\ui_f\hpp\defineDIKCodes.inc" diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml new file mode 100644 index 0000000000..78b7ad6fe8 --- /dev/null +++ b/addons/fieldmanual/stringtable.xml @@ -0,0 +1,913 @@ + + + + + Field Rations + 戰地口糧 + 野战军粮 + Poměrové pole + Rations sur le terrain + Feld Rationen + Terepi adagok + Razioni da campo + フィールド レーション + 전투식량 + Racje polowe + Rações de campo + Полевые рационы + Raciones de campo + Gıda Ihtiyaçları + + + Hunger + Głód + 허기 + Fome + Fame + Hunger + 空腹 + Голод + Faim + Hambre + + + %3Hunger%4 increases linearly with soldier's movement speed. Restore by eating food.<br/><br/>%3Usage:%4<br/>%2Pick up food.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. + %3Głód%4 zwiększa się liniowo wraz z prędkością ruchu. Odnawiany przez spożywanie jedzenia.<br/><br/>%3Użycie:%4<br/>%2Podnieś jedzenie.<br/>%2Użyj [%3%12%4] i wybierz %3Surwiwal%4.<br/>%2Wybierz pokarm do zjedzenia + %3허기%4는 병사의 이동속도에 따라 선형적으로 증가합니다. 음식을 섭취하여 회복하십시오.<br/><br/>%3사용 방법:%4<br/>%2음식을 집으십시오.<br/>%2[%3%12%4]를 사용하여 %3생존%4을 선택하십시오.<br/>%2섭취할 아이템을 선택하십시오. + %3A fome%4 aumenta linearmente com a velocidade de movimento do soldado. Restaure comendo comida.<br/><br/>%3Uso:%4<br/>%2Pegue comida.<br/>%2Use [%3%12%4] e selecione %3Sobrevivência%4.<br/>%2Escolha um item para consumir. + %3Hunger%4 steigt linear mit der Bewegungsgeschwindigkeit des Soldaten. Regeneriert sich, indem Nahrung zu sich genommen wird.<br/><br/>%3Verwende:%4<br/>%2Nahrung einsammeln.<br/>%2Verwende [%3%12%4] und wählen %3Überleben%4.<br />%2Wähle einen Gegenstand zum Verzehr aus. + %3Fame%4 aumenta linearmente con la velocità di movimento del soldato. Si rigenera consumando cibo.<br/><br/>%3Usa:%4<br/>%2Raccogli cibo.<br/>%2Usa [%3%12%4] e scegli %3sopravvivenza%4.<br />%2Scegli un articolo da mangiare. + %3空腹度%4は兵士の移動速度に比例して増加します。食べ物を食べることで回復します。<br/><br/>%3使用方法:%4<br/>%2食べ物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2食べたいものを選ぶ。 + %3Голод%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя пищу.<br/><br/>%3 Использование:%4<br/>%2Возьмите еду.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите продукт для потребления. + %3La faim%4 augmente linéairement avec la vitesse de déplacement du soldat. Il se régénère en consommant de la nourriture.<br/><br/>%3Utilisation:%4<br/>%2Ramasser la nourriture.<br/>%2Utilisez [%3%12%4] et sélectionnez %3Survie%4.<br/>%2Choisissez un article à consommer. + El %3Hambre%4 aumenta linealmente con los movimientos del soldado. Se reestablece comiendo comida.<br/><br/>%3Uso:%4<br/>%2Coger comida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. + + + Thirst + Pragnienie + 갈증 + Sede + Sete + Durst + 渇き + Жажда + Soif + Sed + + + %3Thirst%4 increases linearly with soldier's movement speed. Restore by drinking liquids.<br/><br/>%3Usage:%4<br/>%2Pick up a drink.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. + %3Pragnienie%4 zwiększa się liniowo wraz z prędkością ruchu. Odnawiane przez spożywanie napojów.<br/><br/>%3Użycie:%4<br/>%2Podnieś napój.<br/>%2Użyj [%3%12%4] i wybierz %3Surwiwal%4.<br/>%2Wybierz napój do wypicia. + %3갈증%4은 병사의 이동속도에 따라 선형적으로 증가합니다. 음료를 섭취하여 회복하십시오.<br/><br/>%3사용 방법:%4<br/>%2음료를 집으십시오.<br/>%2[%3%12%4]를 사용하여 %3생존%4을 선택하십시오.<br/>%2섭취할 아이템을 선택하십시오. + %3A sede%4 aumenta linearmente com a velocidade de movimento do soldado. Restaure bebendo líquidos.<br/><br/>%3Uso:%4<br/>%2Pegue uma bebida.<br/>%2Use [%3%12%4] e selecione %3Sobrevivência%4.<br/>%2Escolha um item para consumir. + %3Durst%4 steigt linear mit der Bewegungsgeschwindigkeit des Soldaten. Regeneriert sich durch das Trinken von Flüssigkeiten.<br/><br/>%3Verwende:%4<br/>%2Holen ein Getränk.<br/>%2Verwende [%3%12%4] und wähle %3Überleben%4.< br/>%2Wähle einen Gegenstand zum Verzehr aus. + %3Sete%4 aumenta linearmente con la velocità di movimento del soldato. Si rigenera bevendo liquidi.<br/><br/>%3Usa:%4<br/>%2Raccogli bevanda.<br/>%2Usa [%3%12%4] e scegli %3sopravvivenza%4.<br />%2Scegli un articolo da bere. + %3喉の渇き%4は兵士の移動速度に比例して増加します。飲み物を飲むことで回復します。<br/><br/>%3使用方法:%4<br/>%2飲み物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2飲みたいものを選ぶ。 + %3Жажда%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя напитки.<br/><br/>%3 Использование:%4<br/>%2Возьмите напиток.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите напиток для потребления. + %3La soif%4 augmente linéairement avec la vitesse de déplacement du soldat. Elle se régénère en buvant des liquides.<br/><br/>%3Utilisez [%3%12%4] et choisissez %3survival%4.<br />%2Choisissez un article à boire. + La %3Sed%4 aumenta linealmente con la velocidad de movimiento del soldado. Se restaura bebiendo líquidos.<br/><br/>%3Uso:%4<br/>%2Selecciona una bebida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. + + + Medical Treatment + Opieka Medyczna + 의료 치료법 + Tratamento médico + Medizinische Behandlung + Cure Mediche + 治療 + Медицинское лечение + Traitement médical + Tratamiento Médico + + + Decrease Heart Rate + Obniża Tętno + 심박수를 낮춥니다 + Diminuir a frequência cardíaca + Verringere Herzfrequenz + Rallenta ritmo cardiaco + 心拍数を下げる + Уменьшить частоту сердечных сокращений + Diminution de la fréquence cardiaque + Disminuir Ritmo Cardíaco + + + %3Adenosine%4 is used to decrease heart rate.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Adenosine%4. + %3Adenozyna%4 jest używana do obniżenia tętna.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Wstrzyknij %3Adenozynę%4. + %3아데노신%4은 심박수를 줄이기 위해 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하고 부위를 선택하십시오.<br/>%2%3아데노신%4을 주사하십시오. + %3Adenosina%4 é usada para diminuir a frequência cardíaca.<br/><br/>%3Uso:%4<br/>%2Use [%3%13%4] ou [%3%14%4] e selecione um apêndice.<br/>%2Injete %3Adenosina%4. + %3Adenosin%4 wird verwendet, um die Herzfrequenz zu senken.<br/><br/>%3Verwende:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Injiziere %3Adenosin%4. + %3Adenosina%4 è usata per rallentare il ritmo cardiaco.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Inject %3Adenosina%4. + %3アデノシン%4は心拍数を下げるのに使われます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2そして%3アデノシン%4を注射します。 + %3Аденозин%4 используется для снижения частоты сердечных сокращений.<br/><br/>%3Применение:%4<br/>%2Используйте [%3%13%4] или [%3%14%4] и выберите конечность.<br/>%2Введите %3Аденозин%4. + L'%3adénosine%4 est utilisée pour réduire la fréquence cardiaque.<br/><br/>%3Utilisation:%4<br/>%2Utilisez [%3%13%4] ou [%3%14%4] et sélectionnez un membre.<br/>%2Injectez l'%3Adénosine%4. + La %3Adenosina%4 se usa para disminuir el ritmo cardíaco.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyectar %3Adenosina%4. + + + Bandages + Bandaże + 붕대 + Bandagens + Bandagen + Bende + 包帯 + Бинты + Pansements + Vendas + + + Close Wounds + Zamykają Rany + 상처를 막습니다 + Fechar Feridas + Wunden schließen + Chiudi ferite + 傷口をふさぐ + Закрыть раны + Fermer les plaies + Cerrar Heridas + + + %3Bandages%4 stop bleeding and close wounds. Depending on your settings, bandages may reopen if surgery is not performed.<br/><br/>%2%3Field Dressing:%4<br/>%11<t color='#D9D900'>Average</t> In All Categories<br/>%2%3Packing Bandage:%4<br/>%11<t color='#D9D900'>Average</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopen Delay<br/>%2%3Elastic Bandage:%4<br/>%11<t color='#00CC00'>Higher</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#E60000'>Shorter</t> Reopen Delay<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Lower</t> Treatment<br/>%11<t color='#00CC00'>Lower</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopening Delay<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select a injured body part.<br/>%2Bandage body part by selecting desired %3Bandage%4 type. + %3Bandaże%4 zatrzymają krwawienie i zamykają rany. W zależności od twoich ustawień, bandaże mogą się otwierać, jeżeli rany nie są zaszyte. <br/><br/>%2%3Bandaż Jałowy:%4<br/>%11<t color='#D9D900'>Przeciętne</t> We wszystkich kategoriach<br/>%2%3Bandaż Uciskowy: %4<br/>%11<t color='#D9D900'>Przeciętne</t> Leczenie<br/>%11<t color='#E60000'>Wyższa</t> Szansa Otwarcia<br/>%11<t color='#00CC00'>Dłuższe</t> Opóźnienie Otwarcia<br/>%2%3Bandaż Elastyczny: %4<br/>%11<t color='#00CC00'>Lepsze</t> Leczenie<br/>%11<t color='#E60000'>Wyższa</t> Szansa Otwarcia<br/>%11<t color='#E60000'>Krótsze</t> Opóźnienie Otwarcia<br/>%2%3Quickclot: %4<br/>%11<t color='#E60000'>Gorsze</t> Leczenie<br/>%11<t color='#00CC00'>Niższa</t> Szansa Otwarcia<br/>%11<t color='#00CC00'>Dłuższe</t> Opóźnienie Otwarcia<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz zranioną część ciała. <br/>%2Zabandażuj ranę wybierając typ %3Bandażu%4. + %3붕대%4는 출혈을 멈추고 상처를 치료합니다.설정에 따라 수술을 하지 않을 경우 붕대가 다시 풀릴 수 있습니다.<br/><br/>%2%3붕대(기본):%4<br/>모든 카테고리에 대해 %11<t color='#D9D900'>평균</t>적임<br/>%2%3붕대(거즈):<br/>%11<t color='#D9D900'>평균</t>적인 치료 효과<br/>%11<t color='#E60000'>높은</t> 풀림 확률<br/>%11<t color='#00CC00'>긴</t> 풀림 딜레이<br/>%2%3붕대(압박):%4<br/>%11<t color='#00CC00'>높은</t> 치료 효과<br/>%11<t color='#E60000'>높은</t> 풀림 확률<br/>%11<t color='#E60000'>짧은</t> 풀림 딜레이<br/>%2%3붕대(퀵 클롯):%4<br/>%11<t color='#E60000'>낮은</t> 치료 효과<br/>%11<t color='#00CC00'>낮은</t> 풀림 확률<br/>%11<t color='#00CC00'>긴</t> 풀림 딜레이<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하고 부상당한 신체부위를 선택하십시오.<br/>%2원하는 종류의 %3붕대%4를 선택하여 신체부위에 붕대를 감으십시오. + %3Bandagens%4 interrompem o sangramento e fecham feridas. A depender das suas configurações, as bandagens podem reabrir se não for feita a cirurgia.<br/><br/>%2%3Curativo de Campo:%4<br/>%11<t color='#D9D900'>Mediano</t> em todas as categorias<br/>%2%3Bandagem de Compressão:%4<br/>%11<t color='#D9D900'>Mediana</t> em tratamento<br/>%11<t color='#E60000'>Maior</t> chance de reabertura<br/>%11<t color='#00CC00'>Mais longo</t> atraso na reabertura<br/>%2%3Bandagem Elástica:%4<br/>%11<t color='#00CC00'>Melhor</t> em tratamento<br/>%11<t color='#E60000'>Maior</t> chance de reabertura<br/>%11<t color='#E60000'>Mais curto</t> atraso na reabertura<br/>%2%3QuikClot:%4<br/>%11<t color='#E60000'>Pior</t> em tratamento<br/>%11<t color='#00CC00'>Menor</t> chance de reabertura<br/>%11<t color='#00CC00'>Mais longo</t> atraso na reabertura<br/><br/>%Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione uma parte do corpo ferida.<br/>%2Suture a parte do corpo selecionando o tipo desejado de %3Bandagem%4. + %3Verbände%4 stoppen Blutungen und schließen Wunden. Abhängig von Ihren Einstellungen können sich Verbände wieder öffnen, wenn keine Operation durchgeführt wird.<br/><br/>%2%3Einfache Bandage:%4<br/>%11<t color='#D9D900'>Durchschnittlich</t> In allen Kategorien<br/>%2%3Mullbinde:%4<br/>%11<t color='#D9D900'>Durchschnittliche</t> Behandlung<br/>%11<t color='#E60000' >Höhere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/>%2%3Elastischer Verband:%4<br/>%11<t color='#00CC00'>Längere</t> Behandlung<br/>%11<t color='#E60000'>Höhere</t> Chance auf Wiedereröffnung<br/>%11<t color='#E60000'> Kürzere</t> Wiedereröffnungsverzögerung<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Kürzere</t> Behandlung<br/>%11<t color=' #00CC00'>Geringere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/><br/>%3Verwende:%4<br/> %2Verwenden Sie [%3%13%4] oder [%3%14%4] und wähle ein verletztes Körperteil aus.<br/>%2Verbinde ein Körperteil, indem der gewünschte %3Bandagen%4-Typ ausgewählt wurde. + %3Bende%4 fermano emorragie e chiudono ferite. A seconda delle tue impostazioni, ferite bendate potrebbero riaprirsi se non suturate.<br/><br/>%2%3Bendaggio Basico:%4<br/>%11<t color='#D9D900'>Media</t> In tutte le categorie<br/>%2%3Bendaggio Compressivo:%4<br/>%11<t color='#D9D900'>Media</t> Trattamenti<br/>%11<t color='#E60000'>Alta</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/>%2%3Bendaggio Elastico:%4<br/>%11<t color='#00CC00'>Alto</t> Trattamento<br/>%11<t color='#E60000'>Alto</t> Probabilità di riapertura<br/>%11<t color='#E60000'>Breve</t> Tempo di riapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Basso</t> Trattamento<br/>%11<t color='#00CC00'>Basso</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] seleziona una parte del corpo ferita.<br/>%2Benda la parte del corpo ferita selezionando la %3Benda%4 desiderato. + %3包帯%4は傷口をとじて出血を止めます。設定によっては、手術を行わないと包帯が解けて傷が再開放し出血が再開する場合があります。<br/><br/>%2%3緊急圧迫包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 全体性能を持っています<br/>%2%3弾性包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/>%2%3伸縮包帯:%4<br/>%11<t color='#00CC00'>高い</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#E60000'>短い</t> 再解放の再計算間隔<br/>%2%クイッククロット:%4<br/>%11<t color='#E60000'>低い</t> 治療効果<br/>%11<t color='#00CC00'>低い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って身体の負傷個所を選択します。<br/>%2希望の%3包帯%4の種類を選択して部位に包帯を巻きます。 + Las %3Vendas%4 paran el sangrado y cierran las heridas. Dependiendo de las opciones configuradas, las heridas pueden reabrirse si no se realiza cirugía.<br/><br/>%2%3Vendaje de campaña:%4<br/>%11<t color='#D9D900'>Medio</t> en todas las categorias<br/>%2%3Vendaje compresivo:%4<br/>%11<t color='#D9D900'>Medio</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/>%2%3Vendaje elástico:%4<br/>%11<t color='#00CC00'>Alto</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de reapertura<br/>%11<t color='#E60000'>Corto</t> Retardo en reapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Bajo</t> Tratamiento<br/>%11<t color='#00CC00'>Bajo</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una parte del cuerpo herida.<br/>%2Venda la parte del cuerpo seleccionada eligiendo el tipo de %3Venda%4. + + + IV Fluids + Płyny IV + IV 수액 + Fluidos IV + IV-Flüssigkeiten + Fluidi EV + IV 輸液 + IV Fluides + Fluidos IV + + + Restore Blood Volume + Przywracają Krew + 혈액량을 회복합니다 + Restaurar o volume de sangue + Blutvolumen wiederherstellen + Ristorano Volume di Sangue + 血液量を回復する + Внутривенные жидкости + Restaurer le volume sanguin + Reestablece el volumen de sangre + + + %3IV fluids%4 restore lost blood volume. Blood, Plasma, and Saline are functionally the same.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Restore blood volume by selecting desired %3IV Fluid%4 type. + %3Płyny IV%4 przywracają poziom krwi. Krew, Osocze, i Sól Fizjologiczna są takie same pod względem funkcjonalności.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Przywróć poziom krwi przez podanie wybrego %3Płynu IV%4. + %3수액용기%4는 손실된 혈액량을 보충합니다. 혈액, 혈장 및 생리식염수는 기능적으로 동일합니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하고 부위를 선택하십시오.<br/>%2원하는 %3수액용기%4 종류를 선택하여 혈액량을 보충하십시오. + %3Fluidos IV%4 restauram o volume de sangue perdido. Sangue, Plasma e Soro fisiológico são funcionalmente equivalentes.<br/><br/>%3Uso:%4<br/>%Utilize [%3%13%4] ou [%3%14%4] e selecione um apêndice.<br/>%2Restaure o volume de sangue selecionando o tipo desejado de %3Fluido IV%4. + %3IV-Flüssigkeiten%4 stellen das verlorene Blutvolumen wieder her. Blut, Plasma und Kochsalzlösung sind funktionell gleich.<br/><br/>%3Verwende:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus..<br/>%2Stelle das Blutvolumen wieder her, indem der gewünschte %3IV Flüssigkeitstyp%4 ausgewählt wird. + %3Fluidi EV%4 ristorano volume di sangue perso. Sangue, Plasma, e Salina sono funzionalmente identiche.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Ristora il volume di sangue selezionando il tipo di %3Fluido EV%4 desiderato. + %3IV 輸液%4は失われた血液を回復します。血液、血漿、生理食塩水は機能的には同じです。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2希望の%3IV 輸液%4の種類を選択して、血液量を復元します。 + %%3Внутривенные жидкости%4восстанавливают потерянный объем крови. Кровь, плазма и физраствор функционально идентичны.<br/><br/>%3 Использование:%4<br/>%2 Используйте [%3%13%4] или [%3%14%4] и выберите добавку.<br/>%2 Восстановите объем крови выбрав желаемый %4тип %3жидкости + Los %3Fluidos IV%4 restauran el volumen de sangre. Sangre, Plasma, y Salino funcionan de manera similar.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar una extremidad.<br/>%2Restaura el volumen de sangre seleccionando el tipo de %3Fluido IV%4 elegido. + + + Increase Heart Rate | Wake Up Faster + Zwiększ Tętno | Obudź się Szybciej + 심박수 상승 | 더 빨리 일어남 + Aumentar a frequência cardíaca | Acordar mais rápido + Herzfrequenz erhöhen | Wache schneller auf + Aumenta ritmo cardiaco | Accelera rinvenimento + 心拍数を上げる | はやく起こす + Увеличьте частоту сердечных сокращений | просыпайтесь быстрее + Augmentation de la fréquence cardiaque - Réveil plus rapide + Incrementa el ritmo cardíaco | Despierta más rápido + + + %3Epinephrine%4 increases a patient's pulse as well as potentially decreasing the time between consciousnesss checks (effectively reducing the time needed for the patient to wake up).<br/><br/>%3Usage%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Epinephrine%4. + %3Adrenalina%4 zwiększa tętno pacjenta, zmniejszając czas pomiędzy sprawdzeniami przytomności (efektywnie redukując czas potrzebny do przebudzenia się pacjenta).<br/><br/>%3Użycie%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Wstrzyknij %3Adrenalinę%4. + %3에피네프린%4는 환자의 맥박을 증가시킬 뿐만 아니라 의식 검사 사이의 시간을 감소시킬 수 있습니다(환자가 깨어나는 데 필요한 시간을 효과적으로 단축).<br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 선택하고 부위를 선택하십시오.<br/>%2%3에피네프린%4을 주사하십시오. + %Epinefrina%4 aumenta o pulso do paciente, bem como potencialmente diminui o tempo entre os exames de consciência (reduzindo efetivamente o tempo necessário para que o paciente acorde).<br/><br/>%3Uso%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um apêndice.<br/>%2Injete %3Epinefrina%4. + %3Epinephrine%4 erhöht den Puls eines Patienten und verkürzt möglicherweise die Zeit zwischen Bewusstseinskontrollen (wodurch die Zeit, die der Patient zum Aufwachen benötigt, effektiv verkürzt wird).<br/><br/>%3Verwendung%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Injiziere %3Epinephrine%4. + %3Epinefrina%4 aumenta il ritmo cardiaco di un paziente e riduce potenzialmente gli intervalli tra verifiche di coscienza (effettivamente riducendo il tempo necessario che questo paziente si svegli).<br/><br/>%3Utilizzo%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Inietta %3Epinefrina%4. + %3アドレナリン%4は、患者の脈拍を増加させるだけでなく、意識チェックの間隔を短縮する可能性があります。 (患者が目覚めるまでに必要な時間を効果的に短縮します)<br/><br/>%3使用方法%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2%3アドレナリン%4を注射します。 + La %3Epinefrina%4 aumenta el pulso del paciente así como potencialmente disminuye el tiempo entre las comprobaciones sobre consciencia (reduciendo de manera efectiva el tiempo de despertar del paciente).<br/><br/>%3Uso%4<br/>%2Usa [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyecta %3Epinefrina%4. + + + Restore Like New + Jak Nowo Narodzony + 신체 완치 + Restaurar como novo + Wie neu wiederherstellen + Cura completa + 生まれたてのように回復する + Лечение тела + Remettre comme neuf + Restaurar como nuevo + + + The %3Personal Aid Kit%4 is an item that allows a soldier to be fully healed. Independent of %3ACE Settings%4, it requires that the patient is in %3Stable Condition%4 before use.<br/><br/>%3Stable Condition%4 qualifies as:<br/>%2Unit is %3Alive%4.<br/>%2Unit is %3Conscious%4.<br/>%2Unit has no active %3Bleeding%4.<br/>%2Heart Rate >= 40.<br/>%2Systolic BP >= 60.<br/>%2Diastolic BP >= 50.<br/><br/>%3Usage:%4<br/>%2Move to appropriate location depending on %3ACE Settings%4.<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatments%4<br/>%2Select %3Use Personal Aid Kit%4. + %3Apteczka Osobista%4 jest przedmiotem pozwalającym na pełne uleczenie gracza. Niezależnie od %3Ustawień ACE%4, wymagane jest, aby pacjent był w%3Stanie Stabilnym%4 przed jej użyciem.<br/><br/>%3Stan Stabilny%4 występuje gdy:<br/>%2Jednostka jest %3Żywa%4.<br/>%2Jednostka jest %3Przytomna%4.<br/>%2Jednostka nie%3Krwawu%4.<br/>%2Tętno>= 40. <br/>%2Ciśnienie Skurczowe >= 60.<br/>%2Ciśnienie Rozkurczowe >= 50.<br/><br/>%3Użycie:%4<br/>%2Udaj się do właściwej lokacji żależnej od %3Ustawień ACE%4.<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz %3Zaawansowane Zabiegi%4.<br/>%2Wybierz %3Użyj Apteczki Osobistej%4. + %3개인응급키트%4는 병사를 완치시킬 수 있는 아이템입니다. %3ACE 설정%4과 무관하게 사용 전에 환자가 %3안정된 상태%4로 있어야 합니다.<br/><br/>%3안정된 상태%4는 다음 조건이 필요합니다:<br/>%2유닛이 %3살아있어야%4 합니다.<br/>%2유닛은 %3의식이 있어야%4 합니다.<br/>%2유닛은 %3출혈이 일어나지 않은 상태%4여야 합니다.<br/>%2심박수가 40 이상이어야 합니다.<br/>%2수축 혈압이 60 이상이어야 합니다.<br/>%2이완 혈압이 50 이상이어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3ACE 설정%4에 따라 적절한 위치로 이동하십시오.<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 %3고급 치료%4를 선택하십시오.<br/>%2%3개인응급키트 사용%4을 선택하십시오. + O %3Kit De Primeiros Socorros Pessoal%4 é um item que permite a cura completa de um combatente. Independente das %3Configurações do ACE%4, é necessário que o paciente esteja em %3Condições Estáveis%4 antes do uso.<br/><br/>%3Condições estáveis%4 qualificam-se como:<br/>%2Unidade está %3Viva%4.<br/>%2Unidade está %3Consciente%4.<br/>%2Unidade não está %3Sangrando%4.<br/>%2Frequência Cardíaca >= 40.<br/>%2PA Sistólica >= 60.<br/>%2PA Diastólica >= 50.<br/><br/>%3Uso:%4<br/>%2Mover-se a uma localização apropriada, a depender das %3Configurações do ACE%4.<br/>%2Utilizar [%3%13%4] ou [%3%14%4] e selecionar %3Tratamentos Avançados%4<br/>%2Selecionar %3Usar o kit de primeiros socorros%4. + Das %3Persönliche Erste Hilfe Kit%4 ist ein Gegenstand, der es einem Soldaten ermöglicht, vollständig geheilt zu werden. Unabhängig von den %3ACE-Einstellungen%4 ist es erforderlich, dass sich der Patient vor der Verwendung in einem %3stabilen Zustand%4 befindet.<br/><br/>%3Stabiler Zustand%4 gilt wenn:<br/>%2Einheit ist %3am Leben%4 .<br/>%2Einheit ist %3Bei Bewusstsein%4.<br/>%2Einheit hat keine aktive %3Blutung%4.<br/>%2Herzfrequenz >= 40.<br/>%2Systolischer Blutdruck >= 60.< br/>%2Diastolischer Blutdruck >= 50.<br/><br/>%3Verwende:%4<br/>%2Bewege den Patienten je nach %3ACE-Einstellungen%4 an den entsprechenden Ort.<br/>%2Verwende [%3% 13%4] oder [%3%14%4] und wähle %3Erweiterte Behandlungen%4<br/>%2Wähle %3Persönliche Erste Hilfe Kit verwenden%4. + Il %3Kit di Pronto Soccorso%4 è un oggetto che permette di curare completamente un soldato, indipendentemente da %3impostazioni ACE%4, richiede che il paziente sia in %3condizione stabile%4 prima dell'utilizzo.<br/><br/>%3Condizione stabile%4 significa:<br/>%2Paziente è %3Vivo%4.<br/>%2Paziente è %3Conscio%4.<br/>%2Paziente non sta %3Sanguinando%4.<br/>%2Ritmo cardiaco >= 40.<br/>%2Sistolico BC >= 60.<br/>%2Diastolico BC >= 50.<br/><br/>%3Utilizzo:%4<br/>%2Sposta in luogo specifico a seconda delle %3impostazioni ACE%4.<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti avanzati%4<br/>%2Seleziona %3Usa Kit di Pronto Soccorso%4. + %3個人用治療キット%4は、兵士を完全に回復できるアイテムです。使用時には%3ACE 設定%4と関係なく、対象の患者が%3安定状態%4である必要があります。<br/><br/>%3安定状態%4とは次の状態です:<br/>%2ユニットが %3生存%4している。<br/>%2ユニットが %3覚醒状態%4である。<br/>%2ユニットが %3出血状態%4ではない。<br/>%2心拍数が40以上。<br/>%2収縮期血圧が60以上。<br/>%2拡張期血圧が50以上。<br/><br/>%3使用方法:%4<br/>%2%3ACE 設定%4で使用が許可された場所へ移動する。<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3個人用治療キットを使う%4を選択して使用します。 + El %3Kit de Primeros Auxilios%4 es un objeto que permite al soldado ser curado totalmente. Independientemente de las %3Opciones de ACE%4, requiere que el paciente esté en %3Condición Estable%4 antes de usarse.<br/><br/>%3Condición Estable%4 significa que:<br/>%2La unidad está %3Viva%4.<br/>%2La unidad está %3Consciente%4.<br/>%2La unidad no está %3Sangrando%4.<br/>%2Ritmo Cardíaco >= 40.<br/>%2Presión Sistólica >= 60.<br/>%2Presión Diastólica >= 50.<br/><br/>%3Uso:%4<br/>%2Mover al lugar adecuado dependiendo de las%3Opciones de ACE%4.<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4<br/>%2Seleccionar %3Usar Kit de Primeros Auxilios%4. + + + Fix Fractures + Opatrywanie Złamań + 골절을 치료합니다 + Consertar Fraturas + Brüche richten + Risolvi frattura + 骨折を治す + Исправлять переломы + Réparation des fractures + Curar Fracturas + + + A %3Splint%4 is used to fix fractures. The %3Splint%4 is consumed when used.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Splint%4. + %3Szyna%4 jest używana do leczenie złamań. %3Szyna%4 jest zużywana po wykorzystaniu.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę, na którą ma być założona.<br/>%2Wybierz %3Załóż Szynę%4. + %3부목%4은 골절을 치료하는 데 사용되며 %3부목%4은 사용 시 소모됩니다.<br/><br/>%3사용 방법%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 해당 부위를 선택하십시오.<br/>%2%3부목 대기%4를 선택하십시오. + A %3Tala%4 é utilizada para consertar fraturas. Ela é consumida quando utilizada.<br/><br/>%Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um membro afetado.<br/>%2Selecione %3Aplicar Tala%4. + Ein %3Splint%4 wird zur Fixierung von Frakturen verwendet. Der %3Splint%4 wird bei Verwendung verbraucht.<br/><br/>%3Verwendung:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Wähle %3Schiene verwenden%4. + Una %3Gessatura%4 è usata per risolvere fratture. La %3Gessatura%4 è consumata quando usata.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Gessatura%4. + %3添え木%4は骨折の治療に使います。%3添え木%4は使用時に消費します。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3添え木を当てる%4を選択して使用します。 + La %3Férula%4 se utiliza para curar fracturas. La %3Férula%4 se consume cuando es usada.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad adecuada.<br/>%2Seleccionar %3Aaplicar Férula%4. + + + Prevent Wounds From Reopening + Zapobiegaj Ponownemu Otwieraniu się Ran + 상처가 재발하지 않도록 방지합니다 + Prevenir Reabertura de Feridas + Impedisce la riapertura di ferite + 傷口が開くのを防ぐ + Предотвратить повторное открытие ран + Empêcher la réouverture des plaies + Verhindert, dass sich Wunden wieder öffnen + Prevenir la reapertura de heridas + + + A %3Surgical Kit%4 is used to prevent wounds from reopening after being bandaged. Depending on settings, it can also clear trauma and may require additional %3Sutures%4 to close wounds. Sutures are consumable, much like bandages, and are not a replacement for the Surgical Kit.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatment%4.<br/>%2Select %3Use Surgical Kit%4. + %3Zestaw do Szycia%4 jest używany do zapobiegania otwieraniu się ran po ich zabandażowaniu. W zależności od ustawień może także je leczyć.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz %3Zaawansowane Zabiegi%4.<br/>%2Wybierz %3Użyj Zestawu do Szycia%4. + %3봉합 키트%4는 붕대를 감은 후 상처가 다시 열리는 것을 방지하기 위해 사용됩니다. 설정에 따라 외상을 치료할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 %3고급 치료%4를 선택하십시오.<br/>%2%3봉합 키트%4를 선택하십시오. + O %3Kit Cirúrgico%4 é utilizado para prevenir a reabertura de feridas após a aplicação de bandagens. A depender das configurações, ele também pode remover traumas e pode requerir %3Suturas%4 adicionais para fechar feridas. Suturas são consumíveis, tal como as bandagens, e não são substituem o Kit Cirúrgico.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione %3Tratamento Avançado%4.<br/>%2Selecione %3Usar Kit Cirúrgico%4. + Un %3Kit Chirurgico%4 è usato per impedire che ferite bendate si riaprano. A seconda delle impostazioni, può anche azzerare danni o potrebbe richiedere %3Suture%4 aggiuntive per chiudere ferite. Suture sono consumabili proprio come bende, non sono un sostituto per un Kit Chirurgico.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti Avanzati%4.<br/>%2Seleziona %3Usa Kit Chirurgico%4. + %3手術キット%4は包帯を巻いた傷口が再度開いて出血するのを防ぎます。設定によっては、負傷を取り除いたり、傷口を閉じるのに%3糸付縫合針%4を必要としたりします。糸付縫合針は消耗品で包帯のように使用され、手術キットを代替するものではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3手術キット%4を選択して使用します。 + Ein %3Chirurgisches Kit%4 wird verwendet, um zu verhindern, dass sich Wunden nach dem Verbinden wieder öffnen. Abhängig von den Einstellungen kann es auch Traumata beseitigen und erfordert möglicherweise zusätzliche %3Nähte%4, um Wunden zu schließen. Nahtmaterial ist, ähnlich wie Bandagen, Verbrauchsmaterial und kein Ersatz für das Chirurgie-Set.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3% 14%4] und wählen Sie %3Erweiterte Behandlung%4.<br/>%2Wählen Sie %3Chirurgisches Kit verwenden%4. + El %3Kit Quirúrgico%4 se usa para prevenir la reapertura de heridas despues de ser vendadas. Dependiendo de las opciones, tambien puede curar traumatismos y puede requerir %3Sutura%4 adicional para cerrar las heridas. Las Suturas son consumibles, al igual que las vendas, y no son un reemplazo para el Kit Quirúgico.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4.<br/>%2Seleccionar %3Usar Kit Quirúgico%4. + + + Stop Bleeding + Zatamuj Krwawienie + 피를 멈추게 합니다 + Parar o Sangramento + Ferma emorragia + 出血を止める + Остановить кровотечение + Arrêter les saignements + Stoppt Blutung + Parar Sangrado + + + A %3Tourniquet%4 stops bleeding temporarily so that a wound(s) can be bandaged. Can only be used on limbs.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Tourniquet%4. + %3Staza%4 czasowo zatrzymuje krwawienie pozwalając na zabandażowanie ran. Może być użyta tylko na kończynach.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Wybierz %3Załóż Stazę%4. + %3지혈대%4는 출혈을 일시적으로 멈춰 상처(들)에 붕대를 감을 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 해당 부위를 선택하십시오.<br/>%2%3지혈대 적용%4를 선택하십시오. + O %3Torniquete%4 interrompe o sangramento temporariamente, para que feridas possam ser enfaixadas. Seu uso é restrito aos membros.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um membro afetado.<br/>%2Selecione %3Aplicar Torniquete%4. + Un %3Laccio Emostatico%4 ferma emorragie temporaneamente in modo da poter bendare ferite con calma. Utilizzabile su arti.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Laccio Emostatico%4. + %3止血帯%4は一時的に出血を止め、その間に傷に包帯を巻くことができます。四肢にのみ使用できます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3止血帯を巻く%4を選択して使用します。 + Ein %3Tourniquet%4 stoppt die Blutung vorübergehend, sodass eine oder mehrere Wunden verbunden werden können. Kann nur an Gliedmaßen verwendet werden.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3%14%4] und wählen Sie ein betroffenes Glied aus.< br/>%2Wählen Sie %3Tourniquet anwenden%4. + El %3Torniquete%4 para temporalmente el sangrado hasta que la herida sea vendada. Sólo puede ser usado en extremidades.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad afectada.<br/>%2Seleccionar %3Aplicar Torniquete%4. + + + Medical Menu + Sanitätsmenü + Menu medyczne + Menu Médico + Медицинское меню + Menú médico + Zdravotnická nabídka + Menù Medico + Menu médical + 医療メニュー + 의료 메뉴 + 医疗菜单 + 醫療選單 + Medikal Menü + + + Treatment, Simplified + Leczenie, Uproszczone + 치료를 단순화 + Cure, Semplificato + Tratamento, Simplificado + 治療を簡略化する + Traitement, simplifié + Tratamiento, Simplificado + + + The %3Medical Menu%4 is a dedicated %3interface%4 to facilitate %3medical treatment%4. The %3R%4 and %3L%4 letters indicate the side of the patient's body being treated.<br/><br/>%3Usage:%4<br/>%2Use [%3%14%4] while looking at a patient to open the Medical Menu. Opening the menu without a patient allows for self-treatment.<br/>%2Alternatively, use [%3%12%4] or [%3%13%4] and select %3Medical Menu%4.<br/><br/>%3Keybinds:%4<br/>%2Use [%3W, A, S, D, X, and Z%4] to select body parts.<br/>%2Use your %3number keys%4 to select treatment categories. + %3Menu Medyczne%4 jest dedykowanym %3interfejsem%4 ułatwiającym %3zabiegi medyczne%4. Litery %3P%4 i %3L%4 wskazują, która część ciała pacjenta jest opatrywana.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%14%4] podczas patrzenia na pacjenta aby otworzyć Menu Medyczne. Otwarcie menu bez patrzenia na pacjenta otwiera menu leczenia własnej postaci.<br/>%2Alternatywnie, użyj [%3%12%4] lub [%3%13%4] i wybierz %3Menu Medyczne%4.<br/><br/>%3Przypisanie Klawiszy:%4<br/>%2Użyj [%3W, A, S, D, X, i Z%4] aby wybrać części ciała.<br/>%2Użyj %3klawiszy numerycznych%4 do wybrania kategorii leczenia. + %3의료 메뉴%4는 %3의료%4를 용이하게 사용하기 위한 전용 %3인터페이스%4입니다. %3우%4 및 %3좌%4 문자는 치료 중인 환자의 신체 측면을 나타냅니다.<br/><br/>%3사용 방법:%4<br/>%2환자를 보고 [%3%13%4]를 사용하여 의료 메뉴를 여십시오. 환자 없이 메뉴를 열면 자가 치료가 됩니다.<br/>%2아니면 [%3%12%4] 또는 [%3%13%4]를 사용하고 %3의료 메뉴%4를 선택하십시오.<br/><br/>%3키 설정%4<br/>%2[%3W, A, S, D, X와 Z%4]를 사용하여 신체 부위를 선택하십시오.<br/>%2%3번호판 키%4를 사용하여 치료 카테고리를 선택하십시오. + O %3Menu Médico%4 é uma %3interface%4 dedicada a facilitar o %3tratamento médico%4. As letras %3R%4 e %3L%4 indicam o lado do corpo do paciente que está recebendo o tratamento.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%14%4] enquanto olha o paciente para abrir o Menu Médico. Se não houver paciente, o menu será de auto-tratamento.<br/>%2Alternativamente, utilize [%3%12%4] ou [%3%13%4] e selecione %3Menu Médico%4.<br/><br/>%3Atalhos de teclado:%4<br/>%2Utilize [%3W, A, S, D, X, e Z%4] para selecionar partes do corpo.<br/>%2Utilize as %3teclas numéricas%4 para selecionar as categorias de tratamento. + Il %3Menù Medico%4 è un'%3interfaccia%4 dedicata a facilitare %3trattamenti medici%4. Le lettere %3Dx%4 e %3Sx%4 contrassegnano i lati del corpo del paziente che si stanno medicando.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%14%4] guardando il paziente per aprire il Menù Medico. Aprire il menù senza paziente di fronte permette l'automedicazione.<br/>%2In alternativa, usa [%3%12%4] o [%3%13%4] e seleziona %3Menù Medico%4.<br/><br/>%3Comandi:%4<br/>%2Usa [%3W, A, S, D, X, and Z%4] per selezionare parti del corpo.<br/>%2Usa %3tasti numerici%4 per selezionare categorie di cure. + %3医療メニュー%4は%3治療%4をしやすくするための専用%3インターフェース%4です。%3右%4と%3左%4の文字は治療を受ける患者の向きを表しています。<br/><br/>%3使用方法:%4<br/>%2[%3%14%4] を患者に視点を合わせながら押すことで患者の医療メニューを開けます。視点を合わせないで押すと、自分の医療メニューを開くことが出来ます。<br/>%2もしくは [%3%12%4] または [%3%13%4] を使って%3医療メニュー%4を選択します。<br/><br/>%3キーバインド:%4<br/>%2[%3W, A, S, D, X, と Zキー%4] を使って身体の部位を選択できます。<br/>%2%3数字キー%4を使って治療項目を選択できます。 + El %3Menú Médico%4 es una %3interfaz%4 dedicada para facilitar el %3tratamiento médico%4. Las letras %3R%4 and %3L%4 indican el lado del paciente siendo tratado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%14%4] mientras se mira al paciente para abrir el Menú Médico. Abrir el menú sin mirar a un paciente permite el tratamiento a uno mismo. <br/>%2Alternativamente, usar [%3%12%4] o [%3%13%4] y seleccionar %3Menú Médico%4.<br/><br/>%3Teclas asociadas:%4<br/>%2Usar [%3W, A, S, D, X, and Z%4] para seleccionar las partes del cuerpo.<br/>%2Usar las %3teclas numéricas%4 para seleccionar las categorías de tratamiento. + + + Portable, Precise, Rugged + Przenośny, Precyzyjny, Wytrzymały + 휴대성 있고, 정밀하며, 견고합니다 + Portátil, Preciso e Robusto + Leggero, Preciso, Robusto + 高機動、高精度、高耐久 + Portable, précis, robuste + Portable, Preciso, Robusto + + + The %3Horus ATragMX%4 considers atmospheric conditions, gun data, ammunition, range, speed, and muzzle velocity to calculate precise aiming solutions with %3Come-Up%4 results - and even accounts for %3Coriolis%4 and %3Spin Drift%4 effects. %3ATragMX%4, loaded on a handheld computer made by %3TDS Recon%4, is easy to use and lightning fast. The %3Recon%4 meets the rigorous %3MIL-STD-810F%4 military standard for drops, vibration, humidity, altitude and extreme temperatures.<br/><br/>%3Usage:%4<br/>Please visit the wiki page for more information. + %3Horus ATragMX%4 uwzględnia warunki atmosferyczne, dane broni, amunicję, zasięg, prędkość wylotową do wyliczenia precyzyjnych nastaw - ponadto uwzględnia %3Efekt Coriolisa%4 oraz %3Efekt Spinowy%4. %3ATragMX%4, załadowany na komputer przenośny wyprodukowany przez %3TDS Recon%4, jest łatwy i prosty w użyciu. %3Recon%4 spełnia rygorystyczne wymagania %3MIL-STD-810F%4 pod względem odporności na upadek, wibracje, wilgotność, wyskość oraz ekstremalne temperatury.<br/><br/>%3Użycie:%4<br/>Wejdź na wiki po więcej informacji. + %3호러스 ATragMX%4는 대기 상태, 총기 데이터, 탄약, 사거리, 탄속 그리고 총구 속도를 고려하여 %3나타나는 결과%4로 정확한 해결책을 계산하고 %3코리올리 효과%4와 %3스핀 드리프트 효과%4도 설명합니다. %3TDS Recon%4 사에서 제작한 휴대용 컴퓨터에 탑재된 %3ATragMX%4는 사용하기 쉽고 매우 빠릅니다. %3Recon%4 사는 낙하, 진동, 습도, 고도 및 극한 온도에 대해 엄격한 %3%4MIL-STD-810F%4 군사 표준을 충족합니다.<br/><br/>%3사용 방법:%4<br/>자세한 내용은 위키 페이지를 참조하십시오. + O %3Horus ATragMX%4 considera condições atmosféricas, dados de armas, munição, alcance, e velocidade do projétil - e até os efeitos Coriolis e Spin - para calcular as configurações necessárias da mira. O %3ATragMX%4, carregado em um computador portátil feito pela %3TDS Recon%4, é rápido e fácil de usar. O %3Recon%4 satisfaz os rigorosos padrões militares %3MIL-STD-810F%4 para quedas, vibrações, umidade, altitude e temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visite a wiki para mais informações. + L'%3Horus ATragMX%4 tiene conto di condizioni atmosferiche, caratteristiche del fucile, munizioni, portata e velocità alla volata per calcolare precise impostazioni di mira con risultati %3Come-Up%4 - considerando anche effetti %3Coriolis%4 e %3Magnus%4. L'%3ATragMX%4, caricato su un computer portabile %3TDS Recon%4, è facile da usare e molto rapido nei calcoli. Il %3Recon%4 soddisfa i rigorosi standard militari %3MIL-STD-810F%4 per cadute, vibrazioni, umidità, altitudine e temperature estreme.<br/><br/>%3Utilizzo:%4<br/>Visitate la pagina wiki per ulteriori informazioni. + %3ホルス ATragMX%4は、大気条件、銃のデータ、弾薬、射程、速度、および初速を考慮した%3最適な結果が得られる%4正確な照準のための計算とその解法を提供します。さらに、%3コリオリ効果%4および%3スピン ドリフト効果%4も考慮します。%3ATragMX%4は%3TDS Recon製%4の携帯コンピュータに読み込まれており、使いやすく、超高速です。%3Recon%4はは、落下、振動、湿度、高度、極端な温度に関する厳格な%3MIL-STD-810F%4軍事規格を満たしています。<br/><br/>%3使用方法:%4<br/>詳細については、Wiki ページを参照してください。 + El %3Horus ATragMX%4 tiene en cuenta las condiciones atmosféricas, datos del arma, munición, distancia, velocidad y velocidad en boca para calcular con precisión soluciones de tiro precisas con %3Resultados%4 - e incluso tiene en cuenta los efectos %3Coriolis%4 y %3Movimiento Giroscópico%4. %3ATragMX%4, cargado en un ordenador portátil fabricado por %3TDS Recon%4, es facil de usar y muy rápido. El %3Recon%4 cumple con los rigurosos estándares militares %3MIL-STD-810F%4 en cuanto a caidas, vibraciones, humedad, altitud y temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visita la página de la Wiki para más información. + + + Bring Out Your Dead + Przyprowadź Swoich Zmarłych + 죽은 사람을 끌어냅니다 + Retorne os Abatidos + Recupera i tuoi morti + 死者を連れ出す + Récupérez vos morts + Trae de vuelta a los muertos + + + %3Body Bags%4 are used to transport dead bodies. They can be dragged and loaded into vehicles.<br/><br/>%3Usage:%4<br/>%2Approach a dead body.<br/>%2Use [%3%13%4] or [%3%15%4] and select %3Place Body In Bodybag%4. + %3Worki na Zwłoki%4 są używane do transportu ciał. Worki mogą być przeciągane i ładowanie do pojazdów.<br/><br/>%3Użycie:%4<br/>%2Podejdź do martwego ciała.<br/>%2Użyj [%3%13%4] lub [%3%15%4] i wybierz %3Umieść Ciało w Worku na Zwłoki%4. + %3시체 운반용 부대%4는 시체를 운반하는 데 사용되며, 차량으로 끌고 가서 적재할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2시체에 접근하십시오.<br/>%2[%3%13%4] 또는 [%3%15%4]를 사용하여 %3시체 운반용 부대에 담기%4를 선택하십시오. + OS %3Sacos de Cadáver%4 são utilizados para transportar cadáveres. Eles podem ser arrastados e embarcados em veículos.<br/><br/>%3Uso:%4<br/>%2Aproxime-se de um cadáver.<br/>%2Utilize [%3%13%4] ou [%3%15%4] e selecione %3Colocar cadáver dentro do saco%4. + %3Sacche per cadaveri%4 sono usate per trasportare i morti. Possono essere trascinate e caricate su veicoli.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati ad un morto.<br/>%2Usa [%3%13%4] o [%3%15%4] e seleziona %3Metti il corpo nella sacca per cadaveri%4. + %3遺体袋%4は、遺体の輸送に使用されます。引きずって車両に積み込むことができます。<br/><br/>%3使用方法:%4<br/>%2遺体に近寄る。<br/>%2[%3%13%4] または [%3%15%4] を使って%3遺体袋に入れる%4を選択して使用します。 + Las %3Bolsas para Cadáveres%4 se usan para transportar cadáveres. Pueden ser arrastradas y cargadas en vehículos. <br/><br/>%3Uso:%4<br/>%2Acercarse a un cadáver.<br/>%2Usar [%3%13%4] o [%3%15%4] y seleccionar %3Colocar cuerpo en la Bolsa para Cadáveres%4. + + + Take Prisoners + Weź Więźniów + 포로를 데려갑니다 + Faça Prisioneiros + Prendi prigionieri + 捕虜の捕り方 + Faire des prisonniers + Tomar prisioneros + + + %3Cable Ties%4 enable a soldier to capture and detain another soldier. Once apprehended, the captor gains the ability to inspect the prisoner's belongings, set them free, or accompany them to an alternate area. Transporting escorted prisoners is also possible, including loading them into vehicles if needed. Depending on your settings, units may need to surrender before being taken captive.<br/><br/>%3Usage:%4<br/>%2Approach the unit and use the [%3%13%4].<br/>%2The interaction is located around the hands in the form of a handcuffs icon.<br/>%2Repeat to release. + %3Opaski Zaciskowe%4 umożliwiają żołnierzowi pojmanie i zatrzymanie innego żołnierza, a po zatrzymaniu pozwalają na sprawdzenia ekwipunku więźnia, uwolnienia go lub przeniesienia w inne miejsce, a także załadowania go do pojazdu, jeśli zajdzie taka potrzeba. W zależności od ustawień, jednostka może wymagać poddania się przed wzięciem do niewoli.<br/><br/>%3Użycie:%4<br/>%2Podejdź do jednostki i użyj [%3%13%4].<br/>%2Interakcja jest zlokalizowana na rękach pod postacią ikony kajdanek.<br/>%2Użyj ponownie aby uwolnić. + %3케이블 타이%4를 사용하면 병사가 다른 병사를 포로로 잡고 구금할 수 있습니다. 체포되면 포로는 포로의 소지품을 검사하여 석방하거나 대체 지역으로 동행시킬 수 있습니다. 필요하면 차량에 싣는 것을 포함하여 죄수를 호송할 수도 있습니다. 설정에 따라 유닛은 포로가 되기 전에 항복해야 할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2유닛에 접근하여 [%3%13%4]를 사용하십시오.<br/>%2상호작용은 수갑 아이콘의 형태로 손 부분에 위치합니다.<br/>%2해제 하려면 같은 행동을 반복하십시오. + As %3Algema Plásticas%4 permitem a captura e detenção de soldados. Quando apreendidos, o captor se torna capaz de inspecionar os pertences do prisioneiro, liberá-los, ou acompanhá-los a outro local. Transportes mais longos também são possíveis, podendo colocá-los em veículos, se necessário. A depender das configurações, pode ser necessário que as unidades estejam rendidas antes de serem detidas.<br/><br/>%3Uso:%4<br/>%2Aproxime-se da unidade e use [%3%13%4].<br/>%2A interação encontra-se próxima às mãos simbolizada por uma algema.<br/>%2Faça o mesmo para liberar. + %3Fascette%4 permettono a soldati di catturare e ammanettare altri soldati. Una volta catturati è possibile ispezionare il loro inventario, liberarli o scortarli altrove. È inoltre possibile caricarli su veicoli se necessario. A seconda delle impostazioni, potrebbe essere necessaria la resa di unità prima di poterle ammanettare.<br/><br/>%3Uso:%4<br/>%2Avvicinati all'unità e usa [%3%13%4].<br/>%2L'interazione è localizzata intorno alle mani con l'icona di manette.<br/>%2Ripeti per liberare. + %3ケーブル タイ%4は兵士が他の兵士を拘束できるようにします。一度拘束すれば、拘束者は捕虜の所持品を検査したり、釈放したり、別の場所に移送することができるようになります。必要に応じて車両に積み込むなどして捕虜の輸送や護送も可能です。設定によっては、ユニットは捕虜になる前に降伏する必要がある場合があります。<br/><br/>%3使用方法:%4<br/>%2対象に近づいて [%3%13%4] を使います。<br/>%2インタラクションは、手錠アイコンの形で手のあたりに表示されます。<br/>%2同様の方法で解放できます。 + Las %3Bridas%4 permiten a un soldado capturar y detener a otro soldado. Una vez atado, el capturador tiene la habilidad de inspeccionar las pertenencias del prisionero, liberarles de nuevo o transportarles a otro área diferente. Transportar prisioneros escoltados tambien es posible, incluído montarles en vehículos si es necesario. Dependiendo de las opciones, puede requerirse que las unidades se rindan antes de ser capturados.<br/><br/>%3Uso:%4<br/>%2Acercarse a la unidad y usar el [%3%13%4].<br/>%2El punto de interacción se situa sobre las manos en forma de un icono de unas esposas.<br/>%2Repetir el paso para liberar. + + + Phone In An Explosion + Zadzwoń po Eksplozję + 기폭 전화입니다 + Celular Explosivo + Cellulare per esplosivi + 電話でドカン + Explosifs téléphone portable + Teléfono explosivo + + + The %3Cellphone%4 is functionally a %3Clacker%4. Use it to connect and detonate an explosive device. Multiple devices can be linked to the cellphone and called within the phonebook.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select %3Cellphone%4.<br/>%2Open the cellphone interface with [%3%12%4].<br/>%2Navigate the phone book with the arrows and select your calling number.<br/>%2Call the number to detonate. + %3Telefon%4 jest funkcjonalnie %3Detonatorem%4. Użyj go, aby podłączyć i zdetonować ładunek wybuchowy. Wiele urządzeń może być połączonych z jednym telefonem komórkowym i wywoływanych za pomocą książki telefonicznej.<br/><br/>%3Użycie:%4<br/>%2Połóż ładunek wybuchowy<br/>%2Użyj [%3%13%4], wybierz %3Ładunki Wybuchowe%4, i wybierz %3Telefon%4. <br/>%2Otwórz interfejs telefonu za pomocą [%3%12%4].<br/>%2Nawiguj po książce telefonicznej za pomocą strzałek i wybierz żądany numer.<br/>%2Zadzwoń pod niego aby wywołać wybuch. + %3휴대전화%4는 기능적으로는 %3격발기%4입니다. 폭발물 장치를 연결하여 폭발물을 터뜨릴 때 사용합니다. 여러 장치를 휴대전화와 연결하여 전화번호부 내에서 호출할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 놓으십시오.<br/>%2[%3%13%4]를 사용하고, %3폭발물%4을 선택하고, %3휴대전화%4를 선택하십시오.<br/%2[%3%12%4]로 휴대전화 인터페이스를 여십시오.<br/>%2기폭시킬 전화번호를 선택하십시오. + O %3Celular%4 serve como dispositivo de detonação ao explosivo. Utilize-o para conectar e detonar dispositivos explosivos. Múltiplos dispositivos podem estar conectados ao celular e aparecerão na lista telefônica.<br/><br/>%3Uso:%4<br/>%2Plante o explosivo.<br/>%2Utilize [%3%13%4], selecione %3Explosivos%4, e selecione %3Celular%4.<br/>%2Abra a interface do celular com [%3%12%4].<br/>%2Navegue pela lista telefônica utilizando as setas e selecione o número desejado.<br/>%2Ligue para o número para detonar. + Il %3Cellulare%4 è essenzialmente una %3spoletta%4. Usalo per collegare e detonare esplosivi. Molteplici esplosivi possono essere collegati ad un cellulare e detonati chiamando numeri nella rubrica.<br/><br/>%3Utilizzo:%4<br/>%2Piazza un esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivi%4, seleziona %3Cellulare%4.<br/>%2Apri l'interfaccia del telefono con [%3%12%4].<br/>%2Naviga la rubrica con le freccette e seleziona il numero da chiamare.<br/>%2Chiama il numero del dispositivo da detonare. + %3携帯電話%4は%3点火装置%4として機能します。爆破装置を接続して起爆するために使用します。複数のデバイスを携帯電話に繋ぎ、電話帳から呼び出すことができます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、%3携帯電話%4を選択します。<br/>%2[%3%12%4] を使って携帯電話インターフェースを開きます。<br/>%2矢印ボタンで電話帳に移動し、発信番号を選択します。<br/>%2電話を掛けることで起爆します。 + El %3Teléfono%4 es funcionalmente un %3Detonador%4. Úsalo para conectarlo y detonar un dispositivo explosivo. Múltiples dispositivos pueden ser conectados al teléfono y llamados desde la agenda de contactos.<br/><br/>%3Uso:%4<br/>%2Colocar un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y seleccionar %3Teléfono%4.<br/>%2Abrir la interfaz del teléfono con [%3%12%4].<br/>%2Navegar por la agenda de contactos con las flechas y selecciona el número a llamar.<br/>%2Llamar al número para detonarlo. + + + Portable Reading Lights + Przenośne Lampki do Czytania + 휴대용 조명입니다 + Luzes de Leitura Portáteis + Luci da Lettura Portabili + 携帯読書灯 + Lampes de lecture portables + Luces de Lectura Portátiles + + + %3Chemlight Shields%4 give you the ability to read your map, even in dark environments. However, when using %3Chemlight Shields%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2elect %3Chemlights%4 and %3Prepare Chemlight Shield (Color)%4.<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Flashlights%4 where you will find your chemlight shield. + %3Osłony na Świetliki%4 dają ci możliwość czytania mapy nawet w najciemniejszym otoczeniu. Jednak podczas korzystania z %3Świetlików%4, wokół ciebie będzie widoczna lekka poświata<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4. <br/>%2Wybierz %3Świetlik%4 i %3Przygotuj Osłonę Świetlika (Kolor)%4.<br/>%2Otwórz%3Mapę%4.<br/>%2Użyj [%3%12%4] i wybierz %3Latarki%4 gdzie znajdziesz twoją osłonę na świetlik. + %3화학조명 가림막%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3화학조명 가림막%4을 사용하면 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3화학조명%4을 선택하고 %화학조명 가림막 준비%4를 선택하십시오.<br/>%2%3지도%4를 열고 [%3%12%4]를 사용하고 화학조명 가림막을 찾을 수 있는 %3손전등%4을 선택하십시오. + Os %3Protetores de Bastão de Luz%4 possibilitam a leitura de mapas em ambientes escuros. Todavia, quando utilizados, eles iluminam parcialmente os seus arredores.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%12%4] e selecione %3Equipamento%4.<br/>%2Selecione %3Bastões de Luz%4 e %Preparar Protetor de Bastão de Luz (Cor)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Utilize [%3%12%4] e selecione %3Lanternas%4 onde você encontrará o seu bastão de luz. + %3Scudi per Luci Chimiche%4 permettono di leggere la mappa anche in ambienti bui. Il loro utilizzo comporta però un leggero effetto di luminosità intorno alla testa del giocatore.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Eqipaggiamenti%4.<br/>%2Seleziona %3Luce Chimica%4 e %3Prepara Scudo Luce Chimica (Colore)%4.<br/>%2Apri %3Mappa%4.<br/>%2Usa [%3%12%4] e seleziona %3Torcia%4 dove troverai il tuo scudo per luce chimica. + %3ケミライト シールド%4を使用すると、暗い環境でも地図を読み取ることができます。ただし、%3ケミライト シールド%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケミライト%4を選択し%3ケミライト シールドを使う (色)%4を選択します。<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3フラッシュライト%4を選択し、ケミライト シールドを選択します。 + Los %3Protectores de Luz Química%4 proveen la habilidad de poder leer mapas en entornos oscuros. No obstante, cuando se usan los, %3Protectores de Luz Química%4, tendrás un ligero brillo alrededor tuyo.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Luces químicas%4 y %3Preparar Protector de Luz Química (Color)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Linternas%4 donde encontrarás el protector de luz química. + + + Remote Detonation + Zdalna Detonacja + 원격 격발기입니다 + Detonação Remota + Detonazione da remoto + リモコン爆弾 + Détonation à distance + Detonación Remota + + + Use %3Clackers%4 to connect and detonate an explosive device. Multiple devices can be linked to a clacker and detonated on different channels.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select the %3Clacker%4 you wish to link to.<br/>%2Open the ACE interface with [%3%12%4].<br/>%2Select %3Explosives%4 and select a %3Clacker%4.<br/>%2Select the %3Explosive%4 you wish to detonate. + Użyj%3Detonatora%4 do podłączenia i wysadzenia ładunku. Do jednego ładunku może być podłączonych wiele ładunków na różnych kanałach.<br/><br/>%3Użycie:%4<br/>%2Połóż ładunek wybuchowy.<br/>%2Użyj [%3%13%4], wybierz%3Mat. Wybuchowe%4, i wybierz %3Detonator%4, do którego chcesz go podłączyć.<br/>%2Otwórz menu interakcji ACE [%3%12%4].<br/>%2Wybierz %3Mat. Wybuchowe%4 i wybierz %3Detonator%4.<br/>%2Wybierz %3Ładunek%4 który chcesz wysadzić. + %3격발기%4를 사용하여 폭발물을 연결하고 폭발시킬 수 있습니다. 여러 폭발물을 다른 채널에 연결하여 폭발시킬 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 설치합니다.<br/>%2[%3%13%4]를 사용하여 %3폭발물%4을 선택하고 연결할 %3격발기%4를 선택하십시오.<br/>%2[%3%12%4] 키로 ACE 인터페이스를 여십시오.<br/>%2%3폭발물%4을 선택하고 %3격발기%4를 선택하십시오.<br/>%2%3폭발물%4을 선택하면 폭발합니다. + Usa %3Spolette%4 per collegare e detonare dispositivi esplosivi. Molteplici dispositivi possono essere collagati a una spoletta e detonati individualmente come vari canali.<br/><br/>%3Utilizzo:%4<br/>%2Piazza esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivo%4, seleziona la %3Spoletta%4 a cui intendi collegarlo.<br/>%2Apri l'interfaccia ACE con [%3%12%4].<br/>%2Seleziona %3Esplosivi%4 e scegli una %3Spoletta%4.<br/>%2Seleziona un %3Explosivo%4 da detonare. + %3点火装置%4を爆破装置に接続し使用することで起爆することが出来ます。複数の爆破装置を接続しそれぞれ違うチャンネルから起爆することもできます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、接続したい%3点火装置%4を選択します。<br/>%2ACEインターフェースを [%3%12%4] で開きます。<br/>%2%3爆発物%4を選択し、%3点火装置%4を選びます。<br/>%2起爆したい%3爆破装置%4を選択します。 + Utiliza los %3Detonadores%4 para conectar y detonar un explosivo. Múltiple dispositivos pueden ser conectados a un detonador y detonados en diferentes canales.<br/><br/>%3Uso:%4<br/>%2 Coloca un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y selecciona el %3Detonador%4 al que quieres conectarlo.<br/>%2Abre la interfaz de ACE con [%3%12%4].<br/>%2Selecciona %3Explosivos%4 y selecciona un %3Detonador%4.<br/>%2Selecciona el %3Explosivo%4 que quieres detonar. + + + Navigate + Nawigacja + 내비게이션입니다 + Naviga + 測位 + Навигация + Naviguer + Navegar + + + The %3DAGR%4 is a simpler version of the %3MicroDAGR GPS%4. It has similar features but lacks the topographic and satellite imaging functions of the %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Use [%3%12%4] and select %3Configure%4 or %3Toggle%4.<br/><br/>The following menus are available when configuring your %3DAGR:%4<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: Select a waypoint to track.<br/>%11%2WP List: Add/Edit/Remove waypoints.<br/>%11%2Connect To: Connect %3DAGR%4 to the %3Vector 21 Rangefinder%4.<br/>%11%2Options + %3DAGR%4 jest uproszczoną wersją%3MicroDAGR GPS%4. Posiada podobne funkcje, ale brakuje mu map dostępnych w %3MicroDAGR GPS%4.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3DAGR%4.<br/>%2Użyj [%3%12%4] i wybierz %3Konfiguruj%4 lub %3Przełącz%4.<br/><br/>Poniższe menu są dostępne podczas konfiguracji %3DAGR:%4<br/>%11%2Widok Danych: WIP<br/>%11%2GoTo WP: Wybierz waypoint do śledzenia.<br/>%11%2WP List: Dodaj/Edytuj/Usuń waypointy.<br/>%11%2Połącz do: Połącz %3DAGR%4 do dalmierza %3Vector 21%4.<br/>%11%2Opcje + %3DAGR%4은 %3마이크로DAGR GPS%4의 단순화 버전입니다. 유사한 기능을 가지고 있지만 %3마이크로DAGR GPS%4의 지형 및 위성 이미지 기능이 없습니다.<br/><br/>%3사용 방법:%4<br/>%2%3DAGR%4를 장착하십시오.<br/>%2[%3%12%4를 사용하고 %3DAGR 설정%4 또는 %3DAGR 토글%4을 선택하십시오.<br/><br/>%3DAGR%4을 구성할 때 다음 메뉴를 사용할 수 있습니다:<br/>%11%2Data View: 제작 중<br/>%11%2GoTo WP: 추적할 웨이포인트를 선택합니다.<br/>%11%2WP List: 경유지를 추가/편집/제거합니다.<br/>%11%2Connect To: %3DAGR%4을 %3벡터 21%4 거리계에 연동시킵니다.<br/>%11%2옵션입니다 + Il %3DAGR%4 è una versione più semplice del %3GPS MicroDAGR%4. Ha funzioni simili, gli manca però la capacità di visualizzare informazioni topografiche e satellitari come il %3GPS MicroDAGR%4.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia il %3DAGR%4.<br/>%2Usa [%3%12%4] e seleziona %3Configura%4 o %3Apri%4.<br/><br/>I seguenti Menù sono disponibili durante la configurazione del tuo %3DAGR:%4<br/>%11%2Pagina Dati: WIP<br/>%11%2VaiA WP: Seleziona un waypoint da tracciare.<br/>%11%2Lista WP: Aggiungi/Modifica/Rimuovi waypoint.<br/>%11%2Collega A: Collega il %3DAGR%4 al %3Telemetro Vector 21%4.<br/>%11%2Opzioni + %3DAGR%4はシンプルなバージョンの%3MicroDAGR GPS%4です。同様の機能を備えていますが、%3MicroDAGR GPS%4のような地形および衛星画像機能はありません。<br/><br/>%3使用方法:%4<br/>%2%3DAGR%4を装備する。<br/>%2[%3%12%4] を使って%3設定%4 もしくは %3表示切替%4を選択します。<br/><br/>%3DAGR%4の設定には次のメニューを使用できます:<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: 追跡するウェイポイントを選択します。<br/>%11%2WP List: ウェイポイントを追加/編集/削除します。<br/>%11%2Connect To: %3DAGR%4を%3ベクター 21 レンジファインダー%4に接続できます。<br/>%11%2Options + El %3DAGR%4 es una versión simplificada del %3MicroDAGR GPS%4. Tiene unas funcionalidades similares pero le faltan las funciones de los mapas topográficos e imágenes satelitales del %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Usar [%3%12%4] y seleccionar %3Configurar%4 o %3Activar%4.<br/><br/>Los siguientes menús están disponibles cuando configuras el %3DAGR:%4<br/>%11%2Vista de Datos: WIP<br/>%11%2Ir a WP: Selecciona un Punto de Ruta para seguir.<br/>%11%2Lista de WP: Añadir/Editar/Suprimir puntos de ruta.<br/>%11%2Conectar A: Conectar %3DAGR%4 a %3Telémetro Vector 21%4.<br/>%11%2Opciones + + + Explosive Revenge + Wybuchowa Zemsta + '폭발'적인 복수입니다 + Vendetta Esplosiva + 爆発的な復讐 + Взрывная месть + Homme mort + Venganza Explosiva + + + The %3Dead Man's Switch%4 is a device that allows a soldier to detonate an %3Explosive%4 when the soldier dies.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Explosives%4.<br/>%2Select %3Dead Man's Switch%4 and connect the desired %3Explosive%4.<br/>%2Repeat the process and disconnect to reverse. + %3Czuwak%4 jest urządzeniem pozwalającym wysadzić %3Ładunek Wybuchowy%4 gdy żołnierz zginie.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Mat. Wybuchowe%4.<br/>%2Wybierz %3Czuwak%4 i połącz wybrany %3Ładunek Wybuchowy%4.<br/>%2W celu odłączenia powtórz czynności i wybierz odłącz. + %3자폭 장치%4는 병사가 사망했을 때 병사가 %3폭발물%4을 폭발시킬 수 있는 장치입니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3폭발물%4을 선택하십시오.<br/>%2%3자폭 장치%4를 선택하고 원하는 %3폭발물%4에 연결하십시오.<br/>%2반대로 해제하고 싶다면 같은 행동을 반복하십시오. + Il %3Detonatore a rilascio%4 è un dispositivo che permette a soldati di detonare un %3Esplosivo%4 quando perdono i sensi.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Esplosivi%4.<br/>%2Seleziona %3Detonatore a rilascio%4 e collega l'%3Esplosivo%4 desiderato.<br/>%2Ripeti il processo e scollega per disarmare il detonatore. + %3自爆装置%4は、兵士の死亡時に%3爆発物%4を起爆させることができる装置です。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3爆発物%4を選択します。<br/>%2%3自爆装置%4を選択し、接続したい%3爆発物%4を選びます。<br/>%2同様の手順を逆に行うことで接続を解除できます。 + El %3Detonador de Hombre Muerto%4 es un dispositivo que permite a un soldado detonar un %3Explosivo%4 cuando el soldado muere.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Explosivos%4.<br/>%2Seleccionar %3Detonador de Hombre Muerto%4 y conectar el %3Explosivo%4.<br/> deseado%2Repetir el proceso y desconectar para revertirlo. + + + The %3Defusal Kit%4 allows defusal of explosives.<br/><br/>%3Usage:%4<br/>%2Equip a %3Defusal Kit%4.<br/>%2Safely approach an %3Explosive%4.<br/>%2Use [%3%13%4] and select %3Defuse%4. + %3Zestaw do Rozbrajania%4 pozwala rozbrajać ładunki wybuchowe.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Zestaw do Rozbrajania%4.<br/>%2Ostrożnie podejdź pod %3Ładunek Wybuchowy%4.<br/>%2Użyj [%3%13%4] i wybierz %3Rozbrój%4. + %3해체 장비%4를 사용하면 폭발물을 제거할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3해체 장비%4를 장착하십시오.<br/>%2%3폭발물%4에 안전하게 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3해체%4를 선택하십시오. + The %3Kit E.O.D.%4 permette il disinnesco di esplosivi.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Kit E.O.D.%4.<br/>%2Avvicinati in modo sicuro ad un %3Esplosivo%4.<br/>%2Usa [%3%13%4] e seleziona %3Disinnesca%4. + %3解除キット%4は爆発物の無力化を行うことができます。<br/><br/>%3使用方法:%4<br/>%2%3解除キット%4を装備。<br/>%2慎重に%3爆発物%4に接近します。<br/>%2[%3%13%4] を使って%3無力化%4を選択します。 + El %3Kit de Desactivación%4 permite la desactivación de explosivos.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kit de Desactivación%4.<br/>%2Aproxímate al %3Explosivo%4<br/> de forma segura.%2Usa [%3%13%4] y selecciona %3Desactivar%4. + + + Defuse Explosives + Rozbrajanie Ładunków + 폭발물을 해체합니다 + Disinnesca Esplosivi + 爆発物の解除 + Обезвреживание взрывчатки + Désamorcer les explosifs + Desactivar Explosivos + + + Protect Your Hearing + Dbaj o Swój Słuch + 청력을 보호합니다 + Proteggi il tuo Udito + 聴覚の保護 + Защитите свой слух + Protéger votre audition + Protege tus oídos + + + %3Ear Plugs%4 help prevent hearing damage from repeat loud noises near a soldier. Insert %3Ear Plugs%4 to lower volume of a soldier's environment and prevent %3Combat Deafness%4.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Insert %3Ear Plugs%4. + %3Stopery do Uszu%4 zapobiegają uszkodzeniom słuchu na skutek wybuchów i strzałów w pobliżu żołnierza. Włóż %3Stopery do Uszu%4 w celu wyciszenia otoczenia i uniknięcia %3Głuchoty Bojowej%4.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Włóż %3Stopery do Uszu%4. + %3Tappi auricolari%4 aiutano a prevenire danni all'udito da ripetuti rumori forti in prossimità del soldato. Inserisci %3Tappi auricolari%4 per ridurre il volume dell'ambiente per il soldato e impedire %3Assordamento%4.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Indossa %3Tappi Auricolari%4. + %3귀마개%4는 병사 주변에서 반복되는 시끄러운 소리로 인한 청력 손상을 방지하는 데 도움이 됩니다. %3귀마개%4를 끼워서 병사가 있는 환경의 소리 크기를 낮추고 %3전투로 인한 청력손상%4을 방지하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3귀마개%4를 삽입하십시오. + %3耳栓%4は、兵士の近くで繰り返される大きな騒音による聴覚障害を防ぐのに役立ちます。%3耳栓%4を耳に挿入することで兵士の環境の音量を下げ、%3戦闘難聴%4を防ぎます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3耳栓を着ける%4ことで使用できます。 + Los %3Tapones de oídos%4 ayudan a prevenir el daño auditivo de ruidos altos repetidos cerca de un soldado. Inserta los %3Tapones de oídos%4 para reducir el volumen del entorno del soldado y prevenir la %3Sordera de Combate%4.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Insertar %3Tapones de oídos%4. + + + Get To Cover + Łap Osłonę + 엄폐하십시오 + Mettiti in Copertura + 遮蔽を造り出す + Добраться до укрытия + Se mettre à couvert + Ponerse A Cubierto + + + The %3Entrenching Tool%4 allows soldiers to dig trenches to help defend their position. The soldier must be on soil in order to dig a trench.<br/><br/>%3Usage:%4<br/>%2Equip an %3Entrenching Tool%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the type of trench you wish to build. + %3Saperka%4 pozwala żołnierzowi kopać okopy w celu obrony swoich pozycji. Żołnierz musi być na glebie, aby wykopać okop.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Saperkę%4.<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz rodzaj okopu, który chcesz wykopać. + La %3Pala da Trincea%4 permette a soldati di scavare trincee per difendere meglio la loro posizione. Il soldato deve trovarsi su suolo scavabile per poter creare trincee.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Pala da Trincea%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona il tipo di trincea che vuoi costruire. + %3야전삽%4을 사용하면 병사들의 진지 방어를 위한 참호를 팔 수 있습니다. 병사가 참호를 파려면 흙 위에 있어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3야전삽%4을 장비하십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2짓고 싶은 종류의 참호를 선택하십시오. + %3塹壕ツール%4を使用すると、兵士は自分の陣地を守るために塹壕を掘ることができます。塹壕を掘るには、兵士は土の上にいる必要があります。<br/><br/>%3使用方法:%4<br/>%2%3塹壕ツール%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2構築する塹壕の種類を選択します。 + La %3Pala de Trincheras%4 permite a los soldados excavar trincheras para ayudarles a defender su posición. El soldado debe estar sobre tierra para poder excavar una trinchera.<br/><br/>%3Uso:%4<br/>%2Equipar la %3Pala de Trincheras%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar el tipo de trinchera que quieres construir. + + + Flashlights + Latarki + Torce + 손전등 + フラッシュライト + Фонари + Lampes de poche + Linternas + + + Illuminate Your Map + Rozświetlij Swoją Mapę + Illumina la tua Mappa + 지도를 밝혀줍니다 + 地図に光あれ + Осветите свою карту + Éclairer votre carte + Ilumina Tu Mapa + + + %3Flashlights%4 give you the ability to read your map, even in dark environments. However, when using %3Flashlights%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2On the map screen, use [%3%12%4] and select %3Flashlights%4.<br/>%2Select the %3Flashlight%4 you want to use and select %3On%4.<br/><br/>%3Available Flashlight Items%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Flashlight states are persistent. + %3Latarki%4 pozwalają czytać mapę, nawet w ciemnościach. Jednakże podczas używani %3Latarki%4, będziesz miał wokół siebie delikatną poświatę.<br/><br/>%3Użycie:%4<br/>%2W widoku mapy użyj [%3%12%4] i wybierz %3Latarki%4.<br/>%2Wybierz %3Latarkę%4, którą chcesz użyć i wybierz %3Włącz%4.<br/><br/>%3Dostępne latarki%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Stan latarki jest trwały. + %3Torce%4 permettono di leggere la tua mappa anche in ambienti bui. Però quando le utilizzi avrai un leggero effetto luminoso intorno a te.<br/><br/>%3Utilizzo:%4<br/>%2Sulla mappa usa [%3%12%4] e seleziona %3Torcia%4.<br/>%2Seleziona la %3Torcia%4 che vuoi usare e seleziona %3Accendi%4.<br/><br/>%3Oggetti Torcia Disponibili%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Lo stato di una torcia è persistente. + %3손전등%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3손전등%4을 사용할 때 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2지도 화면에서 [%3%12%4]를 사용하고 %3손전등%4을 선택하십시오.<br/>%2사용할 %3손전등%4을 선택하고 %3켜기%4를 선택하십시오.<br/><br/>%3사용 가능한 손전등 아이템%4:<br/>%2풀턴 MX-991<br/>%2 KSF-1<br/>%2 매그라이트 XL50<br/><br/>%3참고:%4<br/>손전등 상태는 영구적입니다. + %3フラッシュライト%4を使用すると、暗い環境でも地図を読むことができます。ただし、%3フラッシュライト%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2マップ画面で [%3%12%4] を使用し、%3フラッシュライト%4を選択します。<br/>%2%3フラッシュライト%4を選択し、使用したいライトを%3点ける%4。<br/><br/>%3使用可能なフラッシュライトのアイテム%4:<br/>%2 フルトン MX-991<br/>%2 KSF-1<br/>%2 マグライト XL50<br/><br/>%3備考:%4<br/>フラッシュライトの状態は継続します。 + Las %3Linternas%4 proveen la habilidad para leer tu mapa, incluso en entornos oscuros. No obstante, cuando se usen las %3Linternas%4, aparecerá un ligero brillo alrededor tuya.<br/><br/>%3Uso:%4<br/>%2En la pantalla del mapa, utilizar [%3%12%4] y seleccionar %3Linternas%4.<br/>%2Seleccionar la %3Linterna%4 Que quieres utilizar y selecciona %3On%4.<br/><br/>%3Objetos de Linternas disponibles%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTA:%4<br/>Los estados de las Linternas son persistentes. + + + Observe From The Skies + Obserwuj Świat z Góry + Osserva dal Cielo + 하늘에서 관측합니다 + 空から戦場を見てみよう + Наблюдайте с Небес + Observer depuis le ciel + Observar Desde El Cielo + + + The %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 is designed to be fired from a grenade launcher. After being fired in the air, the built-in parachute will be deployed and the IR CMOS camera will activate, providing a video stream until it touches the ground or is shot down.<br/><br/>%3Usage:%4<br/>%2Equip a %3HuntIR Monitor%4 and compatible ammunition.<br/>%2Fire the %3HuntIR Round%4 as high as possible over the area you want to observe.<br/>%2Open the %3HuntIR Monitor%4.<br/>%2Use [%3%12%4], select %3Equipment%4.<br/>%2Select %3Activate HuntIR Monitor%4. + %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 przeznaczony jest do wystrzeliwania z granatnika. Po wystrzeleniu, wbudowany spadochron zostanie otwarty i uruchomi się kamera IR CMOS, zapewniająca obraz wideo do momentu zetknięcia się z ziemią lub zestrzelenia.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Monitor HuntIR%4 i kompatybilną amunicję.<br/>%2Wystrzel %3Pocisk HuntIR%4 najwyżej jak to tylko możliwe nad teren, który chcesz obserwować.<br/>%2Otwórz%3Monitor HuntIR%4.<br/>%2Użyj [%3%12%4], wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Aktywuj Monitor HuntIR%4. + Il %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 è progettato per essere sparato da un lanciagranate. Dopo essere stato sparato verso l'alto, verrà aperto un paracadute incorporato e attivata una videocamera IR CMOS, inviando una diretta video finché toccherà terra o verrà abbattuto.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Monitor HuntIR%4 e munizioni compatibili.<br/>%2Spara un %3Colpo HuntIR%4 il più alto possibile sopra l'area che vuoi osservare.<br/>%2Apri il %3Monitor HuntIR%4.<br/>%2Usa [%3%12%4], seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attiva Monitor HuntIR%4. + %3고고도 유닛 탐색용 전술 영상화 탄약 (HuntIR)%4은 유탄발사기에서 발사될 수 있도록 설계되었습니다.공주에서 발사된 후 내장된 낙하산이 전개되고 적외선 CMOS 카메라가 작동하여 지상에 닿거나 격추될 때까지 비디오 스트림이 제공됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3헌트IR 모니터%4와 호환 탄약을 장착하십시오.<br/>%2%3헌트IR 유탄%4을 발사하려는 구역에서 가능한 한 높게 발사하십시오.<br/>%2%3헌트IR 모니터%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3헌트IR 모니터 활성화%4를 선택하십시오. + %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4はグレネードランチャーから発射されるように設計されています。空中で発射された後、内蔵のパラシュートが展開され、IR CMOS カメラが起動し、地面に着くか撃墜されるまでビデオ ストリームを提供します。<br/><br/>%3使用方法:%4<br/>%2%3HuntIR モニター%4と互換性のある弾薬を装備します。<br/>%2観測したいエリアに向けてできるだけ高く%3HuntIR 弾頭%4を発射します。<br/>%2%3HuntIR モニター%4を開きます。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3HuntIRを起動する%4からモニターを起動します。 + El %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 está diseñado para ser disparado desde un lanzagranadas. Despues de ser disparada al aire, desplegará su paracaídas integrado y activará su cámara IR CMOS integrada, proveyendo de un flujo de video hasta que toque el suelo o sea derribado.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Monitor HuntIR%4 y la munición compatible.<br/>%2Dispara la %3Munición HuntIR%4 tan alto como sea posible sobre el área que quieres observar.<br/>%2Abre el %3Monitor HuntIR%4.<br/>%2Usar [%3%12%4], seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Activar Monitor HuntIR%4. + + + Track Your Team With Stealth + Śledź Swój Zespół w Ciszy + Traccia la tua squadra con discrezione + 은신하여 팀을 찾아냅니다 + 自分の部隊を追う + Следите за своей командой незаметно + Suivez votre équipe en toute discrétion + Sigue A Tu Equipo Con Sigilo + + + The %3IR Strobe%4 is a throwable that emits an IR light pulse intermittently. The %3IR Strobe%4 can also be attached to a soldier, making it useful for tracking teammates under night vision devices.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Attach%4 and select the %3IR Strobe%4. + %3Stroboskop IR%4 jest rzucanym przedmiotem emitującym pulsujące światło podczerwone. %3Stroboskop IR%4 może być także przypięty do munduru, tworząc z niego użyteczne urządzenie do śledzenia żołnierzy z użyciem noktowizji.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Przyczep%4 i wybierz %3Stroboskop IR%4. + La %3Strobo IR%4 è un lanciabile che emette un impulso intermittente di luce IR. La %3Strobo IR%4 può anche essere attaccata ad un soldato, facilitando l'identificazione di alleati con visori notturni.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attacca%4 e scegli la %3Strobo IR%4. + %3적외선 스트로브%4는 던질 수 있는 적외선 광펄스를 간헐적으로 방출하는 투척형 아이템입니다. %3적외선 스트로브%4는 병사에게도 부착 가능하기 때문에 야간투시장치로 팀원을 추적할 때 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3아이템 부착%4을 선택하고 %3적외선 스트로브%4를 선택하십시오. + %3赤外線ストロボ%4は、赤外線光パルスを断続的に放射します。投擲可能です。%3赤外線ストロボ%4は兵士に取り付けることもできるため、暗視装置の下でチームメイトを追跡するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3アイテムを取り付ける%4を選択して%3赤外線ストロボ%4を選び使用します。 + El %3Estroboscópico IR%4 es un objeto lanzable que emite un pulso intermitente de luz IR. El %3Estroboscópico IR%4 tambien puede ser sujeto a un soldado, haciéndolo útil para el seguimiento de los compañeros utilizando gafas de visión nocturna.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Sujetar%4 y seleccionar el %3Estroboscópico IR%4. + + + Pocket Weatherstation + Przenośna Pogodynka + Stazione Meteo Tascabile + 휴대용 기상 관측 장비입니다 + 携帯気象予報所 + Карманная метеостанция + Station météo de poche + Estación Climática de Bolsillo + + + The %3Kestrel 4500 Pocket Weather Tracker%4 is a mini weather station useful for collecting the the following weather data:<br/>%2Heading and wind direction<br/>%2Crosswind and headwind<br/>%2Altitude and barometric pressure<br/>%2Wet bulb temperature<br/>%2Humidity and dewpoint<br/>%2Density altitude<br/>%2Wind chill and temperature<br/>%2Time and date<br/>%2Minimum, maximum, and average values<br/><br/>%3Usage:%4<br/>%2Equip a %3Kestrel%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Open%4. + %3Kestrel 4500 Pocket Weather Tracker%4 jest przenośną stacją pogodową pozwalającą zbierać takie dane jak: <br/>%2Kurs i kierunek wiatru<br/>%2Wiatr boczny i czołowy<br/>%2Wysokość i ciśnienie barometryczne<br/>%2Temperatua mokrego termometru<br/>%2Wilgotność i punkt rosy<br/>%2Gęstość powietrza<br/>%2Temperatura i temperatura odczuwalna<br/>%2Czas i data<br/>%2Wartości minimalne, maksymalne oraz średnie<br/><br/>%3Użycie: %4<br/>%2Wyekwipuj %3Kestrela%4. <br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Otwórz%4. + Il %3Kestrel 4500 Indicatore Meteorologico Tascabile%4 è una mini-stazione meteo utile per ricavare le seguenti informazioni meteorologiche:<br/>%2Prua e direzione del vento<br/>%2Vento di traverso e frontale<br/>%2Altitudine and pressione barometrica<br/>%2Temperatura di bulbo umido<br/>%2Umidità e punto di rugiada<br/>%2Density altitude<br/>%2Temperatura e gelo del vento<br/>%2Data e Ora<br/>%2Valori minimi, massimi, e medi<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia %3Kestrel%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Apri%4. + %3케스트렐 4500 휴대용 기상 추적 장비%4는 다음 날씨 데이터들을 수집하는 데 유용한 소형 기상 관측 장비입니다:<br/>%2바람이 오는 방향과 가는 방향<br/>%2옆바람과 맞바람<br/>%2고도 및 기압<br/>%2습구온도<br/>%2습도 및 이슬점<br/>%2밀도고도<br/>%2체감온도<br/>%2시간 및 날짜<br/>%2최소, 최대, 평균값<br/><br/>%3사용 방법:%4<br/>%2%3케스트렐 4500NV%4를 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3열기%4를 선택하십시오. + %3ケストレル 4500 携帯気象計%4は、次の気象データの収集に役立つミニ気象ステーションです:<br/>%2方位と風向<br/>%2横風と向かい風<br/>%2高度と気圧<br/>%2湿球温度<br/>%2湿度と露点<br/>%2密度高度<br/>%2ウィンドチルと温度<br/>%2日付と時刻<br/>%2最小値、最大値、平均値<br/><br/>%3使用方法:%4<br/>%2%3ケストレル%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケストレルを開く%4で使用できます。 + La %3Estación Climática de Bolsillo Kestrel 4500%4 es una pequeña estación climática portátil para recolectar la siguiente información del tiempo:<br/>%2Dirección y Sentido del Viento<br/>%2VIento cruzado y Viento en cola<br/>%2Altitud y presión barométrica<br/>%2Temperatura húmeda<br/>%2Humedad y punto de condensación<br/>%2Densidad de altitud<br/>%2Sensación térmica y temperatura<br/>%2Hora y fecha<br/>%2Valores mínimos, máximos y medios<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kestrel%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Abrir%4. + + + Triangulate Your Position + Trianguluj Swoją Pozycję + Triangola la tua posizione + 위치를 삼각측량합니다 + 三角測量で位置を特定 + Передавайте свое местоположение + Trianguler votre position + Triangular Tu Posición + + + The %3Map Tools%4 are a set of tools that allows a soldier to measure distances and angles. Useful for land, and calculating firing solutions for artillery.<br/><br/>%3Usage:%4<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Map Tools%4.<br/>%2 The Tool can be moved by dragging with [%3Left-Click%4] while holding [%3ALT%4]. + %3Narzędzia Nawigacyjne%4 są zestawem narzędzi pozwalającym mierzyć dystans i kąt. Użyteczne do wyliczania parametrów strzałów dla artylerii.<br/><br/>%3Użycie:%4<br/>%2Otwórz%3Mapę%4.<br/>%2Użyj [%3%12%4] i wybierz %3Narzędzia Nawigacyjne%4.<br/>%2 Narzędzia mogą być przeciągane za pomocą [%3LPM%4] trzymając [%3ALT%4]. + Gli %3Strumenti Cartografici%4 permettono al soldato di misurare distanze e angoli sulla mappa. Utile a terra e per calculare direzioni di tiro per artiglieria.<br/><br/>%3Utilizzo:%4<br/>%2Apri %3Mappa%4.<br/>%2Usa [%3%12%4] e seleziona %3Strumenti Cartografici%4.<br/>%2 Lo strumento può essere spostato trascinandolo con [%3Click-Sinistro%4] premendo [%3ALT%4]. + %3독도용 도구%4는 병사가 거리와 각도를 측정할 수 있는 도구 세트입니다. 지상에서 유용하며 포병 사격 솔루션 계산에 유용합니다,<br/><br/>%3사용 방법:%4<br/>%2%3지도%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3독도용 도구%4를 선택하십시오.<br/>%2도구는 [%3Alt 키%4]를 누른 상태에서 [%3마우스 왼쪽 클릭%4]으로 드래그하여 이동할 수 있습니다. + %3マップ ツール%4は、兵士が距離と角度を測定できるようにするツールのセットです。陸上や大砲の射撃工程の計算を解くのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3マップ ツール%4を選択します。<br/>%2 [%3ALT%4] を押しながら [%3左クリック%4] でドラッグするとツールを移動できます。 + Les %3Outils cartographiques%4 sont un ensemble d'outils permettant au soldat de mesurer des distances et des angles. Utile pour la terre et le calcul des solutions de tir pour l'artillerie.<br/><br/>%3Utilisation:%4<br/>%2Ouvrir la%3Carte%4.<br/>%2Utiliser [%3%12%4] et sélectionner %3Outils cartographiques%4.<br/>%2 L'outil peut être déplacé en le faisant glisser avec [%3Clic gauche%4] tout en maintenant [%3ALT%4]. + Las %3Herramientas de mapa%4 son un conjunto de herramientas que permiten a un soldado medir distancias y ángulos. Util para terrenos, y para calcular soluciones de tiro para artillería.<br/><br/>%3Uso:%4<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Herramientas de Mapa%4.<br/>%2 La herramienta puede ser movida siendo arrastrada con [%3CLick-Izquierdo%4] mientras se pulsa [%3ALT%4]. + + + Advanced DAGR + Zaawansowany DAGR + DAGR Avanzato + 고급형 DAGR입니다 + より高度なDAGR + Продвинутый DAGR + DAGR avancé + DAGR Avanzado + + + The %3MicroDAGR GPS%4 is an advanced version of the %3DAGR%4. It provides position, navigation, and timing (PNT) data to include:<br/>%2Compass and heading<br/>%2Date and hour synced to the mission<br/>%2Elevation (relative to sea level)<br/>%2Current speed<br/>%2GPS with topographic and satellite view<br/>%2Creating, naming, and deleting waypoints<br/>%2Friendly identification (Requires ACE BLUFOR Tracker Setting)<br/>Connection to the Vector-21 Rangefinder for data import (waypoint creation and grid reference of ranged targets)<br/><br/>%3Usage:%4<br/>%2For usage instructions, please visit the dedicated %3MicroDAGR%4 wiki. + %3MicroDAGR GPS%4 jest zaawansowaną wersją %3DAGR%4. Dostarcza dane oparte o pozycję, nawigację, i czas (PNT): <br/>%2Kompas i kierunek<br/>%2Datę i godzinę zsynchronizowaną z misją<br/>%2Elewację (relatywną do poziomu morza)<br/>%2Obecną prędkość<br/>%2GPS z widokiem topograficznym i satelitarnym<br/>%2Tworzenie, nazywanie oraz usuwanie waypointów<br/>%2Identyfikację sojuszników (Wymaga ACE BLUFOR Tracker)<br/>Połączenie do dalmierza Vector-21 w celu importu danych (waypointy i współrzędne zmierzonego celu)<br/><br/>%3Użycie: %4<br/>%2Po instrukcję użycia odwiedź %3MicroDAGR%4 wiki. + Il %3GPS MicroDAGR%4 è una versione avanzata del %3DAGR%4. Esso mostra dati su posizione, navigazione e tempismo (PNT), includendo:<br/>%2Bussola e azimut<br/>%2Data e ora sincronizzate con la missione<br/>%2Elevazione (dal livello del mare)<br/>%2Velocità attuale<br/>%2GPS con visuale topografica e satellitare<br/>%2Creazione, rinomina e rimozione di waypoint<br/>%2Identificazione di alleati (Richiede Impostazioni ACE BLUFOR Tracker)<br/>Connessione al Telemetro Vector-21 per importazione di dati (creazione waypoint e indicazione di griglia su bersagli puntati)<br/><br/>%3Utilizzo:%4<br/>%2Per informazioni sull'utilizzo sei pregato di visitare la pagina wiki dedicata al %3MicroDAGR%4. + %3마이크로DAGR GPS%4는 %3DAGR%4의 고급 버전입니다. 다음과 같이 위치, 내비게이션 및 타이밍(PNT) 데이터를 제공합니다:<br/>%2나침반 및 방향<br/>%2임무와 동기화된 날짜 및 시간<br/>%2고도 (해수면 기준)<br/>%2현재 속도<br/>%2지형 및 위성 시점 기능이 있는 GPS<br/>%2웨이포인트 생성, 작명 및 삭제<br/>%2아군 식별 (ACE의 GPS 피아식별기 켜기 체크 필요)<br/>%2데이터를 가져오기 위한 벡터-21 거리계에 연결(원거리 대상의 웨이포인트 생성 및 좌표 참조)<br/><br/>%3사용 방법:%4<br/>%2사용 방법을 보려면 전용 %3마이크로DAGR%4의 위키를 방문하십시오. + %3MicroDAGR GPS%4は%3DAGR%4のより高度なバージョンです。測位、航法、計時(PNT)データが提供されます。これには以下の情報を含みます:<br/>%2コンパスと方位<br/>%2ミッションに同期された日付と時間<br/>%2標高 (海面に対する相対値)<br/>%2現在の速度<br/>%2地形図と衛星ビューを備えたGPS<br/>%2ウェイポイントの作成、名前付け、および削除<br/>%2友軍の識別 (ACE ブルーフォーストラッキング設定が必要)<br/>ベクター21レンジファインダーへの接続とデータのインポート (ウェイポイントの作成と遠距離ターゲットのグリッド参照)<br/><br/>%3使用方法:%4<br/>%2使用手順については、専用の %3MicroDAGR%4 wiki を参照してください。 + El %3GPS MicroDAGR%4 es una versión avanzada del %3DAGR%4. Provee de posicionamiento, navegación y datos de temporización (PNT) que incluye:<br/>%2Brújula y dirección<br/>%2Fecha y hora sincronizada con la misión<br/>%2Elevación (relativa al nivel del mar)<br/>%2Velocidad actual<br/>%2GPS con vista topográfica y satelital<br/>%2Creación, nombrado y borrado de puntos de ruta<br/>%2Identificación de aliados (Requiere la opción de ACE BLUFOR Tracker)<br/>Conexión con el telémetro Vector-21 para importación de datos (creación de puntos de ruta y referenciado en eje de coordenada para objetivos a distancia)<br/><br/>%3Uso:%4<br/>%2Para instrucciones de uso, por favor visita la Wiki dedicada de %3MicroDAGR%4. + + + Range Tables + Tabele Strzelnicze + Tavole di Tiro + 사거리표 + 射表 + Таблицы диапазонов + Tables de tir + Tablas de Distancia + + + Get A Firing Solution + Strzelaj Celnie + Per una soluzione di tiro + 사격 솔루션을 제공합니다 + 撃ち方の解を得る + Получите расчёт + Obtenir une solution de tir + Obtener Una Solución de Tiro + + + %3Range Tables%4 allow for a soldier to estimate accurate shot placement on direct or indirect targets (depending on asset). The %3Range Table%4 will automatically fill depending on the soldiers selected weapon/vehicle.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the desired %3Range Table%4. + %3Tabele Strzelnicze%4 pozwalają żołnierzowi oszacować dokładne rozmieszczenie strzałów na cele bezpośrednie lub pośrednie (w zależności od zasobu). %3Tabele Strzelnicze%4 wypełnią się automatycznie w zależności od wybranej broni/pojazdu.<br/><br/>%3Użycie:%4%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4<br/>.<br/>%2Wybierz żądaną%3Tabelę Strzelniczą%4. + %3Tavole di tiro%4 permettono al soldato di stimare piazzamenti accurati di colpi mediante fuoco diretto o indiretto (a seconda dell'arma). La %3Tavola di tiro%4 si modificherà in automatico a seconda dell'arma/veicolo del soldato.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] and seleziona %3Equipaggiamento%4.<br/>%2Seleziona la portata desiderata sulla %3Tavola di tiro%4. + %3사거리표%4를 사용하면 병사가 직접 또는 간접 표적(자산에 따라 다름)에 대한 정확한 사격 배치를 추정할 수 있습니다. %3사거리표%4는 선택한 병사의 무기/차량에 따라 자동으로 작성됩니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2원하는 %3사거리표%4를 선택하십시오. + %3射表%4 を使用すると、兵士は (手段に応じて) 直接的または間接的なターゲットへの正確な射撃位置を推定できます。%3射表%4は、兵士が選択した武器/車両に応じて自動的に入力されます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2目的の%3射表%4を選択します。 + La %3Tabla de distancias%4 permite a un soldado estimar con precisión el posicionamiento de un disparo sobre un objetivo de manera directa o indirecta (dependiendo del dispositivo). La %3Tabla de distancias%4 se autorellena dependiendo del arma o vehículo seleccionado por el soldado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Selecciona la %3Tabla de distancias%4 deseada. + + + Ropes + Liny + Corde + 로프 + ロープ + Канаты + Corde + Cuerdas + + + Tow With Ease + Holowanie bez Wysiłku + Rimorchia con facilità + 쉽게 견인을 할 수 있습니다 + 楽々けん引 + Буксируйте с легкостью + Remorquer avec facilité + Remolcar Con Facilidad + + + %3Ropes%4 have multiple uses including %3Towing%4 vehicles and %3Fast Roping%4 from helicopters.<br/><br/>%3Towing:%4<br/>%2Approach a vehicle.<br/>%2Use [%3%13%4] and select %3Towing%4.<br/>%2Select rope length.<br/>%2Select attachment point on towing vehicle.<br/>%2Select attachment on towed vehicle.<br/><br/>%3Available Rope Lengths:%4<br/>%2 3.2 meters<br/>%2 6.2 meters<br/>%2 12.2 meters<br/>%2 15.2 meters<br/>%2 18.3 meters<br/>%2 27.4 meters<br/>%2 36.6 meters + %3Liny%4 mają wiele zastosowań, takich jak %3Holowanie%4 pojazdów czy %3Zjeżdżanie na Linach%4 z helikopterów.<br/><br/>%3Holowanie:%4<br/>%2Podejdź pod pojazd.<br/>%2Użyj [%3%13%4] i wybierz %3Holowanie%4.<br/>%2Wybierz długość liny. <br/>%2Wybierz punkt zaczepu liny na holującym pojeździe.<br/>%2Wybierz punkt zaczepu liny na holowanym pojeździe.<br/><br/>%3Dostępne Długości Liny:%4<br/>%2 3.2 metera<br/>%2 6.2 metera<br/>%2 12.2 metera<br/>%2 15.2 metera<br/>%2 18.3 metera<br/>%2 27.4 metera<br/>%2 36.6 metera + %3Corde%4 hanno molteplici utilizzi, come %3Trainare%4 veicoli e %3Fast Roping%4 da elicotteri.<br/><br/>%3Traino:%4<br/>%2Avvicinati a un veicolo.<br/>%2Usa [%3%13%4] e seleziona %3Traina%4.<br/>%2Seleziona lunghezza corda.<br/>%2Seleziona punto di attacco su veicolo trainante.<br/>%2Seleziona attacco su veicolo trainato.<br/><br/>%3Lunghezze corde a disposizione:%4<br/>%2 3.2 metri<br/>%2 6.2 metri<br/>%2 12.2 metri<br/>%2 15.2 metri<br/>%2 18.3 metri<br/>%2 27.4 metri<br/>%2 36.6 metri + %3로프%4는 차량 %3견인%4 및 헬기의 %3패스트로프%4 등 여러 용도로 사용됩니다.<br/><br/>%3견인 방법:%4<br/>%2차량에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3견인%4을 선택하십시오.<br/>%2로프 길이를 선택하십시오.<br/>%2견인할 차량의 부착 지점을 선택하십시오.<br/>%2견인될 차량의 부착 지점을 선택하십시오.<br/><br/>%3사용 가능한 로프 길이:%4<br/>%2 3.2m<br/>%2 6.2m<br/>%2 12.2m<br/>%2 15.2m<br/>%2 18.3m<br/>%2 27.4m<br/>%2 36.6m + %3ロープ%4には、車両の%3けん引%4やヘリコプターからの%3ファストロープ%4など、複数の用途があります。<br/><br/>%3けん引方法:%4<br/>%2車両に近づきます。<br/>%2[%3%13%4] を使って%3けん引%4を選択します。<br/>%2ロープの長さを選択します。<br/>%2けん引する車両のロープ取付位置を選択します。<br/>%2けん引される車両のロープ取付位置を選択します。<br/><br/>%3利用可能なロープの長さ:%4<br/>%2 3.2 メートル<br/>%2 6.2 メートル<br/>%2 12.2 メートル<br/>%2 15.2 メートル<br/>%2 18.3 メートル<br/>%2 27.4 メートル<br/>%2 36.6 メートル + Las %3Cuerdas%4 tienen múltiples usos incluyendo el %3Remolcado%4 de vehículos y el %3Descenso con Cuerda%4 desde helicópteros.<br/><br/>%3Remolcado:%4<br/>%2Acércate a un vehículo.<br/>%2Usar [%3%13%4] y seleccionar %3Remolcado%4.<br/>%2Selecciona la longitud de la cuerda.<br/>%2Selecciona un punto de anclaje en el vehículo de remolcado.<br/>%2Selecciona una sujección en el vehículo remolcado.<br/><br/>%3Longitudes de Cuerda Disponibles:%4<br/>%2 3.2 metros<br/>%2 6.2 metros<br/>%2 12.2 metros<br/>%2 15.2 metros<br/>%2 18.3 metros<br/>%2 27.4 metros<br/>%2 36.6 metros + + + Expand Your Fortifications + Powiększ Swoje Fortyfikacje + Espandi le tue Fortificazioni + 당신의 요새를 확장합니다 + 要塞を拡張する + Расширить свои укрепления + Élargissez vos fortifications + Expande Tus Fortificaciones + + + %3Sandbags%4 are sacks made of sturdy material, filled with sand, used for a variety of purposes such as creating barriers or providing stability in construction projects. Useful in expanding larger placed fortifications.<br/><br/>%3Usage:%4<br/>%2Equip a %3Sandbag (Empty)%4.<br/>%2Use [%3%12%4] and select %3Deploy Sandbag%4.<br/>%2Follow on-screen instructions for placement. + %3Worki z Piaskiem%4 to worki wykonane z mocnego materiału, wypełnione piaskiem, używane do różnych celów, takich jak tworzenie barier lub zapewnianie stabilności w projektach budowlanych. Przydatne przy tworzeniu większych fortyfikacji.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Worek z Piaskiem (Pusty%4.<br/>%2Use [%3%12%4] i wybierz %3Rozłóż Worek z Piaskiem%4.<br/>%2Podążaj za instrukcjami na ekranie. + %3Sacchi di Sabbia%4 sono sacchi di un materiale robusto, riempiti di sabbia, usati per una varietà di utilizzi come creare barriere o aumentare la stabilità di fortificazioni.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Sacco di Sabbia (Vuoto)%4.<br/>%2Usa [%3%12%4] e seleziona %3Posiziona Sacco di Sabbia%4.<br/>%2Segui le istruzioni sullo schermo per il piazzamento. + %3모래주머니%4는 튼튼한 재료로 만든 주머니로 모래를 채워 장벽을 만들거나 건설 작업에서 안정성을 제공하는 등 다양한 용도로 사용되며, 더 큰 요새를 확장하는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3모래주머니(비어있음)%4을 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3모래주머니 배치%4를 선택하십시오.<br/>%2화면의 지시에 따라 배치하십시오. + %3土のう%4は、砂が詰められた頑丈な素材で作られた袋で、建設プロジェクトでの障壁の作成や安定性の提供など、さまざまな目的に使用されます。より大きな配置の要塞を拡張するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3土のう (空)%4を装備します。<br/>%2[%3%12%4] を使って%3土のうを作る%4を選択します。<br/>%2画面上の指示に従って配置します。 + Los %3Sacos de tierra%4 son sacos hechos de un material resistente, rellenados de tierra, usados para una diversa variedad de propósitos como la construcción de barreras o proveer estabilidad en los proyectos de construcción. Son útiles en la expansión de proyectos de construcción más grandes.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Saco de tierra (Vacío)%4.<br/>%2Usar [%3%12%4] y seleccionar %3Desplegar Saco de tierra%4.<br/>%2Seguir las instrucciones en pantalla para su colocación. + + + Lower Firearm Temperature + Niższa Temperatura twojej Broni + Raffredda l'Arma + 총기의 온도를 낮춥니다 + 銃の熱を冷ます + Понизьте температуру оружия + Refroidir l'arme + Bajar la Temperatura del Arma + + + %3Spare Barrels%4 allow a soldier to reduce their weapon's heat significantly. After a short delay, the weapon's barrel will be swapped and its heat reduced. A soldier may also check the temperature of any barrels within their inventory. Not all weapons support swapping barrels.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Swap Barrel%4.<br/>%2Resume operation after barrel swap is complete. + %3Zapasowa Lufa%4 pozwala żołnierzowi znacznie zmniejszyć ciepło broni. Po krótkim czasie lufa broni zostanie zamieniona, a jej temperatura zostanie zmniejszona. Żołnierz może również sprawdzić temperaturę każdej lufy w swoim ekwipunku. Nie wszystkie bronie obsługują zamianę luf.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Zmień Lufę%4.<br/>%2. + %3Canne di Ricambio%4 permettono ai soldati di raffreddare la loro arma notevolmente. Dopo una breve attesa, la canna dell'arma verrà sostituita e la temperatura ridotta. Un soldato può anche controllare la temperatura di canne di ricambio presenti nel proprio inventario. Non tutte le armi consentono lo scambio canna.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Sostituisci Canna%4.<br/>%2Continua l'ingaggio dopo sostituzione avvenuta. + %3예비 총열%4을 사용하면 병사의 무기의 발열을 크게 줄일 수 있습니다. 잠시 뒤에 무기의 총신이 교체되고 발열이 감소합니다. 군인은 소지품에 있는 총열의 온도도 확인할 수 있습니다. 모든 무기가 총열 교환을 지원하는 것은 아닙니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3총열 교체%4를 선택하십시오.<br/>%2총열 교체가 완료된 후 작전을 계속하십시오. + %3予備銃身%4を使用すると、兵士は武器の熱を大幅に下げることができます。少し経つと、武器の銃身が交換され熱が下がります。兵士はインベントリ内の銃身の温度を確認することもできます。すべての武器が銃身の交換をサポートしているわけではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3銃身を交換%4を選択します。<br/>%2銃身交換が完了すると、再度射撃することが出来ます。 + El %3Cañón de Repuesto%4 permite a un soldado reducir el calor del arma significativamente. Tras un pequeño periodo, el cañón del arma habrá sido sustituido y el calor reducido. Un soldado puede tambien comprobar la temperatura de cualquier cañón en su inventario. No todas las armas soportan el cambio de cañón.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Cambiar Cañón%4.<br/>%2Continuar con la operación una vez se haya cambiado el cañón. + + + Spray Paint + Farba w Sprayu + Bomboletta Spray + 스프레이 페인트 + ペイントスプレー + Аэрозольная краска + Bombe de peinture + Pintura En Spray + + + Tag Your Territory + Zaznacz Swój Teren + Marca il tuo territorio + 당신의 영역을 지정합니다 + 自分のテリトリーをマーキング + Пометьте свою территорию + Marquez votre territoire + Marca Tu Territorio + + + %3Spray Paint%4 is used to tag surfaces with various symbols.<br/><br/>%3Usage:%4<br/>%2Move close to a surface (wall, vehicle, ground, etc).<br/>%2Use [%3%12%4] and select %3Tag%4.<br/>%2Choose a symbol.<br/><br/>%3Available Colors:%4<br/>%2Black<br/>%2Blue<br/>%2Green<br/>%2Red + %3Farba w Sprayu%4 jest używana do oznaczania powierzchni różnymi symbolami.<br/><br/>%3Użycie:%4<br/>%2Podejdź blisko powierzchni (ściany, pojazdu, ziemi, etc). <br/>%2Użyj [%3%12%4] i wybierz %3Malowanie%4.<br/>%2Wybierz Symbol.<br/><br/>%3Dostępne Kolory:%4<br/>%2Czarny<br/>%2Niebieski<br/>%2Zielony<br/>%2Czerwony + %3Bombolette Spray%4 vengono usate per marcare superfici con vari simboli.<br/><br/>%3Utilizzo:%4<br/>%2Muoviti vicino a una superfice (muro, veicolo, suolo, etc).<br/>%2Usa [%3%12%4] e seleziona %3Marca%4.<br/>%2Seleziona un simbolo.<br/><br/>%3Colori disponibili:%4<br/>%2Nero<br/>%2Blu<br/>%2Verde<br/>%2Rosso + %3스프레이 페인트%4다양한 기호로 표면에 태그를 지정하는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2표면(벽, 차량, 지면 등)에 가까이 가십시오.<br/>%2[%3%12%4]를 사용하고 %3태그%4를 선택하십시오.<br/>%2모양을 고르십시오.<br/><br/>%3사용 가능 색상:%4<br/>%2검정<br/>%2파랑<br/>%2초록<br/>%2빨강 + %3ペイントスプレー%4は、地面や壁、車両の表面などに様々な図形のタグを付けるために使えます。<br/><br/>%3使用方法:%4<br/>%2塗りたい面に近づきます。(壁、車両、地面など)<br/>%2[%3%12%4] を使って%3タグ (スプレーペイント)%4を選択します。<br/>%2図形を選びます。<br/><br/>%3利用可能な色:%4<br/>%2黒<br/>%2白<br/>%2赤<br/>%2青<br/>%2緑<br/>%2黄 + La %3Pintura en Spray%4 se usa para marcar superficies con varios símbolos.<br/><br/>%3Uso:%4<br/>%2Acércate a una superficie (pared, vehículo, suelo, etc).<br/>%2Usar [%3%12%4] y seleccionar %3Tag%4.<br/>%2Elige un símbolo.<br/><br/>%3Colores disponibles:%4<br/>%2Negro<br/>%2Azul<br/>%2Verde<br/>%2Rojo + + + Brace From Anywhere + Zawsze Stabilny + Stabilizzati Ovunque + 어느 곳에나 지지대를 배치할 수 있습니다 + どこでも支持器 + Опора может быть установлена в любом месте + Stabilisé partout + Apoyarte En Cualquier Lugar + + + The %3SSWT Kit%4 is a deployable tripod that allows a soldier to brace their aim when deployed. Use it when you need an elevated shooting position and there are no other objects around.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3SSWT Kit%4 and follow the on screen prompts to place. + %3Trójnóg Snajperski%4 jest to rozkładany statyw, który pozwala żołnierzowi dokładnie przycelować, gdy jest rozłożony. Używaj go, gdy potrzebujesz stabilnej pozycji strzeleckiej, a wokół nie ma innych obiektów.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Trójnóg Snajperski%4 i podążaj za instrukcjami wyświetlanymi na ekranie. + Il %3Kit SSWT%4 è un treppiede piazzabile che permette al soldato di appoggiare la sua arma. Usalo quando ti serve una posizione di tiro rialzata e non ci sono altri oggetti utili nelle vicinanze.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Kit SSWT%4 e segui le indicazioni di piazzamento. + %3SSWT 키트%4는 병사가 배치 시 조준력을 상승시킬 수 있는 배치 가능한 삼각대입니다. 높이 조절이 된 사격 위치가 필요하고 주위에 다른 물체가 없을 때 사용하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4] 를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3SSWT 키트%4를 선택하고 화면의 지시에 따라 배치하십시오. + %3SSWT キット%4は展開可能な三脚で、展開時に兵士が狙いを定めることができます。高い射撃位置が必要で、周囲に他の物体がない場合に使用してください。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3SSWT キット%4を選択し、画面上の指示に従って配置します。 + El %3Kit SSWT%4 es un trípode desplegable que permite a un soldado apoyarse para apuntar cuando está desplegado. Úsalo cuando necesites una posición de tiro elevada y no hay ningún otro objeto alrededor.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Kit SSWT%4 y sigue las indicaciones en pantalla para colocarlo. + + + Keep Eyes In The Sky + Trzymaj Głowę w Górze + Tieni gli occhi nel cielo + 하늘에서 계속 내려다봅니다 + 空の目を維持する + Не Отрывай Глаз От Неба + Gardez les yeux au ciel + Gardez les yeux au ciel + Manten Tus Ojos En El Cielo + + + %3UAV Batteries%4 are used to recharge a UAV's energy storage. Especially useful for small UAVs.<br/><br/>%3Usage:%4<br/>%2Equip a %3UAV Battery%4<br/>%2Approach a %3UAV%4 with its %3Engine Off%4.<br/>%2Use [%3%13%4] and select %3Recharge%4. + %3Baterie UAV%4 są używane do zasilania UAV. Zwłaszcza tych małych.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Baterię UAV%4<br/>%2Podejdź pod %3UAV%4 z %3Wyłączonym Silnikiem%4.<br/>%2Użyj [%3%13%4] i wybierz %3Naładuj%4. + %3Batteria UAV%4 vengono usate per ricaricare gli UAV. Molto utile per piccoli UAV.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Batteria UAV%4<br/>%2Avvicinati al %3UAV%4 con il %3Motore Spento%4.<br/>%2Usa [%3%13%4] e seleziona %3Ricarica%4. + %3무인기 배터리%4는 무인기의 에너지 저장소를 재충전하는 데 사용됩니다. 소형 무인기에 특히 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3무인기 배터리%4를 장착하십시오.<br/>%2%3엔진을 끄고%4 %3무인기%4에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3재충전%4을 선택하십시오. + %3UAVバッテリー%4は、UAVの電源容量を充電するために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3UAV バッテリー%4を装備します。<br/>%2%3エンジンをオフ%4にした%3UAV%4に近づきます。<br/>%2[%3%13%4] を使って%3充電%4を選択します。 + La %3Batería de VANT%4 se utilizan para recargar el almacenamiento de energía de un VANT. Especialmente útiles para pequeños VANTs.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Batería de VANT%4<br/>%2Acércate a un %3VANT%4 con su %3Motor Apagado%4.<br/>%2Usa [%3%13%4] y selecciona %3Recargar%4. + + + Making An Entrance + Robienie Własnego Wejścia + Fai un'entrata + 진입로를 만듭니다 + 堂々入場する + Создание собственного входа + Faire son entrée + Abriendo Una Entrada + + + %3Wirecutters%4 are a tool that allows a soldier to bypass wired fencing. Useful for creating backdoor entrances into secure areas.<br/><br/>%3Usage:%4<br/>%2Move close to a fence.<br/>%2Use [%3%12%4] and select %3Cut Fence%4. + %3Nożyce do Cięcia Drutu%4 są narzędziem pozwalającym pokonywać zapory z siatki oraz drutu. Użyteczne przy tworzenia tylnego wejścia do pilnownej strefy.<br/><br/>%3Użycie:%4<br/>%2Podejdź pod ogrodzenie.<br/>%2Użyj[%3%12%4] i wybierz %3Przetnij Płot%4. + La %3Trancia%4 è un utensile che permette ai soldati di sorpassare filo spinato e recinzioni. Utile per creare punti di accesso nel retro di zone protette.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati a una barriera.<br/>%2Usa [%3%12%4] e seleziona %3Taglia%4. + %3절단기%4는 병사가 철조망을 통과할 수 있게 해주는 도구입니다. 보안 구역에 뒷입구를 만드는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2철조망에 가까이 가십시오.<br/>%2[%3%13%4]를 사용하고 %3철조망 자르기%4를 선택하십시오. + %3ワイヤーカッター%4は、兵士が有線フェンスを回避できるようにするツールです。安全にエリアへの裏口を作成するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2フェンスの近くに移動します。<br/>%2[%3%12%4] を使って%3フェンスを切断する%4を選択します。 + La %3Cizalla%4 es una herramienta que permite a un soldado atravesar una valla de alambre. Es útil para crear entradas traseras en áreas seguras.<br/><br/>%3Uso:%4<br/>%2Acércate a una valla.<br/>%2Usar [%3%12%4] y seleccionar %3Cortar Valla%4. + + + Items + 物品 + Objets + Objetos + Oggetti + Przedmioty + Предметы + Gegenstände + Předměty + Itens + 물품 + 物品 + アイテム + Eşyalar + + + ACE3 + ACE3 + ACE3 + ACE3 + ACE 3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + + + Build Fortifications + Budowanie Fortyfikacji + Costruisci Fortificazioni + 요새를 건설합니다 + 要塞を構築する + Стройте укрепления + Construire des fortifications + Construir Fortificaciones + + + The %3Fortify Tool%4 allows soldiers to build fortifications provided by their mission creator.<br/><br/>%3Usage:%4<br/>%2Pick up a %3Fortify Tool%4.<br/>%2Use [%3%12%4] and select %3Fortify%4.<br/>%2Select an available fortification and follow the on screen prompts for placement. + %3Narzędzie do fortyfikowania%4 pozwala żołnierzom budować fortyfikacje wybrane przez twórcę misji.<br/><br/>%3Użycie:%4<br/>%2Podnieś %3Narzędzie do fortyfikowania%4.<br/>%2Użyj [%3%12%4] i wybierz %3Fortyfikuj%4.<br/>%2Wybierz dostępną fortyfikację i postępuj zgodnie ze wskazówkami na ekranie. + L'%3Attrezzo di Fortificazione%4 permette ai soldati di costruire fortificazioni permesse dal creatore della missione.<br/><br/>%3Utilizzo:%4<br/>%2Raccogli un %3Attrezzo di Fortificazione%4.<br/>%2Usa [%3%12%4] e seleziona %3Fortifica%4.<br/>%2Seleziona una fortificazione disponibile e segui le indicazioni di piazzamento sullo schermo. + %3요새화 도구%4를 사용하면 병사들이 임무 생성자가 제공한 요새를 구축할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3요새화 도구%4를 가지십시오.<br/>%2[%3%12%4]를 사용하고 %3요새화%4를 선택하십시오.<br/>%2사용 가능한 요새를 선택하고 화면의 지시에 따라 배치하십시오. + %3要塞ツール%4を使用すると、兵士はミッション作成者が提供した要塞を構築できます。<br/><br/>%3使用方法:%4<br/>%2%3要塞ツール%4を持つ。<br/>%2[%3%12%4] を使って%3要塞%4を選択します。<br/>%2利用可能な構造物を選択し、画面上の指示に従って配置します。 + La %3Herramienta de Fortificación%4 permite a los soldados construir fortificaciones provistas por su creador de mision.<br/><br/>%3Uso:%4<br/>%2Coge una %3Herramienta de Fortificación%4.<br/>%2Usar [%3%12%4] y seleccionar %3Fortificar%4.<br/>%2Selecciona una fortificación disponible y sigue las instrucciones en pantalla para su colocación. + + + Breaking and Entering + Włamywanie i Otwieranie + Effrazione + 침입용 도구입니다 + 破壊して乗り込む + Взлом и проникновение + Entrée par effraction + Romper y Entrar + + + %3Lockpicks%4 are used to gain access to locked vehicles.<br/><br/>%3Usage:%4<br/>%2Equip a %3Lockpick%4.<br/>%2Approach a %3Locked%4 vehicle.<br/>Use [%3%13%4] and select %3Lockpick Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. + %3Wytrychy%4 są używane w celu uzyskania dostępu do zablokowanych pojazdów.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Wytrych%4.<br/>%2Podejdź do %3Zablokowanego%4 pojazdu. <br/>Użyj [%3%13%4] i wybierz %3Otwórz Zamek%4.<br/><br/><t underline='1'>%3Uwaga:%4</t> Klucze i wytrychy są dostępne tylko przy zastosowaniu skryptów lub użyciu modułu ACE Zamknięcie Pojazdu + I %3Grimaldelli%4 sono usati per forzare l'accesso a veicoli bloccati.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Grimaldello%4.<br/>%2Avvicinati a un veicolo %3Bloccato%4 vehicle.<br/>Usa [%3%13%4] e seleziona %3Scassina Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo reperibili mediante scripting o moduli ACE di assegnazione Chiavi Veicoli. + %3해정도구%4는 잠긴 차량에 들어가는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3해정도구%4를 장착하십시오.<br/>%2%3잠긴%4 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. + %3Lockpick%4は、ロックされた車両にアクセスするために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3Lockpick%4を装備します。<br/>%2%3鍵の掛かった%4車両に近づきます。<br/>[%3%13%4] を使って%3鍵をこじ開ける%4を選択します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + La %3Ganzúa%4 es usada para lograr acceso a vehículos bloqueados.<br/><br/>%3Uso:%4<br/>%2Equipar %3Ganzúa%4.<br/>%2Acércate a un vehículo %3Bloqueado%4.<br/>Usar [%3%13%4] y seleccionar %3Ganzuar Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t>Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE. + + + Vehicle Keys + Kluczyki od Pojazdu + Chiavi dei Veicoli + 차량 열쇠 + 車両キー + Взлом и проникновение + Clés de véhicule + Llaves de Vehículos + + + Lock/Unlock Vehicles + Zablokuj/Odblokuj Pojazdy + Blocco/Sblocco di Veicoli + 차량을 잠그거나 해제합니다 + 車両のロック/ロック解除 + Взлом и проникновение + Verrouiller/déverrouiller un véhicule + Bloquear/Desbloquear vehículos + + + %3Vehicle Keys%4 are used to lock/unlock your vehicles. Vehicle keys can exist for the whole side, or keys can be created for a particular vehicle itself.<br/><br/>%3Usage:%4<br/>%2Equip a %3Vehicle Key%4.<br/>%2Approach the vehicle that the key belongs to.<br/>Use [%3%13%4] and select %3Lock/Unlock Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. + %3Kluczyki od Pojazdów%4 są używane w celu ich zablokowania/odblokowania. Kluczyki mogą istnieć dla całej strony, lub być tworzone tylko dla wybranych pojazdów<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Kluczyk do Pojazdu%4.<br/>%2Podejdź do samochodu, do którego pasuje kluczyk. <br/>Użyj [%3%13%4] i wybierz %3Zablokuj/Odblokuj Pojazd%4.<br/><br/><t underline='1'>%3Uwaga:%4</t> Klucze i wytrychy są dostępne tylko przy zastosowaniu skryptów lub użyciu modułu ACE Zamknięcie Pojazdu + Le %3Chiavi di Veicoli%4 vengono usate per bloccare/sbloccare i propri veicoli. Chiavi di veicoli possono esistere per un'intera fazione, oppure per un veicolo particolare.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Chiave di Veicolo%4.<br/>%2Avvicinati al veicolo a cui appartiene la chiave.<br/>Usa [%3%13%4] e seleziona %3Blocca/Sblocca Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo disponibili mediante scripting o moduli ACE Chiavi Veicoli. + %3차량 열쇠%4는 차량을 잠그거나 잠금해제하는 데 사용됩니다. 차량 열쇠는 모든 세력에게 존재할 수도 있고, 특정 차량 자체에 대해 열쇠를 생성할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3차량 열쇠%4를 장착하십시오.<br/>%2해당 열쇠에 속한 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금/잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. + %3Vehicle Key%4は、車両のロック/ロック解除に使用されます。車両キーは陣営全体に存在することも、特定の車両だけに対してキーを作成することもできます。<br/><br/>%3使用方法:%4<br/>%2%3Vehicle Key%4を装備します。<br/>%2鍵の対応している車両に近づきます。<br/>[%3%13%4] を使って%3鍵を解錠/施錠%4します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + Las %3Llaves de Vehículos%4 son usadas para bloquear/desbloquear tus vehículos. Las Llaves de Vehículos existen para un bando entero o para un vehículo concreto.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Llave de Vehículo%4.<br/>%2Acércate a un vehículo cuya llave corresponda.<br/>Usar [%3%13%4] y selecciona %3Bloquear/Desbloquear Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t> Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE + + + diff --git a/addons/finger/ACE_Settings.hpp b/addons/finger/ACE_Settings.hpp index c28b33dd74..a8c52e69ee 100644 --- a/addons/finger/ACE_Settings.hpp +++ b/addons/finger/ACE_Settings.hpp @@ -1,32 +1,14 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(DisplayName); - value = 0; - typeName = "BOOL"; - displayName = CSTRING(enabled_displayName); + movedToSQF = 1; }; class GVAR(maxRange) { - category = CSTRING(DisplayName); - value = 4; - typeName = "SCALAR"; - displayName = CSTRING(maxRange_displayName); - description = CSTRING(maxRange_description); - sliderSettings[] = {0, 50, 4, 1}; + movedToSQF = 1; }; class GVAR(indicatorForSelf) { - category = CSTRING(DisplayName); - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(indicatorForSelf_name); - description = CSTRING(indicatorForSelf_description); + movedToSQF = 1; }; class GVAR(indicatorColor) { - category = CSTRING(DisplayName); - value[] = {0.83, 0.68, 0.21, 0.75}; - typeName = "COLOR"; - isClientSettable = 1; - displayName = CSTRING(indicatorColor_name); - description = CSTRING(indicatorColor_description); + movedToSQF = 1; }; }; diff --git a/addons/finger/CfgEventHandlers.hpp b/addons/finger/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/finger/CfgEventHandlers.hpp +++ b/addons/finger/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/finger/README.md b/addons/finger/README.md index 6c5d55b7aa..bfd4ab4153 100644 --- a/addons/finger/README.md +++ b/addons/finger/README.md @@ -2,11 +2,3 @@ ace_finger =========== Allows players to point and show a virtual spot in the distance to nearby players. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Drill](https://github.com/TheDrill/) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/finger/XEH_postInit.sqf b/addons/finger/XEH_postInit.sqf index ba4e5a99fc..6a44a5ae79 100644 --- a/addons/finger/XEH_postInit.sqf +++ b/addons/finger/XEH_postInit.sqf @@ -2,16 +2,16 @@ if (!hasInterface) exitWith {}; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { //If not enabled, dont't bother adding eventhandler - TRACE_1("ace_settingsInitialized eh", GVAR(enabled)); + TRACE_1("CBA_settingsInitialized eh",GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; - + GVAR(lastFPTime) = -1; - GVAR(fingersHash) = [] call CBA_fnc_hashCreate; + GVAR(fingersHash) = createHashMap; GVAR(pfeh_id) = -1; - - [QGVAR(fingered), {_this call FUNC(incomingFinger)}] call CBA_fnc_addEventHandler; + + [QGVAR(fingered), LINKFUNC(incomingFinger)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; //Add Keybind: diff --git a/addons/finger/XEH_preInit.sqf b/addons/finger/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/finger/XEH_preInit.sqf +++ b/addons/finger/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/finger/functions/fnc_incomingFinger.sqf b/addons/finger/functions/fnc_incomingFinger.sqf index 4706798f40..4509a270db 100644 --- a/addons/finger/functions/fnc_incomingFinger.sqf +++ b/addons/finger/functions/fnc_incomingFinger.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: TheDrill, PabstMirror * Recieve an finger event, adds to the array (or updates if already present) and starts PFEH if not already running @@ -25,12 +25,12 @@ private _fingerPos = if (_sourceUnit == ACE_player) then { _fingerPosPrecise vectorAdd ([random (2 * FP_RANDOMIZATION_X) - FP_RANDOMIZATION_X, random (2 * FP_RANDOMIZATION_X) - FP_RANDOMIZATION_X, random (2 * FP_RANDOMIZATION_Y) - FP_RANDOMIZATION_Y] vectorMultiply _distance) }; -TRACE_3("incoming finger:", _sourceUnit, _fingerPosPrecise, _fingerPos); +TRACE_3("incoming finger:",_sourceUnit,_fingerPosPrecise,_fingerPos); -private _data = [diag_tickTime, _fingerPos, ([_sourceUnit, false, true] call EFUNC(common,getName))]; -[GVAR(fingersHash), _sourceUnit, _data] call CBA_fnc_hashSet; +private _data = [diag_tickTime, _fingerPos, ([_sourceUnit, false, true] call EFUNC(common,getName)), _sourceUnit]; +GVAR(fingersHash) set [hashValue _sourceUnit, _data]; if (GVAR(pfeh_id) == -1) then { GVAR(pfeh_id) = [DFUNC(perFrameEH), 0, []] call CBA_fnc_addPerFrameHandler; - TRACE_1("Started PFEH", GVAR(pfeh_id)); + TRACE_1("Started PFEH",GVAR(pfeh_id)); }; diff --git a/addons/finger/functions/fnc_keyPress.sqf b/addons/finger/functions/fnc_keyPress.sqf index 5308c44e6c..2445986d15 100644 --- a/addons/finger/functions/fnc_keyPress.sqf +++ b/addons/finger/functions/fnc_keyPress.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: TheDrill, PabstMirror * On keypress, point and send position to nearby players @@ -32,7 +32,7 @@ GVAR(lastFPTime) = diag_tickTime; private _originASL = AGLtoASL positionCameraToWorld [0, 0, 0]; private _fingerPosASL = AGLtoASL positionCameraToWorld [0, 0, FP_DISTANCE]; private _intersections = lineIntersectsSurfaces [_originASL, _fingerPosASL, ACE_player, vehicle ACE_player, true, 1]; -if !(_intersections isEqualTo []) then { +if (_intersections isNotEqualTo []) then { _fingerPosASL = _intersections select 0 select 0; }; @@ -42,19 +42,18 @@ private _sendFingerToPlayers = []; private _nearbyMen = (ACE_player nearObjects ["CAManBase", (GVAR(maxRange) + 2)]); { _nearbyMen append (crew _x); -} count (ACE_player nearObjects ["StaticWeapon", (GVAR(maxRange) + 2)]); +} forEach (ACE_player nearObjects ["StaticWeapon", (GVAR(maxRange) + 2)]); { if ((((eyePos _x) vectorDistance _playerEyePosASL) < GVAR(maxRange)) && {alive _x} && {(_x == (vehicle _x)) || {(vehicle _x) isKindOf "StaticWeapon"}} && {GVAR(indicatorForSelf) || {_x != ACE_player}} && - {!(lineIntersects [(eyePos _x), _playerEyePosASL, vehicle ACE_player, vehicle _x])} && + {((lineIntersectsSurfaces [(eyePos _x), _playerEyePosASL, vehicle ACE_player, vehicle _x]) isEqualTo [])} && {[_x] call EFUNC(common,isPlayer)}) then { _sendFingerToPlayers pushBack _x; }; - true -} count _nearbyMen; +} forEach _nearbyMen; TRACE_1("sending finger to",_sendFingerToPlayers); diff --git a/addons/finger/functions/fnc_moduleSettings.sqf b/addons/finger/functions/fnc_moduleSettings.sqf index 7dd93ee7ae..be6821768d 100644 --- a/addons/finger/functions/fnc_moduleSettings.sqf +++ b/addons/finger/functions/fnc_moduleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Module for fingering settings diff --git a/addons/finger/functions/fnc_perFrameEH.sqf b/addons/finger/functions/fnc_perFrameEH.sqf index bfb9995720..4af4f6b643 100644 --- a/addons/finger/functions/fnc_perFrameEH.sqf +++ b/addons/finger/functions/fnc_perFrameEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: TheDrill, PabstMirror * The perFrameEventHandler to draw the icons @@ -15,31 +15,36 @@ * Public: No */ -if (!alive ACE_player) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; +if (!alive ACE_player) then {GVAR(fingersHash) = createHashMap}; // Conditions: canInteract -if !([ACE_player, ACE_player, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; +if !([ACE_player, ACE_player, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) then {GVAR(fingersHash) = createHashMap}; // Make sure player is dismounted or in a static weapon: -if ((ACE_player != vehicle ACE_player) && {!((vehicle ACE_player) isKindOf "StaticWeapon")}) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; +if ((ACE_player != vehicle ACE_player) && {!((vehicle ACE_player) isKindOf "StaticWeapon")}) then {GVAR(fingersHash) = createHashMap}; -private _iconSize = BASE_SIZE * 0.10713 * (call EFUNC(common,getZoom)); +private _iconBaseSize = GVAR(sizeCoef) * BASE_SIZE * 0.10713 * (call EFUNC(common,getZoom)); -[+GVAR(fingersHash), { - //IGNORE_PRIVATE_WARNING ["_key", "_value"]; - _value params ["_lastTime", "_pos", "_name"]; +{ + //IGNORE_PRIVATE_WARNING ["_x", "_y"]; + _y params ["_lastTime", "_pos", "_name", "_sourceUnit"]; private _timeLeftToShow = _lastTime + FP_TIMEOUT - diag_tickTime; if (_timeLeftToShow <= 0) then { - [GVAR(fingersHash), _key] call CBA_fnc_hashRem; + GVAR(fingersHash) deleteAt _x; } else { private _drawColor = + GVAR(indicatorColor); // Fade out: _drawColor set [3, ((_drawColor select 3) * ((_timeLeftToShow min 0.5) / 0.5))]; + private _iconSize = _iconBaseSize; + if (GVAR(proximityScaling)) then { + _iconSize = _iconSize * linearConversion [0, GVAR(maxRange), (getPosASL ACE_player) vectorDistance (getPosASL _sourceUnit), 0.25, 2, true]; + }; + drawIcon3D [QPATHTOF(UI\fp_icon2.paa), _drawColor, ASLtoAGL _pos, _iconSize, _iconSize, 0, _name, 1, 0.03, "RobotoCondensed"]; }; -}] call CBA_fnc_hashEachPair; +} forEach GVAR(fingersHash); -if ((GVAR(fingersHash) select 1) isEqualTo []) then { - TRACE_1("Ending PFEH", GVAR(pfeh_id)); +if (GVAR(fingersHash) isEqualTo createHashMap) then { + TRACE_1("Ending PFEH",GVAR(pfeh_id)); [GVAR(pfeh_id)] call CBA_fnc_removePerFrameHandler; GVAR(pfeh_id) = -1; }; diff --git a/addons/finger/functions/script_component.hpp b/addons/finger/functions/script_component.hpp deleted file mode 100644 index 4d3625f072..0000000000 --- a/addons/finger/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\finger\script_component.hpp" \ No newline at end of file diff --git a/addons/finger/initSettings.inc.sqf b/addons/finger/initSettings.inc.sqf new file mode 100644 index 0000000000..79c129bc46 --- /dev/null +++ b/addons/finger/initSettings.inc.sqf @@ -0,0 +1,49 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_displayName), LSTRING(enabled_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(maxRange), "SLIDER", + [LSTRING(maxRange_displayName), LSTRING(maxRange_description)], + _category, + [0, 50, 4, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(sizeCoef), "SLIDER", + [LSTRING(sizeCoef_displayName), LSTRING(sizeCoef_description)], + _category, + [0.1, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(proximityScaling), "CHECKBOX", + [LSTRING(proximityScaling_displayName), LSTRING(proximityScaling_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(indicatorForSelf), "CHECKBOX", + [LSTRING(indicatorForSelf_name), LSTRING(indicatorForSelf_description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(indicatorColor), "COLOR", + [LSTRING(indicatorColor_name), LSTRING(indicatorColor_description)], + _category, + [0.83, 0.68, 0.21, 0.75], + 0 +] call CBA_fnc_addSetting; diff --git a/addons/finger/stringtable.xml b/addons/finger/stringtable.xml index e7edbdac91..bdb0c835b6 100644 --- a/addons/finger/stringtable.xml +++ b/addons/finger/stringtable.xml @@ -1,131 +1,23 @@ - - + + Pointing Fingerzeig Puntamento 指向指示器 - 指向标记器 + 指向标记 指差し 가리키기 - Pointage + Pointage du doigt Wskazywanie Указание пальцем + Apontando + Ukazování + Señalando + Işaretleme - - Show pointing indicator to self - Zeigersymbol einem selbst anzeigen - Индикатор пальца для показывающего - Afficher un indicateur de pointage à soi-même - Pokaż indykator wskazywania palcem dla siebie - Saját mutatási indikátor megjelenítése - Mostrar indicador para si mesmo - Mostrar el indicador de señalado a uno mismo - Zobrazit ukázání směru pro sebe - Mostra puntatore per te stesso - 自分に指差し表記を表示する - 자신이 가리키는곳을 보여줍니다 - 在自己身边显示指向标记 - 顯示指向指示器給自己 - - - Render the indicator for the pointing player. This option doesn't affect whether the other players would see the indicator - Zeigt das eigene Zeigersymbol an. Diese Einstellung beeinflusst jedoch nicht andere Spieler, welche das Zeigersymbol sehen können. - Отображать индикатор указания пальцем для показывающего игрока. Эта настройка не влияет на то, будут ли другие игроки видеть индикатор - Affiche l'indicateur pour le joueur qui pointe. Cette option n'affecte pas les autres joueurs - Wyświetl indykator kiedy wskazujesz coś palcem. Ta opcja nie wpływa na to, czy inni gracze zobaczą ten indykator czy też nie. - Az indikátor megjelenítése a mutató játékosnak. Ez a beállítás nem változtat azon, hogy más játékosok látják-e az indikátort. - Renderizar o indicador para o jogador que está apontando. Esta opção não afeta se os outros jogadores verão ou não o indicador - Muestra el indicador para el jugador que apunta. Esta opción no afecta si los otros jugadores verían el indicador - Zobrazit infikátor, když ukážete prstem. Tato volba nemá vliv, zda ostatní hráči uvidí indikátor nebo ne. - Mostra puntatore per il giocatore indicato. Questa opzione non influisce la possibilità che gli altri giocatori vedano il puntatore - プレイヤーへ指差し表記を描画します。これは他のプレイヤーの表記に影響しません。 - 대상이 가리키는곳을 보이게 합니다. - 显示指向标记给玩家自己。此选项设定并不影响其他玩家能否看到指示标记 - 顯示指向指示器給玩家自己。此選項設定並不影響其他玩家能否看到指示器 - - - Pointing indicator - Zeigersymbol - Индикатор указания пальцем - Indicateur de pointage - Indykator palca - Ujj-indikátor - Indicador de apontamento - Indicador de señalado - Ukazování směru - Indicatore di puntamento - 指差し表記 - 가리키기 표시기 - 指向标记 - 指向指示器 - - - Color of the pointing indicator circle - Farbe des Zeigersymbols - Цвет индикатора указания пальцем - Couleur du cercle de l'indicateur de pointage - Kolor okręgu wyświetlanego przy wskazywaniu palcem - Mutatási indikátor körének színe - Cor do círculo de indicação - Color del círculo indicador que señala - Barva kruhu pro ukázání směru - Colore del cerchio dell'indicatore di puntamento - 指差し表記の円の色 - 가리키기의 원형 색상 - 指向标记颜色 - 指向指示器顏色 - - - Action "point a finger at" - Aktion: "Zeige Finger auf" - Действие "показать пальцем на" - Action 'Pointer du doigt" - Akcja "wskaż palcem" - Cselekvés "ujj rámutatása" - Ação "Apontar um dedo para" - Acción "apuntar con el dedo a" - Akce "ukázat prstem na" - Azione "punta il dito a" - "指差し"キー - "손가락으로 가리키기"행동 - 使"手指指向在" - 使"手指指向在" - - - Points, and shows a virtual marker of where you are looking to nearby units. Can be held down. - Zeigt in der Nähe befindlichen Spielern die eigene Blickrichtung mit Hilfe eines Kreissymbols an. - Montre, et affiche un marqueur virtuel là ou vous regardez aux unités proches. Peut être maintenu. - Wskazuje a także wyświetla wirtualny marker-okrąg w miejscu, w które patrzysz, dla wszystkich pobliskich jednostek. Może być przytrzymywany. - Mutat, és elhelyez egy virtuális jelölőt a nézett területhez közeli egységekhez. Lenyomva tartható. - Aponta e mostra um marcador virtual para onde você está olhando para unidades próximas. Pode ser utilizado para baixo. - Показывает пальцем и рисует виртуальный маркер в направлении взгляда ближайшим игрокам. Можно удерживать. - Señala y muestra un marcador virtual donde ustás apuntando para las unidades cercanas. Puede ser mantenido. - Ukazuje virtuální značku kruhu ve směru, kterým se díváte pro všechny blízké jednotky. - Punta e mostra un marker virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. - 指差し表記は自ユニットの近くにいる人のみに表記されます。また押しっぱなしにできます。 - 당신이 보는것을 가상의 마커로 표시함으로서 다른 인원이 볼 수 있게 합니다. 누른채로 유지할 수 있습니다. - 当按下此按键后,你附近的单位即可看见一个虚拟图示,标明你正在指向的位置。此按键可以被按住来持续显示。 - 當按下此按鍵後,你附近的單位即可看見一個虛擬圖示,標明你正在指向的位置。此按鍵可以被按住來持續顯示。 - - - Pointing Settings - Zeigen Einstellungen - Options de pointage - Ustawienia wskazywania palcem - Ujj beállításai - Preferências de apontamento - Настройки указания пальцем - Ajustes de señalado - Nastavení ukázování směru - Impostazioni puntamento - 指差し設定 - 가리키기 설정 - 指向设定 - 指向設定 - - + Pointing Enabled Zeigen aktiviert Pointage activé @@ -133,18 +25,36 @@ Mutatás engedélyezése Apontamento ativado Указание пальцем включено - Señalado habilitado Ukazování povoleno Puntamento abilitato 指差しを有効 가리키기 활성화 - 指向系统启动 + 启用指向系统 指向系統啟動 + Señalado permitido + Işaretleme Etkin - + + Points, and shows a virtual marker of where you are looking to nearby units. Can be held down. + Zeigt in der Nähe befindlichen Spielern die eigene Blickrichtung mit Hilfe eines Kreissymbols an. + Permet d'effectuer un pointage du doigt, ce qui a pour effet d'afficher sur l'écran des joueurs alliés proches un marqueur virtuel, indiquant la direction dans laquelle vous regardez. Peut être maintenu. + Wskazuje a także wyświetla wirtualny znacznik - okrąg w miejscu, w które patrzysz, dla wszystkich pobliskich jednostek. Może być przytrzymywany. + Mutat, és elhelyez egy virtuális jelölőt a nézett területhez közeli egységekhez. Lenyomva tartható. + Aponta e mostra um marcador virtual para onde você está olhando para unidades próximas. Pode ser utilizado para baixo. + Показывает пальцем и рисует виртуальный маркер в направлении взгляда ближайшим игрокам. Можно удерживать. + Señala y muestra un marcador virtual donde ustás apuntando para las unidades cercanas. Puede ser mantenido. + Ukazuje virtuální značku kruhu ve směru, kterým se díváte pro všechny blízké jednotky. + Punta e mostra un indicatore virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. + 近くのユニットに対して、今見ている場所に向けて指を差し、仮想のマーカーを表示して指示することが出来る。 押し続けることも可能。 + 당신이 보는 것을 가상의 마커로 표시함으로서 다른 인원이 볼 수 있게 합니다. 누른 채로 유지할 수 있습니다. + 当按下此按键后,你附近的单位即可看见一个虚拟图示,标明你正在指向的位置。此按键可以被按住来持续显示。 + 當按下此按鍵後,你附近的單位即可看見一個虛擬圖示,標明你正在指向的位置。此按鍵可以被按住來持續顯示。 + Işaretleyince nereye baktığınıza dair sanal bir daire gösterir. Basılı da tutulabilir. + + Pointing Max Range Maximale Zeigerreichweite - Distance maximale de pointage + Portée maximale du pointage Maks. zasięg wskazywania Ujj maximum hatótávja Distância máxima do apontamento @@ -156,22 +66,195 @@ 가리키기 최대 범위 指向标记最大显示距离 指向指示器最大顯示距離 + Işaretleme maksimum uzaklığı - + Max range between players to show the pointing indicator [default: 4 meters] Maximale Reichweite zwischen Spielern, welche das Zeigesymbol des jeweils anderen sehen können. (Standard: 4 Meter). - Distance maximale entre joueurs pour afficher l'indicateur (défaut: 4 mètres) + Définit le rayon au-delà duquel les joueurs ne verront plus l'indicateur de pointage de leurs alliés. Valeur par défaut : 4 mètres. Określ dystans na jakim można wskazywać coś palcem innym graczom. [domyślnie: 4m] A maximális távolság, amelyben a közeli játékosoknak megjelenik az indikátor. [alapértelmezett: 4 méter] Distância máxima entre jogadores para mostrar o apontamento [padrão: 4 metros] - Максимальная дальность между игроками для отображения индикатора указания пальцем [по-умолчанию: 4 метра] + Максимальная дальность между игроками для отображения индикатора указания пальцем [по умолчанию: 4 метра] Distancia máxima entre los jugadores para mostrar el indicador que señala [por defecto: 4 metros] Maximální vzdálenost mezi hráči pro ukázání směru [výchozí: 4 metry] - Distanza massima tra giocatori per mostrare l'indicatore di puntamento [default: 4 metri] - 指差し表記が他のプレイヤーに表示される範囲を決定できます。(標準 4 メートル) + Distanza massima tra giocatori per mostrare l'indicatore di puntamento [Predefinito: 4 metri] + 指差しのマーカー表示が他のプレイヤーに表示される最大範囲 [デフォルト: 4メートル] 플레이어 사이에서 가리키기 표시를 보이게 하는 최대거리를 설정합니다[기본설정: 4 미터] - 设定指向标记最大显示距离。[预设: 4公尺] + 设定指向标记最大显示距离。[预设:4米] 設定指向指示器最大顯示距離。[預設: 4公尺] + Hangi uzaklıktakilerin sanal daireyi görmesini seçin. [Varsayılan : 4 metre] + + + Visual Marker Size Coefficient + Visueller Markergrößenkoeffizient + Coefficiente di dimensione puntatore + 보이는 마커 크기 계수 + Współczynnik wielkości wirtualnego znacznika + 指差しマーカーの大きさ係数 + 屏幕标记大小系数 + Коэф. размера маркера + Coeficiente del tamaño del marcador visual + Coefficient taille des marqueurs visuels + Coeficiente de tamanho do marcador visual + + + Adjusts the size of the visual marker. + Passt die Größe der visuellen Markierung an. + Modifica la dimensione del puntatore virtuale. + 눈에 보이는 마커의 크기를 조정합니다. + Dostosowuje rozmiar wirtualnego znacznika. + 指差しマーカーの大きさを調整します。 + 调整屏幕上显示的标记大小 + Настраивает размер визуального маркера + Ajusta el tamaño del marcador visual. + Ajuste la taille des marqueurs visuels + Ajusta o tamanho do marcador visual + + + Proximity Scaling + Näherungsskalierung + Scalaggio di prossimità + 근접 스케일링 + Skalowanie odległościowe + 近接性スケーリング + 根据距离缩放 + Масштабирование от дальности + Escalado de cercanía + Mise à l'échelle + Escala por proximidade + + + Scales the size of the visual marker based on the distance between the player observing and the player pointing. + Skaliert die Größe der visuellen Markierung basierend auf der Entfernung zwischen dem beobachtenden Spieler und dem zeigenden Spieler. + Scala la dimensione del puntatore a seconda della distanza tra il giocatore osservatore e quello che punta. + 관찰하는 플레이어와 가리키는 플레이어 사이의 거리에 따라 보이는 마커의 크기를 조정합니다. + Skaluje rozmiar wirtualnego znacznika, na podstawie odległości między graczem obserwującym a graczem wskazującym. + 見ているプレーヤーと指差ししたプレーヤーの距離に基づいて、指差しマーカーの大きさを調整します。 + 根据观察的玩家和在指出方向的的玩家之间的距离调整视觉标记的大小。 + Масштабирует размер визуального маркера в зависимости от дальности от игрока до точки указания. + Escala el tamaño del marcador visual dependiendo de la distancia entre el jugador observador y el jugador que señala. + Modifie la taille du marqueur visuel en fonction de la distance entre le joueur qui observe et le joueur qui pointe. + Redimensiona o tamanho do marcador visual baseado na distância entre o jogador observador e o jogador que aponta. + + + Show pointing indicator to self + Zeigersymbol einem selbst anzeigen + Индикатор пальца для показывающего + Afficher son propre indicateur de pointage + Pokaż indykator wskazywania palcem dla siebie + Saját mutatási indikátor megjelenítése + Mostrar indicador para si mesmo + Mostrar el indicador de señalado a uno mismo + Zobrazit ukázání směru pro sebe + Mostra puntatore per te stesso + 指差しマーカーを自分で見る + 자신이 가리키는곳을 보여줍니다 + 在自己身边显示指向标记 + 顯示指向指示器給自己 + Sanal daireyi işaretleyen kişiye göster + + + Render the indicator for the pointing player. This option doesn't affect whether the other players would see the indicator + Zeigt das eigene Zeigersymbol an. Diese Einstellung beeinflusst jedoch nicht andere Spieler, welche das Zeigersymbol sehen können. + Отображать индикатор указания пальцем для показывающего игрока. Эта настройка не влияет на то, будут ли другие игроки видеть индикатор + Le joueur qui pointe du doigt voit son propre indicateur à l'écran. Cette option n'a aucune incidence sur ce que voient les autres joueurs. + Wyświetl indykator kiedy wskazujesz coś palcem. Ta opcja nie wpływa na to, czy inni gracze zobaczą ten indykator czy też nie. + Az indikátor megjelenítése a mutató játékosnak. Ez a beállítás nem változtat azon, hogy más játékosok látják-e az indikátort. + Renderizar o indicador para o jogador que está apontando. Esta opção não afeta se os outros jogadores verão ou não o indicador + Muestra el indicador para el jugador que apunta. Esta opción no afecta si los otros jugadores verían el indicador + Zobrazit infikátor, když ukážete prstem. Tato volba nemá vliv, zda ostatní hráči uvidí indikátor nebo ne. + Mostra indicatore per il giocatore che punta. Questa opzione non influisce sulla visibilità del puntatore per gli altri giocatori + 指差ししたプレーヤーが自身の指差しマーカーを描画して確認できるようにします。 このオプションは、他のプレイヤーが指差しマーカーを表示出来るかどうかには影響しません。 + 대상이 가리키는곳을 보이게 합니다. + 显示指向标记给玩家自己。此选项设定并不影响其他玩家能否看到指示标记 + 顯示指向指示器給玩家自己。此選項設定並不影響其他玩家能否看到指示器 + İşaret eden oyuncu için göstergeyi oluşturun. Bu seçenek, diğer oyuncuların göstergeyi görüp görmeyeceğini etkilemez + + + Pointing indicator + Zeigersymbol + Индикатор указания пальцем + Indicateur de pointage + Indykator palca + Ujj-indikátor + Indicador de apontamento + Indicador de señalado + Ukazování směru + Indicatore di puntamento + 指差しマーカー + 가리키기 표시기 + 指向标记 + 指向指示器 + Daire Rengi + + + Color of the pointing indicator circle + Farbe des Zeigersymbols + Цвет индикатора указания пальцем + Couleur et transparence du cercle indicateur de pointage. + Kolor okręgu wyświetlanego przy wskazywaniu palcem + Mutatási indikátor körének színe + Cor do círculo de indicação + Color del círculo indicador que señala + Barva kruhu pro ukázání směru + Colore del cerchio dell'indicatore di puntamento + 指差しマーカーの円の色 + 가리키기의 원형 색상 + 指向标记颜色 + 指向指示器顏色 + Sanal dairenin rengini belirleyin + + + Action "point a finger at" + Aktion: "Zeige Finger auf" + Действие "показать пальцем на" + Action "Pointer du doigt vers" + Akcja "wskaż palcem" + Cselekvés "ujj rámutatása" + Ação "Apontar um dedo para" + Acción "apuntar con el dedo a" + Akce "ukázat prstem na" + Azione "punta il dito a" + アクション "指を差す" + "손가락으로 가리키기" 행동 + 使"手指指向在" + 使"手指指向在" + Animasyon "Parmakla Gösterme" + + + Points, and shows a virtual marker of where you are looking to nearby units. Can be held down. + Zeigt in der Nähe befindlichen Spielern die eigene Blickrichtung mit Hilfe eines Kreissymbols an. + Effectue un pointage du doigt, et affiche sur l'écran des unités alliées proches un marqueur virtuel, indiquant la direction dans laquelle vous regardez. Peut être maintenu. + Wskazuje a także wyświetla wirtualny marker-okrąg w miejscu, w które patrzysz, dla wszystkich pobliskich jednostek. Może być przytrzymywany. + Mutat, és elhelyez egy virtuális jelölőt a nézett területhez közeli egységekhez. Lenyomva tartható. + Aponta e mostra um marcador virtual para onde você está olhando para unidades próximas. Pode ser utilizado para baixo. + Показывает пальцем и рисует виртуальный маркер в направлении взгляда ближайшим игрокам. Можно удерживать. + Señala y muestra un marcador virtual donde ustás apuntando para las unidades cercanas. Puede ser mantenido. + Ukazuje virtuální značku kruhu ve směru, kterým se díváte pro všechny blízké jednotky. + Punta e mostra un indicatore virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. + 近くのユニットに対して、今見ている場所に向けて指を差し、仮想のマーカーを表示して指示することが出来る。 押し続けることも可能。 + 당신이 보는 것을 가상의 마커로 표시함으로서 다른 인원이 볼 수 있게 합니다. 누른 채로 유지할 수 있습니다. + 当按下此按键后,你附近的单位即可看见一个虚拟图示,标明你正在指向的位置。此按键可以被按住来持续显示。 + 當按下此按鍵後,你附近的單位即可看見一個虛擬圖示,標明你正在指向的位置。此按鍵可以被按住來持續顯示。 + Işaretleyince nereye baktığınıza dair sanal bir daire gösterir. Basılı da tutulabilir. + + + Pointing Settings + Zeigen Einstellungen + Options de pointage + Ustawienia wskazywania palcem + Ujj beállításai + Preferências de apontamento + Настройки указания пальцем + Ajustes de señalado + Nastavení ukázování směru + Impostazioni Puntamento + 指差し設定 + 가리키기 설정 + 指向设定 + 指向設定 + Işaretleme Ayarları diff --git a/addons/fire/$PBOPREFIX$ b/addons/fire/$PBOPREFIX$ new file mode 100644 index 0000000000..ec282b453b --- /dev/null +++ b/addons/fire/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\fire diff --git a/addons/fire/ACE_Medical_Treatment_Actions.hpp b/addons/fire/ACE_Medical_Treatment_Actions.hpp new file mode 100644 index 0000000000..434a794fa7 --- /dev/null +++ b/addons/fire/ACE_Medical_Treatment_Actions.hpp @@ -0,0 +1,20 @@ +class EGVAR(medical_treatment,actions) { + class BasicBandage; + class PatDown: BasicBandage { + displayName = CSTRING(Actions_PatDown); + displayNameProgress = CSTRING(Actions_PerformingPatDown); + icon = ""; + category = "advanced"; + treatmentLocations = 0; + allowedSelections[] = {"All"}; + allowSelfTreatment = 1; + medicRequired = 0; + treatmentTime = 5; + items[] = {}; + condition = QFUNC(medical_canPatDown); + callbackSuccess = QFUNC(medical_success); + callbackProgress = QFUNC(medical_progress); + consumeItem = 0; + litter[] = {}; + }; +}; diff --git a/addons/fire/CfgEventHandlers.hpp b/addons/fire/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/fire/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/fire/CfgSounds.hpp b/addons/fire/CfgSounds.hpp new file mode 100644 index 0000000000..76fb0e64f7 --- /dev/null +++ b/addons/fire/CfgSounds.hpp @@ -0,0 +1,26 @@ +// weird ass concatenation syntax. PBO Project complains otherwise... +#define CONCAT(a,b) a####b +#define CREATE_SCREAM(no)\ +class GVAR(DOUBLES(scream,no)) {\ + name = QGVAR(CONCAT(scream,no));\ + sound[] = {QPATHTOF(CONCAT(sounds\scream,no).ogg), QUOTE(db+8), 1};\ + titles[] = {};\ +} + +class CfgSounds { + CREATE_SCREAM(1); + CREATE_SCREAM(2); + CREATE_SCREAM(3); + CREATE_SCREAM(4); + CREATE_SCREAM(5); + CREATE_SCREAM(6); + CREATE_SCREAM(7); + CREATE_SCREAM(8); + CREATE_SCREAM(9); + CREATE_SCREAM(10); + CREATE_SCREAM(11); + CREATE_SCREAM(12); + CREATE_SCREAM(13); + CREATE_SCREAM(14); + CREATE_SCREAM(15); +}; diff --git a/addons/fire/CfgVehicles.hpp b/addons/fire/CfgVehicles.hpp new file mode 100644 index 0000000000..0ed16faff7 --- /dev/null +++ b/addons/fire/CfgVehicles.hpp @@ -0,0 +1,7 @@ +class CfgVehicles { + class Static; + class GVAR(logic): Static { + scope = 1; + displayName = ""; + }; +}; diff --git a/addons/fire/RscTitles.hpp b/addons/fire/RscTitles.hpp new file mode 100644 index 0000000000..02ecd250e4 --- /dev/null +++ b/addons/fire/RscTitles.hpp @@ -0,0 +1,41 @@ +class RscTitles { + class RscPicture; + class GVAR(onFire1) { + idd = -1; + movingEnable = "true"; + duration = 0.1; + fadein = 0.15; + fadeout = 0.75; + name = QGVAR(onFire1); + onload = QUOTE(with uiNamespace do {GVAR(onFireIndicator1) = _this select 0}); + + class controls { + class GVAR(indicator): RscPicture { + idc = -1; + type = 0; + style = 48; + colorBackground[] = {0, 0, 0, 0}; + colorText[] = {0.9, 0.9, 0.9, 0.6}; + font = "LucidaConsoleB"; + sizeEx = 0.023; + x = "SafeZoneX"; + y = "SafeZoneY"; + w = "SafeZoneW + 0.05"; + h = "SafeZoneH + 0.05"; + text = QPATHTOF(data\overlay_burn_1.paa); + }; + }; + }; + + class GVAR(onFire2): GVAR(onFire1) { + idd = -1; + name = QGVAR(onFire2); + onload = QUOTE(with uiNamespace do {GVAR(onFireIndicator2) = _this select 0}); + + class controls: controls { + class GVAR(indicator): GVAR(indicator) { + text = QPATHTOF(data\overlay_burn_2.paa); + }; + }; + }; +}; diff --git a/addons/fire/XEH_PREP.hpp b/addons/fire/XEH_PREP.hpp new file mode 100644 index 0000000000..a352cdf2aa --- /dev/null +++ b/addons/fire/XEH_PREP.hpp @@ -0,0 +1,10 @@ +PREP(burn); +PREP(burnEffects); +PREP(burnIndicator); +PREP(burnReaction); +PREP(burnSimulation); +PREP(fireManagerPFH); +PREP(isBurning); +PREP(medical_canPatDown); +PREP(medical_progress); +PREP(medical_success); diff --git a/addons/fire/XEH_postInit.sqf b/addons/fire/XEH_postInit.sqf new file mode 100644 index 0000000000..641b74fffe --- /dev/null +++ b/addons/fire/XEH_postInit.sqf @@ -0,0 +1,89 @@ +#include "script_component.hpp" + +[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler; +[QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler; +[QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler; + +[QGVAR(playScream), { + params ["_scream", "_source"]; + + // Only play sound if enabled in settings and enabled for the unit + if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then { + _source say3D _scream; + }; +}] call CBA_fnc_addEventHandler; + +if (!isServer) exitWith {}; + +["CBA_settingsInitialized", { + TRACE_1("settingsInit",GVAR(enabled)); + + if (!GVAR(enabled)) exitWith {}; + + GVAR(fireSources) = createHashMap; + + [QGVAR(addFireSource), { + params [ + ["_source", objNull, [objNull, []]], + ["_radius", 0, [0]], + ["_intensity", 0, [0]], + ["_key", ""], + ["_condition", {true}, [{}]], + ["_conditionArgs", []] + ]; + + private _isObject = _source isEqualType objNull; + + // Check if the source is valid + if !(_isObject || {_source isEqualTypeParams [0, 0, 0]}) exitWith {}; + + if (_isObject && {isNull _source}) exitWith {}; + if (_radius == 0 || _intensity == 0) exitWith {}; + if (_key isEqualTo "") exitWith {}; // key can be many types + + // hashValue supports more types than hashmaps do by default, but not all (e.g. locations) + private _hashedKey = hashValue _key; + + if (isNil "_hashedKey") exitWith { + ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key); + }; + + // If a position is passed, create a static object at said position + private _sourcePos = if (_isObject) then { + getPosATL _source + } else { + ASLToATL _source + }; + + private _fireLogic = createVehicle [QGVAR(logic), _sourcePos, [], 0, "CAN_COLLIDE"]; + + // If an object was passed, attach logic to the object + if (_isObject) then { + _fireLogic attachTo [_source]; + }; + + // To avoid issues, remove existing entries first before overwriting + if (_hashedKey in GVAR(fireSources)) then { + [QGVAR(removeFireSource), _key] call CBA_fnc_localEvent; + }; + + GVAR(fireSources) set [_hashedKey, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]]; + }] call CBA_fnc_addEventHandler; + + [QGVAR(removeFireSource), { + params ["_key"]; + + private _hashedKey = hashValue _key; + + if (isNil "_hashedKey") exitWith { + ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key); + }; + + (GVAR(fireSources) deleteAt _hashedKey) params [["_fireLogic", objNull]]; + + detach _fireLogic; + deleteVehicle _fireLogic; + }] call CBA_fnc_addEventHandler; + + [LINKFUNC(fireManagerPFH), FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/fire/XEH_preInit.sqf b/addons/fire/XEH_preInit.sqf new file mode 100644 index 0000000000..894773534a --- /dev/null +++ b/addons/fire/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/fire/XEH_preStart.sqf b/addons/fire/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/fire/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/fire/addon.toml b/addons/fire/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/fire/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/fire/config.cpp b/addons/fire/config.cpp new file mode 100644 index 0000000000..df2eb5cb79 --- /dev/null +++ b/addons/fire/config.cpp @@ -0,0 +1,31 @@ +#include "script_component.hpp" + +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "ace_medical_engine"}; + author = ECSTRING(common,ACETeam); + authors[] = {"commy2", "tcvm"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgSounds.hpp" +#include "CfgVehicles.hpp" +#include "ACE_Medical_Treatment_Actions.hpp" +#include "RscTitles.hpp" + +#endif diff --git a/addons/fire/data/overlay_burn_1.paa b/addons/fire/data/overlay_burn_1.paa new file mode 100644 index 0000000000..d3871b4b7b Binary files /dev/null and b/addons/fire/data/overlay_burn_1.paa differ diff --git a/addons/fire/data/overlay_burn_2.paa b/addons/fire/data/overlay_burn_2.paa new file mode 100644 index 0000000000..7f87ec9458 Binary files /dev/null and b/addons/fire/data/overlay_burn_2.paa differ diff --git a/addons/fire/functions/fnc_burn.sqf b/addons/fire/functions/fnc_burn.sqf new file mode 100644 index 0000000000..1cf0fc6759 --- /dev/null +++ b/addons/fire/functions/fnc_burn.sqf @@ -0,0 +1,78 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Makes a unit catch fire. Only call from targeted events, is applied globally. + * + * Arguments: + * 0: Unit + * 1: Fire intensity + * 2: Fire instigator (default: objNull) + * + * Return Value: + * None + * + * Example: + * [player, 4] call ace_fire_fnc_burn + * + * Public: No + */ + +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(burn), _this]; +}; + +if (!GVAR(enabled)) exitWith {}; + +params ["_unit", "_intensity", ["_instigator", objNull]]; +TRACE_3("burn",_unit,_intensity,_instigator); + +if (BURN_MIN_INTENSITY > _intensity) exitWith { + TRACE_3("intensity is too low",_unit,_intensity,BURN_MIN_INTENSITY); +}; + +// Check if unit is remote (objNull is remote) +if (!local _unit) exitWith { + TRACE_1("unit is null or not local",_unit); +}; + +// Check if the unit can burn (takes care of spectators and curators) +if (getNumber (configOf _unit >> "isPlayableLogic") == 1 || {!(_unit isKindOf "CAManBase")}) exitWith { + TRACE_1("unit is virtual or not a man",_unit); +}; + +// If unit is invulnerable, don't burn the unit +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith { + TRACE_1("unit is invulnerable",_unit); +}; + +private _eyePos = eyePos _unit; + +// Check if unit is mostly submerged in water +if (surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}) exitWith { + TRACE_1("unit is in water",_unit); +}; + +// If unit is already burning, update intensity, but don't add another PFH +if (_unit call FUNC(isBurning)) exitWith { + // Only allow intensity to be increased + if (_intensity <= (_unit getVariable [QGVAR(intensity), 0])) exitWith { + TRACE_2("unit already burning, no intensity update",_unit,_intensity); + }; + + TRACE_2("unit already burning, updating intensity",_unit,_intensity); + + _unit setVariable [QGVAR(intensity), _intensity, true]; +}; + +TRACE_2("setting unit ablaze",_unit,_intensity); + +_unit setVariable [QGVAR(intensity), _intensity, true]; + +// Fire simulation (fire sources are handled differently) +[QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent; + +// Spawn effects for unit +private _burnEffectsJipID = [QGVAR(burnEffects), _unit] call CBA_fnc_globalEventJIP; +[_burnEffectsJipID, _unit] call CBA_fnc_removeGlobalEventJIP; + +_unit setVariable [QGVAR(jipID), _burnEffectsJipID, true]; diff --git a/addons/fire/functions/fnc_burnEffects.sqf b/addons/fire/functions/fnc_burnEffects.sqf new file mode 100644 index 0000000000..4dadda8526 --- /dev/null +++ b/addons/fire/functions/fnc_burnEffects.sqf @@ -0,0 +1,191 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawns particle effects for a burning unit. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_fire_fnc_burnEffects + * + * Public: No + */ + +params ["_unit"]; + +// Spawn particles +private _unitPos = getPos _unit; +private _fireParticle = objNull; +private _smokeParticle = objNull; +private _fireLight = objNull; +private _lightFlare = objNull; + +if (hasInterface) then { + _fireParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"]; + _fireParticle attachTo [_unit]; + _fireParticle setDropInterval 0.03; + + _smokeParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"]; + + _fireLight = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"]; + _fireLight setLightIntensity 0; + _fireLight setLightAmbient [0.8, 0.6, 0.2]; + _fireLight setLightColor [1, 0.5, 0.4]; + _fireLight attachTo [_unit]; + _fireLight setLightDayLight false; + + _lightFlare = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"]; + _lightFlare setLightIntensity 0; + _lightFlare setLightColor [1, 0.8, 0.8]; + _lightFlare setLightUseFlare true; + _lightFlare setLightFlareMaxDistance 100; + _lightFlare setLightFlareSize 0; + + if (_unit != ACE_player) then { + private _relativeAttachPoint = vectorNormalized (_unit worldToModelVisual (getPos ACE_player)); + _relativeAttachPoint set [2, 0.5]; + _lightFlare attachTo [_unit, _relativeAttachPoint]; + } else { + _lightFlare attachTo [_unit, [0, 0, 0.3]]; + }; +}; + +private _fireSound = objNull; + +if (isServer) then { + _fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0]; + _fireSound attachTo [_unit, [0, 0, 0], "Head"]; +}; + +[{ + params ["_args", "_pfhID"]; + _args params ["_unit", "_fireParticle", "_smokeParticle", "_fireLight", "_lightFlare", "_fireSound"]; + + if (isNull _unit || {!(_unit call FUNC(isBurning))}) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + deleteVehicle _fireParticle; + deleteVehicle _smokeParticle; + deleteVehicle _fireLight; + deleteVehicle _lightFlare; + deleteVehicle _fireSound; + }; + + // Display burn indicators + if (_unit == ACE_player && {alive _unit} && {isNil {_unit getVariable QGVAR(burnUIPFH)}}) then { // This accounts for player remote controlled a new unit + private _burnIndicatorPFH = [LINKFUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; + _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; + }; + + if (!hasInterface) exitWith {}; + + private _intensity = _unit getVariable [QGVAR(intensity), 0]; + + _fireParticle setDropInterval (0.01 max linearConversion [BURN_MAX_INTENSITY, BURN_MIN_INTENSITY, _intensity, 0.03, 0.1, false]); + _fireParticle setParticleParams [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32], // sprite sheet values + "", // animation name + "Billboard", // particle type + 1, // timer period + 0.7, // lifetime + "destructionEffect2", // position + [0, 0, 1], // move velocity + 0, // rotation velocity + 10, // weight + 7.9, // volume + 1, // rubbing + [0.3, 0.3], // size + [ + [1, 1, 1, -0], + [1, 1, 1, -1], + [1, 1, 1, -1], + [1, 1, 1, -1], + [1, 1, 1, -0] + ], // colour + [0.5, 1], // animation speed + 1, // random dir period + 0, // random dir intensity + "", // on timer script + "", // before destroy script + _unit, // particle source + 0, + false, + 0, + [[0.8, 0.6, 0.2, 1]] // emissive color + ]; + _fireParticle setParticleRandom [ + 0.04 * _intensity, // life time + [0.05, 0.05, 2], // position + [0.05, 0.05, 0.05] vectorMultiply _intensity, // move velocity + 0, // rotation velocity + 0.06 * _intensity, // size + [0, 0, 0, 0], // color + 0, // random direction period + 0 // random direction intensity + ]; + + _smokeParticle setDropInterval 0.15; + _smokeParticle setParticleCircle [0, [0, 0, 0]]; + _smokeParticle setParticleParams [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values + "", // animation name + "Billboard", // particle type + 1, // timer period + 8, // lifetime + [0, 0, 1.1], // position + [0, 0, 1], // move velocity + 0, // rotation velocity + 10, // weight + 7.9, // volume + 0.066, // rubbing + [1, 3, 6], // size + [ + [0.5, 0.5, 0.5, 0.15], + [0.75, 0.75, 0.75, 0.075], + [1, 1, 1, 0] + ], // colour + [0.125], // animation speed + 1, // random dir period + 0, // random dir intensity + "", // on timer script + "", // before destroy script + _unit // particle source + ]; + _smokeParticle setParticleRandom [ + 0, // life time + [0.25, 0.25, 0], // position + [0.2, 0.2, 0], // move velocity + 0, // rotation velocity + 0.25, // size + [0, 0, 0, 0.1], // color + 0, // random direction period + 0 // random direction intensity + ]; + + _fireLight setLightBrightness ((_intensity * 3) / 10); + _fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15]; + + _lightFlare setLightBrightness (_intensity / 30); + _lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER; + + if (!GVAR(enableFlare)) then { + _lightFlare setLightFlareSize 0; + }; + + // Always keep flare visible to perceiving unit as long as it isn't the player + if (_unit != ACE_player) then { + private _distanceToUnit = _unit distance ACE_player; + private _relativeAttachPoint = [0, 0, 0.3]; + + if (_distanceToUnit > 1.5) then { + _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ACE_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5]; + _relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)]; + }; + + _lightFlare attachTo [_unit, _relativeAttachPoint]; + }; +}, 0, [_unit, _fireParticle, _smokeParticle, _fireLight, _lightFlare, _fireSound]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fire/functions/fnc_burnIndicator.sqf b/addons/fire/functions/fnc_burnIndicator.sqf new file mode 100644 index 0000000000..5dbc1a8cbf --- /dev/null +++ b/addons/fire/functions/fnc_burnIndicator.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Run once per second in a PFH. Update screen effects with burn indicator. + * + * Arguments: + * 0: Unit on fire + * 1: PFH Handle + * + * Return Value: + * None + * + * Example: + * [player, _pfhID] call ace_fire_fnc_burnIndicator + * + * Public: No + */ + +params ["_unit", "_pfhID"]; + +if (!alive _unit || {!(_unit call FUNC(isBurning))}) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + _unit setVariable [QGVAR(burnUIPFH), nil]; +}; + +// Don't show burn overlay if unconscious or dead +if !(_unit call EFUNC(common,isAwake)) exitWith {}; + +private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0]; + +if (_iteration == 0) then { + QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"]; + _iteration = 1; +} else { + QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"]; + _iteration = 0; +}; + +_unit setVariable [QGVAR(indicatorIteration), _iteration]; diff --git a/addons/fire/functions/fnc_burnReaction.sqf b/addons/fire/functions/fnc_burnReaction.sqf new file mode 100644 index 0000000000..5a9b75d48c --- /dev/null +++ b/addons/fire/functions/fnc_burnReaction.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, veteran29 + * Handles burning reactions of an unit, like screaming or throwing the weapons away due to pain. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Public: No + */ + +params ["_unit"]; + +if ( + GVAR(dropWeapon) > 0 && + {isNull objectParent _unit} && + {(currentWeapon _unit) != ""} && + {!isPlayer _unit || GVAR(dropWeapon) == 2} +) then { + _unit call EFUNC(common,throwWeapon); +}; + +[QGVAR(playScream), [format [QGVAR(scream_%1), floor (1 + random 15)], _unit]] call CBA_fnc_globalEvent; diff --git a/addons/fire/functions/fnc_burnSimulation.sqf b/addons/fire/functions/fnc_burnSimulation.sqf new file mode 100644 index 0000000000..b50afab5dc --- /dev/null +++ b/addons/fire/functions/fnc_burnSimulation.sqf @@ -0,0 +1,167 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Simulates fire intensity over time on burning units. + * Arbitrary values to ignite people. Assumed maximum is "10". + * + * Arguments: + * 0: Unit + * 1: Instigator + * + * Return Value: + * None + * + * Example: + * [player, player] call ace_fire_fnc_burnSimulation + * + * Public: No + */ + +params ["_unit", "_instigator"]; + +[{ + params ["_args", "_pfhID"]; + _args params ["_unit", "_instigator"]; + + if (isNull _unit) exitWith { + TRACE_1("unit is null",_unit); + + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + // Locality has changed + if (!local _unit) exitWith { + TRACE_1("unit is no longer local",_unit); + + _pfhID call CBA_fnc_removePerFrameHandler; + + [QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent; + }; + + // If the unit is invulnerable, in water or if the fire has died out, stop burning the unit + if ( + !(_unit call FUNC(isBurning)) || + {!(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]})} || + {private _eyePos = eyePos _unit; surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}} + ) exitWith { + TRACE_3("unit is no longer burning, invulnerable or in water",_unit,_unit call FUNC(isBurning),isDamageAllowed _unit && {_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]}); + + // Remove global effects + (_unit getVariable [QGVAR(jipID), ""]) call CBA_fnc_removeGlobalEventJIP; + + // Update globally that the unit isn't burning anymore + _unit setVariable [QGVAR(intensity), nil, true]; + + _pfhID call CBA_fnc_removePerFrameHandler; + + if (!isNil {_unit getVariable QGVAR(stopDropRoll)} && {!isPlayer _unit}) then { + _unit setUnitPos "AUTO"; + + _unit setVariable [QGVAR(stopDropRoll), nil, true]; + }; + }; + + if (isGamePaused) exitWith {}; + + private _intensity = _unit getVariable [QGVAR(intensity), 0]; + + // Propagate fire to other units (alive or dead) if it's intense + if (_intensity >= BURN_THRESHOLD_INTENSE) then { + TRACE_2("check for other units",_unit,_intensity); + + { + private _distancePercent = 1 - ((_unit distance _x) / BURN_PROPAGATE_DISTANCE); + private _adjustedIntensity = _intensity * _distancePercent; + + // Don't burn if intensity is too low or already burning with higher intensity + if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then { + continue; + }; + + [QGVAR(burn), [_x, _adjustedIntensity, _instigator], _x] call CBA_fnc_targetEvent; + + TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity); + } forEach nearestObjects [_unit, ["CAManBase"], BURN_PROPAGATE_DISTANCE]; + }; + + // Update intensity/fire reactions + if (CBA_missionTime >= _unit getVariable [QGVAR(intensityUpdate), 0]) then { + TRACE_2("update intensity",_unit,_intensity); + + _unit setVariable [QGVAR(intensityUpdate), CBA_missionTime + INTENSITY_UPDATE]; + + _intensity = _intensity - INTENSITY_LOSS - (rain / 10); + + if (_unit call EFUNC(common,isAwake)) then { + if (_unit call EFUNC(common,isPlayer)) then { + // Decrease intensity of burn if rolling around + if ((animationState _unit) in PRONE_ROLLING_ANIMS) then { + _intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING; + }; + } else { + private _sdr = _unit getVariable [QGVAR(stopDropRoll), false]; + + private _vehicle = objectParent _unit; + + if (isNull _vehicle && {_sdr || {0.05 > random 1}}) then { + _unit setVariable [QGVAR(stopDropRoll), true, true]; + + if (!_sdr) then { + TRACE_1("stop, drop, roll!",_unit); + + _unit setUnitPos "DOWN"; + doStop _unit; + }; + + // Queue up a bunch of animations + for "_i" from 0 to 2 do { + [_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation); + }; + + _intensity = _intensity - (1 / _intensity); + } else { + // Make the unit leave the vehicle + if (_vehicle != _unit) then { + TRACE_1("Ejecting",_unit); + + _unit leaveVehicle _vehicle; + unassignVehicle _unit; + + _unit action ["Eject", _vehicle]; + }; + + _unit disableAI "TARGET"; + _unit disableAI "AUTOTARGET"; + + // Run away, erraticly + if (leader group _unit != _unit) then { + [_unit] join grpNull; + }; + + _unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]); + _unit setSpeedMode "FULL"; + _unit setSuppression 1; + }; + }; + + // Play screams and throw weapon (if enabled) + _unit call FUNC(burnReaction); + }; + + if (!isNull _instigator) then { + _unit setVariable [QEGVAR(medical,lastDamageSource), _instigator]; + _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; + }; + + // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ + private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; + + // Keep pain around unconciousness limit to allow for more fun interactions + private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)}); + + // Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive + [QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent; + + _unit setVariable [QGVAR(intensity), _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic + }; +}, BURN_PROPAGATE_UPDATE, [_unit, _instigator]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fire/functions/fnc_fireManagerPFH.sqf b/addons/fire/functions/fnc_fireManagerPFH.sqf new file mode 100644 index 0000000000..924279e3c8 --- /dev/null +++ b/addons/fire/functions/fnc_fireManagerPFH.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Handles various objects on fire and determines if units close to objects deserve to get burned. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * ace_fire_fnc_fireManagerPFH call CBA_fnc_addPerFrameHandler + * + * Public: No + */ + +{ + _y params ["_fireLogic", "_radius", "_intensity", "_condition", "_conditionArgs"]; + TRACE_2("fireManagerPFH loop",_x,_y); + + // Remove when condition is no longer valid + if !(_conditionArgs call _condition) then { + TRACE_2("condition no longer valid, deleting",_x,_y); + + detach _fireLogic; + deleteVehicle _fireLogic; + + GVAR(fireSources) deleteAt _x; + + continue; + }; + + // Burn units (alive or dead) close to the fire + { + private _distancePercent = 1 - ((_fireLogic distance _x) / _radius); + private _adjustedIntensity = _intensity * _distancePercent; + + // Don't burn if intensity is too low or already burning with higher intensity + if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then { + continue; + }; + + [QGVAR(burn), [_x, _adjustedIntensity], _x] call CBA_fnc_targetEvent; + + TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity); + } forEach nearestObjects [_fireLogic, ["CAManBase"], _radius]; +} forEach GVAR(fireSources); diff --git a/addons/fire/functions/fnc_isBurning.sqf b/addons/fire/functions/fnc_isBurning.sqf new file mode 100644 index 0000000000..04a57c29e6 --- /dev/null +++ b/addons/fire/functions/fnc_isBurning.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: commy2 + * Check if an object is burning. + * + * Arguments: + * 0: Object + * + * Return Value: + * None + * + * Example: + * player call ace_fire_fnc_isBurning + * + * Public: Yes + */ + +params [["_object", objNull, [objNull]]]; + +(_object getVariable [QGVAR(intensity), 0]) > BURN_MIN_INTENSITY diff --git a/addons/fire/functions/fnc_medical_canPatDown.sqf b/addons/fire/functions/fnc_medical_canPatDown.sqf new file mode 100644 index 0000000000..758b83b922 --- /dev/null +++ b/addons/fire/functions/fnc_medical_canPatDown.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Returns if unit can pat down fire or not. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * Can Pat-Down + * + * Example: + * [nil, player] call ace_fire_fnc_medical_canPatDown + * + * Public: No + */ + +params ["", "_patient"]; + +_patient call FUNC(isBurning) diff --git a/addons/fire/functions/fnc_medical_progress.sqf b/addons/fire/functions/fnc_medical_progress.sqf new file mode 100644 index 0000000000..fd64b5c27d --- /dev/null +++ b/addons/fire/functions/fnc_medical_progress.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks if patient is still burning for medical progress to continue. + * + * Arguments: + * 0: Arguments + * - 0: Medic (not used) + * - 1: Patient + * + * Return Value: + * Continue pat down + * + * Example: + * [[player, cursorObject]] call ace_fire_fnc_medical_progress + * + * Public: No + */ + +params ["_args"]; +_args params ["", "_patient"]; + +_patient call FUNC(isBurning) diff --git a/addons/fire/functions/fnc_medical_success.sqf b/addons/fire/functions/fnc_medical_success.sqf new file mode 100644 index 0000000000..ca569e1280 --- /dev/null +++ b/addons/fire/functions/fnc_medical_success.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Decreases burning intensity on successful medical action. + * The medical action is looped until the user stops the interaction or the unit is no longer burning. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_fire_fnc_medical_success + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart", "_classname"]; + +private _intensity = _patient getVariable [QGVAR(intensity), 0]; +_intensity = _intensity * INTENSITY_DECREASE_MULT_PAT_DOWN; + +_patient setVariable [QGVAR(intensity), _intensity, true]; + +// If the unit is still burning, loop the medical action +if !(_patient call FUNC(isBurning)) exitWith { + TRACE_1("patient no longer burning, quitting",_this); +}; + +TRACE_1("patient still burning, looping",_this); + +if (EGVAR(medical_gui,pendingReopen)) then { + TRACE_1("temporarily blocking medical menu reopen",_this); + + EGVAR(medical_gui,pendingReopen) = false; + [{EGVAR(medical_gui,pendingReopen) = true}] call CBA_fnc_execNextFrame; +}; + +[_medic, _patient, _bodyPart, _classname] call EFUNC(medical_treatment,treatment); diff --git a/addons/fire/initSettings.inc.sqf b/addons/fire/initSettings.inc.sqf new file mode 100644 index 0000000000..edcd51a8a7 --- /dev/null +++ b/addons/fire/initSettings.inc.sqf @@ -0,0 +1,40 @@ +[ + QGVAR(enabled), + "CHECKBOX", + [ELSTRING(common,Enabled), LSTRING(Setting_Description)], + LSTRING(Category_DisplayName), + true, + 1, + {[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(enableFlare), + "CHECKBOX", + [LSTRING(Setting_FlareEnable), LSTRING(Setting_FlareDescription)], + LSTRING(Category_DisplayName), + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(dropWeapon), + "LIST", + [LSTRING(Setting_DropWeapon), LSTRING(Setting_DropWeapon_Description)], + LSTRING(Category_DisplayName), + [ + [0, 1, 2], + ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)], + 1 + ], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableScreams), + "CHECKBOX", + [LSTRING(Setting_EnableScreams), LSTRING(Setting_EnableScreams_Description)], + LSTRING(Category_DisplayName), + true +] call CBA_fnc_addSetting; diff --git a/addons/fire/script_component.hpp b/addons/fire/script_component.hpp new file mode 100644 index 0000000000..ebb0002ff6 --- /dev/null +++ b/addons/fire/script_component.hpp @@ -0,0 +1,44 @@ +#define COMPONENT fire +#define COMPONENT_BEAUTIFIED Fire +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define CBA_DEBUG_SYNCHRONOUS +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_FIRE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_FIRE + #define DEBUG_SETTINGS DEBUG_SETTINGS_FIRE +#endif + +#include "\z\ace\addons\main\script_macros.hpp" +#include "\z\ace\addons\medical_engine\script_macros_medical.hpp" + +#define FIRE_MANAGER_PFH_DELAY 0.25 +#define FLARE_SIZE_MODIFIER 5 +#define PRONE_ROLLING_ANIMS [\ + "amovppnemstpsnonwnondnon_amovppnemevasnonwnondl",\ + "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr",\ + "amovppnemstpsraswrfldnon_amovppnemevaslowwrfldl",\ + "amovppnemstpsraswrfldnon_amovppnemevaslowwrfldr",\ + "amovppnemstpsraswpstdnon_amovppnemevaslowwpstdl",\ + "amovppnemstpsraswpstdnon_amovppnemevaslowwpstdr",\ + "amovppnemstpsoptwbindnon_amovppnemevasoptwbindl",\ + "amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\ +] + +#define BURN_MAX_INTENSITY 10 +#define BURN_MIN_INTENSITY 1 + +#define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8 +#define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN + +#define INTENSITY_LOSS 0.02 +#define INTENSITY_UPDATE 2 +#define BURN_PROPAGATE_UPDATE 1 +#define BURN_PROPAGATE_DISTANCE 2 +#define BURN_THRESHOLD_INTENSE 3 diff --git a/addons/fire/sounds/scream1.ogg b/addons/fire/sounds/scream1.ogg new file mode 100644 index 0000000000..c705370958 Binary files /dev/null and b/addons/fire/sounds/scream1.ogg differ diff --git a/addons/fire/sounds/scream10.ogg b/addons/fire/sounds/scream10.ogg new file mode 100644 index 0000000000..1c42e762e1 Binary files /dev/null and b/addons/fire/sounds/scream10.ogg differ diff --git a/addons/fire/sounds/scream11.ogg b/addons/fire/sounds/scream11.ogg new file mode 100644 index 0000000000..c215ad3a61 Binary files /dev/null and b/addons/fire/sounds/scream11.ogg differ diff --git a/addons/fire/sounds/scream12.ogg b/addons/fire/sounds/scream12.ogg new file mode 100644 index 0000000000..11bc13fd91 Binary files /dev/null and b/addons/fire/sounds/scream12.ogg differ diff --git a/addons/fire/sounds/scream13.ogg b/addons/fire/sounds/scream13.ogg new file mode 100644 index 0000000000..726cd87be5 Binary files /dev/null and b/addons/fire/sounds/scream13.ogg differ diff --git a/addons/fire/sounds/scream14.ogg b/addons/fire/sounds/scream14.ogg new file mode 100644 index 0000000000..eff98f7ebc Binary files /dev/null and b/addons/fire/sounds/scream14.ogg differ diff --git a/addons/fire/sounds/scream15.ogg b/addons/fire/sounds/scream15.ogg new file mode 100644 index 0000000000..fa7c5d884b Binary files /dev/null and b/addons/fire/sounds/scream15.ogg differ diff --git a/addons/fire/sounds/scream2.ogg b/addons/fire/sounds/scream2.ogg new file mode 100644 index 0000000000..8f79081fcd Binary files /dev/null and b/addons/fire/sounds/scream2.ogg differ diff --git a/addons/fire/sounds/scream3.ogg b/addons/fire/sounds/scream3.ogg new file mode 100644 index 0000000000..2749b01a74 Binary files /dev/null and b/addons/fire/sounds/scream3.ogg differ diff --git a/addons/fire/sounds/scream4.ogg b/addons/fire/sounds/scream4.ogg new file mode 100644 index 0000000000..c92497e869 Binary files /dev/null and b/addons/fire/sounds/scream4.ogg differ diff --git a/addons/fire/sounds/scream5.ogg b/addons/fire/sounds/scream5.ogg new file mode 100644 index 0000000000..23fb6c7ed9 Binary files /dev/null and b/addons/fire/sounds/scream5.ogg differ diff --git a/addons/fire/sounds/scream6.ogg b/addons/fire/sounds/scream6.ogg new file mode 100644 index 0000000000..9a14a69e74 Binary files /dev/null and b/addons/fire/sounds/scream6.ogg differ diff --git a/addons/fire/sounds/scream7.ogg b/addons/fire/sounds/scream7.ogg new file mode 100644 index 0000000000..ab1970ee53 Binary files /dev/null and b/addons/fire/sounds/scream7.ogg differ diff --git a/addons/fire/sounds/scream8.ogg b/addons/fire/sounds/scream8.ogg new file mode 100644 index 0000000000..688460e934 Binary files /dev/null and b/addons/fire/sounds/scream8.ogg differ diff --git a/addons/fire/sounds/scream9.ogg b/addons/fire/sounds/scream9.ogg new file mode 100644 index 0000000000..72ef6e4f7c Binary files /dev/null and b/addons/fire/sounds/scream9.ogg differ diff --git a/addons/fire/stringtable.xml b/addons/fire/stringtable.xml new file mode 100644 index 0000000000..dc93a88c2b --- /dev/null +++ b/addons/fire/stringtable.xml @@ -0,0 +1,135 @@ + + + + + ACE Fire + ACE 火災 + ACE Feu + ACE Возгорание + ACE Feuer + ACE Fuoco + ACE Ogień + ACE Fuego + ACE 火 + ACE 불 + ACE Fogo + + + Pat Down Fire + 火を叩き消す + Éteindre le feu + Потушить + Feuer löschen + Estingui Fuoco + Zgaś ogień + Extingir el fuego + 灭火 + 불 끄기 + Apagar Fogo + + + Patting down fire... + 火を叩き消しています・・・ + Feu en cours d'extinction... + Тушение... + Feuer wird gelöscht... + Estinguendo Fuoco... + Gaszenie ognia... + Extinguiendo el fuego... + 正在灭火... + 불 끄는 중... + Apagando Fogo... + + + Allow units to catch fire + ユニットへ着火を許可 + Définit si les unités peuvent prendre feu ou non. + Включает возгорание + Erlaubt, dass Einheiten Feuer fangen können + Permette che unità possono prendere fuoco + Zezwól jednostkom na zapalenie się + Permitir que las unidades se incendien + 允许单位着火 + 유닛에 불이 붙게합니다 + Permitir que as unidades peguem fogo + + + Enable fire-flare at night + 夜間にフレア効果を有効化 + Halo lumineux la nuit + Включает сверкание пламени + Aktiviert Feuerschein bei Nacht. + Ability luce-fuoco di notte + Włącza efekt flary od ognia w nocy + Habilitar bengalas de fuego por la noche + 在夜间启用耀斑效果 + 밤에 불로 인한 조명 활성화 + Ativar brilho do fogo à noite + + + Uses a flare effect to increase fire intensity at night + 夜間に火災の強さを上昇させるフレア効果を有効化します。 + Ajoute un effet de halo lumineux afin d'accroitre l'intensité du feu durant la nuit. + Включает ореол пламени для большей интенсивности ночью + Benutzt einen Feuerschein-Effekt um die Intensität des Feuers bei Nacht zu verstärken. + Usa un effetto flare per mettere in mostra fuochi di notte + Używa efektu flary, aby zwiększyć jasność w nocy + Utiliza un efecto de bengala para aumentar la intensidad del fuego por la noche + 启用耀斑效果,增加夜间火焰的强度。 + 야간에 불로 인한 조명을 극대화 시킵니다 + Usa um efeito de brilho para aumentar a intensidade do fogo à noite + + + Enable screams by units on fire + Habilitar los gritos de las unidades en llamas + 启用着火单位发出惨叫声 + 불 붙은 유닛 비명 + Schreie von brennenden Einheiten aktivieren + Grida di unità a fuoco + Włącz krzyki podpalonych jednostek + 炎上中の悲鳴を有効 + Вкл. крики от горения + Activer les cris des unités en feu + Habilita os gritos das unidades em chamas + + + Enables if units on fire will play the screaming sound + Habilita si las unidades en llamas reproducirán el sonido de los gritos + 启用着火的单位是否会发出惨叫声。 + 불이 붙은 유닛이 소리를 지르게 합니다 + Aktiviert, ob brennende Einheiten den Schrei-Ton abspielen + Abilita le grida di unità andate a fuoco + Włącza, czy płonące jednostki będą odtwarzać dźwięk krzyku + 有効化すると炎上しているユニットが悲鳴を上げます + Включает воспроизведение криков когда юнит загорается + Active un son de hurlement si les unités sont en feu + Define se as unidades em chamas reproduzirão o som de grito + + + Drop Weapons When on Fire + Soltar armas cuando esté en llamas + Włącz wyrzucanie broni podczas płonięcia + 着火时扔掉武器 + 불 붙을 경우 무기 내려놓음 + Waffen fallen lassen, wenn in Brand geraten. + Fai cadere armi quando a fuoco + 炎上時に武器を落とす + Бросать оружие из-за горения + Lâche les armes si en feu + Soltar Armas Quando em Chamas + + + Controls whether units drop their weapons when on fire. + Controla si las unidades dejan caer sus armas cuando están en llamas + Powoduje że jednostki wyrzucają swoją broń gdy płoną. + 控制单位在着火时是否丢掉武器。 + 유닛이 불에 붙이면 무기를 떨굴지를 결정합니다. + Steuert, ob Einheiten ihre Waffen fallen lassen, wenn sie brennen. + Determina se le unità fanno cadere le proprie armi quando cominciano a bruciare. + ユニットが炎上時に武器を落とすかどうかを定義します。 + Должны ли юниты выбрасывать оружие когда загораются. + Contrôle si les unités lâchent leurs armes lorsqu'elles sont en feu. + Controla se as unidades soltam suas armas quando estão em chamas. + + + diff --git a/addons/flashlights/CfgEventHandlers.hpp b/addons/flashlights/CfgEventHandlers.hpp index 58b84ad864..123f7553aa 100644 --- a/addons/flashlights/CfgEventHandlers.hpp +++ b/addons/flashlights/CfgEventHandlers.hpp @@ -1,6 +1,5 @@ - class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient)); }; }; diff --git a/addons/flashlights/CfgVehicles.hpp b/addons/flashlights/CfgVehicles.hpp index fa766ad87b..6c3e32c1c7 100644 --- a/addons/flashlights/CfgVehicles.hpp +++ b/addons/flashlights/CfgVehicles.hpp @@ -7,18 +7,17 @@ class CfgVehicles { }; class Item_Base_F; - class ACE_Flashlight_MX991Item: Item_Base_F { scope = 2; scopeCurator = 2; displayName = CSTRING(MX991_DisplayName); author = ECSTRING(common,ACETeam); - vehicleClass = "WeaponAccessories"; + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + vehicleClass = "Items"; + class TransportItems { - class ACE_Flashlight_MX991 { - name = "ACE_Flashlight_MX991"; - count = 1; - }; + MACRO_ADDITEM(ACE_Flashlight_MX991,1); }; }; @@ -27,12 +26,12 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(KSF1_DisplayName); author = ECSTRING(common,ACETeam); - vehicleClass = "WeaponAccessories"; + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + vehicleClass = "Items"; + class TransportItems { - class ACE_Flashlight_KSF1 { - name = "ACE_Flashlight_KSF1"; - count = 1; - }; + MACRO_ADDITEM(ACE_Flashlight_KSF1,1); }; }; @@ -41,38 +40,52 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(XL50_DisplayName); author = ECSTRING(common,ACETeam); - vehicleClass = "WeaponAccessories"; + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + vehicleClass = "Items"; + class TransportItems { - class ACE_Flashlight_XL50 { - name = "ACE_Flashlight_XL50"; - count = 1; - }; + MACRO_ADDITEM(ACE_Flashlight_XL50,1); + }; + }; + + class Pistol_Base_F; + class ACE_Item_Flashlight_Maglite_ML300L: Pistol_Base_F { + scope = 2; + scopeCurator = 2; + displayName = CSTRING(Maglite_ML300L_DisplayName); + author = ECSTRING(common,ACETeam); + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + vehicleClass = "Items"; + + class TransportWeapons { + MACRO_ADDWEAPON(ACE_Flashlight_Maglite_ML300L,1); }; }; class NATO_Box_Base; - class EAST_Box_Base; - class IND_Box_Base; - class FIA_Box_Base_F; - class Box_NATO_Support_F: NATO_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_Flashlight_MX991,12); }; }; + class EAST_Box_Base; class Box_East_Support_F: EAST_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_Flashlight_KSF1,12); }; }; + class IND_Box_Base; class Box_IND_Support_F: IND_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_Flashlight_XL50,12); }; }; + class FIA_Box_Base_F; class Box_FIA_Support_F: FIA_Box_Base_F { class TransportItems { MACRO_ADDITEM(ACE_Flashlight_MX991,12); @@ -85,5 +98,8 @@ class CfgVehicles { MACRO_ADDITEM(ACE_Flashlight_KSF1,12); MACRO_ADDITEM(ACE_Flashlight_XL50,12); }; + class TransportWeapons { + MACRO_ADDWEAPON(ACE_Flashlight_Maglite_ML300L,2); + }; }; -}; \ No newline at end of file +}; diff --git a/addons/flashlights/CfgWeapons.hpp b/addons/flashlights/CfgWeapons.hpp index 41bfd4a8bb..f939f84bb7 100644 --- a/addons/flashlights/CfgWeapons.hpp +++ b/addons/flashlights/CfgWeapons.hpp @@ -1,17 +1,82 @@ class CfgWeapons { + class Pistol; + class Pistol_Base_F: Pistol { + class WeaponSlotsInfo; + }; + + class ACE_Flashlight_Maglite_ML300L: Pistol_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(Maglite_ML300L_DisplayName); + descriptionShort = CSTRING(Maglite_ML300L_Description); + model = QPATHTOF(data\maglite_ml300l.p3d); + picture = QPATHTOF(UI\maglite_ml300l_ca.paa); + cursor = ""; + cursorAim = ""; + + // binarized rtm, animation in "extras/assets/maglite" + handAnim[] = {"OFP2_ManSkeleton", QPATHTOF(data\maglite_ml300l.rtm)}; + recoil = "empty"; + muzzlePos = "flash"; + muzzleEnd = "flash dir"; + magazines[] = {"FakeMagazine"}; // Required for the weapon info box to work correctly. + textureType = "default"; // empty texture + weaponInfoType = "RscWeaponEmpty"; + + class WeaponSlotsInfo: WeaponSlotsInfo { + holsterScale = 0; // Item does not fit a pistol holster, so hide it. + mass = 20; + + class MuzzleSlot {}; + class CowsSlot {}; + }; + + inertia = 0.2; + dexterity = 1.8; + + class FlashLight { + color[] = {180,180,190}; + ambient[] = {0.9,0.81,0.7}; + intensity = 85; + size = 1; + innerAngle = 5; + outerAngle = 80; + coneFadeCoef = 8; + position = "flash dir"; + direction = "flash"; + useFlare = 1; + flareSize = 0.8; + flareMaxDistance = 100; + dayLight = 1; + + class Attenuation { + start = 0.25; + constant = 0; + linear = 0; + quadratic = 1; + hardLimitStart = 140; + hardLimitEnd = 150; + }; + + scale[] = {0}; + }; + }; class ACE_ItemCore; class CBA_MiscItem_ItemInfo; class ACE_Flashlight_MX991: ACE_ItemCore { author = ECSTRING(common,ACETeam); + scope = 2; displayName = CSTRING(MX991_DisplayName); descriptionShort = CSTRING(MX991_Description); - model = QPATHTOF(data\MX_991.p3d); - picture = QPATHTOF(UI\mx991_ca.paa); - scope = 2; + model = QPATHTOF(data\mx_991.p3d); + picture = QPATHTOF(UI\mx_991_ca.paa); + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 4; + class FlashLight { ACE_Flashlight_Colour = "red"; ACE_Flashlight_Beam = QPATHTOF(UI\Flashlight_beam_red_ca.paa); @@ -22,13 +87,16 @@ class CfgWeapons { class ACE_Flashlight_KSF1: ACE_ItemCore { author = ECSTRING(common,ACETeam); + scope = 2; displayName = CSTRING(KSF1_DisplayName); descriptionShort = CSTRING(KSF1_Description); - model = QPATHTOF(data\KSF_1.p3d); - picture = QPATHTOF(UI\ksf1_ca.paa); - scope = 2; + model = QPATHTOF(data\ksf_1.p3d); + picture = QPATHTOF(UI\ksf_1_ca.paa); + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 4; + class FlashLight { ACE_Flashlight_Colour = "red"; ACE_Flashlight_Beam = QPATHTOF(UI\Flashlight_beam_red_ca.paa); @@ -39,13 +107,16 @@ class CfgWeapons { class ACE_Flashlight_XL50: ACE_ItemCore { author = ECSTRING(common,ACETeam); + scope = 2; displayName = CSTRING(XL50_DisplayName); descriptionShort = CSTRING(XL50_Description); - model = QPATHTOF(data\Maglight.p3d); - picture = QPATHTOF(UI\xl50_ca.paa); - scope = 2; + model = QPATHTOF(data\maglite_xl50.p3d); + picture = QPATHTOF(UI\maglite_xl50_ca.paa); + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 3; + class FlashLight { ACE_Flashlight_Colour = "white"; ACE_Flashlight_Beam = QPATHTOF(UI\Flashlight_beam_white_ca.paa); diff --git a/addons/flashlights/README.md b/addons/flashlights/README.md index 6a04b78091..214dc3dea1 100644 --- a/addons/flashlights/README.md +++ b/addons/flashlights/README.md @@ -2,10 +2,3 @@ ace_flashlights ======= Flashlights for use on map and to attach to player. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [voiper](https://github.com/voiperr) diff --git a/addons/flashlights/UI/KSF1_ca.paa b/addons/flashlights/UI/ksf_1_ca.paa similarity index 100% rename from addons/flashlights/UI/KSF1_ca.paa rename to addons/flashlights/UI/ksf_1_ca.paa diff --git a/addons/flashlights/UI/maglite_ml300l_ca.paa b/addons/flashlights/UI/maglite_ml300l_ca.paa new file mode 100644 index 0000000000..4a0440724f Binary files /dev/null and b/addons/flashlights/UI/maglite_ml300l_ca.paa differ diff --git a/addons/flashlights/UI/xl50_ca.paa b/addons/flashlights/UI/maglite_xl50_ca.paa similarity index 100% rename from addons/flashlights/UI/xl50_ca.paa rename to addons/flashlights/UI/maglite_xl50_ca.paa diff --git a/addons/flashlights/UI/mx991_ca.paa b/addons/flashlights/UI/mx_991_ca.paa similarity index 100% rename from addons/flashlights/UI/mx991_ca.paa rename to addons/flashlights/UI/mx_991_ca.paa diff --git a/addons/flashlights/XEH_postInitClient.sqf b/addons/flashlights/XEH_postInitClient.sqf index 53e7d041a8..15cd1372b4 100644 --- a/addons/flashlights/XEH_postInitClient.sqf +++ b/addons/flashlights/XEH_postInitClient.sqf @@ -5,4 +5,4 @@ if (!hasInterface) exitWith {}; LOG(MSG_INIT); -//todo: make flashlights attachable to players \ No newline at end of file +//todo: make flashlights attachable to players diff --git a/addons/flashlights/config.cpp b/addons/flashlights/config.cpp index eefeb782f1..f88afc0663 100644 --- a/addons/flashlights/config.cpp +++ b/addons/flashlights/config.cpp @@ -3,12 +3,22 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; - weapons[] = {"ACE_Flashlight_MX991", "ACE_Flashlight_KSF1", "ACE_Flashlight_XL50"}; + units[] = { + "ACE_Flashlight_MX991Item", + "ACE_Flashlight_KSF1Item", + "ACE_Flashlight_XL50Item", + "ACE_Item_Flashlight_Maglite_ML300L" + }; + weapons[] = { + "ACE_Flashlight_MX991", + "ACE_Flashlight_KSF1", + "ACE_Flashlight_XL50", + "ACE_Flashlight_Maglite_ML300L" + }; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); - authors[] = {"voiper"}; + authors[] = {"voiper","bux","HorribleGoat"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; diff --git a/addons/flashlights/data/KSF_1.p3d b/addons/flashlights/data/KSF_1.p3d index 0ec2fd23c6..0059335bd6 100644 Binary files a/addons/flashlights/data/KSF_1.p3d and b/addons/flashlights/data/KSF_1.p3d differ diff --git a/addons/flashlights/data/MX_991.p3d b/addons/flashlights/data/MX_991.p3d index c79c330ea3..a373dd3f74 100644 Binary files a/addons/flashlights/data/MX_991.p3d and b/addons/flashlights/data/MX_991.p3d differ diff --git a/addons/flashlights/data/Maglight.p3d b/addons/flashlights/data/Maglight.p3d deleted file mode 100644 index 6ce3b9fcd4..0000000000 Binary files a/addons/flashlights/data/Maglight.p3d and /dev/null differ diff --git a/addons/flashlights/data/ksf_1.rvmat b/addons/flashlights/data/ksf_1.rvmat index 113fe0cc14..ed9e802c54 100644 --- a/addons/flashlights/data/ksf_1.rvmat +++ b/addons/flashlights/data/ksf_1.rvmat @@ -8,7 +8,7 @@ PixelShaderID="Super"; VertexShaderID="Super"; class Stage1 { - texture="z\ace\addons\flashlights\data\KSF_1_nohq.paa"; + texture="z\ace\addons\flashlights\data\textures\ksf_1_nohq.paa"; uvSource="tex"; class uvTransform { aside[]={1,0,0}; @@ -48,7 +48,7 @@ class Stage4 { }; }; class Stage5 { - texture="z\ace\addons\flashlights\data\KSF_1_smdi.paa"; + texture="z\ace\addons\flashlights\data\textures\ksf_1_smdi.paa"; uvSource="tex"; class uvTransform { aside[]={1,0,0}; diff --git a/addons/flashlights/data/maglite.rvmat b/addons/flashlights/data/maglite.rvmat deleted file mode 100644 index 960599813b..0000000000 --- a/addons/flashlights/data/maglite.rvmat +++ /dev/null @@ -1,79 +0,0 @@ -ambient[]={1,1,1,1}; -diffuse[]={1,1,1,1}; -forcedDiffuse[]={0,0,0,0}; -emmisive[]={0,0,0,1}; -specular[]={0.6,0.6,0.6,1}; //amount of glossiness - the higher the number, the higher the glossiness -specularPower=700; //area of glossiness - the higher the number, the smaller the area -PixelShaderID="Super"; -VertexShaderID="Super"; - -class Stage1 { - texture="z\ace\addons\flashlights\data\Maglite_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="#(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,1}; - }; -}; -class Stage5 { - texture="z\ace\addons\flashlights\data\Maglite_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(4.7,1.2)"; - 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_ca.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/flashlights/data/maglite_ml300l.p3d b/addons/flashlights/data/maglite_ml300l.p3d new file mode 100644 index 0000000000..e916514d51 Binary files /dev/null and b/addons/flashlights/data/maglite_ml300l.p3d differ diff --git a/addons/flashlights/data/maglite_ml300l.rtm b/addons/flashlights/data/maglite_ml300l.rtm new file mode 100644 index 0000000000..0a82508447 Binary files /dev/null and b/addons/flashlights/data/maglite_ml300l.rtm differ diff --git a/addons/flashlights/data/maglite_ml300l.rvmat b/addons/flashlights/data/maglite_ml300l.rvmat new file mode 100644 index 0000000000..a869bb93b4 --- /dev/null +++ b/addons/flashlights/data/maglite_ml300l.rvmat @@ -0,0 +1,80 @@ +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.6,0.6,0.6,1}; //amount of glossiness - the higher the number, the higher the glossiness +specularPower = 700; //area of glossiness - the higher the number, the smaller the area +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\flashlights\data\textures\maglite_ml300l_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 = "#(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,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\flashlights\data\textures\maglite_ml300l_as.paa"; + uvSource = "tex"; + + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,1}; + }; +}; + +class Stage5 { + texture = "z\ace\addons\flashlights\data\textures\maglite_ml300l_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,64,64,1)fresnel(4.7,1.2)"; + uvSource = "tex"; + + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/flashlights/data/maglite_xl50.p3d b/addons/flashlights/data/maglite_xl50.p3d new file mode 100644 index 0000000000..b5619337d4 Binary files /dev/null and b/addons/flashlights/data/maglite_xl50.p3d differ diff --git a/addons/flashlights/data/maglite_xl50.rvmat b/addons/flashlights/data/maglite_xl50.rvmat new file mode 100644 index 0000000000..c1450280f3 --- /dev/null +++ b/addons/flashlights/data/maglite_xl50.rvmat @@ -0,0 +1,79 @@ +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.6,0.6,0.6,1}; //amount of glossiness - the higher the number, the higher the glossiness +specularPower=700; //area of glossiness - the higher the number, the smaller the area +PixelShaderID="Super"; +VertexShaderID="Super"; + +class Stage1 { + texture="z\ace\addons\flashlights\data\textures\maglite_xl50_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="#(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,1}; + }; +}; +class Stage5 { + texture="z\ace\addons\flashlights\data\textures\maglite_xl50_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(4.7,1.2)"; + 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_ca.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/flashlights/data/model.cfg b/addons/flashlights/data/model.cfg new file mode 100644 index 0000000000..58bc63eb8d --- /dev/null +++ b/addons/flashlights/data/model.cfg @@ -0,0 +1,175 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; + + class OFP2_ManSkeleton { + isDiscrete = 0; + skeletonInherit = ""; + skeletonBones[] = { + "Pelvis","", + "Spine","Pelvis", + "Spine1","Spine", + "Spine2","Spine1", + "Spine3","Spine2", + "Camera","Pelvis", + "weapon","Spine1", + "launcher","Spine1", + + // Head skeleton in hierarchy + "neck","Spine3", + "neck1","neck", + "head","neck1", + + // New facial features + "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", + + // 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" + }; + + // location of pivot points (local axes) for hierarchical animation + pivotsModel = "A3\anims_f\data\skeleton\SkeletonPivots.p3d"; + }; +}; + +class CfgModels { + class Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = ""; + }; + + class ArmaMan: Default { + htMin = 60; // Minimum half-cooling time (in seconds) + htMax = 1800; // Maximum half-cooling time (in seconds) + afMax = 30; // Maximum temperature in case the model is alive (in celsius) + mfMax = 0; // Maximum temperature when the model is moving (in celsius) + mFact = 1; // Metabolism factor - number from interval <0, 1> (0 - metabolism has no influence, 1 - metabolism has full influence (no other temperature source will be considered)). + tBody = 37; // Metabolism temperature of the model (in celsius) + + sections[] = { + "osobnost", + "Head_Injury", + "Body_Injury", + "l_leg_injury", + "l_arm_injury", + "r_arm_injury", + "r_leg_injury", + "injury_body", + "injury_legs", + "injury_hands", + "clan", + "clan_sign", + "Camo", + "CamoB", + "Camo1", + "Camo2", + "personality", + "hl", + "injury_head", + "insignia", + "ghillie_hide" + }; + + skeletonName = "OFP2_ManSkeleton"; + }; +}; diff --git a/addons/flashlights/data/mx_991.rvmat b/addons/flashlights/data/mx_991.rvmat index 0268d4903c..040b3ea8c6 100644 --- a/addons/flashlights/data/mx_991.rvmat +++ b/addons/flashlights/data/mx_991.rvmat @@ -8,7 +8,7 @@ PixelShaderID="Super"; VertexShaderID="Super"; class Stage1 { - texture="z\ace\addons\flashlights\data\MX_991_nohq.paa"; + texture="z\ace\addons\flashlights\data\textures\mx_991_nohq.paa"; uvSource="tex"; class uvTransform { aside[]={1,0,0}; diff --git a/addons/flashlights/data/ksf_1_co.paa b/addons/flashlights/data/textures/ksf_1_co.paa similarity index 100% rename from addons/flashlights/data/ksf_1_co.paa rename to addons/flashlights/data/textures/ksf_1_co.paa diff --git a/addons/flashlights/data/KSF_1_nohq.paa b/addons/flashlights/data/textures/ksf_1_nohq.paa similarity index 100% rename from addons/flashlights/data/KSF_1_nohq.paa rename to addons/flashlights/data/textures/ksf_1_nohq.paa diff --git a/addons/flashlights/data/KSF_1_smdi.paa b/addons/flashlights/data/textures/ksf_1_smdi.paa similarity index 100% rename from addons/flashlights/data/KSF_1_smdi.paa rename to addons/flashlights/data/textures/ksf_1_smdi.paa diff --git a/addons/flashlights/data/textures/maglite_ml300l_as.paa b/addons/flashlights/data/textures/maglite_ml300l_as.paa new file mode 100644 index 0000000000..6dc466f969 Binary files /dev/null and b/addons/flashlights/data/textures/maglite_ml300l_as.paa differ diff --git a/addons/flashlights/data/textures/maglite_ml300l_ca.paa b/addons/flashlights/data/textures/maglite_ml300l_ca.paa new file mode 100644 index 0000000000..2a2368b6e3 Binary files /dev/null and b/addons/flashlights/data/textures/maglite_ml300l_ca.paa differ diff --git a/addons/flashlights/data/textures/maglite_ml300l_nohq.paa b/addons/flashlights/data/textures/maglite_ml300l_nohq.paa new file mode 100644 index 0000000000..4a08ff5925 Binary files /dev/null and b/addons/flashlights/data/textures/maglite_ml300l_nohq.paa differ diff --git a/addons/flashlights/data/textures/maglite_ml300l_smdi.paa b/addons/flashlights/data/textures/maglite_ml300l_smdi.paa new file mode 100644 index 0000000000..32cab82188 Binary files /dev/null and b/addons/flashlights/data/textures/maglite_ml300l_smdi.paa differ diff --git a/addons/flashlights/data/maglite_co.paa b/addons/flashlights/data/textures/maglite_xl50_co.paa similarity index 100% rename from addons/flashlights/data/maglite_co.paa rename to addons/flashlights/data/textures/maglite_xl50_co.paa diff --git a/addons/flashlights/data/Maglite_nohq.paa b/addons/flashlights/data/textures/maglite_xl50_nohq.paa similarity index 100% rename from addons/flashlights/data/Maglite_nohq.paa rename to addons/flashlights/data/textures/maglite_xl50_nohq.paa diff --git a/addons/flashlights/data/Maglite_smdi.paa b/addons/flashlights/data/textures/maglite_xl50_smdi.paa similarity index 100% rename from addons/flashlights/data/Maglite_smdi.paa rename to addons/flashlights/data/textures/maglite_xl50_smdi.paa diff --git a/addons/flashlights/data/mx_991_co.paa b/addons/flashlights/data/textures/mx_991_co.paa similarity index 100% rename from addons/flashlights/data/mx_991_co.paa rename to addons/flashlights/data/textures/mx_991_co.paa diff --git a/addons/flashlights/data/MX_991_nohq.paa b/addons/flashlights/data/textures/mx_991_nohq.paa similarity index 100% rename from addons/flashlights/data/MX_991_nohq.paa rename to addons/flashlights/data/textures/mx_991_nohq.paa diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index dc2c76dd4f..2afaa1aacf 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -12,9 +12,10 @@ Fulton MX-991 Fulton MX-991 フルトン MX-991 - Fulton MX-991 - Fulton MX-991手电筒 + 풀턴 MX-991 + Fulton MX-991 手电筒 Fulton MX-991 + Fulton MX-991 Flashlight with red filter. For use on map. @@ -27,9 +28,10 @@ Torcia con filtro rosso. Da usare in mappa. Lampe torche avec un filtre rouge. Pour utilisation sur carte. 赤色フィルタ付きのフラッシュライト。地図上でつかいます。 - 빨간색 필터가 달린 손전등입니다. 지도를 비출때 씁니다. + 빨간색 필터가 달린 손전등입니다. 지도를 비출 때 씁니다. 拥有红色滤光片的手电筒。用来照亮地图。 擁有紅色濾光片的手電筒。用來照亮地圖。 + Kırmızı filtreli el feneri. Harita üzerin de kullanım için. Maglite XL50 @@ -42,9 +44,10 @@ Maglite XL50 Maglite XL50 マグライト XL50 - Maglite XL50 - Maglite XL50手电筒 + 매그라이트 XL50 + Maglite XL50 手电筒 Maglite XL50 + Maglite XL50 White mini flashlight. For use on map. @@ -56,10 +59,11 @@ Mini linterna blanca. Para su uso en el mapa. Mini-torcia bianca. Da usare in mappa. Mini lampe torche blanche. Pour utilisation sur carte. - 白色光の小さなフラッシュライト。地図上でつかいます。 - 하얀색 조그마한 손전등. 지도를 비출때 씁니다. + 白色光の小さなフラッシュライト。地図上で使用します。 + 조그마한 하얀색 손전등. 지도를 비출 때 씁니다. 白色的迷你手电筒。用来照亮地图。 白色的迷你手電筒。用來照亮地圖。 + Beyaz küçük el feneri. Harita üzerin de kullanım için. KSF-1 @@ -73,8 +77,9 @@ KSF-1 KSF-1 KSF-1 - KSF-1手电筒 + KSF-1 手电筒 KSF-1 + KSF-1 Flashlight with red filter. For use on map. @@ -86,21 +91,59 @@ Linterna con filtro rojo. Para su uso en el mapa. Torcia con filtro rosso. Da usare in mappa. Lampe torche avec un filtre rouge. Pour utilisation sur carte. - 赤色フィルタ付きのフラッシュライト。地図上でつかいます。 - 빨간색 필터가 달린 손전등입니다. 지도를 비출때 씁니다. + 赤色フィルタ付きのフラッシュライト。地図上で使用します。 + 빨간색 필터가 달린 손전등입니다. 지도를 비출 때 씁니다. 拥有红色滤光片的手电筒。用来照亮地图。 擁有紅色濾光片的手電筒。用來照亮地圖。 + Kırmızı filtreli el feneri. Harita üzerin de kullanım için. 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 + Barva svítilny na mapě + Harita ışık rengi + Color de luz sobre el mapa + 지도상 색상 + + + Maglite ML300L + Maglite ML300L + Maglite ML300L + Maglite ML300L + Maglite ML300L 强光手电筒 + Maglite ML300L + Maglite ML300L + Maglite ML300L + マグライト ML300L + Maglite ML300L + Maglite ML300L + Maglite ML300L + 매그라이트 ML300L + Maglite ML300L + + + Powerful LED flashlight. + Leistungsstarke LED-Taschenlampe. + Mocna latarka LED. + 強大的LED手電筒 + 强光 LED 手电筒。 + Torcia a LED molto luminosa + Silná LED svítilna. + Puissante lampe torche à LED. + 強力な LED のフラッシュライト。 + Güçlü LED el feneri + Linterna LED potente + Мощный светодиодный фонарь. + 고휘도 LED 손전등. + Potente lanterna LED. diff --git a/addons/flashsuppressors/CfgWeapons.hpp b/addons/flashsuppressors/CfgWeapons.hpp index bf5aee16f1..aba24e1809 100644 --- a/addons/flashsuppressors/CfgWeapons.hpp +++ b/addons/flashsuppressors/CfgWeapons.hpp @@ -50,28 +50,26 @@ class asdg_MuzzleSlot_762MG: asdg_MuzzleSlot { // for 7.62, 6.5 and 5.56 univers ACE_muzzle_mzls_B = 1; }; }; + +// Vanilla Muzzles from 1.94+ (ref https://github.com/CBATeam/CBA_A3/pull/1184) class MuzzleSlot; +class MuzzleSlot_65: MuzzleSlot { + class compatibleItems { + ACE_muzzle_mzls_H = 1; + }; +}; +class MuzzleSlot_556: MuzzleSlot { + class compatibleItems { + ACE_muzzle_mzls_L = 1; + }; +}; +class MuzzleSlot_762: MuzzleSlot { + class compatibleItems { + ACE_muzzle_mzls_B = 1; + }; +}; class CfgWeapons { - class Rifle_Base_F; - - class Rifle_Long_Base_F: Rifle_Base_F { - class WeaponSlotsInfo; - }; - - /* Other */ - class LMG_Mk200_F: Rifle_Long_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762MG { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - - /* Flashsuppressors */ class ItemCore; diff --git a/addons/flashsuppressors/README.md b/addons/flashsuppressors/README.md index 29b66420c5..f366b2d821 100644 --- a/addons/flashsuppressors/README.md +++ b/addons/flashsuppressors/README.md @@ -2,11 +2,3 @@ ace_flashsuppressors ==================== Allows the flash suppressors that are already in the game to be used. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/flashsuppressors/stringtable.xml b/addons/flashsuppressors/stringtable.xml index 52563ea1c4..2591ee5398 100644 --- a/addons/flashsuppressors/stringtable.xml +++ b/addons/flashsuppressors/stringtable.xml @@ -5,7 +5,7 @@ Flash Suppressor (6.5 mm) Lángrejtő (6,5 mm) Mündungsfeuerdämpfer (6,5 mm) - Soppressore di fiamma (6.5mm) + Rompifiamma (6.5mm) Supressor de Clarão (6,5mm) Tłumik płomienia (6,5 mm) Tlumič plamene (6,5 mm) @@ -13,15 +13,16 @@ Пламегаситель (6,5 мм) Bocacha (6,5 mm) 消炎器 (6.5 mm) - 소염기 (6.5 mm) - 消光器 (6.5 mm) - 消光器 (6.5 mm) + 소염기 (6.5mm) + 消焰器(6.5 mm) + 消光器 (6.5 mm) + Flash Suppressor (6.5 mm) Flash Suppressor (7.62 mm) Lángrejtő (7,62 mm) Mündungsfeuerdämpfer (7,62 mm) - Soppressore di fiamma (7.62mm) + Rompifiamma (7.62mm) Supressor de Clarão (7,62mm) Tłumik płomienia (7,62 mm) Tlumič plamene (7,62 mm) @@ -29,15 +30,16 @@ Пламегаситель (7,62 мм) Bocacha (7,62 mm) 消炎器 (7.62 mm) - 소염기 (7.62 mm) - 消光器 (7.62 mm) - 消光器 (7.62 mm) + 소염기 (7.62mm) + 消焰器(7.62 mm) + 消光器 (7.62 毫米) + Flash Suppressor (7.62 mm) Flash Suppressor (5.56 mm) Lángrejtő (5,56 mm) Mündungsfeuerdämpfer (5,56 mm) - Soppressore di fiamma (5.56mm) + Rompifiamma (5.56mm) Supressor de Clarão (5,56mm) Tłumik płomienia (5,56 mm) Tlumič plamene (5,56 mm) @@ -45,15 +47,16 @@ Пламегаситель (5,56 мм) Bocacha (5,56 mm) 消炎器 (5.56 mm) - 소염기 (5.56 mm) - 消光器 (5.56 mm) + 소염기 (5.56mm) + 消焰器(5.56 mm) 消光器 (5.56 mm) + Flash Suppressor (5.56 mm) Flash Suppressor (.45 ACP) Lángrejtő (.45 ACP) Mündungsfeuerdämpfer (.45 ACP) - Soppressore di fiamma (.45 ACP) + Rompifiamma (.45 ACP) Supressor de Clarão (.45 ACP) Tłumik płomienia (.45 ACP) Tlumič plamene (.45 ACP) @@ -62,14 +65,15 @@ Bocacha (.45 ACP) 消炎器 (.45 ACP) 소염기 (.45 ACP) - 消光器 (.45 ACP) + 消焰器(.45 ACP) 消光器 (.45 ACP) + Flash Suppressor (.45 ACP) Flash Suppressor (9 mm) Lángrejtő (9 mm) Mündungsfeuerdämpfer (9 mm) - Soppressore di fiamma (9 mm) + Rompifiamma (9mm) Supressor de Clarão (9mm) Tłumik płomienia (9 mm) Tlumič plamene (9 mm) @@ -77,15 +81,16 @@ Пламегаситель (9 мм) Bocacha (9 mm) 消炎器 (9 mm) - 소염기 (9 mm) - 消光器 (9 mm) - 消光器 (9 mm) + 소염기 (9mm) + 消焰器(9 mm) + 消光器 (9 毫米) + Flash Suppressor (9 mm) Flash Suppressor (.338) Lángrejtő (.338) Mündungsfeuerdämpfer (.338) - Soppressore di fiamma (.338) + Rompifiamma (.338) Supressor de Clarão (.338) Tłumik płomienia (.338) Tlumič plamene (.338) @@ -94,14 +99,15 @@ Bocacha (.338) 消炎器 (.338) 소염기 (.338) - 消光器 (.338) + 消焰器(.338) 消光器 (.338) + Flash Suppressor (.338) Flash Suppressor (9.3 mm) Lángrejtő (9,3 mm) Mündungsfeuerdämpfer (9,3 mm) - Soppressore di fiamma (9.3mm) + Rompifiamma (9.3mm) Supressor de Clarão (9,3mm) Tłumik płomienia (9,3 mm) Tlumič plamene (9,3 mm) @@ -109,9 +115,10 @@ Пламегаситель (9,3 мм) Bocacha (9,3 mm) 消炎器 (9.3 mm) - 소염기 (9.3 mm) - 消光器 (9.3 mm) - 消光器 (9.3 mm) + 소염기 (9.3mm) + 消焰器(9.3 mm) + 消光器 (9.3 毫米) + Flash Suppressor (9.3 mm) diff --git a/addons/fonts/CfgFontFamilies.hpp b/addons/fonts/CfgFontFamilies.hpp index 9ec341c83d..6d7825a8ea 100644 --- a/addons/fonts/CfgFontFamilies.hpp +++ b/addons/fonts/CfgFontFamilies.hpp @@ -34,4 +34,9 @@ class CfgFontFamilies { spaceWidth = 0.5; spacing = 0.065; }; + class ACE_Stencil { + fonts[] = { + QPATHTOF(SairaStencilOne\ace_stencil64) + }; + }; }; diff --git a/addons/fonts/README.md b/addons/fonts/README.md index 7e6f704d67..98e530a75d 100644 --- a/addons/fonts/README.md +++ b/addons/fonts/README.md @@ -2,10 +2,3 @@ ace_fonts ======== Custom fonts including fixed-width font. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [jaynus](https://github.com/jaynus/) diff --git a/addons/fonts/SairaStencilOne/ace_stencil64-01.paa b/addons/fonts/SairaStencilOne/ace_stencil64-01.paa new file mode 100644 index 0000000000..8445f780a9 Binary files /dev/null and b/addons/fonts/SairaStencilOne/ace_stencil64-01.paa differ diff --git a/addons/fonts/SairaStencilOne/ace_stencil64.fxy b/addons/fonts/SairaStencilOne/ace_stencil64.fxy new file mode 100644 index 0000000000..d701a65c67 Binary files /dev/null and b/addons/fonts/SairaStencilOne/ace_stencil64.fxy differ diff --git a/addons/fortify/$PBOPREFIX$ b/addons/fortify/$PBOPREFIX$ new file mode 100644 index 0000000000..9d0a9e26d8 --- /dev/null +++ b/addons/fortify/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\fortify diff --git a/addons/fortify/ACEX_Fortify_Presets.hpp b/addons/fortify/ACEX_Fortify_Presets.hpp new file mode 100644 index 0000000000..edf12465ea --- /dev/null +++ b/addons/fortify/ACEX_Fortify_Presets.hpp @@ -0,0 +1,89 @@ +class ACEX_Fortify_Presets { + class small { + displayName = CSTRING(small); + objects[] = { + {"Land_BagFence_Round_F", 5}, + {"Land_BagFence_Short_F", 5}, + {"Land_BagFence_Long_F", 10}, + {"Land_Plank_01_4m_F", 10}, + {"Land_BagBunker_Small_F", 25} + }; + }; + class smallGreen { + displayName = CSTRING(smallGreen); + objects[] = { + {"Land_BagFence_01_round_green_F", 5}, + {"Land_BagFence_01_short_green_F", 5}, + {"Land_BagFence_01_long_green_F", 10}, + {"Land_Plank_01_4m_F", 10}, + {"Land_WoodenShelter_01_F", 25} + }; + }; + class medium { + displayName = CSTRING(medium); + objects[] = { + {"Land_HBarrierTower_F", 100}, + {"Land_HBarrierWall4_F", 25}, + {"Land_HBarrierWall_corner_F", 25}, + {"Land_HBarrier_1_F", 5} + }; + }; + class mediumGreen { + displayName = CSTRING(mediumGreen); + objects[] = { + {"Land_HBarrier_01_big_tower_green_F", 100}, + {"Land_HBarrier_01_wall_4_green_F", 25}, + {"Land_HBarrier_01_wall_corner_green_F", 25}, + {"Land_HBarrier_01_line_1_green_F", 5} + }; + }; + class big { + displayName = CSTRING(big); + objects[] = { + {"Land_BagBunker_Tower_F", 50}, + {"Land_BagBunker_Large_F", 100}, + {"Land_BagBunker_Small_F", 25}, + {"Land_Cargo_Patrol_V1_F", 100}, + {"Land_BagFence_Round_F", 5}, + {"Land_BagFence_Short_F", 5}, + {"Land_BagFence_Long_F", 10} + }; + }; + class bigGreen { + displayName = CSTRING(bigGreen); + objects[] = { + {"Land_PillboxBunker_01_big_F", 100}, + {"Land_PillboxWall_01_3m_F", 10}, + {"Land_PillboxWall_01_6m_F", 15}, + {"Land_PillboxBunker_01_hex_F", 50}, + {"Land_PillboxBunker_01_rectangle_F", 50}, + {"Land_Plank_01_8m_F", 10}, + {"Land_Plank_01_4m_F", 5}, + {"Land_BagFence_01_round_green_F", 5}, + {"Land_BagFence_01_short_green_F", 5}, + {"Land_BagFence_01_long_green_F", 10} + }; + }; + class bigCombo { + displayName = CSTRING(bigCombo); + objects[] = { + {"Land_BagBunker_Tower_F", 50, "big"}, + {"Land_BagBunker_Large_F", 100, "big"}, + {"Land_BagBunker_Small_F", 25, "big"}, + {"Land_Cargo_Patrol_V1_F", 100, "big"}, + {"Land_BagFence_Round_F", 5, "big"}, + {"Land_BagFence_Short_F", 5, "big"}, + {"Land_BagFence_Long_F", 10, "big"}, + {"Land_PillboxBunker_01_big_F", 100, "bigGreen"}, + {"Land_PillboxWall_01_3m_F", 10, "bigGreen"}, + {"Land_PillboxWall_01_6m_F", 15, "bigGreen"}, + {"Land_PillboxBunker_01_hex_F", 50, "bigGreen"}, + {"Land_PillboxBunker_01_rectangle_F", 50, "bigGreen"}, + {"Land_Plank_01_8m_F", 10, "bigGreen"}, + {"Land_Plank_01_4m_F", 5, "bigGreen"}, + {"Land_BagFence_01_round_green_F", 5, "bigGreen"}, + {"Land_BagFence_01_short_green_F", 5, "bigGreen"}, + {"Land_BagFence_01_long_green_F", 10, "bigGreen"} + }; + }; +}; diff --git a/addons/fortify/Cfg3DEN.hpp b/addons/fortify/Cfg3DEN.hpp new file mode 100644 index 0000000000..ce6085cf77 --- /dev/null +++ b/addons/fortify/Cfg3DEN.hpp @@ -0,0 +1,30 @@ +class Cfg3DEN { + class Attributes { + class Default; + class Title: Default { + class Controls { + class Title; + }; + }; + class Combo: Title { + class Controls: Controls { + class Title: Title {}; + class Value; + }; + }; + class GVAR(presetSelection): Combo { + class Controls: Controls { + class Title: Title {}; + class Value: Value { + delete Items; + class ItemsConfig { + path[] = {"ACEX_Fortify_Presets"}; + localConfig = 1; + propertyText = "displayName"; + sort = 1; + }; + }; + }; + }; + }; +}; diff --git a/addons/fortify/CfgEventHandlers.hpp b/addons/fortify/CfgEventHandlers.hpp new file mode 100644 index 0000000000..b468b9e8b5 --- /dev/null +++ b/addons/fortify/CfgEventHandlers.hpp @@ -0,0 +1,23 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + +class Extended_DisplayLoad_EventHandlers { + class RscDisplayMission { + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); + }; +}; diff --git a/addons/fortify/CfgVehicles.hpp b/addons/fortify/CfgVehicles.hpp new file mode 100644 index 0000000000..671652e974 --- /dev/null +++ b/addons/fortify/CfgVehicles.hpp @@ -0,0 +1,101 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ADDON { + displayName = CSTRING(Fortify); + condition = QUOTE([_player] call FUNC(canFortify)); + modifierFunction = QUOTE(call FUNC(modifyAction)); + insertChildren = QUOTE(_this call FUNC(addActions)); + statement = ""; + exceptions[] = {}; + showDisabled = 0; + priority = 1; + }; + }; + }; + class Logic; + class Module_F: Logic { + class AttributesBase { + class Default; + class Combo; + class Edit; + class Checkbox; + class ModuleDescription; + }; + class ModuleDescription; + }; + class ACE_Module: Module_F {}; + class XGVAR(setupModule): ACE_Module { + author = ECSTRING(common,ACETeam); + category = "ACE"; + displayName = CSTRING(Fortify); + function = QFUNC(setupModule); + scope = 2; + isGlobal = 0; + class Attributes: AttributesBase { + class Side: Combo { + displayName = "$STR_eval_typeside"; + property = QGVAR(setupModule_Side); + typeName = "NUMBER"; + defaultValue = 1; + class values { + class West { + name = "$STR_WEST"; + value = 1; + }; + class East { + name = "$STR_east"; + value = 2; + }; + class Indp { + name = "$STR_guerrila"; + value = 3; + }; + class Civ { + name = "$STR_civilian"; + value = 4; + }; + }; + }; + class Preset: Default { + displayName = "$STR_controls_presets"; + property = QGVAR(setupModule_Preset); + control = QGVAR(presetSelection); + typeName = "STRING"; + defaultValue = 0; + }; + class Budget: Edit { + property = QGVAR(setupModule_Budget); + displayName = CSTRING(budget); + typeName = "NUMBER"; + defaultValue = -1; + }; + class AddToolItem: Checkbox { + property = QGVAR(setupModule_AddToolItem); + displayName = CSTRING(addToolItem); + typeName = "BOOL"; + }; + class ModuleDescription: ModuleDescription {}; + }; + + class ModuleDescription: ModuleDescription { + description = CSTRING(moduleDescription); + }; + }; + + class XGVAR(buildLocationModule): ACE_Module { + author = ECSTRING(common,ACETeam); + category = "ACE"; + displayName = CSTRING(buildLocationModule); + scope = 2; + isGlobal = 1; + canSetArea = 1; + function = QFUNC(buildLocationModule); + class AttributeValues { + size3[] = {300, 300, -1}; + IsRectangle = 1; + }; + }; + +}; diff --git a/addons/fortify/CfgWeapons.hpp b/addons/fortify/CfgWeapons.hpp new file mode 100644 index 0000000000..66ff7f52d8 --- /dev/null +++ b/addons/fortify/CfgWeapons.hpp @@ -0,0 +1,17 @@ +class CfgWeapons { + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + class ACE_Fortify: ACE_ItemCore { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(FortifyItem_name); + descriptionShort = ""; + model = "\A3\Structures_F\Items\Tools\Hammer_F.p3d"; + picture = QPATHTOF(UI\hammer_ca.paa); + scope = 2; + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0; + }; + }; +}; diff --git a/addons/fortify/README.md b/addons/fortify/README.md new file mode 100644 index 0000000000..988699a706 --- /dev/null +++ b/addons/fortify/README.md @@ -0,0 +1,10 @@ +ace_fortify +============ + +Allows quick placement of fortifications. + +## ACEX Conversion - things still using acex prefix +- **Some** settings +- CfgVehicles Module Classnames +- `ACEX_Fortify_Presets` config +- Events (`acex_fortify_objectPlaced`, `acex_fortify_objectDeleted`, `acex_fortify_onDeployStart`) diff --git a/addons/fortify/UI/hammer_ca.paa b/addons/fortify/UI/hammer_ca.paa new file mode 100644 index 0000000000..a71d5fb197 Binary files /dev/null and b/addons/fortify/UI/hammer_ca.paa differ diff --git a/addons/fortify/XEH_PREP.hpp b/addons/fortify/XEH_PREP.hpp new file mode 100644 index 0000000000..785ba0a49f --- /dev/null +++ b/addons/fortify/XEH_PREP.hpp @@ -0,0 +1,18 @@ +ACEX_PREP(addDeployHandler); +ACEX_PREP(registerObjects); +ACEX_PREP(canFortify); +ACEX_PREP(deployObject); +ACEX_PREP(deployConfirm); +ACEX_PREP(handleScrollWheel); +ACEX_PREP(addActions); +ACEX_PREP(getCost); +ACEX_PREP(getBudget); +ACEX_PREP(updateBudget); +ACEX_PREP(axisLengths); +ACEX_PREP(handleChatCommand); +ACEX_PREP(parseSide); +ACEX_PREP(getPlaceableSet); +ACEX_PREP(modifyAction); +ACEX_PREP(setupModule); +ACEX_PREP(buildLocationModule); +ACEX_PREP(createObjectMarker); diff --git a/addons/fortify/XEH_missionDisplayLoad.sqf b/addons/fortify/XEH_missionDisplayLoad.sqf new file mode 100644 index 0000000000..9f07b0bc29 --- /dev/null +++ b/addons/fortify/XEH_missionDisplayLoad.sqf @@ -0,0 +1,15 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +params ["_display"]; + +_display displayAddEventHandler ["MouseZChanged", { + (_this select 1) call FUNC(handleScrollWheel); +}]; + +_display displayAddEventHandler ["MouseButtonDown", { + if (GVAR(isPlacing) != PLACE_WAITING) exitWith {false}; + if ((_this select 1) != 1) exitWith {false}; + GVAR(isPlacing) = PLACE_CANCEL +}]; diff --git a/addons/fortify/XEH_postInit.sqf b/addons/fortify/XEH_postInit.sqf new file mode 100644 index 0000000000..ed13a116c7 --- /dev/null +++ b/addons/fortify/XEH_postInit.sqf @@ -0,0 +1,106 @@ +#include "script_component.hpp" + +if (isServer) then { + [QGVAR(registerObjects), LINKFUNC(registerObjects)] call CBA_fnc_addEventHandler; + [QXGVAR(objectPlaced), { + params ["_unit", "_side", "_object"]; + TRACE_3("objectPlaced",_unit,_side,_object); + private _jipID = [QGVAR(addActionToObject), [_side, _object]] call CBA_fnc_globalEventJIP; + [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; // idealy this function should be called on the server + + if (GVAR(markObjectsOnMap) isNotEqualTo 0 && {_object isKindOf "Static"}) then { + // Wait ensures correct marker pos/rot as object is moved into position after creation + [ + FUNC(createObjectMarker), + [_unit, _object], + 1 + ] call CBA_fnc_waitAndExecute; + }; + }] call CBA_fnc_addEventHandler; +}; + +if (!hasInterface) exitWith {}; + +GVAR(isPlacing) = PLACE_CANCEL; +["ace_interactMenuOpened", {GVAR(isPlacing) = PLACE_CANCEL}] call CBA_fnc_addEventHandler; + +GVAR(objectRotationX) = 0; +GVAR(objectRotationY) = 0; +GVAR(objectRotationZ) = 0; + +// Register CBA Chat command for admins (Example: #ace-fortify west small 200) +["ace-fortify", LINKFUNC(handleChatCommand), "admin"] call CBA_fnc_registerChatCommand; + +[QGVAR(sideBudgetHint), { + params ["_side"]; + if (_side isEqualTo side group ACE_player && {XGVAR(settingHint) isEqualTo 2 || {XGVAR(settingHint) isEqualTo 1 && {"ACE_Fortify" in (ACE_player call EFUNC(common,uniqueItems))}}}) then { + private _budget = [_side] call FUNC(getBudget); + TRACE_2("sideBudgetHint",_side,_budget); + [format ["%1 $%2", LLSTRING(Budget), _budget]] call EFUNC(common,displayTextStructured); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(addActionToObject), { + params ["_side", "_object"]; + TRACE_2("addActionToObject EH",_side,_object); + if (isNull _object) exitWith {}; + if (_side isEqualTo side group ace_player) then { + private _budget = [_side] call FUNC(getBudget); + private _cost = [_side, typeOf _object] call FUNC(getCost); + private _text = [format ["Remove Object +$%1", _cost], "Remove Object"] select (_budget == -1); + + // Remove object action + private _removeAction = [ + QGVAR(removeObject), + _text, + "", + { + params ["_target", "_player", "_params"]; + _params params ["_side"]; + TRACE_2("deleting placed object",_target,_params); + [QXGVAR(objectDeleted), [_player, _side, _target]] call CBA_fnc_globalEvent; + deleteVehicle _target; + _params call FUNC(updateBudget); + }, + {(missionNamespace getVariable [QGVAR(fortifyAllowed), true]) && {"ACE_Fortify" in (_player call EFUNC(common,uniqueItems))}}, + {}, + [_side, _cost], + {[0, 0, 0]}, + 5 + ] call EFUNC(interact_menu,createAction); + + [_object, 0, ["ACE_MainActions"], _removeAction] call EFUNC(interact_menu,addActionToObject); + }; +}] call CBA_fnc_addEventHandler; + +// Place object event handler +[QGVAR(deployFinished), { + params ["_args", "_elapsedTime", "_totalTime", "_errorCode"]; + _args params ["_unit", "_side", "_typeOf", "_posASL", "_vectorDir", "_vectorUp", "_cost"]; + + private _newObject = _typeOf createVehicle _posASL; + _newObject setPosASL _posASL; + _newObject setVectorDirAndUp [_vectorDir, _vectorUp]; + + // Server will use this event to run the jip compatible QGVAR(addActionToObject) event and create the related map marker + [QXGVAR(objectPlaced), [_unit, _side, _newObject]] call CBA_fnc_globalEvent; + + if (cba_events_control) then { + // Re-run if ctrl key held + [_unit, _unit, [_side, _typeOf, [GVAR(objectRotationX), GVAR(objectRotationY), GVAR(objectRotationZ)]]] call FUNC(deployObject); + }; + + // Reset animation + [_unit, "", 1] call EFUNC(common,doAnimation); +}] call CBA_fnc_addEventHandler; + +[QGVAR(deployCanceled), { + params ["_args", "_elapsedTime", "_totalTime", "_errorCode"]; + _args params ["_unit", "_side", "_typeOf", "_posASL", "_vectorDir", "_vectorUp", "_cost"]; + + // Refund if deploy was canceled + [_side, _cost] call FUNC(updateBudget); + + // Reset animation + [_unit, "", 1] call EFUNC(common,doAnimation); +}] call CBA_fnc_addEventHandler; diff --git a/addons/fortify/XEH_preInit.sqf b/addons/fortify/XEH_preInit.sqf new file mode 100644 index 0000000000..382fc80566 --- /dev/null +++ b/addons/fortify/XEH_preInit.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +// Init array of build locations at preinit +// Can add anything that would work in inArea (triggers, markers or array format [center, a, b, angle, isRectangle, c]) +GVAR(locations) = []; + +// Custom deploy handlers +GVAR(deployHandlers) = []; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/fortify/XEH_preStart.sqf b/addons/fortify/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/fortify/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/fortify/config.cpp b/addons/fortify/config.cpp new file mode 100644 index 0000000000..ab12338982 --- /dev/null +++ b/addons/fortify/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {QXGVAR(setupModule), QXGVAR(buildLocationModule)}; + weapons[] = {"ACE_Fortify"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Kingsley"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; + + BWC_CONFIG(XADDON); +}; + +#include "Cfg3DEN.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" + +#include "ACEX_Fortify_Presets.hpp" diff --git a/addons/fortify/functions/fnc_addActions.sqf b/addons/fortify/functions/fnc_addActions.sqf new file mode 100644 index 0000000000..4802effa01 --- /dev/null +++ b/addons/fortify/functions/fnc_addActions.sqf @@ -0,0 +1,67 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Adds the child actions. + * + * Arguments: + * 0: Player + * + * Return Value: + * Actions + * + * Example: + * [player] call ace_fortify_fnc_addActions + * + * Public: No + */ + +params ["_player"]; + +private _side = side group _player; +private _objects = missionNamespace getVariable [format [QGVAR(Objects_%1), _side], []]; +private _actions = []; +private _infiniteBudget = ([side group _player] call FUNC(getBudget)) == -1; +private _subActions = createHashmap; + +{ + _x params ["_classname", "_cost", ["_category", ""]]; + + private _displayName = getText (configFile >> "CfgVehicles" >> _classname >> "displayName"); + + private _action = [ + _classname, + if (_infiniteBudget) then { _displayName } else { format ["$%1 - %2", _cost, _displayName] }, + "", + LINKFUNC(deployObject), + { + params ["", "_player", "_args"]; + + private _cost = _args call FUNC(getCost); + private _budget = [side group _player] call FUNC(getBudget); + _budget == -1 || {_budget >= _cost} + }, + {}, + [_side, _classname] + ] call EFUNC(interact_menu,createAction); + + if (_category == "") then { + _actions pushBack [_action, [], _player]; + } else { + private _categoryActions = _subActions getOrDefault [_category, [], true]; + _categoryActions pushBack [_action, [], _player]; + }; +} forEach _objects; + +{ + private _displayName = if (isLocalized _x) then { + localize _x + } else { + if (isText (configFile >> "ACEX_Fortify_Presets" >> _x >> "displayName")) exitWith { getText (configFile >> "ACEX_Fortify_Presets" >> _x >> "displayName") }; + if (isText (missionConfigFile >> "ACEX_Fortify_Presets" >> _x >> "displayName")) exitWith { getText (missionConfigFile >> "ACEX_Fortify_Presets" >> _x >> "displayName") }; + _x + }; + private _action = [_x, _displayName, "", {}, {true}] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, _y, _player]; +} forEach _subActions; + +_actions diff --git a/addons/fortify/functions/fnc_addDeployHandler.sqf b/addons/fortify/functions/fnc_addDeployHandler.sqf new file mode 100644 index 0000000000..4eef1ad0ae --- /dev/null +++ b/addons/fortify/functions/fnc_addDeployHandler.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Cuel, mharis001 + * Adds a custom deploy handler. + * Code needs to return BOOL: true (allowed) / false (blocked). + * + * Arguments: + * 0: Code + * - Passed [Unit , Object being placed , Cost ] + * + * Return Value: + * None + * + * Example: + * [{(_this select 0) getVariable ["isBobTheBuilder", false]}] call ace_fortify_fnc_addDeployHandler + * + * Public: Yes + */ + +params [["_code", {}, [{}]]]; + +if (_code isEqualTo {} || {_code isEqualTo {true}}) exitWith {}; +GVAR(deployHandlers) pushBack _code; diff --git a/addons/fortify/functions/fnc_axisLengths.sqf b/addons/fortify/functions/fnc_axisLengths.sqf new file mode 100644 index 0000000000..f68939bfa7 --- /dev/null +++ b/addons/fortify/functions/fnc_axisLengths.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Gets the longest axis of the bounding box of the given object. + * + * Arguments: + * 0: Object + * + * Return Value: + * Lengths + * + * Example: + * [_object] call ace_fortify_fnc_axisLengths; + * + * Public: Yes + */ + +params [["_object", objNull, [objNull]]]; + +(boundingBoxReal _object) params ["_p1", "_p2"]; + +[ + (abs ((_p2 select 0) - (_p1 select 0))), + (abs ((_p2 select 1) - (_p1 select 1))), + (abs ((_p2 select 2) - (_p1 select 2))) +] diff --git a/addons/fortify/functions/fnc_buildLocationModule.sqf b/addons/fortify/functions/fnc_buildLocationModule.sqf new file mode 100644 index 0000000000..c777b80d4e --- /dev/null +++ b/addons/fortify/functions/fnc_buildLocationModule.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Handles build location module + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [logic] call ace_fortify_fnc_buildLocationModule + * + * Public: No + */ + +params ["_logic"]; +TRACE_1("buildLocations",_logic); + +private _area = _logic getvariable ["objectArea",[0,0,0,false,0]]; // seems to be set via the canSetArea config +if ((_area param [0, 0]) == 0) exitWith {WARNING_1("Bad size? %1",_area);}; +private _locationArray = [_logic]; +_locationArray append _area; + +TRACE_1("Adding build location",_locationArray); +GVAR(locations) pushBack _locationArray; diff --git a/addons/fortify/functions/fnc_canFortify.sqf b/addons/fortify/functions/fnc_canFortify.sqf new file mode 100644 index 0000000000..3a382bc98c --- /dev/null +++ b/addons/fortify/functions/fnc_canFortify.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Checks whether the given player can fortify. + * + * Arguments: + * 0: Player + * 1: Cost (default: 0) + * + * Return Value: + * Can Fortify + * + * Example: + * [player] call ace_fortify_fnc_canFortify + * + * Public: Yes + */ + +params ["_player", ["_cost", 0]]; + +(missionNamespace getVariable [QGVAR(fortifyAllowed), true]) && +{"ACE_Fortify" in (_player call EFUNC(common,uniqueItems))} && +{ + private _budget = [side group _player] call FUNC(getBudget); + ((_budget == -1) || {_budget >= _cost}) +} && { + private _inArea = GVAR(locations) isEqualTo []; + { + if (_player inArea _x) exitWith {_inArea = true}; + } forEach GVAR(locations); + _inArea +} diff --git a/addons/fortify/functions/fnc_createObjectMarker.sqf b/addons/fortify/functions/fnc_createObjectMarker.sqf new file mode 100644 index 0000000000..ce6fd279b0 --- /dev/null +++ b/addons/fortify/functions/fnc_createObjectMarker.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: Seb + * Creates a map marker for a created static object but only for sides friendly to the creator side. + * + * Arguments: + * 0: Unit placing + * 1: Created fortify object + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_fortify_fnc_createObjectMarker + * + * Public: No + */ + +params ["_unit", "_object"]; +TRACE_2("createObjectMarker",_unit,_object); + +// Get Object size and direction +private _bbr = 0 boundingBoxReal _object; +private _p1 = _bbr select 0; +private _p2 = _bbr select 1; +private _maxWidth = abs ((_p2 select 0) - (_p1 select 0)); +private _maxLength = abs ((_p2 select 1) - (_p1 select 1)); +private _direction = getDir _object; + +// Marker name unique to this object +private _markerNameStr = format [QGVAR(marker_%1), hashValue _object]; +private _channel = parseNumber (GVAR(markObjectsOnMap) != 2); + +private _marker = createMarkerLocal [_markerNameStr, _object, _channel, _unit]; +TRACE_2("created",_marker,_channel); +_marker setMarkerShapeLocal "RECTANGLE"; +_marker setMarkerBrushLocal "SolidFull"; +_marker setMarkerSizeLocal [(_maxWidth / 2),(_maxLength / 2)]; +_marker setMarkerDirLocal _direction; +_marker setMarkerColor "ColorGrey"; +_object setVariable [QGVAR(mapMarker), _marker, false]; + +_object addEventHandler ["Deleted", { + params ["_object"]; + private _marker = _object getVariable QGVAR(mapMarker); + TRACE_2("cleaning up marker",_object,_marker); + deleteMarker _marker +}]; diff --git a/addons/fortify/functions/fnc_deployConfirm.sqf b/addons/fortify/functions/fnc_deployConfirm.sqf new file mode 100644 index 0000000000..b0105a7919 --- /dev/null +++ b/addons/fortify/functions/fnc_deployConfirm.sqf @@ -0,0 +1,57 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Confirms the deployment. + * + * Arguments: + * 0: Player + * 1: Fortify Object + * + * Return Value: + * None + * + * Example: + * [player, wall] call ace_fortify_fnc_deployConfirm + * + * Public: No + */ + +params ["_unit", "_object"]; +TRACE_2("deployConfirm",_unit,_object); + +private _side = side group _unit; +private _typeOf = typeOf _object; +private _cost = [_side, _typeOf] call FUNC(getCost); +[_side, -_cost] call FUNC(updateBudget); + +private _posASL = getPosASL _object; +private _vectorUp = vectorUp _object; +private _vectorDir = vectorDir _object; + +deleteVehicle _object; + +// Create progress bar to place object +private _totalTime = _cost * GVAR(timeCostCoefficient) + GVAR(timeMin); // time = Ax + b + +private _perframeCheck = { + params ["_args", "_elapsedTime", "_totalTime", "_errorCode"]; + _args params ["_unit", "_side", "_typeOf", "_posASL", "_vectorDir", "_vectorUp", "_cost"]; + + // Animation loop (required for longer constructions) + if (_totalTime != 0 && {animationState _unit != "AinvPknlMstpSnonWnonDnon_medic4"}) then { + // Perform animation + [_unit, "AinvPknlMstpSnonWnonDnon_medic4"] call EFUNC(common,doAnimation); + }; + + // Return true always + true +}; + +[ + _totalTime, + [_unit, _side, _typeOf, _posASL, _vectorDir, _vectorUp, _cost], + QGVAR(deployFinished), + QGVAR(deployCanceled), + LLSTRING(progressBarTitle), + _perframeCheck +] call EFUNC(common,progressBar); diff --git a/addons/fortify/functions/fnc_deployObject.sqf b/addons/fortify/functions/fnc_deployObject.sqf new file mode 100644 index 0000000000..f7e9e6dbad --- /dev/null +++ b/addons/fortify/functions/fnc_deployObject.sqf @@ -0,0 +1,99 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Deploys the object to the player for them to move it around. + * + * Arguments: + * 0: Target + * 1: Player + * 2: Object params (side, classname, rotations) + * + * Return Value: + * None + * + * Example: + * [player, player, [west, "Land_BagBunker_Small_F"]] call ace_fortify_fnc_deployObject + * + * Public: No + */ + +params ["", "_player", "_params"]; +_params params [["_side", sideUnknown, [sideUnknown]], ["_classname", "", [""]], ["_rotations", [0,0,0]]]; +TRACE_4("deployObject",_player,_side,_classname,_rotations); + +private _budget = [_side] call FUNC(getBudget); +private _cost = [_side, _classname] call FUNC(getCost); + +// Create a local only copy of the object +private _object = _classname createVehicleLocal [0, 0, 0]; +_object disableCollisionWith _player; + +GVAR(objectRotationX) = _rotations select 0; +GVAR(objectRotationY) = _rotations select 1; +GVAR(objectRotationZ) = _rotations select 2; + +GVAR(isPlacing) = PLACE_WAITING; + +private _lmb = LLSTRING(confirm); +if (_budget > -1) then {_lmb = _lmb + format [" -$%1", _cost];}; +private _rmb = localize ELSTRING(Common,Cancel); +private _wheel = LLSTRING(rotate); +private _xAxis = localize "str_disp_conf_xaxis"; +private _icons = [["alt", localize "str_3den_display3den_entitymenu_movesurface_text"], ["shift", localize "str_disp_conf_xaxis" + " " + _wheel], ["control", localize "str_disp_conf_yaxis" + " " + _wheel]]; +[_lmb, _rmb, _wheel, _icons] call EFUNC(interaction,showMouseHint); + +private _mouseClickID = [_player, "DefaultAction", {GVAR(isPlacing) == PLACE_WAITING}, {GVAR(isPlacing) = PLACE_APPROVE}] call EFUNC(common,addActionEventHandler); +[QXGVAR(onDeployStart), [_player, _object, _cost]] call CBA_fnc_localEvent; + +[{ + params ["_args", "_pfID"]; + _args params ["_unit", "_object", "_cost", "_mouseClickID"]; + + if (_unit != ACE_player || {isNull _object} || {!([_unit, _object, []] call EFUNC(common,canInteractWith))} || {!([_unit, _cost] call FUNC(canFortify))}) then { + GVAR(isPlacing) = PLACE_CANCEL; + }; + + // If place approved, verify deploy handlers + if (GVAR(isPlacing) == PLACE_APPROVE && {(GVAR(deployHandlers) findIf {([_unit, _object, _cost] call _x) isEqualTo false}) > -1}) then { + GVAR(isPlacing) = PLACE_WAITING; + }; + + if (GVAR(isPlacing) != PLACE_WAITING) exitWith { + TRACE_3("exiting PFEH",GVAR(isPlacing),_pfID,_mouseClickID); + [_pfID] call CBA_fnc_removePerFrameHandler; + call EFUNC(interaction,hideMouseHint); + [_unit, "DefaultAction", _mouseClickID] call EFUNC(common,removeActionEventHandler); + + if (GVAR(isPlacing) == PLACE_APPROVE) then { + TRACE_1("deploying object",_object); + GVAR(isPlacing) = PLACE_CANCEL; + [_unit, _object] call FUNC(deployConfirm); + } else { + TRACE_1("deleting object",_object); + [QGVAR(onDeployStop), [_unit, _object, _cost]] call CBA_fnc_localEvent; + deleteVehicle _object; + }; + }; + + ([_object] call FUNC(axisLengths)) params ["_width", "_length", "_height"]; + private _distance = (_width max _length) + 0.5; // for saftey, move it a bit extra away from player's center + + private _start = eyePos _unit; + private _camViewDir = getCameraViewDirection _unit; + private _basePos = _start vectorAdd (_camViewDir vectorMultiply _distance); + _basePos set [2, ((_basePos select 2) - (_height / 2)) max (getTerrainHeightASL _basePos - 0.05)]; + + _object setPosASL _basePos; + + private _vZ = 180 + GVAR(objectRotationZ) + getDir _unit; + if (cba_events_alt) then { + // Snap to terrain surface dir + _object setDir _vZ; + _object setVectorUp (surfaceNormal _basePos); + } else { + [_object, GVAR(objectRotationX), GVAR(objectRotationY), _vZ] call EFUNC(common,setPitchBankYaw); + }; + #ifdef DEBUG_MODE_FULL + hintSilent format ["Rotation:\nX: %1\nY: %2\nZ: %3", GVAR(objectRotationX), GVAR(objectRotationY), GVAR(objectRotationZ)]; + #endif +}, 0, [_player, _object, _cost, _mouseClickID]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fortify/functions/fnc_getBudget.sqf b/addons/fortify/functions/fnc_getBudget.sqf new file mode 100644 index 0000000000..44b254eae9 --- /dev/null +++ b/addons/fortify/functions/fnc_getBudget.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Gets the budget for the given side. + * + * Arguments: + * 0: Side + * + * Return Value: + * Budget + * + * Example: + * [west] call ace_fortify_fnc_getBudget + * + * Public: Yes + */ + +params ["_side"]; + +(missionNamespace getVariable [format [QGVAR(Budget_%1), _side], -1]) diff --git a/addons/fortify/functions/fnc_getCost.sqf b/addons/fortify/functions/fnc_getCost.sqf new file mode 100644 index 0000000000..a55e39f299 --- /dev/null +++ b/addons/fortify/functions/fnc_getCost.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Gets the cost for the given side and classname. + * + * Arguments: + * 0: Side + * 1: Classname + * + * Return Value: + * Cost + * + * Example: + * [west, "Sandbag"] call ace_fortify_fnc_getCost + * + * Public: Yes + */ + +params ["_side", "_classname"]; + +private _objects = missionNamespace getVariable [format [QGVAR(Objects_%1), _side], []]; + +(((_objects select {(_x select 0) == _classname}) param [0, []]) param [1, 0]) diff --git a/addons/fortify/functions/fnc_getPlaceableSet.sqf b/addons/fortify/functions/fnc_getPlaceableSet.sqf new file mode 100644 index 0000000000..9643d54190 --- /dev/null +++ b/addons/fortify/functions/fnc_getPlaceableSet.sqf @@ -0,0 +1,49 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Gets placeable object classnames and values. + * + * Arguments: + * 0: Size + * + * Return Value: + * Pairs of classnames and costs + * + * Example: + * ["small"] call ace_fortify_fnc_getPlaceableSet + * + * Public: No + */ + +params ["_preset"]; +TRACE_1("getPlaceableSet",_preset); + +private _config = missionConfigFile >> "ACEX_Fortify_Presets" >> _preset; +if (!isClass _config) then { + _config = configfile >> "ACEX_Fortify_Presets" >> _preset; +}; +if (!isClass _config) exitWith { + private _msg = format ["Could not find [%1]", _preset]; + ERROR_WITH_TITLE("Preset not found",_msg); + [] +}; + +private _objects = getArray (_config >> "objects"); + +// Attempt to filter bad input +_objects = _objects select { + if ((_x isEqualTypeParams ["", 0]) || {_x isEqualTypeParams ["", 0, ""]}) then { + _x params [["_classname", "#", [""]], ["_cost", -1, [0]]]; + if (isClass (configFile >> "CfgVehicles" >> _classname)) then { + true + } else { + ERROR_2("Preset [%1] - Classname does not exist",_preset,_classname); + false + }; + } else { + ERROR_2("Preset [%1] - Bad data in objects array %2",_preset,_x); + false + }; +}; + +_objects diff --git a/addons/fortify/functions/fnc_handleChatCommand.sqf b/addons/fortify/functions/fnc_handleChatCommand.sqf new file mode 100644 index 0000000000..1422558de8 --- /dev/null +++ b/addons/fortify/functions/fnc_handleChatCommand.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Handles the chat command usage by admin. + * + * Arguments: + * 0: Chat Text + * + * Return Value: + * None + * + * Example: + * [""] call ace_fortify_fnc_handleChatCommand + * + * Public: No + */ + +params ["_args"]; +TRACE_1("handleChatCommand",_args); + +_args = _args splitString " "; +if (_args isEqualTo []) exitWith {ERROR("Bad command");}; +private _command = toLowerANSI (_args select 0); +_args deleteAt 0; + +switch (_command) do { + // Turns fortify mode on + case "on": { + missionNamespace setVariable [QGVAR(fortifyAllowed), true, true]; + }; + + // Turns fortify mode off + case "off": { + missionNamespace setVariable [QGVAR(fortifyAllowed), false, true]; + }; + + // Registers fortify presets for given side + default { + _args params [["_preset", "small"], ["_budget", "-1"]]; + + private _side = [_command] call FUNC(parseSide); + _budget = parseNumber _budget; + + private _objects = [_preset] call FUNC(getPlaceableSet); + + [QGVAR(registerObjects), [_side, _budget, _objects]] call CBA_fnc_serverEvent; + }; +}; diff --git a/addons/fortify/functions/fnc_handleScrollWheel.sqf b/addons/fortify/functions/fnc_handleScrollWheel.sqf new file mode 100644 index 0000000000..fa5007cd51 --- /dev/null +++ b/addons/fortify/functions/fnc_handleScrollWheel.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Handles the object direction. + * + * Arguments: + * 0: Scroll + * + * Return Value: + * Handled + * + * Example: + * [5] call ace_fortify_fnc_handleScrollWheel + * + * Public: No + */ + +if (GVAR(isPlacing) != PLACE_WAITING) exitWith {false}; + +params ["_scroll"]; + +if (cba_events_shift) exitWith { + GVAR(objectRotationX) = GVAR(objectRotationX) + (_scroll * 5); + true +}; + +if (cba_events_control) exitWith { + GVAR(objectRotationY) = GVAR(objectRotationY) + (_scroll * 5); + true +}; + +GVAR(objectRotationZ) = GVAR(objectRotationZ) + (_scroll * 5); +true diff --git a/addons/fortify/functions/fnc_modifyAction.sqf b/addons/fortify/functions/fnc_modifyAction.sqf new file mode 100644 index 0000000000..08da255a46 --- /dev/null +++ b/addons/fortify/functions/fnc_modifyAction.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Modifies the fortify action, shows current budget. + * + * Arguments: + * 0: Target + * 1: Player + * 2: Args + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [player, player, [], []] call ace_fortify_fnc_modifyAction + * + * Public: No + */ + +params ["", "_player", "", "_actionData"]; + +private _budget = [side group _player] call FUNC(getBudget); +private _actionText = if (_budget > 0) then { + format ["%1 [$%2]", LLSTRING(fortify), _budget]; +} else { + LLSTRING(fortify); +}; + +_actionData set [1, _actionText]; diff --git a/addons/fortify/functions/fnc_parseSide.sqf b/addons/fortify/functions/fnc_parseSide.sqf new file mode 100644 index 0000000000..6af2fac4b4 --- /dev/null +++ b/addons/fortify/functions/fnc_parseSide.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Parses the given text and returns a side. + * + * Arguments: + * 0: Text + * + * Return Value: + * Side + * + * Example: + * ["blufor"] call ace_fortify_fnc_parseSide; + * ["west"] call ace_fortify_fnc_parseSide; + * ["b"] call ace_fortify_fnc_parseSide; + * + * Public: Yes + */ + +params ["_side"]; +TRACE_1("parseSide",_side); + +if (_side isEqualType sideUnknown) exitWith {_side}; + +private _char = toLowerANSI (_side select [0, 1]); + +private _return = switch (_char) do { + case ("b"); + case ("w"): {west}; + case ("o"); + case ("e"): {east}; + case ("r"); + case ("i"): {resistance}; + case ("c"): {civilian}; + default {sideUnknown}; +}; + +TRACE_2("",_char,_return); +_return diff --git a/addons/fortify/functions/fnc_registerObjects.sqf b/addons/fortify/functions/fnc_registerObjects.sqf new file mode 100644 index 0000000000..7fea4996a4 --- /dev/null +++ b/addons/fortify/functions/fnc_registerObjects.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Registers the given objects in the given side's player interaction menu. + * Players on that side must have the pickaxe item in their inventory to access the menu. + * Classnames must be in the format [, , ] + * MUST BE CALLED ON SERVER! + * + * Arguments: + * 0: Side + * 1: Budget + * 2: Object Classnames + * + * Return Value: + * None + * + * Example: + * [west, 5000, [["Land_BagFence_Long_F", 5], ["Land_BagBunker_Small_F", 50]]] call ace_fortify_fnc_registerObjects + * [west, 5000, [["Land_BagFence_Long_F", 5, "tan"], ["Land_BagFence_01_long_green_F", 5, "green"]]] call ace_fortify_fnc_registerObjects + * + * Public: Yes + */ + +if (!isServer) exitWith {}; + +params [["_side", sideUnknown, [sideUnknown]], ["_budget", -1, [0]], ["_objects", [], [[]]]]; +TRACE_3("registerObjects",_side,_budget,_objects); + +if (_side isEqualTo sideUnknown) exitWith {ERROR_1("Bad Side %1",_this);}; + +_objects = _objects select { + private _isValid = _x params [["_xClassname", "", [""]], ["_xCost", 0, [0]]]; + private _category = toLower (_x param [2, "", [""]]); + if (_category != "") then { _x set [2, _category]; }; + + if (_isValid) then { + _isValid = isClass (configFile >> "CfgVehicles" >> _xClassname); + if (!_isValid) then {WARNING_1("Classname does not exist in CfgVehicles %1",_x);}; + } else { + WARNING_1("Bad classname/cost input %1, should be [,]",_x); + }; + _isValid +}; + +if (!isNil {missionNamespace getVariable format [QGVAR(Budget_%1), _side]}) then { + INFO_1("Overwriting previous budget for side [%1]",_side); +}; +if (!isNil {missionNamespace getVariable format [QGVAR(Objects_%1), _side]}) then { + INFO_1("Overwriting previous objects for side [%1]",_side); +}; + +missionNamespace setVariable [format [QGVAR(Budget_%1), _side], _budget, true]; +missionNamespace setVariable [format [QGVAR(Objects_%1), _side], _objects, true]; diff --git a/addons/fortify/functions/fnc_setupModule.sqf b/addons/fortify/functions/fnc_setupModule.sqf new file mode 100644 index 0000000000..1215393a46 --- /dev/null +++ b/addons/fortify/functions/fnc_setupModule.sqf @@ -0,0 +1,72 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Handles setup module. + * + * Arguments: + * 0: The module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [logic, [], true] call ace_fortify_fnc_setupModule + * + * Public: No + */ + +params ["_logic", "", "_activated"]; +TRACE_2("setupModule",_logic,_activated); + +// Note: no changes needed here for cba-setting switch +if (!isServer) exitWith {}; +if (!_activated) exitWith {}; + + +private _side = _logic getVariable ["Side", 1]; +_side = switch (_side) do { + case (1): {west}; + case (2): {east}; + case (3): {resistance}; + case (4): {civilian}; + default {sideUnknown}; +}; + +private _preset = _logic getVariable ["Preset", "small"]; +if IS_NUMBER(_preset) then { // Legacy support + _preset = switch (_preset) do { + case 1: {"small"}; + case 2: {"medium"}; + case 3: {"big"}; + case 4: {"smallGreen"}; + case 5: {"mediumGreen"}; + case 6: {"bigGreen"}; + default {"?"}; + }; +}; + +private _budget = _logic getVariable ["Budget", -1]; +if !(_budget isEqualType 0) then {_budget = -1}; + +private _addToolItem = _logic getVariable ["AddToolItem", false]; +if !(_addToolItem isEqualType false) then {_addToolItem = false}; + + +private _objects = [_preset] call FUNC(getPlaceableSet); +[QGVAR(registerObjects), [_side, _budget, _objects]] call CBA_fnc_serverEvent; + +if (_addToolItem) then { + [{ + params ["_side"]; + TRACE_1("Adding tool",_side); + { + if (((side group _x) == _side) && {!("ACE_Fortify" in (_x call EFUNC(common,uniqueItems)))}) then { + _x addItem "ACE_Fortify"; + }; + } forEach allUnits; + }, [_side], 3] call CBA_fnc_waitAndExecute; +}; + +INFO_4("Fortify Module Actived [Side: %1][Preset: %2][Budget: %3][AutoAdd: %4]",_side,_preset,_budget,_addToolItem); diff --git a/addons/fortify/functions/fnc_updateBudget.sqf b/addons/fortify/functions/fnc_updateBudget.sqf new file mode 100644 index 0000000000..fe6d89dca2 --- /dev/null +++ b/addons/fortify/functions/fnc_updateBudget.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Updates the given sides budget. + * + * Arguments: + * 0: Side + * 1: Change (default: 0) + * 2: Display hint (default: true) + * + * Return Value: + * None + * + * Example: + * [west, -250, false] call ace_fortify_fnc_updateBudget + * + * Public: Yes + */ + +params [["_side", sideUnknown, [sideUnknown]], ["_change", 0, [0]], ["_hint", true, [true]]]; +TRACE_3("updateBudget",_side,_change,_hint); + +if (_side isEqualTo sideUnknown) exitWith {ERROR("Unknown side");}; + +private _budget = [_side] call FUNC(getBudget); +private _newBudget = _budget + _change; + +_newBudget = 0 max _newBudget; + +if (_budget != -1) then { + missionNamespace setVariable [format [QGVAR(Budget_%1), _side], _newBudget, true]; + + if (_hint) then { + [QGVAR(sideBudgetHint), [_side]] call CBA_fnc_globalEvent; + }; +}; diff --git a/addons/fortify/initSettings.inc.sqf b/addons/fortify/initSettings.inc.sqf new file mode 100644 index 0000000000..aa8d62f5c4 --- /dev/null +++ b/addons/fortify/initSettings.inc.sqf @@ -0,0 +1,44 @@ +[ + QXGVAR(settingHint), + "LIST", + [LLSTRING(settingHint), LLSTRING(settingHintDesc)], + LLSTRING(settingsCategory), + [ + [0, 1, 2], + [LLSTRING(settingHintNone), LLSTRING(settingHintHasTool), LLSTRING(settingHintEveryone)], + 2 + ] +] call CBA_fnc_addSetting; + +[ + QGVAR(timeCostCoefficient), + "SLIDER", + [LLSTRING(settingHint_timeCostCoefficient), LLSTRING(settingHintDesc_timeCostCoefficient)], + LLSTRING(settingsCategory), + [0, 10, 1, 2], // Min, Max, Default, Trailing Decimals, is Percentage + true //isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(timeMin), + "SLIDER", + [LLSTRING(settingHint_timeMin), LLSTRING(settingHintDesc_timeMin)], + LLSTRING(settingsCategory), + [0, 25, 1.5, 2], // Min, Max, Default, Trailing Decimals, is Percentage + true //isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(markObjectsOnMap), + "LIST", + [LLSTRING(markObjectsOnMap), LLSTRING(markObjectsOnMapDesc)], + LLSTRING(settingsCategory), + [ + [0, 1, 2], + [LLSTRING(markObjectsOnMapNone), LLSTRING(markObjectsOnMapFriendly), LLSTRING(markObjectsOnMapEveryone)], + 1 + ], + true, + {}, + true +] call CBA_fnc_addSetting; diff --git a/addons/fortify/script_component.hpp b/addons/fortify/script_component.hpp new file mode 100644 index 0000000000..82dddfab77 --- /dev/null +++ b/addons/fortify/script_component.hpp @@ -0,0 +1,24 @@ +#define COMPONENT fortify +#define COMPONENT_BEAUTIFIED Fortify +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_FORTIFY + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_FORTIFY + #define DEBUG_SETTINGS DEBUG_SETTINGS_FORTIFY +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + + +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +#define PLACE_WAITING -1 +#define PLACE_CANCEL 0 +#define PLACE_APPROVE 1 diff --git a/addons/fortify/stringtable.xml b/addons/fortify/stringtable.xml new file mode 100644 index 0000000000..15150d6685 --- /dev/null +++ b/addons/fortify/stringtable.xml @@ -0,0 +1,452 @@ + + + + + Fortify + Verstärken + 要塞 + 요새화 + Fortifica + 要塞 + 设防 + Fortyfikowanie + Фортификация + Inşa Etme + Fortificar + Fortification + Fortificação + + + Fortify Tool + Bauwerkzeug + Attrezzo di Fortificazione + 要塞ツール + 요새화 도구 + 要塞工具 + 设防工具 + Narzędzie do fortyfikowania + Инструмент строителя + Inşa Etme Aleti + Herramienta de Fortificar + Outil de fortification + Ferramenta de Fortificação + + + Budget + Budget + 予算 + Budget + 예산 + 預算 + 预算 + Budżet + Бюджет + Bütçe + Presupuesto + Budget + Provisão + + + Auto add fortify item + Füge das Bauwerkzeug automatisch hinzu + 自動的に要塞ツールを追加 + Auto-aggiungi attrezzo di fortificazione + 요새화 도구 자동으로 추가 + 自動增加要塞物品 + 自动增加设防物品 + Automatycznie dodaj narzędzie do fortyfikowania + Автоматически добавлять Инструмент строителя + Otomatik olarak inşa etme aletini ekle + Añadir objeto de Fortificar automáticamente + Ajout automatique de l'outil de fortification + Adicionar item de fortificação automaticamente + + + Initializes the Fortify system, with some basic parameters.<br/>Presets are pulled from configFile and missionConfigFile, see wiki for format. + Inicjalizuje system fortyfikacji, z podstawowymi parametrami.<br/>Domyślne ustawienia są załadowane z configFile oraz missionConfigFile, odwiedź wiki aby znaleźć format + Inizializza il sistema di fortificazione con alcuni parametri di base.<br/>Preset vengono presi da configFile and missionConfigFile, leggi la wiki per il formato richiesto. + Инициализирует систему фортификации с некоторыми базовыми параметрами.<br/>Предустановки взяты из configFile и missionConfigFile, формат смотри на wiki. + Inşa etme sistemini bazı temel parametrelerle başlatır. <br/> Ön ayarlar configFile ve missionConfigFile'dan alınır, format için wiki'ye bakın. + 要塞システムを初期設定に戻します。<br/>プリセットは configfile と missionConfigFile から参照されます。詳細は wiki を参照してください。 + Initialisiert das Verstärken-System, mit grundlegenden Einstellungen <br/>Vorseinstellungen werden aus der configFile und der missionConfigFile gezogen, für mehr Informationen: siehe das ACE Wiki. + 使用一些基本参数初始化设防系统。<br/>预设从 configFile 和 missionConfigFile 中提取,参见 wiki 的格式。 + 기본 파라미터와 함께 요새화 시스템을 활성화합니다<br/>configFile 과 missionConfigFile에서 프리셋을 뽑아옵니다, 포맷은 위키를 참조하십시오. + Inicializa el sistema deFortificación con los parámetros básicos. .<br/>Los presets son importados de configFile y de missionConfigFile, consultar la wiki para ver el formato. + Initialise le système de fortification, avec quelques paramètres de base.<br/>Les presets sont tirés du configFile et du missionConfigFile, consulter le wiki pour les formats. + Inicializa o sistema de fortificação, com alguns parâmetros básicos.<br/>Os presets são retirados do configFile e do missionConfigFile, consulte a wiki para o formato. + + + Rotate + Drehen + Girar + Tourner + Rotazione + Otočit + Forgatás + Obrót + Rotaciona + Bращать + 回転 + 회전 + 旋转 + 旋轉 + Yönlendir + + + Confirm Deployment + Aufbauen + Подтвердить размещение + Potwierdź rozłożenie + Confirmar despliegue + Confirmer Déploiement + Potvrdit Položení + Conferma Posizionamento + Lerak + Confirmar implantação + ここで作る + 설치 확인 + 确认部署 + 確認佈署 + Yerleştirmeyi Onayla + + + Fortify: Limit Build Area + Verstärken: Beschränke Baubereich + 要塞: 構築制限エリア + 要塞: 限制建造區 + Fortificazione: Limita Area + 设防:限制建造区 + Fortyfikowanie: Limituj strefe budowania + Фортификация: Ограничить зону постройки + Inşa Etme : Bölgede Inşa Etmeyi Limitle + 요새화: 건설 영역 제한 + Fortificar: Limitar área de construcción + Fortification : limiter la zone de construction + Fortificação: Limitar área de construção + + + ACE Fortify + ACE Verstärken + ACE Fortificazione + ACE 要塞 + ACE 设防 + ACE 要塞 + ACE Fortyfikowanie + ACE Фортификация + ACE Inşa Etme + ACE 요새화 + ACE Fortificar + ACE Fortification + ACE Fortificação + + + Show budget updates + Zeige Budgetveränderungen + Mostra aggiornamenti di budget + 顯示預算更新 + 显示预算更新 + 予算更新を表示 + Pokaż aktualizacje budżetu + Показывать обновления бюджета + Bütçe güncellenmelerini göster + 비용 업데이트 표시 + Mostrar actualizaciones de presupuesto + Afficher les changements de budget + Mostrar as atualizações de previsão + + + Controls when budget update hints are shown + Bestimmt wann Budgetveränderungen angezeigt werden + 決定預算變更時是否會顯示提示 + 决定预算变更时是否会显示提示 + Controlla se vengono mostrati avvisi di aggiornamento del budget + 予算更新のヒントが表示される場面を制御します + Kontroluje kiedy aktualizacje budżetu są wyświetlane + Настраивает сообщения об обновлении бюджета + Bütçe güncellenince bilgi verilip verilmeyeceğini kontrol eder. + 어떤 행동을 취할 때 비용이 표시되는지를 결정합니다 + Controla cuándo los avisos de actualizaciones de presupuesto se muestran + Détermine quand les modifications de budget sont affichées + Controla quando as atualizações de previsão são mostradas + + + Never show + Niemals anzeigen + Non mostrare + 永不顯示 + 永不显示 + 非表示 + Nigdy + Не показывать никогда + Asla Gösterme + 안 보여줌 + No mostrar nunca + Ne jamais afficher + Nunca mostrar + + + Has fortify tool + Hat Bauewerkzeug + Ha l'attrezzo di fortificazione + 有要塞工具 + 有设防工具 + 要塞ツール所持時 + Posiada narzędzie do fortyfikowania + Если имеется инструмент + Insa Etme Aleti Olanlara Göster + 요새화 도구를 들고 있을 때 + Tiene herramienta de Fortificar + Dispose d'un outil de fortification + Tem ferramenta de fortificação + + + Always show + Immer anzeigen + Mostra sempre + 總是顯示 + 总是显示 + 常に表示 + Zawsze + Показывать всегда + Her Zaman Göster + 항상 보여줌 + Mostrar siempre + Toujours afficher + Sempre mostrar + + + Time-Cost Coefficient + 时间—成本系数 + 시간-가격 계수 + Zeit-Kosten-Koeffizient + Coefficiente tempo/costo + タイム-コスト係数 + Współczynnik Czas-Koszt + Коэф. время-цена + Coeficiente Tiempo-Coste + Coefficient de temps/coût + Coeficiente de Tempo/Custo + + + Coefficient used to determine time to build structure.\nA in Ax + b where x is cost of object + 用于确定建造建筑所需时间的系数。\nA是 Ax+b中的一个参数,其中x是物体的成本 + 건축물을 지을 때 걸리는 시간을 계수를 적용하여 계산합니다. + Koeffizient zur Bestimmung der Bauzeit \nA in Ax + b, wobei x die Kosten des Objekts sind. + Il coefficiente 'C' che determina il tempo di costruzione.\nTempo Totale = Costo * C + Tempo Minimo + 建造する時間を定義するために使用される係数。\n計算式はAx + bです。この係数はAであり、xは建造物のコストです。 + Współczynnik używany do określenia czasu budowy konstrukcji.\nA w Ax + b gdzie x jest kosztem obiektu + Коэффициент используемый для указания времени необходимого для возведения постройки.\nA в формуле Ax + b, где x - это цена объекта + Coeficiente usado para determinar el tiempo de construcción de una estructura.\nA en Ax + b donde x es el coste del objeto + Coefficient utilisé pour déterminer le temps de construction d'une structure.\nA dans Ax + b où x est le coût de l'objet. + Coeficiente usado para determinar o tempo para construir uma estrutura.\nA em Ax + b, onde x é o custo do objeto + + + Minimum Build Time + 最短建造时间 + 최소 건축 시간 + Minimale Bauzeit + Tempo di costruzione minimo + 最短建造時間 + Minimalny czas budowy + Мин. время возведения + Tiempo mínimo de construcción + Temps de construction minimum + Tempo Mínimo de Construção + + + Minimum time to build any structure.\nb in Ax + b where x is cost of object + 建造任何建筑的最短时间。\nb是 Ax+b中的一个参数,其中x是物体的成本 + 건축물을 지을 때 걸리는 최소 시간을 계수를 적용하여 계산합니다. + Mindestzeit für den Bau eines beliebigen Bauwerks.\nb in Ax + b, wobei x die Kosten des Objekts sind. + Tempo minimo necessario per costruire una qualsiasi fortificazione.\nTempo Totale = Costo * CoefT/C + Tempo Minimo + 建造に掛かる最短時間。\n計算式はAx + bです。この時間はbであり、xは建造物のコストです。 + Minimalny czas do zbudowania dowolenj konstrukcji.\nb w Ax + b gdzie x jest kosztem obiektu + Минимальное время для возведения любой постройки.\nb в формуле Ax + b, где x - это цена объекта + Tiempo mínimo para construir una estructura.\nb en Ax + b donde x es el coste del objeto + Temps minimum pour construire une structure.\nb dans Ax + b où x est le coût de l'objet. + Tempo mínimo para construir uma estrutura.\nb em Ax + b, onde x é o custo do objeto + + + Building + 建造 + 건설 중 + Bauwerk + Costruendo + 建造 + Budowanie + Возведение + Construyendo + Construction + Construindo + + + Create map markers + 创建地图标记 + 지도에 마커 생성 + Kartenmarkierungen erstellen + Crea marker sulla mappa + マップマーカーを生成する + Twórz znaczniki na mapie + Создавать маркера на карте + Crear marcadores de mapa + Créer des marqueurs sur carte + Criar marcadores de mapa + + + Create map markers that look like terrain buildings when static fortifications are placed + 在放置静态防御工事时,创建看起来像地形建筑的地图标记 + 건축물을 건설하고 나서 지도에 마커를 생성합니다 + Erstellen von Kartenmarkierungen, die wie Gebäude im Gelände aussehen, wenn statische Befestigungen platziert werden + Crea marker che appaiono come edifici sulla mappa lì dove vengono costruite fortificazioni + 静的な建築物が配置されたときに地形の建物のように見えるマップマーカーを生成します + Utwórz znaczniki mapy, które wyglądają jak obiekty terenu, gdy umieszczane są statyczne fortyfikacje + Создавать маркера от статических фортификаций как от зданий на карте + Crear marcadores de mapa que tienen la apariencia de edificios del terreno cuando las fortificaciones estáticas son colocadas + Créer des marqueurs sur carte qui ressemblent à des bâtiments sur le terrain lorsque des fortifications statiques sont placées + Criar marcadores de mapa que parecem edifícios do terreno quando fortificações estáticas são colocadas + + + Never + Nikdy + Nie + Никогда + Nigdy + Mai + Nunca + Jamais + 永不 + なし + 안 함 + Nunca + 永不 + Asla + + + For units friendly to the placer + 对放置者友军单位 + 아군 유닛이 지은 건물만 + Für, zum Erbauer, verbündete Einheiten. + Per unità alleate al costruttore + 設置者の友軍に + Dla jednostek sojuszniczych wobec stawiającego + Для союзников + Para unidades aliadas de quien coloca la fortificación + Pour les unités alliées du placeur + Para unidades aliadas do autor da fortificação + + + For everyone + 所有人 + Pour tous + Para todos + Per tutti + Dla wszystkich + Для всех + Für alle + Pro všechny + Para todos + 모든 사람 + 针对每一个人 + 全員に + Herkes için + + + Small + Małe + Малый + Küçük + 小型 + Piccola + Klein + 小型 + 소형 + Pequeña + Petit + Pequena + + + Small (Green) + Малый (зелёный) + Małe (Zielone) + Küçük (Yeşil) + 小型 (グリーン) + Klein (Grün) + Piccola (Verde) + 小型(绿色) + 소형 (초목) + Pequeña (Verde) + Petit (Vert) + Pequena (Verde) + + + Medium + Średnie + Средний + Orta + 中型 + Mittel + Media + 中型 + 중형 + Mediana + Moyen + Média + + + Medium (Green) + Средний (зелёный) + Średnie (Zielone) + Orta (Yeşil) + 中型 (グリーン) + Mittel (Grün) + Media (Verde) + 中型(绿色) + 중형 (초목) + Mediana (Verde) + Moyen (Vert) + Média (Verde) + + + Big + Duże + Большой + Büyük + 大型 + Grande + Groß + 大型 + 대형 + Grande + Grand + Grande + + + Big (Green) + Duże (Zielone) + Большой (зелёный) + Büyük (Yeşil) + 大型 (グリーン) + Groß (Grün) + Grande (Verde) + 大型(绿色) + 대형 (초목) + Grande (Verde) + Grand (Vert) + Grande (Verde) + + + Big (Both) + Duże (Oba) + Большой (Оба) + Büyük (İkisi de) + 大型 (両方) + Groß (Beide) + Grande (Entrambe) + 大型(两方) + 대형 (둘 다) + Grande (Ambos) + Grand (les deux) + Grande (Ambos) + + + diff --git a/addons/frag/ACE_Settings.hpp b/addons/frag/ACE_Settings.hpp index 6d511d3c3d..a6018ee859 100644 --- a/addons/frag/ACE_Settings.hpp +++ b/addons/frag/ACE_Settings.hpp @@ -1,39 +1,17 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(EnableFrag); - description = CSTRING(EnableFrag_Desc); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(spallEnabled) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(EnableSpall); - description = CSTRING(EnableSpall_Desc); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(reflectionsEnabled) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(EnableReflections); - description = CSTRING(EnableReflections_Desc); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(maxTrack) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(MaxTrack); - description = CSTRING(MaxTrack_Desc); - typeName = "SCALAR"; - value = 10; - sliderSettings[] = {0, 50, 10, -1}; + movedToSQF = 1; }; class GVAR(maxTrackPerFrame) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(MaxTrackPerFrame); - description = CSTRING(MaxTrackPerFrame_Desc); - typeName = "SCALAR"; - value = 10; - sliderSettings[] = {0, 50, 10, -1}; + movedToSQF = 1; }; }; diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 00d2d62ad8..7a124833b3 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -13,7 +13,7 @@ class CfgAmmo { GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(enabled) = 1; @@ -22,7 +22,7 @@ class CfgAmmo { GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class BombCore; class Bo_Mk82: BombCore { @@ -32,7 +32,7 @@ class CfgAmmo { GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; // ~~~~ Grenades: @@ -52,7 +52,7 @@ class CfgAmmo { GVAR(metal) = 210; // metal in grams GVAR(charge) = 185; // explosive in grams GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations - GVAR(gurney_k) = 3/5; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations + GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations }; class GrenadeHand_stone: GrenadeHand { GVAR(skip) = 1; @@ -69,7 +69,7 @@ class CfgAmmo { GVAR(metal) = 200; GVAR(charge) = 32; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class G_40mm_HEDP: G_40mm_HE { // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 @@ -79,7 +79,7 @@ class CfgAmmo { GVAR(metal) = 200; GVAR(charge) = 45; GVAR(gurney_c) = 2830; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class ACE_G_40mm_HEDP: G_40mm_HEDP {}; @@ -87,6 +87,7 @@ class CfgAmmo { class ACE_G_40mm_Practice: ACE_G_40mm_HE { GVAR(skip) = 1; GVAR(force) = 0; + EGVAR(vehicle_damage,incendiary) = 0; }; class ACE_G40mm_HE_VOG25P: G_40mm_HE { GVAR(skip) = 0; @@ -121,6 +122,18 @@ class CfgAmmo { GVAR(classes)[] = {"ACE_frag_medium_HD"}; }; + // https://ofb.gov.in/product/products/product-details/84-mm-he-round-ffv-441-b + // https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf (page 99, Table A-6. HE 441D RS, 84-mm projectile) + class R_MRAAWS_HEAT_F; + class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { + GVAR(enabled) = 1; + GVAR(metal) = 2300; + GVAR(charge) = 590; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {"ACE_frag_small"}; + }; + // ~~~~ Missiles: class M_PG_AT; @@ -132,7 +145,7 @@ class CfgAmmo { GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class RocketBase; class R_80mm_HE: RocketBase { @@ -146,7 +159,7 @@ class CfgAmmo { GVAR(metal) = 56250; GVAR(charge) = 39000; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(enabled) = 1; @@ -154,7 +167,7 @@ class CfgAmmo { GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class M_Scalpel_AT: MissileBase { // 9K121 Vikhr GVAR(enabled) = 1; @@ -162,7 +175,7 @@ class CfgAmmo { GVAR(metal) = 10000; GVAR(charge) = 3000; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class ACE_Hellfire_AGM114K: M_Scalpel_AT { // Source: http://www.designation-systems.net/dusrm/m-114.html @@ -172,7 +185,7 @@ class CfgAmmo { GVAR(metal) = 8000; GVAR(charge) = 2400; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class M_Air_AA: MissileBase { GVAR(skip) = 1; @@ -192,7 +205,7 @@ class CfgAmmo { GVAR(metal) = 36000; GVAR(charge) = 9979; GVAR(gurney_c) = 2440; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class Sh_82mm_AMOS: Sh_155mm_AMOS { // Source: http://www.arsenal-bg.com/defense_police/mortar_bombs_82mm.htm @@ -202,7 +215,7 @@ class CfgAmmo { GVAR(metal) = 3200; GVAR(charge) = 420; GVAR(gurney_c) = 2440; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { GVAR(enabled) = 1; @@ -211,7 +224,7 @@ class CfgAmmo { GVAR(metal) = 800; GVAR(charge) = 4200; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { GVAR(enabled) = 1; @@ -220,7 +233,7 @@ class CfgAmmo { GVAR(metal) = 11400; GVAR(charge) = 7100; GVAR(gurney_c) = 2800; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class Sh_120mm_HE: ShellBase { GVAR(enabled) = 1; @@ -229,7 +242,7 @@ class CfgAmmo { GVAR(metal) = 23000; GVAR(charge) = 3148; GVAR(gurney_c) = 2830; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class Sh_125mm_HE: Sh_120mm_HE { GVAR(enabled) = 1; @@ -238,7 +251,7 @@ class CfgAmmo { GVAR(metal) = 16000; GVAR(charge) = 3200; GVAR(gurney_c) = 2440; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { GVAR(enabled) = 1; @@ -247,12 +260,13 @@ class CfgAmmo { GVAR(metal) = 1950; GVAR(charge) = 15800; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = 1/2; + GVAR(gurney_k) = "1/2"; }; class B_65x39_Caseless; class GVAR(base): B_65x39_Caseless { + ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 12; typicalSpeed = 1500; deflecting = 65; @@ -266,29 +280,29 @@ class CfgAmmo { class GVAR(tiny_HD): GVAR(base) { hit = 6; - airFriction = BASE_DRAG_HD; + airFriction = QUOTE(BASE_DRAG_HD); caliber = 0.75; }; class GVAR(small): GVAR(base) { hit = 12; - airFriction = BASE_DRAG*0.9; + airFriction = QUOTE(BASE_DRAG*0.9); }; class GVAR(small_HD): GVAR(base) { hit = 12; - airFriction = BASE_DRAG_HD*0.9; + airFriction = QUOTE(BASE_DRAG_HD*0.9); }; class GVAR(medium): GVAR(base) { hit = 14; - airFriction = BASE_DRAG*0.75; + airFriction = QUOTE(BASE_DRAG*0.75); caliber = 1.2; }; class GVAR(medium_HD): GVAR(base) { hit = 14; - airFriction = BASE_DRAG_HD*0.75; + airFriction = QUOTE(BASE_DRAG_HD*0.75); caliber = 1.2; }; @@ -296,7 +310,7 @@ class CfgAmmo { hit = 28; indirectHit = 2; indirectHitRange = 0.25; - airFriction = BASE_DRAG*0.65; + airFriction = QUOTE(BASE_DRAG*0.65); caliber = 2; explosive = 0; @@ -306,7 +320,7 @@ class CfgAmmo { hit = 28; indirectHit = 2; indirectHitRange = 0.25; - airFriction = BASE_DRAG_HD*0.65; + airFriction = QUOTE(BASE_DRAG_HD*0.65); caliber = 2; }; @@ -314,7 +328,7 @@ class CfgAmmo { hit = 40; indirectHit = 4; indirectHitRange = 0.5; - airFriction = BASE_DRAG*0.5; + airFriction = QUOTE(BASE_DRAG*0.5); caliber = 2.8; }; @@ -322,7 +336,7 @@ class CfgAmmo { hit = 40; indirectHit = 4; indirectHitRange = 0.5; - airFriction = BASE_DRAG_HD*0.5; + airFriction = QUOTE(BASE_DRAG_HD*0.5); caliber = 2.8; }; diff --git a/addons/frag/CfgAmmoReflections.hpp b/addons/frag/CfgAmmoReflections.hpp index 513b58d544..a6183eaa7b 100644 --- a/addons/frag/CfgAmmoReflections.hpp +++ b/addons/frag/CfgAmmoReflections.hpp @@ -1,9 +1,9 @@ #define ACE_EXPLOSION_REFLECTION(range, hit)\ -class ace_explosion_reflection_##range##_##hit : ace_explosion_reflection_base {\ +class ace_explosion_reflection_##range##_##hit: ace_explosion_reflection_base {\ indirectHitRange = range;\ indirectHit = hit;\ - dangerRadiusHit = range*3;\ - suppressionRadiusHit = range*2;\ + dangerRadiusHit = QUOTE(range*3);\ + suppressionRadiusHit = QUOTE(range*2);\ } #define ACE_EXPLOSION_RANGE(range)\ @@ -58,7 +58,7 @@ class ace_explosion_reflection_##range##_##hit : ace_explosion_reflection_base { ACE_EXPLOSION_REFLECTION(range,490);\ ACE_EXPLOSION_REFLECTION(range,500) -class ace_explosion_reflection_base : Sh_120mm_HE { +class ace_explosion_reflection_base: Sh_120mm_HE { CraterWaterEffects = ""; CraterEffects = ""; effectsMissile = ""; diff --git a/addons/frag/CfgEventhandlers.hpp b/addons/frag/CfgEventhandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/frag/CfgEventhandlers.hpp +++ b/addons/frag/CfgEventhandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/frag/README.md b/addons/frag/README.md index 2bcccda913..ca62771f00 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -2,11 +2,3 @@ ace_frag ======== Shrapnel system for explosives. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [NouberNou](https://github.com/NouberNou) -- [walterpearce](https://github.com/walterpearce) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 4126ca328c..cc58e1d15b 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -2,10 +2,10 @@ if (isServer) then { GVAR(lastFragTime) = -1; - [QGVAR(frag_eh), {_this call FUNC(frago);}] call CBA_fnc_addEventHandler; + [QGVAR(frag_eh), LINKFUNC(frago)] call CBA_fnc_addEventHandler; }; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; // Register fire event handler @@ -18,7 +18,7 @@ if (isServer) then { }] call CBA_fnc_addEventHandler; // Cache for ammo type configs -GVAR(cacheRoundsTypesToTrack) = [false] call CBA_fnc_createNamespace; +GVAR(cacheRoundsTypesToTrack) = createHashMap; // Debug stuff: diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 7cbd6092a1..dc616917b8 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -20,4 +20,6 @@ GVAR(lastIterationIndex) = 0; GVAR(objects) = []; GVAR(arguments) = []; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 71452b9814..d0cc127d05 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou * Adds a round to the blacklist (will be ignored). diff --git a/addons/frag/functions/fnc_addPfhRound.sqf b/addons/frag/functions/fnc_addPfhRound.sqf index 35b927e687..358a9ee71e 100644 --- a/addons/frag/functions/fnc_addPfhRound.sqf +++ b/addons/frag/functions/fnc_addPfhRound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou * Starts tracking a round that will frag. @@ -60,14 +60,14 @@ if (alive _round) then { private _spallTrackID = []; private _args = [ - _round, getPosASL _round, velocity _round, _type, diag_frameno, _gun, _doSpall, _spallTrack, _spallTrackID, + _round, getPosASL _round, velocity _round, _type, diag_frameno, getPosASL _round, _doSpall, _spallTrack, _spallTrackID, getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip)), getNumber (configFile >> "CfgAmmo" >> _type >> "explosive"), getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"), getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force)), getNumber (configFile >> "CfgAmmo" >> _type >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"))) ]; - TRACE_1("Initializing track", _round); + TRACE_1("Initializing track",_round); GVAR(objects) pushBack _round; GVAR(arguments) pushBack _args; diff --git a/addons/frag/functions/fnc_dev_addTrack.sqf b/addons/frag/functions/fnc_dev_addTrack.sqf index ce459008f6..0e75a9fb99 100644 --- a/addons/frag/functions/fnc_dev_addTrack.sqf +++ b/addons/frag/functions/fnc_dev_addTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -10,7 +10,7 @@ * None * * Example: - * call ace_frag_fnc_addTack + * call ace_frag_fnc_dev_addTrack * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 42debf3d61..4484edbdc4 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -1,5 +1,5 @@ #define DEBUG_MODE_FULL -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -11,7 +11,7 @@ * None * * Example: - * call ace_frag_fnc_debugAmmo + * call ace_frag_fnc_dev_debugAmmo * * Public: No */ @@ -28,7 +28,7 @@ private _allMagsConfigs = configProperties [configFile >> "CfgMagazines", "isCla private _processedCfgAmmos = []; { - private _ammo = toLower getText (_x >> "ammo"); + private _ammo = toLowerANSI getText (_x >> "ammo"); if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; diff --git a/addons/frag/functions/fnc_dev_drawTraces.sqf b/addons/frag/functions/fnc_dev_drawTraces.sqf index 76e729ed7f..7fcca3c48f 100644 --- a/addons/frag/functions/fnc_dev_drawTraces.sqf +++ b/addons/frag/functions/fnc_dev_drawTraces.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -10,7 +10,7 @@ * None * * Example: - * call ace_frag_fnc_drawTraces + * call ace_frag_fnc_dev_drawTraces * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_startTracing.sqf b/addons/frag/functions/fnc_dev_startTracing.sqf index d709255a73..897dde3011 100644 --- a/addons/frag/functions/fnc_dev_startTracing.sqf +++ b/addons/frag/functions/fnc_dev_startTracing.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * diff --git a/addons/frag/functions/fnc_dev_stopTracing.sqf b/addons/frag/functions/fnc_dev_stopTracing.sqf index 75cf38b6d9..949d3cd55d 100644 --- a/addons/frag/functions/fnc_dev_stopTracing.sqf +++ b/addons/frag/functions/fnc_dev_stopTracing.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Dev things @@ -10,6 +10,7 @@ * None * * Example: + * None * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_trackTrace.sqf b/addons/frag/functions/fnc_dev_trackTrace.sqf index 6481b89310..6c010bdb63 100644 --- a/addons/frag/functions/fnc_dev_trackTrace.sqf +++ b/addons/frag/functions/fnc_dev_trackTrace.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Dev things @@ -18,7 +18,7 @@ params ["_args", "_pfhID"]; _args params ["_tracerObj", "_index"]; -if (alive _tracerObj && {!(GVAR(traces) isEqualTo [])}) then { +if (alive _tracerObj && {GVAR(traces) isNotEqualTo []}) then { private _data = GVAR(traces) select _index; private _positions = _data select 4; _positions pushBack [getPos _tracerObj, vectorMagnitude (velocity _tracerObj)]; diff --git a/addons/frag/functions/fnc_doExplosions.sqf b/addons/frag/functions/fnc_doExplosions.sqf index 1f5c37597a..a5a687aa53 100644 --- a/addons/frag/functions/fnc_doExplosions.sqf +++ b/addons/frag/functions/fnc_doExplosions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * diff --git a/addons/frag/functions/fnc_doReflections.sqf b/addons/frag/functions/fnc_doReflections.sqf index 7b16385d75..70c7471181 100644 --- a/addons/frag/functions/fnc_doReflections.sqf +++ b/addons/frag/functions/fnc_doReflections.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Dev things @@ -22,5 +22,5 @@ if (_depth <= 2) then { private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); private _indirectHit = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHit"); private _testParams = [_pos, [_indirectHitRange, _indirectHit], [], [], -4, _depth, 0]; - [DFUNC(findReflections), 0, _testParams] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(findReflections), 0, _testParams] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index eb97875570..8b5a06d812 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Dev things diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index 8b4a5922a5..a753934fe8 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -65,7 +65,7 @@ if (_zIndex < 5) then { while {count _nlos != count _excludes && {_c < (count _nlos)}} do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x; @@ -74,7 +74,7 @@ if (_zIndex < 5) then { }; } forEach _nlos; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { _testPos = _x; if (_testPos vectorDistanceSqr _bucketPos <= 30) then { _bucketList pushBack _x; @@ -117,10 +117,10 @@ if (_zIndex < 5) then { if (count _explosions > (_radi * 2) / _depth) exitWith {}; } forEach _buckets; // _can = "Land_Bricks_V4_F" createVehicle (ASLtoATL _pos); - // _dirvec = _pos vectorFromTo ((ATLtoASL (player modelToWorldVisual (player selectionPosition "Spine3")))); + // _dirvec = _pos vectorFromTo ((player modelToWorldVisualWorld (player selectionPosition "Spine3"))); // _dirvec = _dirvec vectorMultiply 100; // _can setVelocity _dirvec; - [DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; [_pfhID] call CBA_fnc_removePerFrameHandler; }; END_COUNTER(fnc_findReflections); diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index a61a2d14c7..03d2fab609 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: nou, jaynus, PabstMirror * Called from the unified fired EH for all. @@ -17,9 +17,9 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -private _shouldAdd = GVAR(cacheRoundsTypesToTrack) getVariable _ammo; +private _shouldAdd = GVAR(cacheRoundsTypesToTrack) get _ammo; if (isNil "_shouldAdd") then { TRACE_1("no cache for round",_ammo); @@ -40,7 +40,7 @@ if (isNil "_shouldAdd") then { }; TRACE_6("Setting Cache",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd); - GVAR(cacheRoundsTypesToTrack) setVariable [_ammo, _shouldAdd]; + GVAR(cacheRoundsTypesToTrack) set [_ammo, _shouldAdd]; }; if (_shouldAdd) then { diff --git a/addons/frag/functions/fnc_frago.sqf b/addons/frag/functions/fnc_frago.sqf index 8c90445411..8fd77dbc73 100644 --- a/addons/frag/functions/fnc_frago.sqf +++ b/addons/frag/functions/fnc_frago.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou * Server func to create the fragmentation for a round. @@ -95,7 +95,7 @@ private _fragArcs = []; _fragArcs set [360, 0]; private _doRandom = true; -if (!(_objects isEqualTo [])) then { +if (_objects isNotEqualTo []) then { if (GVAR(reflectionsEnabled)) then { [_lastPos, _shellType] call FUNC(doReflections); }; @@ -127,7 +127,7 @@ if (!(_objects isEqualTo [])) then { if (_currentCount < 10) then { private _count = ceil (random (sqrt (_m / 1000))); private _vecVar = FRAG_VEC_VAR; - if (!(_target isKindOf "Man")) then { + if !(_target isKindOf "Man") then { ADD(_vecVar,(sqrt _cubic) / 2000); if ((crew _target) isEqualTo [] && {_count > 0}) then { _count = 0 max (_count / 2); @@ -144,7 +144,7 @@ if (!(_objects isEqualTo [])) then { private _vel = _vec vectorMultiply _fp; private _fragObj = (selectRandom _fragTypes) createVehicleLocal [0,0,10000]; - // TRACE_4("targeted",_fp, typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); + // TRACE_4("targeted",_fp,typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); _fragObj setPosASL _lastPos; _fragObj setVectorDir _vec; _fragObj setVelocity _vel; diff --git a/addons/frag/functions/fnc_masterPFH.sqf b/addons/frag/functions/fnc_masterPFH.sqf index 06baaad17f..004af9a9ce 100644 --- a/addons/frag/functions/fnc_masterPFH.sqf +++ b/addons/frag/functions/fnc_masterPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Master single PFH abstraction for all rounds being tracked by frag/spall. @@ -34,7 +34,7 @@ while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} if (!isNil "_object") then { private _args = GVAR(arguments) select GVAR(lastIterationIndex); - if (!(_args call FUNC(pfhRound))) then { + if !(_args call FUNC(pfhRound)) then { _gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false }; }; @@ -45,7 +45,7 @@ while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} // Clean up dead object references private _deletionCount = 0; { - TRACE_1("GC Projectile", _x); + TRACE_1("GC Projectile",_x); private _deleteIndex = _x - _deletionCount; GVAR(objects) deleteAt _deleteIndex; GVAR(arguments) deleteAt _deleteIndex; diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf index 4d5e9b2e99..ce734a08e3 100644 --- a/addons/frag/functions/fnc_pfhRound.sqf +++ b/addons/frag/functions/fnc_pfhRound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -15,7 +15,7 @@ * Public: No */ -params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_gun", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; +params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_firedPos", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; if (_round in GVAR(blackList)) exitWith { false @@ -26,13 +26,10 @@ if (!alive _round) exitWith { if (_skip == 0) then { if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then { // shotbullet, shotShell don't seem to explode when touching water, so don't create frags - if (((_lastPos select 2) < 0) && {(toLower getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; - private _isArmed = true; - if (!isNil "_gun") then { - private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); - _isArmed = ((getPosASL _gun) distance _lastPos > _fuseDist); - TRACE_2("",_fuseDist,_isArmed); - }; + if ((surfaceIsWater _lastPos) && {(toLowerANSI getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; + private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); + private _isArmed = _firedPos vectorDistance _lastPos >= _fuseDist; // rounds explode at exactly fuseDistance, so check inclusive + TRACE_2("",_fuseDist,_isArmed); if (!_isArmed) exitWith {TRACE_1("round not armed",_this);}; TRACE_3("Sending frag event to server",_lastPos,_lastVel,_shellType); [QGVAR(frag_eh), [_lastPos,_lastVel,_shellType]] call CBA_fnc_serverEvent; diff --git a/addons/frag/functions/fnc_spallHP.sqf b/addons/frag/functions/fnc_spallHP.sqf index 9a1e144f44..367bea7644 100644 --- a/addons/frag/functions/fnc_spallHP.sqf +++ b/addons/frag/functions/fnc_spallHP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Handles the HitPart event diff --git a/addons/frag/functions/fnc_spallTrack.sqf b/addons/frag/functions/fnc_spallTrack.sqf index 8e1bf2f804..43dae8afcb 100644 --- a/addons/frag/functions/fnc_spallTrack.sqf +++ b/addons/frag/functions/fnc_spallTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Add HitPart EventHandler to objects in the projectile's path @@ -24,11 +24,10 @@ private _velocity = velocity _round; private _velocityStep = _velocity vectorMultiply _delta; private _forwardPos = _curPos vectorAdd _velocityStep; + private _intersectsWith = lineIntersectsWith [_curPos, _forwardPos]; if (_intersectsWith isEqualTo []) exitWith {}; - -// player sideChat format ["inter: %1", _intersectsWith]; { // diag_log text format ["Adding HP: %1", _x]; private _index = count GVAR(spallHPData); diff --git a/addons/frag/functions/script_component.hpp b/addons/frag/functions/script_component.hpp deleted file mode 100644 index 0903b3ba1e..0000000000 --- a/addons/frag/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\frag\script_component.hpp" diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf new file mode 100644 index 0000000000..421d5d4566 --- /dev/null +++ b/addons/frag/initSettings.inc.sqf @@ -0,0 +1,40 @@ +private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(EnableFrag), LSTRING(EnableFrag_Desc)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(spallEnabled), "CHECKBOX", + [LSTRING(EnableSpall), LSTRING(EnableSpall_Desc)], + _category, + false, + 1 +] call CBA_fnc_addSetting; +[ + QGVAR(reflectionsEnabled), "CHECKBOX", + [LSTRING(EnableReflections), LSTRING(EnableReflections_Desc)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(maxTrack), "SLIDER", + [LSTRING(MaxTrack), LSTRING(MaxTrack_Desc)], + _category, + [0, 50, 10, -1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(maxTrackPerFrame), "SLIDER", + [LSTRING(MaxTrackPerFrame), LSTRING(MaxTrackPerFrame_Desc)], + _category, + [0, 50, 10, -1], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index d5a3091969..f88877448d 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -13,8 +13,8 @@ Симуляция осколков Simulazione Frammentazione 破片シミュレーション - 조각 시뮬레이션 - 模拟碎片 + 파편화 시뮬레이션 + 破片模拟 模擬碎片 @@ -29,8 +29,8 @@ Симуляция осколков Simulazione Frammentazione 破片シミュレーション - 조각 시뮬레이션 - 模拟碎片 + 파편화 시뮬레이션 + 破片模拟 模擬碎片 @@ -40,13 +40,13 @@ Aktiviere die ACE-Splittersimulation Povolit ACE simulaci fragmentů Ativa a simulação de fragmentação do ACE - Active la simulation ACE de la fragmentation + Active la simulation de la fragmentation ACE. Az ACE repesz-szimuláció engedélyezése Включить симуляцию осколков ACE Abilita la Simulazione Frammentazione di ACE ACE 破片シミュレーションを有効化 - ACE 조각 시뮬레이션을 적용합니다. - 启用ACE模拟碎片 + ACE 파편화 시뮬레이션을 적용합니다. + 启用 ACE 破片模拟 啟用ACE模擬碎片 @@ -61,7 +61,7 @@ Симуляция обломков Simulazione Spalling 剥離シミュレーション - 파편 시뮬레이션 + 탄환파편 시뮬레이션 模拟剥落 模擬剝落 @@ -72,13 +72,13 @@ Aktiviere ACE-Explosionssimulation Povolit ACE simulaci úlomků Ativa a simulação de estilhaços do ACE - Active la simulation d'éclat ACE + Active la simulation d'éclat ACE. Az ACE pattogzás-szimuláció engedélyezése Включить симуляцию обломков ACE Abilita la Simulazione Spalling di ACE ACE 剥離シミュレーションを有効化 - ACE 파편 시뮬레이션을 적용합니다. - 启用ACE模拟剥落 + ACE 탄환파편 시뮬레이션을 적용합니다. + 启用 ACE 模拟剥落 啟用ACE模擬剝落 @@ -87,13 +87,14 @@ Simulazione Riflessi Esplosioni Druckwellensimulation Activar simulación de reflexiones - Simulation de la réflection des explosions. + Simulation de la réflexion des explosions Simulação de reflexo de explosão Cимуляция отражения взрывов ACE - 爆発による飛翔シミュレーション + 爆発反射シミュレーション 폭발 반사 시뮬레이션 模拟爆炸反射 模擬爆炸反射 + Simulace odrazu exploze Enable the ACE Explosion Reflection Simulation @@ -101,13 +102,14 @@ Abilita la Simulazione Riflessi Esplosioni di ACE Aktiviere die ACE-Druckwellensimulation Activa la simulación de reflexiones para las explosiones. - Activer la simulation de la réfléction des explosions ACE. + Active la simulation de la réflexion des explosions ACE. Ativa a simulação de reflexo de explosão do ACE Включить симуляцию отражения взрывов ACE - 爆発による飛翔シミュレーションを有効化 + ACE 爆発反射シミュレーションを有効化 ACE 폭발 반사 시뮬레이션을 적용합니다. - 启用ACE模拟爆炸反射 + 启用 ACE 模拟爆炸反射 啟用ACE模擬爆炸反射 + Povolit ACE simulaci odrazu exploze Maximum Projectiles Tracked @@ -116,13 +118,13 @@ Maximalzahl der verfolgten Projektile Maximální počet sledovaných projektilů Máximo de projéteis rastreados - Nombre maximum de projectile suivis + Nombre maximum de projectiles suivis Maximum követett repeszek Макс. количество отслеживаемых снарядов Numero massimo di Proiettili Tracciati - 最大弾頭追跡数 + 飛翔体最大追跡数 최대 발사체 추적수 - 最大碎片粒子追踪数量 + 最大破片粒子追踪数量 最大碎片/剝落粒子追蹤數量 @@ -132,13 +134,13 @@ Diese Einstellung steuert die maximale Anzahl an Projektilen, die das Splitter- und Explosionssystem gleichzeitig verfolgen wird. Wenn mehr Projektile abgefeuert werden, werden sie nicht verfolgt werden. Diese Einstellung zu verringern, kann FPS-Einbrüche bei Szenarien mit vielen Projektilen verhindern (>200 Objekte gleichzeitig in der Luft) Toto nastavení kontroluje maximální množství projektilů z fragmentace a úlomků, která jsou sledována v dané době. Pokud je vystřeleno více projektilů, tak nebudou sledovány. Snižte toto nastavení pokud si nepřejete propady FPS v situacích, kde je velké množství projektilů ( >200 nábojů najednou ve vzduchu) Esta definição controla a quantidade máxima de projéteis que o sistema de fragmentação e estilhaçamento irá acompanhar em qualquer momento. Se mais projéteis são disparados, eles não serão rastreados. Diminua essa configuração se você não quiser que o FPS caia em cenários com alta contagem de projéteis (> 200 projéteis no ar ao mesmo tempo) - Cette option contrôle le nombre maximum de projectiles et d'éclats résultant de la fragmentation que le système suivra à un moment T. Si plus de projectiles sont générés, ils ne seront pas pris en compte. Baisser cette option si vous ne voulez pas de baisse de FPS en cas d'un nombre important de projectiles (>200 éclats en même temps) + Ce paramètre contrôle le nombre maximum de projectiles et d'éclats résultant de la fragmentation, que le système peut suivre à chaque instant.\nSi plus de projectiles sont générés, ils ne seront pas pris en compte. Baissez ce réglage si vous ne voulez pas de chute de FPS en cas de nombre important de projectiles (>200 éclats en même temps). Ez a beállítás szabályozza a repeszeződés és pattogzás által kilőtt objektumok követett számát. Ha több ez a szám, ezek az objektumok nem lesznek követve. Csökkentsd ezt a beállítást, ha nem akarsz lassulásokat magas-törmelékmennyiségű helyzetekben (200+ repesz a levegőben egyszerre) - Эта настройка контролирует максимальное количество снарядов, которок отслеживает система осколков и обломков в каждый момент времени. Снаряды, выстреленные сверх этого числа, отслеживаться не будут. Уменьшите это значение, если вы не хотите падения FPS при большом количестве снарядов в одной перестрелке (> 200 одновременно летящих снарядов) - Questo parametro controlla il numero massimo di proiettili che la frammentazione e il sistema di spalling tracciano in ogni momento. Se più proiettili sono sparati, non verranno tracciati. Abbassa questo parametro se non vuoi cali di FPS in scenari con molti proiettili (>200 proiettili in aria contemporaneamente) - 時間が許すかぎり、破片と剥離システムの最大数を設定できます。設定数以上の弾丸が発射された場合、それは対象になりません。もし多い弾数による FPS の低下を望まない場合は、低い数へ設定にします。( &gt;一度に空中内で200発) - 이 설정은 조각 및 파편 시스템으로 인해 생긴 발사체의 수를 결정합니다. 만약 더 많은 발사체가 나올경우 정해진 수 이외에는 추적하지 않습니다. 이 설정을 낮춤으로써 파편이 많은 시나리오를 실행할때 더욱 원활히 진행할 수 있습니다 (한 번에 200개 이하) - 设定在指定时间内,系统最大可追踪的碎片粒子数量。如有更多的碎片在这之后产生,这些粒子将不会被追踪。如果你想要维持好的帧数,此设定勿调的过高。( >一次200颗粒子) + Эта настройка контролирует максимальное количество снарядов, которок отслеживает система осколков и обломков в каждый момент времени. /nСнаряды, выстреленные сверх этого числа, отслеживаться не будут. Уменьшите это значение, если вы не хотите падения FPS при большом количестве снарядов в одной перестрелке (> 200 одновременно летящих снарядов) + Questo parametro controlla il numero massimo di proiettili che la frammentazione e il sistema di spalling tracciano in ogni momento. Se vengono sparati ulteriori proiettili, non verranno tracciati. Abbassa questo parametro se non vuoi cali di FPS in scenari con molti proiettili (>200 proiettili in aria contemporaneamente) + この設定では、断片化および剥離システムが常に追跡する飛翔体の最大量を制御します。 この値より多くの飛翔体が発射された場合、それらは追跡されません。 弾数が多いシナリオでFPSを低下させたくない場合は、この設定を下げてください。 (一度に200発以上が空中に発射されます) + 이 설정은 탄환파편 및 파편 시스템으로 인해 생긴 발사체의 수를 결정합니다. 만약 더 많은 발사체가 나올 경우 정해진 수 이외에는 추적하지 않습니다. 이 설정을 낮춤으로써 파편이 많은 시나리오를 실행할때 더욱 원활히 진행할 수 있습니다 (한 번에 200개 이하) + 设定在指定时间内,系统最大可追踪的破片粒子数量。如有更多的碎片在这之后产生,这些粒子将不会被追踪。如果你想要维持好的帧数,此设定勿调的过高。( >一次200颗粒子) 設定在指定時間內,系統最大可追蹤的碎片/剝落粒子數量。如有更多的碎片在這之後產生,這些粒子將不會被追蹤。如果你想要維持好的幀數,此設定勿調的過高。( >一次200顆粒子) @@ -152,9 +154,9 @@ Maximum repesz/képkocka Макс. количество снарядов за кадр Numero massimo di proiettili per Frame - フレームごとの最大弾頭数 - 프레임당 최대 발사체 수 - 每一帧数(FPS)最大碎片粒子数量 + フレームごとの飛翔体最大数 + 프레임 당 최대 발사체 수 + 每帧最大破片粒子数量 每一幀數(FPS)最大碎片/剝落粒子數量 @@ -164,13 +166,13 @@ El número de cálculos de esquirlas que se hará en cualquier cuadro. Esto ayuda a dispersar el impacto en FPS del seguimiento de esquirlas de balas a través de múltiples cuadros, lo que limita aún más su impacto. Počet úlomků v daném snímku. Toto pomáhá rozšířit FPS dopad sledovaného úlomku napříč více snímky, omezuje jeho vliv ještě více. O número de cálculos por estilhaço rastreado para executar em qualquer quadro. Isso ajuda a distribuir o impacto no FPS do rastreamento de estilhaço em vários quadros, o que limita o seu impacto ainda mais. - Le nombre d'éclats à calculer dans chaque image. Ceci permet de diffuser l'impact sur les FPS dans de multiples images, limitant la perte de FPS. + Le nombre de calculs de suivi à effectuer pour chaque image. Cela aide à répartir l'impact des calculs sur plusieurs images, limitant ainsi encore davantage l'impact sur les FPS. A lepattogzási útvonalak számításának darabjai képkockánként. Ez eloszlatja az FPS-megszakadást több képkockára, ezzel csökkentve a súlyosságát. Число обрабатываемых осколков за кадр. Это позволяет распределить нагрузку по отслеживанию осколков между несколькими кадрами, чтобы предотвратить падение FPS. - Il numero di calcoli per tracciamento di spalling ad ogni frame. Questo aiuta a distribuire l'impatto del tracciamento dello spalling su più frame, limitando ancora di più l'impatto. - 与えられたフレームごとに追跡する剥離の数を決定します。FPS に影響をあたえないよう、剥離を複数のフレームで追跡し、分散させています。 + Il numero di calcoli per tracciamento di spalling ad ogni frame. Questo aiuta a distribuire l'impatto del tracciamento dello spalling su più frame, riducendolo ulteriormente. + 任意のフレームごとに追跡される剥離飛翔体の数。剥離による飛翔体を追跡することによるFPSへの影響を複数フレームに分散させ抑えることが出来ます。 가능한 프레임마다 파편을 추적 및 계산합니다. 여러 프레임에 걸쳐 파편난 발사체를 추적하여 FPS에 도움을 줍니다. 이를 제한함으로써 더욱 큰 효과를 볼 수 있습니다. - 设定在每一帧数内,系统最大可追踪的碎片粒子数量。此设定可有效帮助系统减低计算压力。 + 设定在每一帧数内,系统最大可追踪的破片粒子数量。此设定可有效帮助系统减低计算压力。 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 @@ -185,8 +187,8 @@ (Только для одиночной игры) Отслеживаение/отладка осколков (Solo SP) Debug Tracciamento Frag/Spall (SP のみ) 破片/剥離のデバッグ用表示 - (싱글플레이 전용) 조각/파편 디버그 추적화 - (仅在单人模式) 追踪显示碎片粒子 + (싱글플레이 전용) 탄환파편/파편 디버그 추적화 + (仅单人)追踪显示破片粒子 (僅在單人模式) 碎片/剝落除錯追蹤 @@ -200,10 +202,10 @@ (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. - (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の弾頭が見えるようになります。 - (仅在单人模式) 激活后,只有在单人模式下才可观察到碎片粒子的移动轨迹。 + (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 + (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 - (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 조각화 및 스 폴링 라운드의 시각적 추적을 가능하게합니다. + (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. diff --git a/addons/gestures/ACE_Settings.hpp b/addons/gestures/ACE_Settings.hpp index 8ed8aedb6b..3c31060781 100644 --- a/addons/gestures/ACE_Settings.hpp +++ b/addons/gestures/ACE_Settings.hpp @@ -1,11 +1,5 @@ class ACE_Settings { class GVAR(showOnInteractionMenu) { - value = 2; - typeName = "SCALAR"; - isClientSettable = 1; - category = ECSTRING(interact_menu,Category_InteractionMenu); - displayName = CSTRING(ShowOnInteractionMenu_displayName); - description = CSTRING(ShowOnInteractionMenu_description); - values[] = {"$STR_A3_OPTIONS_DISABLED", CSTRING(JustKeybinds), CSTRING(KeysAndInteractionMenu)}; + movedToSQF = 1; }; }; diff --git a/addons/gestures/CfgEventHandlers.hpp b/addons/gestures/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/gestures/CfgEventHandlers.hpp +++ b/addons/gestures/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/gestures/README.md b/addons/gestures/README.md index e224ff6d69..cb274c7a85 100644 --- a/addons/gestures/README.md +++ b/addons/gestures/README.md @@ -2,10 +2,3 @@ ace_gestures ======== Gestures system in interaction menu and keybinds. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [jokoho48](https://github.com/jokoho48) diff --git a/addons/gestures/XEH_postInit.sqf b/addons/gestures/XEH_postInit.sqf index 935b81aa61..5133f48c41 100644 --- a/addons/gestures/XEH_postInit.sqf +++ b/addons/gestures/XEH_postInit.sqf @@ -31,9 +31,7 @@ if (!hasInterface) exitWith {}; [_key, [false, (_key != -1), false]], false ] call CBA_fnc_addKeybind; - - false -} count [ +} forEach [ ["Freeze", 80], // Numpad 2 ["Cover", 81], // Numpad 3 ["Forward", 75], // Numpad 4 diff --git a/addons/gestures/XEH_preInit.sqf b/addons/gestures/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/gestures/XEH_preInit.sqf +++ b/addons/gestures/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/gestures/anim/zDummy.rtm b/addons/gestures/anim/zDummy.rtm new file mode 100644 index 0000000000..dfeb7b7fcc Binary files /dev/null and b/addons/gestures/anim/zDummy.rtm differ diff --git a/addons/gestures/functions/fnc_playSignal.sqf b/addons/gestures/functions/fnc_playSignal.sqf index 3dcae0d2e3..b6d9f9602a 100644 --- a/addons/gestures/functions/fnc_playSignal.sqf +++ b/addons/gestures/functions/fnc_playSignal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: joko // Jonas, Emperias, Zigomarvin * Detect if the player and play the Gesture Animation diff --git a/addons/gestures/functions/script_component.hpp b/addons/gestures/functions/script_component.hpp deleted file mode 100644 index 53f6849ebc..0000000000 --- a/addons/gestures/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\gestures\script_component.hpp" diff --git a/addons/gestures/initSettings.inc.sqf b/addons/gestures/initSettings.inc.sqf new file mode 100644 index 0000000000..994bb4abc7 --- /dev/null +++ b/addons/gestures/initSettings.inc.sqf @@ -0,0 +1,7 @@ +[ + QGVAR(showOnInteractionMenu), "LIST", + [LSTRING(ShowOnInteractionMenu_displayName), LSTRING(ShowOnInteractionMenu_description)], + format ["ACE %1", localize ELSTRING(interact_menu,Category_InteractionMenu)], + [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", LSTRING(JustKeybinds), LSTRING(KeysAndInteractionMenu)], 2], + 0 +] call CBA_fnc_addSetting; diff --git a/addons/gestures/stringtable.xml b/addons/gestures/stringtable.xml index 6e61d5cac0..33b73290c3 100644 --- a/addons/gestures/stringtable.xml +++ b/addons/gestures/stringtable.xml @@ -16,6 +16,7 @@ ACE 수신호 ACE 手势 ACE 手勢 + ACE Hareketleri ACE Gestures @@ -32,6 +33,7 @@ ACE 수신호 ACE 手势 ACE 手勢 + ACE Hareketleri Gestures @@ -48,6 +50,7 @@ 수신호 手势 手勢 + Hareketler Advance @@ -60,10 +63,11 @@ Előre Avançar Avanzare - 警戒 + 前進 전진 前进 前進 + Ilerle Go @@ -76,10 +80,11 @@ Mozgás Mover-se Muoversi - 進め + 行け 이동 出发 出發 + Git Follow @@ -93,9 +98,10 @@ Seguir Seguire ついて来い - 따라올것 + 따라와 跟进 跟進 + Takip Et Up @@ -108,10 +114,11 @@ Fel Acima Alzarsi - 立ち上がれ + 立て 起立 起立 + Yukarı Cease Fire @@ -128,6 +135,7 @@ 사격 중지 停火 停火 + Ateşi durdur Stop @@ -143,6 +151,7 @@ 멈춰 停止 停止 + Dur Freeze @@ -159,6 +168,7 @@ 정지 不准动 不准動 + Don Cover @@ -175,6 +185,7 @@ 엄폐 掩护 掩護 + Mevzi Al Rally up @@ -184,12 +195,13 @@ Собраться Reagrupar Přeskupit - Raggruppare + Raggrupparsi Reunirse 集合 집결 集合 集合 + Toplan Move forward @@ -205,6 +217,7 @@ 앞으로 이동 往前走 往前走 + Ileri Git Engage @@ -217,9 +230,10 @@ Ingaggiare Atacar 交戦しろ - 교전할것 + 교전 交战 交戰 + Tut Point @@ -229,12 +243,13 @@ Показать направление Ponta Ukázat - Puntare + Punta Señalar 指示 가리키기 指出 指出 + Nokta Hold @@ -250,6 +265,7 @@ 기다려 停住 停住 + Dur Warning @@ -265,21 +281,23 @@ 주의 警告 警告 + Uyarı Show Gestures On Interaction Menu Zeige Gesten im Interaktionsmenü Zobrazit posunky v interakčním menu Pokaż gesty w menu interakcji - Mostra Gesti su Menù Interazione + Mostra Gesti nel Menù Interazione Mostrar gestos en el menú de interacción - Afficher les gestes dans le menu d'interaction. + Afficher les gestes dans le menu d'interaction Mostrar gestos no menu de interação Показать жесты в меню взаимодействия - インタラクション メニュー上でジェスチャー表示 + インタラクションメニュー上でジェスチャー表示 수신호를 상호작용 메뉴에서 보여줍니다 - 显示手势互动选单 + 显示手势互动菜单 顯示手勢互動選單 + Hareketleri Etkileşim Menüsünde Göster Show gestures on the self interaction menu, or just use keybinds, or disable completely @@ -288,13 +306,14 @@ Pokaż listę gestów w menu własnej interakcji, użyj tylko skrótów na klawiaturze lub wyłącz całkowicie Mostra Gesti nel Menù Interazione Personale, o usa solamente tasti di scelta rapida, o disabilita completamente Muestror los gestos en el menú de interacción propia, utilizar solo combinación de teclas o desactivarlos completamente - Afficher les gestes dans le menu d'interaction personnel, ou seulement utiliser les touches, ou desactiver complètement. + Afficher les gestes dans le menu d'interaction personnel, ou utiliser uniquement les touches, ou désactiver complètement. Mostra gestos no menu de interação, ou utilize um dos atalhos de teclado ou desative completamente Показать жесты в меню взамиодейтсвия с собой или только использовать горячие клавиши, или полностью отключить - キー操作や同時使用を無効化している場合はセルフ インタラクション メニュ上でジェスチャーを表示します + セルフ インタラクションメニューでジェスチャーを表示するか、キーバインドのみを使用するか、完全に無効にします 수신호를 상호작용 메뉴에서 보여주거나 혹은 단축키를 지정하거나 아니면 아예 사용하지 않습니다. - 显示手势选项在自己的互动选单上,或只利用键盘来使用手势,或完全禁用 + 显示手势选项在自己的互动菜单上,或只利用键盘来使用手势,或完全禁用 顯示手勢選項在自己的互動選單上,或只利用鍵盤來使用手勢,或完全禁用 + Kendi kendine etkileşim menüsünde hareketleri göster veya sadece tuş atamaları kullan veya tamamen devre dışı bırak. Just Keybinds @@ -303,13 +322,14 @@ Tylko skróty klaw. Solo tasti di scelta rapida Solo mediante teclas - Seulement les touches + Touches uniquement Somente atalhos de teclado Только горячие клавиши キー操作のみ 오직 단축키만 只利用键盘 只利用鍵盤 + Sadece Tuş Atamaları Keybinds + Interaction Menu @@ -321,10 +341,11 @@ Touches + menu d'interaction Atalhos + Menu de Interação Клавиши + Меню взаимодействия - キー操作とインタラクション メニュ - 단축키및 상호작용 메뉴 - 键盘 + 互动选单 + キー操作とインタラクションメニュー + 단축키 및 상호작용 메뉴 + 键盘 + 互动菜单 鍵盤 + 互動選單 + Tuş Atamaları + Etkileşim Menüsü diff --git a/addons/gforces/ACE_Arsenal_Stats.hpp b/addons/gforces/ACE_Arsenal_Stats.hpp index 4148ba5fe2..bebcf74489 100644 --- a/addons/gforces/ACE_Arsenal_Stats.hpp +++ b/addons/gforces/ACE_Arsenal_Stats.hpp @@ -2,11 +2,11 @@ class EGVAR(arsenal,stats) { class statBase; class ACE_gReduction: statBase { scope = 2; - priority = 1; + priority = 1.7; stats[] = {"ACE_GForceCoef"}; displayName = CSTRING(statGReduction); showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(1, 0)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(1,0)],[ARR_2(0.01,1)],false)])] call EFUNC(arsenal,statBarStatement_default)); condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); tabs[] = {{3}, {}}; }; diff --git a/addons/gforces/ACE_Settings.hpp b/addons/gforces/ACE_Settings.hpp index dbe6dec13a..e970265467 100644 --- a/addons/gforces/ACE_Settings.hpp +++ b/addons/gforces/ACE_Settings.hpp @@ -1,8 +1,5 @@ class ACE_Settings { class GVAR(enabledFor) { - displayName = CSTRING(enabledFor_displayName); - typeName = "SCALAR"; - value = 1; - values[] = {ECSTRING(Common,Disabled), CSTRING(enabledFor_onlyAircraft), ECSTRING(Common,Enabled)}; + movedToSQF = 1; }; }; diff --git a/addons/gforces/CfgEventHandlers.hpp b/addons/gforces/CfgEventHandlers.hpp index f82caf47dd..e4e7d86951 100644 --- a/addons/gforces/CfgEventHandlers.hpp +++ b/addons/gforces/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/gforces/CfgWeapons.hpp b/addons/gforces/CfgWeapons.hpp index 2349ba7b2a..35b0ec9792 100644 --- a/addons/gforces/CfgWeapons.hpp +++ b/addons/gforces/CfgWeapons.hpp @@ -19,4 +19,7 @@ class CfgWeapons { class U_O_PilotCoveralls: Uniform_Base { ACE_GForceCoef = 0.8; }; -}; \ No newline at end of file + class U_I_E_Uniform_01_coveralls_F: Uniform_Base { + ACE_GForceCoef = 0.8; + }; +}; diff --git a/addons/gforces/README.md b/addons/gforces/README.md index 15aa7116aa..a22854006c 100644 --- a/addons/gforces/README.md +++ b/addons/gforces/README.md @@ -2,11 +2,3 @@ ace_gforces =========== Adds G-force induced tunnel vision and unconsciousness. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/gforces/XEH_postInit.sqf b/addons/gforces/XEH_postInit.sqf index f7d532c288..d0d58488d3 100644 --- a/addons/gforces/XEH_postInit.sqf +++ b/addons/gforces/XEH_postInit.sqf @@ -5,15 +5,14 @@ if (!hasInterface) exitWith {}; GVAR(pfID) = -1; GVAR(playerIsVirtual) = false; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { TRACE_1("SettingsInitialized eh",GVAR(enabledFor)); if (GVAR(enabledFor) == 0) exitWith {}; //Module has no effect if enabledFor is "None" ["unit", { // Add unit changed EH to check if player is either virtual (logic) or a UAV AI params ["_unit"]; - GVAR(playerIsVirtual) = ((getNumber (configFile >> "CfgVehicles" >> (typeOf _unit) >> "isPlayableLogic")) == 1) || - {(getText (configFile >> "CfgVehicles" >> (typeOf _unit) >> "simulation")) == "UAVPilot"}; + GVAR(playerIsVirtual) = unitIsUAV _unit || {(getNumber (configOf _unit >> "isPlayableLogic")) == 1}; TRACE_3("unit changed",_unit,typeOf _unit,GVAR(playerIsVirtual)); }, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/gforces/XEH_preInit.sqf b/addons/gforces/XEH_preInit.sqf index 7530cabc45..55e142c18b 100644 --- a/addons/gforces/XEH_preInit.sqf +++ b/addons/gforces/XEH_preInit.sqf @@ -6,6 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + GVAR(GForces) = []; GVAR(GForces_Index) = 0; diff --git a/addons/gforces/functions/fnc_addPFEH.sqf b/addons/gforces/functions/fnc_addPFEH.sqf index 55dd8dcd12..b93bb0ab6d 100644 --- a/addons/gforces/functions/fnc_addPFEH.sqf +++ b/addons/gforces/functions/fnc_addPFEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi and esteldunedain * Adds the PFEH diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf index ccaedff0d4..4bb680ee47 100644 --- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf +++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi and esteldunedain * Calculates average g-forces and triggers g-effects @@ -29,7 +29,7 @@ private _accel = ((_newVel vectorDiff GVAR(oldVel)) vectorMultiply (1 / INTERVAL // Cap maximum G's to +- 10 to avoid g-effects when the update is low fps. private _currentGForce = (((_accel vectorDotProduct vectorUp (vehicle ACE_player)) / 9.8) max -10) min 10; -GVAR(GForces) set [GVAR(GForces_Index), _currentGForce]; +GVAR(GForces) set [GVAR(GForces_Index), _currentGForce * GVAR(coef)]; GVAR(GForces_Index) = (GVAR(GForces_Index) + 1) % 30; // 30 = round (AVERAGEDURATION / INTERVAL); GVAR(oldVel) = _newVel; @@ -61,7 +61,7 @@ if (_count > 0) then { }; private _classCoef = (ACE_player getVariable ["ACE_GForceCoef", - getNumber (configFile >> "CfgVehicles" >> (typeOf ACE_player) >> "ACE_GForceCoef")]) max 0.001; + getNumber ((configOf ACE_player) >> "ACE_GForceCoef")]) max 0.001; private _suitCoef = if ((uniform ACE_player) != "") then { (getNumber (configFile >> "CfgWeapons" >> (uniform ACE_player) >> "ACE_GForceCoef")) max 0.001 } else { @@ -71,7 +71,7 @@ private _suitCoef = if ((uniform ACE_player) != "") then { private _gBlackOut = MAXVIRTUALG / _classCoef + MAXVIRTUALG / _suitCoef - MAXVIRTUALG; // Unconsciousness -if ((_average > _gBlackOut) and {isClass (configFile >> "CfgPatches" >> "ACE_Medical") and {!(ACE_player getVariable ["ACE_isUnconscious", false])}}) then { +if (_average > _gBlackOut && {GETEGVAR(medical,enabled,false) && {ACE_player call EFUNC(common,isAwake)}}) then { [ACE_player, true, (10 + floor(random 5)), true] call EFUNC(medical,setUnconscious); }; diff --git a/addons/gforces/functions/script_component.hpp b/addons/gforces/functions/script_component.hpp deleted file mode 100644 index 4d0ee63e05..0000000000 --- a/addons/gforces/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\gforces\script_component.hpp" \ No newline at end of file diff --git a/addons/gforces/initSettings.inc.sqf b/addons/gforces/initSettings.inc.sqf new file mode 100644 index 0000000000..2ea9dd12ef --- /dev/null +++ b/addons/gforces/initSettings.inc.sqf @@ -0,0 +1,20 @@ + +[ + QGVAR(enabledFor), + "LIST", + [LLSTRING(enabledFor_displayName)], + LLSTRING(Category), + [[0, 1, 2], [LELSTRING(Common,Disabled), LLSTRING(enabledFor_onlyAircraft), LELSTRING(Common,Enabled)], 1], + true, + {[QGVAR(enabledFor), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(coef), + "SLIDER", + [LLSTRING(Coefficient_DisplayName), LLSTRING(Coefficient_Description)], + LLSTRING(Category), + [0, 1, 1, 0, true], + true +] call CBA_fnc_addSetting; diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index 2fb8c1b1d1..b84bcb01f1 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -1,46 +1,95 @@ - - + + + ACE G-Forces + ACE Przeciążenia + ACE Force gravitationnelle + ACE Перегрузки + ACE G フォース + ACE G-Kuvveti + ACE Fuerza G + ACE G-Kräfte + ACE Forze-G + ACE G力 + ACE 중력가속도 + ACE Força G + + Gforces Effects Effekte der G-Kräfte - Efectos Gforces + Efectos de fuerza G G Force efekty - Efeitos de ForçaG + Efeitos da Força G Effets de force gravitationnelle Эффекты перегрузок G による効果 Efekty przeciążeń 중력가속도 효과 - Effetti forza G + Effetti Forze-G G力影响 G力影響 + G-Kuvveti Efekti - + Only Aircraft Nur Luftfahrzeug Sólo Aeronave Pouze letadla Somente Aeronave Avions seulement - Только для летательных аппаратов + Только авиация 航空機のみ Tylko samoloty 비행기에만 적용 Solo Aerei - 只有战斗机 + 仅飞行器 只有戰鬥機 + Sadece Uçaklar - + G-force reduction G-Kräfte Reduzierung - Reduction des Gs - 耐 G 性 + Réduction des Gs + 耐G性 减少G力 減少G力 - Riduzione forza G + Riduzione forze-G Redukcja przeciążenia Уменьшение перегрузок + Redução de Força G + Redukce G Force + Reducción de fuerzas G + G-Kuvvetinde azalma + 중력가속도 감소 + + + G-Force Coefficient + Współczynnk przeciążenia + Coefficient de force gravitationnelle + Коэф. перегрузки + G効果係数 + G-Kuvvet Katsayısı + Coeficiente de Fuerza G + G-Kräfte-Koeffizient + Coefficiente Forze-G + G力系数 + 중력가속도 계수 + Coeficiente de Força G + + + Controls strength of G-Force affecting players. + Wpływa na siłe przeciążeń oddziałujących na graczy + Coefficient permettant d'ajuster le niveau de force gravitationnelle affectant les joueurs. + Определяет силу перегрузок, влияющих на игроков. + G効果がプレイヤーに与える影響量を設定できます。 + Oyuncuları etkileyen G-Force'un gücünü kontrol eder. + Controla la intensidad de fuerza G que afecta a los jugadores. + Bestimmt, wie stark G-Kräfte Spieler beeinflussen. + Controlla quanto fortemente i giocatori sono influenzati da Forze-G. + 控制影响玩家的G力的强度。 + 플레이어에게 영향을 끼칠 중력가속도의 계수를 조절합니다. + Controla a intensidade da Força G que afeta os jogadores. diff --git a/addons/goggles/ACE_Settings.hpp b/addons/goggles/ACE_Settings.hpp index 26575ab554..f45d13caa8 100644 --- a/addons/goggles/ACE_Settings.hpp +++ b/addons/goggles/ACE_Settings.hpp @@ -1,18 +1,9 @@ class ACE_Settings { class GVAR(effects) { - category = CSTRING(DisplayName); - displayName = CSTRING(effects_displayName); - typeName = "SCALAR"; - value = 2; - isClientSettable = 1; - values[] = {ECSTRING(common,Disabled), CSTRING(effects_tintOnly), CSTRING(enabled_tintAndEffects)}; + movedToSQF = 1; }; class GVAR(showInThirdPerson) { - category = CSTRING(DisplayName); - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(ShowInThirdPerson); + movedToSQF = 1; }; }; diff --git a/addons/goggles/CfgEventHandlers.hpp b/addons/goggles/CfgEventHandlers.hpp index 99cbf2f8ad..6b26f3c2f1 100644 --- a/addons/goggles/CfgEventHandlers.hpp +++ b/addons/goggles/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/goggles/CfgVehicles.hpp b/addons/goggles/CfgVehicles.hpp new file mode 100644 index 0000000000..68506d3269 --- /dev/null +++ b/addons/goggles/CfgVehicles.hpp @@ -0,0 +1,15 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ACE_Equipment { + class GVAR(wipeGlasses) { + displayName = CSTRING(WipeGlasses); + condition = QUOTE(GVAR(showClearGlasses) && {call FUNC(canWipeGlasses)}); + statement = QUOTE(call FUNC(clearGlasses)); + exceptions[] = {"isNotInside", "isNotSitting", "isNotSwimming", "isNotEscorting"}; + }; + }; + }; + }; +}; diff --git a/addons/goggles/README.md b/addons/goggles/README.md index 959459f58e..627e750297 100644 --- a/addons/goggles/README.md +++ b/addons/goggles/README.md @@ -2,11 +2,3 @@ ace_goggles =========== Adds various effects to different kinds of goggles and ambient effects like dirt thrown up by explosions. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [esteldunedain](https://github.com/esteldunedain) -- [CorruptedHeart](https://github.com/CorruptedHeart) diff --git a/addons/goggles/RscTitles.hpp b/addons/goggles/RscTitles.hpp index 5544b9b132..0716892312 100644 --- a/addons/goggles/RscTitles.hpp +++ b/addons/goggles/RscTitles.hpp @@ -1,37 +1,37 @@ -class RscTitles{ +class RscTitles { #include "define.hpp" - class RscACE_Goggles_BaseTitle{ + class RscACE_Goggles_BaseTitle { idd = -1; onLoad = "uiNamespace setVariable ['ACE_Goggles_Display', _this select 0]"; onUnload = "uiNamespace setVariable ['ACE_Goggles_Display', displayNull]"; fadeIn=0.5; fadeOut=0.5; - movingEnable = false; + movingEnable = 0; duration = 10e10; name = "RscACE_Goggles_BaseTitle"; class controls; }; - class RscACE_Goggles:RscACE_Goggles_BaseTitle{ + class RscACE_Goggles: RscACE_Goggles_BaseTitle { idd = 1044; name = "RscACE_Goggles"; - class controls{ - class gogglesImage: RscPicture{ + class controls { + class gogglesImage: RscPicture { idc = 10650; }; }; }; - class RscACE_GogglesEffects:RscACE_Goggles_BaseTitle{ + class RscACE_GogglesEffects: RscACE_Goggles_BaseTitle { idd = 1045; onLoad = "uiNamespace setVariable ['ACE_Goggles_DisplayEffects', _this select 0]"; onUnload = "uiNamespace setVariable ['ACE_Goggles_DisplayEffects', displayNull]"; name = "RscACE_GogglesEffects"; fadeIn=0; fadeOut=0.5; - class controls{ - class dirtImage: RscPicture { + class controls { + class dirtImage: RscPicture { idc = 10660; }; class dustImage: RscPicture { diff --git a/addons/goggles/XEH_PREP.hpp b/addons/goggles/XEH_PREP.hpp index ba198439b5..fdbb4f9fef 100644 --- a/addons/goggles/XEH_PREP.hpp +++ b/addons/goggles/XEH_PREP.hpp @@ -17,6 +17,7 @@ PREP(isGogglesVisible); PREP(isInRotorWash); // general +PREP(canWipeGlasses); PREP(clearGlasses); PREP(getExplosionIndex); diff --git a/addons/goggles/XEH_postInit.sqf b/addons/goggles/XEH_postInit.sqf index a1a7c53460..e5a6bf5d1c 100644 --- a/addons/goggles/XEH_postInit.sqf +++ b/addons/goggles/XEH_postInit.sqf @@ -3,19 +3,19 @@ if (!hasInterface) exitWith {}; ["ACE3 Common", QGVAR(wipeGlasses), localize LSTRING(WipeGlasses), { - if (GVAR(effects) != 2) exitWith {false}; //Can only wipe if full effects setting is set - if (!GETVAR(ace_player,ACE_isUnconscious,false)) exitWith { - call FUNC(clearGlasses); - true - }; - false + // Conditions: specific + if !(call FUNC(canWipeGlasses)) exitWith {false}; + + call FUNC(clearGlasses); + + true }, {false}, [20, [true, true, false]], false] call CBA_fnc_addKeybind; -["ace_settingsInitialized", { - TRACE_2("ace_settingsInitialized eh",GVAR(effects),GVAR(showInThirdPerson)); +["CBA_settingsInitialized", { + TRACE_2("CBA_settingsInitialized eh",GVAR(effects),GVAR(showInThirdPerson)); if (GVAR(effects) == 0) exitWith {}; @@ -85,13 +85,13 @@ if (!hasInterface) exitWith {}; // // ---Add the Dust/Dirt/Rain Effects--- - if (GVAR(effects) == 2) then { + if (GVAR(effects) in [2, 3]) then { // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; //Add Explosion XEH - ["CAManBase", "explosion", FUNC(handleExplosion)] call CBA_fnc_addClassEventHandler; + ["CAManBase", "explosion", LINKFUNC(handleExplosion)] call CBA_fnc_addClassEventHandler; GVAR(PostProcessEyes) = ppEffectCreate ["ColorCorrections", 1992]; GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [1, 1, 1, 0]]; @@ -133,12 +133,16 @@ if (!hasInterface) exitWith {}; }] call CBA_fnc_addEventHandler; + // Handle "rain is snow" maps like CUP's Chernarus Winter + private _rainSpeed = getNumber (configFile >> "CfgWorlds" >> worldName >> "RainParticles" >> "dropSpeed"); + GVAR(mapHasRain) = _rainSpeed > 10; // CAWorld default is 25, Chernarus_Winter is 1 + // goggles effects main PFH [{ BEGIN_COUNTER(goggles); // rain - call FUNC(applyRainEffect); + if (GVAR(mapHasRain)) then FUNC(applyRainEffect); // auto remove effects under water if (GVAR(EffectsActive) && {underwater ACE_player} && {[goggles ACE_player] call FUNC(isDivingGoggles)}) then { diff --git a/addons/goggles/XEH_preInit.sqf b/addons/goggles/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/goggles/XEH_preInit.sqf +++ b/addons/goggles/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/goggles/anim/zDummy.rtm b/addons/goggles/anim/zDummy.rtm new file mode 100644 index 0000000000..dfeb7b7fcc Binary files /dev/null and b/addons/goggles/anim/zDummy.rtm differ diff --git a/addons/goggles/config.cpp b/addons/goggles/config.cpp index ba2e1a1d29..f39ab4d458 100644 --- a/addons/goggles/config.cpp +++ b/addons/goggles/config.cpp @@ -16,6 +16,7 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" #define COMBAT_GOGGLES ACE_Overlay = QPATHTOF(textures\HUD\CombatGoggles.paa); \ ACE_OverlayCracked = QPATHTOF(textures\HUD\CombatGogglesCracked.paa); \ @@ -34,7 +35,14 @@ class CfgGlasses { ACE_DustPath = QPATHTOF(textures\fx\dust\%1.paa); }; - class G_Combat:None { + class G_Blindfold_01_base_F: None { + ACE_Overlay = QPATHTOF(textures\HUD\blindfold_ca.paa); + ACE_OverlayCracked = ""; + ACE_Resistance = 2; + ACE_Protection = 1; + }; + + class G_Combat: None { COMBAT_GOGGLES }; @@ -49,136 +57,136 @@ class CfgGlasses { ACE_Protection = 1; }; - class G_Lowprofile:None { - ACE_TintAmount=COLOUR*2; + class G_Lowprofile: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 2; ACE_Protection = 1; }; - class G_Shades_Black:None { - ACE_TintAmount=COLOUR*2; + class G_Shades_Black: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; }; - class G_Shades_Blue:None{ + class G_Shades_Blue: None { ACE_Color[] = {0,0,1}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Shades_Green:None{ + class G_Shades_Green: None { ACE_Color[] = {0,1,0}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Shades_Red:None{ + class G_Shades_Red: None { ACE_Color[] = {1,0,0}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Spectacles:None{ + class G_Spectacles: None { ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Spectacles_Tinted:None{ - ACE_TintAmount=COLOUR*2; + class G_Spectacles_Tinted: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; }; - class G_Sport_Blackred:None{ + class G_Sport_Blackred: None { ACE_Color[] = {1,0,0}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Sport_BlackWhite:None{ + class G_Sport_BlackWhite: None { ACE_Color[] = {0,0,1}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Sport_Blackyellow:None{ - ACE_TintAmount=COLOUR*2; + class G_Sport_Blackyellow: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; }; - class G_Sport_Checkered:None{ - ACE_TintAmount=COLOUR*2; + class G_Sport_Checkered: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; }; - class G_Sport_Greenblack:None{ - ACE_TintAmount=COLOUR*2; + class G_Sport_Greenblack: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; }; - class G_Sport_Red:None{ - ACE_TintAmount=COLOUR*2; + class G_Sport_Red: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Color[] = {0,0,0}; ACE_Resistance = 1; }; - class G_Squares:None{ + class G_Squares: None { ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Squares_Tinted:None{ + class G_Squares_Tinted: None { ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Tactical_Black:None{ + class G_Tactical_Black: None { ACE_TintAmount=COLOUR; ACE_Color[] = {0,0,-1.5}; ACE_Resistance = 1; }; - class G_Tactical_Clear:None{ + class G_Tactical_Clear: None { ACE_TintAmount=COLOUR; ACE_Color[] = {0,0,-1}; ACE_Resistance = 1; }; - class G_Aviator:None{ + class G_Aviator: None { ACE_Color[] = {0,0,-1}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Lady_Blue:None{ + class G_Lady_Blue: None { ACE_Color[] = {0,0,1}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Lady_Red:None{ + class G_Lady_Red: None { ACE_Color[] = {1,0,0}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; - class G_Lady_Dark:None{ - ACE_TintAmount=COLOUR*2; + class G_Lady_Dark: None { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; }; - class G_Lady_Mirror:None{ + class G_Lady_Mirror: None { ACE_TintAmount=COLOUR; ACE_Resistance = 1; }; class G_Balaclava_blk; - class G_Balaclava_combat:G_Balaclava_blk { + class G_Balaclava_combat: G_Balaclava_blk { COMBAT_GOGGLES }; - class G_Balaclava_lowprofile:G_Balaclava_blk { - ACE_TintAmount=COLOUR*2; + class G_Balaclava_lowprofile: G_Balaclava_blk { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 2; ACE_Protection = 1; }; @@ -194,8 +202,8 @@ class CfgGlasses { }; class G_Bandanna_blk; - class G_Bandanna_shades:G_Bandanna_blk { - ACE_TintAmount=COLOUR*2; + class G_Bandanna_shades: G_Bandanna_blk { + ACE_TintAmount=QUOTE(COLOUR*2); ACE_Resistance = 1; ACE_Protection = 1; }; @@ -221,6 +229,22 @@ class CfgGlasses { ACE_Resistance = 1; ACE_Protection = 1; }; + + class G_AirPurifyingRespirator_01_base_F: None { + ACE_Overlay = "a3\ui_f_enoch\data\objects\data\optics_apr_ca.paa"; + ACE_OverlayCracked = ""; + ACE_Resistance = 2; + ACE_Protection = 1; + ACE_Overlay_Angle = 180; + }; + class G_AirPurifyingRespirator_02_base_F: G_AirPurifyingRespirator_01_base_F { + ACE_Overlay = "a3\ui_f_enoch\data\objects\data\optics_APR_02_CA.paa"; + }; + class G_RegulatorMask_base_F: None { + ACE_Overlay = "a3\ui_f_enoch\data\objects\data\optics_regulator_ca.paa"; + ACE_OverlayCracked = ""; + ACE_Overlay_Angle = 180; + }; }; #include "RscTitles.hpp" @@ -244,13 +268,13 @@ class CfgGesturesMale { class CfgWeapons { class H_HelmetB; - class H_CrewHelmetHeli_B:H_HelmetB { + class H_CrewHelmetHeli_B: H_HelmetB { ACE_Protection = 1; }; - class H_PilotHelmetHeli_B:H_HelmetB { + class H_PilotHelmetHeli_B: H_HelmetB { ACE_Protection = 1; }; - class H_PilotHelmetFighter_B:H_HelmetB { + class H_PilotHelmetFighter_B: H_HelmetB { ACE_Protection = 1; }; }; @@ -269,7 +293,7 @@ class SniperCloud { class CfgCloudlets { class Default; - class ACERainEffect:Default { + class ACERainEffect: Default { interval = 0.001; particleShape = "\A3\data_f\ParticleEffects\Universal\Refract"; particleFSNtieth = 1; diff --git a/addons/goggles/define.hpp b/addons/goggles/define.hpp index 38271ccc67..81d3fcb689 100644 --- a/addons/goggles/define.hpp +++ b/addons/goggles/define.hpp @@ -18,8 +18,8 @@ class RscPicture { fixedWidth = 0; shadow = 0; text = ""; - x = safezoneX; - y = safezoneY; - w = safezoneW; - h = safezoneH; + x = "safezoneX"; + y = "safezoneY"; + w = "safezoneW"; + h = "safezoneH"; }; diff --git a/addons/goggles/functions/fnc_applyDirtEffect.sqf b/addons/goggles/functions/fnc_applyDirtEffect.sqf index df73bd5bec..38fc57f0ce 100644 --- a/addons/goggles/functions/fnc_applyDirtEffect.sqf +++ b/addons/goggles/functions/fnc_applyDirtEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds dirt effect to the glasses. @@ -28,7 +28,7 @@ if ([_unit] call FUNC(isGogglesVisible)) then { private _dirtImage = getText (configFile >> "CfgGlasses" >> goggles _unit >> "ACE_OverlayDirt"); if (_dirtImage != "") then { - GVAR(GogglesEffectsLayer) cutRsc ["RscACE_GogglesEffects", "PLAIN", 0.1, false]; + GVAR(GogglesEffectsLayer) cutRsc ["RscACE_GogglesEffects", "PLAIN", 0.1, false, false]; (GETUVAR(GVAR(DisplayEffects),displayNull) displayCtrl 10660) ctrlSetText _dirtImage; private _effectBrightness = linearConversion [0,1,([] call EFUNC(common,ambientBrightness)),0.25,1]; diff --git a/addons/goggles/functions/fnc_applyDustEffect.sqf b/addons/goggles/functions/fnc_applyDustEffect.sqf index d8c6e1c07a..93bcbad1d6 100644 --- a/addons/goggles/functions/fnc_applyDustEffect.sqf +++ b/addons/goggles/functions/fnc_applyDustEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Applies dust to screen. @@ -20,7 +20,7 @@ if (call FUNC(ExternalCamera)) exitWith {}; private _unit = ACE_player; if ([_unit] call FUNC(isGogglesVisible)) exitWith { - GVAR(GogglesEffectsLayer) cutRsc ["RscACE_GogglesEffects", "PLAIN", 2, false]; + GVAR(GogglesEffectsLayer) cutRsc ["RscACE_GogglesEffects", "PLAIN", 2, false, false]; ((GETUVAR(GVAR(DisplayEffects),displayNull)) displayCtrl 10662) ctrlSetText format [getText (configFile >> "CfgGlasses" >> goggles _unit >> "ACE_DustPath"), GETDUSTT(DAMOUNT) + 1]; diff --git a/addons/goggles/functions/fnc_applyGlassesEffect.sqf b/addons/goggles/functions/fnc_applyGlassesEffect.sqf index 096673ea3a..9df47ec4d2 100644 --- a/addons/goggles/functions/fnc_applyGlassesEffect.sqf +++ b/addons/goggles/functions/fnc_applyGlassesEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets screen tint for glasses. @@ -24,7 +24,7 @@ TRACE_2("applyGlassesEffect",_player,_glasses); // remove old effect call FUNC(removeGlassesEffect); -if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _player) >> "isPlayableLogic")) == 1) exitWith { +if ((getNumber (configOf _player >> "isPlayableLogic")) == 1) exitWith { TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) }; @@ -33,7 +33,7 @@ private _config = configFile >> "CfgGlasses" >> _glasses; private _postProcessColour = getArray (_config >> "ACE_Color"); private _postProcessTintAmount = getNumber (_config >> "ACE_TintAmount"); -if (_postProcessTintAmount != 0 && {GVAR(UsePP)}) then { +if (_postProcessTintAmount != 0 && {GVAR(UsePP)} && GVAR(effects) in [1, 2]) then { _postProcessColour set [3, _postProcessTintAmount/100]; GVAR(PostProcess) ppEffectAdjust[0.9, 1.1, 0.004, _postProcessColour, [0,0,0,1],[0,0,0,0]]; GVAR(PostProcess) ppEffectCommit 0; @@ -44,13 +44,19 @@ if (_postProcessTintAmount != 0 && {GVAR(UsePP)}) then { }; private _imagePath = getText (_config >> ["ACE_Overlay", "ACE_OverlayCracked"] select GETBROKEN); +private _angle = getNumber (_config >> "ACE_Overlay_Angle"); if (_imagePath != "") then { - GVAR(GogglesLayer) cutRsc ["RscACE_Goggles", "PLAIN", 1, false]; - (GLASSDISPLAY displayCtrl 10650) ctrlSetText _imagePath; + GVAR(GogglesLayer) cutRsc ["RscACE_Goggles", "PLAIN", 1, false, false]; + private _overlay = (GLASSDISPLAY displayCtrl 10650); + _overlay ctrlSetText _imagePath; + + if ((_angle != 0) && {((ctrlAngle _overlay) # 0) != _angle}) then { + _overlay ctrlSetAngle [_angle, 0.5, 0.5, true]; + }; }; -if (GVAR(effects) == 2) then { +if (GVAR(effects) in [2, 3]) then { if (GETDIRT) then { call FUNC(applyDirtEffect); }; diff --git a/addons/goggles/functions/fnc_applyRainEffect.sqf b/addons/goggles/functions/fnc_applyRainEffect.sqf index 845490f95f..0058209acd 100644 --- a/addons/goggles/functions/fnc_applyRainEffect.sqf +++ b/addons/goggles/functions/fnc_applyRainEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Handles rain effects being created on glasses. @@ -22,7 +22,7 @@ if (!alive _unit) exitWith {}; private _fnc_underCover = { params ["_unit"]; - if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith {true}; + if (!isNull objectParent _unit && {!isTurnedOut _unit}) exitWith {true}; // looking up and no roof over head private _position = eyePos _unit; diff --git a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf index ab71f01d51..85b7e60934 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Handles the rotor wash effects. @@ -23,7 +23,7 @@ if (!alive _unit) exitWith {}; GVAR(FrameEvent) set [0, !(GVAR(FrameEvent) select 0)]; if (GVAR(FrameEvent) select 0) exitWith { - if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith { + if (!isNull objectParent _unit && {!isTurnedOut _unit}) exitWith { (GVAR(FrameEvent) select 1) set [0, false]; }; diff --git a/addons/goggles/functions/fnc_canWipeGlasses.sqf b/addons/goggles/functions/fnc_canWipeGlasses.sqf new file mode 100644 index 0000000000..ef9d961bc1 --- /dev/null +++ b/addons/goggles/functions/fnc_canWipeGlasses.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Checks if player can wipe goggles. + * + * Arguments: + * None + * + * Return Value: + * Can wipe goggles + * + * Example: + * [] call ace_goggles_fnc_canWipeGlasses + * + * Public: No + */ + +GVAR(effects) in [2, 3] && {!GETVAR(ACE_player,ACE_isUnconscious,false)} // return diff --git a/addons/goggles/functions/fnc_clearGlasses.sqf b/addons/goggles/functions/fnc_clearGlasses.sqf index 5efc547c10..f00ad4629c 100644 --- a/addons/goggles/functions/fnc_clearGlasses.sqf +++ b/addons/goggles/functions/fnc_clearGlasses.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Clears all dirt, rain, dust from glasses. diff --git a/addons/goggles/functions/fnc_externalCamera.sqf b/addons/goggles/functions/fnc_externalCamera.sqf index 0cd06fdcd6..4afafa3a5a 100644 --- a/addons/goggles/functions/fnc_externalCamera.sqf +++ b/addons/goggles/functions/fnc_externalCamera.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Returns if the camera is external or not. diff --git a/addons/goggles/functions/fnc_getExplosionIndex.sqf b/addons/goggles/functions/fnc_getExplosionIndex.sqf index 33f0668bef..1007085d5a 100644 --- a/addons/goggles/functions/fnc_getExplosionIndex.sqf +++ b/addons/goggles/functions/fnc_getExplosionIndex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Turns 0-1 damage of explosion Event into a rating system of 0-3 diff --git a/addons/goggles/functions/fnc_handleExplosion.sqf b/addons/goggles/functions/fnc_handleExplosion.sqf index db38e9ab20..8b6027cb36 100644 --- a/addons/goggles/functions/fnc_handleExplosion.sqf +++ b/addons/goggles/functions/fnc_handleExplosion.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Handles explosions. @@ -41,7 +41,7 @@ if (getText (_config >> "ACE_OverlayCracked") != "") then { if (call FUNC(ExternalCamera)) exitWith {}; if (isNull (GLASSDISPLAY)) then { - GVAR(GogglesLayer) cutRsc ["RscACE_Goggles", "PLAIN", 1, false]; + GVAR(GogglesLayer) cutRsc ["RscACE_Goggles", "PLAIN", 1, false, false]; }; (GLASSDISPLAY displayCtrl 10650) ctrlSetText getText (_config >> "ACE_OverlayCracked"); diff --git a/addons/goggles/functions/fnc_handleFired.sqf b/addons/goggles/functions/fnc_handleFired.sqf index 434a61ee5f..0c711169ef 100644 --- a/addons/goggles/functions/fnc_handleFired.sqf +++ b/addons/goggles/functions/fnc_handleFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Determines whether to place dust on the goggles, based on calibre of weapon fired and other requirements. Called from the unified fired EH only for the local player. @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); // no dust in rain if (rain > 0.1) exitWith {true}; diff --git a/addons/goggles/functions/fnc_handleKilled.sqf b/addons/goggles/functions/fnc_handleKilled.sqf index db7364492d..ebf9657ba9 100644 --- a/addons/goggles/functions/fnc_handleKilled.sqf +++ b/addons/goggles/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Handles the player dying. @@ -22,7 +22,7 @@ if (GVAR(effects) == 0) exitWith {true}; call FUNC(removeGlassesEffect); -if (GVAR(effects) == 2) then { +if (GVAR(effects) in [2, 3]) then { GVAR(PostProcessEyes) ppEffectEnable false; SETGLASSES(_unit,GLASSESDEFAULT); diff --git a/addons/goggles/functions/fnc_isDivingGoggles.sqf b/addons/goggles/functions/fnc_isDivingGoggles.sqf index cc173f6dc3..2595142e83 100644 --- a/addons/goggles/functions/fnc_isDivingGoggles.sqf +++ b/addons/goggles/functions/fnc_isDivingGoggles.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Determines whether passed goggles is diving goggles or a variant of them. diff --git a/addons/goggles/functions/fnc_isGogglesVisible.sqf b/addons/goggles/functions/fnc_isGogglesVisible.sqf index 3ad5085a57..d52134b298 100644 --- a/addons/goggles/functions/fnc_isGogglesVisible.sqf +++ b/addons/goggles/functions/fnc_isGogglesVisible.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Determines if goggles are visible on passed unit. diff --git a/addons/goggles/functions/fnc_isInRotorWash.sqf b/addons/goggles/functions/fnc_isInRotorWash.sqf index d978cde0ce..6784e9db12 100644 --- a/addons/goggles/functions/fnc_isInRotorWash.sqf +++ b/addons/goggles/functions/fnc_isInRotorWash.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Checks for nearby running helicopters (within 15m) @@ -9,8 +9,8 @@ * * Return Value: * Array : - * 0: In rotorwash - * 1: Amount of rotor wash. + * - 0: In rotorwash + * - 1: Amount of rotor wash. * * Example: * if ([ace_player, 10] call ace_goggles_fnc_isInRotorWash select 0) then { hint "Rotor wash"; }; @@ -36,7 +36,6 @@ private _rotorWash = [false, 0]; _rotorWash set [1, _distance]; }; }; - false -} count (position _unit nearEntities [["Helicopter"], _radius]); +} forEach (position _unit nearEntities [["Helicopter"], _radius]); _rotorWash diff --git a/addons/goggles/functions/fnc_removeDirtEffect.sqf b/addons/goggles/functions/fnc_removeDirtEffect.sqf index 732cbb5c23..eff8e102ab 100644 --- a/addons/goggles/functions/fnc_removeDirtEffect.sqf +++ b/addons/goggles/functions/fnc_removeDirtEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes dirt from the glasses. diff --git a/addons/goggles/functions/fnc_removeDustEffect.sqf b/addons/goggles/functions/fnc_removeDustEffect.sqf index 00031084b2..8d424662d9 100644 --- a/addons/goggles/functions/fnc_removeDustEffect.sqf +++ b/addons/goggles/functions/fnc_removeDustEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes dust from the glasses. diff --git a/addons/goggles/functions/fnc_removeGlassesEffect.sqf b/addons/goggles/functions/fnc_removeGlassesEffect.sqf index ab19570594..ea6286187b 100644 --- a/addons/goggles/functions/fnc_removeGlassesEffect.sqf +++ b/addons/goggles/functions/fnc_removeGlassesEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes the glasses effect from the screen, removes dirt effect, removes rain effect, removes dust effect. Does not reset array (glasses will still be broken, dirty, ect.) @@ -22,7 +22,7 @@ if (!isNull (GLASSDISPLAY)) then { GLASSDISPLAY closeDisplay 0; }; -if (GVAR(effects) == 2) then { +if (GVAR(effects) in [2, 3]) then { call FUNC(removeDirtEffect); call FUNC(removeRainEffect); call FUNC(removeDustEffect); diff --git a/addons/goggles/functions/fnc_removeRainEffect.sqf b/addons/goggles/functions/fnc_removeRainEffect.sqf index 53de0721b1..b5140566c3 100644 --- a/addons/goggles/functions/fnc_removeRainEffect.sqf +++ b/addons/goggles/functions/fnc_removeRainEffect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes rain effects from the screen. diff --git a/addons/goggles/functions/script_component.hpp b/addons/goggles/functions/script_component.hpp deleted file mode 100644 index d8624df3b2..0000000000 --- a/addons/goggles/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\goggles\script_component.hpp" diff --git a/addons/goggles/initSettings.inc.sqf b/addons/goggles/initSettings.inc.sqf new file mode 100644 index 0000000000..9b2fba6ef7 --- /dev/null +++ b/addons/goggles/initSettings.inc.sqf @@ -0,0 +1,23 @@ +[ + QGVAR(effects), "LIST", + LSTRING(effects_displayName), + localize LSTRING(SettingsName), + [[0, 1, 2, 3], [ELSTRING(common,Disabled), LSTRING(effects_tintOnly), LSTRING(enabled_tintAndEffects), LSTRING(effects_effectsOnly)], 2], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showInThirdPerson), "CHECKBOX", + LSTRING(ShowInThirdPerson), + localize LSTRING(SettingsName), + false, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showClearGlasses), "CHECKBOX", + [LSTRING(SettingShowClearGlasses), LELSTRING(common,showActionInSelfInteraction)], + localize LSTRING(SettingsName), + false, // default value + 0 // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index f12d4d31e5..f02b95bf5c 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -11,22 +11,44 @@ 고글 Gogle Очки + Óculos + Lunettes + Brýle + Gafas + Gözlük + + + ACE Goggles + ACE Schutzbrille + ACE Occhiali + ACE 護目鏡 + ACE 护目镜 + ACE ゴーグル + ACE 고글 + ACE Gogle + ACE Очки + ACE Óculos + ACE Lunettes + ACE Brýle + [ACE] Gafas + ACE Gözlük Show Goggle Effects in Third Person Brilleneffekt in dritter Person anzeigen Mostrar efectos de las gafas en tercera persona Zobrazit efekt brýlí v třetí osobě - Effets de lunettes à la 3ème personne - Отображать эффект очков от третьего лица + Effets des lunettes à la 3ème personne + Вкл. эффект очков от 3-го лица Szemüveg-effekt mutatása külső nézetből Włącz efekty gogli w trzeciej osobie Mostrar efeitos de óculos em Terceira Pessoa Attiva l'effetto degli occhiali in terza persona - 三人称視点でもゴーグルによる効果を出す - 3인칭시에도 고글 효과를 보이게 합니다 + 三人称視点でもゴーグルによる効果を表示 + 3인칭 시에도 고글 효과를 보이게 하기 在第三人称视角显示护目镜效果 在第三人稱視角顯示護目鏡效果 + Gözlük efektlerini 3. şahıs görünümün de göster Wipe Goggles @@ -43,6 +65,7 @@ 고글 닦기 擦拭护目镜 擦拭護目鏡 + Gözlük Camlarını Sil Goggle Effects @@ -55,6 +78,10 @@ Effetti Occhiali 护目镜效果 護目鏡效果 + Efeitos de Óculos + Efekty brýlí + Efectos de gafas + Gözlük efektleri Tint @@ -65,20 +92,60 @@ 색조 Teinte Colore - 染色 + 着色 染色 + Cor + Zabarvení + Tinte + Ton + + + Effects + Эффекты + エフェクト + Efekty + Effekte + 효과 + Effets + Effetti + 影响 + 影響 + Efeitos + Efekty + Efectos + Efektler Tint + Effects Тонировка + эффекты - 色彩 + 効果 + 色彩 + エフェクト Winieta + Efekty Tönung + Effekte 색조+효과 Teinte + effets Colore + Effetti - 染色 + 影响 + 着色 + 效果 染色 + 影響 + Cor + Efeitos + Zabarvení + Efekty + Tinte + efectos + Ton + Efektler + + + Show Wipe Goggles self interaction + Zeige "Brille abwischen" im Selbstinteraktionsmenü + Pokaż interakcję Wyczyść Gogle + Mostra interazione automatica per la pulizia degli occhiali + Ukaž Vyčistit brýle v menu Interakce (vlastní) + ゴーグル拭き取りをセルフ インタラクションに表示 + 在自我互動中顯示擦拭護目鏡的動作 + 在自我互动中显示擦拭护目镜的动作 + Afficher l'interaction "Essuyer les lunettes" + Mostra a auto-interação de limpar os óculos + Mostrar limpiar gafas en menú de auto-interacción + Kendi etkileşim menüsün de gözlük camlarını silmeyi göster + Показывать действие Протереть очки + 자기상호작용에 고글 닦기 선택 보이기 diff --git a/addons/goggles/textures/HUD/blindfold_ca.paa b/addons/goggles/textures/HUD/blindfold_ca.paa new file mode 100644 index 0000000000..460cf649b3 Binary files /dev/null and b/addons/goggles/textures/HUD/blindfold_ca.paa differ diff --git a/addons/grenades/CfgAmmo.hpp b/addons/grenades/CfgAmmo.hpp index c52ec34d04..2b0849d2f7 100644 --- a/addons/grenades/CfgAmmo.hpp +++ b/addons/grenades/CfgAmmo.hpp @@ -1,4 +1,3 @@ - class CfgAmmo { class Default; class Grenade: Default { @@ -120,6 +119,16 @@ class CfgAmmo { whistleDist = 0; }; + class ACE_G_CTS9: ACE_G_M84 { + GVAR(flashbang) = 1; + GVAR(flashbangBangs) = 9; + GVAR(flashbangInterval) = 0.5; + GVAR(flashbangIntervalMaxDeviation) = 0.35; + model = QPATHTOF(models\ACE_CTS_9bang_thrown.p3d); + explosionTime = 1.5; + timeToLive = 10; + }; + class Chemlight_base: SmokeShell { GVAR(pullPinSound)[] = {"A3\sounds_f\weapons\Other\dry4.wss", 3, 2, 10}; soundImpactHard1[] = {"A3\sounds_f\characters\footsteps\concrete_run_1",1,1.8,65}; @@ -143,7 +152,7 @@ class CfgAmmo { class ACE_G_M14: SmokeShell { GVAR(incendiary) = 1; model = QPATHTOF(models\ace_anm14th3_armed.p3d); - hit = 5; + hit = 10; indirectHit = 4; indirectHitRange = 1.1; dangerRadiusHit = 50; @@ -161,4 +170,49 @@ class CfgAmmo { whistleDist = 0; // no BIS explosion effects whistleOnFire = 0; // no BIS firing effects }; + + class ACE_SatchelCharge_Remote_Ammo_Thrown: Grenade { + model = "\A3\Weapons_F\Explosives\satchel"; + hit = 3000; + indirectHit = 3000; + indirectHitRange = 5; + defaultMagazine = "ACE_SatchelCharge_Remote_Mag_Throwable"; + multiSoundHit[] = {"soundHit1", 0.5, "soundHit2", 0.5}; + ExplosionEffects = "MineNondirectionalExplosion"; + CraterEffects = "MineNondirectionalCrater"; + whistleDist = 10; + SoundSetExplosion[] = {"ClaymoreMine_Exp_SoundSet", "ClaymoreMine_Tail_SoundSet", "Explosion_Debris_SoundSet"}; + timeToLive = 8; + fuseDistance = 0; + explosionTime = 7; + deflectionSlowDown = 0.1; + explosionType = "bomb"; + ACE_damageType = "explosive"; + EGVAR(frag,skip) = 1; + EGVAR(advanced_throwing,torqueMagnitude) = "(5 + random 20) * selectRandom [1, -1]"; + GVAR(pullPinSound)[] = {"A3\Sounds_F_Orange\arsenal\explosives\Handling\ExplosiveSatchel_TouchOff_01.wss", 2, 1, 50}; + class CamShakeExplode { + power = 20; + duration = 2; + frequency = 20; + distance = 250; + }; + }; + + class ACE_DemoCharge_Remote_Ammo_Thrown: ACE_SatchelCharge_Remote_Ammo_Thrown { + model = "\A3\Weapons_F\explosives\c4_charge_small"; + hit = 500; + indirectHit = 500; + defaultMagazine = "ACE_DemoCharge_Remote_Mag_Throwable"; + ExplosionEffects = "MineNondirectionalExplosionSmall"; + CraterEffects = "MineNondirectionalCraterSmall"; + whistleDist = 32; + SoundSetExplosion[] = {"ExplosiveCharge_Exp_SoundSet", "ExplosiveCharge_Tail_SoundSet", "Explosion_Debris_SoundSet"}; + class CamShakeExplode { + power = 10; + duration = 2; + frequency = 20; + distance = 250; + }; + }; }; diff --git a/addons/grenades/CfgEventHandlers.hpp b/addons/grenades/CfgEventHandlers.hpp index becf395052..f6503c2479 100644 --- a/addons/grenades/CfgEventHandlers.hpp +++ b/addons/grenades/CfgEventHandlers.hpp @@ -1,18 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/grenades/CfgMagazineWells.hpp b/addons/grenades/CfgMagazineWells.hpp index 7ac4a555dd..6f75fa31f7 100644 --- a/addons/grenades/CfgMagazineWells.hpp +++ b/addons/grenades/CfgMagazineWells.hpp @@ -1,8 +1,8 @@ class CfgMagazineWells { class CBA_40mm_M203 { - ADDON[] = {"ACE_40mm_flare_white", "ACE_40mm_flare_red", "ACE_40mm_flare_green", "ACE_40mm_flare_ir"}; + 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"}; + ADDON[] = {"ACE_40mm_Flare_white", "ACE_40mm_Flare_red", "ACE_40mm_Flare_green", "ACE_40mm_Flare_ir"}; }; }; diff --git a/addons/grenades/CfgMagazines.hpp b/addons/grenades/CfgMagazines.hpp index 7faf13c9e1..2ff86c443d 100644 --- a/addons/grenades/CfgMagazines.hpp +++ b/addons/grenades/CfgMagazines.hpp @@ -1,4 +1,3 @@ - class CfgMagazines { class HandGrenade; class ACE_HandFlare_Base: HandGrenade { @@ -65,6 +64,17 @@ class CfgMagazines { mass = 4; }; + class ACE_CTS9: HandGrenade { + author = ECSTRING(common,ACETeam); + displayname = CSTRING(CTS9_Name); + descriptionShort = CSTRING(M84_Description); + displayNameShort = CSTRING(CTS9_NameShort); + model = QPATHTOF(models\ACE_CTS_9bang.p3d); + picture = QPATHTOF(UI\ace_cts9_x_ca.paa); + ammo = "ACE_G_CTS9"; + mass = 4; + }; + class SmokeShell; class ACE_M14: SmokeShell { author = ECSTRING(common,ACETeam); @@ -120,4 +130,45 @@ class CfgMagazines { displayName = CSTRING(40mm_flare_ir); descriptionShort = CSTRING(parachute_flare_ir_description); }; + + class CA_Magazine; + class ACE_SatchelCharge_Remote_Mag_Throwable: CA_Magazine { + author = ECSTRING(common,ACETeam); + ammo = "ACE_SatchelCharge_Remote_Ammo_Thrown"; + scope = 1; + picture = "\A3\Weapons_f\data\UI\gear_satchel_CA.paa"; + model = "\A3\Weapons_F\Explosives\satchel_i"; + displayName = CSTRING(SatchelCharge_Remote_Mag_Throwable); + displayNameShort = "$STR_A3_cfgMagazines_PipeBomb0"; + descriptionShort = CSTRING(SatchelCharge_Description); + class Library { + libTextDesc = CSTRING(SatchelCharge_LibText); + }; + type = "2* 256"; + allowedSlots[] = {901}; + value = 5; + mass = 80; + count = 1; + initSpeed = 7.5; + maxLeadSpeed = 0; + nameSound = "satchelcharge"; + nameSoundWeapon = "satchelcharge"; + sound[] = {"A3\sounds_f\dummysound", 0.000316228, 1, 10}; + useAction = 0; + }; + + class ACE_DemoCharge_Remote_Mag_Throwable: ACE_SatchelCharge_Remote_Mag_Throwable { + ammo = "ACE_DemoCharge_Remote_Ammo_Thrown"; + picture = "\A3\Weapons_F\Data\UI\gear_c4_charge_small_CA.paa"; + model = "\A3\Weapons_F\explosives\c4_charge_small_d"; + displayName = CSTRING(DemoCharge_Remote_Mag_Throwable); + displayNameShort = "$STR_A3_cfgMagazines_DemoCharge0"; + descriptionShort = CSTRING(SatchelCharge_Description); + class Library { + libTextDesc = CSTRING(DemoCharge_LibText); + }; + allowedSlots[] = {901, 701}; + mass = 20; + initSpeed = 12.5; + }; }; diff --git a/addons/grenades/CfgVehicles.hpp b/addons/grenades/CfgVehicles.hpp index f9ac60d9fe..34cf4196e6 100644 --- a/addons/grenades/CfgVehicles.hpp +++ b/addons/grenades/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class NATO_Box_Base; class Box_NATO_Grenades_F: NATO_Box_Base { diff --git a/addons/grenades/CfgWeapons.hpp b/addons/grenades/CfgWeapons.hpp index 832be6fe73..683ec7532b 100644 --- a/addons/grenades/CfgWeapons.hpp +++ b/addons/grenades/CfgWeapons.hpp @@ -1,8 +1,7 @@ - class CfgWeapons { class GrenadeLauncher; class Throw: GrenadeLauncher { - muzzles[] += {"ACE_HandFlare_WhiteMuzzle","ACE_HandFlare_RedMuzzle","ACE_HandFlare_GreenMuzzle","ACE_HandFlare_YellowMuzzle","ACE_M84Muzzle","ACE_M14Muzzle"}; + muzzles[] += {"ACE_HandFlare_WhiteMuzzle","ACE_HandFlare_RedMuzzle","ACE_HandFlare_GreenMuzzle","ACE_HandFlare_YellowMuzzle","ACE_M84Muzzle","ACE_M14Muzzle","ACE_CTS9Muzzle","ACE_SatchelMuzzle","ACE_DemoMuzzle"}; class ThrowMuzzle; class ACE_HandFlare_WhiteMuzzle: ThrowMuzzle { @@ -28,5 +27,17 @@ class CfgWeapons { class ACE_M14Muzzle: ThrowMuzzle { magazines[] = {"ACE_M14"}; }; + + class ACE_CTS9Muzzle: ThrowMuzzle { + magazines[] = {"ACE_CTS9"}; + }; + + class ACE_SatchelMuzzle: ThrowMuzzle { + magazines[] = {"ACE_SatchelCharge_Remote_Mag_Throwable"}; + }; + + class ACE_DemoMuzzle: ThrowMuzzle { + magazines[] = {"ACE_DemoCharge_Remote_Mag_Throwable"}; + }; }; }; diff --git a/addons/grenades/Effects.hpp b/addons/grenades/Effects.hpp index 95c3f12ba8..b4a16c6412 100644 --- a/addons/grenades/Effects.hpp +++ b/addons/grenades/Effects.hpp @@ -1,4 +1,3 @@ - class ACE_M84FlashbangEffect { // empty }; diff --git a/addons/grenades/README.md b/addons/grenades/README.md index c58ac19683..97addb3268 100644 --- a/addons/grenades/README.md +++ b/addons/grenades/README.md @@ -2,11 +2,3 @@ ace_grenades ============ Introduces different throwing modes for grenades, as well as a flashbang and hand flares. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/grenades/UI/ace_cts9_x_ca.paa b/addons/grenades/UI/ace_cts9_x_ca.paa new file mode 100644 index 0000000000..dfb775c23b Binary files /dev/null and b/addons/grenades/UI/ace_cts9_x_ca.paa differ diff --git a/addons/grenades/XEH_PREP.hpp b/addons/grenades/XEH_PREP.hpp index e5e0cb4732..06ceebc6b4 100644 --- a/addons/grenades/XEH_PREP.hpp +++ b/addons/grenades/XEH_PREP.hpp @@ -1,4 +1,5 @@ - +PREP(addChangeFuseItemContextMenuOptions); +PREP(damageEngineAndWheels); PREP(flare); PREP(flashbangExplosionEH); PREP(flashbangThrownFuze); diff --git a/addons/grenades/XEH_postInit.sqf b/addons/grenades/XEH_postInit.sqf index 6809321d83..c13bc81b43 100644 --- a/addons/grenades/XEH_postInit.sqf +++ b/addons/grenades/XEH_postInit.sqf @@ -1,13 +1,15 @@ // by commy2 #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" -["ace_flashbangExploded", {_this call FUNC(flashbangExplosionEH)}] call CBA_fnc_addEventHandler; +["ace_flashbangExploded", LINKFUNC(flashbangExplosionEH)] call CBA_fnc_addEventHandler; +[QGVAR(damageEngineAndWheels), LINKFUNC(damageEngineAndWheels)] call CBA_fnc_addEventHandler; // Register fired event handlers -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedPlayerNonLocal", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedNonPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayerNonLocal", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedNonPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; @@ -15,14 +17,45 @@ GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265]; GVAR(flashbangPPEffectCC) ppEffectForceInNVG true; // Add keybinds -["ACE3 Weapons", QGVAR(switchGrenadeMode), localize LSTRING(SwitchGrenadeMode), { +["ACE3 Weapons", QGVAR(switchGrenadeMode), LLSTRING(SwitchGrenadeMode), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement - [] call FUNC(nextMode); -}, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key + call FUNC(nextMode) // return +}, {}, [DIK_8, [false, false, false]], false] call CBA_fnc_addKeybind; // 8 Key + +["CBA_settingsInitialized", { + if (GVAR(convertExplosives)) then { + call FUNC(addChangeFuseItemContextMenuOptions); + }; +}] call CBA_fnc_addEventHandler; + +["vehicle", { + private _currentThrowable = currentThrowable ACE_player; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // If the player can't use throwables, don't change it + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(currentThrowMode) = 0; + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/grenades/XEH_preInit.sqf b/addons/grenades/XEH_preInit.sqf index b47cf6628d..9456dc9c9f 100644 --- a/addons/grenades/XEH_preInit.sqf +++ b/addons/grenades/XEH_preInit.sqf @@ -6,4 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +GVAR(currentThrowMode) = 0; +GVAR(throwModePFEH) = -1; + +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/grenades/config.cpp b/addons/grenades/config.cpp index 326308a5eb..504b8d5f0e 100644 --- a/addons/grenades/config.cpp +++ b/addons/grenades/config.cpp @@ -10,7 +10,10 @@ class CfgPatches { "ACE_HandFlare_Green", "ACE_HandFlare_Yellow", "ACE_M84", - "ACE_M14" + "ACE_M14", + "ACE_CTS9", + "ACE_SatchelCharge_Remote_Mag_Throwable", + "ACE_DemoCharge_Remote_Mag_Throwable" }; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; diff --git a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf new file mode 100644 index 0000000000..c0b5c9dc80 --- /dev/null +++ b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf @@ -0,0 +1,109 @@ +#include "..\script_component.hpp" +/* + * Author: Cyruz + * Allows conversion of explosive charges into throwable versions. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_grenades_fnc_addChangeFuseItemContextMenuOptions + * + * Public: No + */ + +LOG("addChangeFuseItemContextMenuOptions"); + +{ + _x params ["_mag", "_throwableMag"]; + + [ + _mag, + "CONTAINER", + LLSTRING(convert_fuse), + nil, + "\a3\ui_f\data\igui\cfg\simpletasks\types\destroy_ca.paa", + [ + {true}, + { + params ["", "", "_item", "", "_magArr"]; + + _item == (_magArr select 0) + } + ], + { + params ["_unit", "", "", "_slot", "_magArr"]; + + private _container = switch (_slot) do { + case "UNIFORM_CONTAINER": { + "uniform" + }; + case "VEST_CONTAINER": { + "vest" + }; + case "BACKPACK_CONTAINER": { + "backpack" + }; + default { + "" + }; + }; + + if (_container != "") then { + [_unit, _magArr select 1, _container] call EFUNC(common,addToInventory); + }; + + false + }, + true, + [_mag, _throwableMag] + ] call CBA_fnc_addItemContextMenuOption; + + [ + _throwableMag, + "CONTAINER", + LLSTRING(remove_fuse), + nil, + "\a3\ui_f\data\igui\cfg\simpletasks\types\destroy_ca.paa", + [ + {true}, + { + params ["", "", "_item", "", "_magArr"]; + + _item == (_magArr select 1) + } + ], + { + params ["_unit", "", "", "_slot", "_magArr"]; + + private _container = switch (_slot) do { + case "UNIFORM_CONTAINER": { + "uniform" + }; + case "VEST_CONTAINER": { + "vest" + }; + case "BACKPACK_CONTAINER": { + "backpack" + }; + default { + "" + }; + }; + + if (_container != "") then { + [_unit, _magArr select 0, _container] call EFUNC(common,addToInventory); + }; + + false + }, + true, + [_mag, _throwableMag] + ] call CBA_fnc_addItemContextMenuOption; +} forEach [ + ["SatchelCharge_Remote_Mag", "ACE_SatchelCharge_Remote_Mag_Throwable"], + ["DemoCharge_Remote_Mag", "ACE_DemoCharge_Remote_Mag_Throwable"] +]; diff --git a/addons/grenades/functions/fnc_damageEngineAndWheels.sqf b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf new file mode 100644 index 0000000000..ab95ecbe6a --- /dev/null +++ b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Damage a vehicle's wheels and engine. + * + * Arguments: + * 0: Vehicle + * 1: Incendiary position AGL + * + * Return Value: + * None + * + * Example: + * [cursorObject, position cursorObject] call ace_grenades_fnc_damageEngineAndWheels + * + * Public: No + */ + +params ["_vehicle", "_position"]; +TRACE_2("damageWheelsAndEngine",_vehicle,_position); + +// Vehicle needs to be local and vulnerable +if !(local _vehicle && {isDamageAllowed _vehicle}) exitWith {}; + +{ + // If wheel is close enough to incendiary, burn it + if (_position distance (_vehicle modelToWorld (_vehicle selectionPosition _x)) < EFFECT_SIZE * 2) then { + _vehicle setHit [_x, 1]; + }; +} forEach ((_vehicle call EFUNC(common,getWheelHitPointsWithSelections)) select 1); + +// Burn car engines only +if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; + +private _engineSelection = getText (configOf _vehicle >> "HitPoints" >> "HitEngine" >> "name"); +private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); + +if (_position distance _enginePosition < EFFECT_SIZE * 2) then { + _vehicle setHit [_engineSelection, 1]; + + if (["ace_cookoff"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; + }; +}; diff --git a/addons/grenades/functions/fnc_flare.sqf b/addons/grenades/functions/fnc_flare.sqf index 9ad3348f6b..2db6335a77 100644 --- a/addons/grenades/functions/fnc_flare.sqf +++ b/addons/grenades/functions/fnc_flare.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Makes flare shine. * * Arguments: - * 0: The flare + * 0: Flare * 1: Color of flare * 2: Intensity of flare * 3: Flare lifetime @@ -34,6 +34,5 @@ _light setLightFlareMaxDistance 1000; _light setLightDayLight true; _light lightAttachObject [_projectile, [0,0,0]]; -//_light attachTo [_projectile, [0,0,0]]; [{deleteVehicle _this}, _light, _timeToLive] call CBA_fnc_waitAndExecute; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index 7beb128df6..33c4bdffc2 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Creates the flashbang effect and knock out AI units. * * Arguments: - * 0: The flashBang position ASL + * 0: Flashbang position ASL * * Return Value: * None @@ -18,130 +18,148 @@ params ["_grenadePosASL"]; TRACE_1("params",_grenadePosASL); -// Create flash to illuminate environment -if (hasInterface) then { - private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; - _light setPosASL _grenadePosASL; - - _light setLightBrightness 20; - _light setLightAmbient [1,1,1]; - _light setLightColor [1,1,1]; - _light setLightDayLight true; - _light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - - // Reduce the light after 0.1 seconds - [{ - params ["_light"]; - _light setLightBrightness 5; - // Delete the light after 0.2 more seconds - [{ - params ["_light"]; - deleteVehicle _light; - }, [_light], 0.2] call CBA_fnc_waitAndExecute; - }, [_light], 0.1] call CBA_fnc_waitAndExecute; -}; - -// Affect local AI +// Affect local AI (players are not local, except for ACE_player) // @todo: Affect units in static weapons, turned out, etc -private _affected = (ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]; -_affected = _affected - [ACE_player]; +private _affected = ((ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]) - [ACE_player]; + { - if (local _x && {alive _x}) then { - private _strength = 1 - (((getPosASL _x) vectorDistance _grenadePosASL) min 20) / 20; + private _unit = _x; + private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; - TRACE_3("FlashBangEffect Start",_x,((getPosASL _x) vectorDistance _grenadePosASL),_strength); + TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); - [_x, true] call EFUNC(common,disableAI); + [_unit, true] call EFUNC(common,disableAI); - _x setSkill (skill _x / 50); + // Make AI try to look away + private _dirToFlash = _unit getDir _grenadePosASL; + _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); - if (_strength > 0.2) then { - _x setVectorDir ((getPosASL _x) vectorDiff _grenadePosASL); - }; + private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; + _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; + + if (_flashReactionDebounce < CBA_missionTime) then { + // Not used internally but could be useful for other mods + _unit setVariable [QGVAR(flashStrength), _strength, true]; + + [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; + + { + _unit setSkill [_x, (_unit skill _x) / 50]; + } forEach SUBSKILLS; [{ + CBA_missiontime >= _this getVariable [QGVAR(flashReactionDebounce), 0] + }, { params ["_unit"]; - //Make sure we don't enable AI for unconscious units - if !(_unit getVariable ["ace_isUnconscious", false]) then { + _unit setVariable [QGVAR(flashStrength), 0, true]; + + // Make sure we don't enable AI for unconscious units + if (_unit call EFUNC(common,isAwake)) then { [_unit, false] call EFUNC(common,disableAI); }; - _unit setSkill (skill _unit * 50); - }, [_x], 7 * _strength] call CBA_fnc_waitAndExecute; + { + _unit setSkill [_x, (_unit skill _x) * 50]; + } forEach SUBSKILLS; + }, _unit] call CBA_fnc_waitUntilAndExecute; }; -} count _affected; +} forEach (_affected select {local _x && {_x call EFUNC(common,isAwake)}}); + +if (!hasInterface) exitWith {}; + +// Create flash to illuminate environment +private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; +_light setPosASL _grenadePosASL; + +_light setLightBrightness 20; +_light setLightAmbient [1,1,1]; +_light setLightColor [1,1,1]; +_light setLightDayLight true; +_light setLightAttenuation [0, 1, 5, 1000, 0, 20]; + +// Reduce the light after 0.1 seconds +[{ + _this setLightBrightness 5; + + // Delete the light after 0.2 more seconds + [{deleteVehicle _this}, _this, 0.2] call CBA_fnc_waitAndExecute; +}, _light, 0.1] call CBA_fnc_waitAndExecute; + +// Ignore dead and placeable logic (zeus / spectator) +if (!alive ACE_player || {(getNumber (configOf ACE_player >> "isPlayableLogic")) == 1}) exitWith {}; // Affect local player, independently of distance -if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { - if ((getNumber (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 - _grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground +// Check for line of sight to the grenade +private _eyePos = eyePos ACE_player; // PositionASL +_grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground - private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; +private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; - // Check for line of sight (check 4 points in case grenade is stuck in an object or underground) - private _losCoefficient = 1; - private _losCount = { - !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] - } count [[0,0,0], [0,0,0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; - TRACE_1("Line of sight count (out of 4)",_losCount); - if (_losCount <= 1) then { - _losCoefficient = 0.1; - }; - _strength = _strength * _losCoefficient; +// Check for line of sight (check 4 points in case grenade is stuck in an object or underground) +private _losCount = { + !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] +} count [[0, 0, 0], [0, 0, 0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; +TRACE_1("Line of sight count (out of 4)",_losCount); - // Add ace_hearing ear ringing sound effect - if (isClass (configFile >> "CfgPatches" >> "ACE_Hearing") && {_strength > 0 && {EGVAR(hearing,damageCoefficent) > 0.25}}) then { - private _earringingStrength = 40 * _strength; - [_earringingStrength] call EFUNC(hearing,earRinging); - TRACE_1("Earringing Strength",_earringingStrength); - }; +private _losCoefficient = [1, 0.1] select (_losCount <= 1); +_strength = _strength * _losCoefficient; - // add ace_medical pain effect: - if (isClass (configFile >> "CfgPatches" >> "ACE_Medical") && {_strength > 0.1}) then { - [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); - }; - - // Effect on vision has a wider range, with a higher falloff - _strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; - _strength = _strength * _losCoefficient; - // Account for people looking away by slightly reducing the effect for visual effects. - private _eyeDir = ((AGLtoASL positionCameraToWorld [0,0,1]) vectorDiff (AGLtoASL positionCameraToWorld [0,0,0])); - private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; - private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); - TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); - // from 0-45deg, full effect - if (_angleDiff > 45) then { - _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); - }; - - // Blind player - if (_strength > 0.1) then { - GVAR(flashbangPPEffectCC) ppEffectEnable true; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1,1,(0.8 + _strength) min 1,[1,1,1,0],[0,0,0,1],[0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; - - //PARTIALRECOVERY - start decreasing effect over time - [{ - params ["_strength"]; - - GVAR(flashbangPPEffectCC) ppEffectAdjust [1,1,0,[1,1,1,0],[0,0,0,1],[0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); - }, [_strength], 7 * _strength] call CBA_fnc_waitAndExecute; - - //FULLRECOVERY - end effect - [{ - GVAR(flashbangPPEffectCC) ppEffectEnable false; - }, [], 17 * _strength] call CBA_fnc_waitAndExecute; - }; - - if (_strength > 0.2) then { - ACE_player setVectorDir (_eyePos vectorDiff _grenadePosASL); - }; +// Add ace_hearing ear ringing sound effect +if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0} && {EGVAR(hearing,damageCoefficent) > 0.25}) then { + private _earringingStrength = 40 * _strength; + [_earringingStrength] call EFUNC(hearing,earRinging); + TRACE_1("Earringing Strength",_earringingStrength); }; -true + +// Add ace_medical pain effect +if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { + [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); +}; + +// Effect on vision has a wider range, with a higher falloff +_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; +_strength = _strength * _losCoefficient; + +// Account for people looking away by slightly reducing the effect for visual effects. +private _eyeDir = ((AGLtoASL positionCameraToWorld [0, 0, 1]) vectorDiff (AGLtoASL positionCameraToWorld [0, 0, 0])); +private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; +private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); +TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); + +// From 0-45deg, full effect +if (_angleDiff > 45) then { + _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); +}; + +// Blind player +if (_strength > 0.1) then { + private _blend = [[1, 1, 1, 0], [0.3, 0.3, 0.3, 1]] select EGVAR(common,epilepsyFriendlyMode); + + GVAR(flashbangPPEffectCC) ppEffectEnable true; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; + + // PARTIALRECOVERY - start decreasing effect over time + [{ + params ["_strength", "_blend"]; + + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); + }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; + + // FULLRECOVERY - end effect + [{ + GVAR(flashbangPPEffectCC) ppEffectEnable false; + }, [], 17 * _strength] call CBA_fnc_waitAndExecute; +}; + +// Make player flinch +if (_strength <= 0.2) exitWith {}; + +private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; +private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true]; +private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1]; +ACE_player setDir (getDir ACE_player + _flinch); + +[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; diff --git a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf index 46ff41171d..89020842d2 100644 --- a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf +++ b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Waits for the flashbang grenade fuze to trigger and 'explode' * * Arguments: - * 0: projectile - Flashbang Grenade + * 0: Flashbang grenade * * Return Value: * None @@ -18,8 +18,17 @@ params ["_projectile"]; TRACE_1("params",_projectile); -if (alive _projectile) then { - playSound3D ["A3\Sounds_F\weapons\Explosion\explosion_mine_1.wss", _projectile, false, getPosASL _projectile, 5, 1.2, 400]; +if (!alive _projectile) exitWith {}; - ["ace_flashbangExploded", [getPosASL _projectile]] call CBA_fnc_globalEvent; -}; +private _posASL = getPosASL _projectile; +private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound)); + +(if (_sounds isEqualTo []) then { + [format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400] +} else { + selectRandom _sounds +}) params ["_file", "_volume", "_pitch", "_distance"]; + +playSound3D [_file, _projectile, false, _posASL, _volume, _pitch, _distance]; + +["ace_flashbangExploded", [_posASL]] call CBA_fnc_globalEvent; diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index b07ed48fb3..f0caf82ed8 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -1,11 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Makes incendiary burn. + * Makes an incendiary grenade burn. * * Arguments: - * 0: The grenade + * 0: Incendiary grenade * 1: Incendiary lifetime + * 2: Instigator's side * * Return Value: * None @@ -30,11 +31,11 @@ #define PARTICLE_SMOKE_LIFTING 1 #define PARTICLE_SMOKE_WIND_EFFECT 1 -#define EFFECT_SIZE 1 #define ORIENTATION 5.4 #define EXPANSION 1 #define DESTRUCTION_RADIUS 1.8 +#define SEARCH_RADIUS 5 params ["_projectile", "_timeToLive", "_center"]; @@ -42,16 +43,16 @@ if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; private _position = position _projectile; -// --- AI +// Alert nearby hostile AI private _nearLocalEnemies = []; { { - if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE! + if (local _x && {[_center, side group _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECT'S SIDE HERE! _nearLocalEnemies pushBackUnique _x; }; } forEach crew _x; -} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); +} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); //@todo replace with nearEntities in 2.18 { if (behaviour _x in ["SAFE", "AWARE"]) then { @@ -59,7 +60,7 @@ private _nearLocalEnemies = []; }; } forEach _nearLocalEnemies; -// --- fire +// Fire particles private _fire = "#particlesource" createVehicleLocal _position; _fire setParticleParams [ @@ -99,7 +100,7 @@ _fire setParticleRandom [PARTICLE_LIFE_TIME / 4, [0.15 * EFFECT_SIZE, 0.15 * EFF _fire setParticleFire [1.2,1.0,0.1]; _fire setDropInterval (1 / PARTICLE_DENSITY); -// --- smoke +// Smoke particles private _smoke = "#particlesource" createVehicleLocal _position; _smoke setParticleParams [ @@ -137,7 +138,7 @@ _smoke setParticleParams [ _smoke setParticleRandom [PARTICLE_SMOKE_LIFE_TIME / 2, [0.5 * EFFECT_SIZE, 0.5 * EFFECT_SIZE, 0.2 * EFFECT_SIZE], [0.3,0.3,0.5], 1, 0, [0,0,0,0.06], 0, 0]; _smoke setDropInterval (1 / PARTICLE_SMOKE_DENSITY); -// --- light +// Light private _light = "#lightpoint" createVehicleLocal (_position vectorAdd [0,0,0.5]); _light setLightBrightness 1.0; @@ -150,86 +151,72 @@ _light setLightDayLight false; _light lightAttachObject [_projectile, [0,0,0]]; -// --- sound +// Sound private _sound = objNull; if (isServer) then { _sound = createSoundSource ["Sound_Fire", _position, [], 0]; + private _radius = 1.5 * getNumber (configOf _projectile >> "indirectHitRange"); + private _intensity = getNumber (configOf _projectile >> "hit"); + + [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, { + params ["_endTime", "_projectile"]; + + // If incendiary no longer exists, exit + if (isNull _projectile) exitWith { + false // return + }; + + // Need to get the position every time, as grenade might have been moved + private _position = position _projectile; + + { + // Damage vehicles + [QGVAR(damageEngineAndWheels), [_x, _position], _x] call CBA_fnc_targetEvent; + } forEach (_position nearEntities ["Car", SEARCH_RADIUS]); + + CBA_missionTime < _endTime // return + }, [CBA_missionTime + _timeToLive, _projectile]]] call CBA_fnc_serverEvent; }; [{ {deleteVehicle _x} forEach _this; }, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; -// --- damage +// Damage { - if (local _x) then { - //systemChat format ["burn: %1", _x]; + // Inflame fireplace, barrels etc. + _x inflame true; - // --- destroy nearby static weapons and ammo boxes - if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + // Destroy nearby static weapons and ammo boxes + if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + _x setDamage 1; + + continue; + }; + + if (_x isKindOf "ReammoBox_F") then { + if ( + (["ace_cookoff"] call EFUNC(common,isModLoaded)) && + {EGVAR(cookoff,enableAmmobox)} && + {EGVAR(cookoff,ammoCookoffDuration) != 0} && + {_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]} + ) then { + [QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent; + } else { _x setDamage 1; }; - if (_x isKindOf "ReammoBox_F") then { - if ( - "ace_cookoff" call EFUNC(common,isModLoaded) && - {GETVAR(_x,EGVAR(cookoff,enableAmmoCookoff),EGVAR(cookoff,enableAmmobox))} - ) then { - _x call EFUNC(cookoff,cookOffBox); - } else { - _x setDamage 1; - }; - }; - // --- delete nearby ground weapon holders - if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { - deleteVehicle _x; - }; - - // --- inflame fireplace, barrels etc. - _x inflame true; + continue; }; -} forEach (_position nearObjects DESTRUCTION_RADIUS); -// --- damage local vehicle -private _vehicle = _position nearestObject "Car"; - -if (!local _vehicle) exitWith {}; - -private _config = _vehicle call CBA_fnc_getObjectConfig; - -// --- burn tyres -private _fnc_isWheelHitPoint = { - params ["_selectionName"]; - - // wheels must use a selection named "wheel_X_Y_steering" for PhysX to work - _selectionName select [0, 6] == "wheel_" && { - _selectionName select [count _selectionName - 9] == "_steering" - } // return -}; + // Delete nearby ground weapon holders + if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { + deleteVehicle _x; + }; +} forEach ((_position nearObjects DESTRUCTION_RADIUS) select {local _x && {isDamageAllowed _x}}); { - private _wheelSelection = getText (_config >> "HitPoints" >> _x >> "name"); - - if (_wheelSelection call _fnc_isWheelHitPoint) then { - private _wheelPosition = _vehicle modelToWorld (_vehicle selectionPosition _wheelSelection); - - if (_position distance _wheelPosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_wheelSelection, 1]; - }; - }; -} forEach (getAllHitPointsDamage _vehicle param [0, []]); - -// --- burn car engine -if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; - -private _engineSelection = getText (_config >> "HitPoints" >> "HitEngine" >> "name"); -private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); - -if (_position distance _enginePosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_engineSelection, 1]; - - if ("ace_cookoff" call EFUNC(common,isModLoaded) && {EGVAR(cookoff,enable)}) then { - _vehicle call EFUNC(cookoff,engineFire); - }; -}; + // Damage vehicles (locality is checked in FUNC(damageEngineAndWheels)) + [_x, _position] call FUNC(damageEngineAndWheels); +} forEach (_position nearEntities ["Car", SEARCH_RADIUS]); diff --git a/addons/grenades/functions/fnc_nextMode.sqf b/addons/grenades/functions/fnc_nextMode.sqf index 839fbd5786..f33fa7a5a5 100644 --- a/addons/grenades/functions/fnc_nextMode.sqf +++ b/addons/grenades/functions/fnc_nextMode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Select the next throwing mode and display message. @@ -7,37 +7,72 @@ * None * * Return Value: - * Handeled + * Handled * * Example: - * [] call ace_grenades_fnc_nextMode + * call ace_grenades_fnc_nextMode * * Public: No */ -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +// _mode is 0-4, don't overflow +private _mode = (GVAR(currentThrowMode) + 1) % 5; -if (_mode == 4) then { - _mode = 0; -} else { +private _currentThrowable = currentThrowable ACE_player; + +// Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) +if ( + _mode == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } +) then { _mode = _mode + 1; }; -// ROLL GRENADE DOESN'T WORK RIGHT NOW -if (_mode == 3) then { - _mode = 4; -}; - private _hint = localize ([ LSTRING(NormalThrow), LSTRING(HighThrow), LSTRING(PreciseThrow), LSTRING(RollGrenade), - LSTRING(DropGrenade) + LSTRING(DropGrenade) ] select _mode); [_hint] call EFUNC(common,displayTextStructured); +GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; GVAR(currentThrowMode) = _mode; +// If in rolling mode, check every frame if current throwable is rollable +if (GVAR(currentThrowMode) == 3) then { + GVAR(currentThrowable) = _currentThrowable; + + GVAR(throwModePFEH) = { + private _currentThrowable = currentThrowable ACE_player; + + if (GVAR(currentThrowable) isEqualTo _currentThrowable) exitWith {}; + + GVAR(currentThrowable) = _currentThrowable; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; + GVAR(currentThrowMode) = 0; + } call CBA_fnc_addPerFrameHandler; +}; + true diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 1c8066dec2..a440c8fd1b 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Adjust the grenades throwing direction and speed to the selected throwing mode. Called from the unified fired EH only for CAManBase @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); if (_weapon != "Throw") exitWith {}; @@ -27,40 +27,26 @@ if (isNull _projectile) then { private _config = configFile >> "CfgAmmo" >> _ammo; -// handle special grenades and sounds +// Handle special grenades and sounds if (local _unit) then { - // handle priming sound, if present - private _soundConfig = getArray (configFile >> "CfgAmmo" >> _ammo >> QGVAR(pullPinSound)); - if !(_soundConfig isEqualTo []) then { + // Handle priming sound, if present + private _soundConfig = getArray (_config >> QGVAR(pullPinSound)); + + if (_soundConfig isNotEqualTo []) then { _soundConfig params ["_file", "_volume", "_pitch", "_distance"]; - playSound3D [_file, objNull, false, getPosASL _projectile, _volume, _pitch, _distance]; + playSound3D [_file, objNull, insideBuilding _unit >= 0.5, getPosASL _projectile, _volume, _pitch, _distance]; }; if (getNumber (_config >> QGVAR(flashbang)) == 1) then { - private _bangs = 1; - private _entry = _config >> QGVAR(flashbangBangs); - if (isNumber _entry || isText _entry) then { - _bangs = getNumber _entry; - }; - private _fuzeTimeBase = getNumber (_config >> "explosionTime"); - - private _interval = 0.5; - _entry = _config >> QGVAR(flashbangInterval); - if (isNumber _entry || isText _entry) then { - _interval = getNumber _entry; - }; - - private _maxDeviation = 0.1; - _entry = _config >> QGVAR(flashbangIntervalMaxDeviation); - if (isNumber _entry || isText _entry) then { - _maxDeviation = getNumber _entry; - }; + private _bangs = [_config >> QGVAR(flashbangBangs), "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _interval = [_config >> QGVAR(flashbangInterval), "NUMBER", 0.5] call CBA_fnc_getConfigEntry; + private _maxDeviation = [_config >> QGVAR(flashbangIntervalMaxDeviation), "NUMBER", 0.1] call CBA_fnc_getConfigEntry; for "_i" from 0 to (_bangs - 1) do { - private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation]; + private _fuzeTime = _fuzeTimeBase + _i * _interval + random [-_maxDeviation, 0, _maxDeviation]; - [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flashbangThrownFuze), _projectile, _fuzeTime] call CBA_fnc_waitAndExecute; }; }; }; @@ -71,47 +57,56 @@ if (getNumber (_config >> QGVAR(flare)) == 1) then { private _color = getArray (_config >> QGVAR(color)); private _intensity = _color deleteAt 3; - [FUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; }; if (getNumber (_config >> QGVAR(incendiary)) == 1) then { private _fuzeTime = getNumber (_config >> "explosionTime"); private _timeToLive = getNumber (_config >> "timeToLive"); - [FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE! + [LINKFUNC(incendiary), [_projectile, _timeToLive, side group _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // Get the unit's real side (will return civilian if unconscious) }; -// handle throw modes +// Handle throw modes if (_unit != ACE_player) exitWith {}; if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +if (GVAR(currentThrowMode) == 0) exitWith {}; -if (_mode != 0) then { - private _velocity = velocity _projectile; +private _velocity = velocity _projectile; - switch (_mode) do { - //high throw - case 1 : { - _velocity = [ - 0.5 * (_velocity select 0), - 0.5 * (_velocity select 1), - [0, 0, 0] distance (_velocity vectorMultiply 0.5) - ]; - }; - //precise throw - case 2 : { - _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); - }; - //roll grande - case 3 : { - //@todo - }; - //drop grenade - case 4 : { - _velocity = [0, 0, 0]; - }; +switch (GVAR(currentThrowMode)) do { + // High throw + case 1: { + _velocity = _velocity vectorMultiply 0.5; + + _velocity set [2, vectorMagnitude _velocity]; }; + // Precise throw + case 2: { + _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); + }; + // Roll grenade + case 3: { + private _posASL = getPosASL _projectile; - _projectile setVelocity _velocity; + // getPos is unreliable, as surfaces in some ruins are not recognised as surfaces + private _lisPos = (lineIntersectsSurfaces [_posASL, _posASL vectorAdd [0, 0, -1e11], ACE_player, objNull, true, 1, "ROADWAY", "FIRE"]) select 0; + _projectile setPosASL ((_lisPos select 0) vectorAdd [0, 0, 0.2]); + + // Rotate throwables by 90° to the side by default, so cylindrical throwables can be rolled + private _vectorDirAndUp = getArray (_config >> QGVAR(rollVectorDirAndUp)); + _vectorDirAndUp params [["_vectorDir", [0, 1, 0], [[]], 3], ["_vectorUp", [1, 0, 0], [[]], 3]]; + + // Do as if object were facing north + _projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp); + + _velocity = (vectorDir _unit) vectorMultiply 10; + }; + // Drop grenade + case 4: { + _velocity = [0, 0, 0]; + }; }; + +_projectile setVelocity _velocity; diff --git a/addons/grenades/functions/script_component.hpp b/addons/grenades/functions/script_component.hpp deleted file mode 100644 index e6a44b8a20..0000000000 --- a/addons/grenades/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\grenades\script_component.hpp" \ No newline at end of file diff --git a/addons/grenades/initSettings.inc.sqf b/addons/grenades/initSettings.inc.sqf new file mode 100644 index 0000000000..6a6ceb8c37 --- /dev/null +++ b/addons/grenades/initSettings.inc.sqf @@ -0,0 +1,10 @@ +[ + QGVAR(convertExplosives), + "CHECKBOX", + [LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)], + LSTRING(Settings_DisplayName), + true, + 1, + {[QGVAR(convertExplosives), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/grenades/models/ACE_CTS_9bang.p3d b/addons/grenades/models/ACE_CTS_9bang.p3d new file mode 100644 index 0000000000..aedd244c37 Binary files /dev/null and b/addons/grenades/models/ACE_CTS_9bang.p3d differ diff --git a/addons/grenades/models/ACE_CTS_9bang_thrown.p3d b/addons/grenades/models/ACE_CTS_9bang_thrown.p3d new file mode 100644 index 0000000000..646a8b7161 Binary files /dev/null and b/addons/grenades/models/ACE_CTS_9bang_thrown.p3d differ diff --git a/addons/grenades/script_component.hpp b/addons/grenades/script_component.hpp index 49dbe92a3f..e49fa21ca9 100644 --- a/addons/grenades/script_component.hpp +++ b/addons/grenades/script_component.hpp @@ -16,7 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define EFFECT_STAGE_RESETAI 0 -#define EFFECT_STAGE_DELETELIGHT 1 -#define EFFECT_STAGE_PARTIALRECOVERY 2 -#define EFFECT_STAGE_FULLRECOVERY 3 +#define EFFECT_SIZE 1 + +#define MIN_EXPLOSION_TIME_FOR_ROLL 1 diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index a5423468a6..b0630e3a43 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -7,15 +7,16 @@ Cambiar modo de granada Przełącz sposób rzutu granatem Změnit styl hodu granátu - Changer type de lancer de grenade + Changer le mode de jet des grenades Сменить режим броска гранаты Gránátkezelési mód váltása Cambia tipo di granata Alternar Modo de Granada - 投てき方法を切り替え - 투척 종류 전환 + 投擲方法を切り替え + 투척 방법 전환 切换投掷模式 切換投擲模式 + Bomba fırlatma modunu değiştir Normal Throw @@ -23,7 +24,7 @@ Lanzamiento normal Normalny rzut Normální hod - Lancer normal + Lancé normal Нормальный бросок Normál dobás Lancio normale @@ -32,6 +33,7 @@ 일반 던지기 普通投掷 普通投擲 + Normal Fırlatma High Throw @@ -39,7 +41,7 @@ Lanzamiento alto Wysoki rzut Vysoký hod - Lancer haut + Lancé haut Высокий бросок Magas dobás Lancio verso l'alto @@ -48,6 +50,7 @@ 높이 던지기 高抛 高拋 + Yüksek Fırlatma Precise Throw @@ -55,7 +58,7 @@ Lanzamiento preciso Precyzyjny rzut Přesný hod - Lancer précis + Lancé précis Точный бросок Pontos dobás Lancio preciso @@ -64,6 +67,7 @@ 정확한 던지기 精准投掷 精準投擲 + Yakına Fırlatma Roll Grenade @@ -71,7 +75,7 @@ Lanzamiento raso Po ziemi Po zemi - Lancer roulé + Lancé roulé Катить гранату Gránát gurítása Fai rotolare la granata @@ -80,6 +84,7 @@ 굴려넣기 地面滚抛 地面滾拋 + Bombayı Yuvarla Drop Grenade @@ -96,6 +101,15 @@ 떨어뜨리기 下丢投掷 下丟投擲 + Bombayı Yere Bırak + + + Can't roll this grenade, switched to %1 + この手榴弾は転がせません、 %1 に切り替えます + Эта граната не может быть брошена, переключитесь на %1 + 이 수류탄은 굴릴 수 없습니다. %1(으)로 전환되었습니다. + Granate kann nicht rollen, zu %1 gewechselt + Granata non può rotolare, cambiato a %1 M84 Stun Grenade @@ -112,6 +126,7 @@ M84 섬광 수류탄 M84 震撼弹 M84 震撼彈 + M84 Sersemletici El Bombası M84 @@ -128,12 +143,13 @@ M84 M84 M84 + M84 Also known as flashbang. Causes immediate flash blindness, deafness, tinnitus, and inner ear disturbance. Verursacht temporäre Blind- und Taubheit. Tambien conocida como granada cegadora. Produce de manera inmediata ceguera, sordera, tinitus y afecta el oído interior. - Aussi connu en tant que "Flashbang". Explose en causant cécité, surdité, bourdonnements d'oreilles et perturbation de l'oreille interne. + Aussi connue sous le nom de "Flashbang". Elle provoque immédiatement cécité, surdité, acouphènes et troubles 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) - граната нелетального действия, предназначена для отвлечения и временного вывода из строя, либо дезориентации противника. Основное использование нашла при освобождении заложников, захвате преступников и террористов, а также проведении диверсионных миссий. @@ -141,9 +157,43 @@ Anche conosciuta come flashbang. Causa accecamento immediato, sensazioni di sposatezza, mancanza d'equilibrio e disturbi al timpano. Também conhecida como flashbang. Causa uma clarão imediato, cegueira, surdez, zumbido e distúrbio no tímpano. フラッシュバンとも知られています。即時に失明と難聴、耳鳴り、内耳障害を引き起こします。 - 플래시뱅이라고도 알려져있습니다. 사용즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. + 플래시뱅이라고도 알려져 있습니다. 사용 즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. 也被称为闪光弹,会造成暂时性失明,耳聋,耳鸣等效果。 也被稱為閃光彈,會造成暫時性失明,耳聾,耳鳴等效果 + Flashbang olarak da bilinir. Ani flaş körlüğü, sağırlık, kulak çınlaması ve iç kulak rahatsızlığına neden olur. + + + CTS 7290 9-bang Flash Grenade + CTS 7290 9-fach Blendgranate + CTS 7290-9 9閃 閃光彈 + CTS 7290 9闪 闪光弹 + CTS 7290 9- Flash bang Grenade + CTS 7290 9 ranný oslepující granát + CTS 7290 9-bang 閃光手榴弾 + CTS 7290 9-bang Granat Hukowy + CTS 7290 9-bang Grenade incapacitante + Granada de Luz CTS 7290 9-Explosões + CTS 7290 9- Flaş Bombası + CTS 7290-9 Светошумовая граната + Granada aturdidora CTS 7290 9-explosiones + CTS 7290 9-bang 섬광 수류탄 + + + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 + CTS 7290-9 M127A1 Hand Held Signal (White) @@ -153,13 +203,14 @@ M127A1 Bengala (Bianco) Flara ręczna sygnałowa M127A1 (biała) M127A1 Sinalizador (Branco) - M127A1 Фальшфейер (Белый) + M127A1 Фальшфейер (белый) Bengala M127A1 (Blanca) - M127A1 Feux à main (Blanc) - M127A1 信号弾 (白) - M127A1 신호탄 (하얀색) - M127A1 手持式信号弹 (白色) + M127A1 Feu à main (Blanc) + M127A1 手持ち式信号弾 (白) + M127A1 수타식 신호탄 (하얀색) + M127A1 手持式信号弹(白色) M127A1 手持式信號彈 (白色) + M127A1 El Sinyali (Beyaz) M127A1 Hand Held Signal (Red) @@ -169,13 +220,14 @@ M127A1 Bengala (Rosso) Flara ręczna sygnałowa M127A1 (czerwona) M127A1 Sinalizador (Vermelho) - M127A1 Фальшфейер (Красный) + M127A1 Фальшфейер (красный) Bengala M127A1 (Roja) - M127A1 Feux à main (Rouge) - M127A1 信号弾 (赤) - M127A1 신호탄 (빨간색) - M127A1 手持式信号弹 (红色) + M127A1 Feu à main (Rouge) + M127A1 手持ち式信号弾 (赤) + M127A1 수타식 신호탄 (빨간색) + M127A1 手持式信号弹(红色) M127A1 手持式信號彈 (紅色) + M127A1 El Sinyali (Kırmızı) M127A1 Hand Held Signal (Green) @@ -185,13 +237,14 @@ M127A1 Bengala (Verde) Flara ręczna sygnałowa M127A1 (zielona) M127A1 Sinalizador (Verde) - M127A1 Фальшфейер (Зелёный) + M127A1 Фальшфейер (зелёный) Bengala M127A1 (Verde) - M127A1 Feux à main (Vert) - M127A1 信号弾 (緑) - M127A1 신호탄 (초록색) - M127A1 手持式信号弹 (绿色) + M127A1 Feu à main (Vert) + M127A1 手持ち式信号弾 (緑) + M127A1 수타식 신호탄 (초록색) + M127A1 手持式信号弹(绿色) M127A1 手持式信號彈 (綠色) + M127A1 El Sinyali (Yeşil) M127A1 Hand Held Signal (Yellow) @@ -201,13 +254,14 @@ M127A1 Bengala (Giallo) Flara ręczna sygnałowa M127A1 (żółta) M127A1 Sinalizador (Amarelo) - M127A1 Фальшфейер (Жёлтый) + M127A1 Фальшфейер (жёлтый) Bengala M127A1 (Amarilla) - M127A1 Feux à main (Jaune) - M127A1 信号弾 (黄) - M127A1 신호탄 (노란색) - M127A1 手持式信号弹 (黄色) + M127A1 Feu à main (Jaune) + M127A1 手持ち式信号弾 (黄) + M127A1 수타식 신호탄 (노란색) + M127A1 手持式信号弹(黄色) M127A1 手持式信號彈 (黃色) + M127A1 El Sinyali (Sarı) White Hand Flare @@ -217,13 +271,14 @@ Bengala (Bianco) Flara ręczna (biała) Sinalizador de Mão (Branco) - Фальшфейер (Белый) + Фальшфейер (белый) Bengala (Blanca) - Feux à main (Blanc) - 白の手持ち式信号弾 + Feu à main (Blanc) + 白色の手持ち式信号弾 하얀색 불꽃신호기 白色手持式信号弹 白色手持式信號彈 + Beyaz el işaret fişeği Red Hand Flare @@ -233,13 +288,14 @@ Bengala (Rosso) Flara ręczna (czerwona) Sinalizador de Mão (Vermelho) - Фальшфейер (Красный) + Фальшфейер (красный) Bengala (Roja) - Feux à main (Rouge) - 赤の手持ち式信号弾 + Feu à main (Rouge) + 赤色の手持ち式信号弾 빨간색 불꽃신호기 红色手持式信号弹 紅色手持式信號彈 + Kırmızı el işaret fişeği Green Hand Flare @@ -249,13 +305,14 @@ Bengala (Verde) Flara ręczna (zielona) Sinalizador de Mão (Verde) - Фальшфейер (Зелёный) + Фальшфейер (зелёный) Bengala (Verde) - Feux à main (Vert) - 緑の手持ち式信号弾 + Feu à main (Vert) + 緑色の手持ち式信号弾 초록색 불꽃신호기 绿色手持式信号弹 綠色手持式信號彈 + Yeşil el işaret fişeği Yellow Hand Flare @@ -265,13 +322,14 @@ Bengala (Giallo) Flara ręczna (żółta) Sinalizador de Mão (Amarelo) - Фальшфейер (Жёлтый) + Фальшфейер (жёлтый) Bengala (Amarilla) - Feux à main (Jaune) - 黄の手持ち式信号弾 + Feu à main (Jaune) + 黄色の手持ち式信号弾 노란색 불꽃신호기 黄色手持式信号弹 黃色手持式信號彈 + Sarı el işaret fişeği M127A1 (White) @@ -282,12 +340,13 @@ M127A1 (Bianco) M127A1 (biała) M127A1 (Branco) - M127A1 (Белый) + M127A1 (белый) M127A1 (Blanca) M127A1 (白) M127A1 (하양) - M127A1 (白色) + M127A1(白色) M127A1 (白色) + M127A1 (Beyaz) M127A1 (Red) @@ -298,12 +357,13 @@ M127A1 (Rosso) M127A1 (czerwona) M127A1 (Vermelho) - M127A1 (Красный) + M127A1 (красный) M127A1 (Roja) M127A1 (赤) M127A1 (빨강) - M127A1 (红色) + M127A1(红色) M127A1 (紅色) + M127A1 (Kırmızı) M127A1 (Green) @@ -314,12 +374,13 @@ M127A1 (Verde) M127A1 (zielona) M127A1 (Verde) - M127A1 (Зелёный) + M127A1 (зелёный) M127A1 (Verde) M127A1 (緑) M127A1 (초록) - M127A1 (绿色) + M127A1(绿色) M127A1 (綠色) + M127A1 (Yeşil) M127A1 (Yellow) @@ -330,24 +391,29 @@ M127A1 (Giallo) M127A1 (żółta) M127A1 (Amarelo) - M127A1 (Жёлтый) + M127A1 (жёлтый) M127A1 (Amarilla) M127A1 (黄) M127A1 (노랑) - M127A1 (黄色) + M127A1(黄色) M127A1 (黃色) + M127A1 (Sarı) AN-M14 Incendiary Grenade AN-M14 Brandsatz - AN-M14 Зажигательная граната + AN-M14 зажигательная граната AN-M14 焼夷手榴弾 Granat zapalający AN-M14 AN-M14 소이 수류탄 - Grenade incendiaire AN-M14 + AN-M14 Grenade incendiaire AN-M14 Granata Incendiaria AN-M14 燃烧手榴弹 AN-M14 燃燒手榴彈 + Granada Incendiária AN-M14 + AN-M14 zápalný granát + AN-M14 Yangın Bombası + Granada incendiaria AN-M14 AN-M14 @@ -360,6 +426,10 @@ AN-M14 AN-M14 AN-M14 + AN-M14 + AN-M14 + AN-M14 + AN-M14 Incendiary grenade used to destroy weapons, ammunition and other equipment. @@ -367,53 +437,244 @@ Зажигательная граната используется для уничтожения оружия, боеприпасов и прочего оборудования. 焼夷手榴弾は武器や弾薬箱などの装備を破壊する為に使われます。 Granat zapalający, używany do niszczenia broni, amunicji i innego sprzętu. - 소이 수류탄은 무기나 탄약 그리고 장비를 파괴할때 쓰입니다. - Grenade incendiaire utilisé pour détruire des armes, munitions et autres équipements. + 소이 수류탄은 무기나 탄약 그리고 장비를 파괴할 때 쓰입니다. + Grenade incendiaire utilisée pour détruire des armes, des munitions et d'autres équipements. Granata incendiaria usata per distruggere armi, munizioni e altri equipaggiamenti. 燃烧手榴弹是用来摧毁武器,弹药以及其他装备的好帮手。 燃燒手榴彈是用來摧毀武器,彈藥以及其他裝備的好幫手 + Granada Incendiária utilizada para destruir armas, munições e outros equipamentos. + Zápalný granát používaný ke zničení zbraní, munice a další výbavy. + Yangın bombaları, cephaneleri ve diğer teçhizatı yok etmek için kullanılır + Granada incendiaria utilizada para destruir armamento, municiones y otros equipamientos Type: Star Parachute Flare + Typ: Fallschirmfackel Typ: Gwiezdna Flara Spadochronowa Tipo: Granata a paracadute con bengala 種類: パラシュート式照明弾 (星弾) Тип: Осветительная ракета - звезда на парашюте + Tipo: Sinalizador de pára-quedas estrela + 類型:星式帶傘照明彈 + 类型:星式带伞照明弹 + Type : Fusée éclairante à parachute + Typ: Světlice s padákem + Tür: Yıldız Paraşüt Fişeği + Tipo: Bengala de paracaidas + 종류: 낙하식 조명탄 M583 Illumination Flare (White) + M583 Leuchtfackel (Weiß) M583 Flara oświetlająca (Biała) M583 Granata con bengala (Bianca) M583 照明弾 (白) - M583 Осветит. ракета (Белая) + M583 Осветит. ракета (белая) + M583 Sinalizador de Iluminação (Branco) + M583 照明彈(白色) + M583 照明弹(白色) + M583 Fusée éclairante (Blanche) + M583 Světlice (Bílá) + M583 Aydınlatma Fişeği (Beyaz) + M583 Bengala de iluminación (Blanca) + M583 조명탄 (하양) M662 Illumination Flare (Red) + M662 Leuchtfackel (Rot) M662 Flara oświetlająca (Czerwona) M662 Granata con bengala (Rossa) M662 照明弾 (赤) - M662 Осветит. ракета (Красная) + M662 Осветит. ракета (красная) + M662 Sinalizador de Iluminação (Vermelho) + M662 照明彈(紅色) + M662 照明弹(红色) + M662 Fusée éclairante (Rouge) + M662 Světlice (Červená) + M662 Aydınlatma Fişeği (Kırmızı) + M662 Bengala de iluminación (Roja) + M662 조명탄 (빨강) M661 Illumination Flare (Green) + M661 Leuchtfackel (Grün) M661 Flara oświetlająca (Zielona) M661 Granata con bengala (Verde) M661 照明弾 (緑) - M661 Осветит. ракета (Зеленая) + M661 Осветит. ракета (зелёная) + M661 Sinalizador de Iluminação (Verde) + M661 照明彈(綠色) + M661 照明弹(绿色) + M661 Fusée éclairante (Verte) + M661 Světlice (Zelená) + M661 Aydınlatma Fişeği (Yeşil) + M661 Bengala de iluminación (Verde) + M661 조명탄 (초록) Type: Parachute IR Flare + Typ: Infrarote Fallschirmfackel Typ: Spadochronowa Flara IR Tipo: Granata a paracadute con infrarosso 種類: パラシュート式赤外線照明弾 Тип: ИК-осветительная ракета на парашюте + Tipo: Sinalizador Infravermelho de Pára-quedas + 類型:帶傘型紅外線照明彈 + 类型:带伞型红外照明弹 + Type : Fusée IR à parachute + Typ: Infračervená světlice s padákem + Tip : Paraşüt IR Flare + Tipo: Bengala infrarroja de paracaidas + 종류: 낙하식 적외선 조명탄 - M992 Illumination IR Flare - M992 Oświetlająca flara IR - M992 Granata con infrarosso - M992 赤外線照明弾 - M992 ИК-осветительная ракета + M992 Illumination Flare (IR) + M992 Leuchtfackel (IR) + M992 Flara oświetlająca (IR) + M992 Granata con bengala (Infrarosso) + M992 照明弾 (赤外線) + M992 Осветит. ракета (ИК) + M992 Sinalizador de Iluminação (Infravermelho) + M992 紅外線照明彈 + M992 红外照明弹 + M992 Fusée éclairante (IR) + M992 Světlice (Infračervená) + M992 Aydınlatma Fişeği (IR) + M992 Bengala de iluminación (Infrarroja) + M992 조명탄 (적외선) + + + Explosive Satchel (Throwable) + Ранец со взрывчаткой (метательный) + Charge en sacoche (lançable) + 梱包爆薬 (投擲仕様) + Carga de mochila explosiva (Lanzable) + Pakiet ładunków wybuchowych (Rzucany) + Rucksackladung (Werfbar) + Carica da Demolizioni (Lanciabile) + 炸药包(可投掷) + 폭파 장약 (투척) + Sacola Explosiva (Arremessável) + + + Type: Charge<br />Rounds: 1<br />Used on: Things that need to die + Тип: Взрывчатка<br />Боеприпасы 1<br />Применение: На предметах, которые должны быть уничтожены + Type : Charge<br />Munitions : 1<br />Application : à balancer sur des trucs qui doivent mourir + Type: Carica<br />Colpi: 1<br />Usata su: cose che devono morire + 種類: 爆薬<br />弾数: 1<br />次で使用: 破壊すべき物に + Tipo: Carga<br />Unidades: 1<br />Usada: Cosas que necesitan morir + Typ: Ładunek<br/>Naboje: 1<br/>Użycie: Na rzeczach które mają zginąć + Typ: Ladung <br/>Patronen:1<br/>Benutzt für: Dinge die Sterben müssen + 类型:炸药<br />数量:1<br />用于:需要死亡的事物 + 종류: 장약<br />갯수: 1<br />사용처: 죽여야 할 곳에 + Tipo: Carga<br />Munições: 1<br />Utilizada em: Coisas que devem morrer + + + An explosive satchel that is throwable. 7 second fixed fuse + Ранец со взрывчаткой. Детонация через 7 секунд + Charge explosive lançable. Détonation après 7 secondes. + Una carica da demolizioni lanciabile. Detona dopo 7 secondi fissi + 投げられる梱包爆薬。起爆まで7秒の固定時限信管付き。 + Carga de mochila explosiva que se puede lanzar. Espoleta fija de 7 segundos + Rzucany pakiet ładunków wybuchowych. 7 sekundowy zapalnik + Werfbare Rucksackladung. 7 Sekunden Zeitzünder + 一个可投掷的炸药包。7秒定时引信 + 던질 수 있는 폭파 장약입니다. 던지고 7초 후에 터집니다 + Uma sacola explosiva que pode ser arremessada. Pavio de 7 segundos + + + Explosive Charge (Throwable) + Заряд со взрывчаткой (метательный) + Charge explosive (lançable) + Carica Esplosiva (Lanciabile) + 爆薬ブロック (投擲仕様) + Carga explosiva (Lanzable) + Ładunek wybuchowy (Rzucany) + Sprengladung (Werfbar) + 炸药块(可投掷) + 폭파 블럭 (투척) + Carga Explosiva (Arremessável) + + + An explosive charge that is throwable. 7 second fixed fuse + Заряд со взрывчаткой. Детонация через 7 секунд + Bloc explosif lançable. Détonation après 7 secondes. + Una carica esplosiva lanciabile. Detona dopo 7 secondi fissi + 投げられる爆薬ブロック。起爆まで7秒の固定時限信管付き。 + Carga explosiva que se puede lanzar. Espoleta fija de 7 segundos + Rzucany ładunkek wybuchowy. 7 sekundowy zapalnik + Werfbare Sprengladung. 7 Sekunden Zeitzünder + 一个可投掷的炸药块。7秒定时引信 + 던질 수 있는 폭파 블럭입니다. 던지고 7초 후에 터집니다 + Uma carga explosiva que pode ser arremessada. Pavio de 7 segundos + + + Convert to short fuse + Применить фитиль + Appliquer une mèche + Converti a spoletta corta + 短信管へ変更 + Convertir a espoleta corta + Konwertuj na krótki zapalnik + Zündschnur verkürzen + 切换为短引信 + 단축 신관으로 바꾸기 + Converter para pavio curto + + + Remove short fuse + Убрать фитиль + Retirer la mèche + Rimuovi spoletta corta + 短信管を削除 + Quitar espoleta corta + Usuń krótki zapalnik + Kurze Zündschnur entfernen + 去除短引信 + 단축 신관 제거하기 + Remover pavio curto + + + ACE Grenades + ACE Granaten + ACE Granáty + ACE Granaty + ACE Granate + ACE Granadas + ACE Grenades + ACE Granadas + ACE Гранаты + ACE 手榴弾 + ACE 수류탄 + ACE 手榴弹 + ACE 手榴彈 + ACE Bombalar + + + Allow Explosive Conversion + Разрешить фитили + Autoriser les mèches (charges lançables) + Abilita conversione a lanciabili + 爆発物の変換を許可 + Permitir conversión de explosivos + Pozwól na konwersję ładunków wybuchowych + Erlaube die Umwandlung von Sprengstoffen + 允许转换炸药 + 폭발물 변환 가능여부 + Permitir Conversão de Explosivos + + + Allow converting explosives to throwables + Разрешает преобразовывать взрывчатку в метательные снаряды + Cette option permet de rendre les charges explosives lançables, à la manière des grenades.\nPour celà, ouvrir l'inventaire et double-cliquer sur les charges, afin de leur appliquer une mèche.\nLa mèche peut se retirer en suivant la même procédure. + Permette la conversione di certi esplosivi piazzabili a esplosivi lanciabili. + このオプションを使用すると、爆発物が手榴弾のように投擲可能になります。\nこれを行うには、インベントリを開いて爆発物をダブルクリックして、爆発物を短信管に変更します。\n信管は同じ手順で取り外すことができます。 + Permitir convertir explosivos a lanzables + Zezwala na konwersje ładunków wybuchowych na rzucane wersje + Erlaube die Umwandlung von Sprengstoffen in werfbare Ladungen + 允许将炸药转换为可投掷物 + 폭발물을 투척무기로 변환할 수 있도록 허용합니다. + Permitir conversão de explosivos em arremessáveis diff --git a/addons/grenades/textures/ace_cts_9bang_co.paa b/addons/grenades/textures/ace_cts_9bang_co.paa new file mode 100644 index 0000000000..14c17ca463 Binary files /dev/null and b/addons/grenades/textures/ace_cts_9bang_co.paa differ diff --git a/addons/gunbag/ACE_Arsenal_Actions.hpp b/addons/gunbag/ACE_Arsenal_Actions.hpp new file mode 100644 index 0000000000..6064384ad1 --- /dev/null +++ b/addons/gunbag/ACE_Arsenal_Actions.hpp @@ -0,0 +1,26 @@ +class EGVAR(arsenal,actions) { + class ADDON { + displayName = CSTRING(DisplayName); + condition = QUOTE(_this call FUNC(hasGunbag)); + scopeEditor = 0; // variables are reset between 3DEN and mission start + tabs[] = {0,5}; + class GVAR(status) { + textStatement = QUOTE([_this select 0] call FUNC(weaponName)); + }; + class GVAR(store) { + label = CSTRING(ToGunbag); + condition = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(canInteract) == 0); + statement = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(toGunbagCallback)); + }; + class GVAR(retrieve) { + label = CSTRING(OffGunbag); + condition = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(canInteract) == 1); + statement = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(offGunbagCallback)); + }; + class GVAR(swap) { + label = CSTRING(SwapGunbag); + condition = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(canInteract) == 2); + statement = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(swapGunbagCallback)); + }; + }; +}; diff --git a/addons/gunbag/CfgEventHandlers.hpp b/addons/gunbag/CfgEventHandlers.hpp index be284a9d70..b5ee7b4774 100644 --- a/addons/gunbag/CfgEventHandlers.hpp +++ b/addons/gunbag/CfgEventHandlers.hpp @@ -1,12 +1,28 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +//EH must be loaded this way to get ace_gunbag_gunbagWeapon before it is deleted upon opening the BI arsenal. May cause instability with other mods. +class RscPicture; +class RscDisplayArsenal { + class Controls { + class IconBackgroundPrimaryWeapon: RscPicture { + onLoad = QUOTE([ACE_player] call FUNC(BIArsenalOpen)); + }; + }; +}; + +class Extended_DisplayUnload_EventHandlers { + class RscDisplayArsenal { + ADDON = QUOTE([ACE_player] call FUNC(BIArsenalClose)); }; }; diff --git a/addons/gunbag/CfgVehicles.hpp b/addons/gunbag/CfgVehicles.hpp index 0addf22710..a5cae40f77 100644 --- a/addons/gunbag/CfgVehicles.hpp +++ b/addons/gunbag/CfgVehicles.hpp @@ -10,6 +10,13 @@ class CfgVehicles { showDisabled = 0; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; + class GVAR(weaponSwap) { + displayName = CSTRING(SwapGunbag); + condition = QUOTE((GVAR(swapGunbagEnabled)) && ([_target] call FUNC(hasGunbag)) && {[ARR_2(_player,_target)] call FUNC(canInteract) == 2}); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(swapGunbag)); + showDisabled = 0; + icon = QPATHTOF(ui\gunbag_icon_ca.paa); + }; class GVAR(weaponOff) { displayName = CSTRING(OffGunbag); condition = QUOTE(([_target] call FUNC(hasGunbag)) && {[ARR_2(_player,_target)] call FUNC(canInteract) == 1}); @@ -41,6 +48,13 @@ class CfgVehicles { showDisabled = 0; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; + class GVAR(weaponSwap) { + displayName = CSTRING(SwapGunbag); + condition = QUOTE((GVAR(swapGunbagEnabled)) && ([ARR_2(_player,_player)] call FUNC(canInteract) == 2)); + statement = QUOTE([ARR_2(_player,_player)] call FUNC(swapGunbag)); + showDisabled = 0; + icon = QPATHTOF(ui\gunbag_icon_ca.paa); + }; class GVAR(weaponOff) { displayName = CSTRING(OffGunbag); condition = QUOTE([ARR_2(_player,_player)] call FUNC(canInteract) == 1); diff --git a/addons/gunbag/README.md b/addons/gunbag/README.md index 734c18f3c5..2dd0e03bf7 100644 --- a/addons/gunbag/README.md +++ b/addons/gunbag/README.md @@ -2,10 +2,3 @@ ace_gunbag =============== Adds a gunbag for DMRs. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/gunbag/XEH_PREP.hpp b/addons/gunbag/XEH_PREP.hpp index d76682f986..78b7be0968 100644 --- a/addons/gunbag/XEH_PREP.hpp +++ b/addons/gunbag/XEH_PREP.hpp @@ -1,6 +1,8 @@ PREP(toGunbag); PREP(toGunbagCallback); +PREP(swapGunbag); +PREP(swapGunbagCallback); PREP(offGunbag); PREP(offGunbagCallback); PREP(status); @@ -8,3 +10,6 @@ PREP(canInteract); PREP(calculateMass); PREP(hasGunbag); PREP(isMachineGun); +PREP(BIArsenalClose); +PREP(BIArsenalOpen); +PREP(weaponName); diff --git a/addons/gunbag/XEH_preInit.sqf b/addons/gunbag/XEH_preInit.sqf index 8f313ba472..3149314f87 100644 --- a/addons/gunbag/XEH_preInit.sqf +++ b/addons/gunbag/XEH_preInit.sqf @@ -6,6 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + // restore gunbag info after respawn ["CAManBase", "respawn", { [{ @@ -14,32 +16,61 @@ PREP_RECOMPILE_END; private _newBackpack = backpackContainer _unit; private _oldBackpack = backpackContainer _corpse; - if !(typeOf _newBackpack isEqualTo typeOf _oldBackpack) exitWith {}; + if (typeOf _newBackpack isNotEqualTo typeOf _oldBackpack) exitWith {}; private _state = _oldBackpack getVariable [QGVAR(gunbagWeapon), []]; - if !(_state isEqualTo []) then { + if (_state isNotEqualTo []) then { _newBackpack setVariable [QGVAR(gunbagWeapon), _state, true]; }; }, _this] call CBA_fnc_execNextFrame; }] call CBA_fnc_addClassEventHandler; -[QEGVAR(arsenal,displayOpened), { +[QEGVAR(arsenal,loadoutVerified), { + params ["_loadout", "_extendedInfo", "", "", "_missingExtendedInfo"]; + private _gunbagInfo = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []]; + if (_gunbagInfo isEqualTo []) exitWith {}; - private _center = EGVAR(arsenal,center); - - if (_center call FUNC(hasGunBag)) then { - GVAR(arsenalCache) = (backpackContainer _center) getVariable [QGVAR(gunbagWeapon), []]; + private _weapon = (_gunbagInfo select 0) call EFUNC(arsenal,baseWeapon); + if !(_weapon in EGVAR(arsenal,virtualItemsFlat)) exitWith { + _missingExtendedInfo pushBack [QGVAR(gunbagWeapon), _weapon]; + _extendedInfo deleteAt QGVAR(gunbagWeapon); + }; + private _missingItems = []; + private _attachments = _gunbagInfo select 1; + { + if (_x != "" && {!(_x call EFUNC(arsenal,baseWeapon) in EGVAR(arsenal,virtualItemsFlat))}) then { + _missingItems pushBack _x; + _attachments set [_forEachIndex, ""]; + }; + } forEach _attachments; + private _magazines = _gunbagInfo select 2; + { + private _class = _x param [0, ""]; + if (_class != "" && {!(_class in EGVAR(arsenal,virtualItemsFlat))}) then { + _missingItems pushBack _class; + _magazines set [_forEachIndex, ["", 0]]; + }; + } forEach _magazines; + if (_missingItems isNotEqualTo []) then { + _missingExtendedInfo pushBack [QGVAR(gunbagWeapon), _missingItems]; }; }] call CBA_fnc_addEventHandler; -[QEGVAR(arsenal,displayClosed), { - - if !(isNil QGVAR(arsenalCache)) then { - (backpackContainer EGVAR(arsenal,center)) setVariable [QGVAR(gunbagWeapon),GVAR(arsenalCache), true]; +["CBA_loadoutSet", { + params ["_unit", "_loadout", "_extendedInfo"]; + private _gunbagWeapon = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []]; + if (_gunbagWeapon isNotEqualTo []) then { + (backpackContainer _unit) setVariable [QGVAR(gunbagWeapon), _gunbagWeapon, true]; }; +}] call CBA_fnc_addEventHandler; - GVAR(arsenalCache) = nil; +["CBA_loadoutGet", { + params ["_unit", "_loadout", "_extendedInfo"]; + private _gunbagWeapon = (backpackContainer _unit) getVariable [QGVAR(gunbagWeapon), []]; + if (_gunbagWeapon isNotEqualTo []) then { + _extendedInfo set [QGVAR(gunbagWeapon), _gunbagWeapon]; + }; }] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/gunbag/config.cpp b/addons/gunbag/config.cpp index 6efaceb5d6..037d3d5df8 100644 --- a/addons/gunbag/config.cpp +++ b/addons/gunbag/config.cpp @@ -16,3 +16,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" +#include "ACE_Arsenal_Actions.hpp" diff --git a/addons/gunbag/functions/fnc_BIArsenalClose.sqf b/addons/gunbag/functions/fnc_BIArsenalClose.sqf new file mode 100644 index 0000000000..2d39b3a045 --- /dev/null +++ b/addons/gunbag/functions/fnc_BIArsenalClose.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: mjc4wilton + * Handle BI arsenal closing + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [] call ace_gunbag_fnc_BIArsenalClose + * + * Public: No + */ + +params ["_unit"]; + +if (!isNil QGVAR(arsenalCache)) then { + backpackContainer _unit setVariable [QGVAR(gunbagWeapon), GVAR(arsenalCache), true]; +}; + +GVAR(arsenalCache) = nil; + +nil diff --git a/addons/gunbag/functions/fnc_BIArsenalOpen.sqf b/addons/gunbag/functions/fnc_BIArsenalOpen.sqf new file mode 100644 index 0000000000..97f3beeeb2 --- /dev/null +++ b/addons/gunbag/functions/fnc_BIArsenalOpen.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: mjc4wilton + * Handle BI arsenal opening + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [] call ace_gunbag_fnc_BIArsenalOpen + * + * Public: No + */ + +params ["_unit"]; + +if ([_unit] call FUNC(hasGunBag)) then { + GVAR(arsenalCache) = backpackContainer _unit getVariable [QGVAR(gunbagWeapon), []]; +}; diff --git a/addons/gunbag/functions/fnc_calculateMass.sqf b/addons/gunbag/functions/fnc_calculateMass.sqf index 6d66d191df..6dd6a5a660 100644 --- a/addons/gunbag/functions/fnc_calculateMass.sqf +++ b/addons/gunbag/functions/fnc_calculateMass.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Calculate mass of weapon and items. diff --git a/addons/gunbag/functions/fnc_canInteract.sqf b/addons/gunbag/functions/fnc_canInteract.sqf index fbf17819f6..4a55b0f0aa 100644 --- a/addons/gunbag/functions/fnc_canInteract.sqf +++ b/addons/gunbag/functions/fnc_canInteract.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Check if client is able to interact with gunbag. @@ -8,7 +8,7 @@ * 1: Target * * Return Value: - * -1: can't interact 0: empty gunbag 1: full gunbag + * -1: can't interact 0: empty gunbag 1: full gunbag 2: full gunbag & has primary * * Example: * _canInteract = [player, target] call ace_gunbag_fnc_canInteract @@ -26,8 +26,10 @@ if ((_gunbag getVariable [QGVAR(gunbagWeapon), []]) isEqualTo [] && {_weapon != _result = 0; }; -if (!((_gunbag getVariable [QGVAR(gunbagWeapon), []]) isEqualTo []) && {_weapon == ""}) then { +if ((_gunbag getVariable [QGVAR(gunbagWeapon), []] isNotEqualTo []) && {_weapon == ""}) then { _result = 1; }; - +if ((_gunbag getVariable [QGVAR(gunbagWeapon), []] isNotEqualTo []) && {_weapon != ""}) then { + _result = 2; +}; _result diff --git a/addons/gunbag/functions/fnc_hasGunbag.sqf b/addons/gunbag/functions/fnc_hasGunbag.sqf index 7f9c7135e0..aaf4b1918a 100644 --- a/addons/gunbag/functions/fnc_hasGunbag.sqf +++ b/addons/gunbag/functions/fnc_hasGunbag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Check if unit has a gunbag. @@ -17,4 +17,4 @@ params ["_unit"]; -getNumber (configFile >> "CfgVehicles" >> (backpack _unit) >> QUOTE(ADDON)) == 1 +getNumber ((configOf (backpackContainer _unit)) >> QUOTE(ADDON)) == 1 diff --git a/addons/gunbag/functions/fnc_isMachineGun.sqf b/addons/gunbag/functions/fnc_isMachineGun.sqf index 76cf64d443..e6e4e5c96c 100644 --- a/addons/gunbag/functions/fnc_isMachineGun.sqf +++ b/addons/gunbag/functions/fnc_isMachineGun.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Reports true if a weapon is a machine gun. @@ -22,7 +22,7 @@ private _config = _weapon call CBA_fnc_getItemConfig; // definition of a machine gun by BIS_fnc_itemType private _cursor = getText (_config >> "cursor"); -if (toLower _cursor in ["", "emptycursor"]) then { +if (toLowerANSI _cursor in ["", "emptycursor"]) then { _cursor = getText (_config >> "cursorAim"); }; diff --git a/addons/gunbag/functions/fnc_offGunbag.sqf b/addons/gunbag/functions/fnc_offGunbag.sqf index 751402fa0f..8357fae9bc 100644 --- a/addons/gunbag/functions/fnc_offGunbag.sqf +++ b/addons/gunbag/functions/fnc_offGunbag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Get weapon out of gunbag. @@ -11,7 +11,7 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_toGunbag + * [player, target] call ace_gunbag_fnc_offGunbag * * Public: No */ diff --git a/addons/gunbag/functions/fnc_offGunbagCallback.sqf b/addons/gunbag/functions/fnc_offGunbagCallback.sqf index 794ea2e709..68b22fb1ef 100644 --- a/addons/gunbag/functions/fnc_offGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_offGunbagCallback.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Get weapon out of gunbag. @@ -11,7 +11,7 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_offGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_offGunbagCallback * * Public: No */ @@ -23,39 +23,28 @@ private _gunbag = backpackContainer _target; private _state = _gunbag getVariable [QGVAR(gunbagWeapon), []]; if (_state isEqualTo []) exitWith { - [localize LSTRING(empty)] call EFUNC(common,displayTextStructured); + [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; _state params ["_weapon", "_items", "_magazines"]; -_unit addWeapon _weapon; +[_unit, _weapon, true, _magazines] call EFUNC(common,addWeapon); -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +// Add attachments { - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _magazines; - -removeAllPrimaryWeaponItems _unit; - -{ - _unit addWeaponItem [_weapon, _x]; -} forEach (_items + _magazines); + _unit addWeaponItem [_weapon, _x, true]; +} forEach (_items select {_x != ""}); _unit selectWeapon _weapon; -_magazines = _magazines apply {_x select 0}; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -// remove virtual load +// Remove virtual load [_target, _gunbag, -_mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/functions/fnc_status.sqf b/addons/gunbag/functions/fnc_status.sqf index 730e992dcb..c57caac4f5 100644 --- a/addons/gunbag/functions/fnc_status.sqf +++ b/addons/gunbag/functions/fnc_status.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Check gunbag status full/empty. diff --git a/addons/gunbag/functions/fnc_swapGunbag.sqf b/addons/gunbag/functions/fnc_swapGunbag.sqf new file mode 100644 index 0000000000..a379c09e8f --- /dev/null +++ b/addons/gunbag/functions/fnc_swapGunbag.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Ir0n1E and mjc4wilton + * Swap primary weapon and weapon in gunbag. + * + * Arguments: + * 0: Unit + * 1: Target + * + * Return Value: + * None + * + * Example: + * [player, target] call ace_gunbag_fnc_swapGunbag + * + * Public: No + */ + +params ["_unit", "_target"]; + +private _gunbag = backpackContainer _target; + +_unit call EFUNC(common,goKneeling); + +// play sound +if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { + [_target, _gunbag] call EFUNC(backpacks,backpackOpened); +}; + +[(PROGRESSBAR_TIME * 1.5), _this, { + (_this select 0) call FUNC(swapGunbagCallback) +}, {}, LLSTRING(swapGunbag), +{(_this select 0) call FUNC(canInteract) == 2} +] call EFUNC(common,progressBar); diff --git a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf new file mode 100644 index 0000000000..cb4bca2ea4 --- /dev/null +++ b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf @@ -0,0 +1,59 @@ +#include "..\script_component.hpp" +/* + * Author: Ir0n1E, mjc4wilton + * Swap primary weapon and weapon in gunbag. + * + * Arguments: + * 0: Unit + * 1: Target + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_gunbag_fnc_swapGunbagCallback + * + * Public: No + */ + +params ["_unit", "_target"]; + +// Set up current weapon for storing +private _gunbag = backpackContainer _target; +private _currentItems = (getUnitLoadout _unit) select 0; + +private _currentMagazines = _currentItems select [4, 2]; +_currentItems deleteRange [4, 2]; + +private _currentWeapon = _currentItems deleteAt 0; + +private _currentMass = [_currentWeapon, _currentItems, _currentMagazines apply {_x select 0}] call FUNC(calculateMass); + +// Set up weapon in gunbag +private _newState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; + +if (_newState isEqualTo []) exitWith { + [LLSTRING(empty)] call EFUNC(common,displayTextStructured); +}; + +_newState params ["_newWeapon", "_newItems", "_newMagazines"]; + +// Swap Weapons +_unit removeWeapon _currentWeapon; + +[_unit, _newWeapon, true, _newMagazines] call EFUNC(common,addWeapon); + +// Add attachments +{ + _unit addWeaponItem [_newWeapon, _x, true]; +} forEach (_newItems select {_x != ""}); + +_unit selectWeapon _newWeapon; + +private _newMass = [_newWeapon, _newItems, _newMagazines apply {_x select 0}] call FUNC(calculateMass); + +// Update virtual load +[_target, _gunbag, _currentMass - _newMass] call EFUNC(movement,addLoadToUnitContainer); + +// Replace weapon in gunbag +_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentItems, _currentMagazines], true]; diff --git a/addons/gunbag/functions/fnc_toGunbag.sqf b/addons/gunbag/functions/fnc_toGunbag.sqf index 1f52eb6baf..76c27b7587 100644 --- a/addons/gunbag/functions/fnc_toGunbag.sqf +++ b/addons/gunbag/functions/fnc_toGunbag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Put weapon into gunbag. diff --git a/addons/gunbag/functions/fnc_toGunbagCallback.sqf b/addons/gunbag/functions/fnc_toGunbagCallback.sqf index e47c817979..9958eed32b 100644 --- a/addons/gunbag/functions/fnc_toGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_toGunbagCallback.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ir0n1E * Put weapon into gunbag. @@ -11,38 +11,32 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_toGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_toGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _weapon = primaryWeapon _unit; +// Set up current weapon for storing private _gunbag = backpackContainer _target; +private _items = (getUnitLoadout _unit) select 0; -private _state = [_unit, _weapon] call EFUNC(common,getWeaponState); +private _magazines = _items select [4, 2]; +_items deleteRange [4, 2]; -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ +private _weapon = _items deleteAt 0; -_state params ["_items", "", "_magazines", "_ammo"]; - -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -{ - _magazines set [_forEachIndex, [_x, _ammo select _forEachIndex]]; -} forEach _magazines; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); _unit removeWeapon _weapon; -// add virtual load +// Add virtual load [_target, _gunbag, _mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [_weapon, _items, _magazines], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/functions/fnc_weaponName.sqf b/addons/gunbag/functions/fnc_weaponName.sqf new file mode 100644 index 0000000000..51e0385b05 --- /dev/null +++ b/addons/gunbag/functions/fnc_weaponName.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Ir0n1E, Brett Mayson + * Get gunbag weapon name + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_gunbag_fnc_weaponName + * + * Public: No + */ + +params ["_unit"]; + +private _state = (backpackContainer _unit) getVariable [QGVAR(gunbagWeapon), []]; + +private _name = localize LSTRING(empty); +if (_state isNotEqualTo []) then { + _name = getText (configFile >> "CfgWeapons" >> _state#0 >> "displayName"); +}; +_name diff --git a/addons/gunbag/functions/script_component.hpp b/addons/gunbag/functions/script_component.hpp deleted file mode 100644 index 4e342e3b04..0000000000 --- a/addons/gunbag/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\gunbag\script_component.hpp" diff --git a/addons/gunbag/initSettings.inc.sqf b/addons/gunbag/initSettings.inc.sqf new file mode 100644 index 0000000000..b4ec000fa6 --- /dev/null +++ b/addons/gunbag/initSettings.inc.sqf @@ -0,0 +1,9 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(DisplayName_Settings)]; + +[ + QGVAR(swapGunbagEnabled), "CHECKBOX", + [LSTRING(SwapGunbagEnabled_DisplayName), LSTRING(SwapGunbagEnabled_Description)], + _category, + true, // default value + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/gunbag/stringtable.xml b/addons/gunbag/stringtable.xml index ab4fdf5ac7..6389a667c8 100644 --- a/addons/gunbag/stringtable.xml +++ b/addons/gunbag/stringtable.xml @@ -13,50 +13,120 @@ Borsa per Armi 枪袋 槍袋 + Bolsa de Arma + Silah Çantası + Funda de arma Gunbag (Tan) - Waffentasche (Tan) - Housse d'arme (marron clair) + Waffentasche (Hellbraun) + Housse d'arme (Marron clair) Чехол (желтовато-коричневый) Pouzdro na zbraň (Žlutohnědá) ガンバッグ (タン) - Torba na broń (jasnobrązowa) + Torba na broń (Jasnobrązowa) 총가방 (황갈색) - Borsa per Armi (Tan) - 枪袋 (黄褐色) + Borsa per Armi (Marroncina) + 枪袋(黄褐色) 槍袋 (黃褐色) + Bolsa de Arma (Bege) + Silah Çantası (Tan) + Funda de arma (Tan) + + + Gunbag + Waffentasche + Housse d'arme + Чехол + Pouzdro na zbraň + ガンバッグ + Torba na broń + 총가방 + Borsa per Armi + 枪袋 + 槍袋 + Bolsa de Arma + Silah Çantası + Funda de arma Put weapon into gunbag Lege Waffe in Waffentasche - Placer l'arme dans la housse d'arme + Ranger l'arme dans la housse Зачехлить оружие Vložit zbraň do pouzdra ガンバッグへ武器を入れる Włóż broń do torby 무기를 총가방에 넣기 - Metti l'arma nella borsa per armi + Metti l'arma nella borsa 将武器放置枪袋 將武器放置槍袋 + Colocar arma na Bolsa de Arma + Silahını silah çantasına koy + Poner el arma en la funda + + + Exchange weapon in gunbag + Wymień broń w torbie + Заменить оружие в чехле + Échanger les armes + ガンバッグ内の武器を交換 + Silah çantasında silah değişimi + Intercambiar arma en funda de arma + Waffe in Waffentasche tauschen + Scambia arma nella borsa + 交换枪袋中的武器 + 총가방 안에 있는 무기랑 교환하기 + Trocar arma na Bolsa de Arma + + + Enable Weapon Swap + Aktywuj wymianę broni + Вкл. обмен оружием + Activer l'échange d'arme + 武器交換を有効化 + Silah Değiştirmeyi Etkinleştir + Habilitar cambio de arma + Aktiviere Tauschen von Waffen + Abilita Scambio Arma + 启用武器互换 + 무기 교환 활성화 + Habilitar Troca de Arma + + + Allows interaction to directly swap the primary weapon and stored weapon. + Pozwala na interakcje do wymiany broni głównej na bron schowaną. + Разрешает действие прямого обмена основного оружия и спрятанного в чехле. + Active le menu d'interaction personnelle permettant d'échanger directement l'arme primaire et l'arme rangée dans la housse. + 持っている武器とガンバッグ内の武器を交換できるようにします。 + Etkileşimin doğrudan birincil silahı ve depolanan silahı değiştirmesine izin verir. + Permitir interacción para intercambiar el arma principal y el arma guardada. + Erlaube den direkten Wechsel von Primärer und verstauter Waffe über das Interaktionsmenü. + Permetti un'interazione per scambiare l'arma primaria con quella nella borsa. + 允许互动直接切换主武器和存储武器。 + 보관 중인 무기를 주무기와 바로 바꾸는 것을 허용합니다. + Permite interação para trocar a arma primária e a arma armazenada. Get weapon out of gunbag Hole Waffe aus Waffentasche - Sortir l'arme hors de la housse + Prendre l'arme de la housse Расчехлить оружие Vytáhnout zbraň z pouzdra ガンバッグから武器を出す Wyciągnij broń z torby 무기를 총가방에서 꺼내기 - Prendi l'arma dalla borsa per armi + Prendi l'arma dalla borsa 将武器拿出枪袋 將武器拿出槍袋 + Retirar arma da Bolsa de Arma + Silahını silah çantasından çıkart + Sacar el arma de la funda Status Status - Status + Statut Статус Status 中身 @@ -65,6 +135,9 @@ Stato 状态 狀態 + Status + Kontrol Et + Estado Gunbag Empty @@ -72,12 +145,15 @@ Housse d'arme vide Чехол пуст Prázdné pouzdro na zbraň - ガンバッグは空 + ガンバッグは空です Torba jest pusta 총가방 비어있음 Borsa per armi vuota 枪袋为空 槍袋為空 + Bolsa de Arma Vazia + Silah Çantası Boş + Funda de arma vacía diff --git a/addons/headless/$PBOPREFIX$ b/addons/headless/$PBOPREFIX$ new file mode 100644 index 0000000000..553c595da0 --- /dev/null +++ b/addons/headless/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\headless diff --git a/addons/headless/ACE_Settings.hpp b/addons/headless/ACE_Settings.hpp new file mode 100644 index 0000000000..ec7130c2a3 --- /dev/null +++ b/addons/headless/ACE_Settings.hpp @@ -0,0 +1,14 @@ +class ACE_Settings { + class XGVAR(enabled) { + movedToSQF = 1; + }; + class XGVAR(delay) { + movedToSQF = 1; + }; + class XGVAR(endMission) { + movedToSQF = 1; + }; + class XGVAR(log) { + movedToSQF = 1; + }; +}; diff --git a/addons/headless/CfgEden.hpp b/addons/headless/CfgEden.hpp new file mode 100644 index 0000000000..3382b3a89e --- /dev/null +++ b/addons/headless/CfgEden.hpp @@ -0,0 +1,35 @@ +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class XGVAR(blacklist) { + displayName = CSTRING(BlacklistEden); + tooltip = CSTRING(BlacklistEdenDesc); + property = QXGVAR(blacklist); + control = "Checkbox"; + condition = "objectControllable"; + expression = QUOTE(_this setVariable [ARR_3(QQXGVAR(blacklist),_value,true)]); + defaultValue = "(false)"; + }; + }; + }; + }; + }; + class Group { + class AttributeCategories { + class ace_attributes { + class Attributes { + class XGVAR(blacklist) { + displayName = CSTRING(BlacklistEden); + tooltip = CSTRING(BlacklistEdenDesc); + property = QXGVAR(blacklist); + control = "Checkbox"; + expression = QUOTE(_this setVariable [ARR_3(QQXGVAR(blacklist),_value,true)]); + defaultValue = "(false)"; + }; + }; + }; + }; + }; +}; diff --git a/addons/headless/CfgEventHandlers.hpp b/addons/headless/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/headless/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/headless/CfgVehicles.hpp b/addons/headless/CfgVehicles.hpp new file mode 100644 index 0000000000..3bd5ee63b5 --- /dev/null +++ b/addons/headless/CfgVehicles.hpp @@ -0,0 +1,57 @@ +class CfgVehicles { + class ACE_Module; + class XGVAR(module): ACE_Module { + author = ECSTRING(common,ACETeam); + category = "ACE"; + displayName = CSTRING(Module); + function = QFUNC(moduleInit); + scope = 1; + isGlobal = 1; // Global + isTriggerActivated = 0; + isDisposable = 0; + icon = QPATHTOF(UI\Icon_Module_Headless_ca.paa); + class Arguments { + class enabled { + displayName = ECSTRING(common,Enabled); + description = CSTRING(EnabledDesc); + typeName = "BOOL"; + defaultValue = 0; + }; + class delay { + displayName = CSTRING(Delay); + description = CSTRING(DelayDesc); + typeName = "NUMBER"; + defaultValue = DELAY_DEFAULT; + }; + class endMission { + displayName = CSTRING(EndMission); + description = CSTRING(EndMissionDesc); + typeName = "NUMBER"; + class values { + class disabled { + name = ECSTRING(Common,Disabled); + value = 0; + default = 1; + }; + class instant { + name = CSTRING(Instant); + value = 1; + }; + class delayed { + name = CSTRING(Delayed); + value = 2; + }; + }; + }; + class log { + displayName = CSTRING(Log); + description = CSTRING(LogDesc); + typeName = "BOOL"; + defaultValue = 0; + }; + }; + class ModuleDescription { + description = CSTRING(ModuleDesc); + }; + }; +}; diff --git a/addons/headless/README.md b/addons/headless/README.md new file mode 100644 index 0000000000..6d0cf28bd8 --- /dev/null +++ b/addons/headless/README.md @@ -0,0 +1,14 @@ +ace_headless +============ + +Adds automatic passing of AI groups to (up to 3) Headless Clients. +- Automatic Headless Client recognition +- Event-based transferring (on unit spawn, Headless Client connect and disconnect) +- Round-robin transferring when more than 1 Headless Client is present +- Mission makers can use the following to prevent a group from transferring to a Headless Client: + `this setVariable ["acex_headless_blacklist", true, true];` + +## ACEX Conversion - things still using acex prefix +- All settings +- 3DEN attribute config name +- Object SetVar (`acex_headless_blacklist`) diff --git a/addons/headless/UI/Icon_Module_Headless_ca.paa b/addons/headless/UI/Icon_Module_Headless_ca.paa new file mode 100644 index 0000000000..a3e23a8537 Binary files /dev/null and b/addons/headless/UI/Icon_Module_Headless_ca.paa differ diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp new file mode 100644 index 0000000000..e1c65cc083 --- /dev/null +++ b/addons/headless/XEH_PREP.hpp @@ -0,0 +1,8 @@ +ACEX_PREP(blacklist); +ACEX_PREP(endMissionNoPlayers); +ACEX_PREP(handleConnectHC); +ACEX_PREP(handleDisconnect); +ACEX_PREP(handleSpawn); +ACEX_PREP(moduleInit); +ACEX_PREP(rebalance); +ACEX_PREP(transferGroups); diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf new file mode 100644 index 0000000000..90677042f4 --- /dev/null +++ b/addons/headless/XEH_postInit.sqf @@ -0,0 +1,75 @@ +#include "script_component.hpp" + +if (!isMultiplayer) exitWith {}; + +["CBA_settingsInitialized", { + // Register and remove HCs if not client that is not server and distribution or end mission enabled + if ((!hasInterface || isServer) && {XGVAR(enabled) || XGVAR(endMission) != 0}) then { + if (isServer) then { + // Request rebalance on any unit spawn (only if distribution enabled) + if (XGVAR(enabled)) then { + ["CAManBase", "initPost", LINKFUNC(handleSpawn), nil, nil, true] call CBA_fnc_addClassEventHandler; + }; + // Add disconnect EH + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + + [QGVAR(transferGroupsRebalance), { + params ["_groups", "_owner", "_rebalance"]; + + if (_groups isNotEqualTo [] && {_owner > 1}) then { + { + _x setGroupOwner _owner; + } forEach _groups; + }; + + // Rebalance units + if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then { + (_rebalance == FORCED_REBALANCE) call FUNC(rebalance); + }; + }] call CBA_fnc_addEventHandler; + + // If CBA's loadout validation is enabled, warn users + if (XGVAR(transferLoadout) > 0 && {(missionNamespace getVariable ["CBA_network_loadoutValidation", 0]) isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + + ["CBA_SettingChanged", { + params ["_setting", "_value"]; + + if (_setting != "CBA_network_loadoutValidation") exitWith {}; + + if (XGVAR(transferLoadout) > 0 && {_value isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + }] call CBA_fnc_addEventHandler; + } else { + // Register HC (this part happens on HC only) + [QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes + }; + + // Transfer loadouts (naked unit work-around) + if (XGVAR(transferLoadout) > 0) then { + ["CAManBase", "Local", { + params ["_unit", "_local"]; + + // Check if naked unit bug happened + if (_local && {uniform _unit == ""}) then { + scopeName QGVAR(applyLoadout); + INFO_1("Unit [%1] became local with broken loadout - attempting to fix",_unit); + if (XGVAR(transferLoadout) == 1) then { + // Transferred loadout, if unavailable reset to config default (still better than naked) + private _loadout = _unit getVariable [QGVAR(loadout), []]; + if (_loadout isNotEqualTo []) then { + [_unit, _loadout] call CBA_fnc_setLoadout; + breakOut QGVAR(applyLoadout); + }; + }; + // Config default loadout + _unit setUnitLoadout (typeOf _unit); + }; + }] call CBA_fnc_addClassEventHandler; + }; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/headless/XEH_preInit.sqf b/addons/headless/XEH_preInit.sqf new file mode 100644 index 0000000000..c51b62cf57 --- /dev/null +++ b/addons/headless/XEH_preInit.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +if (isServer) then { + GVAR(headlessClients) = []; + GVAR(inRebalance) = false; + GVAR(endMissionCheckDelayed) = false; + [QXGVAR(headlessClientJoined), LINKFUNC(handleConnectHC)] call CBA_fnc_addEventHandler; +}; + +ADDON = true; diff --git a/addons/headless/XEH_preStart.sqf b/addons/headless/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/headless/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/headless/config.cpp b/addons/headless/config.cpp new file mode 100644 index 0000000000..1491c330b5 --- /dev/null +++ b/addons/headless/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[]= {"Jonpas"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; + + BWC_CONFIG(XADDON); +}; + +#include "ACE_Settings.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgEden.hpp" + +class ACE_newEvents { + ACE_HeadlessClientJoined = QXGVAR(headlessClientJoined); +}; diff --git a/addons/headless/functions/fnc_blacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf new file mode 100644 index 0000000000..1c15406ba6 --- /dev/null +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Modifies which units are blacklisted from being transferred to HCs. + * + * Arguments: + * 0: Units + * 1: Add (true) or remove (false) from blacklist (default: true) + * 2: Owner to transfer units to (default: -1) + * 3: Rebalance (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_headless_fnc_blacklist + * + * Public: Yes + */ + +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]]; + +if !(_units isEqualType []) then { + _units = [_units]; +}; + +// Make sure passed arguments are objects or groups +_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; +_units = _units select {!isNull _x}; + +if (_units isEqualTo []) exitWith {}; + +private _transfer = _blacklist && {_owner > 1}; +private _groups = []; + +{ + _x setVariable [QXGVAR(blacklist), _blacklist, true]; + + if (_transfer) then { + if (_x isEqualType objNull) then { + _groups pushBack group _x; + } else { + _groups pushBack _x; + }; + }; +} forEach _units; + +// Try to move AI to new owner; Also takes care of rebalancing groups +if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then { + [QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent; +}; diff --git a/addons/headless/functions/fnc_endMissionNoPlayers.sqf b/addons/headless/functions/fnc_endMissionNoPlayers.sqf new file mode 100644 index 0000000000..6954748ba9 --- /dev/null +++ b/addons/headless/functions/fnc_endMissionNoPlayers.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Ends mission on server if no players are connected. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_headless_fnc_endMissionNoPlayers + * + * Public: No + */ + +// Exit if no players of virtual curators present +if (call CBA_fnc_players isEqualTo [] && {(allCurators select {isPlayer getAssignedCuratorUnit _x}) isEqualTo []}) exitWith { + // End mission + [] call BIS_fnc_endMissionServer; + if (XGVAR(log)) then { + INFO("Ended Mission on all players leaving."); + }; +}; + +// Delay mission end otherwise +GVAR(endMissionCheckDelayed) = false; +TRACE_2("Players are present",count (call CBA_fnc_players),count allCurators); diff --git a/addons/headless/functions/fnc_handleConnectHC.sqf b/addons/headless/functions/fnc_handleConnectHC.sqf new file mode 100644 index 0000000000..e5acaf48fc --- /dev/null +++ b/addons/headless/functions/fnc_handleConnectHC.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Registers connected Headless Client for use. + * + * Arguments: + * 0: Headless Client + * + * Return Value: + * None + * + * Example: + * [headlessClient] call ace_headless_fnc_handleConnectHC + * + * Public: No + */ + +params ["_headlessClient"]; + +// Exit if HC already registered +// No need to check if distribution or end mission enabled, as if disabled this will never run +if (GVAR(headlessClients) pushBackUnique _headlessClient == -1) exitWith {}; + +if (XGVAR(log)) then { + INFO_1("Registered HC: %1",_headlessClient); +}; + +// Exit if AI distribution is disabled +if (!XGVAR(enabled)) exitWith {}; + +// Rebalance +[true] call FUNC(rebalance); diff --git a/addons/headless/functions/fnc_handleDisconnect.sqf b/addons/headless/functions/fnc_handleDisconnect.sqf new file mode 100644 index 0000000000..a18f22a3bd --- /dev/null +++ b/addons/headless/functions/fnc_handleDisconnect.sqf @@ -0,0 +1,61 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Removes Headless Client from use. + * Ends mission if setting enabled and only Headless Clients are still connected. + * + * Arguments: + * 0: Object + * + * Return Value: + * Transfer To Server + * + * Example: + * [unit] call ace_headless_fnc_handleDisconnect + * + * Public: No + */ + +params ["_object"]; +TRACE_1("HandleDisconnect",_object); + +// Exit if not HC +if !(_object in GVAR(headlessClients)) exitWith { + TRACE_2("Object not in HC list",_object,GVAR(headlessClients)); + // End mission when no players present + if (XGVAR(endMission) != 0 && {!GVAR(endMissionCheckDelayed)}) then { + // Delay check until 2.5 minutes into the mission - wait for allPlayers to sync + if (CBA_missionTime < 150) then { + TRACE_1("Mission start delay",CBA_missionTime); + GVAR(endMissionCheckDelayed) = true; + [LINKFUNC(endMissionNoPlayers), [], 150 - CBA_missionTime] call CBA_fnc_waitAndExecute; + } else { + // End instantly or after delay + if (XGVAR(endMission) == 1) then { + TRACE_2("Instant end",GVAR(endMission),CBA_missionTime); + call FUNC(endMissionNoPlayers); + } else { + TRACE_2("Delayed 60s end",GVAR(endMission),CBA_missionTime); + GVAR(endMissionCheckDelayed) = true; + [LINKFUNC(endMissionNoPlayers), [], 60] call CBA_fnc_waitAndExecute; + }; + }; + }; + false +}; + +// Exit if AI distribution is disabled +if (!XGVAR(enabled)) exitWith {true}; + +// Remove HC +GVAR(headlessClients) deleteAt (GVAR(headlessClients) find _object); + +if (XGVAR(log)) then { + INFO_1("Removed HC: %1",_object); +}; + +// Rebalance +[true] call FUNC(rebalance); + +// Prevent transferring of HC to server +false diff --git a/addons/headless/functions/fnc_handleSpawn.sqf b/addons/headless/functions/fnc_handleSpawn.sqf new file mode 100644 index 0000000000..56b74f407d --- /dev/null +++ b/addons/headless/functions/fnc_handleSpawn.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Handles AI spawn and requests a rebalance if applicable. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_headless_fnc_handleSpawn + * + * Public: No + */ + +params ["_unit"]; +TRACE_1("Spawn",_unit); + +// Exit if unit is player or UAV crew +if (isPlayer _unit || {unitIsUAV _unit}) exitWith {}; + +// Rebalance +[false] call FUNC(rebalance); diff --git a/addons/headless/functions/fnc_moduleInit.sqf b/addons/headless/functions/fnc_moduleInit.sqf new file mode 100644 index 0000000000..9c9f83e350 --- /dev/null +++ b/addons/headless/functions/fnc_moduleInit.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Initializes the Headless module. + * + * Arguments: + * 0: The module logic + * 1: Units (Unused) + * 2: Activated + * + * Return Value: + * None + * + * Public: No + */ + +params ["_logic", "", "_activated"]; + +if (!_activated) exitWith {}; + +[_logic, QXGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); +[_logic, QXGVAR(delay), "delay"] call EFUNC(common,readSettingFromModule); +[_logic, QXGVAR(endMission), "endMission"] call EFUNC(common,readSettingFromModule); +[_logic, QXGVAR(log), "log"] call EFUNC(common,readSettingFromModule); + +INFO("Headless Module Initialized."); diff --git a/addons/headless/functions/fnc_rebalance.sqf b/addons/headless/functions/fnc_rebalance.sqf new file mode 100644 index 0000000000..5ec32f39bd --- /dev/null +++ b/addons/headless/functions/fnc_rebalance.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Rebalance AI groups accross HCs. + * + * Arguments: + * 0: Force + * + * Return Value: + * None + * + * Example: + * [false] call ace_headless_fnc_rebalance + * + * Public: No + */ + +params ["_force"]; + +TRACE_3("Rebalance",GVAR(inRebalance),GVAR(headlessClients),_force); + +// Exit if waiting for rebalance or no HCs present +if (GVAR(inRebalance) || {GVAR(headlessClients) isEqualTo []}) exitWith {}; + +// Transfer after rebalance delay +[LINKFUNC(transferGroups), _force, XGVAR(delay)] call CBA_fnc_waitAndExecute; + +// Currently in rebalance flag +GVAR(inRebalance) = true; diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf new file mode 100644 index 0000000000..0efbe26365 --- /dev/null +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -0,0 +1,219 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Transfers AI groups to Headess Client(s). + * + * Arguments: + * 0: Force + * + * Return Value: + * None + * + * Example: + * [false] call ace_headless_fnc_transferGroups + * + * Public: No + */ + +params ["_force"]; + +// Filter out any invalid entries +GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + +GVAR(headlessClients) params [ + ["_HC1", objNull, [objNull]], + ["_HC2", objNull, [objNull]], + ["_HC3", objNull, [objNull]] +]; + +if (XGVAR(log)) then { + INFO_2("Present HCs: %1 - Full Rebalance: %2",GVAR(headlessClients),_force); +}; + +// Enable round-robin load balancing if more than one HC is present +private _loadBalance = [false, true] select (count GVAR(headlessClients) > 1); + +// Get IDs and determine first HC to start with +private _idHC1 = -1; +private _idHC2 = -1; +private _idHC3 = -1; +private _currentHC = 0; + +// objNull is never local +if (!local _HC1 && !isNull _HC1) then { + _idHC1 = owner _HC1; + _currentHC = 1; +}; + +if (!local _HC2 && !isNull _HC2) then { + _idHC2 = owner _HC2; + + if (_currentHC == 0) then { + _currentHC = 2; + }; +}; + +if (!local _HC3 && !isNull _HC3) then { + _idHC3 = owner _HC3; + + if (_currentHC == 0) then { + _currentHC = 3; + }; +}; + +if (_currentHC == 0) exitWith { + TRACE_1("No Valid HC to transfer to",_currentHC); + + if (XGVAR(log)) then { + INFO("No Valid HC to transfer to"); + }; +}; + +// Prepare statistics +private _numTransferredHC1 = 0; +private _numTransferredHC2 = 0; +private _numTransferredHC3 = 0; + +private _units = []; +private _transfer = false; +private _previousOwner = -1; + +// Transfer AI groups +{ + _units = units _x; + + // No transfer if empty group or if group is blacklisted + if (_units isEqualTo [] || {_x getVariable [QXGVAR(blacklist), false]}) then { + continue; + }; + + // No transfer if waypoints with synchronized triggers exist for the group + if (((waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}) isNotEqualTo []) then { + continue; + }; + + { + // No transfer if already transferred + if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { + _transfer = false; + }; + + // No transfer if any unit in group is blacklisted + if (_x getVariable [QXGVAR(blacklist), false]) exitWith { + _transfer = false; + }; + + // No transfer if player or UAV in this group + if (isPlayer _x || {unitIsUAV _x}) exitWith { + _transfer = false; + }; + + private _vehicle = objectParent _x; + + // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted + if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { + _transfer = false; + }; + + // Save gear if unit about to be transferred with current loadout (naked unit work-around) + if (XGVAR(transferLoadout) == 1) then { + _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; + }; + } forEach _units; + + if (!_transfer) then { + continue; + }; + + // Round robin between HCs if load balance enabled, else pass all to one HC + _previousOwner = groupOwner _x; + + switch (_currentHC) do { + case 1: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC2 != -1) then { + _currentHC = 2; + } else { + if (_idHC3 != -1) then { + _currentHC = 3; + }; + }; + }; + + // Don't transfer if it's already local to HC1 + if (_previousOwner == _idHC1) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC1; + + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC1 = _numTransferredHC1 + 1; + }; + }; + case 2: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC3 != -1) then { + _currentHC = 3; + } else { + if (_idHC1 != -1) then { + _currentHC = 1; + }; + }; + }; + + // Don't transfer if it's already local to HC2 + if (_previousOwner == _idHC2) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC2 = _numTransferredHC2 + 1; + }; + }; + case 3: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC1 != -1) then { + _currentHC = 1; + } else { + if (_idHC2 != -1) then { + _currentHC = 2; + }; + }; + }; + + // Don't transfer if it's already local to HC3 + if (_previousOwner == _idHC3) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC3 = _numTransferredHC3 + 1; + }; + }; + }; +} forEach allGroups; + +if (XGVAR(log)) then { + private _numTransferredTotal = _numTransferredHC1 + _numTransferredHC2 + _numTransferredHC3; + INFO_4("Groups Transferred: Total: %1 - HC1: %2 - HC2: %3 - HC3: %4",_numTransferredTotal,_numTransferredHC1,_numTransferredHC2,_numTransferredHC3); +}; + +// Allow rebalance flag +GVAR(inRebalance) = false; diff --git a/addons/headless/initSettings.inc.sqf b/addons/headless/initSettings.inc.sqf new file mode 100644 index 0000000000..ec720fce7c --- /dev/null +++ b/addons/headless/initSettings.inc.sqf @@ -0,0 +1,50 @@ +[ + QXGVAR(enabled), + "CHECKBOX", + [ELSTRING(common,Enabled), LSTRING(EnabledDesc)], + format ["ACE %1", LLSTRING(Module)], + false, + 1, + {[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(delay), + "SLIDER", + [LSTRING(Delay), LSTRING(DelayDesc)], + format ["ACE %1", LLSTRING(Module)], + [0, 60, 15, -1], + 1 +] call CBA_fnc_addSetting; + +[ + QXGVAR(endMission), + "LIST", + [LSTRING(EndMission), LSTRING(EndMissionDesc)], + format ["ACE %1", LLSTRING(Module)], + [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(Instant), LSTRING(Delayed)], 0], + 1, + {[QXGVAR(endMission), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(log), + "CHECKBOX", + [LSTRING(Log), LSTRING(LogDesc)], + format ["ACE %1", LLSTRING(Module)], + false, + 1 +] call CBA_fnc_addSetting; + +[ + QXGVAR(transferLoadout), + "LIST", + [LSTRING(TransferLoadout), LSTRING(TransferLoadoutDesc)], + format ["ACE %1", LLSTRING(Module)], + [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(TransferLoadoutCurrent), LSTRING(TransferLoadoutConfig)], 0], + 1, + {[QXGVAR(transferLoadout), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/headless/script_component.hpp b/addons/headless/script_component.hpp new file mode 100644 index 0000000000..272b288d5f --- /dev/null +++ b/addons/headless/script_component.hpp @@ -0,0 +1,23 @@ +#define COMPONENT headless +#define COMPONENT_BEAUTIFIED Headless +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_HEADLESS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_HEADLESS + #define DEBUG_SETTINGS DEBUG_SETTINGS_HEADLESS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define DELAY_DEFAULT 15 + +#define NO_REBALANCE 0 +#define REBALANCE 1 +#define FORCED_REBALANCE 2 diff --git a/addons/headless/stringtable.xml b/addons/headless/stringtable.xml new file mode 100644 index 0000000000..35dcb11862 --- /dev/null +++ b/addons/headless/stringtable.xml @@ -0,0 +1,243 @@ + + + + + Headless + Headless + Headless + 헤드리스 + ヘッドレス + Headless + Headless 客户端 + 無頭客戶端 + Headless + Headless клиент + Headless + Headless + + + This module allows you to setup automatic transferring of AI to Headless Clients. (Default: No) + Dieses Modul erlaubt es dir, die KI automatisch auf einen Headless Client zu transferieren. (Standard: Nein) + Ten moduł zezwala na automatyczny transfer AI do Headless Cient. (Domyślnie: Nie) + 이 모듈을 사용하면 헤드리스 클라이언트에 AI 자동 전송을 설정할 수 있습니다. (기본값 : No) + モジュールはAIを自動的にヘッドレスクライアントへ移行します。 (デフォルト: 無効) + Ce module permet de mettre en place un transfert aotmatique de l'IA vers le Headless Clients. (Défaut: Non) + 此模块能让你自动转换 AI 的控制权给其他 Headless 客户端。(预设:关闭) + 此模塊能讓你自動轉換AI的控制權給其他無頭客戶端。(預設:關閉) + Questo modulo ti consente di impostare il trasferimento automatico delle IA su dei Client Headless. (Predefinito: No) + Этот модуль позволяет настроить автоматическую передачу управления ИИ Headless клиентам. (По умолчанию: Откл) + Este modulo permite habilitar la transferencia de IA a los Headless Clients. (Defecto: No) + Este módulo permite configurar a transferência automática de IA para Headless Clients. (Padrão: Não) + + + Enables transferring of AI to Headless Clients. + Aktiviert den Transfer der KI auf die Headless Clients. + Włącza transfer AI do Headless Client. + AI를 헤드리스 클라이언트로 전송할 수 있습니다. + AI のヘッドレス クライアントへの転送を有効化します。 + Permet le transfert des IA au Headless Clients. + 开启转换 AI 控制权给 Headless 客户端。 + 開啟轉換AI控制權給無頭客戶端。 + Abilita il trasferimento delle IA sugli Headless Client. + Передает управление ИИ Headless клиентам. + Habilita la transferencia de IA a los Headless Clients + Ativa a transferência de IA para Headless Clients. + + + Delay + Verzögerung + Opóźnienie + 지연 + 遅延 + Délai + 延迟 + 延遲 + Latenza + Задержка + Retardo + Atraso + + + Minimal delay between transfers, in seconds. (Default: 15) + Minimale Verzögerung zwischen Transfers in Sekunden. (Standard: 15) + Minimalny odstęp pomiędzy transferami w sekundach. (Domyślnie: 15) + 전송 간 최소 지연 시간, 초당. (기본값: 15) + 移行する際の最低遅延を秒単位で設定します。 (デフォルト: 15) + Délai minimum entres les transferts, en secondes. (Défaut: 15) + 设定每次转换间隔多少秒。(预设:15秒) + 設定每次轉換間隔多少秒。(預設:15秒) + Latenza minima tra i trasferimenti, in secondi. (Predefinito: 15) + Минимальная задержка в секундах между передачами. (По умолчанию: 15) + Retardo mínimo entre transferencias en segundos. (Default: 15) + Atraso mínimo entre transferências, em segundos. (Padrão: 15) + + + End Mission + Beende Mission + 미션 종료 + ミッション終了 + Termine la Mission + 结束任务 + 結束任務 + Termina Missione + Koniec misji + Завершать миссию + Finalizar misión + Finalizar Missão + + + End mission when there are no players connected (same as 'persistent = 0' in server configuration but with Headless Client support). + Beende die Mission, wenn keine Spieler mehr verbunden sind (das gleiche wie 'persitent = 0' in den Serverkonfigurationen aber mit Headless Client Unterstützung). + 연결된 플레이어가 없을 때 임무 종료. (서버 구성에서는 'persistent = 0'과 같지만 Headless Client는 지원함) + プレイヤーが接続していない場合はミッション終了します。(サーバ設定の'presistent =0'と同じですが、ヘッドレスクライアントをサポートします) + Termine la mission lorsqu'il n'y a plus de joueur connecté (idem que 'persistent = 0' dans la config serveur mais avec la gestion du Headless Client). + 当服务器里没有任何玩家还连线时自动结束任务(效果同于伺服器设定的'persistent = 0',但支援 Headless 客户端)。 + 當伺服器裡沒有任何玩家還連線時自動結束任務(效果同於伺服器設定的'persistent = 0',但支援無頭客戶端)。 + Termina la missione quando non ci sono più giocatori connessi (come 'persistent = 0' nella configurazione dei server ma con il supporto dell'Headless Client). + Kończy misje kiedy nie ma połączonych graczy(tak samo jak 'persistent = 0' w konfiguracji serwer ale z wsparciem Headless Client + Завершает миссию, если нет присоединенных игроков (аналогично 'persistent = 0' в настройках сервера, но с включенной поддержкой Headless клиентов). + Finalizar la misión cuando no hay jugadores conectados (igual que la opción de servidor 'persistent = 0', pero con soporte para Headless Client). + Finaliza a missão quando não há jogadores conectados (o mesmo que 'persistent = 0' na configuração do servidor, mas com suporte para Headless Client). + + + Instant + Sofort + 즉시 + 即座 + Instantané + 立即 + 立即 + Istantaneo + Natychmiastowy + Мгновенно + Instantáneo + Instantâneo + + + Delayed (60s) + Verzögert (60s) + 지연 (60초) + 遅延 (60秒) + Retardé (60s) + 延迟(60秒) + 延遲 (60秒) + Ritardato (60s) + Opóźniony (60s) + С задержкой (60 с) + Retardado (60s) + Atrasado (60s) + + + Log + Protokolldatei anlegen + Dziennik zdarzeń + 로그 + ログ + Archive + 日志 + 日誌 + Registra + Журнал + Registrar + Registo + + + Log transfer statistics and Headless Client (dis)connections to RPT. (Default: No) + Zeichnet Transferstatistiken, Verbindungen und Verbindungsabbrüche in einer RPT-Datei auf. (Standard: Nein) + Zapisz statystyki transferu i status połączenia Headless Clienta do RPT. (Domyślnie: Tak) + 전송 통계 및 헤드리스 클라이언트 연결(해제)를 RPT파일에 로그함. (기본값: No) + 統計とヘッドレスクライアントの接続有無を PRT へ記録します。 (デフォルト: 無効) + Archive les statistiques de transfert et de (dé)connections du Headless Client dans le RPT. (Défaut: Non) + 记录 Headless 客户端间的转换数量与连线/断线等记录到 RPT 报告档中。(预设:关闭) + 記錄無頭客戶端間的轉換數量與連線/斷線等記錄到RPT報告檔中。(預設:關閉) + Registra le statistiche del trasferimento e delle (dis)connessioni dell'Headless Clienti su RPT. (Predefinito: No) + Вести журнал передач и подключений Headless клиентов в файл RPT. (По умолчанию: Откл) + Registrar las estadísticas de transferencia y las (des)conexiones de Headless Client hacia el RPT. (Default: No) + Regista as estatísticas de transferência e as (des)conexões do Headless Client para o RPT. (Padrão: Não) + + + Transfer Loadout + Transferiere Ausrüstung + Trasferisci Equipaggiamento + 装備の移送 + 裝備傳輸 + 装备转移 + Передавать снаряжение + Transfer Wyposażenia + 로드아웃 전송 + Transferir equipamiento + Transfert équipement + Transferir Equipamento + + + Transfer loadout of units attempts to work around an issue where units appear naked after transferring to a Headless Client. + Transferiere die Ausrüstung einer Einheit, um einen Fehler zu umgehen, bei welchem Einheiten nach dem Transfer auf einen Headless Client nackt erscheinen. + Il trasferimento di equipaggiamenti tenta di mitigare un problema dove unità appaiono nude dopo essere state trasferite al Headless Client. + 装備の移送はヘッドレスクライアントへの移行後にユニットが裸で出現する問題の回避を試みます。 + Передача снаряжения юнитов позволяет обходить проблему, при которой юниты оказываются без снаряжения после передачи управления Headless клиенту. + 裝備傳輸用於試著暫時應付單位透過無頭客戶端傳輸時所導致裸裝之問題。 + 装备转移用于试着暂时应付单位透过 Headless 客户端传输时所导致裸装之问题。 + Transfer Wyposażenia jednostek usiłuje uniknąć problemu z nagimi jednostkami po transferze do Headless Clienta + 헤드리스 클라이언트로 넘어갈 때 유닛이 벌거벗고 있는 상황을 해결하기 위해 로드아웃을 유닛에 전송합니다. + Transferir el equipamiento de unidades intenta solventar el problema por el cual las unidades aparecen desnudas despues de ser transferidas a un Headless Client. + Transférer l'équipement des unités pour contourner une erreur où les unités apparaissent nues après un transfer vers le Headless Client. + Transferir equipamento de unidades para contornar um problema onde as unidades aparecem nuas após a transferência para um Headless Client. + + + Current Loadout + Derzeitige Ausrüstung + Equipaggiamento Corrente + 現在の装備 + 目前裝備 + 当前装备 + Текущее снаряжение + Obecne wyposażenie + 현재 로드아웃 + Equipamiento actual + Equipement actuel + Equipamento Atual + + + Config Loadout + Konfiguriere Ausrüstung + Equipaggiamento Configurato + コンフィグの装備 + 設置裝備 + 设置装备 + Снаряжение из настроек + Konfiguracja Wyposażenia + 로드아웃 설정 + Configuración de equipamiento + Configuration de l'équipement + Configuração do Equipamento + + + Headless Blacklist + Headless Blacklist + ヘッドレスブラックリスト + Liste noire Headless + Headless 客户端黑名单 + 無頭客戶端黑名單 + Lista Nera Headless + 헤드리스 블랙리스트 + Czarna lista Headless + Черный список Headless + Lista negra de Headless + Lista Negra Headless + + + Disables transferring of this AI unit/group to Headless Clients. No effect on player units. + Schaltet das Übertragen dieser KI Einheit/Gruppe zu einem Headless Client aus. Hat keinen Effekt auf Spielereinheiten. + ヘッドレスクライアントへ移行させないAIユニット/グループを指定します。プレイヤーユニットへ効果はありません。 + Désactive le transfert de ce(tte) unité/groupe au Headless Clients. Sans effet sur les unités des joueurs. + 禁止转换黑名单中的 AI 单位/群组到 Headless 客户端上。此功能对玩家单位无用。 + 禁止轉換黑名單中的AI單位/群組到無頭客戶端上。此功能對玩家單位無用。 + Disabilita il trasferimento di questa unità/gruppo di IA negli Headless Client. Non ha effetto sui giocatori. + 이 AI 유닛/그룹을 헤드리스 클라이언트로 전송하지 못하도록 합니다. 플레이어 유닛에는 영향을 주지 않습니다. + Wyłącza transfer tych jednostek/grup AI do Headless Clients. Bez efektu na jednostkach gracza. + Отключает передачу управления этого юнита/группы Headless клиентам. Не влияет на юниты игроков. + Deshabilita la transferencia de esta unidad/grupo de IA hacia los Headless Clients.Sin efecto sobre unidades de jugadores. + Desativa a transferência desta unidade/grupo de IA para Headless Clients. Sem efeito nas unidades de jogadores. + + + diff --git a/addons/hearing/ACE_Arsenal_Stats.hpp b/addons/hearing/ACE_Arsenal_Stats.hpp index cc9e048823..0ab83eed60 100644 --- a/addons/hearing/ACE_Arsenal_Stats.hpp +++ b/addons/hearing/ACE_Arsenal_Stats.hpp @@ -6,16 +6,16 @@ class EGVAR(arsenal,stats) { stats[] = {QGVAR(protection)}; displayName= CSTRING(statHearingProtection); showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 1)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,1)],[ARR_2(0.01,1)],false)])] call EFUNC(arsenal,statBarStatement_default)); tabs[] = {{6}, {}}; }; class ACE_volumeMuffling: statBase { scope = 2; - priority = 1; + priority = 1.75; stats[] = {QGVAR(lowerVolume)}; displayName= CSTRING(statHearingLowerVolume); showBar = 1; - barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 1)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default)); + barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,1)],[ARR_2(0.01,1)],false)])] call EFUNC(arsenal,statBarStatement_default)); tabs[] = {{6}, {}}; }; }; diff --git a/addons/hearing/ACE_Settings.hpp b/addons/hearing/ACE_Settings.hpp index a395ddd99f..46202c46f5 100644 --- a/addons/hearing/ACE_Settings.hpp +++ b/addons/hearing/ACE_Settings.hpp @@ -1,47 +1,20 @@ class ACE_Settings { class GVAR(enableCombatDeafness) { - category = CSTRING(Module_DisplayName); - value = 1; - typeName = "BOOL"; - displayName = CSTRING(EnableCombatDeafness_DisplayName); - description = CSTRING(EnableCombatDeafness_Description); + movedToSQF = 1; }; class GVAR(earplugsVolume) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(earplugsVolume_DisplayName); - description = CSTRING(earplugsVolume_Description); - value = 0.5; - typeName = "SCALAR"; - sliderSettings[] = {0, 1, 0.5, 1}; + movedToSQF = 1; }; class GVAR(unconsciousnessVolume) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(unconsciousnessVolume_DisplayName); - description = CSTRING(unconsciousnessVolume_Description); - value = 0.4; - typeName = "SCALAR"; - sliderSettings[] = {0, 1, 0.4, 1}; + movedToSQF = 1; }; class GVAR(disableEarRinging) { - category = CSTRING(Module_DisplayName); - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(DisableEarRinging_DisplayName); - description = CSTRING(DisableEarRinging_Description); + movedToSQF = 1; }; class GVAR(enabledForZeusUnits) { - category = CSTRING(Module_DisplayName); - value = 1; - typeName = "BOOL"; - displayName = CSTRING(enabledForZeusUnits_DisplayName); - description = CSTRING(enabledForZeusUnits_Description); + movedToSQF = 1; }; class GVAR(autoAddEarplugsToUnits) { - category = CSTRING(Module_DisplayName); - value = 1; - typeName = "BOOL"; - displayName = CSTRING(autoAddEarplugsToUnits_DisplayName); - description = CSTRING(autoAddEarplugsToUnits_Description); + movedToSQF = 1; }; }; diff --git a/addons/hearing/CfgAmmo.hpp b/addons/hearing/CfgAmmo.hpp deleted file mode 100644 index ddc2bf3297..0000000000 --- a/addons/hearing/CfgAmmo.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// Setting up old stuff for A3 -class CfgAmmo { - class BulletBase; - class B_127x108_Ball: BulletBase { - audibleFire = 15; - }; -}; diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index cacaee8bce..59cd1b3629 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -1,27 +1,18 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientinit = QUOTE(call COMPILE_FILE(XEH_postInit)); - }; -}; - -class Extended_Init_EventHandlers { - class CAManBase { - class GVAR(AddEarPlugs) { - serverInit = QUOTE( _this call FUNC(addEarPlugs) ); - }; + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index 48fb79277e..636184ecd2 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,17 +5,17 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); + condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; - statement = QUOTE( [_player] call FUNC(putInEarPlugs) ); + statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs)); showDisabled = 0; icon = QPATHTOF(UI\ACE_earplugs_x_ca.paa); }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE( GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); + condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; - statement = QUOTE( [_player] call FUNC(removeEarPlugs) ); + statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs)); showDisabled = 0; icon = QPATHTOF(UI\ACE_earplugs_x_ca.paa); }; diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 5328ff8e9d..8cef02edfd 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -10,82 +10,94 @@ class CfgWeapons { picture = QPATHTOF(UI\ACE_earplugs_x_ca.paa); scope = 2; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.1; }; }; - #define HEARING_PROTECTION_VICCREW EGVAR(hearing,protection) = 0.85; EGVAR(hearing,lowerVolume) = 0.6; - #define HEARING_PROTECTION_EARMUFF EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0.5; - #define HEARING_PROTECTION_PELTOR EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0; class H_HelmetB; class H_HelmetCrew_B: H_HelmetB { - HEARING_PROTECTION_VICCREW + HEARING_PROTECTION_VICCREW; }; class H_CrewHelmetHeli_B: H_HelmetB { - HEARING_PROTECTION_VICCREW + HEARING_PROTECTION_VICCREW; }; class H_PilotHelmetHeli_B: H_HelmetB { - HEARING_PROTECTION_VICCREW + HEARING_PROTECTION_VICCREW; }; class H_PilotHelmetFighter_B: H_HelmetB { - HEARING_PROTECTION_VICCREW + HEARING_PROTECTION_VICCREW; }; class HelmetBase; class H_Cap_headphones: HelmetBase { - HEARING_PROTECTION_EARMUFF + HEARING_PROTECTION_EARMUFF; }; class H_Construction_earprot_base_F: HelmetBase { - HEARING_PROTECTION_EARMUFF + HEARING_PROTECTION_EARMUFF; }; class H_Construction_headset_base_F: HelmetBase { - HEARING_PROTECTION_EARMUFF + HEARING_PROTECTION_EARMUFF; }; class H_EarProtectors_base_F: HelmetBase { - HEARING_PROTECTION_EARMUFF + HEARING_PROTECTION_EARMUFF; }; class H_HeadSet_base_F: HelmetBase { - HEARING_PROTECTION_EARMUFF + HEARING_PROTECTION_EARMUFF; }; class H_HelmetB_light: H_HelmetB { - HEARING_PROTECTION_PELTOR + HEARING_PROTECTION_PELTOR; }; class H_HelmetB_camo: H_HelmetB { - HEARING_PROTECTION_PELTOR + HEARING_PROTECTION_PELTOR; }; class H_HelmetB_plain_mcamo; class H_HelmetSpecB: H_HelmetB_plain_mcamo { - HEARING_PROTECTION_PELTOR + HEARING_PROTECTION_PELTOR; }; class H_HelmetB_TI_tna_F: H_HelmetB { - HEARING_PROTECTION_PELTOR + HEARING_PROTECTION_PELTOR; }; class H_Tank_base_F; class H_Tank_black_F: H_Tank_base_F { - HEARING_PROTECTION_VICCREW + HEARING_PROTECTION_VICCREW; }; class H_RacingHelmet_1_F: H_HelmetB_camo { - HEARING_PROTECTION_VICCREW + HEARING_PROTECTION_VICCREW; }; class H_HelmetO_ocamo: H_HelmetB { - HEARING_PROTECTION_PELTOR - }; // Defender and Assasin Helmet inherit. + HEARING_PROTECTION_PELTOR; + }; // Defender and Assassin Helmet inherit. class H_HelmetO_ViperSP_hex_f: H_HelmetB { - HEARING_PROTECTION_PELTOR + HEARING_PROTECTION_PELTOR; + }; + + class H_HelmetAggressor_base_F: HelmetBase { + HEARING_PROTECTION_PELTOR; + }; + + class H_HelmetHBK_base_F; + class H_HelmetHBK_chops_base_F: H_HelmetHBK_base_F { + HEARING_PROTECTION_PELTOR; + }; + class H_HelmetHBK_ear_base_F: H_HelmetHBK_base_F { + HEARING_PROTECTION_PELTOR; + }; + class H_HelmetHBK_headset_base_F: H_HelmetHBK_base_F { + HEARING_PROTECTION_PELTOR; }; }; diff --git a/addons/hearing/README.md b/addons/hearing/README.md index 711a522559..7655b22e3b 100644 --- a/addons/hearing/README.md +++ b/addons/hearing/README.md @@ -2,12 +2,3 @@ ace_hearing =========== Introduces combat deafness. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/hearing/XEH_PREP.hpp b/addons/hearing/XEH_PREP.hpp index e06fa5d56c..a2bcbb708a 100644 --- a/addons/hearing/XEH_PREP.hpp +++ b/addons/hearing/XEH_PREP.hpp @@ -1,8 +1,8 @@ - PREP(addEarPlugs); PREP(earRinging); PREP(explosionNear); PREP(firedNear); +PREP(getAmmoLoudness); PREP(handleRespawn); PREP(hasEarPlugsIn); PREP(moduleHearing); diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index 17548a973b..4261933bd9 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -1,8 +1,21 @@ #include "script_component.hpp" +if (isServer) then { + ["CBA_settingsInitialized", { + TRACE_1("settingInit - server",GVAR(enableCombatDeafness)); + + // Only install event handler if combat deafness is enabled + if (!GVAR(enableCombatDeafness)) exitWith {}; + + ["CAManBase", "Init", LINKFUNC(addEarPlugs), true, [], true] call CBA_fnc_addClassEventHandler; + }] call CBA_fnc_addEventHandler; +}; + if (!hasInterface) exitWith {}; -GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace; +#include "initKeybinds.inc.sqf" + +GVAR(cacheAmmoLoudness) = createHashMap; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; @@ -13,17 +26,21 @@ GVAR(damageCoefficent) = 1; GVAR(volumeAttenuation) = 1; GVAR(lastPlayerVehicle) = objNull; -["ace_settingsInitialized", { - TRACE_1("settingInit",GVAR(EnableCombatDeafness)); +["CBA_settingsInitialized", { + TRACE_1("settingInit",GVAR(enableCombatDeafness)); + // Only run PFEH and install event handlers if combat deafness is enabled - if (!GVAR(EnableCombatDeafness)) exitWith {}; + if (!GVAR(enableCombatDeafness)) exitWith {}; // Spawn volume updating process - [LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateVolume), 1, false] call CBA_fnc_addPerFrameHandler; + + [QGVAR(updateVolume), LINKFUNC(updateVolume)] call CBA_fnc_addEventHandler; // Update veh attunation when player veh changes ["vehicle", { params ["_player", "_vehicle"]; + TRACE_2("vehicle change",_player,_vehicle); _this call FUNC(updatePlayerVehAttenuation); @@ -34,6 +51,7 @@ GVAR(lastPlayerVehicle) = objNull; GVAR(lastPlayerVehicle) = objNull; TRACE_2("removed veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; + if ((!isNull _vehicle) && {_player != _vehicle}) then { private _firedEH = _vehicle addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _vehicle setVariable [QGVAR(firedEH), _firedEH]; @@ -41,8 +59,8 @@ GVAR(lastPlayerVehicle) = objNull; TRACE_2("added veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; }, true] call CBA_fnc_addPlayerEventHandler; - ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; + ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; // Reset deafness on respawn (or remote control player switch) ["unit", { @@ -53,27 +71,33 @@ GVAR(lastPlayerVehicle) = objNull; private _firedEH = _oldPlayer getVariable [QGVAR(firedEH), -1]; _oldPlayer removeEventHandler ["FiredNear", _firedEH]; _oldPlayer setVariable [QGVAR(firedEH), nil]; + private _explosionEH = _oldPlayer getVariable [QGVAR(explosionEH), -1]; _oldPlayer removeEventHandler ["Explosion", _explosionEH]; _oldPlayer setVariable [QGVAR(explosionEH), nil]; + TRACE_3("removed unit eh",_oldPlayer,_firedEH,_explosionEH); }; // Don't add a new EH if the unit respawned if ((_player getVariable [QGVAR(firedEH), -1]) == -1) then { - if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _player) >> "isPlayableLogic")) == 1) exitWith { + if ((getNumber (configOf _player >> "isPlayableLogic")) == 1) exitWith { TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) }; + private _firedEH = _player addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _player setVariable [QGVAR(firedEH), _firedEH]; + private _explosionEH = _player addEventHandler ["Explosion", {call FUNC(explosionNear)}]; _player setVariable [QGVAR(explosionEH), _explosionEH]; + TRACE_3("added unit eh",_player,_firedEH,_explosionEH); }; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; GVAR(time3) = 0; - [] call FUNC(updateHearingProtection); + + call FUNC(updateHearingProtection); }, true] call CBA_fnc_addPlayerEventHandler; // Update protection on possible helmet change diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index b47cf6628d..e47eafa56e 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -6,4 +6,27 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +["CBA_loadoutSet", { + params ["_unit", "_loadout", "_extendedInfo"]; + + if (_extendedInfo getOrDefault ["ace_earplugs", false]) then { + _unit setVariable ["ACE_hasEarPlugsIn", true, true]; + + // Only force update volume if unit is a player (including remote controlled) + if (_unit call EFUNC(common,isPlayer)) then { + [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; + }; + }; +}] call CBA_fnc_addEventHandler; + +["CBA_loadoutGet", { + params ["_unit", "_loadout", "_extendedInfo"]; + + if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { + _extendedInfo set ["ace_earplugs", true] + }; +}] call CBA_fnc_addEventHandler; + ADDON = true; diff --git a/addons/hearing/config.cpp b/addons/hearing/config.cpp index a1cc956d89..ba6674b9db 100644 --- a/addons/hearing/config.cpp +++ b/addons/hearing/config.cpp @@ -18,6 +18,5 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgSounds.hpp" #include "CfgWeapons.hpp" -#include "CfgAmmo.hpp" #include "ACE_Settings.hpp" #include "ACE_Arsenal_Stats.hpp" diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index 2fcfdab75d..11999f7737 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher. * * Arguments: - * 0: A Soldier + * 0: Unit * * Return Value: * None @@ -15,49 +15,62 @@ * Public: No */ +// Only run this after the settings are initialized +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(addEarPlugs), _this]; +}; + +// Exit if hearing is disabled or if autoAdd is disabled +if (!GVAR(enableCombatDeafness) || {GVAR(autoAddEarplugsToUnits) == 0}) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -// only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this]; -}; +// Exit if the unit already has earplugs (in ears (persistence scenarios) or inventory) +if (_unit call FUNC(hasEarPlugsIn) || {[_unit, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {}; -// Exit if hearing is disabled OR autoAdd is disabled OR soldier has earplugs already in (persistence scenarios) -if (!GVAR(enableCombatDeafness) || {!GVAR(autoAddEarplugsToUnits)} || {[_unit] call FUNC(hasEarPlugsIn)}) exitWith {}; - -// add earplugs if the soldier has a rocket launcher -if ((secondaryWeapon _unit) != "") exitWith { +// Add earplugs if enabled for everyone or if the unit has a rocket launcher +if (GVAR(autoAddEarplugsToUnits) == 2 || {(secondaryWeapon _unit) != ""}) exitWith { TRACE_1("has launcher - adding",_unit); _unit addItem "ACE_EarPlugs"; }; -// otherwise add earplugs if the soldier has a big rifle -if ((primaryWeapon _unit) == "") exitWith {}; +// Otherwise add earplugs if the unit has a big rifle +private _weapon = primaryWeapon _unit; -(primaryWeaponMagazine _unit) params [["_magazine", ""]]; -if (_magazine == "") exitWith {}; +if (_weapon == "") exitWith {}; -private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _count = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); - -private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); -_caliber = call { - if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_caliber <= 0) then { 6.5 } else { _caliber }; +if (isNil QGVAR(cacheMaxAmmoLoudness)) then { + GVAR(cacheMaxAmmoLoudness) = createHashMap; }; -private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; -//If unit has a machine gun boost effective loudness 50% -if (_count >= 50) then {_loudness = _loudness * 1.5}; +// Cache maximum loudness for future calls +private _maxLoudness = GVAR(cacheMaxAmmoLoudness) getOrDefaultCall [_weapon, { + // Get the weapon's compatible magazines, so that all magazines are cached + // From all the loudness factors, take the max + private _maxLoudness = selectMax ((compatibleMagazines _weapon) apply {_x call FUNC(getAmmoLoudness)}); -TRACE_2("primaryWeapon",_unit,_loudness); + // ace_gunbag_fnc_isMachineGun + private _config = _weapon call CBA_fnc_getItemConfig; -if (_loudness > 0.2) then { + // Definition of a machine gun by BIS_fnc_itemType + private _cursor = getText (_config >> "cursor"); + + if (toLowerANSI _cursor in ["", "emptycursor"]) then { + _cursor = getText (_config >> "cursorAim"); + }; + + // If unit has a machine gun boost effective loudness 50% + if (_cursor == "MG") then { + _maxLoudness = _maxLoudness * 1.5; + }; + + _maxLoudness +}, true]; + +TRACE_3("primaryWeapon",_unit,_weapon,_maxLoudness); + +if (_maxLoudness > 0.2) then { TRACE_1("loud gun - adding",_unit); _unit addItem "ACE_EarPlugs"; }; diff --git a/addons/hearing/functions/fnc_earRinging.sqf b/addons/hearing/functions/fnc_earRinging.sqf index ae830e09a2..57888e90a2 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -1,24 +1,25 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg - * Handle new sound souce near ace_player and apply hearing damage + * Handle new sound souce near ace_player and apply hearing damage. * * Arguments: - * 0: strength of ear ringing + * 0: Strength of ear ringing * * Return Value: * None * * Example: - * [_strength] call ace_hearing_fnc_earRinging + * 10 call ace_hearing_fnc_earRinging * * Public: No */ + params ["_strength"]; if (_strength < 0.05) exitWith {}; if (!isNull curatorCamera) exitWith {}; -if ((!GVAR(enabledForZeusUnits)) && {player != ACE_player}) exitWith {}; +if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {}; TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV)); diff --git a/addons/hearing/functions/fnc_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf index 799002b3f7..583c55749e 100644 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ b/addons/hearing/functions/fnc_explosionNear.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, Ruthberg * Handles deafness due to explosions going off near the player. * * Arguments: - * 0: vehicle - Object the event handler is assigned to (player) - * 1: damage - Damage inflicted to the object + * 0: Unit + * 1: Damage inflicted to the unit * * Return Value: * None @@ -21,7 +21,6 @@ params ["_unit", "_damage"]; TRACE_2("explosion near player",_unit,_damage); private _strength = (0 max _damage) * 30; -if (_strength < 0.01) exitWith {}; -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_firedNear.sqf b/addons/hearing/functions/fnc_firedNear.sqf index 4dd8c759a3..1c9a1c5496 100644 --- a/addons/hearing/functions/fnc_firedNear.sqf +++ b/addons/hearing/functions/fnc_firedNear.sqf @@ -1,98 +1,63 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Handles deafness due to large-caliber weapons going off near the player. * * Arguments: - * 0: Unit - Object the event handler is assigned to - * 1: Firer: Object - Object which fires a weapon near the unit - * 2: Distance - Distance in meters between the unit and firer - * 3: weapon - Fired weapon - * 4: muzzle - Muzzle that was used (not used) - * 5: mode - Current mode of the fired weapon (not used) - * 6: ammo - Ammo used + * 0: Object the event handler is assigned to (unused) + * 1: Object which fires a weapon near the unit + * 2: Distance in meters between the unit and firer + * 3: Weapon + * 4: Muzzle + * 5: Current mode of the fired weapon + * 6: Ammo + * 7: Unit that fired the weapon * * Return Value: * None * * Example: - * [clientFiredNearEvent] call ace_hearing_fnc_firedNear - * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless"] call ace_hearing_fnc_firedNear + * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless", player] call ace_hearing_fnc_firedNear * * Public: No */ -params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"]; +params ["", "_firer", "_distance", "_weapon", "_muzzle", "_mode", "_ammo", "_gunner"]; if (_weapon in ["Throw", "Put"]) exitWith {}; if (_distance > 50) exitWith {}; -private _vehAttenuation = if ((ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player}) then {1} else {GVAR(playerVehAttenuation)}; -private _distance = 1 max _distance; - -private _silencer = switch (_weapon) do { - case (primaryWeapon _firer) : {(primaryWeaponItems _firer) select 0}; - case (secondaryWeapon _firer) : {(secondaryWeaponItems _firer) select 0}; - case (handgunWeapon _firer) : {(handgunItems _firer) select 0}; - default {""}; -}; - +_distance = 1 max _distance; private _audibleFireCoef = 1; -if (_silencer != "") then { - _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); -}; -private _loudness = GVAR(cacheAmmoLoudness) getVariable (format ["%1%2",_weapon,_ammo]); -if (isNil "_loudness") then { - private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles"); - private _weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"); - { - if (_x != "this") then { - private _muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); - _weaponMagazines append _muzzleMagazines; - }; - } count _muzzles; - { - private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo"); - _weaponMagazines set [_forEachIndex, [_x, _ammoType]]; - } forEach _weaponMagazines; +// Unit that fired is on foot +private _magazine = if (_gunner == _firer) then { + // Check if the unit has a suppressor + private _suppressor = (_firer weaponAccessories _weapon) select 0; - private _magazine = ""; - { - _x params ["_magazineType", "_ammoType"]; - if (_ammoType == _ammo) exitWith { - _magazine = _magazineType; - }; - } count _weaponMagazines; - - if (_magazine == "") then { - _loudness = 0; - TRACE_2("No mag for Weapon/Ammo??",_weapon,_ammo); - } else { - private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); - private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); - _caliber = call { - // If explicilty defined, use ACE_caliber - if ((count configProperties [(configFile >> "CfgAmmo" >> _ammo), "configName _x == 'ACE_caliber'", false]) == 1) exitWith {_caliber}; - if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_caliber <= 0) then { 6.5 } else { _caliber }; - }; - - _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; - TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness); + if (_suppressor != "") then { + _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); }; - GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness]; + + (_firer weaponState _muzzle) select 3 +} else { + // Unit that fired is in a vehicle + (weaponState [_firer, _firer unitTurret _gunner, _weapon, _muzzle, _mode]) select 3 }; +if (_magazine == "") exitWith { + TRACE_5("No mag for weapon/ammo??",_weapon,_muzzle,_ammo,_firer,_gunner); +}; + +TRACE_6("mag",_magazine,_weapon,_muzzle,_ammo,_firer,_gunner); + +private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player}); +private _loudness = _magazine call FUNC(getAmmoLoudness); + _loudness = _loudness * _audibleFireCoef; private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off TRACE_1("result",_strength); -if (_strength < 0.01) exitWith {}; - -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_getAmmoLoudness.sqf b/addons/hearing/functions/fnc_getAmmoLoudness.sqf new file mode 100644 index 0000000000..062b96fa71 --- /dev/null +++ b/addons/hearing/functions/fnc_getAmmoLoudness.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Get the loudness of ammo. + * However, because `initSpeed` is a magazine attribute, the magazine name needs to be used instead of the ammo. + * + * Arguments: + * 0: Magazine + * + * Return Value: + * None + * + * Example: + * "30Rnd_65x39_caseless_mag" call ace_hearing_fnc_getAmmoLoudness + * + * Public: No + */ + +params ["_magazine"]; + +GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, { + private _magazineConfig = configFile >> "CfgMagazines" >> _magazine; + private _ammo = getText (_magazineConfig >> "ammo"); + private _initSpeed = getNumber (_magazineConfig >> "initSpeed"); + + private _cfgAmmo = configFile >> "CfgAmmo"; + private _ammoConfig = _cfgAmmo >> _ammo; + private _caliber = getNumber (_ammoConfig >> "ACE_caliber"); + + _caliber = switch (true) do { + // If explicilty defined, use ACE_caliber + case (inheritsFrom (_ammoConfig >> "ACE_caliber") isEqualTo _ammoConfig): {_caliber}; + case (_ammo isKindOf ["ShellBase", _cfgAmmo]): {80}; + case (_ammo isKindOf ["RocketBase", _cfgAmmo]): {200}; + case (_ammo isKindOf ["MissileBase", _cfgAmmo]): {600}; + case (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]): {80}; + default {[_caliber, 6.5] select (_caliber <= 0)}; + }; + + private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; + TRACE_5("building cache",_ammo,_magazine,_initSpeed,_caliber,_loudness); + + _loudness +}, true] diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf index 74dee65b04..a075d7901e 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Reset earplugs on respawn, and then re-add if appropriate + * Reset earplugs on respawn, and then re-add if appropriate. * * Arguments: * 0: Unit @@ -10,29 +10,29 @@ * None * * Example: - * [player] call ACE_hearing_fnc_handleRespawn; + * player call ace_hearing_fnc_handleRespawn; * * Public: No */ +// Do not add or remove earplugs if gear should be preserved +if (missionNamespace getVariable [QEGVAR(respawn,savePreDeathGear), false]) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -if (!local _unit) exitWith {}; //XEH should only be called on local units - -//Do not add or remove earplugs if gear should be preserved -if (missionNamespace getVariable [QEGVAR(respawn,SavePreDeathGear), false]) exitWith {}; +if (!local _unit) exitWith {}; // XEH should only be called on local units private _respawn = [0] call BIS_fnc_missionRespawnType; -//if respawn is not Group or side: +// If respawn is not group or side: if (_respawn <= 3) then { - //Remove earplugs if they have them: + // Remove earplugs if they have them: if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { TRACE_1("had EarPlugs in - removing",_unit); _unit setVariable ["ACE_hasEarPlugsin", false, true]; }; }; -//Re-add if they need them: -[_unit] call FUNC(addEarPlugs); +// Re-add if they need them +_unit call FUNC(addEarPlugs); diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf index f24b17737e..fd6682e4de 100644 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf @@ -1,19 +1,20 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit has earplugs put in. * * Arguments: - * 0: Unit (player) + * 0: Unit * * Return Value: - * Have Earplugs in + * Has Earplugs in * * Example: - * [ace_player] call ace_hearing_fnc_hasEarPlugsIn + * player call ace_hearing_fnc_hasEarPlugsIn * * Public: No */ + params ["_unit"]; _unit getVariable ["ACE_hasEarPlugsin", false] diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index d36579c4c0..f7943a712e 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Initializes the Hearing module. @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ACE_hearing_fnc_moduleHearing + * player call ace_hearing_fnc_moduleHearing * * Public: No */ @@ -23,6 +23,8 @@ params ["_logic"]; if ((_logic getVariable "DisableEarRinging") != -1) then { [_logic, QGVAR(DisableEarRinging), "DisableEarRinging"] call EFUNC(common,readSettingFromModule); }; + [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); + INFO("Hearing Module Initialized."); diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 954dc4dee1..aa2166a112 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -1,35 +1,35 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Puts in earplugs. * * Arguments: - * 0: Unit (player) + * 0: Unit + * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player] call ace_hearing_fnc_putInEarplugs + * [player, false] call ace_hearing_fnc_putInEarplugs * * Public: No */ -params ["_player"]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; // Plugs in inventory, putting them in -_player removeItem "ACE_EarPlugs"; +_unit removeItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", true, true]; +_unit setVariable ["ACE_hasEarPlugsIn", true, true]; -[localize LSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); +if (_displayHint) then { + [LLSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); +}; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -// No Earplugs in inventory, telling user -//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured); - -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 9af41f6d8b..743e89ef53 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -1,36 +1,40 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Takes out earplugs. * * Arguments: - * 0: Unit (player) + * 0: Unit + * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player] call ace_hearing_fnc_removeEarplugs + * [player, false] call ace_hearing_fnc_removeEarplugs * * Public: No */ -params ["_player"]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; -if !(_player canAdd "ACE_EarPlugs") exitWith { // inventory full - [localize LSTRING(Inventory_Full)] call EFUNC(common,displayTextStructured); +// Inventory full +if !([_unit, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { + [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); }; // Plugs already in and removing them. -_player addItem "ACE_EarPlugs"; +_unit addItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", false, true]; +_unit setVariable ["ACE_hasEarPlugsIn", false, true]; -[localize LSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); +if (_displayHint) then { + [LLSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); +}; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index e010165f8a..b9d7f1f9a0 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Updates the hearing protection and volume attenuation for player on earbuds/helmet change + * Updates the hearing protection and volume attenuation for player on earbuds/helmet change. * * Arguments: * None @@ -10,12 +10,12 @@ * None * * Example: - * [] call ace_hearing_fnc_updateHearingProtection + * call ace_hearing_fnc_updateHearingProtection * * Public: No */ -TRACE_1("params",_this); +LOG("updateHearingProtection"); if (isNull ACE_player) exitWith { GVAR(damageCoefficent) = 0; @@ -23,22 +23,32 @@ if (isNull ACE_player) exitWith { }; // Handle Earplugs -private _hasEarPlugsIn = [ACE_player] call FUNC(hasEarPlugsIn); +private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn); GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn; -GVAR(volumeAttenuation) = [1, GVAR(EarplugsVolume)] select _hasEarPlugsIn; +GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn; // Handle Headgear -if (headgear ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(protection)) min 1; +private _headgear = headgear ACE_player; + +if (_headgear != "") then { + private _heargearConfig = configFile >> "CfgWeapons" >> _headgear; + + private _protection = getNumber (_heargearConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; // Handle Goggles -if (goggles ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(protection)) min 1; +private _goggles = goggles ACE_player; + +if (_goggles != "") then { + private _gogglesConfig = configFile >> "CfgGlasses" >> _goggles; + + private _protection = getNumber (_gogglesConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; diff --git a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf index 8d42ca1c0c..856b694a3f 100644 --- a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf +++ b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Gets the sound attenuation of a player to the outside. @@ -7,10 +7,10 @@ * None * * Return Value: - * Ammount that unit can hear outside + * Amount that unit can hear outside * * Example: - * [] call ace_hearing_fnc_updatePlayerVehAttenuation + * call ace_hearing_fnc_updatePlayerVehAttenuation * * Public: No */ @@ -20,12 +20,14 @@ private _vehicle = vehicle ACE_player; if (isNull _vehicle) exitWith {}; private _newAttenuation = 1; -if (ACE_player != _vehicle) then { - private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); - private _effectType = getText (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "attenuationEffectType"); - if (!(_turretPath isEqualTo [])) then { - private _turretConfig = [(configFile >> "CfgVehicles" >> (typeOf _vehicle)), _turretPath] call EFUNC(common,getTurretConfigPath); +if (ACE_player != _vehicle) then { + private _vehicleConfig = configOf _vehicle; + private _turretPath = _vehicle unitTurret ACE_player; + private _effectType = getText (_vehicleConfig >> "attenuationEffectType"); + + if (_turretPath isNotEqualTo []) then { + private _turretConfig = [_vehicleConfig, _turretPath] call EFUNC(common,getTurretConfigPath); if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then { _effectType = ""; @@ -40,12 +42,15 @@ if (ACE_player != _vehicle) then { case (_effectType == ""): {1}; case (_effectType == "CarAttenuation"); case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars - private _armor = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "HitPoints" >> "HitBody" >> "armor"); + private _armor = getNumber (_vehicleConfig >> "HitPoints" >> "HitBody" >> "armor"); linearConversion [2, 8, _armor, 0.5, 0.3, true];}; case (_effectType == "OpenCarAttenuation"): {1}; case (_effectType == "TankAttenuation"): {0.1}; + case (_effectType == "MrapAttenuation"): {0.2}; case (_effectType == "HeliAttenuation"): {0.3}; case (_effectType == "OpenHeliAttenuation"): {0.9}; + case (_effectType == "SemiOpenCarAttenuation"); + case (_effectType == "SemiOpenCarAttenuation2"); case (_effectType == "SemiOpenHeliAttenuation"): {0.6}; case (_effectType == "HeliAttenuationGunner"): {0.85}; case (_effectType == "HeliAttenuationRamp"): {0.85}; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 4cf1a6b117..bb1d57e3c1 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,54 +1,61 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain and Ruthberg + * Author: commy2, esteldunedain, Ruthberg * Updates and applies the current deafness. Called every 1 sec from a PFEH. * * Arguments: - * 0: Args - * 0: Just update volume (skip ringing/recovery) (default: false) + * 0: Update volume only (skip ringing/recovery) (default: false) * * Return Value: * None * * Example: - * [] call ace_hearing_fnc_updateVolume + * call ace_hearing_fnc_updateVolume * * Public: No */ +if (isGamePaused) exitWith {}; + if (!alive ACE_player) exitWith { - if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + TRACE_1("dead - removing hearing effects",ACE_player); + [QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability); }; -(_this select 0) params [["_justUpdateVolume", false]]; +params [["_updateVolumeOnly", false]]; GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0; GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05; + TRACE_3("",GVAR(volume),GVAR(deafnessDV),GVAR(deafnessDV) - GVAR(deafnessPrior)); -if (!_justUpdateVolume) then { +if (!_updateVolumeOnly) then { // Ring if we got a big increase in the last second or enough accumulated damage if (GVAR(deafnessDV) - GVAR(deafnessPrior) > 1 || GVAR(deafnessDV) > 10) then { if (CBA_missionTime - GVAR(time3) < 3) exitWith {}; + if (!isGameFocused) exitWith {}; // prevent audio from stacking when tabbed out + GVAR(time3) = CBA_missionTime; if (GVAR(deafnessDV) > 19.75) then { - playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging)); } else { - playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging)); }; }; + GVAR(deafnessPrior) = GVAR(deafnessDV); // Hearing takes longer to return to normal after it hits rock bottom - GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; + GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; }; -if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; private _volume = GVAR(volume); @@ -56,8 +63,8 @@ private _volume = GVAR(volume); _volume = _volume min GVAR(volumeAttenuation); // Reduce volume if player is unconscious -if (ACE_player getVariable ["ACE_isUnconscious", false]) then { - _volume = _volume min GVAR(UnconsciousnessVolume); +if (lifeState ACE_player == "INCAPACITATED") then { + _volume = _volume min GVAR(unconsciousnessVolume); }; [QUOTE(ADDON), _volume, true] call EFUNC(common,setHearingCapability); diff --git a/addons/hearing/functions/script_component.hpp b/addons/hearing/functions/script_component.hpp deleted file mode 100644 index 18305605c4..0000000000 --- a/addons/hearing/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\hearing\script_component.hpp" \ No newline at end of file diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf new file mode 100644 index 0000000000..d129966198 --- /dev/null +++ b/addons/hearing/initKeybinds.inc.sqf @@ -0,0 +1,18 @@ +["ACE3 Equipment", QGVAR(putOrRemoveEarplugs), LLSTRING(PutOrRemoveEarplugs), { + // Conditions: specific + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + if (GVAR(enableCombatDeafness) && {!(ACE_player call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { + [ACE_player, true] call FUNC(putInEarPlugs); + + true // return + }; + + if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith { + [ACE_player, true] call FUNC(removeEarPlugs); + + true // return + }; + + false // return +}] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/initSettings.inc.sqf b/addons/hearing/initSettings.inc.sqf new file mode 100644 index 0000000000..adc6c6def7 --- /dev/null +++ b/addons/hearing/initSettings.inc.sqf @@ -0,0 +1,56 @@ +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; + +[ + QGVAR(enableCombatDeafness), + "CHECKBOX", + [LSTRING(EnableCombatDeafness_DisplayName), LSTRING(EnableCombatDeafness_Description)], + _category, + true, + 1, + {[QGVAR(enableCombatDeafness), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(earplugsVolume), + "SLIDER", + [LSTRING(earplugsVolume_DisplayName), LSTRING(earplugsVolume_Description)], + _category, + [0, 1, 0.5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(unconsciousnessVolume), + "SLIDER", + [LSTRING(unconsciousnessVolume_DisplayName), LSTRING(unconsciousnessVolume_Description)], + _category, + [0, 1, 0.4, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(disableEarRinging), + "CHECKBOX", + [LSTRING(DisableEarRinging_DisplayName), LSTRING(DisableEarRinging_Description)], + _category, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(enabledForZeusUnits), + "CHECKBOX", + [LSTRING(enabledForZeusUnits_DisplayName), LSTRING(enabledForZeusUnits_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(autoAddEarplugsToUnits), + "LIST", + [LSTRING(autoAddEarplugsToUnits_DisplayName), LSTRING(autoAddEarplugsToUnits_Description)], + _category, + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(heavyWeaponUnits), ELSTRING(common,Enabled)], 1], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/hearing/script_component.hpp b/addons/hearing/script_component.hpp index 7e69c908b5..178310cd20 100644 --- a/addons/hearing/script_component.hpp +++ b/addons/hearing/script_component.hpp @@ -15,3 +15,4 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" diff --git a/addons/hearing/script_macros_hearingProtection.hpp b/addons/hearing/script_macros_hearingProtection.hpp new file mode 100644 index 0000000000..377560247e --- /dev/null +++ b/addons/hearing/script_macros_hearingProtection.hpp @@ -0,0 +1,4 @@ +#define HEARING_PROTECTION_OPEN EGVAR(hearing,protection) = 0; EGVAR(hearing,lowerVolume) = 0 +#define HEARING_PROTECTION_VICCREW EGVAR(hearing,protection) = 0.85; EGVAR(hearing,lowerVolume) = 0.6 +#define HEARING_PROTECTION_EARMUFF EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0.5 +#define HEARING_PROTECTION_PELTOR EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0 diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index e5cb9df251..9aba1ab56b 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -8,7 +8,7 @@ Stopery do uszu Špunty Беруши - Bouchons Anti-Bruits + Bouchons anti bruit Füldugó Protetor auricular Tappi auricolari @@ -16,6 +16,7 @@ 귀마개 耳塞 耳塞 + Kulak Tıkacı Protective Earplugs allow the wearer to be near loud weaponry without damage to his hearing. @@ -24,11 +25,11 @@ Stopery do uszu umożliwiają użytkownikowi przebywać w pobliżu głośnej broni bez poniesienia konsekwencji jaką jest utrata słuchu. Ochranné špunty umožňují uživateli, aby neutrpěl zranění jeho sluchu v blízkosti hlasitých zbraní. Беруши позволяют носителю находиться возле громкого вооружения без потери слуха. - Bouchons Anti-Bruits permettant au porteur d'être près d'arme bruyante sans risque d'endommager son ouïe. + Les bouchons d'oreilles anti bruit permettent au porteur d'être près d'armes bruyantes, sans risque d'endommager son ouïe. Erősebb hanghatásoktól védő füldugó, megakadályozza a nagy hanggal járó fegyverzettől való halláskárosodást. Protetor para ouvidos permitem que o usuário esteja próximo a ruídos sem danificar sua audição. Proteggono l'apparato uditivo, permettendo a chi li indossa di resistere ai suoni particolarmente forti senza alcun danno. - 着けることにより、近くの大きな銃声から聴覚を保護します。 + 耳栓を着けることにより、近くの大きな銃声から聴覚を保護します。 보호용 귀마개는 화기로부터의 큰소리로부터 사용자의 청력을 보호합니다. 配戴防护耳塞,遇到大声的武器发射时也不会损害听力。 配戴防護耳塞,遇到大聲的武器發射時也不會損害聽力 @@ -44,10 +45,11 @@ Füldugó berakva Protetores colocados Indossa i tappi auricolari - 耳栓を着ける + 耳栓を装着 귀마개 착용 塞入耳塞 塞入耳塞 + Kulak Tıkacı Tak Earplugs out @@ -64,6 +66,7 @@ 귀마개 뺌 取出耳塞 取出耳塞 + Kulak Tıkacını Çıkart Earplugs in @@ -75,11 +78,12 @@ Bouchons mis Füldugó berakva Protetores colocados - Indossa i tappi auricolari - 耳栓を着けました + Tappi auricolari indossati + 耳栓を装着しました 귀마개 착용 耳塞已塞入 耳塞已塞入 + Kulak Tıkacı Takıldı Earplugs out @@ -91,11 +95,12 @@ Bouchons enlevés Füldugó kivéve Protetores retirados - Levati i tappi auricolari + Tappi auricolari rimossi 耳栓を外しました 귀마개 뺌 耳塞已取出 耳塞已取出 + Kulak Tıkacı Çıkartıldı You have no earplugs @@ -104,7 +109,7 @@ Nie masz stoperów Nemáš žádné špunty У вас нет беруш - Vous n'avez pas de bouchons anti-bruits + Vous n'avez pas de bouchons anti bruit. Nincsen füldugód Você não possui protetores auriculares Non hai i tappi auricolari @@ -112,35 +117,20 @@ 귀마개가 없습니다 你没有耳塞 你沒有耳塞 - - - No inventory space - Kein Platz im Inventar - Sin espacio en el inventario - Brak miejsca w ekwipunku - Pas de place dans l'inventaire - Není místo v inventáři - Non hai abbastanza spazio - Não há espaço no inventário - Nincs több hely - Нет места в инвентаре - インベントリに空きがありません - 넣을 공간이 없습니다 - 无可用空间 - 無可用空間 + Kulak Tıkacın Yok Disable ear ringing - Désactiver le bourdonnement + Désactiver les bourdonnements Desactivar zumbido de oídos - Отключить звон в ушах + Откл. звон в ушах Knalltrauma deaktivieren Vypnout pískání v uších Wyłącz dzwonienie w uszach Fülcsengés letiltása - Disabilita i fischi nelle orecchie + Disabilita il fischio nelle orecchie Desabilitar zumbido de ouvidos - 耳鳴りを無効化する + 耳鳴りを無効化 이명현상 끄기 关闭耳鸣效果 關閉耳鳴效果 @@ -150,14 +140,15 @@ Deaktiviert Ohrklingeln wenn der Spieler Hörschäden davonträgt. Desactiva el efecto de zumbido cuando el jugador recibe daño auditivo. Usuń szum w uszach przy chwilowej utracie słuchu. - Enlève les acouphènes quand le joueur prend des dommages auditifs. - Quando il giocatore riceve danni all'udito, non fa sentire i fischi nelle orecchie + Enlève l'effet d'acouphène lorsqu'un joueur subit des dommages auditifs. + Quando il giocatore riceve danni all'udito, non far sentire il fischio nelle orecchie Remove o efeito de zunido quando o jogador recebe dano na audição Убирает эффект звона в ушах, когда игрок получает повреждение слуха - プレイヤーの聴覚が損傷したら耳鳴りの効果を削除します - 플레이어가 청력손실을 입을때 생기는 이명현상을 제거합니다. - 关闭耳鸣效果时,就算玩家受到相当程度的听力伤害, 也不会造成耳鸣效果 + プレイヤーが聴覚にダメージを受けた際の耳鳴り効果音を無効化します + 플레이어가 청력손실을 입을 때 생기는 이명현상을 제거합니다. + 关闭耳鸣效果时,就算玩家受到相当程度的听力伤害,也不会造成耳鸣效果 關閉耳鳴效果時,就算玩家受到相當程度的聽力傷害, 也不會造成耳鳴效果 + Odstranit tinitus když hráč utrpí poškození sluchu Hearing @@ -186,9 +177,9 @@ Harci süketség engedélyezése? Оглушение Sordità da combattimento - 戦闘による難聴を有効化 + 戦闘難聴を有効化 전투 난청 켜기 - 启用战斗性耳聋? + 启用战斗性耳聋? 啟用戰鬥性耳聾? @@ -199,11 +190,11 @@ Snižuje schopnost sluchu pokud dojde k jeho poškození hlasitou a blízkou střelbou Ativar surdez em combate? Уменьшает возможность игрока слышать звуки при повреждении органов слуха - Riduci l'abilità uditiva quando il giocatore riceve danno uditivo - Réduire l'audition lorsque le joueur prend des dommages auditifs. - 音による損傷をうけ、聴覚が減る可能性があります + Assorda il giocatore quando riceve danni all'udito + Réduit la capacité auditive du joueur lorsqu'il subit des dommages auditifs. + プレイヤーが聴覚にダメージを受けると聴力が低下します 청력에 손상을 입으면 듣는 소리가 감소합니다. - 当玩家听力受损时降低听力能力? + 当玩家听力受损时降低听力能力? 當玩家聽力受損時降低聽力能力? @@ -214,10 +205,10 @@ Dieses Modul aktiviert/deaktiviert die Taubheit im Gefecht. Wenn aktiviert, können Spieler ohne Gehörschutz taub werden, wenn eine Waffe in ihrer Nähe abgefeuert wird oder eine Explosion stattfindet. Ztráta sluchu je možná ve chvíly, kdy se v bezprostřední blízkosti střílí z velkorážní zbraně nebo při bombardování a osoba je bez ochrany sluchu (např. špunty). Tento modul umožňuje tuto věc povolit nebo zakázat. Este módulo ativa / desativa surdez em combate. Quando ativado, os jogadores podem ficar surdos quando uma arma é disparada ao seu redor ou uma explosão ocorre sem proteção auditiva. - Ce module active / désactivé la surdité au combat. Si active, des joueurs peuvent devenir sourds sans protection d'oreille, si une arme est utilisée ou une explosion a lieu à proximité + Pemet le réglage de la surdité au combat et des bourdonnements. Si actif, les joueurs sans protection auditive peuvent être assourdis quand une arme est utilisée à proximité, ou lorsqu'une explosion se produit. Controles de sordera de combate y zumbido en los oídos. Al activarlo, los jugadores pueden ser ensordecidos cuando un arma se dispara cerca o una explosión tiene lugar sin protección auditiva Controlla la sordità da combattimento e fischio alle orecchie. Quando attivato, i giocatori possono essere assordati quando un'arma spara vicino o avviene un'esplosione senza protezione uditiva - 戦闘による難聴や、耳鳴りを設定します。有効では聴覚を保護していないと近傍の銃声や爆発音により、難聴になります。 + 戦闘による難聴や、耳鳴りを設定します。有効にすると聴覚を保護していないと近くの銃声や爆発音により、プレイヤーが難聴になる可能性が発生します。 전투 난청과 이명현상을 조작합니다. 작동시 플레이어가 화기나 폭발의 주변에 있을경우 청력보호장치가 없을때 청력손실을 입습니다. 设定战斗性耳聋和耳鸣。当启用后,玩家会在有武器在旁边射击或爆炸产生时造成耳鸣效果 設定戰鬥性耳聾和耳鳴。當啟用後,玩家會在有武器在旁邊射擊或爆炸產生時造成耳鳴效果 @@ -230,9 +221,9 @@ Afeta Zeus CR Efecto Zeus RC Vliv na Zeus RC - Effetto Zeus RC - Effet sur le CàD du Zeus - Zeus RC への効果 + Affligge unità Zeus RC + Affecte le CàD Zeus + Zeus遠隔操作ユニットへの効果 Zeus RC 효과 启用效果在宙斯远程遥控 啟用效果在宙斯遠程遙控 @@ -245,9 +236,9 @@ Permite que unidades remotamente controladas pelo Zeus sejam atingidas por danos auditivos. Permitir a las unidades por control remoto de zeus que puedan tener daños auditivos. Aktivovat efekt ztráty sluchu pro vzdáleně ovládané jednotky. - Consenti alle unità controllate in remoto da Zeus di ricevere danni all'udito. - Permet aux unités controlées à distance de subir des traumatismes sonores. - Zeus により遠隔操作されたユニットにも、聴覚へ損傷を受けるようにします。 + Abilita danni all'udito per unità controllate in remoto da Zeus. + Permet aux unités contrôlées à distance par Zeus de subir des dommages auditifs. + Zeusにより遠隔操作されたユニットも、聴覚ダメージの効果を受けるようにします。 Zeus가 원격으로 청력손실을 입힐 수 있게 합니다. 设定宙斯远程遥控的单位也会受到耳鸣的效果。 設定宙斯遠程遙控的單位也會受到耳鳴的效果。 @@ -261,7 +252,7 @@ Přidat špunty jednotce Aggiungi Tappi per Orecchie alle unità Agregar tapones de oida a la unidad - Ajouter des bouchons anti-bruits aux unités + Ajouter des bouchons anti bruit aux unités ユニットへ耳栓を追加 해당 인원에게 귀마개 추가 增加耳塞给单位 @@ -274,11 +265,11 @@ Добавляет предмет `ACE_EarPlugs` всем юнитам, которые имеют громкое оружие. Можно отключить при ручной настройке снаряжения. Adicionar o item `ACE_EarPlugs` a todas as unidades que tenham armas barulhentas. Pode ser desabilitado com carregamentos customizados. Přidat `ACE_EarPlugs` všem jednotkám které mají zbraň. Můžete vypnout, pokud používáte vlastní výbavu. - Aggiungi l'oggetto 'ACE_EarPlugs' a tutte le unità che hanno armi rumorose. Può essere disabilitato se vengono usati loadout personalizzati. + Aggiungi l'oggetto 'ACE_EarPlugs' a tutte le unità che hanno armi/lanciatori rumorosi. Può essere disabilitato se vengono usati loadout personalizzati. Agregar el item `ACE_EarPlugs` a todas las unidades equipadas con armas muy ruidosas. Desactivar si quieren utilizarse equipamientos personalizados. - Ajoute l'objet "Ace_EarPlugs" à toutes les unités ayant des armes bruyantes. Peut être désactivé par des loadouts personalisés. - 全ユニットへ`ACE_EarPlugs`アイテムを持たせます。これは変更された武装で無効化できます。 - 무기를 가지고 있는 모든 인원에게 'ACE_EarPlugs'를 지급합니다. 임의의 장비를 사용시 비활성화 할 수 있습니다. + Ajoute l'objet `Ace_EarPlugs` à toutes les unités ayant des armes bruyantes. Peut être désactivé si de l'équipement personnalisé est utilisé. + 全てのユニットに`ACE_EarPlugs`アイテムを所持させます。これはロードアウトの編集で無効化できます。 + 무기를 가지고 있는 모든 인원에게 'ACE_EarPlugs'를 지급합니다. 임의의 장비를 사용시 비활성화할 수 있습니다. 增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。 增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。 @@ -292,57 +283,105 @@ Protezione auditiva Ochrona słuchu Защита слуха + Proteção Auditiva + Ochrana sluchu + Protección auditiva + 청력 보호 Volume muffling Lautstärkedämpfung - Étouffement des sons - 音量低下 + Atténuation du volume + 音量の抑制 降低音量 進低音量 - Volume attenuazione + Attenuazione del volume Tłumienie głośności Глушение звука + Abafamento de Volume + Snížení hlasitosti + Atenuación de volumen + 소리 차음도 Earplugs Volume Lautstärke Ohrenstöpsel - 耳栓時の音量 + 耳栓装着時音量 耳塞时音量 耳塞時音量 - Volume tappi per le orecchie + Volume con i Tappi Głośność Stoperów Громкость в берушах + Volume do Protetor Auricular + Volume bouchons anti bruit + Hlasitost se špunty + Volumen de protectores auditivos + 귀마개 볼륨 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 + Volume audio perçu par les joueurs portant des bouchons anti bruit. + Hlasitost při používání špuntů do uší. + Volumen cuando se utilizan protectores auditivos. + 귀마개 사용 시의 볼륨입니다. Unconscious Volume Lautstärke Bewusstlosigkeit - 気絶時の音量 + 無意識状態時音量 无意识时音量 昏迷時音量 Volume quando incoscente Nieprzytomna Głośność Громкость без сознания + Volume Inconsciente + Volume inconscience + Hlasitost při ztrátě vědomí + Volumen inconsciente + 기절 볼륨 Volume when unconscious. Lautstärke während man Bewusstlos ist - 気絶時の音量を決定します。 + 無意識状態になった時の音量。 决定处于无意识时的音量 昏迷時使用耳塞的音量 Volume quando incoscente. Głośność podczas bycia nieprzytomnym. Громкость при потере сознания + Volume enquanto inconsciente + Volume perçu par les joueurs inconscients. + Hlasitost během ztráty vědomí. + Volumen durante la inconsciencia. + 기절 시 볼륨입니다. + + + Put/take out earplugs + 耳栓の着脱 + Вставить/вынуть беруши + Metti/Togli tappi + 귀마개 토글 + Mettre/enlever les bouchons + Ohrstöpsel einsetzen/herausnehmen + Poner/quitar tapones + + + Only units with heavy weapons + Uniquement les unités dotées d'armes lourdes + Только юниты с тяжелым вооружением + Nur Einheiten mit schweren Waffen + 重火器を装備したユニットのみ + Sólo unidades con armas pesadas + Solo a unità con armi pesanti + 중화기를 가진 유닛만 해당 diff --git a/addons/hellfire/CfgAmmo.hpp b/addons/hellfire/CfgAmmo.hpp index a5d7214292..5eef9ad47e 100644 --- a/addons/hellfire/CfgAmmo.hpp +++ b/addons/hellfire/CfgAmmo.hpp @@ -61,8 +61,70 @@ class CfgAmmo { indirectHitRange = 12; submunitionAmmo = ""; explosionEffects = "BombExplosion"; + EGVAR(vehicle_damage,incendiary) = 0.3; class ace_missileguidance: ace_missileguidance { enabled = 1; // Missile Guidance must be explicitly enabled }; }; + class ACE_Hellfire_AGM114L: ACE_Hellfire_AGM114K { + displayName = "AGM-114L"; + displayNameShort = "AGM-114L"; + description = "AGM-114L"; + descriptionShort = "AGM-114L"; + class ace_missileguidance: ace_missileguidance { + canVanillaLock = 1; + enabled = 1; // Missile Guidance must be explicitly enabled + seekLastTargetPos = 0; + defaultSeekerType = "ARH"; + seekerTypes[] = { "ARH" }; + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = { "LOBL" }; + + activeRadarEngageDistance = 1000; + seekerMaxRange = 2000; // distance that the hellfire internal radar can scan + }; + + // Vanilla lock system vars + weaponLockSystem = "8"; + airLock = 1; + lockType = 0; + maneuvrability = 0; // no maneuvrability so that default guidance doesnt work + + missileLockMaxDistance = 8000; + missileLockMinDistance = 250; + missileLockMaxSpeed = 600; + missileKeepLockedCone = 70; + + flightProfiles[] = {}; + class Components { + class SensorsManagerComponent { + class Components { + class MillimeterWaveRadar { + componentType = "ActiveRadarSensorComponent"; + class AirTarget { + minRange = 0; + maxRange = 8000; + objectDistanceLimitCoef = -1; + viewDistanceLimitCoef = -1; + }; + class GroundTarget { + minRange = 0; + maxRange = 8000; + objectDistanceLimitCoef = -1; + viewDistanceLimitCoef = -1; + }; + typeRecognitionDistance = 4000; + angleRangeHorizontal = 70; + angleRangeVertical = 70; + groundNoiseDistanceCoef = 0; // relevant to AA missiles - not really for this + maxGroundNoiseDistance = 250; + minSpeedThreshold = 0; + maxSpeedThreshold = 600; + nightRangeCoef = 1; + maxFogSeeThrough = 0.8; + }; + }; + }; + }; + }; }; diff --git a/addons/hellfire/CfgEventHandlers.hpp b/addons/hellfire/CfgEventHandlers.hpp index 77ea0239bd..cfa4d5fe32 100644 --- a/addons/hellfire/CfgEventHandlers.hpp +++ b/addons/hellfire/CfgEventHandlers.hpp @@ -1,15 +1,15 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/hellfire/CfgMagazineWells.hpp b/addons/hellfire/CfgMagazineWells.hpp index 5077d2faa6..17d6adee59 100644 --- a/addons/hellfire/CfgMagazineWells.hpp +++ b/addons/hellfire/CfgMagazineWells.hpp @@ -1,4 +1,5 @@ class CfgMagazineWells { class GVAR(K) {}; class GVAR(N) {}; + class GVAR(L) {}; }; diff --git a/addons/hellfire/CfgMagazines.hpp b/addons/hellfire/CfgMagazines.hpp index de63540a2a..d025afadde 100644 --- a/addons/hellfire/CfgMagazines.hpp +++ b/addons/hellfire/CfgMagazines.hpp @@ -1,13 +1,13 @@ class CfgMagazines { class 12Rnd_PG_missiles; - + // Kilo - tandem shaped charge HEAT (anti-tank) class 6Rnd_ACE_Hellfire_AGM114K: 12Rnd_PG_missiles { // Old style vehicle magazine count = 6; ammo = "ACE_Hellfire_AGM114K"; displayName = "AGM-114K [ACE]"; displayNameShort = "AGM-114K"; - descriptionShort = "AGM-114K"; + descriptionShort = CSTRING(KDescriptionShort); }; // 1.70 pylon magazines: @@ -16,7 +16,7 @@ class CfgMagazines { count = 1; mass = 70; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"SCALPEL_1RND"}; + hardpoints[] = {"SCALPEL_1RND", "HellfireRail_MELB"}; model = "\A3\Weapons_F\DynamicLoadout\PylonMissile_1x_Bomb_04_F.p3d"; }; class PylonRack_1Rnd_ACE_Hellfire_AGM114K: 6Rnd_ACE_Hellfire_AGM114K { // 1x Launcher Support Rack @@ -32,7 +32,7 @@ class CfgMagazines { count = 3; mass = 250; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_LONGBOW_RACK"}; + hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_3x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 3}; }; @@ -41,7 +41,7 @@ class CfgMagazines { count = 4; mass = 340; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_HELLFIRE_RACK", "RHS_HP_LONGBOW_RACK"}; + hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_4x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 4, 3}; }; @@ -52,36 +52,75 @@ class CfgMagazines { ammo = "ACE_Hellfire_AGM114N"; displayName = "AGM-114N [ACE]"; displayNameShort = "AGM-114N"; - descriptionShort = "AGM-114N"; + descriptionShort = CSTRING(NDescriptionShort); }; // 1.70 pylon magazines: class PylonMissile_1Rnd_ACE_Hellfire_AGM114N: PylonMissile_1Rnd_ACE_Hellfire_AGM114K { // Bare missle displayName = "1x AGM-114N [ACE]"; displayNameShort = "AGM-114N"; - descriptionShort = "AGM-114N"; + descriptionShort = CSTRING(NDescriptionShort); ammo = "ACE_Hellfire_AGM114N"; pylonWeapon = QGVAR(launcher_N); }; class PylonRack_1Rnd_ACE_Hellfire_AGM114N: PylonRack_1Rnd_ACE_Hellfire_AGM114K { // 1x Launcher Support Rack displayName = "1x AGM-114N [ACE]"; displayNameShort = "AGM-114N"; - descriptionShort = "AGM-114N"; + descriptionShort = CSTRING(NDescriptionShort); ammo = "ACE_Hellfire_AGM114N"; pylonWeapon = QGVAR(launcher_N); }; class PylonRack_3Rnd_ACE_Hellfire_AGM114N: PylonRack_3Rnd_ACE_Hellfire_AGM114K { // 3x Launcher Support Rack displayName = "3x AGM-114N [ACE]"; displayNameShort = "AGM-114N"; - descriptionShort = "AGM-114N"; + descriptionShort = CSTRING(NDescriptionShort); ammo = "ACE_Hellfire_AGM114N"; pylonWeapon = QGVAR(launcher_N); }; class PylonRack_4Rnd_ACE_Hellfire_AGM114N: PylonRack_4Rnd_ACE_Hellfire_AGM114K { // 4x Launcher Support Rack displayName = "4x AGM-114N [ACE]"; displayNameShort = "AGM-114N"; - descriptionShort = "AGM-114N"; + descriptionShort = CSTRING(NDescriptionShort); ammo = "ACE_Hellfire_AGM114N"; pylonWeapon = QGVAR(launcher_N); }; + + // Lima - tandem shaped charge HEAT (anti-tank) Fire and Forget Active Radar Homing + class 6Rnd_ACE_Hellfire_AGM114L: 6Rnd_ACE_Hellfire_AGM114K { // Old style vehicle magazine + count = 6; + ammo = "ACE_Hellfire_AGM114L"; + displayName = "AGM-114L [ACE]"; + displayNameShort = "AGM-114L"; + descriptionShort = CSTRING(LDescriptionShort); + }; + + // 1.70 pylon magazines: + class PylonMissile_1Rnd_ACE_Hellfire_AGM114L: PylonMissile_1Rnd_ACE_Hellfire_AGM114K { // Bare missle + displayName = "1x AGM-114L [ACE]"; + displayNameShort = "AGM-114L"; + descriptionShort = CSTRING(LDescriptionShort); + ammo = "ACE_Hellfire_AGM114L"; + pylonWeapon = QGVAR(launcher_L); + }; + class PylonRack_1Rnd_ACE_Hellfire_AGM114L: PylonRack_1Rnd_ACE_Hellfire_AGM114K { // 1x Launcher Support Rack + displayName = "1x AGM-114L [ACE]"; + displayNameShort = "AGM-114L"; + descriptionShort = CSTRING(LDescriptionShort); + ammo = "ACE_Hellfire_AGM114L"; + pylonWeapon = QGVAR(launcher_L); + }; + class PylonRack_3Rnd_ACE_Hellfire_AGM114L: PylonRack_3Rnd_ACE_Hellfire_AGM114K { // 3x Launcher Support Rack + displayName = "3x AGM-114L [ACE]"; + displayNameShort = "AGM-114L"; + descriptionShort = CSTRING(LDescriptionShort); + ammo = "ACE_Hellfire_AGM114L"; + pylonWeapon = QGVAR(launcher_L); + }; + class PylonRack_4Rnd_ACE_Hellfire_AGM114L: PylonRack_4Rnd_ACE_Hellfire_AGM114K { // 4x Launcher Support Rack + displayName = "4x AGM-114L [ACE]"; + displayNameShort = "AGM-114L"; + descriptionShort = CSTRING(LDescriptionShort); + ammo = "ACE_Hellfire_AGM114L"; + pylonWeapon = QGVAR(launcher_L); + }; }; diff --git a/addons/hellfire/CfgVehicles.hpp b/addons/hellfire/CfgVehicles.hpp deleted file mode 100644 index 89dbf131d7..0000000000 --- a/addons/hellfire/CfgVehicles.hpp +++ /dev/null @@ -1,6 +0,0 @@ -class CfgVehicles { - class Heli_Attack_01_base_F; - class Heli_Attack_01_dynamicLoadout_base_F: Heli_Attack_01_base_F { - GVAR(addLaserDesignator) = 1; - }; -}; diff --git a/addons/hellfire/CfgWeapons.hpp b/addons/hellfire/CfgWeapons.hpp index 5806ab5fbe..fd9bdce044 100644 --- a/addons/hellfire/CfgWeapons.hpp +++ b/addons/hellfire/CfgWeapons.hpp @@ -1,5 +1,6 @@ class CfgWeapons { class RocketPods; + class MissileLauncher; class GVAR(launcher): RocketPods { displayName = "AGM-114K Hellfire II"; GVAR(enabled) = 1; // handle adding interactions and adding Laser Designator @@ -29,4 +30,26 @@ class CfgWeapons { magazines[] = {"6Rnd_ACE_Hellfire_AGM114N", "PylonMissile_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_3Rnd_ACE_Hellfire_AGM114N", "PylonRack_4Rnd_ACE_Hellfire_AGM114N"}; magazineWell[] += {QGVAR(N)}; }; + class GVAR(launcher_L): GVAR(launcher) { + displayName = "AGM-114L Hellfire ""Longbow"""; + magazines[] = {"6Rnd_ACE_Hellfire_AGM114L", "PylonMissile_1Rnd_ACE_Hellfire_AGM114L", "PylonRack_1Rnd_ACE_Hellfire_AGM114L", "PylonRack_3Rnd_ACE_Hellfire_AGM114L", "PylonRack_4Rnd_ACE_Hellfire_AGM114L"}; + magazineWell[] += {QGVAR(L)}; + EGVAR(laser,showHud) = 1; // Just to show the attack profile + EGVAR(laser,canSelect) = 0; + class StandardSound { + begin1[] = {"A3\Sounds_F\weapons\Rockets\missile_1",1.12202,1.3,1000}; + soundBegin[] = {"begin1",1}; + soundsetshot[] = {"RocketsMedium_Shot_SoundSet"}; + }; + cursor = "EmptyCursor"; + cursorAim = "missile"; + showAimCursorInternal = 0; + + // vanilla weapon lock systems + weaponLockSystem = 8; + cmImmunity = 0.9; + lockAcquire = 0; + weaponLockDelay = 0.1; + canLock = 2; + }; }; diff --git a/addons/hellfire/README.md b/addons/hellfire/README.md index bb9eef711e..b894c0050c 100644 --- a/addons/hellfire/README.md +++ b/addons/hellfire/README.md @@ -3,8 +3,3 @@ ace_hellfire Adds AGM-114K Hellfire missiles. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/hellfire/XEH_postInit.sqf b/addons/hellfire/XEH_postInit.sqf index e89bf7a3e3..020e4dc2fc 100644 --- a/addons/hellfire/XEH_postInit.sqf +++ b/addons/hellfire/XEH_postInit.sqf @@ -2,7 +2,7 @@ if (!hasInterface) exitWith {}; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { ["turret", LINKFUNC(setupVehicle), false] call CBA_fnc_addPlayerEventHandler; ["vehicle", LINKFUNC(setupVehicle), true] call CBA_fnc_addPlayerEventHandler; // only one of these needs the retro flag diff --git a/addons/hellfire/config.cpp b/addons/hellfire/config.cpp index 911e016d7f..37358ea702 100644 --- a/addons/hellfire/config.cpp +++ b/addons/hellfire/config.cpp @@ -19,5 +19,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" #include "CfgMagazineWells.hpp" -#include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/hellfire/functions/fnc_attackProfile.sqf b/addons/hellfire/functions/fnc_attackProfile.sqf index 8904d57978..26bc3f1ff0 100644 --- a/addons/hellfire/functions/fnc_attackProfile.sqf +++ b/addons/hellfire/functions/fnc_attackProfile.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Hellfire attack profile. Handles all 4 modes LOBL, LOAL-DIR, LOAL-HI, LOAL-LO @@ -18,8 +18,10 @@ */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH", "_launchParams"]; -_launchParams params ["","_targetLaunchParams"]; +_args params ["_firedEH", "_launchParams", "", "", "_stateParams"]; +_stateParams params ["", "_seekerStateParams"]; +_launchParams params ["","_targetLaunchParams","_seekerType"]; + _targetLaunchParams params ["", "", "_launchPos"]; _firedEH params ["","","","","","","_projectile"]; @@ -54,7 +56,7 @@ switch (_attackStage) do { _returnTargetPos = _projectilePos getPos [100, getDir _projectile]; _returnTargetPos set [2, (_projectilePos select 2) + _cruiseHeight]; - if (!(_seekerTargetPos isEqualTo [0,0,0])) then { + if (_seekerTargetPos isNotEqualTo [0,0,0]) then { _attackProfileStateParams set [0, STAGE_ATTACK_CRUISE]; TRACE_1("New Stage: STAGE_ATTACK_CRUISE",_distanceFromLaunch2d); }; @@ -65,10 +67,10 @@ switch (_attackStage) do { private _distToGoRatio = _distanceToTarget2d / (_launchPos distance2d _seekerTargetPos); // arcing up at 7 degrees to start until 50% left, then smooth curve to a downward attack - private _gainSlope = linearConversion [0.5, 0.1, _distToGoRatio, 7, -7, true]; + private _gainSlope = linearConversion [0.5, 0.1, _distToGoRatio, 7, -7, true]; _returnTargetPos = +_seekerTargetPos; _returnTargetPos set [2, ((_projectilePos select 2) + (_distanceToTarget2d * sin _gainSlope)) max (_seekerTargetPos select 2)]; - + if ((_distanceToTarget2d < 500) || {(_currentHeightOverTarget atan2 _distanceToTarget2d) > 15}) then { // Wait until we can come down at a sharp angle _attackProfileStateParams set [0, STAGE_ATTACK_TERMINAL]; TRACE_2("New Stage: STAGE_ATTACK_TERMINAL",_distanceToTarget2d,_currentHeightOverTarget); @@ -80,5 +82,16 @@ switch (_attackStage) do { }; }; -// TRACE_1("Adjusted target position", _returnTargetPos); +// Special radar case. Adjust target position such that we are leading it +if (_attackStage >= 3 && { _seekerType isEqualTo "ARH" }) then { + _seekerStateParams params ["", "", "", "", "", "", "", "_lastKnownVelocity"]; + private _projectileVelocity = velocity _projectile; + if (_projectileVelocity#2 < 0) then { + private _projectileSpeed = vectorMagnitude _projectileVelocity; // this gives a precise impact time versus using speed _projectile. Dont change + private _timeUntilImpact = (_seekerTargetPos distance _projectilePos) / _projectileSpeed; + _returnTargetPos = _returnTargetPos vectorAdd (_lastKnownVelocity vectorMultiply _timeUntilImpact); + }; +}; + +// TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf index 066d280d65..14d89f82e3 100644 --- a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf +++ b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Gets attack profile parameters for first run of hellfire attack profile function @@ -31,11 +31,10 @@ private _configLaunchHeightClear = getNumber (_attackConfig >> QGVAR(launchHeigh private _startingStage = if (_configLaunchHeightClear > 0) then { STAGE_LAUNCH; // LOAL-HI / LO } else { - if (_seekerTargetPos isEqualTo [0,0,0]) then { - STAGE_SEEK_CRUISE; // LOAL-DIR - } else { - STAGE_ATTACK_CRUISE // LOBL - }; + [ + STAGE_ATTACK_CRUISE, + STAGE_SEEK_CRUISE + ] select (_seekerTargetPos isEqualTo [0,0,0]); }; // Set data in param array diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf index e824542021..ce3961d77a 100644 --- a/addons/hellfire/functions/fnc_setupVehicle.sqf +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Adds interaction menu actions to switch the firemode to a vehicle. @@ -41,12 +41,12 @@ if (!_enabled) exitWith {TRACE_3("Not enabled",_enabled,_vehicle,_turretPath);}; // Add laser if vehicle is configured for one: -if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QGVAR(addLaserDesignator))) == 1) then { +if ((getNumber (configOf _vehicle >> QGVAR(addLaserDesignator))) == 1) then { [{ params ["_vehicle", "_turretPath"]; TRACE_3("checking for laser",_vehicle,_turretPath,_vehicle turretLocal _turretPath); if (!alive _vehicle) exitWith {}; - if (!(_vehicle turretLocal _turretPath)) then {WARNING("Turret not local");}; + if !(_vehicle turretLocal _turretPath) then {WARNING("Turret not local");}; private _hasLaser = false; { // Most addons just use "Laserdesignator_mounted", but this should cover custom ones @@ -78,7 +78,7 @@ private _fnc_statement = { }; private _fnc_condition = { params ["_target", "_player", "_attackProfile"]; - + private _turretPath = if (ACE_player == (driver _target)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; private _hasWeapon = ({(isNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(enabled))) && {getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(enabled)) > 0}} count (_target weaponsTurret _turretPath)) > 0; diff --git a/addons/hellfire/functions/script_component.hpp b/addons/hellfire/functions/script_component.hpp deleted file mode 100644 index 899f29a758..0000000000 --- a/addons/hellfire/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\hellfire\script_component.hpp" diff --git a/addons/hellfire/stringtable.xml b/addons/hellfire/stringtable.xml index e3deab9110..647f349273 100644 --- a/addons/hellfire/stringtable.xml +++ b/addons/hellfire/stringtable.xml @@ -3,7 +3,7 @@ Set Hellfire mode - Setze Hellfire-Modus + Hellfire-Modus einstellen Imposta modalità Hellfire ヘルファイア モードを設定 设定地狱火模式 @@ -11,6 +11,50 @@ Ustaw tryb pocisku Hellfire 헬파이어 모드 세팅 Установить режим Hellfire + Definir modo de Hellfire + Définir mode Hellfire + Nastavit režim Hellfire + Hellfire modunu ayarla + Ajustar modo Hellfire + + + Semi-active laser homing missile with high explosive anti-tank warhead + Самонаводящаяся Ракета с фугасной противотанковой боевой частью и полуактивной лазерной системой наведения + Misil de guiado láser semi-activo con cabeza de alto explosivo anti-tanque + Missile antichar à guidage laser semi-actif (charge HEAT) + Missile a guida laser semi-attiva con una testata HEAT + セミ アクティブ レーダー誘導の対戦車弾頭 + Rakieta naprowadzana laserowo z głowicą przeciwpancerną + Halbaktive Laser-Zielsuchrakete mit HEAT-Gefechtskopf + 高爆反坦克弹头半主动激光制导导弹 + 반능동 레이저 유도미사일로 대전차 고폭 탄두를 탑재하고 있습니다. + Míssil teleguiado a laser semi-ativo com ogiva antitanque altamente explosiva + + + Millimeter-wave radar guided missile with high explosive anti-tank warhead + Радиолокационная управляемая ракета миллиметрового диапазона с фугасной противотанковой боевой частью + Misil guiado por radar de onda milimétrica con cabeza de alto explosivo anti-tanque + Missile antichar à guidage radar à ondes courtes (charge HEAT) + Missile a guida radar con una testata HEAT + ミリ波レーダー誘導の対戦車弾頭 + Rakieta namierzana radarowo z głowicą przeciwpancerną + Millimeterwellenradar-Lenkflugkörper mit HEAT-Gefechtskopf + 高爆反坦克弹头毫米波雷达制导导弹 + 밀리미터파 레이더 유도 미사일로 대전차 고폭 탄두를 탑재하고 있습니다. + Míssil guiado por radar de ondas milimétricas com ogiva antitanque altamente explosiva + + + Semi-active laser homing missile with metal augmented charge anti-personnel warhead + Самонаводящаяся ракета с металлической увеличенной зарядной противопехотной боевой частью и полуактивной лазерной системой наведения + Misil guiado por láser semi-activo con cabeza de carga de metal aumentada anti-persona + Missile a guida laser semi-attiva con una testata a frammentazione antiuomo + Missile antipersonnel thermobarique à guidage laser semi-actif + セミ アクティブ レーダー誘導の対人弾 + Rakieta naprowadzana laserowo z głowicą odłamkową + Halbaktive Laser-Zielsuchrakete mit metallverstärktem Antipersonen-Gefechtskopf + 金属增强人员杀伤弹头半主动激光制导导弹 + 반능동 레이저 유도 미사일로 대인 금속 강화 탄두가 탑재하고 있습니다. + Míssil teleguiado a laser semi-ativo com ogiva antipessoal de carga aumentada de metal diff --git a/addons/hitreactions/ACE_Settings.hpp b/addons/hitreactions/ACE_Settings.hpp index 0220e09629..78a510a141 100644 --- a/addons/hitreactions/ACE_Settings.hpp +++ b/addons/hitreactions/ACE_Settings.hpp @@ -1,10 +1,5 @@ - class ACE_Settings { class GVAR(minDamageToTrigger) { - //Minimum mamage needed to trigger falling down while moving. Set to -1 to disable completely. - typeName = "SCALAR"; - value = 0.1; - displayName = CSTRING(minDamageToTrigger_displayName); - sliderSettings[] = {-1, 1, 0.1, 1}; + movedToSQF = 1; }; }; diff --git a/addons/hitreactions/CfgEventHandlers.hpp b/addons/hitreactions/CfgEventHandlers.hpp index bb990cafea..b737b7bcbf 100644 --- a/addons/hitreactions/CfgEventHandlers.hpp +++ b/addons/hitreactions/CfgEventHandlers.hpp @@ -1,13 +1,18 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/hitreactions/README.md b/addons/hitreactions/README.md index f770470e44..2d69ce0a89 100644 --- a/addons/hitreactions/README.md +++ b/addons/hitreactions/README.md @@ -2,10 +2,3 @@ ace_hitreactions =========== Adds reactions when getting shot. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/hitreactions/XEH_PREP.hpp b/addons/hitreactions/XEH_PREP.hpp index 7701b8ef19..eea48dcaa8 100644 --- a/addons/hitreactions/XEH_PREP.hpp +++ b/addons/hitreactions/XEH_PREP.hpp @@ -1,3 +1,3 @@ - +PREP(checkWeaponDrop); PREP(fallDown); PREP(getRandomAnimation); diff --git a/addons/hitreactions/XEH_postInit.sqf b/addons/hitreactions/XEH_postInit.sqf new file mode 100644 index 0000000000..2750ae1159 --- /dev/null +++ b/addons/hitreactions/XEH_postInit.sqf @@ -0,0 +1,94 @@ +#include "script_component.hpp" + + +[QGVAR(updateFiredEHs), { + TRACE_2("updateFiredEH",GVAR(weaponDropChanceArmHitPlayer),GVAR(weaponDropChanceArmHitAI)); + if (GVAR(weaponDropChanceArmHitPlayer) + GVAR(weaponDropChanceArmHitAI) == 0) then { + if (isNil QGVAR(firedEHs)) exitWith {}; + { + _x call CBA_fnc_removeEventHandler; + } forEach GVAR(firedEHs); + GVAR(firedEHs) = nil; + TRACE_1("removed EHs",GVAR(firedEHs)); + } else { + if (!isNil QGVAR(firedEHs)) exitWith {}; + private _firedEH = { + if (!local (_this select 0)) exitWith {}; + (_this select 6) addEventHandler ["HitPart", { + params ["", "_entity", "", "", "", "", "_selections"]; + [_entity, _selections] call FUNC(checkWeaponDrop); + }]; + }; + GVAR(firedEHs) = []; + { + GVAR(firedEHs) pushBack [_x, [_x, _firedEH] call CBA_fnc_addEventHandler]; + } forEach ["ace_firedNonPlayer", "ace_firedPlayer"]; + TRACE_1("added EHs",GVAR(firedEHs)); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(dropWeapon), { + params ["_unit"]; + TRACE_1("dropWeaponEH",_unit); + + if !(_unit getVariable [QGVAR(canDropWeapon), true]) exitWith {}; + + // Prevents AI from losing both primary and pistol when being shot with their pistol out + _unit setVariable [QGVAR(canDropWeapon), false]; + + private _weapon = currentWeapon _unit; + private _thrownWeapon = _unit call EFUNC(common,throwWeapon); + + [{ + params ["_unit"]; + + _unit setVariable [QGVAR(canDropWeapon), nil]; + }, _unit, 0.5] call CBA_fnc_waitAndExecute; + + if (_unit call EFUNC(common,isPlayer)) exitWith {}; // Don't make players pick their own weapons up + + // Wait before executing, as otherwise the unit would pick up the weapon immediately + [{ + [{ + (_this select 0) params ["_unit", "_weapon", "_thrownWeapon", "_timeout"]; + + // If the unit has been deleted or dead, if the weapon doesn't exist anymore or if it's been too long, stop + if (!alive _unit || {!local _unit} || {isNull _thrownWeapon} || {CBA_missionTime >= _timeout}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + // Don't pick up weapon when unit is unconscious + if (lifeState _unit == "INCAPACITATED") exitWith {}; + + // If the unit has no essential weapons, force them to get their weapon, otherwise wait until no enemies are present + if !( + (primaryWeapon _unit == "" && {handgunWeapon _unit == ""}) || + {(_unit distance (_unit findNearestEnemy _unit)) > missionNamespace getVariable [QGVAR(safePickupDistance), DEFAULT_PICKUP_DISTANCE]} + ) exitWith {}; + + // If the unit is too far away, make them move closer + if (_unit distance _thrownWeapon >= 4) exitWith { + private _pos = getPosATL _thrownWeapon; + + _unit setDestination [_pos, "LEADER PLANNED", true]; + _unit doMove _pos; + }; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + _unit action ["TakeWeapon", _thrownWeapon, _weapon]; + + // Make the unit switch weapons + [{ + (_this select 0) hasWeapon (_this select 1) + }, { + params ["_unit", "_weapon"]; + + if (!alive _unit || {!local _unit} || {primaryWeapon _unit != _weapon}) exitWith {}; + + // Switch to the primary weapon, if it was picked up + _unit selectWeapon _weapon; + }, [_unit, _weapon], 5] call CBA_fnc_waitUntilAndExecute; + }, 5, _this] call CBA_fnc_addPerFrameHandler; + }, [_unit, _weapon, _thrownWeapon, CBA_missionTime + 300], random [2, 3, 4]] call CBA_fnc_waitAndExecute; +}] call CBA_fnc_addEventHandler; diff --git a/addons/hitreactions/XEH_preInit.sqf b/addons/hitreactions/XEH_preInit.sqf index b47cf6628d..296279c7eb 100644 --- a/addons/hitreactions/XEH_preInit.sqf +++ b/addons/hitreactions/XEH_preInit.sqf @@ -6,4 +6,18 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +GVAR(armSelections) = [ + "leftshoulder", + "rightshoulder", + "lefthand", + "leftforearm", + "leftarmroll", + "rightforearm", + "rightarmroll", + "righthand", + "rightarm" +]; + ADDON = true; diff --git a/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf new file mode 100644 index 0000000000..ad4e7c4a41 --- /dev/null +++ b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: KJW + * Checks if an entity should drop their weapon based on projectile hit info. + * + * Arguments: + * 0: Entity that was hit + * 1: Selection names that were hit + * + * Return Value: + * None + * + * Example: + * [player, []] call ace_hitreactions_fnc_checkWeaponDrop + * + * Public: No + */ + +params ["_entity", "_selections"]; + +// Make sure entity is a unit +if !(_entity isKindOf "CAManBase") exitWith {}; + +// Don't throw weapon if unit is unconscious or dead +if !(lifeState _entity in ["HEALTHY", "INJURED"]) exitWith {}; + +if (random 1 >= ([GVAR(weaponDropChanceArmHitAI), GVAR(weaponDropChanceArmHitPlayer)] select (_entity call EFUNC(common,isPlayer)))) exitWith {}; + +if (_selections findAny GVAR(armSelections) == -1) exitWith {}; + +if (getNumber ((currentWeapon _entity) call CBA_fnc_getItemConfig >> QGVAR(undroppable)) == 1) exitWith {}; + +[QGVAR(dropWeapon), _entity, _entity] call CBA_fnc_targetEvent; diff --git a/addons/hitreactions/functions/fnc_fallDown.sqf b/addons/hitreactions/functions/fnc_fallDown.sqf index 4b305700e0..38f3152c7c 100644 --- a/addons/hitreactions/functions/fnc_fallDown.sqf +++ b/addons/hitreactions/functions/fnc_fallDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Adds reactions to a unit that was hit. EH only runs where to unit is local. Adds screams, falling down, falling from ladders, ejecting from static weapons and camshake for players @@ -22,6 +22,9 @@ params ["_unit", "_firer", "_damage"]; // exit if system is disabled if (GVAR(minDamageToTrigger) == -1) exitWith {}; +// exit if damage is disabled on unit +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {}; + // don't fall after minor damage if (_damage < GVAR(minDamageToTrigger)) exitWith {}; diff --git a/addons/hitreactions/functions/fnc_getRandomAnimation.sqf b/addons/hitreactions/functions/fnc_getRandomAnimation.sqf index bfdfd9646f..8b26bf70ef 100644 --- a/addons/hitreactions/functions/fnc_getRandomAnimation.sqf +++ b/addons/hitreactions/functions/fnc_getRandomAnimation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Get a random fall animation for the unit. diff --git a/addons/hitreactions/functions/script_component.hpp b/addons/hitreactions/functions/script_component.hpp deleted file mode 100644 index ba26402e2b..0000000000 --- a/addons/hitreactions/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\hitreactions\script_component.hpp" \ No newline at end of file diff --git a/addons/hitreactions/initSettings.inc.sqf b/addons/hitreactions/initSettings.inc.sqf new file mode 100644 index 0000000000..820f664767 --- /dev/null +++ b/addons/hitreactions/initSettings.inc.sqf @@ -0,0 +1,30 @@ +private _category = [LELSTRING(common,categoryUncategorized), QUOTE(COMPONENT_BEAUTIFIED)]; + +[ + QGVAR(minDamageToTrigger), + "SLIDER", + LSTRING(minDamageToTrigger_displayName), + _category, + [-1, 1, 0.1, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitPlayer), + "SLIDER", + LSTRING(weaponDropChanceArmHitPlayer_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitAI), + "SLIDER", + LSTRING(weaponDropChanceArmHitAI_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; diff --git a/addons/hitreactions/script_component.hpp b/addons/hitreactions/script_component.hpp index dccbef24f7..dd407a914b 100644 --- a/addons/hitreactions/script_component.hpp +++ b/addons/hitreactions/script_component.hpp @@ -15,3 +15,5 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define DEFAULT_PICKUP_DISTANCE 8 diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml index fa65479508..ff541ad6a3 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -1,16 +1,37 @@ - - + + Min Damage to trigger falling - Danno Minimo da caduta + Danno Minimo per far cadere 觸發倒下前最低需受到多少傷害 触发倒下前最低需受到多少伤害 - 崩れ落ちるまでの最低損傷値 - 방아쇠를 당기는 최소한의 피해 + 転倒が発生するダメージの最低値 + 넘어질 때 발생하는 최소 피해량 Mindestschaden, um Sturz auszulösen Minimalne obrażenie, żeby aktywować spadanie - Минимальный урон для активации падения + Мин. урон для активации падения + Dano Mínimo para ativar queda + Dommages minimaux pour faire tomber le joueur + Minimum škody pro aktivaci spadnutí + Düşmeyi tetikleyen min hasar + Daño mínimo para provocar la caída + + + Player Weapon Drop Chance (Arm Hit) + プレイヤーが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у игрока (попадание в руку) + 플레이어가 무기를 떨굴 확률 (팔 피격) + Spieler Wahrscheinlichkeit, die Waffe fallen zu lassen (Arm Treffer) + Probabilità dei giocatori di far cadere l'arma (colpo al braccio) + + + AI Weapon Drop Chance (Arm Hit) + AIが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у ИИ (попадание в руку) + 인공지능이 무기를 떨굴 확률 (팔 피격) + KI-Wahrscheinlichkeit, die Waffe fallen zu lassen (Arm Treffer) + Probabilità dell'IA di far cadere l'arma (colpo al braccio) diff --git a/addons/hot/ACE_GuidanceConfig.hpp b/addons/hot/ACE_GuidanceConfig.hpp deleted file mode 100644 index f129a6b558..0000000000 --- a/addons/hot/ACE_GuidanceConfig.hpp +++ /dev/null @@ -1,21 +0,0 @@ -class EGVAR(missileguidance,AttackProfiles) { - class WIRE { - name = CSTRING(missileType); - visualName = CSTRING(missileType); - description = CSTRING(missileType_Description); - - functionName = QFUNC(attackProfile_WIRE); - onFired = QFUNC(wire_onFired); - }; -}; -class EGVAR(missileguidance,SeekerTypes) { - class SACLOS { - name = "SACLOS"; - visualName = "SACLOS"; - 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 e591d13aff..1be8c6067f 100644 --- a/addons/hot/CfgAmmo.hpp +++ b/addons/hot/CfgAmmo.hpp @@ -53,6 +53,7 @@ class CfgAmmo { initTime = 0.3; EGVAR(rearm,caliber) = 178; + EGVAR(vehicle_damage,incendiary) = 1.0; class ace_missileguidance { enabled = 1; @@ -77,7 +78,7 @@ class CfgAmmo { seekerMinRange = 75; seekerMaxRange = 4000; // Range from the missile which the seeker can visually search - correctionDistance = 15; // distance from center of crosshair where missile slows down + correctionDistance = 8; // distance from center of crosshair where missile slows down offsetFromCrosshair[] = { 0, 0, 0.5 }; // where the missile wants to stay in relation to the center of the crosshair. // Attack profile type selection @@ -111,13 +112,15 @@ class CfgAmmo { EGVAR(frag,metal) = 7100; // 1000 steel balls EGVAR(frag,charge) = 4100; EGVAR(frag,gurney_c) = 2700; - EGVAR(frag,gurney_k) = 3/5; + EGVAR(frag,gurney_k) = "3/5"; EGVAR(frag,classes)[] = {"ACE_frag_small"}; displayName = CSTRING(hot2mp); displayNameShort = CSTRING(hot2mp); description = CSTRING(missileType_Description_AP); + EGVAR(vehicle_damage,incendiary) = 0.1; + class ace_missileguidance: ace_missileguidance { enabled = 1; }; diff --git a/addons/hot/CfgEventHandlers.hpp b/addons/hot/CfgEventHandlers.hpp deleted file mode 100644 index 755e0552c5..0000000000 --- a/addons/hot/CfgEventHandlers.hpp +++ /dev/null @@ -1,12 +0,0 @@ -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)); - }; -}; - diff --git a/addons/hot/CfgWeapons.hpp b/addons/hot/CfgWeapons.hpp index 1263ef8dea..d172de7fa1 100644 --- a/addons/hot/CfgWeapons.hpp +++ b/addons/hot/CfgWeapons.hpp @@ -12,7 +12,7 @@ class CfgWeapons { lockedTargetSound[] = {"",0,1}; soundFly[] = {"A3\Sounds_F\weapons\Rockets\rocket_fly_1",1,1.1,700}; nameSound = "MissileLauncher"; - sounds[] = {"StandardSound"}; + sounds[] = {"StandardSound"}; class StandardSound { begin1[] = {"A3\Sounds_F\weapons\Rockets\missile_1",1.12202,1.3,1000}; soundBegin[] = {"begin1",1}; @@ -45,7 +45,7 @@ class CfgWeapons { lockedTargetSound[] = {"",0,1}; soundFly[] = {"A3\Sounds_F\weapons\Rockets\rocket_fly_1",1,1.1,700}; nameSound = "MissileLauncher"; - sounds[] = {"StandardSound"}; + sounds[] = {"StandardSound"}; class StandardSound { begin1[] = {"A3\Sounds_F\weapons\Rockets\missile_1",1.12202,1.3,1000}; soundBegin[] = {"begin1",1}; @@ -54,7 +54,7 @@ class CfgWeapons { cursor = "EmptyCursor"; cursorAim = "missile"; showAimCursorInternal = 0; - + autoReload = 1; magazineReloadTime = 20; }; diff --git a/addons/hot/README.md b/addons/hot/README.md index 217dfc2f6f..c94e369c7d 100644 --- a/addons/hot/README.md +++ b/addons/hot/README.md @@ -2,11 +2,3 @@ ace_hot =================== Adds HOT1/2/3 Missiles - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Brandon-TCVM](https://github.com/TheCandianVendingMachine) - diff --git a/addons/hot/XEH_PREP.hpp b/addons/hot/XEH_PREP.hpp deleted file mode 100644 index ec59d0f41f..0000000000 --- a/addons/hot/XEH_PREP.hpp +++ /dev/null @@ -1,5 +0,0 @@ -PREP(seekerType_SACLOS); -PREP(attackProfile_WIRE); -PREP(wire_onFired); -PREP(SACLOS_onFired); - diff --git a/addons/hot/XEH_preInit.sqf b/addons/hot/XEH_preInit.sqf deleted file mode 100644 index 29cc0a7f24..0000000000 --- a/addons/hot/XEH_preInit.sqf +++ /dev/null @@ -1,10 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -PREP_RECOMPILE_START; -#include "XEH_PREP.hpp" -PREP_RECOMPILE_END; - -ADDON = true; - diff --git a/addons/hot/XEH_preStart.sqf b/addons/hot/XEH_preStart.sqf deleted file mode 100644 index 76b104a5bc..0000000000 --- a/addons/hot/XEH_preStart.sqf +++ /dev/null @@ -1,4 +0,0 @@ -#include "script_component.hpp" - -#include "XEH_PREP.hpp" - diff --git a/addons/hot/config.cpp b/addons/hot/config.cpp index 52f9f5ef6e..bdb7ad956f 100644 --- a/addons/hot/config.cpp +++ b/addons/hot/config.cpp @@ -8,14 +8,12 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common","ace_missileguidance"}; author = ECSTRING(common,ACETeam); - authors[] = {"Brandon (TCVM)"}; + authors[] = {"tcvm"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; -#include "ACE_GuidanceConfig.hpp" -#include "CfgEventHandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" diff --git a/addons/hot/functions/fnc_SACLOS_onFired.sqf b/addons/hot/functions/fnc_SACLOS_onFired.sqf deleted file mode 100644 index 7702b330ee..0000000000 --- a/addons/hot/functions/fnc_SACLOS_onFired.sqf +++ /dev/null @@ -1,35 +0,0 @@ -#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 deleted file mode 100644 index 139939e4f7..0000000000 --- a/addons/hot/functions/fnc_attackProfile_WIRE.sqf +++ /dev/null @@ -1,60 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Brandon (TCVM) - * Attack profile: Wire guided - * - * Arguments: - * 0: Seeker Target PosASL - * 1: Guidance Arg Array - * 2: Attack Profile State - * - * Return Value: - * Missile Aim PosASL - * - * Example: - * [[1,2,3], [], []] call ace_hot_fnc_attackProfile_WIRE; - * - * Public: No - */ -params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH"]; -_firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "", "_wireCutSource"]; - -private _projectilePos = getPosASL _projectile; - -if ((((getPosASL _shooter) vectorDistanceSqr _projectilePos) > _seekerMaxRangeSqr) || { _wireCut }) exitWith { - // wire snap, random direction - if (_randomVector isEqualTo [0, 0, 0]) then { - _randomVector = RANDOM_VECTOR_3D vectorMultiply 300; - _attackProfileStateParams set [1, true]; - _attackProfileStateParams set [2, _randomVector]; - - playSound3D ["a3\sounds_f\air\sfx\SL_rope_break.wss", objNull, false, AGLtoASL (_shooter modelToWorld _wireCutSource), 150, 1, 25]; - }; - _projectilePos vectorAdd _randomVector -}; - -if (_seekerTargetPos isEqualTo [0, 0, 0]) exitWith { - // cut wire if its caught on terrain - /*if !(lineIntersectsSurfaces [getPosASL _shooter, _projectilePos, _shooter] isEqualTo []) then { - _attackProfileStateParams set [1, true]; - };*/ - // return position 50m infront of projectile - _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) -}; - -private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); -_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; - -private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; - -private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair - -// Adjust the impulse due to near-zero values creating wobbly missiles? -private _correction = _fovImpulse; - -_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; - -_projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); - diff --git a/addons/hot/functions/fnc_seekerType_SACLOS.sqf b/addons/hot/functions/fnc_seekerType_SACLOS.sqf deleted file mode 100644 index 06245d0708..0000000000 --- a/addons/hot/functions/fnc_seekerType_SACLOS.sqf +++ /dev/null @@ -1,50 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Brandon (TCVM) - * SACLOS seeker - * - * Arguments: - * 1: Guidance Arg Array - * 2: Seeker State - * - * Return Value: - * Position of wanted missile pos relative to the camera direction - * - * Example: - * [] call ace_hot_fnc_seekerType_SACLOS - * - * Public: No - */ -params ["", "_args"]; -_args params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; -_firedEH params ["_shooter","_weapon","","","","","_projectile"]; -_seekerParams params ["_seekerAngle"]; -_stateParams params ["", "_seekerStateParams"]; -_seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", "_animationSourceGun", "_distanceAheadOfMissile"]; - -private _shooterPos = AGLToASL (_shooter modelToWorld(_shooter selectionPosition _memoryPointGunnerOptics)); -private _projPos = getPosASL _projectile; - -private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { - private _gBody = -deg(_shooter animationPhase _animationSourceBody); - private _gGun = deg(_shooter animationPhase _animationSourceGun); - - _shooter vectorModelToWorld ([1, _gBody, _gGun] call CBA_fnc_polar2vect); -} else { - _shooterPos = eyePos _shooter; - _shooter weaponDirection _weapon -}; - -private _distanceToProj = _shooterPos vectorDistance _projPos; -private _testPointVector = vectorNormalized (_projPos vectorDiff _shooterPos); -private _testDotProduct = (_lookDirection vectorDotProduct _testPointVector); - -private _testIntersections = lineIntersectsSurfaces [_shooterPos, _projPos, _shooter]; - -if ((_testDotProduct < (cos _seekerAngle)) || { !(_testIntersections isEqualTo []) }) exitWith { - // out of LOS of seeker - [0, 0, 0] -}; - -_shooterPos vectorAdd (_lookDirection vectorMultiply (_distanceToProj + _distanceAheadOfMissile)); - diff --git a/addons/hot/functions/fnc_wire_onFired.sqf b/addons/hot/functions/fnc_wire_onFired.sqf deleted file mode 100644 index 3e1ff2d03d..0000000000 --- a/addons/hot/functions/fnc_wire_onFired.sqf +++ /dev/null @@ -1,46 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Brandon (TCVM) - * Sets up wireGuided state arrays (called from missileGuidance's onFired). - * - * Arguments: - * Guidance Arg Array - * - * Return Value: - * None - * - * Example: - * [] call ace_hot_fnc_wire_onFired - * - * Public: No - */ -params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; -_firedEH params ["_shooter","_weapon","","","","","_projectile", "_gunner"]; -_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 _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange; -private _minDistanceSqr = _seekerMinRange * _seekerMinRange; - -// AI don't know how to use the crosshair offset becauze they dum dum -_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 -}; - -private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon; -private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret; - -private _wireCutSource = _shooter selectionPosition getText(_turretConfig >> "missileEnd"); - -_attackProfileStateParams set [0, _maxCorrectableDistance]; -_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, _minDistanceSqr]; -_attackProfileStateParams set [6, _wireCutSource]; - diff --git a/addons/hot/functions/script_component.hpp b/addons/hot/functions/script_component.hpp deleted file mode 100644 index fbebb0b9a3..0000000000 --- a/addons/hot/functions/script_component.hpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "\z\ace\addons\hot\script_component.hpp" - diff --git a/addons/hot/script_component.hpp b/addons/hot/script_component.hpp index fd5475f15f..54cf5ccea1 100644 --- a/addons/hot/script_component.hpp +++ b/addons/hot/script_component.hpp @@ -16,13 +16,3 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define RANDOM_VECTOR_3D (call {\ - private _z = random 2 - 1;\ - private _r = sqrt (1 - _z^2);\ - private _theta = random 360;\ - [_r * cos _theta, _r * sin _theta, _z]\ -}) - -#define DEFAULT_CORRECTION_DISTANCE 10 -#define DEFAULT_LEAD_DISTANCE 50 - diff --git a/addons/hot/stringtable.xml b/addons/hot/stringtable.xml index a6b427f408..3c872e1994 100644 --- a/addons/hot/stringtable.xml +++ b/addons/hot/stringtable.xml @@ -6,24 +6,48 @@ Drahtgelenkt Kierowany przewodem Filoguidato - ワイヤ有線誘導 + 有線誘導 Проводное управление + Guiado por Fio + 有線制導 + 有线制导 + Filoguidé + Drátem naváděné + Tel-Güdümlü + Guiado por cable + 유선 유도 - Semi-automatic command to line of sight - halbautomatische Steuerung über Sichtverbindung (SACLOS) + Semi-automatic command to line of sight (SACLOS) + Halbautomatische Steuerung über Sichtverbindung (SACLOS) Semi-automatyczna komenda do pola widzenia - Comando Semi-Automatico via Contatto Visivo(SACLOS) - 半自動指令照準線一致誘導方式 + Comando Semi-Automatico su Contatto Visivo (SACLOS) + 半自動指令照準線一致誘導方式 (SACLOS) Полуавтоматическое командное наведение по линии визирования (SACLOS) + Comando semi-automático para a linha de visão (SACLOS) + 視線內半自動指令 + 半自动指令到视线(SACLOS) + Contrôle semi-automatique par contact visuel (SACLOS) + Poloautomatický povelový systém dalkového navedení pro záměrné cíle (SACLOS) + Control semi-automático por línea de visión + Görüş alanına yarı otomatik komut + 반자동 가시선 지령 유도방식 Wire-Guided Missile Drahtgelenkte Rakete Pocisk kierowany przewodowo - Missile filoguidato - ワイヤ有線誘導ミサイル + Missile Filoguidato + 有線誘導ミサイル Ракета с проводным управлением + Míssil Guiado por Fio + 有線制導飛彈 + 线导导弹 + Missile filoguidé + Drátem naváděná střela + Tel Güdümlü Füze + Misil guiado por cable + 유선 유도 미사일 HOT Missile @@ -32,6 +56,14 @@ Missile HOT HOT ミサイル Ракета HOT + Míssil HOT + 高次音速(HOT)飛彈 + 高次音速(HOT)导弹 + Missile HOT + HOT Střela + HOT Missile + Misil HOT + HOT 미사일 HOT 1 @@ -40,6 +72,14 @@ HOT 1 HOT 1 HOT 1 + HOT 1 + HOT 1 + HOT 1 + HOT 1 + HOT 1 + HOT 1 + HOT 1 + HOT 1 HOT 2 @@ -48,6 +88,14 @@ HOT 2 HOT 2 HOT 2 + HOT 2 + HOT 2 + HOT 2 + HOT 2 + HOT 2 + HOT 2 + HOT 2 + HOT 2 HOT 2MP @@ -56,6 +104,14 @@ HOT 2MP HOT 2MP HOT 2MP + HOT 2MP + HOT 2MP + HOT 2MP + HOT 2MP + HOT 2MP + HOT 2MP + HOT 2MP + HOT 2MP HOT 3 @@ -64,14 +120,30 @@ HOT 3 HOT 3 HOT 3 + HOT 3 + 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 - ワイヤ有線誘導ミサイル (対人) + Missile Filoguidato Antiuomo + 有線誘導ミサイル (対人) Ракета с проводным управлением (Противопехотная) + Míssil Guiado por Fio (Anti-Pessoal) + 有線制導飛彈(反步兵) + 线导导弹(反人员) + Missile filoguidé (antipersonnel) + Drátem naváděná střela (protipěchotní) + Tel Güdümlü Füze (Anti-Personelı) + Misil guiado por cable (Antipersona) + 유선 유도 미사일 (대인) 1x HOT 1 [ACE] @@ -80,6 +152,14 @@ 1x HOT1 [ACE] 1x HOT 1 [ACE] 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] 3x HOT 1 [ACE] @@ -88,6 +168,14 @@ 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] + 3x HOT 1 [ACE] + 3x HOT 1 [ACE] + 3x HOT 1 [ACE] + 3x HOT 1 [ACE] 4x HOT 1 [ACE] @@ -96,6 +184,14 @@ 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] + 4x HOT 1 [ACE] + 4x HOT 1 [ACE] + 4x HOT 1 [ACE] + 4x HOT 1 [ACE] 1x HOT 2 [ACE] @@ -104,6 +200,14 @@ 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] + 1x HOT 2 [ACE] + 1x HOT 2 [ACE] + 1x HOT 2 [ACE] + 1x HOT 2 [ACE] 3x HOT 2 [ACE] @@ -112,6 +216,14 @@ 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] + 3x HOT 2 [ACE] + 3x HOT 2 [ACE] + 3x HOT 2 [ACE] + 3x HOT 2 [ACE] 4x HOT 2 [ACE] @@ -120,6 +232,14 @@ 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] + 4x HOT 2 [ACE] + 4x HOT 2 [ACE] + 4x HOT 2 [ACE] + 4x HOT 2 [ACE] 1x HOT 2MP [ACE] @@ -128,6 +248,14 @@ 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] + 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] 3x HOT 2MP [ACE] @@ -136,6 +264,14 @@ 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] + 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] 4x HOT 2MP [ACE] @@ -144,6 +280,14 @@ 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] + 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] 1x HOT 3 [ACE] @@ -152,6 +296,14 @@ 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] + 1x HOT 3 [ACE] + 1x HOT 3 [ACE] + 1x HOT 3 [ACE] + 1x HOT 3 [ACE] 4x HOT 3 [ACE] @@ -160,6 +312,14 @@ 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] + 4x HOT 3 [ACE] + 4x HOT 3 [ACE] + 4x HOT 3 [ACE] + 4x HOT 3 [ACE] 3x HOT 3 [ACE] @@ -168,6 +328,14 @@ 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] + 3x HOT 3 [ACE] + 3x HOT 3 [ACE] + 3x HOT 3 [ACE] + 3x HOT 3 [ACE] diff --git a/addons/hunterkiller/$PBOPREFIX$ b/addons/hunterkiller/$PBOPREFIX$ new file mode 100644 index 0000000000..3474867891 --- /dev/null +++ b/addons/hunterkiller/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\hunterkiller \ No newline at end of file diff --git a/addons/hunterkiller/CfgEventHandlers.hpp b/addons/hunterkiller/CfgEventHandlers.hpp new file mode 100644 index 0000000000..2a3f71f852 --- /dev/null +++ b/addons/hunterkiller/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/hunterkiller/CfgVehicles.hpp b/addons/hunterkiller/CfgVehicles.hpp new file mode 100644 index 0000000000..b0fc79fc2b --- /dev/null +++ b/addons/hunterkiller/CfgVehicles.hpp @@ -0,0 +1,28 @@ +class CfgVehicles { + class Tank_F; + class MBT_01_base_F: Tank_F { + ADDON = 1; // same as ADDON[] = {{{0}, 1}, {{0,0}, 3}}; + }; + class MBT_01_arty_base_F: MBT_01_base_F { + ADDON = 0; + }; + class MBT_01_mlrs_base_F: MBT_01_base_F { + ADDON = 0; + }; + class MBT_02_base_F: Tank_F { + ADDON = 1; + }; + class MBT_02_arty_base_F: MBT_02_base_F { + ADDON = 0; + }; + class MBT_03_base_F: Tank_F { + ADDON = 1; + }; + class MBT_04_base_F: Tank_F { + ADDON = 1; + }; + class Wheeled_APC_F; + class AFV_Wheeled_01_base_F: Wheeled_APC_F { + ADDON = 1; + }; +}; diff --git a/addons/hunterkiller/README.md b/addons/hunterkiller/README.md new file mode 100644 index 0000000000..293192db4e --- /dev/null +++ b/addons/hunterkiller/README.md @@ -0,0 +1,4 @@ +ace_hunterkiller +========== + +Allows a tank commander to re-aim the main turret or to aim their turret at the what the main turret is looking at diff --git a/addons/hunterkiller/XEH_PREP.hpp b/addons/hunterkiller/XEH_PREP.hpp new file mode 100644 index 0000000000..e0d7cd892e --- /dev/null +++ b/addons/hunterkiller/XEH_PREP.hpp @@ -0,0 +1,5 @@ +LOG("prep"); + +PREP(keydown); +PREP(slew); +PREP(turretChangedEH); diff --git a/addons/hunterkiller/XEH_postInit.sqf b/addons/hunterkiller/XEH_postInit.sqf new file mode 100644 index 0000000000..1560b6cc54 --- /dev/null +++ b/addons/hunterkiller/XEH_postInit.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +[QGVAR(slew), LINKFUNC(slew)] call CBA_fnc_addEventHandler; + +if (!hasInterface) exitWith {}; + +GVAR(mode) = 0; +GVAR(targetTurret) = []; + +["CBA_settingsInitialized", { + ["turret", LINKFUNC(turretChangedEH), true] call CBA_fnc_addPlayerEventHandler; +}] call CBA_fnc_addEventHandler; + + +["ACE3 Vehicles", QGVAR(observe), [format ["%1 - %2", LLSTRING(displayName), LLSTRING(observe)], LLSTRING(observe_description)], +{ + [false] call FUNC(keyDown) +}, { + false +}, [DIK_Q, [false, false, false]]] call CBA_fnc_addKeybind; + +["ACE3 Vehicles", QGVAR(override), [format ["%1 - %2", LLSTRING(displayName), LLSTRING(override)], LLSTRING(override_description)], +{ + [true] call FUNC(keyDown) +}, { + false +}, [DIK_E, [false, false, false]]] call CBA_fnc_addKeybind; diff --git a/addons/hunterkiller/XEH_preInit.sqf b/addons/hunterkiller/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/hunterkiller/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/hunterkiller/XEH_preStart.sqf b/addons/hunterkiller/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/hunterkiller/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/hunterkiller/config.cpp b/addons/hunterkiller/config.cpp new file mode 100644 index 0000000000..ff31bbede3 --- /dev/null +++ b/addons/hunterkiller/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/hunterkiller/functions/fnc_keydown.sqf b/addons/hunterkiller/functions/fnc_keydown.sqf new file mode 100644 index 0000000000..8e2255739a --- /dev/null +++ b/addons/hunterkiller/functions/fnc_keydown.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Slew keybind pressed + * + * Arguments: + * 0: Override if true, Observe if false + * + * Return Value: + * None + * + * Example: + * [true] call ace_hunterkiller_fnc_keydown + * + * Public: No + */ + +if ( + (GVAR(mode) == MODE_NO_ACTIONS) + || {!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))} + || {isTurnedOut ACE_player} +) exitWith { + false +}; + +params ["_modeOverride"]; +TRACE_1("keydown",_modeOverride); +if ((_modeOverride) && {!(GVAR(mode) in [MODE_OVERRIDE, MODE_OBSERVE_AND_OVERRIDE])}) exitWith { false }; +if ((!_modeOverride) && {!(GVAR(mode) in [MODE_OBSERVE, MODE_OBSERVE_AND_OVERRIDE])}) exitWith { false }; + +private _vehicle = vehicle ACE_player; +private _playerTurret = _vehicle unitTurret ACE_player; + +private _sourceTurret = [GVAR(targetTurret), _playerTurret] select _modeOverride; +private _puppetTurret = [_playerTurret, GVAR(targetTurret)] select _modeOverride; +TRACE_3("",_modeOverride,_sourceTurret,_puppetTurret); + +private _eyePos = eyePos _vehicle; +private _lookDir = if ((getNumber (([_vehicle, _sourceTurret] call CBA_fnc_getTurret) >> "primaryObserver")) == 1) then { + TRACE_1("using commander",_sourceTurret); + // CBA_fnc_turretDir fails on "CUP_B_M1A2SEP_TUSK_II_NATO", but eyeDirection should be correct on commander turrets + eyeDirection _vehicle +} else { + ([1] + ([_vehicle, _sourceTurret] call CBA_fnc_turretDir)) call CBA_fnc_polar2vect +}; +private _lookPoint = _eyePos vectorAdd (_lookDir vectorMultiply 5000); + +TRACE_1("sending event",_lookDir); +[QGVAR(slew), [_vehicle, _puppetTurret, _lookPoint, _modeOverride], _vehicle, _puppetTurret] call CBA_fnc_turretEvent; + +playSound "ACE_Sound_Click"; + +true // return (key used) diff --git a/addons/hunterkiller/functions/fnc_slew.sqf b/addons/hunterkiller/functions/fnc_slew.sqf new file mode 100644 index 0000000000..11c53001e5 --- /dev/null +++ b/addons/hunterkiller/functions/fnc_slew.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Slews turret to target pos and shows visual feedback + * + * Arguments: + * 0: Vehicle + * 1: Turret (will be local) + * 2: Look PosASL + * 3: Override + * + * Return Value: + * None + * + * Example: + * [vehicle, [0], [0,0,0], true] call ace_hunterkiller_fnc_slew + * + * Public: No + */ + +params ["_vehicle", "_turret", "_posASL", "_isOverride"]; +TRACE_4("slew",_vehicle,_turret,_posASL,_isOverride); + +_vehicle lockCameraTo [_posASL, _turret, true]; + +if (hasInterface && {(_vehicle turretUnit _turret) isEqualTo ace_player}) then { + private _displayText = if (_isOverride) then { LLSTRING(override) } else { LLSTRING(observe) }; + QGVAR(text) cutText [format ["




[%1]", _displayText], "PLAIN", -1, false, true]; + [{ + QGVAR(text) cutText ["", "PLAIN"]; + }, [], 1] call CBA_fnc_waitAndExecute; +}; diff --git a/addons/hunterkiller/functions/fnc_turretChangedEH.sqf b/addons/hunterkiller/functions/fnc_turretChangedEH.sqf new file mode 100644 index 0000000000..2bc00fc26f --- /dev/null +++ b/addons/hunterkiller/functions/fnc_turretChangedEH.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Turret changed event handler. Determine if in a master turret + * + * Arguments: + * 0: Unit + * 1: Turret + * + * Return Value: + * None + * + * Example: + * [player, [0]] call ace_hunterkiller_fnc_turretChangedEH + * + * Public: No + */ + +params ["_player", "_playerTurret"]; +TRACE_2("turretChangedEH",_player,_playerTurret); + +GVAR(mode) = 0; +GVAR(targetTurret) = []; + +if (_playerTurret isEqualTo []) exitWith {}; +private _vehicle = vehicle _player; +private _config = configOf _vehicle; + +// setVar can be real array or true/false +private _hkArray = _vehicle getVariable [QUOTE(ADDON), nil]; +if (isNil "_hkArray") then { + _hkArray = if (isArray (_config >> QUOTE(ADDON))) then { + getArray (_config >> QUOTE(ADDON)) + } else { + ((getNumber (_config >> QUOTE(ADDON))) == 1) + }; +}; +if (_hkArray isEqualTo true) then { _hkArray = [[[0], 1], [[0,0], 3]]; }; +if (_hkArray isEqualTo false) then { _hkArray = []; }; + +TRACE_1("",_hkArray); +if ((count _hkArray) != 2) exitWith {}; + +{ + _x params ["_xTurret", "_xMode"]; + TRACE_2("x",_playerTurret,_xTurret); + if (_xTurret isEqualTo _playerTurret) exitWith { + TRACE_3("seat active",typeOf _vehicle,_xTurret,_xMode); + GVAR(mode) = _xMode; + GVAR(targetTurret) = _hkArray # ((_forEachIndex + 1) % 2) # 0; + }; +} forEach _hkArray; diff --git a/addons/hunterkiller/script_component.hpp b/addons/hunterkiller/script_component.hpp new file mode 100644 index 0000000000..75f4a0ead5 --- /dev/null +++ b/addons/hunterkiller/script_component.hpp @@ -0,0 +1,14 @@ +#define COMPONENT hunterkiller +#define COMPONENT_BEAUTIFIED Hunter Killer +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#include "\z\ace\addons\main\script_macros.hpp" + +#define MODE_NO_ACTIONS 0 +#define MODE_OBSERVE 1 +#define MODE_OVERRIDE 2 +#define MODE_OBSERVE_AND_OVERRIDE 3 diff --git a/addons/hunterkiller/stringtable.xml b/addons/hunterkiller/stringtable.xml new file mode 100644 index 0000000000..5d42659329 --- /dev/null +++ b/addons/hunterkiller/stringtable.xml @@ -0,0 +1,65 @@ + + + + + Hunter Killer + 헌터 킬러 + Hunter Killer + Hunter Killer + ハンターキラー + Hunter Killer + Hunter Killer + Hunter Killer + Hunter Killer + Hunter Killer + + + Override + 오버라이드 + Указать + Anular + オーバーライド + Nadpisanie + Überschreibe + Sovrascrivi + Surcharge + Sobrescrever + + + Force other turret to slew onto your viewpoint + 다른 포탑이 시야에 오도록 강제합니다. + Повернуть другую турель туда, куда смотрит твоя + Forzar otra torreta a dirigirse hacia tu zona de apuntado. + 他のタレットを強制的に自分の視点に旋回させる + Obróć drugą wieżyczkę w kierunku, w którym zwrócona jest twoja wieżyczka. + Zwingt andere Türme, sich auf deine Blickrichtung zu drehen + Costringe altre torrette a puntare dove è puntata la tua. + Force une autre tourelle à s'aligner sur votre point de vue. + Força outra torreta a alinhar-se com o seu ponto de vista. + + + Observe + 관측 + Наблюдать + Observar + オブザーブ + Obserwowanie + Observiere + Osserva + Observation + Observar + + + Slew your turret onto other turret's viewpoint + 포탑을 다른 포탑의 시야에 놓습니다. + Повернуть свою турель туда, куда смотрит другая + Dirigir tu propia torreta hacia la zona de apuntado de otra torreta. + 自分のタレットを相手のタレットの視点に旋回させる。 + Obróć swoją wieżyczkę tam, gdzie patrzy druga. + Richtet deinen Turm auf die Blickrichtung eines anderen Turms + Punta la tua torretta nella direzione di un'altra torretta. + Aligne votre tourelle sur le point de vue d'une autre tourelle. + Alinhe a sua torreta com o ponto de vista de outra torreta. + + + diff --git a/addons/huntir/CfgAmmo.hpp b/addons/huntir/CfgAmmo.hpp index a9cd260d0f..8766795d9f 100644 --- a/addons/huntir/CfgAmmo.hpp +++ b/addons/huntir/CfgAmmo.hpp @@ -5,6 +5,9 @@ class CfgAmmo { lightColor[] = {0, 0, 0, 0}; smokeColor[] = {0, 0, 0, 0}; timeToLive = 6; + class Eventhandlers { + fired = QUOTE(call FUNC(handleFired)); + }; }; class ShellBase; diff --git a/addons/huntir/CfgEventhandlers.hpp b/addons/huntir/CfgEventhandlers.hpp index becf395052..6c29240403 100644 --- a/addons/huntir/CfgEventhandlers.hpp +++ b/addons/huntir/CfgEventhandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/huntir/CfgMagazineWells.hpp b/addons/huntir/CfgMagazineWells.hpp index 2d336054df..4bd116e7a8 100644 --- a/addons/huntir/CfgMagazineWells.hpp +++ b/addons/huntir/CfgMagazineWells.hpp @@ -4,5 +4,5 @@ class CfgMagazineWells { }; class UGL_40x36 { //Vanilla and RHS [rhsusf\addons\rhsusf_c_weapons\cfgMagazineWells.hpp] ADDON[] = {"ACE_HuntIR_M203"}; - }; + }; }; diff --git a/addons/huntir/CfgVehicles.hpp b/addons/huntir/CfgVehicles.hpp index cf6c98904a..2a30cec6fa 100644 --- a/addons/huntir/CfgVehicles.hpp +++ b/addons/huntir/CfgVehicles.hpp @@ -24,10 +24,10 @@ class CfgVehicles { displayName = "HuntIR"; model = QPATHTOF(data\huntir.p3d); scope = 1; - soundCrash[] = {"", db-30, 1 }; + soundCrash[] = {"", "db-30", 1 }; soundEnviron[] = {"z\ace\addons\apl\sounds\padak_let", 0.316228, 1, 80}; - soundLandCrash[] = {"", db-30, 1 }; - soundWaterCrash[] = {"", db10, 1 }; + soundLandCrash[] = {"", "db-30", 1 }; + soundWaterCrash[] = {"", "db-10", 1 }; class HitPoints { class HitEngine { armor = 0; @@ -73,7 +73,7 @@ class CfgVehicles { class ReammoBox_F; class ACE_HuntIR_Box: ReammoBox_F { model = QPATHTOF(data\ace_huntirbox.p3d); - displayName = $STR_DN_ACE_HUNTIRBOX; + displayName = CSTRING(TransportBox_DisplayName); class TransportItems { MACRO_ADDITEM(ACE_HuntIR_monitor,5); }; diff --git a/addons/huntir/CfgWeapons.hpp b/addons/huntir/CfgWeapons.hpp index 7cda0e7066..666e09bd84 100644 --- a/addons/huntir/CfgWeapons.hpp +++ b/addons/huntir/CfgWeapons.hpp @@ -10,6 +10,7 @@ class CfgWeapons { picture = QPATHTOF(UI\w_huntir_monitor_ca.paa); descriptionShort = CSTRING(monitor_displayName); model = QPATHTOF(data\ace_huntir_monitor.p3d); + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 20; diff --git a/addons/huntir/Dialog.hpp b/addons/huntir/Dialog.hpp index 17578bbb3e..e6cc28e327 100644 --- a/addons/huntir/Dialog.hpp +++ b/addons/huntir/Dialog.hpp @@ -60,37 +60,37 @@ class GVAR(cam_dialog) { idd = 18880; - movingEnable = true; + movingEnable = 1; controlsBackground[] = { }; objects[] = { }; controls[] = { - TOP_BORDER, - BOTTOM_BORDER, - LEFT_BORDER, - RIGHT_BORDER, - //HELP_DIALOG, - CAM_BG, - CAM_HEIGHT, - CAM_ALT, - CAM_No, - CAM_NO_x, - CAM_TIME_REMAIN, - CAM_TIME, - CAM_ZOOM, - ZOOM_X, - CAM_POS, - CAM_POS_X, - CAM_DIR, - CAM_DIR_x + "TOP_BORDER", + "BOTTOM_BORDER", + "LEFT_BORDER", + "RIGHT_BORDER", + //"HELP_DIALOG", + "CAM_BG", + "CAM_HEIGHT", + "CAM_ALT", + "CAM_No", + "CAM_NO_x", + "CAM_TIME_REMAIN", + "CAM_TIME", + "CAM_ZOOM", + "ZOOM_X", + "CAM_POS", + "CAM_POS_X", + "CAM_DIR", + "CAM_DIR_x" }; class TOP_BORDER { idc = -1; type = CT_STATIC; style = ST_CENTER; - x = __XA; - y = __Y; - w = __WA; + x = QUOTE(__XA); + y = QUOTE(__Y); + w = QUOTE(__WA); h = 0.08; font = FontM; sizeEx = 0.04; @@ -100,17 +100,17 @@ class GVAR(cam_dialog) { blinkingPeriod = 0; }; class BOTTOM_BORDER: TOP_BORDER { - y = __Y + __H - 0.05; + y = QUOTE(__Y + __H - 0.05); h = 0.05; }; class LEFT_BORDER: TOP_BORDER { - w = (abs(__XA) - abs(__X)) + 0.05; - h = __H; + w = QUOTE((abs(__XA) - abs(__X)) + 0.05); + h = QUOTE(__H); }; class RIGHT_BORDER: TOP_BORDER { - x = __X + __W - 0.05; - w = (__WA - __W) + 0.05; - h = __H; + x = QUOTE(__X + __W - 0.05); + w = QUOTE((__WA - __W) + 0.05); + h = QUOTE(__H); }; class HELP_DIALOG { idc = -1; @@ -135,8 +135,10 @@ class GVAR(cam_dialog) { soundPush[] = { "buttonpushed.ogg", 0.1, 1 }; soundClick[] = { "", 0, 1 }; soundEscape[] = { "", 0, 1 }; - x = __X + (2*0.8); y = __Y + 0.045; - w = 0.05; h = 0.02; + x = QUOTE(__X + (2*0.8)); + y = QUOTE(__Y + 0.045); + w = 0.05; + h = 0.02; text = CSTRING(HELP); action = QUOTE(createDialog QQGVAR(help_dialog)); }; @@ -149,10 +151,10 @@ class GVAR(cam_dialog) { font = "RobotoCondensed"; sizeEx = 0.021; lineSpacing = 1; - x = __X; - y = __Y + 0.08; - w = __W; - h = __H + 0.2; + x = QUOTE(__X); + y = QUOTE(__Y + 0.08); + w = QUOTE(__W); + h = QUOTE(__H + 0.2); border = 0; text = QPATHTOF(UI\ace_huntir_monitor_on.paa); }; @@ -164,65 +166,65 @@ class GVAR(cam_dialog) { colorText[] = {1, 1, 1, 1}; font = FontM; sizeEx = 0.02; - x = __X + 0.42; - y = __Y + 0.32; + x = QUOTE(__X + 0.42); + y = QUOTE(__Y + 0.32); w = 0.08; h = 0.04; text = ""; blinkingPeriod = 0; }; class CAM_ALT: CAM_HEIGHT { - x = __X + 0.35; + x = QUOTE(__X + 0.35); text = CSTRING(ALT); }; class CAM_No: CAM_HEIGHT { - x = __X + __W - 0.64; + x = QUOTE(__X + __W - 0.64); text = CSTRING(CAM); }; class CAM_NO_x: CAM_HEIGHT { idc = 2; - x = __X + __W - 0.56; - y = __Y + 0.32; + x = QUOTE(__X + __W - 0.56); + y = QUOTE(__Y + 0.32); text = ""; }; class CAM_TIME: CAM_HEIGHT { - x = __X + 0.35; - y = __Y + __H - 0.65; + x = QUOTE(__X + 0.35); + y = QUOTE(__Y + __H - 0.65); w = 0.12; text = CSTRING(TIME); }; class CAM_TIME_REMAIN: CAM_TIME { idc = 3; - x = __X + 0.46; + x = QUOTE(__X + 0.46); text = ""; }; class CAM_ZOOM: CAM_No { - y = __Y + 0.36; + y = QUOTE(__Y + 0.36); text = "Zoom:"; }; class ZOOM_X: CAM_ZOOM { idc = 4; - x = __X + __W - 0.56; + x = QUOTE(__X + __W - 0.56); text = ""; }; class CAM_POS: CAM_HEIGHT { - x = __X + 0.35; - y = __Y + 0.36; + x = QUOTE(__X + 0.35); + y = QUOTE(__Y + 0.36); text = "GPS Pos:"; }; class CAM_POS_X: CAM_POS { idc = 5; - x = __X + 0.42; + x = QUOTE(__X + 0.42); w = 0.16; text = ""; }; class CAM_DIR: CAM_POS { - y = __Y + 0.4; + y = QUOTE(__Y + 0.4); text = ""; //"Az:"; }; class CAM_DIR_x: CAM_DIR { idc = 6; - x = __X + 0.42; + x = QUOTE(__X + 0.42); w = 0.16; text = ""; }; @@ -231,14 +233,14 @@ class GVAR(cam_dialog) { class GVAR(cam_dialog_inactive): GVAR(cam_dialog) { idd = 18881; controls[] = { - TOP_BORDER, - BOTTOM_BORDER, - LEFT_BORDER, - RIGHT_BORDER, - //HELP_DIALOG, - //PRESS_HELP, - CAM_BG, - SEARCHING_CAM + "TOP_BORDER", + "BOTTOM_BORDER", + "LEFT_BORDER", + "RIGHT_BORDER", + //"HELP_DIALOG", + //"PRESS_HELP", + "CAM_BG", + "SEARCHING_CAM" }; class TOP_BORDER: TOP_BORDER {}; @@ -249,8 +251,8 @@ class GVAR(cam_dialog_inactive): GVAR(cam_dialog) { idc = -1; type = CT_STATIC; style = ST_LEFT; - x = __X + (__W - 0.2); - y = __Y + 0.06; + x = QUOTE(__X + (__W - 0.2)); + y = QUOTE(__Y + 0.06); w = 0.4; h = 0.02; font = FontM; @@ -264,8 +266,8 @@ class GVAR(cam_dialog_inactive): GVAR(cam_dialog) { idc = -1; type = CT_STATIC; style = ST_LEFT; - x = __X + (__W - 0.2); - y = __Y + 0.03; + x = QUOTE(__X + (__W - 0.2)); + y = QUOTE(__Y + 0.03); w = 0.4; h = 0.02; font = FontM; @@ -282,8 +284,8 @@ class GVAR(cam_dialog_inactive): GVAR(cam_dialog) { style = ST_LEFT; colorText[] = {1, 1, 1, 1}; colorBackground[] = {0,0,0,0}; - x = __X + (__W/2) - 0.07; - y = __Y + (__H/2); + x = QUOTE(__X + (__W/2) - 0.07); + y = QUOTE(__Y + (__H/2)); w = 0.6; h = 0.08; font = FontM; @@ -296,13 +298,13 @@ class GVAR(cam_dialog_inactive): GVAR(cam_dialog) { class GVAR(cam_dialog_off): GVAR(cam_dialog_inactive) { idd = 18882; controls[] = { - TOP_BORDER, - BOTTOM_BORDER, - LEFT_BORDER, - RIGHT_BORDER, - //HELP_DIALOG, - //PRESS_HELP, - CAM_BG + "TOP_BORDER", + "BOTTOM_BORDER", + "LEFT_BORDER", + "RIGHT_BORDER", + //"HELP_DIALOG", + //"PRESS_HELP", + "CAM_BG" }; class TOP_BORDER: TOP_BORDER {}; @@ -317,30 +319,30 @@ class GVAR(cam_dialog_off): GVAR(cam_dialog_inactive) { class GVAR(help_dialog): GVAR(cam_dialog) { idd = -1; controls[] = { - TOP_BORDER, - BOTTOM_BORDER, - LEFT_BORDER, - RIGHT_BORDER, - CAM_BG, - CAM_HEIGHT, - CAM_ALT, - CAM_TIME_REMAIN, - CAM_TIME, - CAM_ZOOM, - ZOOM_X, - CAM_POS, - CAM_POS_x, - CAM_No, - CAM_No_X, - CAM_DIR, - CAM_DIR_x, - HELP0, - HELP1, - HELP2, - HELP3, - HELP4, - HELP5, - HELP6 + "TOP_BORDER", + "BOTTOM_BORDER", + "LEFT_BORDER", + "RIGHT_BORDER", + "CAM_BG", + "CAM_HEIGHT", + "CAM_ALT", + "CAM_TIME_REMAIN", + "CAM_TIME", + "CAM_ZOOM", + "ZOOM_X", + "CAM_POS", + "CAM_POS_x", + "CAM_No", + "CAM_No_X", + "CAM_DIR", + "CAM_DIR_x", + "HELP0", + "HELP1", + "HELP2", + "HELP3", + "HELP4", + "HELP5", + "HELP6" }; class TOP_BORDER: TOP_BORDER {}; class BOTTOM_BORDER: BOTTOM_BORDER {}; @@ -363,8 +365,8 @@ class GVAR(help_dialog): GVAR(cam_dialog) { idc = -1; type = CT_STATIC; style = ST_LEFT; - x = __X + (__W - 0.3); - y = __Y + 0.03; + x = QUOTE(__X + (__W - 0.3)); + y = QUOTE(__Y + 0.03); w = 0.4; h = 0.03; font = FontM; @@ -375,27 +377,27 @@ class GVAR(help_dialog): GVAR(cam_dialog) { blinkingPeriod = 0; }; class HELP1: HELP0 { - y = __Y + 0.06; + y = QUOTE(__Y + 0.06); text = CSTRING(HELP_ZOOM); }; class HELP2: HELP0 { - y = __Y + 0.09; + y = QUOTE(__Y + 0.09); text = CSTRING(HELP_CAM); }; class HELP3: HELP0 { - y = __Y + 0.12; + y = QUOTE(__Y + 0.12); text = CSTRING(HELP_ROT); }; class HELP4: HELP0 { - y = __Y + 0.15; + y = QUOTE(__Y + 0.15); text = CSTRING(HELP_ELV); }; class HELP5: HELP0 { - y = __Y + 0.18; + y = QUOTE(__Y + 0.18); text = CSTRING(HELP_MOD); }; class HELP6: HELP0 { - y = __Y + 0.21; + y = QUOTE(__Y + 0.21); text = CSTRING(HELP_RES); }; }; diff --git a/addons/huntir/README.md b/addons/huntir/README.md index b6c8128cbc..66b837c8d9 100644 --- a/addons/huntir/README.md +++ b/addons/huntir/README.md @@ -2,10 +2,3 @@ ace_huntir =========== Adds High-altitude Unit Navigated Tactical Imaging Round and its Monitor. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/huntir/RscTitles.hpp b/addons/huntir/RscTitles.hpp index e93eb9b508..90cb32bbad 100644 --- a/addons/huntir/RscTitles.hpp +++ b/addons/huntir/RscTitles.hpp @@ -3,18 +3,21 @@ class RscTitles { class GVAR(cam_rose) { idd=-1; - movingEnable = true; + movingEnable = 1; fadein = 0; fadeout = 1; duration = 1e+011; name=QGVAR(cam_rose); - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(cam_rose), _this select 0)]); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(cam_rose),_this select 0)]); class controls { class CHAR_N { type = 0; idc = 64432; style = 0; - x = 0.497;y = 0.297;w = 0.2;h = 0.2; + x = 0.497; + y = 0.297; + w = 0.2; + h = 0.2; font = "RobotoCondensed"; sizeEx = __FONTHEIGHT; colorText[] = {1, 1, 1, 1}; @@ -23,17 +26,20 @@ class RscTitles { }; class CHAR_E: CHAR_N { idc = 64433; - x = 0.697;y = 0.497; + x = 0.697; + y = 0.497; text = "E"; }; class CHAR_S: CHAR_N { idc = 64434; - x = 0.497;y = 0.697; + x = 0.497; + y = 0.697; text = "S"; }; class CHAR_W: CHAR_N { idc = 64435; - x = 0.297;y = 0.497; + x = 0.297; + y = 0.497; text = "W"; }; }; diff --git a/addons/huntir/XEH_postInit.sqf b/addons/huntir/XEH_postInit.sqf index 1f6a39056b..c68252af3b 100644 --- a/addons/huntir/XEH_postInit.sqf +++ b/addons/huntir/XEH_postInit.sqf @@ -8,8 +8,4 @@ GVAR(cur_cam) = 0; GVAR(ROTATE) = 0; GVAR(ELEVAT) = 0.01; -// Register fire event handler -// Don't run for non players, as they are too dumb to launch huntirs anyway -["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_huntir", {!GETMVAR(GVAR(stop),true)}] call CBA_fnc_registerFeatureCamera; diff --git a/addons/huntir/config.cpp b/addons/huntir/config.cpp index 89992d5f52..4e9f5952cc 100644 --- a/addons/huntir/config.cpp +++ b/addons/huntir/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_HuntIR", "ACE_HuntIRBox"}; + units[] = {"ACE_HuntIR", "ACE_HuntIR_Box", "ACE_Item_HuntIR_monitor"}; weapons[] = {"ACE_HuntIR_monitor"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; diff --git a/addons/huntir/functions/fnc_cam.sqf b/addons/huntir/functions/fnc_cam.sqf index ca027b23ab..411dbfe30e 100644 --- a/addons/huntir/functions/fnc_cam.sqf +++ b/addons/huntir/functions/fnc_cam.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * @@ -77,8 +77,7 @@ GVAR(no_cams) sort true; if (((getPosVisual _x) select 2) > 20 && {!(_x in GVAR(no_cams))} && {_x getHitPointDamage "HitCamera" < 0.25}) then { GVAR(no_cams) pushBack _x; }; - true - } count GVAR(nearHuntIRs); + } forEach GVAR(nearHuntIRs); { if (((getPosVisual _x) select 2) <= 20 || {!(_x in GVAR(nearHuntIRs))} || {_x getHitPointDamage "HitCamera" >= 0.25}) then { GVAR(no_cams) deleteAt _forEachIndex; @@ -145,7 +144,7 @@ GVAR(no_cams) sort true; GVAR(cam) camCommit 0; ctrlSetText [1, format["%1 m", round(GVAR(pos) select 2)]]; - ctrlSetText [2, format["%1", GVAR(cur_cam) + 1]]; + ctrlSetText [2, str (GVAR(cur_cam) + 1)]; private _cam_time = CBA_missionTime - (GVAR(huntIR) getVariable [QGVAR(startTime), CBA_missionTime]); ctrlSetText [3, format["%1 s", round(_cam_time)]]; private _cam_pos = getPosVisual GVAR(huntIR); diff --git a/addons/huntir/functions/fnc_handleFired.sqf b/addons/huntir/functions/fnc_handleFired.sqf index 42c6bf3c84..5c7c3aca63 100644 --- a/addons/huntir/functions/fnc_handleFired.sqf +++ b/addons/huntir/functions/fnc_handleFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * @@ -16,12 +16,11 @@ * Public: No */ -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +params ["_unit", "", "", "", "", "", "_projectile"]; +TRACE_2("handleFired",_unit,_projectile); -if (_ammo != "F_HuntIR") exitWith {}; - -if (!hasInterface) exitWith {}; +// Don't run for non players, as they are too dumb to launch huntirs anyway +if (_unit != ACE_player) exitWith {}; [{ params ["_projectile"]; diff --git a/addons/huntir/functions/fnc_huntir.sqf b/addons/huntir/functions/fnc_huntir.sqf index 221bc5ccec..60b7a1fc14 100644 --- a/addons/huntir/functions/fnc_huntir.sqf +++ b/addons/huntir/functions/fnc_huntir.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * diff --git a/addons/huntir/functions/fnc_huntirCompass.sqf b/addons/huntir/functions/fnc_huntirCompass.sqf index 9a7882f45c..8dac53b41b 100644 --- a/addons/huntir/functions/fnc_huntirCompass.sqf +++ b/addons/huntir/functions/fnc_huntirCompass.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * diff --git a/addons/huntir/functions/fnc_keyPressed.sqf b/addons/huntir/functions/fnc_keyPressed.sqf index edfa39c534..70f9e75afc 100644 --- a/addons/huntir/functions/fnc_keyPressed.sqf +++ b/addons/huntir/functions/fnc_keyPressed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Norrin, Rocko * Handles the HuntIR monitor key interaction diff --git a/addons/huntir/functions/script_component.hpp b/addons/huntir/functions/script_component.hpp deleted file mode 100644 index 29e0fbff41..0000000000 --- a/addons/huntir/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\huntir\script_component.hpp" \ No newline at end of file diff --git a/addons/huntir/stringtable.xml b/addons/huntir/stringtable.xml index 1948a6c4b8..74e68b6432 100644 --- a/addons/huntir/stringtable.xml +++ b/addons/huntir/stringtable.xml @@ -1,7 +1,7 @@ - + HuntIR Transport Box HuntIR Transportkiste Caja de transporte de HuntIR @@ -13,11 +13,12 @@ HuntIR Transport Box Caixa de transporte do HuntIR HuntIR 輸送箱 - HuntIR 수송함 + 헌트IR 운반함 高空战术摄像头运输箱 高空戰術成像器運輸箱 + HuntIR Taşıma Kutusu - + HuntIR Round HuntIR Granate Proyectil HuntIR @@ -25,31 +26,33 @@ HuntIR снаряд Colpo HuntIR Nabój HuntIR - Munition HuntIR + Projectile HuntIR HuntIR lövedék Cartucho HuntIR - HuntIR 弾頭 - HuntIR 유탄 + HuntIR弾 + 헌트IR 유탄 高空战术摄像头弹药 高空戰術成像器彈藥 + HuntIR Mermisi - - HuntIR monitor + + HuntIR Monitor HuntIR Monitor Monitor HuntIR - HuntIR monitor + HuntIR Monitor HuntIR монитор Monitor HuntIR Odbiornik HuntIR Ecran HuntIR - HuntIR monitor + HuntIR Monitor Monitor HuntIR - HuntIR モニタ - HuntIR 모니터 + HuntIR モニター + 헌트IR 모니터 高空战术摄像头显示面板 高空戰術成像器顯示面板 + HuntIR Ekranı - + Activate HuntIR monitor HuntIR Monitor aktivieren Activar monitor HuntIR @@ -61,11 +64,12 @@ HuntIR monitor aktiválása Ativar monitor do HuntIR HuntIR を起動する - HuntIR 모니터 켜기 + 헌트IR 모니터 켜기 开启高空战术摄像头显示面板 開啟高空戰術成像器顯示面板 + HuntIR Ekranı Aktif - + Camera: Kamera: Camara: @@ -78,10 +82,11 @@ Câmera: カメラ: 카메라: - 摄像头: + 摄像头: 攝影機: + Kamera: - + Altitude: Höhe: Altitud: @@ -94,10 +99,11 @@ Altitude: 高度: 고도: - 高度: + 高度: 高度: + Yükseklik: - + Recording Time: Aufnahmezeit: Tiempo de grabación: @@ -108,12 +114,13 @@ Temps d'enregistrement : Felvételi idő: Tempo de gravação: - 録画時間: + 記録時間: 녹화시간: - 记录时间: + 记录时间: 記錄時間: + Kayıt süresi: - + Press ESC to quit camera Zum Verlassen ESC drücken Pulsar ESC para salir de la camara @@ -121,15 +128,16 @@ Нажмите ESC чтобы выйти из режима камеры Premi ESC per uscire dalla telecamera Wciśnij ESC by wyjść z widoku kamery - Appuyer sur ESC pour quitter la camera + Appuyez sur ESC pour quitter la camera. Nyomj ESC-ket a kamerából való kilépéshez Pressione ESC para sair da câmera ESC を押しカメラを抜ける ESC를 눌러 카메라 나가기 - 按下ESC退出摄像头 + 按下 ESC 退出摄像头 按下ESC退出攝影機 + ESC'ye basarak çıkış yap - + Help Hilfe Ayuda @@ -144,8 +152,9 @@ 도움말 帮助 幫助 + Yardım - + A/D - Cycle zoom A/D - Zoom A/D - Cambiar zoom @@ -158,10 +167,11 @@ A/D - Troca zoom A/D - 倍率の変更 A/D - 줌 전환 - A/D - 切换放大倍率 + A/D—切换放大倍率 A/D - 切換放大倍率 + A/D Uzaklığı değiştir - + W/S - Select camera W/S - Wähle Kamera W/S - Seleccionar camara @@ -174,42 +184,45 @@ W/S - Seleciona câmera W/S - カメラを選択 W/S - 카메라 선택 - W/S - 切换摄像头 + W/S—切换摄像头 W/S - 切換攝影機 + W/S- Kamerayı seç - + Left/Right - Rotate camera Links/Rechts - Rotiere Kamera Left/Right - Rotar camara Levá/Pravá - Rotace kamery Влево/Вправо - Вращать камеру - Left/Right - Ruota telecamera + Sinistra/Destra - Ruota telecamera Lewo/Prawo - obrót kamery w poziomie Gauche/Droite - Rotation de la caméra Jobb/Bal - Kamera forgatás Esquerda/Direita - Rotaciona câmera - Left/Right - カメラ回転 + Left/Right - カメラの回転 좌/우 - 카메라 돌리기 - 左/右 - 旋转摄像头 + 左/右—旋转摄像头 左/右 - 旋轉攝影機 + Sol/Sağ Kamerayı döndür - + Up/Down - Elevate/lower camera Hoch/Runter - Neige Kamera Up/Down - Subir/bajar camara Nahoru/Dolu - Zvýšít/snížit úhel pohledu kamery - Вверх/Вниз - Поднять/Опустить камеру - Up/Down - Alza/abbassa telecamera + Вверх/Вниз - Поднять/опустить камеру + Su/Giù - Alza/abbassa telecamera Góra/Dół - obrót kamery w pionie Haut/Bas - Monter/descendre la caméra Fel/Le - Kamera döntése/süllyesztése Acima/Abaixo - Eleva/Abaixa a câmera - Up/Down - カメラ角度を変更 + Up/Down - カメラの角度 상/하 카메라 올리기/내리기 - 上/下 - 上升/下降摄像头 + 上/下—上升/下降摄像头 上/下 - 上升/下降攝影機 + Yukarı/Asağı- Kamerayı yukarı aşağı oynat - + N - Cycle IT modes N - Sichtmodi N - Cambiar modos de IT @@ -222,10 +235,11 @@ N - Troca modo IT N - IT モードを変更 N - IT모드 순환 - N - 切换热显模式 + N—切换热显模式 N - 切換熱顯模式 + N- IT modülünü değiştir - + R - Reset camera R - Kamera zurücksetzen R - Reiniciar camara @@ -238,24 +252,26 @@ R - Redefine a câmera R - カメラを初期化 R - 카메라 초기화 - R - 重置摄像头 + R—重置摄像头 R - 重置攝影機 + R- Kamerayı sıfırla - + Esc - Exit help ESC - Hilfe verlassen - Esc - Salit de ayuda + Esc - Salir del menú de ayuda Esc - Ukončit pomoc Esc - Выйти из помощи - Esc - Chiudi aiuto + Esc - Aiuto dal Menù Esc - wyjście z ekranu Pomocy Esc - Sortir de l'aide Exit - Kilépés a súgóból Esc - Sai do Ajuda - Esc - ヘルプ終了 + Esc - ヘルプを閉じる Esc - 도움말 나가기 - Esc - 离开帮助 + Esc—离开帮助 Esc - 離開幫助 + Esc- Çıkış Yardım diff --git a/addons/huntir/subConfig/config.cpp b/addons/huntir/subConfig/config.cpp index 29a9f0ca25..a75b34f253 100644 --- a/addons/huntir/subConfig/config.cpp +++ b/addons/huntir/subConfig/config.cpp @@ -1,9 +1,8 @@ -#include "\z\ace\addons\huntir\script_component.hpp" -#undef COMPONENT -#define COMPONENT huntir_sub +#define SUBCOMPONENT sub +#include "..\script_component.hpp" class CfgPatches { - class ADDON { + class SUBADDON { name = COMPONENT_NAME; units[] = {}; weapons[] = {}; @@ -12,6 +11,8 @@ class CfgPatches { author = ECSTRING(common,ACETeam); url = ECSTRING(main,URL); VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); }; }; diff --git a/addons/intelitems/$PBOPREFIX$ b/addons/intelitems/$PBOPREFIX$ new file mode 100644 index 0000000000..0ff9becd8a --- /dev/null +++ b/addons/intelitems/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\intelitems diff --git a/addons/intelitems/CfgEditorSubcategories.hpp b/addons/intelitems/CfgEditorSubcategories.hpp new file mode 100644 index 0000000000..3fca5e183e --- /dev/null +++ b/addons/intelitems/CfgEditorSubcategories.hpp @@ -0,0 +1,5 @@ +class CfgEditorSubcategories { + class XADDON { + displayName = CSTRING(Category); + }; +}; diff --git a/addons/intelitems/CfgEventHandlers.hpp b/addons/intelitems/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/intelitems/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/intelitems/CfgMagazines.hpp b/addons/intelitems/CfgMagazines.hpp new file mode 100644 index 0000000000..75d1ca29ee --- /dev/null +++ b/addons/intelitems/CfgMagazines.hpp @@ -0,0 +1,41 @@ +class CfgMagazines { + class CA_Magazine; + class GVAR(base): CA_Magazine { + count = 1; + mass = 0.1; + ACE_isUnique = 1; + GVAR(intel) = 1; + GVAR(control) = ""; + scopeArsenal = 0; + }; + + class XGVAR(notepad): GVAR(base) { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeArsenal = 2; // Allows players to access from arsenal + displayName = CSTRING(Notepad_DisplayName); + descriptionShort = CSTRING(Notepad_Description); + picture = QPATHTOF(ui\notepad_ca.paa); + model = "\a3\structures_f\items\documents\notepad_f.p3d"; + GVAR(control) = QGVAR(RscNotepad); + ACE_isTool = 1; + }; + + class XGVAR(document): GVAR(base) { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Document_DisplayName); + descriptionShort = CSTRING(Document_Description); + picture = QPATHTOF(ui\document_ca.paa); + model = "\a3\structures_f\items\documents\file2_f.p3d"; + GVAR(control) = QGVAR(RscDocument); + }; + + class XGVAR(photo): GVAR(base) { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Photo_DisplayName); + descriptionShort = CSTRING(Photo_Description); + picture = QPATHTOF(ui\photo_ca.paa); + model = "\a3\structures_f\items\documents\filephotos_f.p3d"; + GVAR(control) = QGVAR(RscPhoto); + }; +}; diff --git a/addons/intelitems/CfgVehicles.hpp b/addons/intelitems/CfgVehicles.hpp new file mode 100644 index 0000000000..81a0917406 --- /dev/null +++ b/addons/intelitems/CfgVehicles.hpp @@ -0,0 +1,83 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ADDON { + displayName = CSTRING(DisplayName); + condition = QUOTE(visibleMap); + exceptions[] = {"isNotInside", "notOnMap"}; + statement = ""; + insertChildren = QUOTE(_player call FUNC(addActions)); + icon = ""; + }; + }; + }; + + class ThingX; + class GVAR(base): ThingX { + XEH_ENABLED; + icon = "iconObject_2x3"; + mapSize = 0.3; + simulation = "House"; // Needed because the objects don't have good collision physx + destrType = "DesturctNo"; + curatorInfoTypeEmpty = QGVAR(RscSetData); + editorSubcategory = QUOTE(XADDON); + GVAR(magazine) = ""; + class Attributes { + class GVAR(data) { + displayName = CSTRING(Text); + property = QGVAR(data); + control = "EditMulti5"; + expression = QUOTE([ARR_2(_this,_value)] call FUNC(setObjectData)); + defaultValue = "''"; + validate = "STRING"; + typeName = "STRING"; + }; + }; + class ACE_Actions { + class GVAR(pickup) { + displayName = CSTRING(Pickup); + icon = "\a3\ui_f\data\igui\cfg\actions\take_ca.paa"; + distance = 2; + condition = QUOTE(_this call FUNC(canPickup)); + statement = QUOTE(_this call FUNC(pickup)); + }; + }; + }; + + class XGVAR(notepad): GVAR(base) { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Notepad_DisplayName); + model = "\a3\structures_f\items\documents\notepad_f.p3d"; + editorPreview = "\a3\editorpreviews_f\data\cfgvehicles\land_notepad_f.jpg"; + scope = 2; + scopeCurator = 2; + GVAR(magazine) = QXGVAR(notepad); + }; + + class XGVAR(document): GVAR(base) { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Document_DisplayName); + model = "\a3\structures_f\items\documents\file2_f.p3d"; + editorPreview = "\a3\editorpreviews_f\data\cfgvehicles\intel_file2_f.jpg"; + scope = 2; + scopeCurator = 2; + GVAR(magazine) = QXGVAR(document); + }; + + class XGVAR(photo): GVAR(base) { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Photo_DisplayName); + model = "\a3\structures_f\items\documents\filephotos_f.p3d"; + editorPreview = "\a3\editorpreviews_f\data\cfgvehicles\land_filephotos_f.jpg"; + scope = 2; + scopeCurator = 2; + GVAR(magazine) = QXGVAR(photo); + class Attributes: Attributes { + class GVAR(data): GVAR(data) { + displayName = CSTRING(Photo_Filename); + control = "Edit"; + }; + }; + }; +}; diff --git a/addons/intelitems/README.md b/addons/intelitems/README.md new file mode 100644 index 0000000000..0149937739 --- /dev/null +++ b/addons/intelitems/README.md @@ -0,0 +1,7 @@ +ace_intelitems +=============== + +Implements an intel system with unique items. + +## ACEX Conversion - things still using acex prefix +- All CfgWeapon Items (e.g. `acex_intelitems_notepad`) diff --git a/addons/intelitems/XEH_PREP.hpp b/addons/intelitems/XEH_PREP.hpp new file mode 100644 index 0000000000..cef76045d3 --- /dev/null +++ b/addons/intelitems/XEH_PREP.hpp @@ -0,0 +1,13 @@ +ACEX_PREP(addActions); +ACEX_PREP(addIntel); +ACEX_PREP(attributeFocus); +ACEX_PREP(canPickup); +ACEX_PREP(createControl); +ACEX_PREP(deleteControl); +ACEX_PREP(handleLoadout); +ACEX_PREP(handleMagIndex); +ACEX_PREP(onMouseButtonDown); +ACEX_PREP(onMouseButtonUp); +ACEX_PREP(onMouseMoving); +ACEX_PREP(pickup); +ACEX_PREP(setObjectData); diff --git a/addons/intelitems/XEH_postInit.sqf b/addons/intelitems/XEH_postInit.sqf new file mode 100644 index 0000000000..f416b3667e --- /dev/null +++ b/addons/intelitems/XEH_postInit.sqf @@ -0,0 +1,13 @@ +#include "script_component.hpp" + +// Only handle loadout change when on map or have open controls +["loadout", { + if (!visibleMap && {GVAR(controlsGroups) isEqualTo []}) exitWith {}; + call FUNC(handleLoadout); +}, true] call CBA_fnc_addPlayerEventHandler; + +// Check loadout when map is opened +["visibleMap", { + params ["", "_visibleMap"]; + if (_visibleMap) then {call FUNC(handleLoadout)}; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/intelitems/XEH_preInit.sqf b/addons/intelitems/XEH_preInit.sqf new file mode 100644 index 0000000000..ff09f6ea0e --- /dev/null +++ b/addons/intelitems/XEH_preInit.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +if (isServer) then { + // Master Count - only on server and needed before postInit + GVAR(intelCount) = 0; + + // Map of all magazine ids and their corresponding intel index + GVAR(intelMap) = [true] call CBA_fnc_createNamespace; + publicVariable QGVAR(intelMap); + + // Namespace of intel indices and their corresponding data + GVAR(intelData) = [true] call CBA_fnc_createNamespace; + publicVariable QGVAR(intelData); + + [QGVAR(handleMagIndex), LINKFUNC(handleMagIndex)] call CBA_fnc_addEventHandler; + [QGVAR(setObjectData), LINKFUNC(setObjectData)] call CBA_fnc_addEventHandler; +}; + +if (hasInterface) then { + // Array of all open controls groups + GVAR(controlsGroups) = []; + + // Hash to track controls group positions on map between closing + GVAR(controlsData) = [] call CBA_fnc_hashCreate; +}; + +ADDON = true; diff --git a/addons/intelitems/XEH_preStart.sqf b/addons/intelitems/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/intelitems/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/intelitems/config.cpp b/addons/intelitems/config.cpp new file mode 100644 index 0000000000..3b9b37b5b6 --- /dev/null +++ b/addons/intelitems/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = { + QXGVAR(notepad), + QXGVAR(document), + QXGVAR(photo) + }; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interact_menu", "ace_zeus"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror", "mharis001"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; + + BWC_CONFIG(XADDON); +}; + +#include "CfgEventHandlers.hpp" +#include "CfgEditorSubcategories.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "gui.hpp" diff --git a/addons/intelitems/functions/fnc_addActions.sqf b/addons/intelitems/functions/fnc_addActions.sqf new file mode 100644 index 0000000000..6b93a54eb1 --- /dev/null +++ b/addons/intelitems/functions/fnc_addActions.sqf @@ -0,0 +1,58 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Returns children actions for intel items in the player's inventory. + * + * Arguments: + * 0: Player + * + * Return Value: + * Actions + * + * Example: + * [player] call ace_intelitems_fnc_addActions + * + * Public: No + */ + +params ["_player"]; + +private _actions = []; + +private _cfgMagazines = configFile >> "CfgMagazines"; +private _magazines = magazines _player; + +private _openIndices = GVAR(controlsGroups) apply {_x getVariable QGVAR(index)}; + +{ + private _config = _cfgMagazines >> _x; + + if (getNumber (_config >> QGVAR(intel)) == 1) then { + private _displayName = getText (_config >> "displayName"); + private _picture = getText (_config >> "picture"); + private _controlType = getText (_config >> QGVAR(control)); + + private _magazineIds = [_player, _x] call CBA_fnc_getMagazineIndex; + + { + private _index = GVAR(intelMap) getVariable _x; + + // Only add actions for intel indices that are not open + if !(_index in _openIndices) then { + private _action = [ + format [QGVAR(%1), _index], + _displayName, + _picture, + {(_this select 2) call FUNC(createControl)}, + {true}, + {}, + [_controlType, _index] + ] call EFUNC(interact_menu,createAction); + + _actions pushBack [_action, [], _player]; + }; + } forEach _magazineIds; + }; +} forEach (_magazines arrayIntersect _magazines); + +_actions diff --git a/addons/intelitems/functions/fnc_addIntel.sqf b/addons/intelitems/functions/fnc_addIntel.sqf new file mode 100644 index 0000000000..a697afb5ef --- /dev/null +++ b/addons/intelitems/functions/fnc_addIntel.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Adds the given intel item (magazine) to the given unit. + * Must be called on the server. + * + * Arguments: + * 0: Unit + * 1: Item + * 2: Data + * + * Return Value: + * Successful + * + * Example: + * [_unit, "acex_intelitems_notepad", "Notes!"] call ace_intelitems_fnc_addIntel + * + * Public: Yes + */ + +if (canSuspend) exitWith { + [FUNC(addIntel), _this] call CBA_fnc_directCall; +}; + +params [["_unit", objNull, [objNull]], ["_item", "", [""]], ["_data", "", [""]]]; + +if ( + !isServer + || {!(_unit isKindOf "CAManBase")} + || {!(_unit canAdd _item)} + || {getNumber (configFile >> "CfgMagazines" >> _item >> QGVAR(intel)) != 1} +) exitWith { ERROR_1("addIntel failed - %1",_this); false }; + +// Add the magazine item to the unit's inventory and get its id +private _magazinesBefore = [_unit, _item] call CBA_fnc_getMagazineIndex; +_unit addMagazine [_item, 1]; +private _magazinesAfter = [_unit, _item] call CBA_fnc_getMagazineIndex; + +private _magazineId = _magazinesAfter - _magazinesBefore; +if (_magazineId isEqualTo []) exitWith {false}; + +// Assign an intel index to the added magazine id and set its data +private _index = [_magazineId select 0] call FUNC(handleMagIndex); +SET_DATA(_index,_data); + +true diff --git a/addons/intelitems/functions/fnc_attributeFocus.sqf b/addons/intelitems/functions/fnc_attributeFocus.sqf new file mode 100644 index 0000000000..592811ae09 --- /dev/null +++ b/addons/intelitems/functions/fnc_attributeFocus.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Initializes the Zeus attributes display for intel objects. + * + * Arguments: + * 0: Controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_intelitems_fnc_attributeFocus + * + * Public: No + */ + +params ["_control"]; + +private _display = ctrlParent _control; +private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK +private _object = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +private _ctrlLabel = _display displayCtrl IDC_ATTRIBUTE_LABEL; +private _labelText = getText ((configOf _object) >> "Attributes" >> QGVAR(data) >> "displayName"); +_ctrlLabel ctrlSetText _labelText; + +private _index = _object getVariable [QGVAR(index), -1]; + +if (_index != -1) then { + private _ctrlEdit = _display displayCtrl IDC_ATTRIBUTE_EDIT; + _ctrlEdit ctrlSetText GET_DATA(_index); +}; + +private _fnc_onConfirm = { + params ["_ctrlButtonOK"]; + + private _display = ctrlParent _ctrlButtonOK; + private _object = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); + private _data = ctrlText (_display displayCtrl IDC_ATTRIBUTE_EDIT); + + [QGVAR(setObjectData), [_object, _data]] call CBA_fnc_serverEvent; +}; + +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/intelitems/functions/fnc_canPickup.sqf b/addons/intelitems/functions/fnc_canPickup.sqf new file mode 100644 index 0000000000..9bab60af1b --- /dev/null +++ b/addons/intelitems/functions/fnc_canPickup.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Checks if the player can pickup an intel object. + * + * Arguments: + * 0: Object + * 1: Player + * + * Return Value: + * Can pickup + * + * Example: + * [cursorObject, player] call ace_intelitems_fnc_canPickup + * + * Public: No + */ + +params ["_object", "_player"]; + +private _magazineClass = getText ((configOf _object) >> QGVAR(magazine)); + +_magazineClass != "" && {_player canAdd _magazineClass} diff --git a/addons/intelitems/functions/fnc_createControl.sqf b/addons/intelitems/functions/fnc_createControl.sqf new file mode 100644 index 0000000000..b56d3f3681 --- /dev/null +++ b/addons/intelitems/functions/fnc_createControl.sqf @@ -0,0 +1,55 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Creates an intel controls group. + * + * Arguments: + * 0: Control type + * 1: Intel index + * + * Return Value: + * None + * + * Example: + * ["RscNotepad", 1] call ace_intelitems_fnc_createControl + * + * Public: No + */ + +params ["_controlType", "_index"]; + +private _display = findDisplay IDD_MAIN_MAP; +private _controlsGroup = _display ctrlCreate [_controlType, -1]; +_controlsGroup setVariable [QGVAR(index), _index]; + +GVAR(controlsGroups) pushBack _controlsGroup; + +// Add event handlers to header to allow moving controls group +private _ctrlHeader = _controlsGroup controlsGroupCtrl IDC_HEADER; +_ctrlHeader ctrlAddEventHandler ["MouseButtonDown", {call FUNC(onMouseButtonDown)}]; +_ctrlHeader ctrlAddEventHandler ["MouseButtonUp", {call FUNC(onMouseButtonUp)}]; +_ctrlHeader ctrlAddEventHandler ["MouseMoving", {call FUNC(onMouseMoving)}]; + +// Add event handler to close controls group +private _ctrlClose = _controlsGroup controlsGroupCtrl IDC_CLOSE; +_ctrlClose ctrlAddEventHandler ["ButtonClick", { + params ["_ctrlClose"]; + + private _controlsGroup = ctrlParentControlsGroup _ctrlClose; + [_controlsGroup] call FUNC(deleteControl); +}]; + +// Set data in content control +private _ctrlContent = _controlsGroup controlsGroupCtrl IDC_CONTENT; +_ctrlContent ctrlSetText GET_DATA(_index); + +// Restore position of controls group (center if not saved) +private _position = [GVAR(controlsData), _index] call CBA_fnc_hashGet; + +if (isNil "_position") then { + ctrlPosition _controlsGroup params ["", "", "_posW", "_posH"]; + _position = [0.5 - _posW / 2, 0.5 - _posH / 2]; +}; + +_controlsGroup ctrlSetPosition _position; +_controlsGroup ctrlCommit 0; diff --git a/addons/intelitems/functions/fnc_deleteControl.sqf b/addons/intelitems/functions/fnc_deleteControl.sqf new file mode 100644 index 0000000000..c2b986b21f --- /dev/null +++ b/addons/intelitems/functions/fnc_deleteControl.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Deletes an intel controls group. + * + * Arguments: + * 0: Controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_intelitems_fnc_deleteControl + * + * Public: No + */ + +params ["_controlsGroup"]; + +private _index = _controlsGroup getVariable QGVAR(index); + +// Save position of controls group +ctrlPosition _controlsGroup params ["_posX", "_posY"]; +[GVAR(controlsData), _index, [_posX, _posY]] call CBA_fnc_hashSet; + +// Update data if modified +private _ctrlContent = _controlsGroup controlsGroupCtrl IDC_CONTENT; +private _data = ctrlText _ctrlContent; + +if (_data isNotEqualTo GET_DATA(_index)) then { + SET_DATA(_index,_data); +}; + +// Delete the controls group +GVAR(controlsGroups) deleteAt (GVAR(controlsGroups) find _controlsGroup); +ctrlDelete _controlsGroup; diff --git a/addons/intelitems/functions/fnc_handleLoadout.sqf b/addons/intelitems/functions/fnc_handleLoadout.sqf new file mode 100644 index 0000000000..f4e2ed5b25 --- /dev/null +++ b/addons/intelitems/functions/fnc_handleLoadout.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Handles the player loadout changed event. + * + * Arguments: + * 0: Player + * + * Return Value: + * None + * + * Example: + * [player] call ace_intelitems_fnc_handleLoadout + * + * Public: No + */ + +params ["_player"]; + +private _allIndices = []; + +// Handle magazine ids with missing index assignments +private _cfgMagazines = configFile >> "CfgMagazines"; +private _magazines = magazines _player; + +{ + if (getNumber (_cfgMagazines >> _x >> QGVAR(intel)) == 1) then { + private _magazineIds = [_player, _x] call CBA_fnc_getMagazineIndex; + + { + private _index = GVAR(intelMap) getVariable _x; + + if (isNil "_index") then { + // Need new intel index from server + [QGVAR(handleMagIndex), _x] call CBA_fnc_serverEvent; + } else { + // Add valid index to array of all indices + _allIndices pushBack _index; + }; + } forEach _magazineIds; + }; +} forEach (_magazines arrayIntersect _magazines); + +// Close any open controls if player no longer has needed magazine +{ + private _index = _x getVariable QGVAR(index); + + if !(_index in _allIndices) then { + [_x] call FUNC(deleteControl); + }; +} forEach +GVAR(controlsGroups); diff --git a/addons/intelitems/functions/fnc_handleMagIndex.sqf b/addons/intelitems/functions/fnc_handleMagIndex.sqf new file mode 100644 index 0000000000..da47f9c74a --- /dev/null +++ b/addons/intelitems/functions/fnc_handleMagIndex.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Handles assigning a unique intel index to a magazine id. + * + * Arguments: + * 0: Magazine id + * + * Return Value: + * Intel Index + * + * Example: + * ["001"] call ace_intelitems_fnc_handleMagIndex + * + * Public: No + */ + +params ["_magazineId"]; + +private _index = GVAR(intelMap) getVariable _magazineId; + +if (isNil "_index") then { + _index = GVAR(intelCount); + GVAR(intelCount) = GVAR(intelCount) + 1; +}; + +GVAR(intelMap) setVariable [_magazineId, _index, true]; + +_index diff --git a/addons/intelitems/functions/fnc_onMouseButtonDown.sqf b/addons/intelitems/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..02b78678b7 --- /dev/null +++ b/addons/intelitems/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Handles the mouse button down event for an intel control. + * + * Arguments: + * 0: Header control + * 1: Button + * 2: X position + * 3: Y position + * + * Return Value: + * None + * + * Example: + * [CONTROL, 0, 0.5, 0.5] call ace_intelitems_fnc_onMouseButtonDown + * + * Public: No + */ + +params ["_ctrlHeader", "_button", "_posX", "_posY"]; + +if (_button != 0) exitWith {}; + +private _controlsGroup = ctrlParentControlsGroup _ctrlHeader; +_controlsGroup setVariable [QGVAR(clickPos), [_posX, _posY]]; diff --git a/addons/intelitems/functions/fnc_onMouseButtonUp.sqf b/addons/intelitems/functions/fnc_onMouseButtonUp.sqf new file mode 100644 index 0000000000..b8fe39e793 --- /dev/null +++ b/addons/intelitems/functions/fnc_onMouseButtonUp.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Handles the mouse button up event for an intel control. + * + * Arguments: + * 0: Header control + * 1: Button + * + * Return Value: + * None + * + * Example: + * [CONTROL, 0] call ace_intelitems_fnc_onMouseButtonUp + * + * Public: No + */ + +params ["_ctrlHeader", "_button"]; + +if (_button != 0) exitWith {}; + +private _controlsGroup = ctrlParentControlsGroup _ctrlHeader; +_controlsGroup setVariable [QGVAR(clickPos), nil]; diff --git a/addons/intelitems/functions/fnc_onMouseMoving.sqf b/addons/intelitems/functions/fnc_onMouseMoving.sqf new file mode 100644 index 0000000000..673b5718e3 --- /dev/null +++ b/addons/intelitems/functions/fnc_onMouseMoving.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Handles the mouse moving event for an intel control. + * + * Arguments: + * 0: Header control + * 1: X position + * 2: Y position + * + * Return Value: + * None + * + * Example: + * [CONTROL, 0.1, 0.2] call ace_intelitems_fnc_onMouseMoving + * + * Public: No + */ + +params ["_ctrlHeader", "_posX", "_posY"]; + +private _controlsGroup = ctrlParentControlsGroup _ctrlHeader; + +private _clickPos = _controlsGroup getVariable QGVAR(clickPos); +if (isNil "_clickPos") exitWith {}; + +ctrlPosition _controlsGroup params ["_groupX", "_groupY"]; +_clickPos params ["_clickX", "_clickY"]; + +_controlsGroup ctrlSetPosition [_groupX + _posX - _clickX, _groupY + _posY - _clickY]; +_controlsGroup ctrlCommit 0; diff --git a/addons/intelitems/functions/fnc_pickup.sqf b/addons/intelitems/functions/fnc_pickup.sqf new file mode 100644 index 0000000000..1bb075a10f --- /dev/null +++ b/addons/intelitems/functions/fnc_pickup.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Picks up an intel object by converting it into a unique magazine. + * + * Arguments: + * 0: Object + * 1: Player + * + * Return Value: + * None + * + * Example: + * [cursorObject, player] call ace_intelitems_fnc_pickup + * + * Public: No + */ + +params ["_object", "_player"]; + +private _magazineClass = getText ((configOf _object) >> QGVAR(magazine)); +private _index = _object getVariable [QGVAR(index), -1]; + +// Add magazine to inventory and get its id +private _magazinesBefore = [_player, _magazineClass] call CBA_fnc_getMagazineIndex; +_player addMagazine _magazineClass; +private _magazinesAfter = [_player, _magazineClass] call CBA_fnc_getMagazineIndex; + +private _magazineId = _magazinesAfter - _magazinesBefore; +if (_magazineId isEqualTo []) exitWith {}; + +_magazineId = _magazineId select 0; + +// Delete object as it now exists as a magazine +deleteVehicle _object; + +if (_index == -1) then { + // Need new intel index from server + [QGVAR(handleMagIndex), _magazineId] call CBA_fnc_serverEvent; +} else { + // Can simply broadcast index for magazine id + GVAR(intelMap) setVariable [_magazineId, _index, true]; +}; diff --git a/addons/intelitems/functions/fnc_setObjectData.sqf b/addons/intelitems/functions/fnc_setObjectData.sqf new file mode 100644 index 0000000000..395195fad5 --- /dev/null +++ b/addons/intelitems/functions/fnc_setObjectData.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Sets the intel data for an object. Used by 3DEN and Zeus attributes. + * + * Arguments: + * 0: Object + * 1: Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, "123"] call ace_intelitems_fnc_setObjectData + * + * Public: No + */ + +params ["_object", "_data"]; + +private _index = _object getVariable [QGVAR(index), -1]; + +if (_index == -1) then { + _index = GVAR(intelCount); + GVAR(intelCount) = GVAR(intelCount) + 1; + + _object setVariable [QGVAR(index), _index, true]; +}; + +SET_DATA(_index,_data); diff --git a/addons/intelitems/gui.hpp b/addons/intelitems/gui.hpp new file mode 100644 index 0000000000..4f4f1a1206 --- /dev/null +++ b/addons/intelitems/gui.hpp @@ -0,0 +1,189 @@ +class ctrlStatic; +class ctrlStaticMulti; +class ctrlEditMulti; +class ctrlButtonPicture; +class ctrlStaticPictureKeepAspect; +class ctrlControlsGroupNoScrollbars; + +class GVAR(RscBase): ctrlControlsGroupNoScrollbars { + idc = -1; + x = 0; + y = 0; + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(18)); + class controls { + class Border: ctrlStatic { + idc = IDC_BORDER; + x = 0; + y = 0; + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(18)); + colorBackground[] = {0, 0, 0, 1}; + }; + class Background: ctrlStatic { + idc = IDC_BACKGROUND; + x = QUOTE(pixelW); + y = QUOTE(pixelH); + w = QUOTE(POS_W(15) - 2 * pixelW); + h = QUOTE(POS_H(18) - 2 * pixelH); + colorBackground[] = {1, 1, 1, 1}; + }; + class Header: ctrlStatic { + idc = IDC_HEADER; + style = QUOTE(ST_MULTI + ST_NO_RECT); + x = 0; + y = 0; + w = QUOTE(POS_W(14.3)); + h = QUOTE(POS_H(0.7)); + sizeEx = QUOTE(POS_H(0.65)); + colorBackground[] = {0.1, 0.1, 0.1, 1}; + }; + class Close: ctrlButtonPicture { + idc = IDC_CLOSE; + text = "\a3\3DEN\Data\Displays\Display3DEN\search_end_ca.paa"; + x = QUOTE(POS_W(14.3)); + y = 0; + w = QUOTE(POS_W(0.7)); + h = QUOTE(POS_H(0.7)); + offsetPressedX = 0; + offsetPressedY = 0; + colorBackground[] = {0.1, 0.1, 0.1, 1}; + }; + }; +}; + +class GVAR(RscNotepad): GVAR(RscBase) { + class controls: controls { + class Border: Border {}; + class Background: Background { + colorBackground[] = {0.97, 0.91, 0.77, 1}; + }; + class Header: Header { + text = CSTRING(Notepad_DisplayName); + }; + class Close: Close {}; + class Content: ctrlEditMulti { + idc = IDC_CONTENT; + style = QUOTE(ST_MULTI + ST_NO_RECT); + font = "EtelkaMonospaceProBold"; + x = QUOTE(pixelW); + y = QUOTE(POS_H(0.7)); + w = QUOTE(POS_W(15) - 2 * pixelW); + h = QUOTE(POS_H(17.3) - pixelH); + sizeEx = QUOTE(POS_H(0.9)); + shadow = 0; + colorText[] = {0, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 0}; + }; + }; +}; + +class GVAR(RscDocument): GVAR(RscBase) { + class controls: controls { + class Border: Border {}; + class Background: Background { + colorBackground[] = {0.95, 0.95, 0.95, 1}; + }; + class Header: Header { + text = CSTRING(Document_DisplayName); + }; + class Close: Close {}; + class Content: ctrlStaticMulti { + idc = IDC_CONTENT; + font = "EtelkaMonospaceProBold"; + x = QUOTE(pixelW); + y = QUOTE(POS_H(0.7)); + w = QUOTE(POS_W(15) - 2 * pixelW); + h = QUOTE(POS_H(17.3) - pixelH); + sizeEx = QUOTE(POS_H(0.9)); + shadow = 0; + colorText[] = {0, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 0}; + }; + }; +}; + +class GVAR(RscPhoto): GVAR(RscBase) { + w = QUOTE(POS_W(18)); + class controls: controls { + class Border: Border { + w = QUOTE(POS_W(18)); + }; + class Background: Background { + w = QUOTE(POS_W(18) - 2 * pixelW); + }; + class Header: Header { + text = CSTRING(Photo_DisplayName); + w = QUOTE(POS_W(17.3)); + }; + class Close: Close { + x = QUOTE(POS_W(17.3)); + }; + class Content: ctrlStaticPictureKeepAspect { + idc = IDC_CONTENT; + x = QUOTE(pixelW); + y = QUOTE(POS_H(0.7)); + w = QUOTE(POS_W(18) - 2 * pixelW); + h = QUOTE(POS_H(17.3) - pixelH); + }; + }; +}; + +// Zeus Attributes Display +class RscText; +class RscEditMulti; +class RscControlsGroup; +class RscControlsGroupNoScrollbars; + +class RscDisplayAttributes { + class Controls { + class Background; + class Title; + class Content: RscControlsGroup { + class controls; + }; + class ButtonOK; + class ButtonCancel; + }; +}; + +class GVAR(RscSetData): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSetData))] call EFUNC(zeus,zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSetData))] call EFUNC(zeus,zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class setData: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(attributeFocus)); + idc = IDC_ATTRIBUTE_GROUP; + x = 0; + y = 0; + w = QUOTE(POS_W(26)); + h = QUOTE(POS_H(6)); + class controls { + class Label: RscText { + idc = IDC_ATTRIBUTE_LABEL; + x = 0; + y = 0; + w = QUOTE(POS_W(26)); + h = QUOTE(POS_H(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Edit: RscEditMulti { + idc = IDC_ATTRIBUTE_EDIT; + x = QUOTE(pixelW); + y = QUOTE(POS_H(1) + pixelH); + w = QUOTE(POS_W(26) - pixelW); + h = QUOTE(POS_H(5) - pixelH); + sizeEx = QUOTE(POS_H(0.9)); + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/addons/intelitems/script_component.hpp b/addons/intelitems/script_component.hpp new file mode 100644 index 0000000000..f053d00d98 --- /dev/null +++ b/addons/intelitems/script_component.hpp @@ -0,0 +1,39 @@ +#define COMPONENT intelitems +#define COMPONENT_BEAUTIFIED Intel Items +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_INTELITEMS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_INTELITEMS + #define DEBUG_SETTINGS DEBUG_SETTINGS_INTELITEMS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#include "\a3\ui_f\hpp\defineResincl.inc" +#include "\a3\ui_f\hpp\defineCommonGrids.inc" + +#define POS_X(N) ((N) * GUI_GRID_W + GUI_GRID_CENTER_X) +#define POS_Y(N) ((N) * GUI_GRID_H + GUI_GRID_CENTER_Y) +#define POS_W(N) ((N) * GUI_GRID_W) +#define POS_H(N) ((N) * GUI_GRID_H) + +#define IDC_BORDER 10 +#define IDC_BACKGROUND 20 +#define IDC_HEADER 30 +#define IDC_CLOSE 40 +#define IDC_CONTENT 50 + +#define IDC_ATTRIBUTE_GROUP 4800 +#define IDC_ATTRIBUTE_LABEL 4801 +#define IDC_ATTRIBUTE_EDIT 4802 + +#define SYS_DATA(index) (format [QGVAR(%1), index]) +#define SET_DATA(index,data) (GVAR(intelData) setVariable [SYS_DATA(index), data, true]) +#define GET_DATA(index) (GVAR(intelData) getVariable [SYS_DATA(index), ""]) diff --git a/addons/intelitems/stringtable.xml b/addons/intelitems/stringtable.xml new file mode 100644 index 0000000000..8f13939090 --- /dev/null +++ b/addons/intelitems/stringtable.xml @@ -0,0 +1,172 @@ + + + + + ACE Intel Items + ACE Aufklärungsgegenstände + ACE Oggetti Intel + ACE 情報物品 + ACE 情报物品 + ACE 機密アイテム + ACE Предметы с данными + ACE Przedmioty Wywiadu + ACE Istihbarat Eşyaları + ACE 정보 아이템 + ACE Objetos de Inteligencia + ACE Objets de Renseignements + ACE Itens de Inteligência + + + Intel Items + Aufklärungsgegenstände + Oggetti Intel + 情報物品 + 情报物品 + 機密アイテム + Предметы с данными + Przedmioty Wywiadu + Istihbarat Eşyaları + 정보 아이템 + Objetos de Inteligencia + Objets de Renseignements + Itens de Inteligência + + + Notepad + Notizblock + Blocco Note + 筆記本 + 笔记本 + メモ帳 + Блокнот + Notes + Not Defteri + 노트패드 + Bloc de notas + Bloc-notes + Bloco de Notas + + + Notepad - Can access from the map screen + Notizblock - Über die Karte abrufbar + Blocco Note - Accessibile dalla mappa + 筆記本 - 可以透過地圖界面來存取 + 笔记本—可以透过地图界面访问 + メモ帳 - マップ画面から確認可能 + Блокнот - Можно получить доступ с экрана карты + Notes - Dostępne z mapy + Not Defteri - Haritadan erişim sağlanabilinir + 노트패드 - 지도에서 확인 가능합니다 + Block de notas - Puede accederse desde la pantalla de mapa + Bloc-note - Consultable depuis la carte + Bloco de Notas - Pode ser acessado a partir da tela de mapa + + + Document + Dokument + Documento + 文件 + 文件 + 資料 + Документ + Dokument + Döküman + 문서 + Documento + Document + Documento + + + Printed Document - Can access from the map screen + Bedrucktes Dokument - Über die Karte abrufbar + Documento stampato - Accessibile dalla mappa + 影印文件 - 可以透過地圖界面來存取 + 影印文件—可以透过地图界面访问 + 印刷された資料 - マップ画面から確認可能 + Распечатанный документ - Можно получить доступ с экрана карты + Wydrukowane Dokumenty - Dostępne z mapy + Yazılı Döküman - Haritadan erişim sağlanabilinir + 문서들 - 지도에서 확인 가능합니다 + Documento Impreso - Puede accederse desde la pantalla de mapa + Document imprimé - Consultable depuis la carte + Documento Impresso - Pode ser acessado a partir da tela de mapa + + + Photo + Foto + Foto + 相片 + 照片 + 写真 + Фотография + Zdjęcie + Fotoğraf + 사진 + Fotografía + Photo + Fotografia + + + Photo - Can access from the map screen + Foto - Über die Karte abrufbar + Foto - Accessibile dalla mappa + 相片 - 可以透過地圖界面來存取 + 照片—可以透过地图界面访问 + 写真 - マップ画面から確認可能 + Фотография - Можно получить доступ с экрана карты + Zdjęcie - Dostępne z mapy + Fotoğraf - Haritadan erişim sağlanabilinir + 사진 - 지도에서 확인 가능합니다 + Fotografía - Puede accederse desde la pantalla de mapa + Photo - Consultable depuis la carte + Fotografia - Pode ser acessada a partir da tela de mapa + + + Text + Text + Texte + Text + Testo + Tekst + Texto + Текст + Texto + 文字 + 文字 + テキスト + Yazı + 문자 + + + Photo Filename + Foto-Dateiname + Nome File della Foto + 相片名稱 + 照片文件名 + 写真名 + Имя файла фотографии + Zdjęcie Nazwa Pliku + Fotoğraf Dosya Adı + 사진명 + Nombre de fichero de la Fotografía + Nom du fichier photo + Nome do Arquivo da Fotografia + + + Pick Up + Vyzvednout + Ramasser + Aufnehmen + Raccogli + Podnieś + Pegar + Подобрать + Recoger + 撿起 + 捡起 + 拾う + Al + 줍기 + + + diff --git a/addons/intelitems/ui/document_ca.paa b/addons/intelitems/ui/document_ca.paa new file mode 100644 index 0000000000..0d04cd303a Binary files /dev/null and b/addons/intelitems/ui/document_ca.paa differ diff --git a/addons/intelitems/ui/notepad_ca.paa b/addons/intelitems/ui/notepad_ca.paa new file mode 100644 index 0000000000..3724da4cc1 Binary files /dev/null and b/addons/intelitems/ui/notepad_ca.paa differ diff --git a/addons/intelitems/ui/photo_ca.paa b/addons/intelitems/ui/photo_ca.paa new file mode 100644 index 0000000000..8548876e32 Binary files /dev/null and b/addons/intelitems/ui/photo_ca.paa differ diff --git a/addons/interact_menu/ACE_Settings.hpp b/addons/interact_menu/ACE_Settings.hpp index a36d3dd98d..580d494722 100644 --- a/addons/interact_menu/ACE_Settings.hpp +++ b/addons/interact_menu/ACE_Settings.hpp @@ -1,108 +1,44 @@ class ACE_Settings { class GVAR(alwaysUseCursorSelfInteraction) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(AlwaysUseCursorSelfInteraction); + movedToSQF = 1; }; class GVAR(cursorKeepCentered) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(cursorKeepCentered); - description = CSTRING(cursorKeepCenteredDescription); + movedToSQF = 1; }; class GVAR(alwaysUseCursorInteraction) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(AlwaysUseCursorInteraction); + movedToSQF = 1; }; class GVAR(useListMenu) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(UseListMenu); - }; - class GVAR(colorTextMax) { - value[] = {1, 1, 1, 1}; - typeName = "COLOR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(ColorTextMax); - }; - class GVAR(colorTextMin) { - value[] = {1, 1, 1, 0.25}; - typeName = "COLOR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(ColorTextMin); - }; - class GVAR(colorShadowMax) { - value[] = {0, 0, 0, 1}; - typeName = "COLOR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(ColorShadowMax); - }; - class GVAR(colorShadowMin) { - value[] = {0, 0, 0, 0.25}; - typeName = "COLOR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(ColorShadowMin); - }; - class GVAR(textSize) { - value = 2; - typeName = "SCALAR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(textSize); - values[] = {"$str_very_small", "$str_small", "$str_medium", "$str_large", "$str_very_large"}; - }; - class GVAR(shadowSetting) { - value = 2; - typeName = "SCALAR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(shadowSetting); - description = CSTRING(shadowSettingDescription); - values[] = {"$STR_A3_OPTIONS_DISABLED", "$STR_A3_OPTIONS_ENABLED", CSTRING(shadowOutline)}; - }; - class GVAR(actionOnKeyRelease) { - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(ActionOnKeyRelease); + movedToSQF = 1; }; class GVAR(menuBackground) { - value = 0; - typeName = "SCALAR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(background); - values[] = {"$STR_A3_OPTIONS_DISABLED", CSTRING(backgroundBlur), CSTRING(backgroundBlack)}; + movedToSQF = 1; + }; + class GVAR(colorTextMax) { + movedToSQF = 1; + }; + class GVAR(colorTextMin) { + movedToSQF = 1; + }; + class GVAR(colorShadowMax) { + movedToSQF = 1; + }; + class GVAR(colorShadowMin) { + movedToSQF = 1; + }; + class GVAR(textSize) { + movedToSQF = 1; + }; + class GVAR(shadowSetting) { + movedToSQF = 1; + }; + class GVAR(actionOnKeyRelease) { + movedToSQF = 1; }; class GVAR(addBuildingActions) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(addBuildingActions); - description = CSTRING(addBuildingActionsDescription); + movedToSQF = 1; }; class GVAR(menuAnimationSpeed) { - value = 0; - typeName = "SCALAR"; - isClientSettable = 1; - category = CSTRING(Category_InteractionMenu); - displayName = CSTRING(menuAnimationSpeed); - description = CSTRING(menuAnimationSpeed_Description); - values[] = {"$str_speed_normal", "2x", "3x"}; + movedToSQF = 1; }; }; diff --git a/addons/interact_menu/CfgEventHandlers.hpp b/addons/interact_menu/CfgEventHandlers.hpp index b5880fb05b..0704097f25 100644 --- a/addons/interact_menu/CfgEventHandlers.hpp +++ b/addons/interact_menu/CfgEventHandlers.hpp @@ -1,25 +1,25 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); }; }; class Extended_DisplayLoad_EventHandlers { class RscDiary { - ADDON = QUOTE(call COMPILE_FILE(XEH_displayLoad)); + ADDON = QUOTE(call COMPILE_SCRIPT(XEH_displayLoad)); }; class RscDisplayInterrupt { ADDON = QUOTE(_this call FUNC(handleEscapeMenu)); diff --git a/addons/interact_menu/CursorMenus.hpp b/addons/interact_menu/CursorMenus.hpp index 385c3a0f75..79f1109598 100644 --- a/addons/interact_menu/CursorMenus.hpp +++ b/addons/interact_menu/CursorMenus.hpp @@ -9,11 +9,10 @@ class RscTitles { class GVAR(menuBackground) { idd = -1; onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(menuBackground)),_this select 0)]); - onUnload = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(menuBackground)),displayNull)]); fadeIn = 0.25; fadeOut = 0.25; - movingEnable = false; - duration = 10e10; + movingEnable = 0; + duration = QUOTE(10e10); name = QGVAR(menuBackground); class controls {}; class controlsBackground { diff --git a/addons/interact_menu/README.md b/addons/interact_menu/README.md index 77ac2d814a..d22647f059 100644 --- a/addons/interact_menu/README.md +++ b/addons/interact_menu/README.md @@ -2,11 +2,3 @@ ace_interact_menu =========== Base framework for interaction menu. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [NouberNou](https://github.com/NouberNou) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/interact_menu/XEH_PREP.hpp b/addons/interact_menu/XEH_PREP.hpp index 840acbf10d..03114b37e8 100644 --- a/addons/interact_menu/XEH_PREP.hpp +++ b/addons/interact_menu/XEH_PREP.hpp @@ -12,6 +12,7 @@ PREP(createVehiclesActions); PREP(ctrlSetParsedTextCached); PREP(findActionNode); PREP(handleEscapeMenu); +PREP(initMenuReorder); PREP(isSubPath); PREP(keyDown); PREP(keyUp); diff --git a/addons/interact_menu/XEH_clientInit.sqf b/addons/interact_menu/XEH_clientInit.sqf index 9a44674e42..d0c6d93940 100644 --- a/addons/interact_menu/XEH_clientInit.sqf +++ b/addons/interact_menu/XEH_clientInit.sqf @@ -3,16 +3,16 @@ if (!hasInterface) exitWith {}; // Wait until player controls (man,vehicle or uav) a thing before compiling the menu -GVAR(controllableSelfActionsAdded) = [] call CBA_fnc_createNamespace; +GVAR(controllableSelfActionsAdded) = createHashMap; DFUNC(newControllableObject) = { params ["_object"]; private _type = typeOf _object; TRACE_2("newControllableObject",_object,_type); if (_type == "") exitWith {}; - if (!(GVAR(controllableSelfActionsAdded) getVariable [_type, false])) then { + if !(_type in GVAR(controllableSelfActionsAdded)) then { [_type] call FUNC(compileMenuSelfAction); - GVAR(controllableSelfActionsAdded) setVariable [_type, true]; + GVAR(controllableSelfActionsAdded) set [_type, nil]; [{ TRACE_1("sending newControllableObject event",_this); // event for other systems to add self actions, running addActionToClass before this will cause compiling @@ -27,16 +27,15 @@ DFUNC(newControllableObject) = { GVAR(blockDefaultActions) = []; -GVAR(cachedBuildingTypes) = []; -GVAR(cachedBuildingActionPairs) = []; +GVAR(cachedBuildingTypes) = createHashMap; GVAR(ParsedTextCached) = []; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { // Setup text/shadow/size/color settings matrix [] call FUNC(setupTextColors); // Setting changed added here so color setup happens once at init - ["ace_settingChanged", { + ["CBA_SettingChanged", { params ["_name"]; if (_name in [QGVAR(colorTextMax), QGVAR(colorTextMin), QGVAR(colorShadowMax), QGVAR(colorShadowMin), QGVAR(textSize), QGVAR(shadowSetting)]) then { [] call FUNC(setupTextColors); @@ -47,7 +46,7 @@ GVAR(ParsedTextCached) = []; }] call CBA_fnc_addEventHandler; //Add Actions to Houses: -["ace_interactMenuOpened", {_this call FUNC(userActions_addHouseActions)}] call CBA_fnc_addEventHandler; +["ace_interactMenuOpened", LINKFUNC(userActions_addHouseActions)] call CBA_fnc_addEventHandler; ["ACE3 Common", QGVAR(InteractKey), (localize LSTRING(InteractKey)), { @@ -100,10 +99,23 @@ format ["%1 (%2)", (localize LSTRING(SelfInteractKey)), localize ELSTRING(common // background options ["ace_interactMenuOpened", { - if (GVAR(menuBackground)==1) then {[QGVAR(menuBackground), true] call EFUNC(common,blurScreen);}; - if (GVAR(menuBackground)==2) then {0 cutRsc[QGVAR(menuBackground), "PLAIN", 1, false];}; + params ["_menuType"]; + private _menuBackgroundSetting = [GVAR(menuBackground), GVAR(menuBackgroundSelf)] select _menuType; + if (_menuBackgroundSetting == 1) exitWith {[QGVAR(menuBackground), true] call EFUNC(common,blurScreen);}; + if (_menuBackgroundSetting == 2) exitWith {0 cutRsc [QGVAR(menuBackground), "PLAIN", 1, false];}; }] call CBA_fnc_addEventHandler; + ["ace_interactMenuClosed", { - if (GVAR(menuBackground)==1) then {[QGVAR(menuBackground), false] call EFUNC(common,blurScreen);}; - if (GVAR(menuBackground)==2) then {(uiNamespace getVariable [QGVAR(menuBackground), displayNull]) closeDisplay 0;}; + params ["_menuType"]; + private _menuBackgroundSetting = [GVAR(menuBackground), GVAR(menuBackgroundSelf)] select _menuType; + if (_menuBackgroundSetting == 1) exitWith {[QGVAR(menuBackground), false] call EFUNC(common,blurScreen);}; + if (_menuBackgroundSetting == 2) exitWith {(uiNamespace getVariable [QGVAR(menuBackground), displayNull]) closeDisplay 0;}; +}] call CBA_fnc_addEventHandler; + + +// init menu reordering +[QGVAR(newControllableObject), { + params ["_class"]; + if !(_class isKindOf "CAManBase") exitWith {}; + _class call FUNC(initMenuReorder); }] call CBA_fnc_addEventHandler; diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 4266e9f805..88269bcc04 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -6,22 +6,22 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" if (!hasInterface) exitWith { ADDON = true; }; -["All", "init", {_this call FUNC(compileMenu)}] call CBA_fnc_addClassEventHandler; +["All", "init", LINKFUNC(compileMenu)] call CBA_fnc_addClassEventHandler; -GVAR(ActNamespace) = [] call CBA_fnc_createNamespace; -GVAR(ActSelfNamespace) = [] call CBA_fnc_createNamespace; +GVAR(ActNamespace) = createHashMap; +GVAR(ActSelfNamespace) = createHashMap; // Compile actions for CAManBase now and use for all mans types ["CAManBase"] call FUNC(compileMenu); -GVAR(cacheManActions) = +(GVAR(ActNamespace) getVariable ["CAManBase", []]); // copy +GVAR(cacheManActions) = +(GVAR(ActNamespace) getOrDefault ["CAManBase" call EFUNC(common,getConfigName), []]); // copy // Event handlers for all interact menu controls DFUNC(handleMouseMovement) = { - if (GVAR(cursorKeepCentered)) then { + if ([GVAR(cursorKeepCentered), GVAR(cursorKeepCenteredSelfInteraction)] select GVAR(keyDownSelfAction)) then { GVAR(cursorPos) = GVAR(cursorPos) vectorAdd [_this select 1, _this select 2, 0] vectorDiff [0.5, 0.5, 0]; setMousePosition [0.5, 0.5]; } else { @@ -106,6 +106,6 @@ GVAR(inheritedClassesMan) = []; [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); } forEach GVAR(inheritedActionsMan); END_COUNTER(InitPost); -}] call CBA_fnc_addClassEventHandler; +}, true, ["VirtualMan_F"]] call CBA_fnc_addClassEventHandler; ADDON = true; diff --git a/addons/interact_menu/config.cpp b/addons/interact_menu/config.cpp index 687d644924..756e8775ab 100644 --- a/addons/interact_menu/config.cpp +++ b/addons/interact_menu/config.cpp @@ -23,5 +23,8 @@ class CfgPatches { #include "ACE_Settings.hpp" class ACE_Extensions { - extensions[] += {"ace_break_line", "ace_parse_imagepath"}; + class ace_break_line { + windows = 1; + client = 1; + }; }; diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf index 69425ea047..ccea8c4654 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Insert an ACE action to a class, under a certain path @@ -48,6 +48,8 @@ if (param [4, false, [false]]) exitwith { (_parentPath + [_action select 0]) }; +_objectType = _objectType call EFUNC(common,getConfigName); + // Ensure the config menu was compiled first if (_typeNum == 0) then { [_objectType] call FUNC(compileMenu); @@ -56,18 +58,14 @@ if (_typeNum == 0) then { }; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; - _namespace setVariable [_objectType, _actionTrees]; -}; +private _actionTrees = _namespace getOrDefault [_objectType, [], true]; if (_parentPath isEqualTo ["ACE_MainActions"]) then { [_objectType, _typeNum] call FUNC(addMainAction); }; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith { +if (isNil "_parentNode") exitWith { ERROR_4("Failed to add action - action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); [] }; diff --git a/addons/interact_menu/functions/fnc_addActionToObject.sqf b/addons/interact_menu/functions/fnc_addActionToObject.sqf index f3102469a5..d22b77cc83 100644 --- a/addons/interact_menu/functions/fnc_addActionToObject.sqf +++ b/addons/interact_menu/functions/fnc_addActionToObject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Insert an ACE action to an object, under a certain config path diff --git a/addons/interact_menu/functions/fnc_addActionToZeus.sqf b/addons/interact_menu/functions/fnc_addActionToZeus.sqf index 538ea5fe16..3175bf14ad 100644 --- a/addons/interact_menu/functions/fnc_addActionToZeus.sqf +++ b/addons/interact_menu/functions/fnc_addActionToZeus.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Insert an ACE action to zeus. @@ -19,7 +19,7 @@ if (!hasInterface) exitWith { [] }; if (!params [["_parentPath", [], [[]]], ["_action", [], [[]], 11]]) exitWith {ERROR("Bad Params"); []}; -if ((_parentPath param [0, ""]) != "ACE_ZeusActions") exitWith {ERROR_1("Bad path %1 - should have ACE_ZeusActions as base", _parentPath); []}; +if ((_parentPath param [0, ""]) != "ACE_ZeusActions") exitWith {ERROR_1("Bad path %1 - should have ACE_ZeusActions as base",_parentPath); []}; TRACE_2("addActionToZeus",_parentPath,_action); private _currentPath = GVAR(ZeusActions); @@ -37,7 +37,7 @@ private _pathValid = false; } forEach _currentPath; } forEach _parentPath; -if (!_pathValid) exitWith {ERROR_1("Bad path %1", _parentPath); []}; +if (!_pathValid) exitWith {ERROR_1("Bad path %1",_parentPath); []}; TRACE_1("Adding Action",_currentPath); _currentPath pushBack [_action, []]; diff --git a/addons/interact_menu/functions/fnc_addMainAction.sqf b/addons/interact_menu/functions/fnc_addMainAction.sqf index d00cd2b60e..beb02997b9 100644 --- a/addons/interact_menu/functions/fnc_addMainAction.sqf +++ b/addons/interact_menu/functions/fnc_addMainAction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas, PabstMirror * Makes sure there is a ACE_MainActions on the object type @@ -19,15 +19,11 @@ params ["_objectType", "_typeNum"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; - +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode); -if (isNil {_parentNode}) then { - TRACE_2("No Main Action on object", _objectType, _typeNum); +if (isNil "_parentNode") then { + TRACE_2("No Main Action on object",_objectType,_typeNum); private _mainAction = ["ACE_MainActions", localize ELSTRING(interaction,MainAction), "", {}, {true}] call FUNC(createAction); [_objectType, _typeNum, [], _mainAction] call EFUNC(interact_menu,addActionToClass); }; diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index e7fecfcac8..9a3eb31598 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Collect a entire tree of active actions @@ -13,7 +13,7 @@ * Active children * * Example: - * [bob, [array], [array], 5] call ACE_interact_menu_fnc_collectActoveActionTree + * [bob, [array], [array], 5] call ACE_interact_menu_fnc_collectActiveActionTree * * Public: No */ @@ -25,20 +25,39 @@ private _target = _object; private _player = ACE_player; // Check if the function should be modified first -if !((_origActionData select 10) isEqualTo {}) then { +if ((_origActionData select 10) isNotEqualTo {}) then { // It should, so make a copy and pass it to the modifierFunction _origActionData = +_origActionData; [_target, ACE_player, _origActionData select 6, _origActionData] call (_origActionData select 10); }; -_origActionData params ["_actionName", "", "", "_statementCode", "_conditionCode", "_insertChildrenCode", "_customParams", "", "_distance"]; +_origActionData params [ + "_actionName", + "_displayName", + "", + "_statementCode", + "_conditionCode", + "_insertChildrenCode", + "_customParams", + "_position", + "_distance" +]; + +private _result = [_target, ACE_player, _customParams] call _conditionCode; + +// Handle nil as false +if (isNil "_result") then { + ERROR_1("Action [%1] bad condition return",_actionName); + + _result = false; +}; // Return nothing if the action itself is not active -if !([_target, ACE_player, _customParams] call _conditionCode) exitWith { +if (!_result) exitWith { [] }; -// Return nothing if the action is to far (including checking sub actions) [DISABLED FOR NOW ref #2196] +// Return nothing if the action is too far (including checking sub actions) [DISABLED FOR NOW ref #2196] // if (_distanceToBasePoint > _distance) exitWith { // [] // }; @@ -48,27 +67,25 @@ _fullPath pushBack _actionName; private _activeChildren = []; // If there's a statement to dynamically insert children then execute it -if !({} isEqualTo _insertChildrenCode) then { +if (_insertChildrenCode isNotEqualTo {}) then { private _dynamicChildren = [_target, ACE_player, _customParams] call _insertChildrenCode; // Collect dynamic children class actions { private _action = [_x select 2, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; - nil - } count _dynamicChildren; + } forEach _dynamicChildren; }; // Collect children class actions { private _action = [_object, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; - nil -} count _origActionChildren; +} forEach _origActionChildren; // Collect children object actions { @@ -77,12 +94,11 @@ if !({} isEqualTo _insertChildrenCode) then { // Check if the action is children of the original action if (_pPath isEqualTo _fullPath) then { private _action = [_object, [_actionData,[]], _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; }; - nil -} count GVAR(objectActionList); +} forEach GVAR(objectActionList); // If the original action has no statement, and no children, don't display it @@ -91,5 +107,23 @@ if ((_activeChildren isEqualTo []) && {_statementCode isEqualTo {}}) exitWith { [] }; +if (GVAR(consolidateSingleChild) && {count _activeChildren == 1} && {_statementCode isEqualTo {}}) then { + _activeChildren select 0 params ["_childActionData", "_childChildren", "_childObject"]; + _childActionData params ["", "_displayNameChild", "_iconChild", "_statementChild", "_conditionChild", "_insertChildrenChild", "_customParamsChild", "", "", "_paramsChild"]; + _origActionData = [ + _actionName, + format ["%1 > %2", _displayName, _displayNameChild], + _iconChild, + _statementChild, + _conditionChild, + _insertChildrenChild, + _customParamsChild, + _position, + _distance, + _paramsChild + ]; + _activeChildren = _childChildren; + _object = _childObject; +}; [_origActionData, _activeChildren, _object] diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index bac9d42fff..8c5d3c5fa1 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Compile the action menu from config for an object's class @@ -17,22 +17,22 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActNamespace); // Exit if the action menu is already compiled for this class -if !(isNil {_namespace getVariable _objectType}) exitWith {}; +if (_objectType in GVAR(ActNamespace)) exitWith {}; -if ((_objectType isKindOf "CAManBase") && {!isNil QGVAR(cacheManActions)}) exitWith { - _namespace setVariable [_objectType, +GVAR(cacheManActions)]; // copy +if (_objectType isKindOf "VirtualMan_F") exitWith { // these have config: isPlayableLogic = 1 + TRACE_1("skipping playable logic",_objectType); + GVAR(ActNamespace) set [_objectType, []]; }; -if ((getNumber (configFile >> "CfgVehicles" >> _objectType >> "isPlayableLogic")) == 1) exitWith { - TRACE_1("skipping playable logic",_objectType); - _namespace setVariable [_objectType, []]; +if ((_objectType isKindOf "CAManBase") && {!isNil QGVAR(cacheManActions)}) exitWith { + GVAR(ActNamespace) set [_objectType, +GVAR(cacheManActions)]; // copy }; private _recurseFnc = { @@ -41,11 +41,11 @@ private _recurseFnc = { { private _entryCfg = _x; - if(isClass _entryCfg) then { + if (isClass _entryCfg) then { private _displayName = getText (_entryCfg >> "displayName"); private _distance = _parentDistance; if (isNumber (_entryCfg >> "distance")) then {_distance = getNumber (_entryCfg >> "distance");}; - // if (_distance < _parentDistance) then {WARNING_3("[%1] distance %2 less than parent %3", configName _entryCfg, _distance, _parentDistance);}; + // if (_distance < _parentDistance) then {WARNING_3("[%1] distance %2 less than parent %3",configName _entryCfg,_distance,_parentDistance);}; private _icon = if (isArray (_entryCfg >> "icon")) then { getArray (_entryCfg >> "icon"); } else { @@ -69,11 +69,14 @@ private _recurseFnc = { }; private _condition = getText (_entryCfg >> "condition"); - if (_condition == "") then {_condition = "true"}; - // Add canInteract (including exceptions) and canInteractWith to condition - if ((configName _entryCfg) != "ACE_MainActions") then { - _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; + if (configName _entryCfg == "ACE_MainActions") then { + if (_condition isEqualTo "") then {_condition = "true"}; + } else { + // Add canInteract (including exceptions) and canInteractWith to condition + private _canInteractCondition = format [QUOTE([ARR_3(ACE_player,_target,%1)] call EFUNC(common,canInteractWith)),getArray (_entryCfg >> "exceptions")]; + private _conditionFormatPattern = ["%1 && {%2}", "%2"] select (_condition isEqualTo "" || {_condition == "true"}); + _condition = format [_conditionFormatPattern, _condition, _canInteractCondition]; }; private _insertChildren = compile (getText (_entryCfg >> "insertChildren")); @@ -88,6 +91,7 @@ private _recurseFnc = { } else { _runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0; }; + private _doNotCheckLOS = getNumber (_entryCfg >> "doNotCheckLOS") > 0; _condition = compile _condition; private _children = [_entryCfg, _distance] call _recurseFnc; @@ -103,15 +107,14 @@ private _recurseFnc = { [], _position, _distance, - [_showDisabled,_enableInside,_canCollapse,_runOnHover, false], + [_showDisabled, _enableInside, _canCollapse, _runOnHover, _doNotCheckLOS], _modifierFunction ], _children ]; _actions pushBack _entry; }; - nil - } count (configProperties [_actionsCfg, "isClass _x", true]); + } forEach (configProperties [_actionsCfg, "isClass _x", true]); _actions }; @@ -136,7 +139,7 @@ if (_objectType isKindOf "CAManBase") then { }; }; -_namespace setVariable [_objectType, _actions]; +GVAR(ActNamespace) set [_objectType, _actions]; /* [ diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 8a79fe99e1..8f19dfabbe 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Compile the self action menu from config for an object's class @@ -17,15 +17,14 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActSelfNamespace); // Exit if the action menu is already compiled for this class -if !(isNil {_namespace getVariable _objectType}) exitWith {}; - +if (_objectType in GVAR(actSelfNamespace)) exitWith {}; private _recurseFnc = { params ["_actionsCfg"]; @@ -34,7 +33,7 @@ private _recurseFnc = { { private _entryCfg = _x; - if(isClass _entryCfg) then { + if (isClass _entryCfg) then { private _displayName = getText (_entryCfg >> "displayName"); private _icon = if (isArray (_entryCfg >> "icon")) then { @@ -45,10 +44,11 @@ private _recurseFnc = { private _statement = compile (getText (_entryCfg >> "statement")); private _condition = getText (_entryCfg >> "condition"); - if (_condition == "") then {_condition = "true"}; // Add canInteract (including exceptions) and canInteractWith to condition - _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; + private _canInteractCondition = format [QUOTE([ARR_3(ACE_player,_target,%1)] call EFUNC(common,canInteractWith)), getArray (_entryCfg >> "exceptions")]; + private _conditionFormatPattern = ["%1 && {%2}", "%2"] select (_condition isEqualTo "" || {_condition == "true"}); + _condition = compile format [_conditionFormatPattern, _condition, _canInteractCondition]; private _insertChildren = compile (getText (_entryCfg >> "insertChildren")); private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction")); @@ -63,7 +63,6 @@ private _recurseFnc = { _runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0; }; - _condition = compile _condition; private _children = [_entryCfg] call _recurseFnc; private _entry = [ @@ -84,8 +83,7 @@ private _recurseFnc = { ]; _actions pushBack _entry; }; - nil - } count (configProperties [_actionsCfg, "isClass _x", true]); + } forEach (configProperties [_actionsCfg, "isClass _x", true]); _actions }; @@ -132,4 +130,4 @@ private _actions = [ ] ]; -_namespace setVariable [_objectType, _actions]; +GVAR(ActSelfNamespace) set [_objectType, _actions]; diff --git a/addons/interact_menu/functions/fnc_compileMenuZeus.sqf b/addons/interact_menu/functions/fnc_compileMenuZeus.sqf index af28bf2284..e4b926b3e3 100644 --- a/addons/interact_menu/functions/fnc_compileMenuZeus.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuZeus.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Compile the zeus action menu (only to be done once) * * Arguments: @@ -16,7 +16,7 @@ */ // Exit if the action menu is already compiled for zeus -if !(isNil {missionNamespace getVariable [QGVAR(ZeusActions), nil]}) exitWith {}; +if (!isNil {missionNamespace getVariable [QGVAR(ZeusActions), nil]}) exitWith {}; private _recurseFnc = { params ["_actionsCfg"]; @@ -24,7 +24,7 @@ private _recurseFnc = { { private _entryCfg = _x; - if(isClass _entryCfg) then { + if (isClass _entryCfg) then { private _displayName = getText (_entryCfg >> "displayName"); private _icon = if (isArray (_entryCfg >> "icon")) then { @@ -35,7 +35,11 @@ private _recurseFnc = { private _statement = compile (getText (_entryCfg >> "statement")); private _condition = getText (_entryCfg >> "condition"); - if (_condition == "") then {_condition = "true"}; + if (_condition == "") then { + _condition = {true}; + } else { + _condition = compile _condition; + }; private _insertChildren = compile (getText (_entryCfg >> "insertChildren")); private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction")); @@ -50,7 +54,6 @@ private _recurseFnc = { _runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0; }; - private _condition = compile _condition; private _children = [_entryCfg] call _recurseFnc; private _entry = [ diff --git a/addons/interact_menu/functions/fnc_createAction.sqf b/addons/interact_menu/functions/fnc_createAction.sqf index 428f8a26d7..ae00f4fb82 100644 --- a/addons/interact_menu/functions/fnc_createAction.sqf +++ b/addons/interact_menu/functions/fnc_createAction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Creates an isolated ACE action @@ -10,12 +10,12 @@ * 2: Icon file path or Array of icon file path and hex color ("" for default icon) * 3: Statement * 4: Condition - * 5: Insert children code (Optional) - * 6: Action parameters (Optional) - * 7: Position (Position array, Position code or Selection Name) , or (Optional) - * 8: Distance (Optional) - * 9: Other parameters [showDisabled,enableInside,canCollapse,runOnHover,doNotCheckLOS] (Optional) - * 10: Modifier function (Optional) + * 5: Insert children code (default: {}) + * 6: Action parameters (default: []) + * 7: Position (Position array, Position code or Selection Name) , or (default: {[0, 0, 0]}) + * 8: Distance (default: 2) + * 9: Other parameters [showDisabled,enableInside,canCollapse,runOnHover,doNotCheckLOS] (default: all false) + * 10: Modifier function (default: {}) * * Return Value: * Action @@ -49,7 +49,7 @@ _position = if (_position isEqualType "") then { } else { if (_position isEqualType []) then { // If the action is set to a array position, create the suitable code - compile format ["%1", _position]; + compile str _position; } else { _position; }; diff --git a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf index 8218242aab..3aef7b4552 100644 --- a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf +++ b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Creates child actions for vehicle list. @@ -21,13 +21,15 @@ params ["_vehicles", "_statement", "_target"]; _vehicles apply { - private _type = typeOf _x; - private _name = getText (configFile >> "CfgVehicles" >> _type >> "displayName"); + private _name = getText ((configOf _x) >> "displayName"); private _ownerName = [_x, true] call EFUNC(common,getName); + private _distanceStr = (ACE_player distance _x) toFixed 1; if ("" != _ownerName) then { - _name = format ["%1 (%2)", _name, _ownerName]; + _name = format ["%1 (%2, %3m)", _name, _ownerName, _distanceStr]; + } else { + _name = format ["%1 (%2m)", _name, _distanceStr]; }; - private _icon = [_type] call EFUNC(common,getVehicleIcon); - private _action = [format ["%1", _x], _name, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); + private _icon = [_x] call EFUNC(common,getVehicleIcon); + private _action = [str _x, _name, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); [_action, [], _target] } diff --git a/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf b/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf index deed10e293..dd75c37a3c 100644 --- a/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf +++ b/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Sets the controls structured text if it isn't already set. diff --git a/addons/interact_menu/functions/fnc_findActionNode.sqf b/addons/interact_menu/functions/fnc_findActionNode.sqf index c2807a3e9c..4e04fcebea 100644 --- a/addons/interact_menu/functions/fnc_findActionNode.sqf +++ b/addons/interact_menu/functions/fnc_findActionNode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Return action point from path @@ -9,7 +9,7 @@ * 1: Path * * Return Value: - * Action node or if not found + * Action node or if not found * * Example: * [actionTree, ["ACE_TapShoulderRight","VulcanPinchAction"]] call ace_interact_menu_fnc_findActionNode; diff --git a/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf b/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf index d915f57999..8922aca8f4 100644 --- a/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf +++ b/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handle the escape key being pressed. diff --git a/addons/interact_menu/functions/fnc_initMenuReorder.sqf b/addons/interact_menu/functions/fnc_initMenuReorder.sqf new file mode 100644 index 0000000000..d55f2f06ea --- /dev/null +++ b/addons/interact_menu/functions/fnc_initMenuReorder.sqf @@ -0,0 +1,89 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Initializes "More" and "Move to Root" settings and menu. + * + * Arguments: + * 0: Class name + * + * Return Value: + * None + * + * Example: + * [typeOf player] call ace_interact_menu_fnc_initMenuReorder + * + * Public: No + */ + +params ["_class"]; + +private _actionTrees = GVAR(ActSelfNamespace) get _class; +private _rootNode = [_actionTrees, ["ACE_SelfActions"]] call FUNC(findActionNode); +private _rootActions = _rootNode select 1; +private _settingCategoryPrefix = format ["ACE %1 - ", LELSTRING(Interaction,InteractionMenuSelf)]; + + +// init "Move to Root" settings +private _settingCategory = _settingCategoryPrefix + localize "STR_3DEN_Display3DEN_RemoveLayer_tooltip"; + +private _fnc_processNode = { + params ["_node", "_parentVarName", "_titlePrefix", "_parentConditionString"]; + + _node params ["_actionData", "_actionChildren"]; + _actionData params ["_name", "_title", "", "", "_condition"]; + private _varName = _parentVarName + "__" + _name; + private _titleFull = _titlePrefix + _title; + private _conditionFullString = format ["%1 && {%2}", _parentConditionString, _condition call EFUNC(common,codeToString)]; + + // don't add already added setting + if (isNil {missionNamespace getVariable _varName}) then { + [_varName, "CHECKBOX", _titleFull, [_settingCategory, _rootActionTitle], false, 2, {}, true] call CBA_fnc_addSetting; + }; + + if (missionNamespace getVariable [_varName, false]) then { + private _newActionData = +(_actionData); + _newActionData set [4, compile _conditionFullString]; + _rootActions pushBack [_newActionData, _actionChildren]; + }; + + { + [_x, _varName, _titleFull + " / ", _conditionFullString] call _fnc_processNode; + } forEach _actionChildren; +}; + +private _rootActionsCount = count _rootActions; +{ + _x params ["_actionData", "_actionChildren"]; + _actionData params ["_name", "_rootActionTitle", "", "", "_condition"]; + private _parentVarName = QGVAR(moveToRoot__) + _name; + private _conditionString = _condition call EFUNC(common,codeToString); + { + [_x, _parentVarName, "", _conditionString] call _fnc_processNode; + } forEach _actionChildren; +} forEach _rootActions; + + +// init "More" menu +private _action = [QGVAR(more), localize "str_more_menu", "", {}, {true}] call FUNC(createAction); +private _morePath = [_class, 1, ["ACE_SelfActions"], _action] call FUNC(addActionToClass); +private _moreNode = [_actionTrees, _morePath] call FUNC(findActionNode); +private _moreActions = _moreNode select 1; +private _settingCategory = _settingCategoryPrefix + localize "str_more_menu"; + +{ + // prevent moved to root actions processing + if (_forEachIndex >= _rootActionsCount) then {break}; + + _x params ["_actionData", "_actionChildren"]; + _actionData params ["_name", "_title"]; + if (_name isEqualTo QGVAR(more)) then {continue}; + + private _varName = QGVAR(more__) + _name; + [_varName, "CHECKBOX", _title, _settingCategory, false, 2, {}, true] call CBA_fnc_addSetting; + if !(missionNamespace getVariable [_varName, false]) then {continue}; + + private _newActionData = +(_actionData); + // disable action instead of deleting because it can be used as parent lately + _actionData set [4, {false}]; + _moreActions pushBack [_newActionData, _actionChildren]; +} forEach _rootActions; diff --git a/addons/interact_menu/functions/fnc_isSubPath.sqf b/addons/interact_menu/functions/fnc_isSubPath.sqf index 72857f3070..5b58b1b1f0 100644 --- a/addons/interact_menu/functions/fnc_isSubPath.sqf +++ b/addons/interact_menu/functions/fnc_isSubPath.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Check if the first path is a subpath of the other @@ -24,7 +24,7 @@ if (count _shortPath > count _longPath) exitWith {false}; //IGNORE_PRIVATE_WARNING ["_i"]; for [{private _i = 0},{_i < count _shortPath},{_i = _i + 1}] do { - if !((_longPath select _i) isEqualTo (_shortPath select _i)) exitWith { + if ((_longPath select _i) isNotEqualTo (_shortPath select _i)) exitWith { _isSubPath = false; }; }; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 54a9f070ce..9cb638bcea 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Handle interactions key down @@ -15,13 +15,29 @@ * Public: No */ +#include "\a3\ui_f\hpp\defineResincl.inc" + params ["_menuType"]; if (GVAR(openedMenuType) == _menuType) exitWith {true}; +// Conditions: Don't open when editing a text box +private _focusedTextIndex = allDisplays findIf {(ctrlType (focusedCtrl _x)) == CT_EDIT}; +private _isTextEditing = _focusedTextIndex != -1; + +// Map's controls remain open and focused despite map not being visible, workaround +if (_isTextEditing) then { + if (ctrlIDD (allDisplays select _focusedTextIndex) == IDD_MAIN_MAP) then { + _isTextEditing = visibleMap; + }; +}; + // Conditions: canInteract (these don't apply to zeus) -if ((isNull curatorCamera) && { - !([ACE_player, objNull, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)) +if ( + _isTextEditing || + {(isNull curatorCamera) && { + !([ACE_player, objNull, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)) + } }) exitWith {false}; while {dialog} do { @@ -36,6 +52,12 @@ if (_menuType == 0) then { GVAR(keyDownSelfAction) = true; }; GVAR(keyDownTime) = diag_tickTime; + +// Raise MenuClosed event whenever one type is replaced with another, because KeyUp code is not guaranteed. +if (GVAR(openedMenuType) != -1) then { + ["ace_interactMenuClosed", [GVAR(openedMenuType)]] call CBA_fnc_localEvent; +}; + GVAR(openedMenuType) = _menuType; GVAR(lastTimeSearchedActions) = -1000; GVAR(ParsedTextCached) = []; @@ -44,8 +66,8 @@ GVAR(useCursorMenu) = (vehicle ACE_player != ACE_player) || (!(isNull (ACE_controlledUAV select 0))) || visibleMap || (!isNull curatorCamera) || - {(_menuType == 1) && {(isWeaponDeployed ACE_player) || GVAR(AlwaysUseCursorSelfInteraction) || {cameraView == "GUNNER"}}} || - {(_menuType == 0) && GVAR(AlwaysUseCursorInteraction)}; + {(_menuType == 1) && {(isWeaponDeployed ACE_player) || GVAR(alwaysUseCursorSelfInteraction) || {cameraView == "GUNNER"}}} || + {(_menuType == 0) && GVAR(alwaysUseCursorInteraction)}; // Delete existing controls in case there's any left GVAR(iconCount) = 0; @@ -94,7 +116,7 @@ GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; GVAR(expanded) = true; GVAR(expandedTime) = diag_tickTime; diff --git a/addons/interact_menu/functions/fnc_keyUp.sqf b/addons/interact_menu/functions/fnc_keyUp.sqf index be98452177..a12a404da7 100644 --- a/addons/interact_menu/functions/fnc_keyUp.sqf +++ b/addons/interact_menu/functions/fnc_keyUp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Handle interactions key up @@ -23,10 +23,9 @@ if (GVAR(openedMenuType) < 0) exitWith {true}; if (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then { (findDisplay 91919) closeDisplay 2; }; +if ((!isNull curatorCamera) && {!isNull (findDisplay 91919)}) then { closeDialog 2; }; -if(GVAR(actionSelected)) then { - this = GVAR(selectedTarget); - +if (GVAR(actionSelected)) then { private _player = ACE_Player; private _target = GVAR(selectedTarget); @@ -38,6 +37,11 @@ if(GVAR(actionSelected)) then { // Check the action conditions private _actionData = GVAR(selectedAction) select 0; + + // Use global variable this for action condition and action code + private _savedThis = this; + this = GVAR(selectedTarget); + if ([_target, _player, _actionData select 6] call (_actionData select 4)) then { // Call the statement [_target, _player, _actionData select 6] call (_actionData select 3); @@ -45,6 +49,9 @@ if(GVAR(actionSelected)) then { // Clear the conditions caches again if the action was performed [QGVAR(clearConditionCaches), []] call CBA_fnc_localEvent; }; + + // Restore this variable + this = _savedThis; }; ["ace_interactMenuClosed", [GVAR(openedMenuType)]] call CBA_fnc_localEvent; diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf index 92de6b872a..7585616ef6 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Removes an action from a class @@ -19,23 +19,22 @@ params ["_objectType", "_typeNum", "_fullPath"]; +_objectType = _objectType call EFUNC(common,getConfigName); + private _res = _fullPath call FUNC(splitPath); _res params ["_parentPath", "_actionName"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith {}; +if (isNil "_parentNode") exitWith {}; // Iterate through children of the father private _found = false; { if (((_x select 0) select 0) == _actionName) exitWith { - TRACE_2("Deleting Action", _forEachIndex, _x); + TRACE_2("Deleting Action",_forEachIndex,_x); _found = true; (_parentNode select 1) deleteAt _forEachIndex; }; diff --git a/addons/interact_menu/functions/fnc_removeActionFromObject.sqf b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf index 64c96ec949..cb1c4a31d0 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromObject.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, NouberNou and esteldunedain * Removes an action from an object diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index 687498e7cd..e4ee0d6357 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Render all available nearby interactions @@ -62,7 +62,7 @@ if (GVAR(openedMenuType) >= 0) then { GVAR(selectedAction) = _action select 1; GVAR(selectedTarget) = (GVAR(selectedAction)) select 2; - private _misMatch = !(GVAR(lastPath) isEqualTo _hoverPath); + private _misMatch = (GVAR(lastPath) isNotEqualTo _hoverPath); if(_misMatch && {diag_tickTime-GVAR(expandedTime) > linearConversion [0, 2, GVAR(menuAnimationSpeed), 0.25, 0.08333333]}) then { GVAR(startHoverTime) = diag_tickTime; @@ -91,13 +91,16 @@ if (GVAR(openedMenuType) >= 0) then { }; }; if (_runOnHover) then { - this = GVAR(selectedTarget); private _player = ACE_Player; private _target = GVAR(selectedTarget); // Clear the conditions caches [QGVAR(clearConditionCaches), []] call CBA_fnc_localEvent; + // Use global variable this for action condition and action code + private _savedThis = this; + this = GVAR(selectedTarget); + // Check the action conditions private _actionData = GVAR(selectedAction) select 0; if ([_target, _player, _actionData select 6] call (_actionData select 4)) then { @@ -107,6 +110,9 @@ if (GVAR(openedMenuType) >= 0) then { // Clear the conditions caches again if the action was performed [QGVAR(clearConditionCaches), []] call CBA_fnc_localEvent; }; + + // Restore this variable + this = _savedThis; }; }; }; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index f4aa8927f6..62d29be91f 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Render all action points @@ -29,57 +29,54 @@ private _fnc_renderNearbyActions = { GVAR(foundActions) = []; GVAR(lastTimeSearchedActions) = diag_tickTime; + QGVAR(renderNearbyActions) call CBA_fnc_localEvent; + private _numInteractObjects = 0; private _nearestObjects = nearestObjects [ACE_player, ["All"], 13]; { private _target = _x; // Quick oclussion test. Skip objects more than 1 m behind the camera plane - private _lambda = ((getPosASL _x) vectorDiff GVAR(cameraPosASL)) vectorDotProduct GVAR(cameraDir); - if ((_lambda > -1) && {!isObjectHidden _target}) then { - private _numInteractions = 0; + private _lambda = getPosASL _target vectorDiff GVAR(cameraPosASL) vectorDotProduct GVAR(cameraDir); + if ( + _lambda <= -1 + || {isObjectHidden _target} // Prevent interacting with yourself or your own vehicle - if (_target != ACE_player && {_target != vehicle ACE_player}) then { + || {_target in [ACE_player, vehicle ACE_player]} + ) then {continue}; - // Iterate through object actions, find base level actions and render them if appropiate - GVAR(objectActionList) = _target getVariable [QGVAR(actions), []]; - { - // Only render them directly if they are base level actions - if ((_x select 1) isEqualTo []) then { - // Try to render the menu - private _action = _x; - if ([_target, _action] call FUNC(renderBaseMenu)) then { - _numInteractions = _numInteractions + 1; - GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)]; - }; - }; - nil - } count GVAR(objectActionList); + private _hasInteractions = false; - // Iterate through base level class actions and render them if appropiate - private _namespace = GVAR(ActNamespace); - private _classActions = _namespace getVariable typeOf _target; - - { - private _action = _x; - // Try to render the menu - if ([_target, _action] call FUNC(renderBaseMenu)) then { - _numInteractions = _numInteractions + 1; - GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)]; - }; - nil - } count _classActions; - - // Limit the amount of objects the player can interact with - if (_numInteractions > 0) then { - _numInteractObjects = _numInteractObjects + 1; - }; + // Iterate through object actions, find base level actions and render them if appropiate + GVAR(objectActionList) = _target getVariable [QGVAR(actions), []]; + { + // Only render them directly if they are base level actions + if (_x select 1 isNotEqualTo []) then {continue}; + // Try to render the menu + private _action = _x; + if ([_target, _action] call FUNC(renderBaseMenu)) then { + _hasInteractions = true; + GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)]; }; - }; - if (_numInteractObjects >= MAXINTERACTOBJECTS) exitWith {}; + } forEach GVAR(objectActionList); - nil - } count _nearestObjects; + // Iterate through base level class actions and render them if appropiate + private _classActions = GVAR(ActNamespace) getOrDefault [typeOf _target, []]; + { + private _action = _x; + // Try to render the menu + if ([_target, _action] call FUNC(renderBaseMenu)) then { + _hasInteractions = true; + GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)]; + }; + } forEach _classActions; + + // Limit the amount of objects the player can interact with + if (_hasInteractions) then { + INC(_numInteractObjects); + if (_numInteractObjects >= MAXINTERACTOBJECTS) then {break}; + }; + } forEach _nearestObjects; }; private _fnc_renderLastFrameActions = { @@ -88,8 +85,7 @@ private _fnc_renderLastFrameActions = { GVAR(objectActionList) = _objectActionList; [_target, _action] call FUNC(renderBaseMenu); - nil - } count GVAR(foundActions); + } forEach GVAR(foundActions); }; private _fnc_renderSelfActions = { @@ -99,8 +95,7 @@ private _fnc_renderSelfActions = { GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []]; // Iterate through base level class actions and render them if appropiate - private _namespace = GVAR(ActSelfNamespace); - private _classActions = _namespace getVariable typeOf _target; + private _classActions = GVAR(ActSelfNamespace) get typeOf _target; private _pos = if !(GVAR(useCursorMenu)) then { //Convert to ASL, add offset and then convert back to AGL (handles waves when over water) @@ -112,16 +107,14 @@ private _fnc_renderSelfActions = { { _action = _x; [_target, _action, _pos] call FUNC(renderBaseMenu); - nil - } count _classActions; + } forEach _classActions; }; private _fnc_renderZeusActions = { { private _action = _x; [_this, _action, [0.5, 0.5]] call FUNC(renderBaseMenu); - nil - } count GVAR(ZeusActions); + } forEach GVAR(ZeusActions); }; @@ -130,7 +123,7 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { // Render UAV self actions when in control of UAV AI (ACE_controlledUAV select 0) call _fnc_renderSelfActions; } else { @@ -178,5 +171,4 @@ if (count GVAR(collectedActionPoints) > 1) then { { _x params ["_z", "_sPos", "_activeActionTree"]; [[], _activeActionTree, _sPos, [180,360]] call FUNC(renderMenu); - nil -} count GVAR(collectedActionPoints); +} forEach GVAR(collectedActionPoints); diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index 45c30696f3..9e3aaa53a9 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Render the interaction menu for a base action diff --git a/addons/interact_menu/functions/fnc_renderIcon.sqf b/addons/interact_menu/functions/fnc_renderIcon.sqf index 21f1962180..fffa5e91a7 100644 --- a/addons/interact_menu/functions/fnc_renderIcon.sqf +++ b/addons/interact_menu/functions/fnc_renderIcon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou, esteldunedain, mharis001 * Render a single interaction icon. @@ -38,7 +38,7 @@ if (_iconFile isEqualTo "") then { _iconFile = DEFAULT_ICON; }; -_text = if (GVAR(UseListMenu)) then { +_text = if ([GVAR(useListMenu), GVAR(useListMenuSelf)] select GVAR(keyDownSelfAction)) then { format ["%4", _iconFile, _iconColor, _textSettings, _text] } else { format ["
%4", _iconFile, _iconColor, _textSettings, "ace_break_line" callExtension _text]; @@ -47,13 +47,14 @@ _text = if (GVAR(UseListMenu)) then { [_ctrl, GVAR(iconCount), _text] call FUNC(ctrlSetParsedTextCached); GVAR(iconCount) = GVAR(iconCount) + 1; -private _pos = if (GVAR(UseListMenu)) then { +private _pos = if ([GVAR(useListMenu), GVAR(useListMenuSelf)] select GVAR(keyDownSelfAction)) then { [(_sPos select 0) - (0.0095 * SafeZoneW), (_sPos select 1) - (0.0095 * SafeZoneW), 0.20 * SafeZoneW, 0.035 * SafeZoneW] } else { [(_sPos select 0) - (0.0750 * SafeZoneW), (_sPos select 1) - (0.0095 * SafeZoneW), 0.15 * SafeZoneW, 0.100 * SafeZoneW] }; -if (GVAR(cursorKeepCentered) && {uiNamespace getVariable [QGVAR(cursorMenuOpened),false]}) then { + +if (([GVAR(cursorKeepCentered), GVAR(cursorKeepCenteredSelfInteraction)] select GVAR(keyDownSelfAction)) && {uiNamespace getVariable [QGVAR(cursorMenuOpened),false]}) then { _pos set [0, ((_pos select 0) - (GVAR(cursorPos) select 0) + 0.5)]; _pos set [1, ((_pos select 1) - (GVAR(cursorPos) select 1) + 0.5)]; }; diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index 5801f4602f..3aa8a05ab3 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: NouberNou and esteldunedain * Render an interaction menu and it's children recursively @@ -36,7 +36,7 @@ private _menuInSelectedPath = true; if (_forEachIndex >= (count GVAR(menuDepthPath))) exitWith { _menuInSelectedPath = false; }; - if !(_x isEqualTo (GVAR(menuDepthPath) select _forEachIndex)) exitWith { + if (_x isNotEqualTo (GVAR(menuDepthPath) select _forEachIndex)) exitWith { _menuInSelectedPath = false; }; } forEach _path; @@ -89,13 +89,13 @@ if (_numChildren == 1) then { // Scale menu based on the amount of children private _scaleX = 1; private _scaleY = 1; - -if (GVAR(UseListMenu)) then { +private _useListMenu = [GVAR(useListMenu), GVAR(useListMenuSelf)] select GVAR(keyDownSelfAction); +if (_useListMenu) then { private _textSize = [0.75, 0.875, 1, 1.2, 1.4] select GVAR(textSize); _scaleX = _textSize * 0.17 * 1.1; _scaleY = 0.17 * 0.30 * 4/3; } else { - private _textSize = if (GVAR(textSize) > 2) then {1.3} else {1}; + private _textSIze = [1, 1.3] select (GVAR(textSize) > 2); _scaleX = _textSize * 0.17 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5); _scaleY = _textSize * 0.17 * 4/3 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5); }; @@ -112,7 +112,7 @@ private _player = ACE_player; //END_COUNTER(children); private _angle = _centerAngle - _angleSpan / 2; { - private _newPos = if (GVAR(UseListMenu)) then { + private _newPos = if (_useListMenu) then { [(_sPos select 0) + _scaleX, (_sPos select 1) + _scaleY * (_forEachIndex - _numChildren/2 + 0.5)]; } else { diff --git a/addons/interact_menu/functions/fnc_renderSelector.sqf b/addons/interact_menu/functions/fnc_renderSelector.sqf index 0449f9c922..bf71929924 100644 --- a/addons/interact_menu/functions/fnc_renderSelector.sqf +++ b/addons/interact_menu/functions/fnc_renderSelector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Render a single interaction icon @@ -39,7 +39,7 @@ private _pos = if (GVAR(UseListMenu)) then { GVAR(iconCount) = GVAR(iconCount) + 1; -if (GVAR(cursorKeepCentered) && {uiNamespace getVariable [QGVAR(cursorMenuOpened),false]}) then { +if (([GVAR(cursorKeepCentered), GVAR(cursorKeepCenteredSelfInteraction)] select GVAR(keyDownSelfAction)) && {uiNamespace getVariable [QGVAR(cursorMenuOpened), false]}) then { _pos set [0, ((_pos select 0) - (GVAR(cursorPos) select 0) + 0.5)]; _pos set [1, ((_pos select 1) - (GVAR(cursorPos) select 1) + 0.5)]; }; diff --git a/addons/interact_menu/functions/fnc_setupTextColors.sqf b/addons/interact_menu/functions/fnc_setupTextColors.sqf index 3d0a369c60..ff2107587f 100644 --- a/addons/interact_menu/functions/fnc_setupTextColors.sqf +++ b/addons/interact_menu/functions/fnc_setupTextColors.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Builds color strings needed for displaying interaction text @@ -10,7 +10,7 @@ * None * * Example: - * call ACE_interact_menu_fnc_setupTextColor + * call ace_interact_menu_fnc_setupTextColors * * Public: No */ diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index bd59a39d33..8fabaca5a5 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Take full path and split it between parent path and action name @@ -17,11 +17,13 @@ */ private _parentPath = []; -for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { - _parentPath pushBack (_this select _i); -}; -private _actionName = if (count _this > 0) then { - _this select ((count _this) - 1); + +_parentPath append _this; + +private _count = count _this; + +private _actionName = if (_count > 0) then { + _parentPath deleteAt (_count - 1) // TODO: replace with _parentPath deleteAt [-1] and drop _count in 2.18 } else { "" }; diff --git a/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf index 2497021e00..b87f6133f3 100644 --- a/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Scans for nearby "Static" objects (buildings) and adds the UserActions to them. @@ -27,21 +27,21 @@ if ((vehicle ACE_player) != ACE_player) exitWith {}; [{ params ["_args", "_pfID"]; - _args params ["_setPosition", "_addedHelpers", "_housesScaned", "_housesToScanForActions"]; + _args params ["_setPosition", "_addedHelpers", "_housesScanned", "_housesToScanForActions"]; if (!EGVAR(interact_menu,keyDown)) then { {deleteVehicle _x;} forEach _addedHelpers; [_pfID] call CBA_fnc_removePerFrameHandler; } else { // Prevent Rare Error when ending mission with interact key down: - if (isNull ace_player) exitWith {}; + if (isNull ACE_player) exitWith {}; //Make the common case fast (cursorTarget is looking at a door): - if ((!isNull cursorTarget) && {cursorTarget isKindOf "Static"} && {!(cursorTarget in _housesScaned)}) then { - if (((count (configFile >> "CfgVehicles" >> (typeOf cursorTarget) >> "UserActions")) > 0) || {(count (getArray (configFile >> "CfgVehicles" >> (typeOf cursorTarget) >> "ladders"))) > 0}) then { + if ((!isNull cursorTarget) && {cursorTarget isKindOf "Static"} && {!(cursorTarget in _housesScanned)}) then { + if (((count (configOf cursorTarget >> "UserActions")) > 0) || {(count (getArray (configOf cursorTarget >> "ladders"))) > 0}) then { _housesToScanForActions = [cursorTarget]; } else { - _housesScaned pushBack cursorTarget; + _housesScanned pushBack cursorTarget; }; }; @@ -51,47 +51,43 @@ if ((vehicle ACE_player) != ACE_player) exitWith {}; if (_housesToScanForActions isEqualTo []) then { //If player moved >2 meters from last pos, then rescan - if (((getPosASL ace_player) distance _setPosition) < 2) exitWith {}; + if (((getPosASL ACE_player) distance _setPosition) < 2) exitWith {}; - private _nearBuidlings = nearestObjects [ace_player, ["Static"], 30]; + private _nearBuidlings = nearestObjects [ACE_player, ["Static"], 30]; { - private _typeOfHouse = typeOf _x; - if (((count (configFile >> "CfgVehicles" >> _typeOfHouse >> "UserActions")) == 0) && {(count (getArray (configFile >> "CfgVehicles" >> _typeOfHouse >> "ladders"))) == 0}) then { - _housesScaned pushBack _x; + private _configOfHouse = configOf _x; + if (((count (_configOfHouse >> "UserActions")) == 0) && {(count (getArray (_configOfHouse >> "ladders"))) == 0}) then { + _housesScanned pushBack _x; } else { _housesToScanForActions pushBack _x; }; - nil - } count (_nearBuidlings - _housesScaned); + } forEach (_nearBuidlings - _housesScanned); - _args set [0, (getPosASL ace_player)]; + _args set [0, (getPosASL ACE_player)]; } else { - _houseBeingScaned = _housesToScanForActions deleteAt 0; - private _typeOfHouse = typeOf _houseBeingScaned; + private _houseBeingScanned = _housesToScanForActions deleteAt 0; //Skip this house for now if we are outside of it's radius //(we have to scan far out for the big houses, but we don't want to waste time adding actions on every little shack) - if ((_houseBeingScaned != cursorTarget) && {((ACE_player distance _houseBeingScaned) - ((sizeOf _typeOfHouse) / 2)) > 4}) exitWith {}; + if ((_houseBeingScanned != cursorTarget) && {((ACE_player distance _houseBeingScanned) - ((boundingBoxReal _houseBeingScanned) select 2)) > 4}) exitWith {}; - _housesScaned pushBack _houseBeingScaned; + _housesScanned pushBack _houseBeingScanned; - private _actionSet = [_typeOfHouse] call FUNC(userActions_getHouseActions); + private _actionSet = [typeOf _houseBeingScanned] call FUNC(userActions_getHouseActions); _actionSet params ["_memPoints", "_memPointsActions"]; - // systemChat format ["Add Actions for [%1] (count %2) @ %3", _typeOfHouse, (count _memPoints), diag_tickTime]; + TRACE_3("Add Actions for [%1] (count %2) @ %3",typeOf _houseBeingScanned,(count _memPoints),diag_tickTime); { - private _helperPos = AGLtoASL (_houseBeingScaned modelToWorld (_houseBeingScaned selectionPosition _x)); + private _helperPos = _houseBeingScanned modelToWorldWorld (_houseBeingScanned selectionPosition _x); private _helperObject = "ACE_LogicDummy" createVehicleLocal [0,0,0]; _addedHelpers pushBack _helperObject; - _helperObject setVariable [QGVAR(building), _houseBeingScaned]; + _helperObject setVariable [QGVAR(building), _houseBeingScanned]; _helperObject setPosASL _helperPos; - TRACE_3("Making New Helper",_helperObject,_x,_houseBeingScaned); + TRACE_3("Making New Helper",_helperObject,_x,_houseBeingScanned); { [_helperObject, 0, [], _x] call EFUNC(interact_menu,addActionToObject); - nil - } count (_memPointsActions select _forEachIndex); - + } forEach (_memPointsActions select _forEachIndex); } forEach _memPoints; }; }; -}, 0, [((getPosASL ace_player) vectorAdd [-100,0,0]), [], [], []]] call CBA_fnc_addPerFrameHandler; +}, 0, [((getPosASL ACE_player) vectorAdd [-100,0,0]), [], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf index 46667857f5..8f28950840 100644 --- a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Scans the buidling type for UserActions and Ladder mount points. @@ -17,8 +17,9 @@ params ["_typeOfBuilding"]; -private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding; -if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex}; +private _cachedMemPoints = GVAR(cachedBuildingTypes) get _typeOfBuilding; + +if (!isNil "_cachedMemPoints") exitWith {_cachedMemPoints}; private _memPoints = []; private _memPointsActions = []; @@ -26,8 +27,8 @@ private _memPointsActions = []; //Get the offset for a memory point: private _fnc_getMemPointOffset = { params ["_memoryPoint"]; - _memPointIndex = _memPoints find _memoryPoint; - _actionOffset = [0,0,0]; + private _memPointIndex = _memPoints find _memoryPoint; + private _actionOffset = [0,0,0]; if (_memPointIndex == -1) then { _memPoints pushBack _memoryPoint; _memPointsActions pushBack []; @@ -41,15 +42,34 @@ private _fnc_getMemPointOffset = { private _fnc_userAction_Statement = { params ["_target", "_player", "_variable"]; _variable params ["_actionStatement", "_actionCondition"]; + + // Use global variable this for action condition and action code + private _savedThis = this; this = _target getVariable [QGVAR(building), objNull]; + call _actionStatement; + + // Restore this variable + this = _savedThis; }; + private _fnc_userAction_Condition = { params ["_target", "_player", "_variable"]; _variable params ["_actionStatement", "_actionCondition"]; + + private _building = _target getVariable [QGVAR(building), objNull]; + if (isNull _building) exitWith {false}; + + // Use global variable this for action condition and action code + private _savedThis = this; this = _target getVariable [QGVAR(building), objNull]; - if (isNull this) exitWith {false}; - call _actionCondition; + + private _result = call _actionCondition; + + // Restore this variable + this = _savedThis; + + _result }; private _configPath = configFile >> "CfgVehicles" >> _typeOfBuilding >> "UserActions"; @@ -63,7 +83,7 @@ for "_index" from 0 to ((count _configPath) - 1) do { private _actionStatement = getText (_actionPath >> "statement"); private _actionMaxDistance = getNumber (_actionPath >> "radius"); - if (_actionDisplayName == "") then {_actionDisplayName = (configName _x);}; + if (_actionDisplayName == "") then {_actionDisplayName = configName _actionPath;}; if (_actionPosition == "") then {ERROR("Bad Position");}; if (_actionCondition == "") then {_actionCondition = "true";}; if (_actionStatement == "") then {ERROR("No Statement");}; @@ -72,13 +92,12 @@ for "_index" from 0 to ((count _configPath) - 1) do { _actionCondition = compile _actionCondition; _actionMaxDistance = _actionMaxDistance + 0.1; //increase range slightly - //extension ~4x as fast: - private _iconImage = "ace_parse_imagepath" callExtension _actionDisplayNameDefault; + private _iconImage = ((_actionDisplayNameDefault regexFind ["[\w\-\\\/]+.paa/gi", 0]) param [0, []]) param [0, []] param [0, ""]; private _actionOffset = [_actionPosition] call _fnc_getMemPointOffset; private _memPointIndex = _memPoints find _actionPosition; - _action = [(configName _actionPath), _actionDisplayName, _iconImage, _fnc_userAction_Statement, _fnc_userAction_Condition, {}, [_actionStatement, _actionCondition], _actionOffset, _actionMaxDistance, [false,false,false,false,true]] call EFUNC(interact_menu,createAction); + private _action = [(configName _actionPath), _actionDisplayName, _iconImage, _fnc_userAction_Statement, _fnc_userAction_Condition, {}, [_actionStatement, _actionCondition], _actionOffset, _actionMaxDistance, [false,false,false,false,true]] call EFUNC(interact_menu,createAction); (_memPointsActions select _memPointIndex) pushBack _action; }; @@ -130,8 +149,6 @@ private _ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> " } forEach _ladders; -GVAR(cachedBuildingTypes) pushBack _typeOfBuilding; -GVAR(cachedBuildingActionPairs) pushBack [_memPoints, _memPointsActions]; - +GVAR(cachedBuildingTypes) set [_typeOfBuilding, [_memPoints, _memPointsActions]]; [_memPoints, _memPointsActions] diff --git a/addons/interact_menu/functions/script_component.hpp b/addons/interact_menu/functions/script_component.hpp deleted file mode 100644 index 723a7735f1..0000000000 --- a/addons/interact_menu/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\interact_menu\script_component.hpp" \ No newline at end of file diff --git a/addons/interact_menu/initSettings.inc.sqf b/addons/interact_menu/initSettings.inc.sqf new file mode 100644 index 0000000000..c175bd17c2 --- /dev/null +++ b/addons/interact_menu/initSettings.inc.sqf @@ -0,0 +1,153 @@ +private _category = format ["ACE %1", LLSTRING(Category_InteractionMenu)]; +private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcategory_colors)]]; + +[ + QGVAR(selectorColor), "COLOR", + LSTRING(SelectorColor), + _categoryColors, + [1, 0, 0], + false, + {GVAR(selectorColorHex) = _this call BIS_fnc_colorRGBtoHTML} // Stored in Hex to avoid constant conversion +] call CBA_fnc_addSetting; + +[ + QGVAR(colorTextMax), "COLOR", + LSTRING(ColorTextMax), + _categoryColors, + [1, 1, 1, 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(colorTextMin), "COLOR", + LSTRING(ColorTextMin), + _categoryColors, + [1, 1, 1, 0.25], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(colorShadowMax), "COLOR", + LSTRING(ColorShadowMax), + _categoryColors, + [0, 0, 0, 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(colorShadowMin), "COLOR", + LSTRING(ColorShadowMin), + _categoryColors, + [0, 0, 0, 0.25], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(textSize), "LIST", + LSTRING(textSize), + _category, + [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2] +] call CBA_fnc_addSetting; + +[ + QGVAR(shadowSetting), "LIST", + [LSTRING(shadowSetting), LSTRING(shadowSettingDescription)], + _category, + [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", "STR_A3_OPTIONS_ENABLED", LSTRING(shadowOutline)], 2], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(actionOnKeyRelease), "CHECKBOX", + LSTRING(ActionOnKeyRelease), + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(addBuildingActions), "CHECKBOX", + [LSTRING(addBuildingActions), LSTRING(addBuildingActionsDescription)], + _category, + false, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(menuAnimationSpeed), "LIST", + [LSTRING(menuAnimationSpeed), LSTRING(menuAnimationSpeed_Description)], + _category, + [[0, 1, 2], ["str_speed_normal", "2x", "3x"], 0], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(consolidateSingleChild), "CHECKBOX", + [LSTRING(consolidateSingleChild), LSTRING(consolidateSingleChild_Description)], + _category, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(alwaysUseCursorInteraction), "CHECKBOX", + LSTRING(AlwaysUseCursorInteraction), + [_category, LLSTRING(Category_InteractionMenu)], + false, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(cursorKeepCentered), "CHECKBOX", + [LSTRING(cursorKeepCentered), LSTRING(cursorKeepCenteredDescription)], + [_category, LLSTRING(Category_InteractionMenu)], + false, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(useListMenu), "CHECKBOX", + LSTRING(UseListMenu), + [_category, LLSTRING(Category_InteractionMenu)], + true, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(menuBackground), "LIST", + LSTRING(background), + [_category, LLSTRING(Category_InteractionMenu)], + [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", LLSTRING(backgroundBlur), LLSTRING(backgroundBlack)], 0], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(alwaysUseCursorSelfInteraction), "CHECKBOX", + LSTRING(AlwaysUseCursorInteraction), + [_category, LELSTRING(Interaction,InteractionMenuSelf)], + true, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(cursorKeepCenteredSelfInteraction), "CHECKBOX", + [LSTRING(cursorKeepCentered), LSTRING(cursorKeepCenteredDescription)], + [_category, LELSTRING(Interaction,InteractionMenuSelf)], + false, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(useListMenuSelf), "CHECKBOX", + LSTRING(UseListMenu), + [_category, LELSTRING(Interaction,InteractionMenuSelf)], + false, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(menuBackgroundSelf), "LIST", + LSTRING(background), + [_category, LELSTRING(Interaction,InteractionMenuSelf)], + [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", LLSTRING(backgroundBlur), LLSTRING(backgroundBlack)], 0], + false +] call CBA_fnc_addSetting; diff --git a/addons/interact_menu/initSettings.sqf b/addons/interact_menu/initSettings.sqf deleted file mode 100644 index 45c9fdbd3b..0000000000 --- a/addons/interact_menu/initSettings.sqf +++ /dev/null @@ -1,9 +0,0 @@ -[ - QGVAR(selectorColor), - "COLOR", - localize LSTRING(SelectorColor), - format ["ACE %1", localize LSTRING(Category_InteractionMenu)], - [1, 0, 0], - false, - {GVAR(selectorColorHex) = _this call BIS_fnc_colorRGBtoHTML} // Stored in Hex to avoid constant conversion -] call CBA_settings_fnc_init; diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index 599855f826..ce4da0c506 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -10,12 +10,13 @@ Zawsze wyświetlaj kursor dla własnej interakcji Toujours afficher le curseur pour les interactions sur soi-même Mindig legyen a saját cselekvés kurzorja látható - Mostra sempre il cursore delle autointerazioni + Mostra sempre il cursore per le autointerazioni Sempre mostrar cursor para interação pessoal セルフ インタラクションへ常にカーソルを表示 - 자기상호작용시 항상 커서를 보이기 - 自我互动时永远显示游标 + 자기상호작용 시 항상 커서를 보이기 + 自我互动时永远显示光标 自我互動時永遠顯示游標 + Kendi kendine etkileşim için daima imleci göster Always display cursor for interaction @@ -29,9 +30,10 @@ Mindig legyen a cselekvés kurzorja látható Sempre mostrar cursor para interação インタラクションへ常にカーソルを表示 - 상호작용시 항상 커서를 보이기 - 互动时永远显示游标 + 상호작용 시 항상 커서를 보이기 + 互动时永远显示光标 互動時永遠顯示游標 + Etkileşim için her zaman imleci göster Display interaction menus as lists @@ -44,10 +46,11 @@ Interaktionsmenü in Listen anzeigen Cselekvő menük listaként való megjelenítése Mostrar menu de interação como listas - インタラクション メニューを一覧表示 + インタラクションメニューを一覧表示 상호작용메뉴를 리스트화 해서 보이기 以列表方式显示互动表单 以列表方式顯示互動表單 + Etkileşim menülerini listeler halinde görüntüle Interact Key @@ -64,6 +67,7 @@ 상호작용 키 互动键 互動鍵 + Etkileşim Tuşu Self Interaction Key @@ -74,12 +78,13 @@ Klawisz własnej interakcji Touche d'interaction personnelle Saját cselekvő gomb - Tasto interazione su se stessi + Tasto autointerazioni Tecla de Interação Pessoal セルフ インタラクション キー 자기상호작용 키 自我互动键 自我互動鍵 + Kendi Etkileşimim Tuşu Self Actions @@ -90,12 +95,13 @@ Własne akcje Interaction personnelle Saját cselekvések - Interazioni su se stessi + Autointerazioni Ações Pessoais - 自分への動作 + 自分へのアクション 자기 동작 自我动作 自我動作 + Kendi Etkileşimim Vehicle Actions @@ -106,12 +112,13 @@ Akcje pojazdu Interaction véhicule Járműves cselekvések - Interazioni con veicoli + Interazioni su veicoli Ações de Veículos - 車両への動作 + 車両へのアクション 차량 동작 载具动作 載具動作 + Araç Etkileşimi Zeus Actions @@ -123,17 +130,18 @@ Zeus cselekvések Ações do Zeus Действия Зевса - Azioni Zeus - Zeus への動作 - Zeus 동작 + Interazioni Zeus + Zeusでのアクション + 제우스 동작 宙斯操作 宙斯操作 + Zeus Etkileşimi Interaction - Text Max Interakcja - Tekst max Interakce - Text Max - Interaction - Texte Max + Interaction - Texte max Interaktionstextfarbe Max Interazioni - Testo Massimo Взаимодействие - Текст Макс. @@ -142,14 +150,15 @@ Interação - Max. de Texto インタラクション - 文字の色 상호작용 - 문자색깔 - 互动-文字颜色最大值 + 互动—文字颜色最大值 互動 - 文字最大化 + Etkileşim - Maksimum Metin Interaction - Text Min Interakcja - Tekst min Interakce - Text Min - Interaction - Texte Min + Interaction - Texte min Interaktionstextfarbe Min Interazioni - Testo Minimo Взаимодействие - Текст Мин. @@ -158,14 +167,15 @@ Interação - Min. de Texto インタラクション - 文字の背景色 상호작용 - 문자배경색 - 互动-文字颜色最小值 + 互动—文字颜色最小值 互動 - 文字最小化 + Etkileşim - Minumum Metin Interaction - Shadow Max Interakcja - Cień max Interakce - Stín Max - Interaction - Ombre Max + Interaction - Ombre max Interaktionstextschatten Max Interazioni - Ombra Massima Взаимодействие - Тень Макс. @@ -174,14 +184,15 @@ Interação - Max. de Sombra インタラクション - 文字への影の色 상호작용 - 문자그림자색 - 互动 - 阴影最大值 + 互动—阴影最大值 互動 - 陰影最大化 + Etkileşim - Maksimum Gölge Interaction - Shadow Min Interakcja - Cień min Interakce - Stín Min - Interaction - Ombre Min + Interaction - Ombre min Interaktionstextschatten Min Interazioni - Ombra Minima Взаимодействие - Тень Мин. @@ -190,8 +201,9 @@ Interação - Min. de Sombra インタラクション - 文字への影の最低色 상호작용 - 문자그림자배경색 - 互动 - 阴影最小值 + 互动—阴影最小值 互動 - 陰影最小化 + Etkileşim - Minumum Gölge Keep cursor centered @@ -206,13 +218,14 @@ Mantieni il cursore centrato 常にカーソルを中央にする 커서를 항상 가운데에 둡니다 - 保持游标在中心点 + 保持光标在中心点 保持游標在中心點 + İmleci Ortada tut Keeps cursor centered and pans the option menu around. Useful if screen size is limited. Udržuje kurzor na středu. Užitečné, pokud je velikost obrazovky omezena. - Garde le curseur au milieu et dispose le menu des options autour. Utile si la taille de l'écran est limitée. + Garde le curseur au milieu de l'écran, et dispose le menu des options tout autour. Utile si la taille de l'écran est limitée. Центрирует курсор и двигает само меню опций. Полезно при ограниченном размере экрана. Hält den Mauszeiger zentriert und verschiebt das Menü beim Bewegen. Nützlich bei kleinen Bildschirmen. Középen tartja a kurzort, és a menüelemeket mozgatja. Hasznos lehetőség korlátozott képméretnél. @@ -221,25 +234,27 @@ Manter o cursor centralizado e mover o menu de opções. Útil caso o tamanho da tela seja limitado. Mantieni il cursore centrato e sposta il menù intorno. Utile se lo schermo è piccolo. 常にカーソルを中央へ表示させ、オプション メニューが移動します。画面の大きさが制限されている時に使いやすくなります。 - 커서를 항상 가운데에 두고 메뉴를 움직입니다. 화면의 크기가 제한되있을때 유용합니다. - 保持游标在中心点并平移周遭的选项选单。这对在荧幕尺寸有限的玩家很有用! + 커서를 항상 가운데에 두고 메뉴를 움직입니다. 화면의 크기가 제한되있을 때 유용합니다. + 保持光标在中心点并平移周遭的选项菜单。这对在屏幕尺寸有限的玩家很有用! 保持游標在中心點並平移周遭的選項選單。這對在螢幕尺寸有限的玩家很有用! + İmleci ortalanmış halde tutar ve seçenek menüsünü kaydırır. Ekran boyutu sınırlıysa kullanışlıdır. Do action when releasing menu key Aktion nach Loslassen der Taste ausführen Wykonuj akcje po puszczeniu klawisza menu Provést akci při pustění klávesy menu - Action au relachement de touche - Выполнять действие при отпускании кнопки взаимодействия + Action au relâchement des touches + Выполнять при отпускании кнопки меню Realizar la acción al soltar la tecla menu Execute a ação quando soltar a tecla de menu Cselekvés végrehajtása a menügomb elengedésekor Esegui l'azione quando rilasci il tasto menu - メニュー キーを離した時に動作を実行 - 메뉴키를 놓을때 행동하기 - 当放开选单键后就执行动作 + メニュー キーを離した時にアクションを実行 + 메뉴 키를 놓을 때 행동하기 + 当放开菜单键后就执行动作 當放開選單鍵後就執行動作 + Menü tuşunu bırakırken işlem yap Interaction Text Size @@ -254,8 +269,9 @@ Dimensione del testo d'interazione インタラクション文字の大きさ 상호작용 - 문자크기 - 互动选单文字大小 + 互动菜单文字大小 互動選單文字大小 + Etkileşim Metni Boyutu Interaction Text Shadow @@ -270,14 +286,15 @@ Ombra del testo d'interazione インタラクション文字へ影 상호작용 - 문자그림자 - 互动选单文字阴影 + 互动菜单文字阴影 互動選單文字陰影 + Etkileşim Metni Gölgesi Allows controlling the text's shadow. Outline ignores custom shadow colors. Umožňuje změnit stíny textu v menu interakce. Barva stínu je u tahu písma ignorována. Stellt den Hintergrundschatten ein. Die Einstellung 'Kontur' ignoriert die Farbe des Schattens. - Permet de controler l'ombre du texte. Le contour ne prend pas en compte la couleur des ombres. + Permet de régler l'ombre du texte. Le contour ne prend pas en compte la couleur des ombres. Дает возможность изменять тень, отбрасываемую текстом. Контур не зависит от выбранного цвета тени. Permite contolar la sombra del texto. El contorno ignora los colores personalizados de la sombra. Pozwala kontrolować cień tekstu. Kontury ignorują niestandardowe kolory cienia. @@ -285,9 +302,10 @@ Hozzáférést biztosít a szöveg árnyékának kezeléséhez. A körvonal nem veszi figyelembe az egyedi árnyékszíneket. Permette di controllare l'ombra del testo. L'impostazione "Contorno" ignora il colore dell'ombra. 文字への影を設定します。縁取りは設定された影の色を無視します。 - 문자의 그림자를 조절하는것을 가능케합니다. 외각선은 임의의 그림자색을 무시합니다. + 문자의 그림자를 조절하는 것을 가능케 합니다. 외곽선은 임의의 그림자색을 무시합니다. 允许控制文字阴影。轮廓部分则会忽略自定义的阴影颜色。 允許控制文字陰影。輪廓部分則會忽略自定義的陰影顏色 + Metin gölgesinin kontrolüne izin verir. Dış çizgi, özel gölge renklerini yok sayar. Outline @@ -301,9 +319,10 @@ Körvonal Contorno 縁取り - 외각선 + 외곽선 只显示轮廓 只顯示輪廓 + Dış Çizgi Interaction menu background @@ -312,14 +331,15 @@ Pozadí menu interakce Interaktionsmenü-Hintergrund Fundo do menu de interação - Arrière plan du menu d'interaction + Arrière-plan du menu d'interaction Cselekvő menü háttere Фон меню взаимодействия Sfondo Menù Interazioni - インタラクション メニューの背景 + インタラクションメニューの背景 상호작용 메뉴 배경 - 互动选单背景 + 互动菜单背景 互動選單背景 + Etkileşim menüsü arka planı Blur the background while the interaction menu is open. @@ -328,14 +348,15 @@ Rozmazat obraz při otevřeném interakčním menu. Den Hintergrund verschwimmen lassen, während das Interaktionsmenü geöffnet ist. Desfocar o fundo enquanto o menu de interação está aberto. - Flouter l'arrière plan durant l'ouverture du menu d'interaction + Floute l'arrière-plan durant l'ouverture du menu d'interaction. A háttér elmosása a cselekvő menü használata alatt. Размыть фон, пока открыто меню взаимодействия. Sfoca lo sfondo mentre il Menù Interazioni è aperto. - インタラクション メニューを開いたとき、背景にボケを与えます。 - 상호작용 메뉴가 열릴시 배경을 흐릿하게 처리합니다. - 当互动选单开启时,模糊背景画面。 + インタラクションメニューを開いたとき、背景をぼかします。 + 상호작용 메뉴가 열릴 시 배경을 흐릿하게 처리합니다. + 当互动菜单开启时,模糊背景画面。 當互動選單開啟時,模糊背景畫面 + Etkileşim menüsü açıkken arka planı bulanıklaştırın. Blur screen @@ -348,10 +369,11 @@ Kép elmosása Размытый Sfoca schermo - ボケ画面 + 背景をぼかす 화면 흐리게 模糊画面 模糊畫面 + Bulanık Ekran Black @@ -364,10 +386,11 @@ Fekete Черный Nero - ブラック + 背景を黒くする 까맣게 黑色 黑色 + Siyah Show actions for buildings @@ -375,15 +398,16 @@ Pokazuj akcje dla budynków Zobrazit akci pro budovy Mostrar acciones para edificios - Affiche les actions pour les batiments + Afficher les actions pour les bâtiments Cselekvések mutatása épületeknél Mostrar ações para edifícios Показывать действия для зданий Mostra azioni per edifici - 建物へ動作を表示 + 建物へアクションを表示 건물에 행동을 취함 显示建筑物可用的动作 顯示建築物可用的動作 + Binalar için eylemleri göster Adds interaction actions for opening doors and mounting ladders on buildings. (Note: There is a performance cost when opening interaction menu, especially in towns) @@ -391,15 +415,16 @@ Dodaje opcje interakcji dla otwierania drzwi oraz wchodzenia po drabinach do budynków. Uwaga: Użycie tej opcji może spowodować spadek wydajności menu interakcji, szczególnie w dużych miastach. Přidá možnost interakce pro otevření dvěří a umistňovat žebříky na budovy. (Poznámka: Použití této možnosti snižuje výkon při otevírání pomocí interakčního menu, zejména ve velkých městech.) Añade las acciones de interacción para la apertura de puertas y montaje de escaleras en los edificios. (Nota: Hay un coste de rendimiento al abrir el menú de interacción, especialmente en las ciudades) - Ajoute des interactions pour ouvrir les portes et les échelles des batiments. (Note: l'ouverture du menu en ville dégrade les performances) + Ajoute des interactions pour ouvrir les portes et les échelles des bâtiments.\nNote : l'ouverture du menu en ville dégrade les performances. Cselekvéseket engedélyez ajtók kinyitására és létrák mászására. (Figyelem: ez teljesítményvesztéssel járhat a menü megnyitásakor, főleg városokban) Adiciona ações de interações para abrir portas e montar escadas em edifícios. (Nota: Existe um custo de performance quando aberto o menu de interação, especialmente em cidades) Добавляет действия открывания дверей и залезания на лестницы для зданий. (Примечание: возможно падение производительности при открытии меню взаимодействия, особенно в городах) - Aggiunge azioni interattive per l'apertura delle porte e piazzamento scale su edifici. (Nota: C'è un costo in performance quando si apre il Menù Interazioni, soprattutto in città) - 建物にある扉の開閉やはしごの昇降といった動作をインタラクションへ追加します。(街などでインタラクション メニューを開くと動作が低下します) - 건물의 문을 열거나 사다리에 오르는 상호작용 행동을 추가합니다. (주의: 상호작용 메뉴를 열경우 성능하락이 있을 수 있음, 특히 마을 내부에서) - 增加互动选单的功能在可开启的门与建筑物的梯子上。(注意: 此功能有可能会降低系统效能,特别是在城镇区更明显) + Aggiunge interazioni per l'apertura delle porte e piazzamento di scale su edifici. (Nota: C'è un costo in performance quando si apre il Menù Interazioni, soprattutto in città) + 建物にドアを開閉したり梯子を昇降するためのインタラクション アクションを追加します。\n(注: 街中でインタラクション メニューを開く際には特に描画パフォーマンスに影響を及ぼします) + 건물의 문을 열거나 사다리에 오르는 상호작용 행동을 추가합니다. (주의: 상호작용 메뉴를 열 경우 성능하락이 있을 수 있음, 특히 마을 내부에서) + 增加互动菜单的功能在可开启的门与建筑物的梯子上。(注意:此功能有可能会降低系统效能,特别是在城镇区更明显) 增加互動選單的功能在可開啟的門與建築物的梯子上。(注意: 此功能有可能會降低系統效能,特別是在城鎮區更明顯) + Binalara kapıları açmak ve merdivenleri monte etmek için etkileşim eylemleri ekler. (Not: Etkileşim menüsünü açarken, özellikle şehirlerde bir performansı etkiler) Interaction Menu @@ -411,10 +436,11 @@ Menú de interacción Menù Interazioni Menu d'interaction - インタラクション メニュー + インタラクションメニュー 상호작용 메뉴 - 互动选单 + 互动菜单 互動選單 + Etkileşim Menüsü Interaction Animation Speed @@ -423,38 +449,72 @@ Скорость анимации меню взаимодействия Velocidade da animação de interação Rychlost animace interakce - Velocità Animazioni Interazioni + Velocità di Animazione delle Interazioni Velocidad de animación del menú de interacción - Vitesse de l'aniamtion d'interaction + Vitesse de l'animation d'interaction インタラクションのアニメーション速度 상호작용 움직임 속도 - 互动选单动画速度 + 互动菜单动画速度 互動選單動畫速度 + Etkileşim Animasyon Hızı Makes menu animations faster and decreases the time needed to hover to show sub actions Beschleunigt die Menüanmimationen und folglich das Öffnen eines Submenüs. Przyśpiesza animacje menu interakcji oraz czas wymagany do pokazania podmenu Ускоряет анимацию меню и уменьшает задержку при наведении мыши для раскрытия подменю - Faz com que as animações do menu de interação sejam mais rápidas, dimiuindo a necessidade de esperar para mostrar as ações + Faz com que as animações do menu de interação sejam mais rápidas, diminuindo a necessidade de esperar para mostrar as ações Zrychlí animaci menu a sníží tak čas potřebný pro plné zobrazení podmenu - Rende le animazioni Menù più veloci e diminuisce il tempo richiesto per mostrare sotto-azioni + Rende le animazioni del Menù più veloci e diminuisce il tempo richiesto per mostrare sotto-azioni Hace la animación del menú más rápida, reduciendo el tiempo necesario para abrir sub-acciones. - Rend les animations de menu plus rapide et réduit le temps nécessaire à l'affichage des sous menus d'action - ホバーで子アクションを表示した時に出るメニューのアニメーション速度を早くしたり遅くしたりできます - 使选单的动画速度更快,并减少子选项显现出来的时间 + Rend les animations du menu plus rapide, et réduit le temps nécessaire à l'affichage des sous menus d'action. + メニューのアニメーションを高速化し、サブアクションを表示するためのホバーに必要な時間を短縮します。 + 使菜单的动画速度更快,并减少子选项显现出来的时间 使選單的動畫速度更快,並減少子選項顯現出來的時間 - 상호 작용을 표시하기 위해 메뉴 애니메이션을 빠르게 만들고 마우스를 가져 오는 데 필요한 시간을 줄입니다. + 상호작용을 표시하기 위해 메뉴 애니메이션을 빠르게 만들고 마우스를 가져오는 데 필요한 시간을 줄입니다. + Menü animasyonlarını daha hızlı hale getirir ve alt eylemleri göstermek için fareyle üzerine gelmek için gereken süreyi azaltır Selector Color Farbauswahl セレクターの色 - 选择器颜色 + 菜单颜色 選單的顏色 - Controllo Settore + Colore Selettore Kolor wybierającego Цвет селектора + Cor do Seletor + Couleur du sélecteur + Barva selektoru + Selector de color + Seçici Renk + 색상 선택 + + + Consolidate single child actions + Объединять ед. дочерные действия + 子アクションを統合 + Consolidar acciones hijo únicas + Combiner les sous-actions uniques + Untergeordnete Aktionen zusammenfassen + Combina sotto-azioni singole + Połącz akcje podrzędne + 整合子操作 + 하위 동작 통합 + Consolidar sub-ações únicas + + + Combines parent action with only one child action together. + Объединять родительское действие с единственным дочерним действием в одно. + 親アクションと子アクションの一つを統合して表示します。 + Combina acciones padre con una única accion hijo de forma conjunta + Lorsqu'un menu ne contient qu'une seule sous-action, elle est combinée avec son menu parent. + Combina interazioni con una sola sotto-azione in una singola interazione. + Übergeordnete Aktionen mit nur einer Unteraktion zusammenfassen. + Gdy menu zawiera tylko jedną akcję podrzędną, łączy ją z akcją nadrzędną. + 主操作与子操作集成显示。 + 대분류로 나뉜 행동을 한눈에 보여줍니다 + Quando um menu contém apenas uma subação, ele é combinado com seu menu pai. diff --git a/addons/interaction/ACE_Settings.hpp b/addons/interaction/ACE_Settings.hpp index 3efb745a6b..67497ec23b 100644 --- a/addons/interaction/ACE_Settings.hpp +++ b/addons/interaction/ACE_Settings.hpp @@ -1,24 +1,12 @@ class ACE_Settings { class GVAR(enableTeamManagement) { - category = CSTRING(DisplayName); - displayName = CSTRING(EnableTeamManagement_DisplayName); - description = CSTRING(EnableTeamManagement_Description); - value = 1; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(enableMagazinePassing) { - category = CSTRING(DisplayName); - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(PassMagazineSetting); + movedToSQF = 1; }; class GVAR(disableNegativeRating) { - category = CSTRING(DisplayName); - displayName = CSTRING(DisableNegativeRating_DisplayName); - description = CSTRING(DisableNegativeRating_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; }; diff --git a/addons/interaction/ACE_ZeusActions.hpp b/addons/interaction/ACE_ZeusActions.hpp index 9fad6c819a..8cc386fbc1 100644 --- a/addons/interaction/ACE_ZeusActions.hpp +++ b/addons/interaction/ACE_ZeusActions.hpp @@ -3,7 +3,7 @@ class ACE_ZeusActions { class ZeusUnits { displayName = "$STR_A3_RscDisplayCurator_ModeUnits_tooltip"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeUnits_ca.paa"; - condition = QUOTE(!([] isEqualTo (curatorSelected select 0))); + condition = QUOTE([] isNotEqualTo (curatorSelected select 0)); class stance { displayName = "$STR_A3_RscAttributeUnitPos_Title"; @@ -35,19 +35,7 @@ class ACE_ZeusActions { displayName = "$STR_A3_CfgVehicles_ModuleRemoteControl_F"; icon = "\A3\Modules_F_Curator\Data\portraitRemoteControl_ca.paa"; condition = QUOTE(ZEUS_ACTION_CONDITION && {-1 < (curatorSelected select 0) findIf {!isNull effectiveCommander _x}}); - statement = QUOTE( \ - private _units = curatorSelected select 0; \ - private _unit = _units param [ARR_2( \ - _units findIf { \ - side _x in [ARR_4(east,west,resistance,civilian)] \ - && !(isPlayer _x) \ - }, \ - objNull \ - )]; \ - bis_fnc_curatorObjectPlaced_mouseOver = [ARR_2('OBJECT',_unit)]; \ - private _rc = group _target createUnit [ARR_5('ModuleRemoteControl_F',[ARR_3(0,0,0)],[],0,'NONE')]; \ - _rc setVariable [ARR_2('BIS_fnc_initModules_disableAutoActivation',false)]; \ - ); + statement = QUOTE(call FUNC(doRemoteControl)); }; class GVAR(repair) { @@ -61,7 +49,7 @@ class ACE_ZeusActions { class ZeusGroups { displayName = "$STR_A3_RscDisplayCurator_ModeGroups_tooltip"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeGroups_ca.paa"; - condition = QUOTE(!([] isEqualTo (curatorSelected select 1))); + condition = QUOTE([] isNotEqualTo (curatorSelected select 1)); class behaviour { displayName = "$STR_Combat_Mode"; @@ -169,7 +157,7 @@ class ACE_ZeusActions { class ZeusWaypoints { displayName = "Waypoints"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeRecent_ca.paa"; - condition = QUOTE(!([] isEqualTo (curatorSelected select 2))); + condition = QUOTE([] isNotEqualTo (curatorSelected select 2)); class behaviour { displayName = "$STR_Combat_Mode"; @@ -277,6 +265,6 @@ class ACE_ZeusActions { class ZeusMarkers { displayName = "$STR_A3_RscDisplayCurator_ModeMarkers_tooltip"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeMarkers_ca.paa"; - condition = QUOTE(!([] isEqualTo (curatorSelected select 3))); + condition = QUOTE([] isNotEqualTo (curatorSelected select 3)); }; }; diff --git a/addons/interaction/CfgEventHandlers.hpp b/addons/interaction/CfgEventHandlers.hpp index f4febe40e9..16f82ea741 100644 --- a/addons/interaction/CfgEventHandlers.hpp +++ b/addons/interaction/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 7a49f43a95..6ae0d4a982 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -72,49 +72,49 @@ class CfgVehicles { displayName = CSTRING(TeamManagement); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {GVAR(EnableTeamManagement)}); statement = ""; + modifierFunction = QUOTE([ARR_3(assignedTeam _target,'PATHTOF(UI\team\team_management_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); exceptions[] = {"isNotSwimming"}; showDisabled = 0; - icon = QPATHTOF(UI\team\team_management_ca.paa); class ACE_AssignTeamRed { displayName = CSTRING(AssignTeamRed); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); - statement = QUOTE([ARR_2(_target,'RED')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_target,'RED',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; - icon = QPATHTOF(UI\team\team_red_ca.paa); + modifierFunction = QUOTE([ARR_3('RED','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_AssignTeamGreen { displayName = CSTRING(AssignTeamGreen); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); - statement = QUOTE([ARR_2(_target,'GREEN')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_target,'GREEN',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; - icon = QPATHTOF(UI\team\team_green_ca.paa); + modifierFunction = QUOTE([ARR_3('GREEN','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_AssignTeamBlue { displayName = CSTRING(AssignTeamBlue); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); - statement = QUOTE([ARR_2(_target,'BLUE')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_target,'BLUE',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; - icon = QPATHTOF(UI\team\team_blue_ca.paa); + modifierFunction = QUOTE([ARR_3('BLUE','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_AssignTeamYellow { displayName = CSTRING(AssignTeamYellow); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); - statement = QUOTE([ARR_2(_target,'YELLOW')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_target,'YELLOW',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; - icon = QPATHTOF(UI\team\team_yellow_ca.paa); + modifierFunction = QUOTE([ARR_3('YELLOW','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_UnassignTeam { displayName = CSTRING(LeaveTeam); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'MAIN'}); - statement = QUOTE([ARR_2(_target,'MAIN')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_target,'MAIN',true)] call DFUNC(joinTeam)); exceptions[] = {"isNotSwimming"}; showDisabled = 1; - icon = QPATHTOF(UI\team\team_white_ca.paa); + modifierFunction = QUOTE([ARR_3('MAIN','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; }; @@ -162,6 +162,12 @@ class CfgVehicles { exceptions[] = {"isNotSwimming"}; icon = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\getout_ca.paa"; }; + class GVAR(Gear) { + displayName = "$STR_ACTION_GEAR"; + condition = QUOTE(!(lifeState _target in [ARR_2('HEALTHY','INJURED')]) && {isNull objectParent _target}); + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; + }; }; class ACE_Torso { @@ -224,16 +230,16 @@ class CfgVehicles { displayName = CSTRING(TapShoulder); selection = "rightshoulder"; distance = 2.0; - condition = QUOTE([ARR_2(_player, _target)] call DFUNC(canTapShoulder)); - statement = QUOTE([ARR_3(_player, _target, 0)] call DFUNC(tapShoulder)); + condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canTapShoulder)); + statement = QUOTE([ARR_3(_player,_target,0)] call DFUNC(tapShoulder)); exceptions[] = {"isNotSwimming"}; }; class ACE_TapShoulderLeft { displayName = CSTRING(TapShoulder); selection = "leftshoulder"; distance = 2.0; - condition = QUOTE([ARR_2(_player, _target)] call DFUNC(canTapShoulder)); - statement = QUOTE([ARR_3(_player, _target, 1)] call DFUNC(tapShoulder)); + condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canTapShoulder)); + statement = QUOTE([ARR_3(_player,_target,1)] call DFUNC(tapShoulder)); exceptions[] = {"isNotSwimming"}; }; }; @@ -244,48 +250,48 @@ class CfgVehicles { condition = QUOTE(GVAR(EnableTeamManagement)); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = ""; + modifierFunction = QUOTE([ARR_3(assignedTeam _target,'PATHTOF(UI\team\team_management_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); showDisabled = 1; - icon = QPATHTOF(UI\team\team_management_ca.paa); class ACE_JoinTeamRed { displayName = CSTRING(JoinTeamRed); condition = QUOTE(true); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; - statement = QUOTE([ARR_2(_player,'RED')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_player,'RED',true)] call DFUNC(joinTeam)); showDisabled = 1; - icon = QPATHTOF(UI\team\team_red_ca.paa); + modifierFunction = QUOTE([ARR_3('RED','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_JoinTeamGreen { displayName = CSTRING(JoinTeamGreen); condition = QUOTE(true); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; - statement = QUOTE([ARR_2(_player,'GREEN')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_player,'GREEN',true)] call DFUNC(joinTeam)); showDisabled = 1; - icon = QPATHTOF(UI\team\team_green_ca.paa); + modifierFunction = QUOTE([ARR_3('GREEN','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_JoinTeamBlue { displayName = CSTRING(JoinTeamBlue); condition = QUOTE(true); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; - statement = QUOTE([ARR_2(_player,'BLUE')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_player,'BLUE',true)] call DFUNC(joinTeam)); showDisabled = 1; - icon = QPATHTOF(UI\team\team_blue_ca.paa); + modifierFunction = QUOTE([ARR_3('BLUE','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_JoinTeamYellow { displayName = CSTRING(JoinTeamYellow); condition = QUOTE(true); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; - statement = QUOTE([ARR_2(_player,'YELLOW')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_player,'YELLOW',true)] call DFUNC(joinTeam)); showDisabled = 1; - icon = QPATHTOF(UI\team\team_yellow_ca.paa); + modifierFunction = QUOTE([ARR_3('YELLOW','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_LeaveTeam { displayName = CSTRING(LeaveTeam); condition = QUOTE(assignedTeam _player != 'MAIN'); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; - statement = QUOTE([ARR_2(_player,'MAIN')] call DFUNC(joinTeam)); + statement = QUOTE([ARR_3(_player,'MAIN',true)] call DFUNC(joinTeam)); showDisabled = 1; - icon = QPATHTOF(UI\team\team_white_ca.paa); + modifierFunction = QUOTE([ARR_3('MAIN','PATHTOF(UI\team\team_white_ca.paa)',_this select 3)] call FUNC(modifyTeamManagementAction)); }; class ACE_BecomeLeader { displayName = CSTRING(BecomeLeader); @@ -299,10 +305,17 @@ class CfgVehicles { displayName = CSTRING(LeaveGroup); condition = QUOTE(count (units group _player) > 1); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; - statement = QUOTE(_oldGroup = units group _player; _newGroup = createGroup side _player; [_player] joinSilent _newGroup; {_player reveal _x} forEach _oldGroup;); + statement = QUOTE(_oldGroup = units group _player; _newGroup = createGroup side group _player; [_player] joinSilent _newGroup; {_player reveal _x} forEach _oldGroup;); showDisabled = 1; icon = QPATHTOF(UI\team\team_management_ca.paa); }; + class ACE_RenameGroup { + displayName = CSTRING(RenameGroup); + condition = QUOTE(_player call FUNC(canRenameGroup)); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; + statement = QUOTE(_player call FUNC(renameGroupUI)); + showDisabled =1; + }; }; class ACE_Equipment { @@ -312,6 +325,14 @@ class CfgVehicles { statement = ""; showDisabled = 1; icon = ""; // @todo + + class GVAR(weaponAttachments) { + displayName = "$STR_A3_CfgEditorSubcategories_EdSubcat_SideSlot0"; + condition = QGVAR(enableWeaponAttachments); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; + insertChildren = QUOTE(call DFUNC(getWeaponAttachmentsActions)); + modifierFunction = QUOTE(_this select 3 set [ARR_2(2,getText (configFile >> 'CfgWeapons' >> currentWeapon (_this select 0) >> 'picture'))];); + }; }; }; }; @@ -327,7 +348,7 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -350,7 +371,7 @@ class CfgVehicles { }; }; - class Car_F: Car{}; + class Car_F: Car {}; class Quadbike_01_base_F: Car_F { class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -394,7 +415,7 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -421,7 +442,7 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -446,13 +467,13 @@ class CfgVehicles { class ACE_Actions { class ACE_MainActions { displayName = CSTRING(MainAction); - position = QUOTE([ARR_2(_target, EGVAR(interact_menu,cameraPosASL))] call DFUNC(getVehiclePosComplex)); + position = QUOTE([ARR_2(_target,EGVAR(interact_menu,cameraPosASL))] call DFUNC(getVehiclePosComplex)); selection = ""; distance = 4; condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -474,13 +495,13 @@ class CfgVehicles { class ACE_Actions { class ACE_MainActions { displayName = CSTRING(MainAction); - position = QUOTE([ARR_2(_target, EGVAR(interact_menu,cameraPosASL))] call DFUNC(getVehiclePosComplex)); + position = QUOTE([ARR_2(_target,EGVAR(interact_menu,cameraPosASL))] call DFUNC(getVehiclePosComplex)); selection = ""; distance = 4; condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -528,7 +549,7 @@ class CfgVehicles { }; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -560,7 +581,7 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = QUOTE(alive _target); + condition = QUOTE(true); statement = ""; exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); @@ -620,14 +641,35 @@ class CfgVehicles { condition = "true"; class ACE_OpenBox { displayName = CSTRING(OpenBox); - condition = QUOTE((alive _target) && {(getNumber (configFile >> 'CfgVehicles' >> (typeOf _target) >> 'disableInventory')) == 0}); - statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)), _target)]); + condition = QUOTE(alive _target && {!lockedInventory _target} && {getNumber (configOf _target >> 'disableInventory') == 0}); + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); showDisabled = 0; }; }; }; class ACE_SelfActions {}; }; + + class Items_base_F; + class PlasticCase_01_base_F: Items_base_F { + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(MainAction); + selection = ""; + distance = 2; + condition = "true"; + class ACE_OpenBox { + displayName = CSTRING(OpenBox); + condition = QUOTE(alive _target && {!lockedInventory _target} && {getNumber (configOf _target >> 'disableInventory') == 0}); + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + showDisabled = 0; + }; + }; + }; + class ACE_SelfActions {}; + }; + + class Slingload_base_F: ReammoBox_F {}; class Slingload_01_Base_F: Slingload_base_F { class ACE_Actions: ACE_Actions { @@ -657,6 +699,62 @@ class CfgVehicles { class ACE_SelfActions {}; }; + // weapons dropped from dead body + class WeaponHolderSimulated: ThingX { + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(MainAction); + distance = 3; + position = QUOTE(_target worldToModel ASLToAGL getPosASL _target); + + class GVAR(Gear) { + displayName = "$STR_ACTION_GEAR"; + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; + }; + }; + }; + }; + // Don't enable for scripted + class WeaponHolderSimulated_Scripted: WeaponHolderSimulated { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + delete GVAR(Gear); + }; + }; + }; + + class ReammoBox; + // dropped weapons/gear + class WeaponHolder: ReammoBox { + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(MainAction); + distance = 3; + position = QUOTE(_target worldToModel ASLToAGL getPosASL _target); + + class GVAR(Gear) { + displayName = "$STR_ACTION_GEAR"; + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; + }; + }; + }; + }; + // Don't enable for scripted + class GroundWeaponHolder: WeaponHolder { + class ACE_Actions: ACE_Actions { + class ACE_MainActions; + }; + }; + class GroundWeaponHolder_Scripted: GroundWeaponHolder { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + delete GVAR(Gear); + }; + }; + }; + class Lamps_base_F; class Land_PortableLight_single_F: Lamps_base_F { class EventHandlers { @@ -717,6 +815,7 @@ class CfgVehicles { displayName = CSTRING(TurnOn); icon = "\A3\Ui_f\data\IGUI\Cfg\VehicleToggles\LightsIconOn_ca.paa"; condition = QUOTE(alive _target); + #pragma hemtt suppress pw3_padded_arg statement = QUOTE(\ private _position = getPosATL _target;\ private _vectorDirAndUp = [ARR_2(vectorDir _target,vectorUp _target)];\ diff --git a/addons/interaction/README.md b/addons/interaction/README.md index 92401b2547..6a58b15a62 100644 --- a/addons/interaction/README.md +++ b/addons/interaction/README.md @@ -2,12 +2,3 @@ ace_interaction =============== Provides interaction options between units. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) -- [NouberNou](https://github.com/NouberNou) diff --git a/addons/interaction/RscTitles.hpp b/addons/interaction/RscTitles.hpp index e157fd696c..ec7856c62c 100644 --- a/addons/interaction/RscTitles.hpp +++ b/addons/interaction/RscTitles.hpp @@ -13,8 +13,8 @@ class ACE_Interaction_Button_Base { style = 2; x = 0; y = 0; - w = 2.0 / 16 * safezoneW; - h = 0.3 / 9 * safezoneH; + w = "2.0 / 16 * safezoneW"; + h = "0.3 / 9 * safezoneH"; offsetX = 0.003; offsetY = 0.003; @@ -38,7 +38,7 @@ class ACE_Interaction_Button_Base { }; class IGUIBack; -class RscListbox; +class RscListBox; class RscText; class RscPicture; class RscControlsGroupNoScrollbars; @@ -57,9 +57,9 @@ class RscACE_SelectAnItem { h = 0.71; colorBackground[] = {0, 0, 0, 0.2}; }; - class header: RscText{ + class header: RscText { idc = 8870; - x = X_OFFSET + 0.005; + x = QUOTE(X_OFFSET + 0.005); y = 0.005; w = 0.59; h = 0.05; @@ -69,7 +69,7 @@ class RscACE_SelectAnItem { class itemList: RscListBox { onMouseButtonDblClick = QUOTE(_this call DFUNC(onSelectMenuDblClick)); idc = 8866; - x = X_OFFSET + 0.005; + x = QUOTE(X_OFFSET + 0.005); w = 0.59; h = 0.54; y = 0.06; @@ -81,7 +81,7 @@ class RscACE_SelectAnItem { idc = -1; colorBackground[] = {0,0,0,0.5}; colorBackgroundDisabled[] = {0,0,0,0.5}; - x = X_OFFSET + 0.005; + x = QUOTE(X_OFFSET + 0.005); w = 0.15; h = 0.1; y = 0.605; @@ -92,7 +92,7 @@ class RscACE_SelectAnItem { idc = -1; colorBackground[] = {0,0,0,0.5}; colorBackgroundDisabled[] = {0,0,0,0.5}; - x = X_OFFSET + 0.445; + x = QUOTE(X_OFFSET + 0.445); y = 0.605; h = 0.1; w = 0.15; @@ -100,13 +100,13 @@ class RscACE_SelectAnItem { class cancelBtn: ACE_Interaction_Button_Base { idc = 8855; - x = X_OFFSET + 0.005; + x = QUOTE(X_OFFSET + 0.005); w = 0.15; h = 0.1; y = 0.605; style = 2; text = CSTRING(Back); - action = QUOTE(call DFUNC(hideMenu);); //'Default' call DFUNC(openMenu); 'Default' call DFUNC(openMenuSelf); + action = QUOTE(call DFUNC(hideMenu)); //'Default' call DFUNC(openMenu); 'Default' call DFUNC(openMenuSelf); colorBackground[] = {0,0,0,0}; colorBackgroundDisabled[] = {0,0,0,0}; colorBackgroundActive[] = {1,1,1,0.2}; @@ -114,13 +114,13 @@ class RscACE_SelectAnItem { }; class approveBtn: ACE_Interaction_Button_Base { idc = 8860; - x = X_OFFSET + 0.445; + x = QUOTE(X_OFFSET + 0.445); y = 0.605; h = 0.1; w = 0.15; style = 2; text = CSTRING(MakeSelection); - action = QUOTE(call DFUNC(hideMenu);); + action = QUOTE(call DFUNC(hideMenu)); colorBackground[] = {0,0,0,0}; colorBackgroundDisabled[] = {0,0,0,0}; colorBackgroundActive[] = {1,1,1,0.2}; @@ -141,37 +141,37 @@ class RscTitles { class IconLMB: RscPicture { idc = IDC_MOUSEHINT_LMB; text = QPATHTOF(UI\mouse_left_ca.paa); - x = 20 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 17.5 * GUI_GRID_H; - w = GUI_GRID_H; - h = GUI_GRID_H; + x = QUOTE(20 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(17.5 * GUI_GRID_H); + w = QUOTE(GUI_GRID_H); + h = QUOTE(GUI_GRID_H); }; class TextLMB: RscText { idc = IDC_MOUSEHINT_LMB_TEXT; text = ""; - x = 21.1 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 17.45 * GUI_GRID_H; - w = 24 * GUI_GRID_W; - h = GUI_GRID_H; - sizeEx = GUI_GRID_H; + x = QUOTE(21.1 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(17.45 * GUI_GRID_H); + w = QUOTE(24 * GUI_GRID_W); + h = QUOTE(GUI_GRID_H); + sizeEx = QUOTE(GUI_GRID_H); }; class IconMMB: IconLMB { idc = IDC_MOUSEHINT_MMB; text = QPATHTOF(UI\mouse_scroll_ca.paa); - y = 18.55 * GUI_GRID_H; + y = QUOTE(18.55 * GUI_GRID_H); }; class TextMMB: TextLMB { idc = IDC_MOUSEHINT_MMB_TEXT; - y = 18.5 * GUI_GRID_H; + y = QUOTE(18.5 * GUI_GRID_H); }; class IconRMB: IconLMB { idc = IDC_MOUSEHINT_RMB; text = QPATHTOF(UI\mouse_right_ca.paa); - y = 19.6 * GUI_GRID_H; + y = QUOTE(19.6 * GUI_GRID_H); }; class TextRMB: TextLMB { idc = IDC_MOUSEHINT_RMB_TEXT; - y = 19.55 * GUI_GRID_H; + y = QUOTE(19.55 * GUI_GRID_H); }; }; }; @@ -181,26 +181,26 @@ class GVAR(RscExtraKey): RscControlsGroupNoScrollbars { idc = IDC_MOUSEHINT_EXTRA; x = 0; y = 0; - w = 40 * GUI_GRID_W; - h = GUI_GRID_H; + w = QUOTE(40 * GUI_GRID_W); + h = QUOTE(GUI_GRID_H); class controls { class Name: RscText { idc = IDC_MOUSEHINT_EXTRA_NAME; style = 1; x = 0; y = 0; - w = 21.5 * GUI_GRID_W + GUI_GRID_CENTER_X; - h = GUI_GRID_H; - sizeEx = GUI_GRID_H; + w = QUOTE(21.5 * GUI_GRID_W + GUI_GRID_CENTER_X); + h = QUOTE(GUI_GRID_H); + sizeEx = QUOTE(GUI_GRID_H); font = "EtelkaMonospaceProBold"; }; class Text: RscText { idc = IDC_MOUSEHINT_EXTRA_TEXT; - x = 21.1 * GUI_GRID_W + GUI_GRID_CENTER_X; - y = 0; - w = 24 * GUI_GRID_W; - h = GUI_GRID_H; - sizeEx = GUI_GRID_H; + x = QUOTE(21.1 * GUI_GRID_W + GUI_GRID_CENTER_X); + y = QUOTE(0); + w = QUOTE(24 * GUI_GRID_W); + h = QUOTE(GUI_GRID_H); + sizeEx = QUOTE(GUI_GRID_H); }; }; }; diff --git a/addons/interaction/XEH_PREP.hpp b/addons/interaction/XEH_PREP.hpp index ea6c275f36..554f903704 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -14,22 +14,32 @@ PREP(hideMouseHint); // interaction with units PREP(canInteractWithCivilian); +PREP(canInteractWithVehicleCrew); PREP(getDown); PREP(sendAway); PREP(canJoinGroup); PREP(modifyJoinGroupAction); +PREP(modifyTeamManagementAction); PREP(canJoinTeam); PREP(joinTeam); PREP(canPassMagazine); PREP(passMagazine); PREP(canBecomeLeader); PREP(doBecomeLeader); +PREP(doRemoteControl); PREP(canTapShoulder); PREP(tapShoulder); PREP(canPardon); PREP(pardon); PREP(canPullOutBody); PREP(pullOutBody); +PREP(canRenameGroup); +PREP(renameGroupUI); +PREP(renameGroup); + +// Weapon Attachments +PREP(getWeaponAttachmentsActions); +PREP(switchWeaponAttachment); // interaction with doors PREP(getDoor); @@ -42,4 +52,6 @@ PREP(openDoor); PREP(canPush); PREP(push); +// misc PREP(canFlip); +PREP(replaceTerrainObject); diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index 7a9f2b6572..f461e2a770 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -77,10 +77,30 @@ ACE_Modifier = 0; }; }] call CBA_fnc_addEventHandler; +if (isServer) then { + [QGVAR(replaceTerrainObject), LINKFUNC(replaceTerrainObject)] call CBA_fnc_addEventHandler; +}; + if (!hasInterface) exitWith {}; GVAR(isOpeningDoor) = false; +[QEGVAR(interact_menu,renderNearbyActions), { + if (!GVAR(interactWithTerrainObjects)) exitWith {}; + { + if ( + isObjectHidden _x // after hiding on server + || {_x getVariable [QGVAR(terrainObjectReplaced), false]} // after checking but before hiding + || {typeOf _x isNotEqualTo ""} + ) then {continue}; + private _model = getModelInfo _x select 1; + private _class = GVAR(replaceTerrainModels) get _model; + if (isNil "_class") then {continue}; + _x setVariable [QGVAR(terrainObjectReplaced), true]; + [QGVAR(replaceTerrainObject), [_x, _class]] call CBA_fnc_serverEvent; + } forEach nearestTerrainObjects [ACE_player, [], 5, false]; +}] call CBA_fnc_addEventHandler; + [QGVAR(tapShoulder), { params ["_unit", "_shoulderNum"]; @@ -116,7 +136,7 @@ GVAR(isOpeningDoor) = false; if !([ACE_player, cursorTarget] call FUNC(canTapShoulder)) exitWith {false}; //Tap whichever shoulder is closest - private _shoulderNum = [0, 1] select (([cursorTarget, ACE_player] call BIS_fnc_relativeDirTo) > 180); + private _shoulderNum = parseNumber (([cursorTarget, ACE_player] call BIS_fnc_relativeDirTo) > 180); // Statement [ACE_player, cursorTarget, _shoulderNum] call FUNC(tapShoulder); @@ -128,10 +148,34 @@ GVAR(isOpeningDoor) = false; ["isNotSwimming", {!(_this call EFUNC(common,isSwimming))}] call EFUNC(common,addCanInteractWithCondition); ["isNotOnLadder", {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "ACE_isLadder") != 1}] call EFUNC(common,addCanInteractWithCondition); -["ace_settingsInitialized", { +["CBA_settingsInitialized", { if (GVAR(disableNegativeRating)) then { player addEventHandler ["HandleRating", { (_this select 1) max 0 }]; }; }] call CBA_fnc_addEventHandler; + +{ + [_x, { + [QGVAR(clearWeaponAttachmentsActionsCache)] call CBA_fnc_localEvent; + }] call CBA_fnc_addPlayerEventHandler; +} forEach ["loadout", "weapon"]; + + +// add "Take _weapon_" action to dropped weapons +private _action = [ + // action display name will be overwritten in modifier function + QGVAR(takeWeapon), "take", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa", + {_player action ["TakeWeapon", _target, weaponCargo _target select 0]}, + {(count weaponCargo _target == 1) && {[_player, objNull, []] call EFUNC(common,canInteractWith)}}, // Not checking if container is claimed + nil, nil, nil, nil, nil, + { + params ["_target", "", "", "_actionData"]; + _actionData set [1, format [localize "STR_ACTION_TAKE_BAG", getText (configfile >> "CfgWeapons" >> weaponCargo _target select 0 >> "displayName")]]; + } +] call EFUNC(interact_menu,createAction); + +{ + [_x, 0, ["ACE_MainActions"], _action, true] call EFUNC(interact_menu,addActionToClass); +} forEach ["WeaponHolder", "WeaponHolderSimulated"]; diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index dbc37e2bb6..c5873bcfc9 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -6,6 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + DFUNC(repair_Statement) = { // moved from config because of build problems TRACE_1("repair_Statement",_this); { @@ -13,4 +15,8 @@ DFUNC(repair_Statement) = { // moved from config because of build problems } forEach (curatorSelected select 0) }; +if (hasInterface) then { + GVAR(replaceTerrainModels) = createHashMapFromArray call (uiNamespace getVariable QGVAR(cacheReplaceTerrainModels)); +}; + ADDON = true; diff --git a/addons/interaction/XEH_preStart.sqf b/addons/interaction/XEH_preStart.sqf index 022888575e..331b5c6d36 100644 --- a/addons/interaction/XEH_preStart.sqf +++ b/addons/interaction/XEH_preStart.sqf @@ -1,3 +1,25 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +if (!hasInterface) exitWith {}; + +private _replaceTerrainClasses = QUOTE( + getNumber (_x >> QQGVAR(replaceTerrainObject)) > 0 + && {getNumber (_x >> 'scope') == 2} +) configClasses (configFile >> "CfgVehicles"); + +private _cacheReplaceTerrainModels = createHashMap; +{ + private _model = toLowerANSI getText (_x >> "model"); + if (_model select [0, 1] == "\") then { + _model = _model select [1]; + }; + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d" + }; + if (_model in _cacheReplaceTerrainModels) then {continue}; + _cacheReplaceTerrainModels set [_model, configName _x]; +} forEach _replaceTerrainClasses; + +uiNamespace setVariable [QGVAR(cacheReplaceTerrainModels), compileFinal str _cacheReplaceTerrainModels]; diff --git a/addons/interaction/config.cpp b/addons/interaction/config.cpp index 77c2b408af..93711a57ce 100644 --- a/addons/interaction/config.cpp +++ b/addons/interaction/config.cpp @@ -19,3 +19,4 @@ class CfgPatches { #include "RscTitles.hpp" #include "ACE_Settings.hpp" #include "ACE_ZeusActions.hpp" +#include "groupRename_GUI.hpp" diff --git a/addons/interaction/dev/initReplaceTerrainCursorObject.sqf b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf new file mode 100644 index 0000000000..a1708be423 --- /dev/null +++ b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf @@ -0,0 +1,59 @@ +// execVM "z\ace\addons\interaction\dev\initReplaceTerrainCursorObject.sqf"; +// use "J" key to replace terrain cursorObject and add dragging actions to it + +#include "..\script_component.hpp" + +DFUNC(replaceTerrainModelsAdd) = { + params ["_model", ["_class", ""]]; + if (_model isEqualType objNull) then { + _model = getModelInfo _model select 1; + }; + if (_model isEqualTo "") exitWith {systemChat "fail model"; false}; + + private _savedClass = GVAR(replaceTerrainModels) get _model; + if (!isNil "_savedClass") exitWith {systemChat ("was " + _savedClass); true}; + + private _parent = ""; + if (_class isEqualTo "") then { + private _configClasses = QUOTE(getNumber (_x >> 'scope') == 2 && {!(configName _x isKindOf 'AllVehicles')}) configClasses (configFile >> "CfgVehicles"); + { + private _xmodel = toLowerANSI getText (_x >> "model"); + if (_xmodel select [0, 1] == "\") then { + _xmodel = _xmodel select [1]; + }; + if ((_xmodel select [count _xmodel - 4]) != ".p3d") then { + _xmodel = _xmodel + ".p3d" + }; + if (_model == _xmodel) then { + _class = configName _x; + _parent = configName inheritsFrom _x; + break; + }; + } forEach _configClasses; + }; + if (_class isEqualTo "") exitWith {systemChat "fail class"; false}; + GVAR(replaceTerrainModels) set [_model, _class]; + QEGVAR(interact_menu,renderNearbyActions) call CBA_fnc_localEvent; + systemChat ("found " + _class); + diag_log format ["replaceTerrain: class %1: %2", _class, _parent]; + true +}; + +// DIK_J +[0x24, [false, false, false], { + if ( + cursorObject call FUNC(replaceTerrainModelsAdd) + && {["ace_dragging"] call EFUNC(common,isModLoaded)} + ) then { + // wait while server replaces object, then init dragging on all clients + [{ + if (typeOf cursorObject == "") exitwith {}; + [cursorObject, { + if !hasInterface exitWith {}; + [_this, true] call EFUNC(dragging,setDraggable); + [_this, true] call EFUNC(dragging,setCarryable); + }] remoteExec ["call", 0]; + }, [], 1] call CBA_fnc_waitAndExecute; + }; + true +}, nil, nil, false] call CBA_fnc_addKeyHandler; diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index 673fb3ad00..9b8981bfd0 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Mount unit actions inside passenger submenu. @@ -12,7 +12,7 @@ * Children actions * * Example: - * array = [target, player, [params]] call ace_interaction_fnc_addPassengerAction + * array = [target, player, [params]] call ace_interaction_fnc_addPassengerActions * * Public: No */ @@ -20,11 +20,7 @@ params ["", "", "_parameters"]; _parameters params ["_unit"]; -private _namespace = EGVAR(interact_menu,ActNamespace); -private _actionTrees = _namespace getVariable typeOf _unit; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = EGVAR(interact_menu,ActNamespace) getOrDefault [typeOf _unit, []]; private _actions = []; @@ -33,7 +29,6 @@ private _actions = []; _x params ["_actionData", "_children"]; _actions pushBack [_actionData, _children, _unit]; - false -} count (_actionTrees select 0 select 1); +} forEach (_actionTrees select 0 select 1); _actions diff --git a/addons/interaction/functions/fnc_addPassengersActions.sqf b/addons/interaction/functions/fnc_addPassengersActions.sqf index 05e5ebfd55..50b0d98a21 100644 --- a/addons/interaction/functions/fnc_addPassengersActions.sqf +++ b/addons/interaction/functions/fnc_addPassengersActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Create one action per passenger. @@ -6,64 +6,68 @@ * Arguments: * 0: Vehicle * 1: Player - * 3: Parameters + * 2: Parameters * * Return Value: * Children actions * * Example: - * [target, player, [params]] call ace_interaction_fnc_addPassengersActions + * [cursorObject, player, [params]] call ace_interaction_fnc_addPassengersActions * * Public: No */ params ["_vehicle", "_player"]; +// If player is not in vehicle and the crew is hostile, do not show any actions +if !(_player in _vehicle || {[_player, _vehicle] call FUNC(canInteractWithVehicleCrew)}) exitWith { + [] // return +}; + private _actions = []; +private _icon = ""; { - private _unit = _x; + _x params ["_unit", "_role"]; - if (_unit != _player && {getText (configFile >> "CfgVehicles" >> typeOf _unit >> "simulation") != "UAVPilot"}) then { - private _icon = [ - "", - "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_driver_ca.paa", - "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_gunner_ca.paa", - "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_commander_ca.paa" - ] select (([driver _vehicle, gunner _vehicle, commander _vehicle] find _unit) + 1); + _icon = [ + "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_driver_ca.paa", + "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_gunner_ca.paa", + "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_commander_ca.paa", + "" + ] select (["driver", "gunner", "commander"] find _role); - if (_unit getVariable [QEGVAR(captives,isHandcuffed), false]) then { - _icon = QPATHTOEF(captives,UI\handcuff_ca.paa); - }; - - _actions pushBack [ - [ - format ["%1", _unit], - [_unit, true] call EFUNC(common,getName), - _icon, - { - //statement (Run on hover) - reset the cache so we will insert actions immedietly when hovering over new unit - TRACE_2("Cleaning Cache",_target,vehicle _target); - [vehicle _target, QEGVAR(interact_menu,ATCache_ACE_SelfActions)] call EFUNC(common,eraseCache); - }, - {true}, - { - if (EGVAR(interact_menu,selectedTarget) isEqualTo _target) then { - _this call FUNC(addPassengerActions) - } else { - [] //not selected, don't waste time on actions - }; - }, - [_unit], - {[0, 0, 0]}, - 2, - [false,false,false,true,false] //add run on hover (4th bit true) - ] call EFUNC(interact_menu,createAction), - [], - _unit - ]; + if (_unit getVariable [QEGVAR(captives,isHandcuffed), false]) then { + _icon = QPATHTOEF(captives,UI\handcuff_ca.paa); }; - false -} count crew _vehicle; + + _actions pushBack [ + [ + str _unit, + [_unit, true] call EFUNC(common,getName), + [_icon, "#FFFFFF"], + { + // statement (Run on hover) - reset the cache so we will insert actions immediately when hovering over new unit + TRACE_2("Cleaning Cache",_target,objectParent _target); + [objectParent _target, QEGVAR(interact_menu,ATCache_ACE_SelfActions)] call EFUNC(common,eraseCache); + }, + {true}, + { + if (EGVAR(interact_menu,selectedTarget) isEqualTo _target) then { + _this call FUNC(addPassengerActions) + } else { + [] // not selected, don't waste time on actions + }; + }, + [_unit], + {[0, 0, 0]}, + 2, + [false, false, false, true, false], // add run on hover (4th bit true) + {if (["ace_medical_gui"] call EFUNC(common,isModLoaded)) then {call EFUNC(medical_gui,modifyActionTriageLevel)}} + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; +} forEach ((fullCrew _vehicle) select {_x select 0 != _player && {!unitIsUAV (_x select 0)}}); _actions diff --git a/addons/interaction/functions/fnc_canBecomeLeader.sqf b/addons/interaction/functions/fnc_canBecomeLeader.sqf index af50c081a0..de06287fa2 100644 --- a/addons/interaction/functions/fnc_canBecomeLeader.sqf +++ b/addons/interaction/functions/fnc_canBecomeLeader.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Test if can Become Leader of group. diff --git a/addons/interaction/functions/fnc_canFlip.sqf b/addons/interaction/functions/fnc_canFlip.sqf index b00164415c..c6a553b48f 100644 --- a/addons/interaction/functions/fnc_canFlip.sqf +++ b/addons/interaction/functions/fnc_canFlip.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Checks if vehicle can be flipped. diff --git a/addons/interaction/functions/fnc_canInteractWithCivilian.sqf b/addons/interaction/functions/fnc_canInteractWithCivilian.sqf index 7b98ba4972..73c225626e 100644 --- a/addons/interaction/functions/fnc_canInteractWithCivilian.sqf +++ b/addons/interaction/functions/fnc_canInteractWithCivilian.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Checks if the unit can interact with civilian diff --git a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf new file mode 100644 index 0000000000..a314a8b601 --- /dev/null +++ b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Checks if a unit can interact with the vehicle crew inside. + * + * Arguments: + * 0: Player + * 1: Vehicle + * + * Return Value: + * Unit can interact with vehicle crew + * + * Example: + * [cursorObject, player] call ace_interaction_fnc_canInteractWithVehicleCrew + * + * Public: No + */ + +params ["_player", "_vehicle"]; + +private _crew = crew _vehicle; + +// If vehicle is empty, quit +if (_crew isEqualTo []) exitWith {true}; + +private _sidePlayer = side group _player; + +(_crew select {_x != _player && {!unitIsUAV _x}}) findIf { // ignore player and UAV units + // Units must all be unconscious, captive or friendly (side group is used in case unit is captive/unconscious) for actions to show up + !captive _x && {lifeState _x in ["HEALTHY", "INJURED"]} && {[_sidePlayer, side group _x] call BIS_fnc_sideIsEnemy} +} == -1 diff --git a/addons/interaction/functions/fnc_canJoinGroup.sqf b/addons/interaction/functions/fnc_canJoinGroup.sqf index bc21e9d162..facc3376ee 100644 --- a/addons/interaction/functions/fnc_canJoinGroup.sqf +++ b/addons/interaction/functions/fnc_canJoinGroup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Checks if the unit can join a group diff --git a/addons/interaction/functions/fnc_canJoinTeam.sqf b/addons/interaction/functions/fnc_canJoinTeam.sqf index 424b3be982..09d0281dca 100644 --- a/addons/interaction/functions/fnc_canJoinTeam.sqf +++ b/addons/interaction/functions/fnc_canJoinTeam.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Checks if the player can join a team diff --git a/addons/interaction/functions/fnc_canPardon.sqf b/addons/interaction/functions/fnc_canPardon.sqf index 81319afb3b..833a518b2f 100644 --- a/addons/interaction/functions/fnc_canPardon.sqf +++ b/addons/interaction/functions/fnc_canPardon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Checks if the unit can pardon the target. diff --git a/addons/interaction/functions/fnc_canPassMagazine.sqf b/addons/interaction/functions/fnc_canPassMagazine.sqf index 5cc1ed96e2..97478bffa7 100644 --- a/addons/interaction/functions/fnc_canPassMagazine.sqf +++ b/addons/interaction/functions/fnc_canPassMagazine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if unit has a spare magazine for the specified weapon. @@ -19,12 +19,12 @@ params ["_player", "_target", "_weapon"]; if (!GVAR(enableMagazinePassing)) exitWith {false}; -if (_weapon isEqualTo "") exitWith {false}; +if (_weapon isEqualTo "" || {!(_target call EFUNC(common,isAwake))}) exitWith {false}; if (((vehicle _target) != _target) && {(vehicle _target) != (vehicle _player)}) exitWith {false}; private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; (magazinesAmmoFull _player) findIf { _x params ["_className", "", "_loaded"]; - (_className in _compatibleMags) && {!_loaded} && {_target canAdd _className} + (_className in _compatibleMags) && {!_loaded} && {[_target, _className] call CBA_fnc_canAddItem} } > -1 diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf index bb61cb2545..2676bfc203 100644 --- a/addons/interaction/functions/fnc_canPullOutBody.sqf +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Checks if unit can pull target body out of vehicle. @@ -18,6 +18,9 @@ params ["_body", "_unit"]; +// Defer to ACE Medical's unload patient if present +if (GETEGVAR(medical,enabled,false)) exitWith {false}; + private _vehicle = objectParent _body; if ( @@ -34,7 +37,7 @@ if ( ((fullCrew [_vehicle, ""] select {_body == _x select 0}) select 0) params ["", "", "_cargoIndex", "_turretPath"]; -private _locked = if (!(_turretPath isEqualTo [])) then { +private _locked = if (_turretPath isNotEqualTo []) then { _vehicle lockedTurret _turretPath; } else { if (_cargoIndex > -1) then { diff --git a/addons/interaction/functions/fnc_canPush.sqf b/addons/interaction/functions/fnc_canPush.sqf index 0032296a50..28197d12cd 100644 --- a/addons/interaction/functions/fnc_canPush.sqf +++ b/addons/interaction/functions/fnc_canPush.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Checks if the boat can be pushed. @@ -18,5 +18,5 @@ params ["_target"]; alive _target && -{getMass _target <= 2600 || getNumber (configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(canPush)) == 1} && +{getMass _target <= 2600 || getNumber (configOf _target >> QGVAR(canPush)) == 1} && {vectorMagnitude velocity _target < 3} diff --git a/addons/interaction/functions/fnc_canRenameGroup.sqf b/addons/interaction/functions/fnc_canRenameGroup.sqf new file mode 100644 index 0000000000..7112db0cbb --- /dev/null +++ b/addons/interaction/functions/fnc_canRenameGroup.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Seb + * Checks if the unit is allowed to rename its group. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Is this unit allowed to rename its group? + * + * Example: + * player call ace_interaction_fnc_canRenameGroup + * + * Public: No + */ + +params [["_unit", objNull, [objNull]]]; + +GVAR(enableGroupRenaming) && {_unit == leader _unit} diff --git a/addons/interaction/functions/fnc_canTapShoulder.sqf b/addons/interaction/functions/fnc_canTapShoulder.sqf index 0c3551051d..049c178152 100644 --- a/addons/interaction/functions/fnc_canTapShoulder.sqf +++ b/addons/interaction/functions/fnc_canTapShoulder.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Checks if the player can tap a shoulder. diff --git a/addons/interaction/functions/fnc_doBecomeLeader.sqf b/addons/interaction/functions/fnc_doBecomeLeader.sqf index 8bf1b23e30..bebda4d262 100644 --- a/addons/interaction/functions/fnc_doBecomeLeader.sqf +++ b/addons/interaction/functions/fnc_doBecomeLeader.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Become Leader of group. diff --git a/addons/interaction/functions/fnc_doRemoteControl.sqf b/addons/interaction/functions/fnc_doRemoteControl.sqf new file mode 100644 index 0000000000..a2ec19b180 --- /dev/null +++ b/addons/interaction/functions/fnc_doRemoteControl.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: kymckay, joko + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_interaction_fnc_doRemoteControl + * + * Public: No + */ + +private _units = curatorSelected select 0; +private _index = _units findIf { + (side _x) in [east, west, resistance, civilian] + && !(isPlayer _x) +}; +private _unit = _units param [_index, objNull]; +bis_fnc_curatorObjectPlaced_mouseOver = ["OBJECT", _unit]; +private _rc = (group _target) createUnit ["ModuleRemoteControl_F", [0,0,0], [], 0, "NONE"]; +_rc setVariable ["BIS_fnc_initModules_disableAutoActivation", false]; diff --git a/addons/interaction/functions/fnc_getDoor.sqf b/addons/interaction/functions/fnc_getDoor.sqf index 6503d1e9e9..5f251d2589 100644 --- a/addons/interaction/functions/fnc_getDoor.sqf +++ b/addons/interaction/functions/fnc_getDoor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Phyma * Find door. @@ -33,7 +33,7 @@ if (typeOf _house == "") exitWith {[objNull, ""]}; _intersections = [_house, "GEOM"] intersect [_position0, _position1]; -private _door = toLower (_intersections select 0 select 0); +private _door = toLowerANSI (_intersections select 0 select 0); if (isNil "_door") exitWith {[_house, ""]}; diff --git a/addons/interaction/functions/fnc_getDoorAnimations.sqf b/addons/interaction/functions/fnc_getDoorAnimations.sqf index 003cce7664..b91c5eac6c 100644 --- a/addons/interaction/functions/fnc_getDoorAnimations.sqf +++ b/addons/interaction/functions/fnc_getDoorAnimations.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Phyma * Get door animations. @@ -23,10 +23,13 @@ params ["_house", "_door"]; private _animate = animationNames _house; private _animations = []; private _lockedVariable = []; +private _numberStrings = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; { - private _animName = toLower _x; - if ((_animName find (toLower _door)) != -1) then { + private _animName = toLowerANSI _x; + private _index = _animName find toLowerANSI _door; + + if (_index != -1 && {!(_animName select [_index + count _door, 1] in _numberStrings)}) then { if (((_animName find "disabled") != -1) || ((_animName find "locked") != -1)) then { _lockedVariable pushBack _animName; } else { diff --git a/addons/interaction/functions/fnc_getDown.sqf b/addons/interaction/functions/fnc_getDown.sqf index 4291a00f0d..531cd23c54 100644 --- a/addons/interaction/functions/fnc_getDown.sqf +++ b/addons/interaction/functions/fnc_getDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Forces a civilian to the ground with a chance of failure. @@ -22,11 +22,10 @@ params ["_unit", "_target"]; [_unit, "GestureGo"] call EFUNC(common,doGesture); -private _chance = [0.5, 0.8] select (count weapons _unit > 0); +private _chance = [0.5, 0.8] select (weapons _unit isNotEqualTo []); { - if (count weapons _x == 0 && {random 1 < _chance}) then { + if (weapons _x isEqualTo [] && {random 1 < _chance}) then { [QGVAR(getDown), [_x], [_x]] call CBA_fnc_targetEvent; }; - false -} count (_target nearEntities ["Civilian", SEND_RADIUS]); +} forEach (_target nearEntities ["Civilian", SEND_RADIUS]); diff --git a/addons/interaction/functions/fnc_getGlassDoor.sqf b/addons/interaction/functions/fnc_getGlassDoor.sqf index 5febe67067..2aea74f82d 100644 --- a/addons/interaction/functions/fnc_getGlassDoor.sqf +++ b/addons/interaction/functions/fnc_getGlassDoor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Phyma * Find glass door. @@ -26,7 +26,7 @@ private _glassDoor = _door splitString "_"; private _glassPos = (_house selectionPosition [(_glassDoor select 0) + "_" + (_glassDoor select 1) + "_effects", "Memory"]); // Calculate all animation names so we know what is there { - private _animName = toLower _x; + private _animName = toLowerANSI _x; if (((_animName find "door") != -1) && ((_animName find "locked") == -1) && ((_animName find "disabled") == -1) && ((_animName find "handle") == -1)) then { private _splitStr = _animName splitString "_"; _doorParts pushBack ((_splitStr select 0) + "_" + (_splitStr select 1) + "_trigger"); @@ -64,4 +64,3 @@ private _lowestDistance = 0; if ((isNil "_door") || ((_door find "glass") != -1)) exitWith {}; _door - diff --git a/addons/interaction/functions/fnc_getInteractionDistance.sqf b/addons/interaction/functions/fnc_getInteractionDistance.sqf index fa15577ed2..1b60b9539c 100644 --- a/addons/interaction/functions/fnc_getInteractionDistance.sqf +++ b/addons/interaction/functions/fnc_getInteractionDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Gets effective interaction distance (handles very large vehicles) @@ -26,7 +26,7 @@ if (!((_target isKindOf "Car") || {_target isKindOf "Tank"} || {_target isKindOf private _unitEyeASL = eyePos _unit; private _targetModelPos = [_target, _unitEyeASL] call FUNC(getVehiclePosComplex); -private _distance = _unitEyeASL distance (AGLtoASL (_target modelToWorld _targetModelPos)); +private _distance = _unitEyeASL distance (_target modelToWorldWorld _targetModelPos); TRACE_2("",_targetModelPos,_distance); diff --git a/addons/interaction/functions/fnc_getVehiclePos.sqf b/addons/interaction/functions/fnc_getVehiclePos.sqf index bd25fc710b..ce2ce9377b 100644 --- a/addons/interaction/functions/fnc_getVehiclePos.sqf +++ b/addons/interaction/functions/fnc_getVehiclePos.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Return a suitable position for the action point for the given target vehicle @@ -67,7 +67,7 @@ if (cursorObject isEqualTo _target) exitWith { private _dest = EGVAR(interact_menu,cameraPosASL) vectorAdd (EGVAR(interact_menu,cameraDir) vectorMultiply 50); private _origin = EGVAR(interact_menu,cameraPosASL); //private _origin = EGVAR(interact_menu,cameraPosASL) vectorAdd [0, 0, -0.35] vectorDiff (EGVAR(interact_menu,cameraDir) vectorMultiply 1.5); - //private _dest = AGLtoASL (_target modelToWorldVisual [0,0,0]); + //private _dest = _target modelToWorldVisualWorld [0,0,0]; private _results = lineIntersectsSurfaces [_origin, _dest, ACE_player, objNull, true, 5]; private _finalPos = [0,0,0]; { diff --git a/addons/interaction/functions/fnc_getVehiclePosComplex.sqf b/addons/interaction/functions/fnc_getVehiclePosComplex.sqf index 17f77922b9..f41b255ad9 100644 --- a/addons/interaction/functions/fnc_getVehiclePosComplex.sqf +++ b/addons/interaction/functions/fnc_getVehiclePosComplex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain, PabstMirror * Return a suitable position for the action point for the given target vehicle @@ -22,7 +22,7 @@ TRACE_2("params",_target,_cameraPosASL); private _bb = boundingBoxReal _target; (_bb select 0) params ["_bbX", "_bbY", "_bbZ"]; -private _config = configFile >> "CfgVehicles" >> (typeOf _target); +private _config = configOf _target; if (isNumber (_config >> QGVAR(bodyWidth))) then {_bbX = getNumber (_config >> QGVAR(bodyWidth));}; if (isNumber (_config >> QGVAR(bodyLength))) then {_bbY = getNumber (_config >> QGVAR(bodyLength));}; diff --git a/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf b/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf new file mode 100644 index 0000000000..c771589904 --- /dev/null +++ b/addons/interaction/functions/fnc_getWeaponAttachmentsActions.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Dystopian + * Returns children actions for weapon attachment switching. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Actions + * + * Example: + * player call ace_interaction_fnc_getWeaponAttachmentsActions + * + * Public: No + */ + +params ["_unit"]; + +[_unit, { + params ["_unit"]; + + private _currentWeapon = currentWeapon _unit; + if (_currentWeapon isEqualTo "") exitWith {[]}; + private _weaponItems = _unit weaponAccessories _currentWeapon; + private _cfgWeapons = configFile >> "CfgWeapons"; + private _actions = []; + + // "attach" actions + private _items = _unit call EFUNC(common,uniqueItems); + private _compatibleItems = _currentWeapon call CBA_fnc_compatibleItems; + { + private _config = _cfgWeapons >> _x; + private _name = format [LLSTRING(weaponAttachmentsAttach), getText (_config >> "displayName")]; + private _picture = getText (_config >> "picture"); + private _type = getNumber (_config >> "itemInfo" >> "type"); + private _oldAttachment = _weaponItems select ([TYPE_MUZZLE, TYPE_FLASHLIGHT, TYPE_OPTICS, TYPE_BIPOD] find _type); + + private _action = [ + _x, _name, _picture, + LINKFUNC(switchWeaponAttachment), + {true}, + {}, + [_currentWeapon, _x, _oldAttachment] + ] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _unit]; + } forEach ((_items arrayIntersect _compatibleItems) - _weaponItems); + + // "detach" actions + { + if (_x isEqualTo "") then {continue}; + + private _config = _cfgWeapons >> _x; + private _name = format [LLSTRING(weaponAttachmentsDetach), getText (_config >> "displayName")]; + private _picture = getText (_config >> "picture"); + + private _action = [ + _x, _name, _picture, + LINKFUNC(switchWeaponAttachment), + {true}, + {}, + [_currentWeapon, "", _x] + ] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _unit]; + } forEach _weaponItems; + + _actions +}, _unit, QGVAR(weaponAttachmentsActions), 5, QGVAR(clearWeaponAttachmentsActionsCache)] call EFUNC(common,cachedCall); diff --git a/addons/interaction/functions/fnc_getWeaponPos.sqf b/addons/interaction/functions/fnc_getWeaponPos.sqf index 9cd526c12c..85cb3dc007 100644 --- a/addons/interaction/functions/fnc_getWeaponPos.sqf +++ b/addons/interaction/functions/fnc_getWeaponPos.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Return a suitable position for the action point for the current weapon diff --git a/addons/interaction/functions/fnc_handleScrollWheel.sqf b/addons/interaction/functions/fnc_handleScrollWheel.sqf index 769995d0a6..ab27419983 100644 --- a/addons/interaction/functions/fnc_handleScrollWheel.sqf +++ b/addons/interaction/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles incremental door opening diff --git a/addons/interaction/functions/fnc_hideMouseHint.sqf b/addons/interaction/functions/fnc_hideMouseHint.sqf index 8daa6d6e09..b7f0420dc5 100644 --- a/addons/interaction/functions/fnc_hideMouseHint.sqf +++ b/addons/interaction/functions/fnc_hideMouseHint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth de Wet (LH) * Hides the interaction hint for mouse buttons. diff --git a/addons/interaction/functions/fnc_joinTeam.sqf b/addons/interaction/functions/fnc_joinTeam.sqf index 92e06b4217..977e902222 100644 --- a/addons/interaction/functions/fnc_joinTeam.sqf +++ b/addons/interaction/functions/fnc_joinTeam.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Unit joins a fire team. @@ -6,19 +6,20 @@ * Arguments: * 0: Unit * 1: Team + * 2: Display hint (default: false) * * Return Value: * None * * Example: - * [player, "YELLOW"] call ace_interaction_fnc_joinTeam + * [player, "YELLOW", false] call ace_interaction_fnc_joinTeam * * Public: No */ -params ["_unit", "_team"]; +params ["_unit", "_team", ["_displayHint", false, [false]]]; -["CBA_teamColorChanged", [_unit, _team]] call CBA_fnc_globalEvent; +_unit assignTeam _team; // display message if (_unit == ACE_player) then { @@ -30,6 +31,7 @@ if (_unit == ACE_player) then { _team = localize format [LSTRING(Team%1), _team]; _message = format [localize LSTRING(JoinedTeam), _team]; }; - - [_message] call EFUNC(common,displayTextStructured); + if (_displayHint) then { + [_message] call EFUNC(common,displayTextStructured); + }; }; diff --git a/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf b/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf index 480cdaea40..eef77dfd37 100644 --- a/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf +++ b/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Modifies the ACE_JoinGroup action to show group name. diff --git a/addons/interaction/functions/fnc_modifyTeamManagementAction.sqf b/addons/interaction/functions/fnc_modifyTeamManagementAction.sqf new file mode 100644 index 0000000000..6324c0598a --- /dev/null +++ b/addons/interaction/functions/fnc_modifyTeamManagementAction.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Modifies the ACE_TeamManagement or join team action with given group color and icon. + * + * Arguments: + * 0: Team color + * 1: Icon to show on action + * 2: Action Data to modifiy + * + * Return Value: + * None + * + * + * Public: No + */ + +params ["_teamColor", "_icon", "_actionData"]; + +private _color = switch (toUpper _teamColor) do { + case "RED": {missionNamespace getVariable [QEGVAR(nametags,nametagColorRed), [221, 0, 0]]}; + case "GREEN": {missionNamespace getVariable [QEGVAR(nametags,nametagColorGreen), [0, 221, 0]]}; + case "BLUE": {missionNamespace getVariable [QEGVAR(nametags,nametagColorBlue), [0, 0, 221]]}; + case "YELLOW": {missionNamespace getVariable [QEGVAR(nametags,nametagColorYellow), [221, 221, 0]]}; + default {missionNamespace getVariable [QEGVAR(nametags,nametagColorMain), [255, 255, 255]]}; +}; + +_actionData set [2, [_icon, _color call BIS_fnc_colorRGBtoHTML]]; + +nil diff --git a/addons/interaction/functions/fnc_moduleInteraction.sqf b/addons/interaction/functions/fnc_moduleInteraction.sqf index 7dd5baa464..25f9d50a45 100644 --- a/addons/interaction/functions/fnc_moduleInteraction.sqf +++ b/addons/interaction/functions/fnc_moduleInteraction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Initializes the Interaction module. diff --git a/addons/interaction/functions/fnc_openDoor.sqf b/addons/interaction/functions/fnc_openDoor.sqf index 73cf4e0a37..11b9c67c91 100644 --- a/addons/interaction/functions/fnc_openDoor.sqf +++ b/addons/interaction/functions/fnc_openDoor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Open door. @@ -23,7 +23,7 @@ TRACE_2("openDoor",_house,_door); if (isNull _house) exitWith {}; -if ((configProperties [configFile >> "CfgVehicles" >> (typeOf _house) >> "UserActions"]) isEqualTo []) exitWith { +if ((configProperties [configOf _house >> "UserActions"]) isEqualTo []) exitWith { TRACE_1("Ignore houses with no UserActions",typeOf _house); // Fix problem with Shoothouse Walls }; @@ -34,12 +34,17 @@ _getDoorAnimations params ["_animations"]; if (_animations isEqualTo []) exitWith {}; private _lockedVariable = format ["bis_disabled_%1", _door]; +private _lockedVariableAlt = _lockedVariable; // GM Buildings may have door names like door_01 but locking expects door_1 +if ((count _door == 7) && {(_door select [0, 6]) == "door_0"}) then { + _lockedVariableAlt = format ["bis_disabled_door_%1", _door select [6, 1]]; // stip off the leading zero then check both vars +}; // Check if the door can be locked aka have locked variable, otherwhise cant lock it -if ((_house animationPhase (_animations select 0) <= 0) && {_house getVariable [_lockedVariable, 0] == 1}) exitWith { +if ((_house animationPhase (_animations select 0) <= 0) && + {(_house getVariable [_lockedVariable, 0] == 1) || {_house getVariable [_lockedVariableAlt, 0] == 1}}) exitWith { private _lockedAnimation = format ["%1_locked_source", _door]; - TRACE_3("locked",_house,_lockedAnimation,isClass (configfile >> "CfgVehicles" >> (typeOf _house) >> "AnimationSources" >> _lockedAnimation)); - if (isClass (configfile >> "CfgVehicles" >> (typeOf _house) >> "AnimationSources" >> _lockedAnimation)) then { + TRACE_3("locked",_house,_lockedAnimation,isClass (configOf _house >> "AnimationSources" >> _lockedAnimation)); + if (isClass (configOf _house >> "AnimationSources" >> _lockedAnimation)) then { // from: a3\structures_f\scripts\fn_door.sqf: - wiggles the door handle (A3 buildings) _house animateSource [_lockedAnimation, (1 - (_house animationSourcePhase _lockedAnimation))]; }; @@ -47,7 +52,7 @@ if ((_house animationPhase (_animations select 0) <= 0) && {_house getVariable [ // Add handle on carrier if (typeOf _house == "Land_Carrier_01_island_01_F") then { - private _handle = format ["door_handle_%1_rot_1", (_animations select 0) select [5, 1]]; + private _handle = format ["door_handle_%1_rotate_1", (_animations select 0) select [5, 1]]; TRACE_1("carrier handle",_handle); _animations pushBack _handle; }; @@ -58,18 +63,24 @@ GVAR(doorTargetPhase) = _house animationPhase (_animations select 0); GVAR(isOpeningDoor) = true; GVAR(usedScrollWheel) = false; +// Raise local started opening event +[QGVAR(doorOpeningStarted), [_house, _door, _animations]] call CBA_fnc_localEvent; + [{ - (_this select 0) params ["_house", "_animations", "_position", "_time", "_frame"]; + (_this select 0) params ["_house", "_animations", "_position", "_time", "_frame", "_door"]; if !(GVAR(isOpeningDoor)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; // didn't use incremental opening. Just do animation normally. if !(GVAR(usedScrollWheel)) then { - private _phase = [0, 1] select (_house animationPhase (_animations select 0) < 0.5); + private _phase = parseNumber (_house animationPhase (_animations select 0) < 0.5); - {_house animate [_x, _phase]; false} count _animations; + {_house animate [_x, _phase]} forEach _animations; }; + + // Raise local stopped opening event + [QGVAR(doorOpeningStopped), [_house, _door, _animations]] call CBA_fnc_localEvent; }; // check if player moved too far away @@ -82,5 +93,5 @@ GVAR(usedScrollWheel) = false; GVAR(usedScrollWheel) = true; }; // do incremental door opening - {_house animate [_x, GVAR(doorTargetPhase)]; false} count _animations; -}, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameno + 2]] call CBA_fnc_addPerFrameHandler; + {_house animate [_x, GVAR(doorTargetPhase)]} forEach _animations; +}, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameno + 2, _door]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/interaction/functions/fnc_pardon.sqf b/addons/interaction/functions/fnc_pardon.sqf index 4a64771e81..5a29c13046 100644 --- a/addons/interaction/functions/fnc_pardon.sqf +++ b/addons/interaction/functions/fnc_pardon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Unit pardons target unit. diff --git a/addons/interaction/functions/fnc_passMagazine.sqf b/addons/interaction/functions/fnc_passMagazine.sqf index 07db3dba3c..8750078502 100644 --- a/addons/interaction/functions/fnc_passMagazine.sqf +++ b/addons/interaction/functions/fnc_passMagazine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Pass spare magazine for the specified weapon. @@ -7,6 +7,7 @@ * 0: Unit that passes the magazine * 1: Unit to pass the magazine to * 2: Weapon classname + * 3: Play passing animation (default: true) * * Return Value: * None @@ -16,12 +17,12 @@ * * Public: No */ -params ["_player", "_target", "_weapon"]; +params ["_player", "_target", "_weapon", ["_animate", true, [true]]]; private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; private _filteredMags = magazinesAmmoFull _player select { _x params ["_className", "", "_loaded"]; - (_className in _compatibleMags) && {!_loaded} && {_target canAdd _className} + (_className in _compatibleMags) && {!_loaded} && {[_target, _className] call CBA_fnc_canAddItem} }; //select magazine with most ammo @@ -35,18 +36,12 @@ private _magToPassIndex = 0; }; } foreach _filteredMags; -//remove all magazines and add them again, except the one to be passed -//needed because of missing commands, see http://feedback.arma3.com/view.php?id=12782 +//remove the magazine from _player and add it to _target _magToPass params ["_magToPassClassName", "_magToPassAmmoCount"]; -_player removeMagazines _magToPassClassName; -{ - _x params ["_className", "_ammoCount"]; - if ((_className == _magToPassClassName) && (_forEachIndex != _magToPassIndex)) then { - _player addMagazine [_className, _ammoCount]; - }; -} foreach _filteredMags; +// Exit if failed to remove specific magazine +if !([_player, _magToPassClassName, _magToPassAmmoCount] call EFUNC(common,removeSpecificMagazine)) exitWith {}; -[_player, "PutDown"] call EFUNC(common,doGesture); +if (_animate) then {[_player, "PutDown"] call EFUNC(common,doGesture)}; _target addMagazine [_magToPassClassName, _magToPassAmmoCount]; diff --git a/addons/interaction/functions/fnc_pullOutBody.sqf b/addons/interaction/functions/fnc_pullOutBody.sqf index 6f754eae67..397fc30f84 100644 --- a/addons/interaction/functions/fnc_pullOutBody.sqf +++ b/addons/interaction/functions/fnc_pullOutBody.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Makes unit pull target body out of vehicle. @@ -37,7 +37,7 @@ TRACE_3("",_cargoIndex,_cargoNumber,_turretPath); private _preserveEngineOn = false; // first get in to target seat -if (!(_turretPath isEqualTo [])) then { +if (_turretPath isNotEqualTo []) then { _unit action ["GetInTurret", _vehicle, _turretPath]; } else { if (_cargoIndex > -1) then { diff --git a/addons/interaction/functions/fnc_push.sqf b/addons/interaction/functions/fnc_push.sqf index abed6be396..be4440eceb 100644 --- a/addons/interaction/functions/fnc_push.sqf +++ b/addons/interaction/functions/fnc_push.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Pushes a boat away from the player diff --git a/addons/interaction/functions/fnc_renameGroup.sqf b/addons/interaction/functions/fnc_renameGroup.sqf new file mode 100644 index 0000000000..4ffff5771a --- /dev/null +++ b/addons/interaction/functions/fnc_renameGroup.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Seb + * Renames a group to a given string (groupID), whilst checking that it is not an invalid name. + * + * Arguments: + * 0: The group to be renamed + * 1: The new name of the group + * + * Return Value: + * Whether the group was succesfully renamed + * + * Example: + * [group player, "leet squad"] call ace_interaction_fnc_renameGroup + * + * Public: No + */ + +params [ + ["_group", grpNull, [grpNull]], + ["_newName", "", [""]] +]; +if (_newName isEqualTo (groupID _group)) exitWith {true}; + +private _lowerName = toLower _newName; // Case insensitive name search +private _nameAlreadyTaken = allGroups findIf { + side _x isEqualTo side _group + && {_lowerName isEqualTo toLower (groupID _x)} + && {_group != _x} +} != -1; + + +if (_nameAlreadyTaken) then { + [LLSTRING(RenameGroupAlreadyExists)] call EFUNC(common,displayTextStructured); +} else { + _group setGroupIdGlobal [_newName]; +}; + +!_nameAlreadyTaken diff --git a/addons/interaction/functions/fnc_renameGroupUI.sqf b/addons/interaction/functions/fnc_renameGroupUI.sqf new file mode 100644 index 0000000000..5d891b0cf8 --- /dev/null +++ b/addons/interaction/functions/fnc_renameGroupUI.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: Seb + * Shows a UI to allow a unit to change its group ID. + * + * Arguments: + * 0: The unit renaming their group + * + * Return Value: + * None + * + * Example: + * player call ace_interaction_fnc_renameGroupUI + * + * Public: No + */ + +// delay a frame so we don't overlap with interaction-menu as it closes +[{ + params [["_unit", objNull, [objNull]]]; + + private _display = findDisplay 46 createDisplay QGVAR(groupNameDisplay); + private _textCtrl = _display displayCtrl 451; + _textCtrl ctrlSetText (groupID group _unit); + _display setVariable [QGVAR(renamedGroup), group _unit]; + _display displayAddEventHandler ["Unload", { + params ["_display", "_exitCode"]; + + if (_exitCode isNotEqualTo 1) exitWith {}; + + private _group = _display getVariable QGVAR(renamedGroup); + private _textCtrl = _display displayCtrl 451; + private _newName = ctrlText _textCtrl; + [_group, _newName] call FUNC(renameGroup); + }]; +}, _this] call CBA_fnc_execNextFrame; diff --git a/addons/interaction/functions/fnc_replaceTerrainObject.sqf b/addons/interaction/functions/fnc_replaceTerrainObject.sqf new file mode 100644 index 0000000000..a857df3f95 --- /dev/null +++ b/addons/interaction/functions/fnc_replaceTerrainObject.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Replaces terrain object with created one. + * Run on server only. + * + * Arguments: + * 0: Terrain object + * 1: New object class + * + * Return Value: + * None + * + * Example: + * [cursorObject, "Land_Bucket_F"] call ace_interaction_fnc_replaceTerrainObject + * + * Public: No + */ + +params ["_terrainObject", "_class"]; +TRACE_2("",_terrainObject,_class); + +if (isObjectHidden _terrainObject) exitWith {}; + +private _position = getPosATL _terrainObject; +if (_position select 2 < 0) then { + _position set [2, 0]; +}; +private _vectorDirAndUp = [vectorDir _terrainObject, vectorUp _terrainObject]; + +hideObjectGlobal _terrainObject; +// prevent new object clipping with old one +_terrainObject setDamage [1, false]; + +private _newObject = createVehicle [_class, [0,0,0]]; +_newObject setVectorDirAndUp _vectorDirAndUp; +_newObject setPosATL _position; diff --git a/addons/interaction/functions/fnc_sendAway.sqf b/addons/interaction/functions/fnc_sendAway.sqf index 4831fb7e3f..b986ea2661 100644 --- a/addons/interaction/functions/fnc_sendAway.sqf +++ b/addons/interaction/functions/fnc_sendAway.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Sends a near civilian crowd away with a chance of failure. @@ -22,14 +22,13 @@ params ["_unit"]; [_unit, "GestureGo"] call EFUNC(common,doGesture); -private _chance = [0.5, 0.8] select (count weapons _unit > 0); +private _chance = [0.5, 0.8] select (weapons _unit isNotEqualTo []); { - if (count weapons _x == 0 && {random 1 < _chance}) then { + if (weapons _x isEqualTo [] && {random 1 < _chance}) then { private _position = getPosASL _unit vectorAdd (eyeDirection _unit vectorMultiply SEND_DISTANCE); _position set [2, 0]; [QGVAR(sendAway), [_x, _position], [_x]] call CBA_fnc_targetEvent; }; - false -} count (_unit nearEntities ["Civilian", SEND_RADIUS]); +} forEach (_unit nearEntities ["Civilian", SEND_RADIUS]); diff --git a/addons/interaction/functions/fnc_showMouseHint.sqf b/addons/interaction/functions/fnc_showMouseHint.sqf index b56d053eaa..9adc15f493 100644 --- a/addons/interaction/functions/fnc_showMouseHint.sqf +++ b/addons/interaction/functions/fnc_showMouseHint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth de Wet (LH), mharis001 * Shows an interaction hint for mouse buttons. @@ -8,7 +8,7 @@ * 0: Left click text * 1: Right click text * 2: Scroll text (default: "") - * 2: Extra icon/text pairs (default: []) + * 3: Extra icon/text pairs (default: []) * * Return Value: * None @@ -71,7 +71,7 @@ if (_textMMB == "") then { // Only create extra key if both name and text are valid if (_keyName != "" && {_keyText != ""}) then { // Localize Ctrl, Shift, or Alt keys - switch (toLower _keyName) do { + switch (toLowerANSI _keyName) do { case "ctrl"; case "control": {_keyName = format ["<%1>", toUpper localize "STR_dik_control"]}; case "shift": {_keyName = format ["<%1>", toUpper localize "STR_dik_shift"]}; diff --git a/addons/interaction/functions/fnc_switchWeaponAttachment.sqf b/addons/interaction/functions/fnc_switchWeaponAttachment.sqf new file mode 100644 index 0000000000..aaefb3315e --- /dev/null +++ b/addons/interaction/functions/fnc_switchWeaponAttachment.sqf @@ -0,0 +1,59 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Dystopian + * Switches weapon attachment. + * + * Arguments: + * 0: Target + * 1: Player (not used) + * 2: Action params + * + * Return Value: + * None + * + * Example: + * [player, player, [currentWeapon player, "acc_flashlight", ""]] call ace_interaction_fnc_switchWeaponAttachment + * + * Public: No + */ + +params ["_unit", "", "_actionParams"]; +_actionParams params ["_weapon", "_newAttachment", "_oldAttachment"]; +TRACE_3("Switching attachment",_weapon,_newAttachment,_oldAttachment); + +[_unit, "Gear"] call EFUNC(common,doGesture); + +private _addNew = _newAttachment isNotEqualTo ""; +private _removeOld = _oldAttachment isNotEqualTo ""; + +if (_addNew) then { + _unit removeItem _newAttachment; +}; + +if (_removeOld && {!([_unit, _oldAttachment] call CBA_fnc_canAddItem)}) exitWith { + LOG("no space"); + [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); + if (_addNew) then { + _unit addItem _newAttachment; + }; +}; + +if (_removeOld) then { + [{ + params ["_unit", "_weapon", "_oldAttachment"]; + switch (_weapon) do { + case (primaryWeapon _unit): {_unit removePrimaryWeaponItem _oldAttachment;}; + case (handgunWeapon _unit): {_unit removeHandgunItem _oldAttachment;}; + default {_unit removeSecondaryWeaponItem _oldAttachment;}; + }; + _unit addItem _oldAttachment; + }, [_unit, _weapon, _oldAttachment], 0.3] call CBA_fnc_waitAndExecute; +}; + +if (!_addNew) exitWith {}; + +[{ + params ["_unit", "_weapon", "_newAttachment"]; + _unit addWeaponItem [_weapon, _newAttachment]; + [[getText (configFile >> "CfgWeapons" >> _newAttachment >> "picture"), 4], true] call CBA_fnc_notify; +}, [_unit, _weapon, _newAttachment], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/interaction/functions/fnc_tapShoulder.sqf b/addons/interaction/functions/fnc_tapShoulder.sqf index c55f3b65d4..b7e88e8a7e 100644 --- a/addons/interaction/functions/fnc_tapShoulder.sqf +++ b/addons/interaction/functions/fnc_tapShoulder.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Taps a shoulder diff --git a/addons/interaction/functions/script_component.hpp b/addons/interaction/functions/script_component.hpp deleted file mode 100644 index ef1c22f146..0000000000 --- a/addons/interaction/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\interaction\script_component.hpp" \ No newline at end of file diff --git a/addons/interaction/groupRename_GUI.hpp b/addons/interaction/groupRename_GUI.hpp new file mode 100644 index 0000000000..20684b0e46 --- /dev/null +++ b/addons/interaction/groupRename_GUI.hpp @@ -0,0 +1,66 @@ +#define FONT_H (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1) +#define FONT_W (FONT_H / pixelH * pixelW) +#define GAP_W (pixelW * 2) +#define GAP_H (pixelH * 2) +#define ELEMENT_HEIGHT FONT_H + FONT_W +#define TOTAL_W FONT_W * 25 +#define TOTAL_H FONT_H * 3 + GAP_H + +class ctrlStatic; +class ctrlButton; +class ctrlEdit; +class ctrlStaticTitle; + +class GVAR(groupNameDisplay) { + idd = -1; + enableSimulation = 1; + + class ControlsBackground { + class Title: ctrlStaticTitle { + x = QUOTE(safeZoneX + (safeZoneW / 2) - TOTAL_W/2); + y = QUOTE(safeZoneY + (safeZoneH / 2) - (FONT_H * 1.2) - GAP_H); + w = QUOTE(TOTAL_W); + h = QUOTE(FONT_H * 1.2); + sizeEx = QUOTE(FONT_H * 1.2); + text = CSTRING(renameGroupInput); + }; + class Background: ctrlStatic { + colorBackground[] = {0, 0, 0, 0.8}; + x = QUOTE(safeZoneX + (safeZoneW / 2) - TOTAL_W/2); + y = QUOTE(safeZoneY + (safeZoneH / 2)); + w = QUOTE(TOTAL_W); + h = QUOTE(ELEMENT_HEIGHT); + }; + }; + + class controls { + class Input: ctrlEdit { + idc = 451; + x = QUOTE(safeZoneX + (safeZoneW / 2) - TOTAL_W/2 + FONT_W/2); + y = QUOTE(safeZoneY + (safeZoneH / 2) + FONT_W/2); + w = QUOTE(TOTAL_W - FONT_W); + h = QUOTE(ELEMENT_HEIGHT - FONT_W); + sizeEx = QUOTE(FONT_H); + }; + + class OkButton: ctrlButton { + idc = 1; + x = QUOTE(safeZoneX + (safeZoneW / 2) + TOTAL_W/2 - FONT_W * 15); + y = QUOTE(safeZoneY + (safeZoneH / 2) + ELEMENT_HEIGHT + GAP_H); + w = QUOTE(FONT_W * 15); + h = QUOTE(ELEMENT_HEIGHT - FONT_W); + sizeEx = QUOTE(FONT_H); + text = CSTRING(RenameGroup); + }; + + class CancelButton: ctrlButton { + idc = 2; + x = QUOTE(safeZoneX + (safeZoneW / 2) - TOTAL_W/2); + y = QUOTE(safeZoneY + (safeZoneH / 2) + ELEMENT_HEIGHT + GAP_H); + w = QUOTE(FONT_W * 6); + h = QUOTE(ELEMENT_HEIGHT - FONT_W); + sizeEx = QUOTE(FONT_H); + text = CSTRING(CancelSelection); + }; + }; +}; diff --git a/addons/interaction/initSettings.inc.sqf b/addons/interaction/initSettings.inc.sqf new file mode 100644 index 0000000000..2cefb162a7 --- /dev/null +++ b/addons/interaction/initSettings.inc.sqf @@ -0,0 +1,47 @@ +[ + QGVAR(enableTeamManagement), "CHECKBOX", + [LSTRING(EnableTeamManagement_DisplayName), LSTRING(EnableTeamManagement_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(enableMagazinePassing), "CHECKBOX", + LSTRING(PassMagazineSetting), + format ["ACE %1", LLSTRING(DisplayName)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(disableNegativeRating), "CHECKBOX", + [LSTRING(DisableNegativeRating_DisplayName), LSTRING(DisableNegativeRating_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true, + {[QGVAR(disableNegativeRating), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(enableWeaponAttachments), "CHECKBOX", + ["str_a3_cfgeditorcategories_edcat_weaponattachments0", LSTRING(weaponAttachments_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(enableGroupRenaming), "CHECKBOX", + [LSTRING(EnableRenameGroup_DisplayName), LSTRING(EnableRenameGroup_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(interactWithTerrainObjects), "CHECKBOX", + ["str_a3_modules_moduleomquest_defend_f_attributes_useterrainobject0", LSTRING(interactWithTerrainObjects_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true +] call CBA_fnc_addSetting; diff --git a/addons/interaction/script_component.hpp b/addons/interaction/script_component.hpp index 8114dc37a2..9c0ab4c764 100644 --- a/addons/interaction/script_component.hpp +++ b/addons/interaction/script_component.hpp @@ -30,6 +30,6 @@ #define IDC_MOUSEHINT_EXTRA_NAME 2510 #define IDC_MOUSEHINT_EXTRA_TEXT 2520 -#define MACRO_DOOR_REACH_DISTANCE (AGLToASL positionCameraToWorld [0,0,0] vectorDistance AGLToASL (ACE_player modelToWorld (ACE_player selectionPosition "Head"))) + 2 +#define MACRO_DOOR_REACH_DISTANCE ((AGLToASL positionCameraToWorld [0, 0, 0]) vectorDistance (ACE_player modelToWorldWorld (ACE_player selectionPosition "Head"))) + 2 #define DISABLED_LAMP_DAMAGE 0.95 diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 65c1dfa00f..41861dcb31 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -6,11 +6,16 @@ Interaktion Interazione 互動 - 互动 + 互动菜单 インタラクション 상호작용 Interakcja Взаимодействие + Interação + Interaction + Interakce + Interacción + Etkileşim Interactions @@ -22,11 +27,12 @@ Взаимодействия Cselekvések Interazioni - Interaçãoes + Interações インタラクション 상호작용 互动 互動 + Etkileşimler Torso @@ -43,6 +49,7 @@ 몸통 身体 身體 + Gövde Head @@ -59,6 +66,7 @@ 머리 头部 頭部 + Kafa Left Arm @@ -72,9 +80,10 @@ Braccio sinistro Braço Esquerdo 左腕 - 왼쪽 팔 + 왼팔 左手 左手 + Sol Kol Right Arm @@ -88,9 +97,10 @@ Braccio destro Braço Direito 右腕 - 오른쪽 팔 + 오른팔 右手 右手 + Sağ Kol Left Leg @@ -104,9 +114,10 @@ Gamba sinistra Perna Esquerda 左足 - 왼쪽 다리 + 왼다리 左脚 左腳 + Sol Bacak Right Leg @@ -120,9 +131,10 @@ Gamba destra Perna Direita 右足 - 오른쪽 다리 + 오른다리 右脚 右腳 + Sağ Bacak Weapon @@ -139,6 +151,7 @@ 무기 武器 武器 + Silah Interaction Menu @@ -150,11 +163,12 @@ Меню взаимодействия Cselekvő menü Menu de Interação - Menù interazione - インタラクション メニュー + Menù Interazioni + インタラクションメニュー 상호작용 메뉴 - 互动选单 + 互动菜单 互動選單 + Etkileim Menüsü Interaction Menu (Self) @@ -162,15 +176,16 @@ Menú de interacción (Propio) Menu interakcji (własne) Menu interakce (vlastní) - Menu d'interaction (Perso) + Menu d'interaction (personnel) Меню взаимодействия (с собой) Cselekvő menü (saját) Menu de Interação (Individual) - Menù interazione (individuale) - インタラクション メニュー (セルフ) + Menù Interazioni (su se stesso) + インタラクションメニュー (セルフ) 상호작용 메뉴(자신) - 互动选单 (自我) + 互动菜单(自我) 互動選單 (自我) + Etkileşim Menüsü(Şahsi) Open / Close Door @@ -178,8 +193,8 @@ Abrir / Cerrar puerta Otwórz / Zamknij drzwi Otevřít / Zavřít dveře - Ouvrir / Fermer la porte - Открыть / Закрыть двери + Ouvrir/Fermer la porte + Открыть/закрыть двери Ajtó nyitása / zárása Abrir / Fechar Porta Apri / Chiudi la porta @@ -187,6 +202,7 @@ 문 열기 / 닫기 打开/关上 门 打開/關上 門 + Kapıyı Aç/Kapat Lock Door @@ -199,10 +215,11 @@ Ajtó bezárása Zablokuj drzwi Zamknout dveře - ドアの鍵をしめる + ドアを施錠 문 잠그기 锁门 鎖門 + Kapıyı Kilitle Unlock Door @@ -215,10 +232,11 @@ Zár kinyitása Odblokuj drzwi Odemknout dveře - ドアの鍵をあける - 잠긴문 열기 + ドアを解錠 + 잠긴 문 열기 解锁门 解鎖門 + Kapının Kilidini Aç Locked Door @@ -231,10 +249,11 @@ Zárt ajtó Zablokowano drzwi Zamčené dveře - ドアの鍵をしめました + ドアを施錠しました 잠긴 문 门已上锁 門已上鎖 + Kilitli Kapı Unlocked Door @@ -247,10 +266,11 @@ Nyitott ajtó Odblokowano drzwi Odemčené dveře - ドアの鍵をあけました + ドアを解錠しました 열린 문 门未上锁 門未上鎖 + Kilidi Açık Kapı Join group @@ -267,6 +287,7 @@ 그룹 참여 加入小队 加入小隊 + Gruba katıl Leave Group @@ -283,6 +304,7 @@ 그룹 나가기 离开小队 離開小隊 + Gruptan ayrıl Become Leader @@ -299,6 +321,46 @@ 리더 되기 成为队长 成為隊長 + Lider ol + + + Rename Group + グループ名変更 + Renommer le groupe + Rinomina il gruppo + Переименовать группу + Gruppe umbenennen + Zmień nazwę grupy + 小队重命名 + 그룹 명칭 다시 짓기 + Renombrar grupo + Renomear Grupo + + + This group name is already in use. + このグループ名は既に使われています。 + Ce nom de groupe est déjà attribué. + C'è già un gruppo con questo nome. + Данное имя группы уже используется. + Dieser Gruppenname ist bereits in Verwendung. + Ta nazwa grupy jest już w użyciu. + 该小队名称已被使用 + 그 명칭은 이미 사용 중 입니다. + Este nombre de grupo ya está siendo usado. + Este nome de grupo já está em uso. + + + NEW GROUP NAME: + 新しいグループ名: + NOUVEAU NOM DE GROUPE : + NUOVO NOME GRUPPO: + НОВОЕ ИМЯ ГРУППЫ + NEUER GRUPPENNAME: + NOWA NAZWA GRUPY: + 新的小队名: + 새 그룹 명칭: + NUEVO NOMBRE DE GRUPO: + NOVO NOME DE GRUPO: DANCE! @@ -306,7 +368,7 @@ BAILAR! TAŃCZ! TANCUJ! - Danser ! + DANSER ! ТАНЦЕВАТЬ! TÁNC! DANCE! @@ -315,6 +377,7 @@ 춤추기! 跳舞 跳舞 + DANS! Stop Dancing @@ -328,9 +391,10 @@ Parar de dançar Smetti di ballare 踊るのを止める - 춤 멈추기 + 춤 그만 추기 停止跳舞 停止跳舞 + Dans Etmeyi Durdur << Back @@ -347,6 +411,7 @@ <<뒤로 <<返回 <<返回 + << Geri Put weapon on back @@ -363,6 +428,7 @@ 등에 무기 메기 将武器放到背后 將武器放到背後 + Silahı arkaya koy Tap Shoulder @@ -379,12 +445,13 @@ 어깨 치기 轻拍肩膀 輕拍肩膀 + Omuzuna Dokun You were tapped on the RIGHT shoulder Te tocaron el hombro DERECHO Dir wurde auf die rechte Schulter geklopft - On vous tape sur l'épaule droite + On vous tape sur l'épaule DROITE Zostałeś klepnięty w prawe ramię Megveregették a JOBB válladat. Někdo tě poklepal na PRAVÉ rameno @@ -395,12 +462,13 @@ 누군가 오른쪽 어깨를 쳤다 你的右肩膀被轻拍了一下 你的右肩膀被輕拍了一下 + Birisi Sağ Omuzuna Dokundu You were tapped on the LEFT shoulder. Te tocaron el hombro IZQUIERDO. Dir wurde auf die linke Schulter geklopft - On vous tape sur l'épaule gauche + On vous tape sur l'épaule GAUCHE Zostałeś klepnięty w lewe ramię Megveregették a BAL válladat. Někdo tě poklepal na LEVÉ rameno @@ -411,6 +479,7 @@ 누군가 왼쪽 어깨를 쳤다 你的左肩膀被轻拍了一下 你的左肩膀被輕拍了一下 + Birisi Sol Omuzuna Dokundu Cancel @@ -427,6 +496,7 @@ 취소 取消 取消 + Iptal Select @@ -443,6 +513,7 @@ 선택 选择 選擇 + Seç Go Away! @@ -457,8 +528,9 @@ Via di qui! 失せろ! 저리 가! - 走开! + 走开! 走開! + Git! Get Down! @@ -466,15 +538,16 @@ Al suelo! Padnij! K zemi! - A terre ! + À terre ! A földre! Ложись! Abaixe-se! A terra! 伏せろ! 엎드려! - 趴下! + 趴下! 趴下! + Yat! Get Out @@ -489,6 +562,8 @@ 나가 出去 出去 + Saia! + Dışarı Team Management @@ -505,6 +580,7 @@ 팀 설정 小队管理 小隊管理 + Takım Yönetimi Red @@ -521,6 +597,7 @@ 빨강 红色 紅色 + Kırmızı Green @@ -529,7 +606,7 @@ Vert Zielonych Zelený - Зеленый + Зелёный Verde Verde Zöld @@ -537,6 +614,7 @@ 초록 绿色 綠色 + Yeşil Blue @@ -553,6 +631,7 @@ 파랑 蓝色 藍色 + Mavi Yellow @@ -569,6 +648,7 @@ 노랑 黄色 黃色 + Sarı Assign Red @@ -581,10 +661,11 @@ Назначить в Красную группу Assigner à rouge Assegna al team rosso - レッドにする + レッドに割り当て 빨강에 등록 指派为红组 指派為紅組 + Kırmızıya Ata Assign Green @@ -597,10 +678,11 @@ Назначить в Зеленую группу Assigner à vert Assegna al team verde - グリーンにする + グリーンに割り当て 초록에 등록 指派为绿组 指派為綠組 + Yeşile Ata Assign Blue @@ -613,10 +695,11 @@ Назначить в Синюю группу Assigner à bleu Assegna al team blu - ブルーにする - 파랑이 등록 + ブルーに割り当て + 파랑에 등록 指派为蓝组 指派為藍組 + Maviye Ata Assign Yellow @@ -629,10 +712,11 @@ Назначить в Желтую группу Assigner à jaune Assegna al team giallo - イエローにする + イエローに割り当て 노랑에 등록 指派为黄组 指派為黃組 + Sarıya Ata Join Red @@ -649,6 +733,7 @@ 빨강에 참여 加入红组 加入紅組 + Kırmızıya Katıl Join Green @@ -665,6 +750,7 @@ 초록에 참여 加入绿组 加入綠組 + Yeşile Katıl Join Blue @@ -681,6 +767,7 @@ 파랑에 참여 加入蓝组 加入藍組 + Maviye Katıl Join Yellow @@ -697,12 +784,13 @@ 노랑에 참여 加入黄组 加入黃組 + Sarıya Katıl You joined Team %1 Du bist Gruppe %1 beigetreten Te has unido al equipo %1 - Vous avez rejoint l'équipe %1 + Vous avez rejoint l'équipe %1. Dołączyłeś do %1 Připojili jste se do %1 týmu Вы присоединились к группе %1 @@ -713,6 +801,7 @@ 당신은 %1팀에 참여했습니다 你已加入%1组 你已加入%1組 + Takıma katıldın %1 Leave Team @@ -729,12 +818,13 @@ 팀 나가기 离开小队 離開小隊 + Takımdan Ayrıl You left the Team Du hast die Gruppe verlassen Has dejado el equipo - Vous avez quitté l'équipe + Vous avez quitté l'équipe. Opuściłeś drużynę Opustili jste tým Вы покинули группу @@ -745,6 +835,7 @@ 팀을 나갔습니다 你已离开小队 你已離開小隊 + Takımdan Ayrıldın Pardon @@ -761,6 +852,7 @@ 허용 原谅 原諒 + Pardon Scroll @@ -777,6 +869,7 @@ 스크롤 滚动 滾動 + Kaydırma Modifier Key @@ -786,13 +879,14 @@ Tecla modificadora Клавиша-модификатор Tecla Modificadora - Tasto modifica + Tasto modificatore Módosító billentyű Modifikátor キーを割り当て 키 할당하기 编辑按键 編輯按鍵 + Modifiye Tuşu Not in Range @@ -800,15 +894,16 @@ Hors de portée Fuera de rango Слишком далеко - Fora do Alcançe + Fora do Alcance Hatótávolságon kívül Poza zasięgiem Mimo dosah - Fuori limite + Fuori portata 範囲内にありません 범위 내에 없습니다 不在范围内 不在範圍內 + Menzilde Değil Equipment @@ -825,6 +920,7 @@ 장비 装备 裝備 + Ekipmanlar Push @@ -841,6 +937,7 @@ 밀기 + Ittir Flip @@ -848,8 +945,15 @@ Перевернуть ひっくり返す - Gira + 翻动 + Capovolgi Przewróć + Virar + Tourner + Otočit + Voltear + Döndür + 뒤집기 Interact @@ -860,12 +964,13 @@ Interakcja Interactuar Cselekvés - Interagire + Interagisci Interagir インタラクト 상호작용 互动 互動 + Etkileşim Passengers @@ -882,6 +987,7 @@ 승객 乘客 乘客 + Yolcular Open @@ -898,6 +1004,7 @@ 열기 打开 打開 + Interaction System @@ -914,6 +1021,7 @@ 상호작용 시스템 互动系统 互動系統 + Etkileşim Sistemi Enable Team Management @@ -925,11 +1033,12 @@ Activer la gestion d'équipe Csapatkezelés engedélyezése Habilitar gestão de equipes - Abilità Management Squadra - チーム管理を使う + Abilita Gestione Squadra + チーム管理の有効化 팀 설정 활성화 启用小队管理 啟用小隊管理 + Takım Yönetimini Etkinleştir Should players be allowed to use the Team Management Menu? Default: Yes @@ -937,37 +1046,46 @@ ¿Deben tener permitido los jugadores el uso del menu de gestión de equipos? Por defecto: Si Sollen Spieler das Gruppenverwaltungsmenü verwenden dürfen? Standard: Ja Mohou hráči použít menu správy týmu? Výchozí: Ano - Разрешить ли игрокам использовать меню управления группами? По-умолчани: Да - Permettre aux joueurs d'utiliser la gestion de groupe? Défaut : oui + Разрешить ли игрокам использовать меню управления группами? По умолчанию: Да + Permet aux joueurs d'utiliser la gestion d'équipe. Valeur par défaut : activé. A játékosoknak engedélyezve legyen a csapatkezelő menü? Alapértelmezett: Igen Devem os jogadores ter permissão de usar o menu de gestão de equipes? Padrão: Sim - Possono i giocatori usare il Menù Managment Squadra? Default: Si - プレイヤーがチーム管理メニューを使えるようにしますか? 標準: 有効化 + I giocatori possono usare il Menù di Gestione Squadra? Predefinito: Si + プレイヤーがチーム管理メニューを使えるかどうかを設定します。 デフォルト: 有効化 플레이어들이 팀 설정하는 것을 허락합니까? 기본설정: 예 - 允许玩家使用小队管理选单? 预设: 是 + 允许玩家使用小队管理菜单? 预设:是 允許玩家使用小隊管理選單? 預設: 是 + Oyuncuların Takım Yönetimi Menüsünü kullanmalarına izin verilmeli mi? Varsayılan: Evet Disable negative rating Negative Bewertung deaktivieren 否定評価を無効化 - Disabilita valutazione negativa + Impedisci Valutazione Negativa 關閉負面評價 关闭负面评价 - 부정행위 가중치 사용안함 + 부정행위 가중치 사용 안함 Wyłącz negatywną ocenę - Отключить отрицательный рейтинг + Откл. отрицательный рейтинг + Desativar avaliação negativa + Désactiver la notation négative + Vypnout negativní hodnocení + Deshabilitar valoración 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. Sollen Spieler negative Bewertungen erhalten dürfen? Wenn diese Option aktiviert ist, erhalten Spieler nur positive Bewertungen, was Freundbeschuss durch KI verhindert, wenn befreundete Ausrüstung zerstört oder befreundete Einheiten von Spielern des selben Teams getötet werden. - 否定評価を受けますか?有効化した場合プレイヤーは肯定評価のみを受け、友軍の装備を壊したり殺害をしても AI からの攻撃を防ぎます。 - I giocatori dovrebbero ricevere delle valutazioni negative ? Quando è abilitato i giocatori ricevono esclusivamente valutazioni positive che prevengono il fuoco delle AI alleate quando distruggono equipaggiamenti o uccidono membri della squadra. + 否定評価を受けますか?有効化した場合プレイヤーは肯定評価のみを受け、友軍の装備を壊したり殺害をしてもAIからの攻撃を防ぎます。 + I giocatori possono ricevere valutazioni negative? Se abilitato i giocatori riceveranno esclusivamente valutazioni positive, impedendo l'ingaggio da parte di IA alleate quando distruggono equipaggiamenti o uccidono alleati/civili. 玩家是否會收到負面評價? 當本功能開啟時玩家只會接收到正面評價,所以當玩家做出擊殺友軍AI、毀壞友軍裝備或殺害小隊夥伴都不會收到負面評價 - 玩家是否会收到负面评价? 当本功能开启时玩家只会接收到正面评价,所以当玩家做出击杀友军AI、毁坏友军装备或杀害小队伙伴都不会收到负面评价。 - 플레이어의 부정행위 가중치를 계산합니까? 활성화된 플레이어는 높은 레이팅을 가질때, 아군의 장비나 병력을 사격해도 아군 AI의 사격을 받지 않습니다. + 玩家是否会收到负面评价? 当本功能开启时玩家只会接收到正面评价,所以当玩家做出击杀友军 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. - Должны ли игроки получать отрицательный рейтинг? Когда включено, игроки получают только положительный рейтинг, что предотвращает дружественный огонь от ИИ при уничтожении дружественного оборудования или убийстве членов команды. + Должны ли игроки получать отрицательный рейтинг?\nКогда включено, игроки получают только положительный рейтинг, что предотвращает дружественный огонь от ИИ при уничтожении дружественного оборудования или убийстве членов команды. + 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. + Définit si les joueurs peuvent recevoir une note négative. Si l'option est activée, les joueurs obtiennent des notes positives exclusivement.\nCela permet d'éviter que les unités IA ne fassent du tir ami lorsque des joueurs détruisent de l'équipement allié, ou tuent des membres de l'équipe. + Měli by hráči obdržet negativní hodnocení? Pokud ne, hráči obdrží pouze pozitivní hodnocení, což zabrání přátelské AI střílet na hráče pokud hráči ničí přátelské vybavení nebo zabíjejí vlastní tým. + ¿Deben los jugadores recibir una calificación negativa? Cuando los jugadores habilitados solo reciben calificaciones positivas, lo que evita el fuego amistoso de la IA al destruir equipamiento amigo o matar a los miembros del equipo. Team management allows color allocation for team members, taking team command and joining/leaving teams. @@ -975,11 +1093,11 @@ Die Gruppenverwaltung erlaubt die Zuweisung von Farben für Einheiten, die Kommandierung und das Beitreten/Verlassen einer Gruppe. Správa týmu se skládá z: přidělení barev pro členy týmu, převzetí velení, připojení/odpojení. La gestión del equipo permite la asignación de colores para los miembros del equipo, tomando el mando del equipo y uniendo/dejando equipos. - La gestion d'équipe permet l'allocation de couleur aux membres d'équipe, de prendre le commandement, de rejoindre ou quitter une équipe. + La gestion d'équipe permet d'allouer des couleurs aux membres des équipes, de prendre le commandement, et de rejoindre ou quitter une équipe. A csapatkezelés engedélyezi a tagok színének meghatározását, a vezetés átvételét, és csapatoknál be-és kilépést. O módulo de gestão de equipe é composto por: a atribuição de cores para os membros da equipe, comando das equipes, juntando-se / deixando equipes. Управление группами позволяет назначать цвета членам групп, брать командование, вступать в группы или покидать их. - Management Squadra permette l'assegnazione di colori per membri della squadra, prendere il comando ed entrare/uscire dalle squadre. + Gestione Squadra permette l'assegnazione di colori per membri della squadra, prendere il comando ed entrare/uscire dalle squadre. チーム管理はチーム メンバーへ色の割り当てや指揮権を取ったり、チームの出入りを許可します。 팀 설정은 팀 멤버에게 색을 부여하거나 팀에 참여 혹은 나가게 할 수 있게 합니다. 队伍管理系统允许将指定颜色分配到队伍成员上,接管队长职位或加入/离开队伍 @@ -999,13 +1117,14 @@ 켜기 开启 開啟 + Turn off Deaktivieren Wyłącz Apagar - Eteindre + Éteindre Spegni Vypnout Desligar @@ -1014,6 +1133,7 @@ 끄기 关闭 關閉 + Kapat Pass magazine @@ -1029,6 +1149,7 @@ 탄창 건네기 给予弹匣 給予彈匣 + Sarjörleri birleştir Primary magazine @@ -1039,11 +1160,12 @@ Zásobník do primární zbraně Caricatore Primario Cargador primario - Chargeur de l'arme principale + Chargeur d'arme principale プライマリ用弾倉 주무기 탄창 给予主武器弹匣 給予主武器彈匣 + Birincil Şarjörü Pistol magazine @@ -1059,6 +1181,7 @@ 부무기 탄창 给予手枪弹匣 給予手槍彈匣 + Tabanca Şarjörü %1 passed you a %2 magazine. @@ -1067,10 +1190,10 @@ %1 передал вам магазин %2. %1 passou a você um carregador %2. %1 ti podal zásobník %2. - %1 ti ha passato un caricatore %2 . + %1 ti ha passato un caricatore %2. %1 te pasó un cargador %2. %1 vous a passé un chargeur de %2. - %1 はあなたに %2 弾倉を渡した + %1 は あなたに弾倉 %2 を渡した。 %1에게서 %2탄창을 받았다 %1给你%2弹匣 %1給你%2彈匣 @@ -1082,10 +1205,10 @@ Показывать действие "передать магазин" Mostrar a interação "Passar carregador" Zobrazit "interakci "podat zásobník" - Mostra interazione "passa caricatore" + Mostra l'interazione "passa caricatore" Mostrar "Pasar cargador" en el menú de interacción Montrer l'interaction "Passer un chargeur" - "弾倉を渡す"をインタラクションに表示する + "弾倉を渡す"をインタラクションに表示 '탄창 건네기'를 상호작용에서 보여줌 显示"给予弹匣"互动动作 顯示"給予彈匣"互動動作 @@ -1096,21 +1219,110 @@ Вытащить тело 身体を引き出す Estrai il corpo - 시체 끌기 + 인원 꺼내기 拿出屍體 拿出尸体 Wyciągnij ciało + Retirar Corpo + Retirer le corps + Vytáhnout tělo + Sacar cuerpo + Vücudu dışarı çıkart Smash windshield Frontscheibe einschlagen - Dégager le pare-brise + Briser le pare-brise Vyrazit čelní sklo Выбить лобовое стекло Wyłam szybę Szélvédő széttörése フロントガラスを破る Sfonda il parabrezza + Quebrar pára-brisa + 踹開擋風玻璃 + Romper parabrisas + Ön camı parçala + 砸碎挡风玻璃 + 전면유리 부수기 + + + Attach %1 + Установить %1 + %1 を取り付け + Acoplar %1 + Fixer %1 + Przyczep %1 + Befestige %1 + Attacca %1 + 附加 %1 + %1 붙이기 + Fixar %1 + + + Detach %1 + Снять %1 + %1 を外す + Desacoplar %1 + Retirer %1 + Odczep %1 + Löse %1 + Stacca %1 + 拆卸 %1 + %1 떼내기 + Desfixar %1 + + + Enables attach/detach weapon attachment actions for current weapon. + Включает действия Установить/Снять для приспособлений текущего оружия. + インタラクションから使用中の武器に対してのアタッチメント取り外しを可能にします。 + Activar acciones de acoplar/desacoplar accesorios para el arma actual. + Cette option permet de fixer/retirer des accessoires d'arme à partir du menu d'interaction personnel. + Abilita le interazioni di attacco/stacco degli accessori sull'arma usata. + Włącza akcje przyczepienia/odczepienia dodatków dla obecnej broni + Aktiviert das Befestigen/Lösen von Waffenausätzen an der aktuellen Waffe. + 启用当前武器的附加/拆卸武器配件的动作。 + 현재 사용하고 있는 무기에서 부착물을 붙이거나 떼냅니다. + Ativa as ações de fixar/desfixar acessórios para a arma atual. + + + Allow group rename + グループ名変更を許可 + Permettre le renommage de groupe + Разрешить переименование группы + Erlaube das Umbenennen der Gruppe + Permetti la rinomina del gruppo + Zezwól na zmianę nazwy grupy + 允许小队重命名 + 그룹 이름 재설정 허가 + Permitir renombrar grupo + Permitir renomear grupo + + + Allows a group leader to rename their group if the name is not already taken. + グループ リーダーによるグループ名の変更を許可します。 + Cette option permet aux chefs de groupe de modifier le nom de leur groupe. + Разрешить лидеру группы её переименование, если имя не занято. + Erlaube Gruppenführer das Umbenennen Ihrer Gruppe, wenn der Name nicht bereits vergeben ist. + Permetti ad un capogruppo di rinominare il proprio gruppo se quel nome non è già assegnato. + Pozwala liderowi grupy na zmianę jej nazwy, jeżeli ta nazwa nie jest już w użyciu. + 允许队长在队名未被占用的情况下重命名。 + 그룹 리더가 그룹 이름을 재설정하는 것을 허가합니다. + Permite al lider de un grupo renombrar a su grupo si el nombre no está siendo actualmente usado. + Permite que o líder renomeie seu grupo se o nome não estiver sendo usado. + + + Warning: can cause some objects to collide with others. + Внимание: может вызвать отталкивание некоторых объектов друг от друга. + Attention : certains objets peuvent entrer en collision avec d'autres. + 警告: 一部のオブジェクトが干渉する可能性があります。 + Achtung: einige Objekte könnten mit anderen Kollidieren. + Attenzione: può causare collisioni tra oggetti. + Uwaga: niektóre obiekty mogą kolidować z innymi. + 警告:会导致一些物体与其他物体发生碰撞。 + 주의: 물체끼리 충돌하는 현상이 있을 수 있음. + Advertencia: puede provocar que algunos objetos choquen con otros. + Aviso: pode causar que alguns objetos colidam com outros. diff --git a/addons/inventory/ACE_Settings.hpp b/addons/inventory/ACE_Settings.hpp index 87f2b59550..8f907bfd91 100644 --- a/addons/inventory/ACE_Settings.hpp +++ b/addons/inventory/ACE_Settings.hpp @@ -1,10 +1,5 @@ class ACE_Settings { class GVAR(inventoryDisplaySize) { - value = 0; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(SettingName); - description = CSTRING(SettingDescription); - values[] = {"$str_medium", "$str_large", "$str_very_large"}; + movedToSQF = 1; }; -}; \ No newline at end of file +}; diff --git a/addons/inventory/CfgEventHandlers.hpp b/addons/inventory/CfgEventHandlers.hpp index 369f47e1dd..f95adcb029 100644 --- a/addons/inventory/CfgEventHandlers.hpp +++ b/addons/inventory/CfgEventHandlers.hpp @@ -1,24 +1,30 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_DisplayLoad_EventHandlers { class RscDisplayInventory { ADDON = QUOTE(_this call FUNC(inventoryDisplayLoad)); + GVAR(displayNameWeight) = QUOTE(_this call FUNC(displayNameWeight)); // separate to allow other mods to disable them individually + }; +}; + +class Extended_DisplayUnload_EventHandlers { + class RscDisplayInventory { + ADDON = QUOTE(GVAR(unit) = ACE_player); }; }; diff --git a/addons/inventory/README.md b/addons/inventory/README.md index 7d644143cf..7027e5cf52 100644 --- a/addons/inventory/README.md +++ b/addons/inventory/README.md @@ -2,11 +2,3 @@ ace_inventory ============= Adds options to increase the size of the inventory dialog. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/inventory/RscDisplayInventory.hpp b/addons/inventory/RscDisplayInventory.hpp index c3a1904678..91e68f5fb1 100644 --- a/addons/inventory/RscDisplayInventory.hpp +++ b/addons/inventory/RscDisplayInventory.hpp @@ -27,26 +27,26 @@ class RscCombo; #define W_MAKEITBIGGA(num) (num * (safeZoneH / 40)) #define H_MAKEITBIGGA(num) (num * (safeZoneH / 30)) -#define X_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)), 0)]), X_BIS(num), X_MAKEITBIGGA(num))]) -#define Y_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)), 0)]), Y_BIS(num), Y_MAKEITBIGGA(num))]) -#define W_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)), 0)]), W_BIS(num), W_MAKEITBIGGA(num))]) -#define H_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)), 0)]), H_BIS(num), H_MAKEITBIGGA(num))]) +#define X_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),X_BIS(num),X_MAKEITBIGGA(num))]) +#define Y_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),Y_BIS(num),Y_MAKEITBIGGA(num))]) +#define W_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),W_BIS(num),W_MAKEITBIGGA(num))]) +#define H_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),H_BIS(num),H_MAKEITBIGGA(num))]) class RscDisplayInventory { class controls { class CA_ContainerBackground: RscText { - //crate: GroundLoad adjust size + // Crate: GroundLoad adjust size x = X_PART(1); y = Y_PART(1); w = W_PART(12); - h = H_PART(22.5); //default 23 + h = H_PART(22.5); // default 23 }; class CA_PlayerBackground: RscText { - //center player's container: decrease height because of progressbar height decrease + // Center player's container: Decrease height because of progressbar height decrease x = X_PART(14.6); y = Y_PART(2); w = W_PART(24.4); - h = H_PART(21.5); //default 22 + h = H_PART(21.5); // default 22 }; class TitleBackground: RscText { x = X_PART(14.6); @@ -98,7 +98,7 @@ class RscDisplayInventory { }; class BackgroundSlotPrimaryFlashlight: BackgroundSlotPrimary { x = X_PART(30.6); - y = Y_PART(9.2); //not sure why different (double check release) + y = Y_PART(9.2); // not sure why different (double check release) w = W_PART(1.9); h = H_PART(2); }; @@ -283,11 +283,11 @@ class RscDisplayInventory { h = H_PART(1); }; class GroundLoad: RscProgress { - //crate: GroundLoad adjust size + // Crate: GroundLoad adjust size x = X_PART(1.5); y = Y_PART(22.5); w = W_PART(11); - h = H_PART(0.5); //Default 1 + h = H_PART(0.5); // Default 1 }; class SlotPrimary: GroundTab { x = X_PART(26.6); @@ -345,7 +345,7 @@ class RscDisplayInventory { }; class SlotSecondaryUnderBarrel: SlotPrimary { x = X_PART(29); - y = Y_PART(14.59); //Why is this different? (check release) + y = Y_PART(14.59); // Why is this different? (check release) w = W_PART(2.3); h = H_PART(2); }; @@ -518,11 +518,11 @@ class RscDisplayInventory { h = H_PART(0.5); }; class TotalLoad: GroundLoad { - //center: progressbar height decrease + // Center: progressbar height decrease x = X_PART(15.1); y = Y_PART(22.5); w = W_PART(23.4); - h = H_PART(0.5); //Default 1 + h = H_PART(0.5); // default 1 }; class ContainerMarker: GroundTab { x = X_PART(0); diff --git a/addons/inventory/XEH_PREP.hpp b/addons/inventory/XEH_PREP.hpp index 7c58268e23..824ebf63d7 100644 --- a/addons/inventory/XEH_PREP.hpp +++ b/addons/inventory/XEH_PREP.hpp @@ -1,10 +1,6 @@ - PREP(addCustomFilter); PREP(currentItemListBox); -PREP(forceItemListUpdate); -PREP(inventoryDisplayLoad); -PREP(onLBSelChanged); - +PREP(displayNameWeight); PREP(filterWeapons); PREP(filterMagazines); PREP(filterItems); @@ -14,3 +10,6 @@ PREP(filterVests); PREP(filterBackpacks); PREP(filterGrenades); PREP(filterMedical); +PREP(forceItemListUpdate); +PREP(inventoryDisplayLoad); +PREP(onLBSelChanged); diff --git a/addons/inventory/XEH_postInit.sqf b/addons/inventory/XEH_postInit.sqf index c5dc6c48f6..a670a7bfd5 100644 --- a/addons/inventory/XEH_postInit.sqf +++ b/addons/inventory/XEH_postInit.sqf @@ -2,40 +2,39 @@ if (!hasInterface) exitWith {}; -// cache config -// items in the inventory display can only be distinguished by their lb names and pictures -// this can cause collisions (mainly weapons with attachments), -// but if the item has the same name and picture it at least shouldn't change the filter anyway -// luckily we don't need private items, so dummy and parent classes are out of the picture +// If medical_treatment is loaded, get its items +if (["ace_medical_treatment"] call EFUNC(common,isModLoaded)) then { + private _medicalList = +(uiNamespace getVariable [QGVAR(medicalItemList), createHashMap]); -GVAR(ItemKeyNamespace) = [] call CBA_fnc_createNamespace; -private _allItems = uiNamespace getVariable [QGVAR(ItemKeyCache), []]; //See XEH_preStart.sqf + _medicalList merge [uiNamespace getVariable [QEGVAR(medical_treatment,treatmentItems), createHashMap], true]; -// isEqualType is hacking protection as we cannot trust that the cache hasn't been manipulated -{ - if (_x isEqualType [] && {_x isEqualTypeArray ["", configNull]}) then { - GVAR(ItemKeyNamespace) setVariable _x; - }; -} forEach ([[], _allItems] select (_allItems isEqualType [])); + GVAR(medicalItemList) = compileFinal _medicalList; +} else { + GVAR(medicalItemList) = uiNamespace getVariable [QGVAR(medicalItemList), compileFinal createHashMap]; +}; GVAR(customFilters) = []; GVAR(selectedFilterIndex) = -1; -// add custom filters +// Add custom filters +[LLSTRING(Grenades), QFUNC(filterGrenades)] call FUNC(addCustomFilter); +[LLSTRING(Backpacks), QFUNC(filterBackpacks)] call FUNC(addCustomFilter); +[LLSTRING(Uniforms), QFUNC(filterUniforms)] call FUNC(addCustomFilter); +[LLSTRING(Vests), QFUNC(filterVests)] call FUNC(addCustomFilter); +[LLSTRING(Headgear), QFUNC(filterHeadgear)] call FUNC(addCustomFilter); +[LLSTRING(Medical), QFUNC(filterMedical)] call FUNC(addCustomFilter); -// get list of grenades -GVAR(Grenades_ItemList) = uiNamespace getVariable [QGVAR(Grenades_ItemList), []]; -if (!(GVAR(Grenades_ItemList) isEqualType [])) then {GVAR(Grenades_ItemList) = []}; +// Used for displaying the correct name when opening a subordinate's inventory +GVAR(unit) = ACE_player; -[localize LSTRING(Grenades), QFUNC(filterGrenades)] call FUNC(addCustomFilter); +["CAManBase", "InventoryOpened", { + params ["_unit", "_container"]; -[localize LSTRING(Backpacks), QFUNC(filterBackpacks)] call FUNC(addCustomFilter); -[localize LSTRING(Uniforms), QFUNC(filterUniforms)] call FUNC(addCustomFilter); -[localize LSTRING(Vests), QFUNC(filterVests)] call FUNC(addCustomFilter); -[localize LSTRING(Headgear), QFUNC(filterHeadgear)] call FUNC(addCustomFilter); + // GVAR(unit) is ACE_player by default + if (_unit isEqualTo ACE_player) exitWith {}; -// get list of medical items -GVAR(Medical_ItemList) = uiNamespace getVariable [QGVAR(Medical_ItemList), []]; -if (!(GVAR(Medical_ItemList) isEqualType [])) then {GVAR(Medical_ItemList) = []}; - -[localize LSTRING(Medical), QFUNC(filterMedical)] call FUNC(addCustomFilter); + // If the player is a group leader and opens a subordinate's inventory or has a subordinate open the player's backpack, update name to correct unit + if (leader ACE_player == ACE_player && {(_unit in units ACE_player) || {(objectParent _container) isEqualTo ACE_player}}) then { + GVAR(unit) = _unit; + }; +}] call CBA_fnc_addClassEventHandler; diff --git a/addons/inventory/XEH_preInit.sqf b/addons/inventory/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/inventory/XEH_preInit.sqf +++ b/addons/inventory/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/inventory/XEH_preStart.sqf b/addons/inventory/XEH_preStart.sqf index ae4ce6500c..a9a634ab5a 100644 --- a/addons/inventory/XEH_preStart.sqf +++ b/addons/inventory/XEH_preStart.sqf @@ -2,56 +2,49 @@ #include "XEH_PREP.hpp" -//item cache, see XEH_postInit.sqf +// Cache config +// Items in the inventory display can all use lb data to get their classname (exception: backpacks, handled separately) private _allItems = ("getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgWeapons")); _allItems append ("getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgGlasses")); -_allItems append ("getNumber (_x >> 'scope') == 2" configClasses (configFile >> "CfgMagazines")); -_allItems append ("getNumber (_x >> 'scope') > 0 && {getNumber (_x >> 'isBackpack') == 1}" configClasses (configFile >> "CfgVehicles")); +_allItems append ("getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgMagazines")); -uiNamespace setVariable [QGVAR(ItemKeyCache), _allItems apply { +uiNamespace setVariable [QGVAR(itemKeyCache), compileFinal ((_allItems apply {configName _x}) createHashMapFromArray _allItems)]; + +// Backpacks in the inventory display can only be distinguished by their lb names and pictures, lb data returns "" +_allItems = "getNumber (_x >> 'scope') > 0 && {getNumber (_x >> 'isBackpack') == 1}" configClasses (configFile >> "CfgVehicles"); + +uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFromArray (_allItems apply { private _displayName = getText (_x >> "displayName"); private _picture = getText (_x >> "picture"); - // list box seems to delete the leading backslash - if (_picture select [0,1] == "\") then { + // List box seems to delete the leading backslash + if (_picture select [0, 1] == "\") then { _picture = _picture select [1]; }; - [format ["%1:%2", _displayName, _picture], _x]; -}]; + // Handle missing file extension, as inventory returns path with extension + if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then { + if (!fileExists (_picture + ".paa")) exitWith {}; + _picture = _picture + ".paa"; + }; -// generate list of grenades -private _grenades_ItemList = []; + // Listboxes store pictures as lowercase + [format ["%1:%2", _displayName, toLowerANSI _picture], _x] +})]; + +// Generate list of grenades +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; +private _grenadeList = createHashMap; { - _grenades_ItemList append getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); -} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); + _grenadeList insert [true, (getArray (_cfgThrow >> _x >> "magazines")) apply {_x call EFUNC(common,getConfigName)}, []]; +} forEach getArray (_cfgThrow >> "muzzles"); -// make list case insensitive -_grenades_ItemList = _grenades_ItemList apply {toLower _x}; +uiNamespace setVariable [QGVAR(grenadesItemList), compileFinal _grenadeList]; -// filter duplicates -_grenades_ItemList = _grenades_ItemList arrayIntersect _grenades_ItemList; +// Generate list of medical items +private _medicalList = QUOTE(getNumber (_x >> 'scope') > 0 && {getNumber (_x >> 'ItemInfo' >> 'type') in [ARR_2(TYPE_FIRST_AID_KIT,TYPE_MEDIKIT)]}) configClasses (configFile >> "CfgWeapons"); -uiNamespace setVariable [QGVAR(Grenades_ItemList), _grenades_ItemList]; +_medicalList = _medicalList apply {configName _x}; -// generate list of medical items -private _medical_ItemList = []; - -{ - _medical_ItemList append getArray (_x >> "items"); -} forEach ( - ("true" configClasses (configFile >> QEGVAR(Medical,Actions) >> "Basic")) + - ("true" configClasses (configFile >> QEGVAR(Medical,Actions) >> "Advanced")) -); - -// remove all numbers from list -_medical_ItemList = _medical_ItemList select {_x isEqualType ""}; - -// make list case insensitive -_medical_ItemList = _medical_ItemList apply {toLower _x}; - -// filter duplicates -_medical_ItemList = _medical_ItemList arrayIntersect _medical_ItemList; - -uiNamespace setVariable [QGVAR(Medical_ItemList), _medical_ItemList]; +uiNamespace setVariable [QGVAR(medicalItemList), compileFinal (_medicalList createHashMapFromArray [])]; diff --git a/addons/inventory/functions/fnc_addCustomFilter.sqf b/addons/inventory/functions/fnc_addCustomFilter.sqf index 6d7ab4796f..50820fa448 100644 --- a/addons/inventory/functions/fnc_addCustomFilter.sqf +++ b/addons/inventory/functions/fnc_addCustomFilter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Adds a custom filter list to the inventory display. @@ -12,11 +12,13 @@ * None * * Example: - * ["displayname", "filter"] call ACE_inventory_fnc_addCustomFilter + * ["displayname", "filter"] call ace_inventory_fnc_addCustomFilter * * Public: No */ -params [["_filterName", "ERROR: No Name", [""]], ["_fncName", "", [""]]]; +params [["_filterName", "", [""]], ["_fncName", "", [""]]]; + +if (_filterName == "") exitWith {}; GVAR(customFilters) pushBack [_filterName, _fncName]; diff --git a/addons/inventory/functions/fnc_currentItemListBox.sqf b/addons/inventory/functions/fnc_currentItemListBox.sqf index 3a0889865c..1546e8a509 100644 --- a/addons/inventory/functions/fnc_currentItemListBox.sqf +++ b/addons/inventory/functions/fnc_currentItemListBox.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns the current item list box of given inventory display. @@ -12,7 +12,7 @@ * Currently selected item list box * * Example: - * [DISPLAY] call ACE_inventory_fnc_currentItemListBox + * [DISPLAY] call ace_inventory_fnc_currentItemListBox * * Public: No */ @@ -27,7 +27,6 @@ scopeName "main"; if (ctrlShown _control) then { _control breakOut "main"; }; - false -} count [IDC_ITEMLIST_GROUND, IDC_ITEMLIST_SOLDIER, IDC_ITEMLIST_UNIFORM, IDC_ITEMLIST_VEST, IDC_ITEMLIST_BACKPACK]; +} forEach [IDC_ITEMLIST_GROUND, IDC_ITEMLIST_SOLDIER, IDC_ITEMLIST_UNIFORM, IDC_ITEMLIST_VEST, IDC_ITEMLIST_BACKPACK]; --1 +controlNull diff --git a/addons/inventory/functions/fnc_displayNameWeight.sqf b/addons/inventory/functions/fnc_displayNameWeight.sqf new file mode 100644 index 0000000000..c480593d85 --- /dev/null +++ b/addons/inventory/functions/fnc_displayNameWeight.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: commy2 + * Executed every time an inventory display is opened. + * + * Arguments: + * 0: Inventory display + * + * Return Value: + * None + * + * Example: + * [DISPLAY] call ace_inventory_fnc_displayNameWeight + * + * Public: No + */ + +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 [_format, + [GVAR(unit), false, true] call EFUNC(common,getName), + LELSTRING(common,Weight), + GVAR(unit) call EFUNC(common,getWeight), + [GVAR(unit), true] call EFUNC(common,getWeight) + ]; +}; + +_display displayAddEventHandler ["MouseMoving", _fnc_update]; +_display displayAddEventHandler ["MouseHolding", _fnc_update]; + +_display call _fnc_update; diff --git a/addons/inventory/functions/fnc_filterBackpacks.sqf b/addons/inventory/functions/fnc_filterBackpacks.sqf index 66f33ec105..db1edd9756 100644 --- a/addons/inventory/functions/fnc_filterBackpacks.sqf +++ b/addons/inventory/functions/fnc_filterBackpacks.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Filter condition for the Backpacks filter list @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterBackpacks + * [CONFIG] call ace_inventory_fnc_filterBackpacks * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterGrenades.sqf b/addons/inventory/functions/fnc_filterGrenades.sqf index 777f8c01cb..7e871699b8 100644 --- a/addons/inventory/functions/fnc_filterGrenades.sqf +++ b/addons/inventory/functions/fnc_filterGrenades.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Filter condition for the Grenades filter list @@ -10,11 +10,11 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterGrenades + * [CONFIG] call ace_inventory_fnc_filterGrenades * * Public: No */ params ["_config"]; -toLower configName _config in GVAR(Grenades_ItemList) +(configName _config) in (uiNamespace getVariable QGVAR(grenadesItemList)) diff --git a/addons/inventory/functions/fnc_filterHeadgear.sqf b/addons/inventory/functions/fnc_filterHeadgear.sqf index e75898849e..010c33040f 100644 --- a/addons/inventory/functions/fnc_filterHeadgear.sqf +++ b/addons/inventory/functions/fnc_filterHeadgear.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Filter condition for the Headgear filter list @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterHeadgear + * [CONFIG] call ace_inventory_fnc_filterHeadgear * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterItems.sqf b/addons/inventory/functions/fnc_filterItems.sqf index 78343127af..a3c2567233 100644 --- a/addons/inventory/functions/fnc_filterItems.sqf +++ b/addons/inventory/functions/fnc_filterItems.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove uniforms, vests and backpacks from Items filter. @@ -10,11 +10,14 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterItems + * [CONFIG] call ace_inventory_fnc_filterItems * * Public: No */ params ["_config"]; -!(getNumber (_config >> "ItemInfo" >> "type") in [TYPE_UNIFORM, TYPE_VESTS, TYPE_HEADGEAR]) && {!(_this call FUNC(filterBackpacks))} +!(_this call FUNC(filterMedical)) && +{!(_this call FUNC(filterBackpacks))} && +{!(_this call FUNC(filterHeadgear))} && +{!(getNumber (_config >> "ItemInfo" >> "type") in [TYPE_UNIFORM, TYPE_VEST])} diff --git a/addons/inventory/functions/fnc_filterMagazines.sqf b/addons/inventory/functions/fnc_filterMagazines.sqf index 0e23872d73..e6d9237c21 100644 --- a/addons/inventory/functions/fnc_filterMagazines.sqf +++ b/addons/inventory/functions/fnc_filterMagazines.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove backpacks and grenades from Magazines filter. @@ -10,9 +10,9 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterMagazines + * [CONFIG] call ace_inventory_fnc_filterMagazines * * Public: No */ -!(_this call FUNC(filterBackpacks)) && {!(_this call FUNC(filterGrenades))} +!(_this call FUNC(filterGrenades)) && {!(_this call FUNC(filterBackpacks))} diff --git a/addons/inventory/functions/fnc_filterMedical.sqf b/addons/inventory/functions/fnc_filterMedical.sqf index 6e04ddc3de..73cfdbdffb 100644 --- a/addons/inventory/functions/fnc_filterMedical.sqf +++ b/addons/inventory/functions/fnc_filterMedical.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Filter condition for the Medical filter list @@ -10,11 +10,11 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterMedical + * [CONFIG] call ace_inventory_fnc_filterMedical * * Public: No */ params ["_config"]; -toLower configName _config in GVAR(Medical_ItemList) +(configName _config) in GVAR(medicalItemList) diff --git a/addons/inventory/functions/fnc_filterUniforms.sqf b/addons/inventory/functions/fnc_filterUniforms.sqf index 39529121a5..b627475038 100644 --- a/addons/inventory/functions/fnc_filterUniforms.sqf +++ b/addons/inventory/functions/fnc_filterUniforms.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Filter condition for the Uniforms filter list @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterUniforms + * [CONFIG] call ace_inventory_fnc_filterUniforms * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterVests.sqf b/addons/inventory/functions/fnc_filterVests.sqf index 99115ac84f..2bb2af9ef4 100644 --- a/addons/inventory/functions/fnc_filterVests.sqf +++ b/addons/inventory/functions/fnc_filterVests.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Filter condition for the Vests filter list @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterVests + * [CONFIG] call ace_inventory_fnc_filterVests * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterWeapons.sqf b/addons/inventory/functions/fnc_filterWeapons.sqf index 60065069bb..db4d402099 100644 --- a/addons/inventory/functions/fnc_filterWeapons.sqf +++ b/addons/inventory/functions/fnc_filterWeapons.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Remove backpacks from Weapons filter. @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterWeapons + * [CONFIG] call ace_inventory_fnc_filterWeapons * * Public: No */ diff --git a/addons/inventory/functions/fnc_forceItemListUpdate.sqf b/addons/inventory/functions/fnc_forceItemListUpdate.sqf index e162aeee6c..fb8f09b5c8 100644 --- a/addons/inventory/functions/fnc_forceItemListUpdate.sqf +++ b/addons/inventory/functions/fnc_forceItemListUpdate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Updates item list and removes every entry that does not fit in the currently selected filter list. @@ -10,31 +10,38 @@ * None * * Example: - * [DISPLAY] call ACE_inventory_fnc_forceitemListUpdate + * [DISPLAY] call ace_inventory_fnc_forceItemListUpdate * * Public: No */ disableSerialization; + params ["_display"]; -private _index = GVAR(selectedFilterIndex); +// Get the appropriate filter +private _filterFunction = missionNamespace getVariable [(_display displayCtrl IDC_FILTERLISTS) lbData GVAR(selectedFilterIndex), ""]; + +if !(_filterFunction isEqualType {}) exitWith {}; + private _itemList = _display call FUNC(currentItemListBox); -private _filterFunction = missionNamespace getVariable ((_display displayCtrl IDC_FILTERLISTS) lbData _index); +private _itemKeyCache = uiNamespace getVariable QGVAR(itemKeyCache); +private _backpackKeyCache = uiNamespace getVariable QGVAR(backpackKeyCache); +private _config = configNull; -if (_filterFunction isEqualType {}) then { - private _i = 0; +for "_i" from (lbSize _itemList) to 0 step -1 do { + // All items have their classnames in lbData, except backpacks + _className = _itemList lbData _i; - while {_i < lbSize _itemList} do { - private _config = GVAR(ItemKeyNamespace) getVariable format ["%1:%2", _itemList lbText _i, _itemList lbPicture _i]; + _config = if (_className != "") then { + _itemKeyCache get _className + } else { + // Backpack are gotten with their display name and inventory icon + _backpackKeyCache get format ["%1:%2", _itemList lbText _i, _itemList lbPicture _i] + }; - if (!isNil "_config" && {!(_config call _filterFunction)}) then { - _itemList lbDelete _i; - - // in case the filter function returns nil. Otherwise could lock up the game. - _i = _i - 1; - }; - - _i = _i + 1; + // If item is valid and doesn't match the current filter, remove it + if (!isNil "_config" && {!(_config call _filterFunction)}) then { + _itemList lbDelete _i; }; }; diff --git a/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf b/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf index 8657d212cd..3e70bbd8d9 100644 --- a/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf +++ b/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Executed every time an inventory display is opened. @@ -10,71 +10,60 @@ * None * * Example: - * [DISPLAY] call ACE_inventory_fnc_inventoryDisplayLoad + * [DISPLAY] call ace_inventory_fnc_inventoryDisplayLoad * * Public: No */ disableSerialization; + params ["_display"]; private _filter = _display displayCtrl IDC_FILTERLISTS; -// engine defined behaviour is the following: +// Engine defined behaviour is the following: // lb value, data and text don't matter, only the index. -// the first three indecies are hard coded: 0 - weapons , 1 - magazines, 2 - items -// all of them show backpacks, because BI -// all other indecies show everything, so all we have to do is delete stuff we dont like -_filter ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChanged)}]; +// The first three indecies are hard coded: 0 - weapons , 1 - magazines, 2 - items +// All of them show backpacks, because BI +// All other indecies show everything, so all we have to do is delete stuff we don't like +_filter ctrlAddEventHandler ["LBSelChanged", LINKFUNC(onLBSelChanged)]; -// have to add these a frame later, because this event happens before the engine adds the default filters +// Have to add these a frame later, because this event happens before the engine adds the default filters [{ disableSerialization; + params ["_filter"]; - // remove "All", so we can push it to the back later. - // to keep localization we can keep the lbText (displayed name). + // Remove "All", so we can push it to the back later + // To keep localization we keep the lbText (displayed name) private _index = lbSize _filter - 1; private _nameAll = _filter lbText _index; _filter lbDelete _index; - // add additional filter functions to the default filters. These remove backpacks etc. + // Add additional filter functions to the default filters. These remove backpacks etc. _filter lbSetData [0, QFUNC(filterWeapons)]; _filter lbSetData [1, QFUNC(filterMagazines)]; _filter lbSetData [2, QFUNC(filterItems)]; - // add our custom filters + // Add our custom filters { _x params ["_name", "_fncName"]; _index = _filter lbAdd _name; _filter lbSetData [_index, _fncName]; + } forEach GVAR(customFilters); - false - } count GVAR(customFilters); - - // readd "All" filter to last position and select it + // Readd "All" filter to last position and select it _index = _filter lbAdd _nameAll; _filter lbSetCurSel _index; -}, [_filter]] call CBA_fnc_execNextFrame; +}, _filter] call CBA_fnc_execNextFrame; -// monitor changes that can happen and force our update +// Monitor changes that can happen and force our update private _dummyControl = _display ctrlCreate ["RscMapControl", -1]; -_dummyControl ctrlSetPosition [0,0,0,0]; +_dummyControl ctrlSetPosition [0, 0, 0, 0]; _dummyControl ctrlCommit 0; _dummyControl ctrlAddEventHandler ["Draw", { - disableSerialization; - params ["_dummyControl"]; - - private _display = ctrlParent _dummyControl; - - private _itemList = _display call FUNC(currentItemListBox); - - // monitoring is done by setting a lb value. These are unused here and are reset every time the list box updates. - if (_itemList lbValue 0 != DUMMY_VALUE) then { - _display call FUNC(forceItemListUpdate); - _itemList lbSetValue [0, DUMMY_VALUE]; - }; + (ctrlParent (_this select 0)) call FUNC(forceItemListUpdate); }]; diff --git a/addons/inventory/functions/fnc_onLBSelChanged.sqf b/addons/inventory/functions/fnc_onLBSelChanged.sqf index 7f20e48fdf..a2316dc4b6 100644 --- a/addons/inventory/functions/fnc_onLBSelChanged.sqf +++ b/addons/inventory/functions/fnc_onLBSelChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Executed when the filter list box is changed. @@ -12,19 +12,16 @@ * None * * Example: - * [CONTROL, 5] call ACE_inventory_fnc_onLBSelChanged + * [CONTROL, 5] call ace_inventory_fnc_onLBSelChanged * * Public: No */ disableSerialization; + params ["_filter", "_index"]; GVAR(selectedFilterIndex) = _index; -[{ - disableSerialization; - params ["_display"]; - - [_display] call FUNC(forceItemListUpdate); -}, [ctrlParent _filter]] call CBA_fnc_execNextFrame; +// Force update +[LINKFUNC(forceItemListUpdate), ctrlParent _filter] call CBA_fnc_execNextFrame; diff --git a/addons/inventory/functions/script_component.hpp b/addons/inventory/functions/script_component.hpp deleted file mode 100644 index 07c5e38d2d..0000000000 --- a/addons/inventory/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\inventory\script_component.hpp" \ No newline at end of file diff --git a/addons/inventory/initSettings.inc.sqf b/addons/inventory/initSettings.inc.sqf new file mode 100644 index 0000000000..be7ff37b99 --- /dev/null +++ b/addons/inventory/initSettings.inc.sqf @@ -0,0 +1,9 @@ +private _category = [LELSTRING(common,categoryUncategorized), localize "str_a3_gear1"]; + +[ + QGVAR(inventoryDisplaySize), "LIST", + [LSTRING(SettingName), LSTRING(SettingDescription)], + _category, + [[0, 1, 2], ["str_medium", "str_large", "str_very_large"], 0], + 0 +] call CBA_fnc_addSetting; diff --git a/addons/inventory/stringtable.xml b/addons/inventory/stringtable.xml index ca09417810..a020e96048 100644 --- a/addons/inventory/stringtable.xml +++ b/addons/inventory/stringtable.xml @@ -8,7 +8,7 @@ Изменить размер окна инвентаря Zvětšit zobrazení inventáře Powiększ UI ekwipunku - Agrandir la taille d'affichage de l'inventaire + Agrandir l'affichage de l'inventaire Legyen a felszerelés menüje nagyobb Ingrandisci il menù inventario Aumentar o Tamanho da Tela do Inventário @@ -16,6 +16,7 @@ 소지품 화면을 더 크게 합니다 使物品显示清单更大 使物品顯示清單更大 + Envanter Görüntüsünü Daha Büyük Yap Normally inventory display is scaled by UI size. This allows scaling the Inventory UI size up, but doesn't increase font size allowing more rows displayed. @@ -24,14 +25,15 @@ Обычно, размер окна инвентаря зависит от размеров пользовательского интерфейса. Эта настройка позволяет увеличить размер окна инвентаря, не увеличивая размеры шрифтов, так что отображется большее количество строк. Normálně se velikost invetáře škáluje s velikostí UI. Toto nastavení dovoluje škálování velikost inventáře ale nežvětšuje velikost fontu. To dovoluje zobrazení více řad v inventáři. Ekwipunek skalowany jest poprzez rozmiar UI. Ta opcja pozwala powiększyć rozmiar UI ekwipunku, lecz nie zwiększa rozmiaru fontu pozwalając na wyświetlanie większej ilości wierszy. - L'inventaire est normalement affiché en fonction de la taille de l'UI. Cette option permet d'agrandir l'affichage de l'inventaire, mais n'a aucun effet sur la taille des polices permettant d'afficher plus de lignes. + En principe, l'affichage de l'inventaire est dimensionné par la taille de l'IU. Cette option permet d'agrandir l'IU de l'inventaire, mais sans augmenter la taille des polices, ce qui permet d'afficher plus de lignes. Alaphelyzetben a kezelőfelület mérete skálázza a felszerelési menüt. Ez az opció engedélyezi a menü felskálázását, de megtartja a betűméreteket, így növelve a láthatóságot. Normalmente il menù inventario è scalato in base alle dimensioni dell'interfaccia. Questa opzione permette di ingrandirlo ulteriormente ma senza aumentare la dimensione del testo. Normalmente o tamanho da tela do inventário é ditada pelo tamanho da UI. Isso permite aumentar o tamanho da tela de inventário, mas não aumenta o tamanho da fonte, permitindo que mais linhas sejam visualizadas. 通常、インベントリは UI の大きさにより調整して表示されます。これはインベントリ UI を大きくできますが、文字は大きくできません。 - 보통 소지품 화면은 사용자 인터페이스 크기에 비례합니다. 이 항목은 소지품의 사용자 인터페이스를 확대를 가능케하면서 글씨는 그대로 냅두게 해줍니다. - 一般来说,物品清单尺寸是由使用者介面来决定的。此选项能让你的物品显示清单更大但不会增加字体大小,此举可增加更多能被显示的描述行数! + 보통 소지품 화면은 사용자 인터페이스 크기에 비례합니다. 이 항목은 소지품의 사용자 인터페이스를 확대를 가능케 하면서 글씨는 그대로 놔두게 해줍니다. + 一般来说,物品清单尺寸是由使用者界面来决定的。此选项能让你的物品显示清单更大但不会增加字体大小,此举可增加更多能被显示的描述行数! 一般來說,物品清單尺寸是由使用者介面來決定的。此選項能讓你的物品顯示清單更大但不會增加字體大小,此舉可增加更多能被顯示的描述行數! + Normalde envanter görüntüleme, kullanıcı arayüzü boyutuna göre ölçeklenir. Bu, Envanter kullanıcı arayüzü boyutunu büyütmeye izin verir, ancak daha fazla satır görüntülenmesine izin vermek için yazı tipi boyutunu büyütmez. Backpacks @@ -47,6 +49,7 @@ 가방 背包 背包 + Çantalar Headgear @@ -62,6 +65,7 @@ 헬멧 头盔 頭盔 + Kasklar Glasses @@ -77,6 +81,7 @@ 안경 眼镜 眼鏡 + Gözlükler Uniforms @@ -92,6 +97,7 @@ 복장 服装 服裝 + Üniformalar Vests @@ -107,6 +113,7 @@ 조끼 背心 背心 + Yelekler Grenades @@ -122,6 +129,7 @@ 수류탄 手榴弹 手榴彈 + Bombalar Medical @@ -133,10 +141,11 @@ Médical Médico Медицина - 医療 + 医療品 의료 医疗 醫療 + Sağlık diff --git a/addons/irlight/$PBOPREFIX$ b/addons/irlight/$PBOPREFIX$ new file mode 100644 index 0000000000..5bb6f98681 --- /dev/null +++ b/addons/irlight/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\irlight diff --git a/addons/irlight/CfgEventHandlers.hpp b/addons/irlight/CfgEventHandlers.hpp new file mode 100644 index 0000000000..66a525846a --- /dev/null +++ b/addons/irlight/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/irlight/CfgJointRails.hpp b/addons/irlight/CfgJointRails.hpp new file mode 100644 index 0000000000..f9b3081c42 --- /dev/null +++ b/addons/irlight/CfgJointRails.hpp @@ -0,0 +1,82 @@ +class SlotInfo; +class PointerSlot: SlotInfo { + compatibleItems[] += { + "ACE_DBAL_A3_Red", + "ACE_DBAL_A3_Red_IP", + "ACE_DBAL_A3_Red_II", + "ACE_DBAL_A3_Red_VP", + "ACE_DBAL_A3_Red_LR", + "ACE_DBAL_A3_Red_LR_IP", + "ACE_DBAL_A3_Red_LR_II", + "ACE_DBAL_A3_Red_LR_VP", + "ACE_DBAL_A3_Green", + "ACE_DBAL_A3_Green_IP", + "ACE_DBAL_A3_Green_II", + "ACE_DBAL_A3_Green_VP", + "ACE_DBAL_A3_Green_LR", + "ACE_DBAL_A3_Green_LR_IP", + "ACE_DBAL_A3_Green_LR_II", + "ACE_DBAL_A3_Green_LR_VP", + "ACE_SPIR", + "ACE_SPIR_Medium", + "ACE_SPIR_Narrow", + "ACE_SPIR_LR", + "ACE_SPIR_LR_Medium", + "ACE_SPIR_LR_Narrow" + }; +}; + +class PointerSlot_Rail: PointerSlot { + class compatibleItems { + ACE_DBAL_A3_Red = 1; + ACE_DBAL_A3_Red_IP = 1; + ACE_DBAL_A3_Red_II = 1; + ACE_DBAL_A3_Red_VP = 1; + ACE_DBAL_A3_Red_LR = 1; + ACE_DBAL_A3_Red_LR_IP = 1; + ACE_DBAL_A3_Red_LR_II = 1; + ACE_DBAL_A3_Red_LR_VP = 1; + ACE_DBAL_A3_Green = 1; + ACE_DBAL_A3_Green_IP = 1; + ACE_DBAL_A3_Green_II = 1; + ACE_DBAL_A3_Green_VP = 1; + ACE_DBAL_A3_Green_LR = 1; + ACE_DBAL_A3_Green_LR_IP = 1; + ACE_DBAL_A3_Green_LR_II = 1; + ACE_DBAL_A3_Green_LR_VP = 1; + ACE_SPIR = 1; + ACE_SPIR_Medium = 1; + ACE_SPIR_Narrow = 1; + ACE_SPIR_LR = 1; + ACE_SPIR_LR_Medium = 1; + ACE_SPIR_LR_Narrow = 1; + }; +}; + +class asdg_SlotInfo; +class asdg_FrontSideRail: asdg_SlotInfo { + class compatibleItems { + ACE_DBAL_A3_Red = 1; + ACE_DBAL_A3_Red_IP = 1; + ACE_DBAL_A3_Red_II = 1; + ACE_DBAL_A3_Red_VP = 1; + ACE_DBAL_A3_Red_LR = 1; + ACE_DBAL_A3_Red_LR_IP = 1; + ACE_DBAL_A3_Red_LR_II = 1; + ACE_DBAL_A3_Red_LR_VP = 1; + ACE_DBAL_A3_Green = 1; + ACE_DBAL_A3_Green_IP = 1; + ACE_DBAL_A3_Green_II = 1; + ACE_DBAL_A3_Green_VP = 1; + ACE_DBAL_A3_Green_LR = 1; + ACE_DBAL_A3_Green_LR_IP = 1; + ACE_DBAL_A3_Green_LR_II = 1; + ACE_DBAL_A3_Green_LR_VP = 1; + ACE_SPIR = 1; + ACE_SPIR_Medium = 1; + ACE_SPIR_Narrow = 1; + ACE_SPIR_LR = 1; + ACE_SPIR_LR_Medium = 1; + ACE_SPIR_LR_Narrow = 1; + }; +}; diff --git a/addons/irlight/CfgWeapons.hpp b/addons/irlight/CfgWeapons.hpp new file mode 100644 index 0000000000..6d28c937e4 --- /dev/null +++ b/addons/irlight/CfgWeapons.hpp @@ -0,0 +1,378 @@ +// Only a dependency when building +#include "\z\ace\addons\laserpointer\script_macros_config.hpp" + +// Attenuation and Flashlight seem to not work with inheritance +#define DBAL_A3_FLASHLIGHT \ + class Flashlight { \ + color[] = {1, 1, 1}; \ + ambient[] = {1, 1, 1}; \ + size = 1; \ + innerAngle = 10; \ + outerAngle = 12; \ + position = "laser pos"; \ + direction = "laser dir"; \ + useFlare = 1; \ + flareSize = 1.4; \ + flareMaxDistance = 200; \ + coneFadeCoef = 6; \ + intensity = 100; \ + irLight = 1; \ + volumeShape = "a3\data_f\VolumeLightFlashlight.p3d"; \ + scale[] = {0.25, 0.25, 1}; \ + class Attenuation { \ + constant = 1; \ + linear = 0; \ + quadratic = 0.008; \ + start = 1; \ + hardLimitStart = 220; \ + hardLimitEnd = 250; \ + }; \ + } +#define DBAL_A3_FLASHLIGHT_LR \ + class Flashlight { \ + color[] = {1, 1, 1}; \ + ambient[] = {1, 1, 1}; \ + size = 1; \ + innerAngle = 10; \ + outerAngle = 12; \ + position = "laser pos"; \ + direction = "laser dir"; \ + useFlare = 1; \ + flareSize = 1.4; \ + flareMaxDistance = 200; \ + coneFadeCoef = 6; \ + intensity = 200; \ + irLight = 1; \ + volumeShape = "a3\data_f\VolumeLightFlashlight.p3d"; \ + scale[] = {0.25, 0.25, 1}; \ + class Attenuation { \ + constant = 1; \ + linear = 0; \ + quadratic = 0.001; \ + start = 1; \ + hardLimitStart = 570; \ + hardLimitEnd = 600; \ + }; \ + } +#define SPIR_FLASHLIGHT(hardLimitStart,hardLimitEnd) \ + color[] = {1, 1, 1}; \ + ambient[] = {1, 1, 1}; \ + size = 1; \ + position = "flash dir"; \ + direction = "flash"; \ + useFlare = 1; \ + flareSize = 1.4; \ + flareMaxDistance = 100; \ + irLight = 1; \ + volumeShape = "a3\data_f\VolumeLightFlashlight.p3d"; \ + class Attenuation { \ + constant = 1; \ + linear = 0; \ + quadratic = 0.02; \ + start = 1; \ + hardLimitStart = hardLimitStart; \ + hardLimitEnd = hardLimitEnd; \ + } +#define SPIR_FLASHLIGHT_LR(hardLimitStart,hardLimitEnd) \ + color[] = {1, 1, 1}; \ + ambient[] = {1, 1, 1}; \ + size = 1; \ + position = "flash dir"; \ + direction = "flash"; \ + useFlare = 1; \ + flareSize = 1.4; \ + flareMaxDistance = 100; \ + irLight = 1; \ + volumeShape = "a3\data_f\VolumeLightFlashlight.p3d"; \ + class Attenuation { \ + constant = 1; \ + linear = 0; \ + quadratic = 0.002; \ + start = 1; \ + hardLimitStart = hardLimitStart; \ + hardLimitEnd = hardLimitEnd; \ + } +#define POINTER_IR \ + class Pointer { \ + irLaserPos = "laser pos"; \ + irLaserEnd = "laser dir"; \ + irDistance = 5; \ + } + + +class CfgWeapons { + class acc_pointer_IR; + class acc_flashlight; + class InventoryFlashLightItem_Base_F; + + // DBAL-A3 (red pointer) + // IR Pointer + Illuminator + class ACE_DBAL_A3_Red: acc_pointer_IR { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(DBAL_A3_Red); + descriptionUse = CSTRING(DBAL_A3_DescriptionUse); + descriptionShort = CSTRING(DBAL_A3_DescriptionShort); + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_IP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_VP"; + MRT_SwitchItemHintText = CSTRING(Mode_IRDual); + baseWeapon = "ACE_DBAL_A3_Red"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + DBAL_A3_FLASHLIGHT; + POINTER_IR; + }; + }; + + // IR Pointer only + class ACE_DBAL_A3_Red_IP: ACE_DBAL_A3_Red { + scope = 1; + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_II"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red"; + MRT_SwitchItemHintText = CSTRING(Mode_IRPointer); + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight {}; + POINTER_IR; + }; + }; + + // Illuminator only + class ACE_DBAL_A3_Red_II: ACE_DBAL_A3_Red { + scope = 1; + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_VP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_IP"; + MRT_SwitchItemHintText = CSTRING(Mode_IRIlluminator); + + class ItemInfo: InventoryFlashLightItem_Base_F { + DBAL_A3_FLASHLIGHT; + }; + }; + + // Visible Pointer only + class ACE_DBAL_A3_Red_VP: ACE_DBAL_A3_Red { + scope = 1; + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_II"; + MRT_SwitchItemHintText = CSTRING(Mode_VisiblePointer); + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight {}; + POINTER_VISIBLE_RED; + }; + }; + + // DBAL-A3 (red pointer, long range) + class ACE_DBAL_A3_Red_LR: ACE_DBAL_A3_Red { + scope = 1; + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_LR_IP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_LR_VP"; + baseWeapon = "ACE_DBAL_A3_Red_LR"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + DBAL_A3_FLASHLIGHT_LR; + POINTER_IR; + }; + }; + + class ACE_DBAL_A3_Red_LR_IP: ACE_DBAL_A3_Red_IP { + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_LR_II"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_LR"; + baseWeapon = "ACE_DBAL_A3_Red_LR"; + }; + + class ACE_DBAL_A3_Red_LR_II: ACE_DBAL_A3_Red_II { + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_LR_VP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_LR_IP"; + baseWeapon = "ACE_DBAL_A3_Red_LR"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + DBAL_A3_FLASHLIGHT_LR; + }; + }; + + class ACE_DBAL_A3_Red_LR_VP: ACE_DBAL_A3_Red_VP { + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Red_LR"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Red_LR_II"; + baseWeapon = "ACE_DBAL_A3_Red_LR"; + }; + + // DBAL-A3 (green pointer) + class ACE_DBAL_A3_Green: ACE_DBAL_A3_Red { + scope = 2; + displayName = CSTRING(DBAL_A3_Green); + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_IP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_VP"; + baseWeapon = "ACE_DBAL_A3_Green"; + }; + + class ACE_DBAL_A3_Green_IP: ACE_DBAL_A3_Red_IP { + displayName = CSTRING(DBAL_A3_Green); + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_II"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green"; + baseWeapon = "ACE_DBAL_A3_Green"; + }; + + class ACE_DBAL_A3_Green_II: ACE_DBAL_A3_Red_II { + displayName = CSTRING(DBAL_A3_Green); + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_VP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_IP"; + baseWeapon = "ACE_DBAL_A3_Green"; + }; + + class ACE_DBAL_A3_Green_VP: ACE_DBAL_A3_Red_VP { + displayName = CSTRING(DBAL_A3_Green); + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_II"; + baseWeapon = "ACE_DBAL_A3_Green"; + class ItemInfo: ItemInfo { + POINTER_VISIBLE_GREEN; + }; + }; + + // DBAL-A3 (green pointer, long range) + class ACE_DBAL_A3_Green_LR: ACE_DBAL_A3_Green { + scope = 1; + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_LR_IP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_LR_VP"; + baseWeapon = "ACE_DBAL_A3_Green_LR"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + DBAL_A3_FLASHLIGHT; + POINTER_IR; + }; + }; + + class ACE_DBAL_A3_Green_LR_IP: ACE_DBAL_A3_Green_IP { + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_LR_II"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_LR"; + baseWeapon = "ACE_DBAL_A3_Green_LR"; + }; + + class ACE_DBAL_A3_Green_LR_II: ACE_DBAL_A3_Green_II { + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_LR_VP"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_LR_IP"; + baseWeapon = "ACE_DBAL_A3_Green_LR"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + DBAL_A3_FLASHLIGHT; + }; + }; + + class ACE_DBAL_A3_Green_LR_VP: ACE_DBAL_A3_Green_VP { + MRT_SwitchItemNextClass = "ACE_DBAL_A3_Green_LR"; + MRT_SwitchItemPrevClass = "ACE_DBAL_A3_Green_LR_II"; + baseWeapon = "ACE_DBAL_A3_Green_LR"; + }; + + // SPIR + class ACE_SPIR: acc_flashlight { + author = ECSTRING(common,ACETeam); + displayName = "SPIR"; + descriptionUse = CSTRING(SPIR_DescriptionUse); + descriptionShort = CSTRING(SPIR_DescriptionShort); + MRT_SwitchItemNextClass = "ACE_SPIR_Medium"; + MRT_SwitchItemPrevClass = "ACE_SPIR_Narrow"; + MRT_SwitchItemHintText = CSTRING(Mode_Wide); + baseWeapon = "ACE_SPIR"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight { + SPIR_FLASHLIGHT(50,70); + innerAngle = 20; + outerAngle = 32; + coneFadeCoef = 2; + intensity = 50; + scale[] = {1, 1, 1}; + }; + }; + }; + + class ACE_SPIR_Medium: ACE_SPIR { + scope = 1; + MRT_SwitchItemNextClass = "ACE_SPIR_Narrow"; + MRT_SwitchItemPrevClass = "ACE_SPIR"; + MRT_SwitchItemHintText = CSTRING(Mode_Medium); + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight { + SPIR_FLASHLIGHT(80,100); + intensity = 100; + innerAngle = 10; + outerAngle = 12; + coneFadeCoef = 3; + scale[] = {1, 1, 5}; + }; + }; + }; + + class ACE_SPIR_Narrow: ACE_SPIR { + scope = 1; + MRT_SwitchItemNextClass = "ACE_SPIR"; + MRT_SwitchItemPrevClass = "ACE_SPIR_Medium"; + MRT_SwitchItemHintText = CSTRING(Mode_Narrow); + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight { + SPIR_FLASHLIGHT(120,150); + intensity = 200; + innerAngle = 5; + outerAngle = 6; + coneFadeCoef = 4; + scale[] = {1, 1, 10}; + }; + }; + }; + + // SPIR (long range) + class ACE_SPIR_LR: ACE_SPIR { + scope = 1; + MRT_SwitchItemNextClass = "ACE_SPIR_LR_Medium"; + MRT_SwitchItemPrevClass = "ACE_SPIR_LR_Narrow"; + baseWeapon = "ACE_SPIR_LR"; + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight { + SPIR_FLASHLIGHT_LR(80,100); + innerAngle = 20; + outerAngle = 32; + coneFadeCoef = 2; + intensity = 50; + scale[] = {1, 1, 1}; + }; + }; + }; + + class ACE_SPIR_LR_Medium: ACE_SPIR_LR { + MRT_SwitchItemNextClass = "ACE_SPIR_LR_Narrow"; + MRT_SwitchItemPrevClass = "ACE_SPIR_LR"; + MRT_SwitchItemHintText = CSTRING(Mode_Medium); + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight { + SPIR_FLASHLIGHT_LR(100,120); + intensity = 100; + innerAngle = 10; + outerAngle = 12; + coneFadeCoef = 3; + scale[] = {1, 1, 5}; + }; + }; + }; + + class ACE_SPIR_LR_Narrow: ACE_SPIR_LR { + MRT_SwitchItemNextClass = "ACE_SPIR_LR"; + MRT_SwitchItemPrevClass = "ACE_SPIR_LR_Medium"; + MRT_SwitchItemHintText = CSTRING(Mode_Narrow); + + class ItemInfo: InventoryFlashLightItem_Base_F { + class Flashlight { + SPIR_FLASHLIGHT_LR(180,200); + intensity = 200; + innerAngle = 5; + outerAngle = 6; + coneFadeCoef = 4; + scale[] = {1, 1, 10}; + }; + }; + }; +}; diff --git a/addons/irlight/README.md b/addons/irlight/README.md new file mode 100644 index 0000000000..3e55e4903f --- /dev/null +++ b/addons/irlight/README.md @@ -0,0 +1,4 @@ +ace_irlight +=================== + +Adds IR flashlights. diff --git a/addons/irlight/XEH_PREP.hpp b/addons/irlight/XEH_PREP.hpp new file mode 100644 index 0000000000..db1a29d22e --- /dev/null +++ b/addons/irlight/XEH_PREP.hpp @@ -0,0 +1,3 @@ +PREP(getGlowOffset); +PREP(initItemContextMenu); +PREP(onLightToggled); diff --git a/addons/irlight/XEH_postInit.sqf b/addons/irlight/XEH_postInit.sqf new file mode 100644 index 0000000000..d95186f07b --- /dev/null +++ b/addons/irlight/XEH_postInit.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" + +[] call FUNC(initItemContextMenu); + +addUserActionEventHandler ["headlights", "Deactivate", LINKFUNC(onLightToggled)]; + +["ACE3 Equipment", QGVAR(hold), LLSTRING(MomentarySwitch), { + ACE_player action ["GunLightOn", ACE_player]; + ACE_player action ["IRLaserOn", ACE_player]; + [] call FUNC(onLightToggled); + true +}, { + ACE_player action ["GunLightOff", ACE_player]; + ACE_player action ["IRLaserOff", ACE_player]; + [] call FUNC(onLightToggled); + true +}] call CBA_fnc_addKeybind; + +["CBA_attachmentSwitched", { + params ["", "", "_item"]; + + private _substr = _item select [0, 8]; + if ( + ACE_player getVariable [QGVAR(isTurnedOn), false] + && {_substr == "ACE_SPIR" || {_substr == "ACE_DBAL"}} + ) then { + ACE_player action ["GunLightOn", ACE_player]; + ACE_player action ["IRLaserOn", ACE_player]; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/irlight/XEH_preInit.sqf b/addons/irlight/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/irlight/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/irlight/XEH_preStart.sqf b/addons/irlight/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/irlight/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/irlight/config.cpp b/addons/irlight/config.cpp new file mode 100644 index 0000000000..9446d8e9d7 --- /dev/null +++ b/addons/irlight/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"BaerMitUmlaut", "OmniMan"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgJointRails.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/irlight/data/irglow.p3d b/addons/irlight/data/irglow.p3d new file mode 100644 index 0000000000..d43e40d0f0 Binary files /dev/null and b/addons/irlight/data/irglow.p3d differ diff --git a/addons/irlight/data/irglow.rvmat b/addons/irlight/data/irglow.rvmat new file mode 100644 index 0000000000..d39184a535 --- /dev/null +++ b/addons/irlight/data/irglow.rvmat @@ -0,0 +1,79 @@ +ambient[] = {0, 0, 0, 1}; +diffuse[] = {0, 0, 0, 1}; +forcedDiffuse[] = {0, 0, 0, 1}; +emmisive[] = {775, 121, 549, 0}; +specular[] = {0, 0, 0, 1}; +specularPower = 30; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +class Stage1 { + texture = "#(argb,8,8,3)color(0.5,0.5,1,1,NOHQ)"; + 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,0.5,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1, 0, 0}; + up[] = {0, 1, 0}; + dir[] = {0, 0, 0}; + pos[] = {0, 0, 0}; + }; +}; +class Stage3 { + texture = "#(argb,8,8,3)color(1.0,1.0,1.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 = "#(argb,8,8,3)color(1.0,1.0,1.0,1.0,AS)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1, 0, 0}; + up[] = {0, 1, 0}; + dir[] = {0, 0, 0}; + pos[] = {0, 0, 0}; + }; +}; +class Stage5 { + texture = "#(argb,8,8,3)color(1,0.0,1,0,SMDI)"; + 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(0.4,0.2)"; + 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"; + useWorldEnvMap = "true"; + uvSource = "tex"; + class uvTransform { + aside[] = {1, 0, 0}; + up[] = {0, 1, 0}; + dir[] = {0, 0, 0}; + pos[] = {0, 0, 0}; + }; +}; diff --git a/addons/irlight/data/model.cfg b/addons/irlight/data/model.cfg new file mode 100644 index 0000000000..949c7bebcc --- /dev/null +++ b/addons/irlight/data/model.cfg @@ -0,0 +1,8 @@ +class CfgModels { + class Default { + sectionsInherit = ""; + sections[] = {""}; + skeletonName = ""; + }; + class irglow: Default {}; +}; diff --git a/addons/irlight/dev/createTestLight.sqf b/addons/irlight/dev/createTestLight.sqf new file mode 100644 index 0000000000..3aace8ab3d --- /dev/null +++ b/addons/irlight/dev/createTestLight.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Creates a scripted test light to test weapon lights without reloading. + * + * Arguments: + * 0: Flashlight class name + * + * Return Value: + * None + * + * Example: + * "ACE_SPIR" call compile preprocessFileLineNumbers "\z\ace\addons\irlight\dev\createTestLight.sqf" + * + * Public: No + */ + +params ["_className"]; + +private _cfg = configFile >> "CfgWeapons" >> _className >> "ItemInfo" >> "Flashlight"; + +deleteVehicle lgt; +lgt = "#lightreflector" createVehicleLocal [0, 0, 0]; +lgt attachTo [player, [0.0396804,0.237947,0.104276], "proxy:\a3\characters_f\proxies\weapon.001", true]; +lgt setLightIntensity getNumber (_cfg >> "intensity"); +lgt setLightColor (getArray (_cfg >> "color") select [0, 3]); +lgt setLightAmbient (getArray (_cfg >> "ambient") select [0, 3]); +lgt setLightConePars [ + getNumber (_cfg >> "outerAngle"), + getNumber (_cfg >> "innerAngle"), + getNumber (_cfg >> "coneFadeCoef") +]; + +attenuation = [ + getNumber (_cfg >> "Attenuation" >> "start"), + getNumber (_cfg >> "Attenuation" >> "constant"), + getNumber (_cfg >> "Attenuation" >> "linear"), + getNumber (_cfg >> "Attenuation" >> "quadratic"), + getNumber (_cfg >> "Attenuation" >> "hardLimitStart"), + getNumber (_cfg >> "Attenuation" >> "hardLimitEnd") +]; +lgt setLightAttenuation attenuation; diff --git a/addons/irlight/functions/fnc_getGlowOffset.sqf b/addons/irlight/functions/fnc_getGlowOffset.sqf new file mode 100644 index 0000000000..613e551111 --- /dev/null +++ b/addons/irlight/functions/fnc_getGlowOffset.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Gets the player model offset of the IR laser origin. + * Currently unused, see onLightToggled. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_irlight_fnc_getGlowOffset + * + * Public: No + */ + +if (isNil QGVAR(offsetCache)) then { + GVAR(offsetCache) = createHashMap; +}; + +private _weapon = currentWeapon ACE_player; +private _laser = ((weaponsItems ACE_player) select {_x#0 == _weapon})#0#2; + +GVAR(offsetCache) getOrDefaultCall [[_weapon, _laser], { + private _model = getText (configFile >> "CfgWeapons" >> _weapon >> "model"); + private _dummy = createSimpleObject [_model, [0, 0, 0], true]; + private _proxyOffset = _dummy selectionPosition ["\a3\data_f\proxies\weapon_slots\SIDE.001", 1]; + _proxyOffset = [_proxyOffset#1, _proxyOffset#0 * -1, _proxyOffset#2]; + deleteVehicle _dummy; + + _model = getText (configFile >> "CfgWeapons" >> _laser >> "model"); + _dummy = createSimpleObject [_model, [0, 0, 0], true]; + private _selection = getText (configFile >> "CfgWeapons" >> _laser >> "ItemInfo" >> "Pointer" >> "irLaserPos"); + private _laserOffset = _dummy selectionPosition [_selection, "Memory"]; + _laserOffset = [_laserOffset#1, _laserOffset#0 * -1, _laserOffset#2 * -1]; + deleteVehicle _dummy; + + _proxyOffset vectorAdd _laserOffset +}, true]; diff --git a/addons/irlight/functions/fnc_initItemContextMenu.sqf b/addons/irlight/functions/fnc_initItemContextMenu.sqf new file mode 100644 index 0000000000..fa75eba77b --- /dev/null +++ b/addons/irlight/functions/fnc_initItemContextMenu.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Initializes the item context menu for the DBAL. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_irlight_fnc_initItemContextMenu + * + * Public: No + */ + +{ + _x params ["_variant", "_displayName"]; + + [ + "ACE_DBAL_A3_Red", "POINTER", _displayName, [], "", { + params ["", "", "_item", "", "_variant"]; + + private _baseClass = getText (configFile >> "CfgWeapons" >> _item >> "baseWeapon"); + _item != _baseClass + _variant + }, { + params ["", "", "_item", "", "_variant"]; + + private _baseClass = getText (configFile >> "CfgWeapons" >> _item >> "baseWeapon"); + + ACE_player removePrimaryWeaponItem _item; + ACE_player addPrimaryWeaponItem (_baseClass + _variant); + playSound "click"; + + if (_turnedOn) then { + // Force update of flashlight + ACE_player action ["GunLightOff", ACE_player]; + + { + ACE_player action ["GunLightOn", ACE_player]; + ACE_player action ["IRLaserOn", ACE_player]; + } call CBA_fnc_execNextFrame; + }; + }, false, _variant + ] call CBA_fnc_addItemContextMenuOption; +} forEach [ + ["", LSTRING(Mode_IRDual)], + ["_IP", LSTRING(Mode_IRPointer)], + ["_II", LSTRING(Mode_IRIlluminator)], + ["_VP", LSTRING(Mode_VisiblePointer)] +]; diff --git a/addons/irlight/functions/fnc_onLightToggled.sqf b/addons/irlight/functions/fnc_onLightToggled.sqf new file mode 100644 index 0000000000..b3592f28f6 --- /dev/null +++ b/addons/irlight/functions/fnc_onLightToggled.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Handles toggling flashlights on and off. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_irlight_fnc_onLightToggled + * + * Public: No + */ + +private _isTurnedOn = ACE_player isFlashlightOn primaryWeapon ACE_player + || ACE_player isIRLaserOn primaryWeapon ACE_player; +ACE_player setVariable [QGVAR(isTurnedOn), _isTurnedOn]; + +// This is a surprise tool that will help us later +// Requires: https://feedback.bistudio.com/T170774 +/* +deleteVehicle (ACE_player getVariable [QGVAR(glow), objNull]); + +if (ACE_player isIRLaserOn currentWeapon ACE_player) then { + private _offset = [] call FUNC(getGlowOffset); + private _glow = createSimpleObject [QPATHTOF(data\irglow.p3d), [0, 0, 0]]; + _glow attachTo [ACE_player, _offset, "proxy:\a3\characters_f\proxies\weapon.001", true]; + _glow setObjectTexture [0, "#(rgb,8,8,3)color(0.35,0,0.38,0.1)"]; + _glow setObjectScale 0.1; + + ACE_player setVariable [QGVAR(glow), _glow]; +}; +*/ diff --git a/addons/irlight/script_component.hpp b/addons/irlight/script_component.hpp new file mode 100644 index 0000000000..76e3eb11a3 --- /dev/null +++ b/addons/irlight/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT irlight +#define COMPONENT_BEAUTIFIED IR Lights +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_IRLIGHT + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_IRLIGHT + #define DEBUG_SETTINGS DEBUG_SETTINGS_IRLIGHT +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/irlight/stringtable.xml b/addons/irlight/stringtable.xml new file mode 100644 index 0000000000..506e9deb9d --- /dev/null +++ b/addons/irlight/stringtable.xml @@ -0,0 +1,173 @@ + + + + + DBAL-A3 (red) + DBAL-A3 (rot) + DBAL-A3 (Rosso) + DBAL-A3 (czerwony) + DBAL-A3 (빨강) + DBAL-A3 (rouge) + DBAL-A3 (vermelho) + DBAL-A3 (赤) + DBAL-A3 (красный) + DBAL-A3 (rojo) + + + DBAL-A3 (green) + DBAL-A3 (Grün) + DBAL-A3 (Verde) + DBAL-A3 (Zielony) + DBAL-A3 (녹색) + DBAL-A3 (Vert) + DBAL-A3 (Verde) + DBAL-A3 (緑) + DBAL-A3 (зеленый) + DBAL-A3 (verde) + + + <t color='#9cf953'>Use: </t>Turn Laser ON/OFF<br>Double click to switch mode + <t color='#9cf953'>Benutzen: </t>Laser EIN/AUS<br>Doppelklick um Modus zu wechseln + <t color='#9cf953'>Usa: </t>Laser ACCESO/SPENTO<br>Doppio Click per cambiare modalità + <t color='#9cf953'>Użycie: </t>Laser WŁ/WYŁ<br>Kliknij dwukrotnie, aby zmienić tryb + <t color='#9cf953'>사용: </t>레이저 켜기/끄기<br>터블 클릭으로 모드 전환 + <t color='#9cf953'>Utilisation: </t>Allumer/Eteindre le laser<br>Double clic pour changer de mode + <t color='#9cf953'>Uso: </t>Ligar/Desligar Laser<br>Duplo clique para mudar o modo + <t color='#9cf953'>使用方法: </t>レーザーのオン/オフ切り替え<br>ダブルクリックでモード切り替え + <t color='#9cf953'>Использование: </t>Включение / выключение лазера <br>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Láser ON/OFF<br>Doble click para cambiar estado + + + Dual Beam Aiming Laser + Doppelstrahllaservisier + Puntatore Laser Multiuso + Laser Celowniczy z Podwójną Wiązką + 이중 빔 조준 레이저 + Viseur laser à double faisceau + Laser de Pontaria de Duplo Feixe + 複合ビーム照準レーザー + Двухлучевой прицельный лазер + Láser de Apuntado de Doble Haz + + + Visible Laser + Sichtbarer Laser + Laser Visibile + Laser Widzialny + 가시 레이저 + Laser visible + Laser Visível + 可視光レーザー + Видимый лазер + Láser Visible + + + IR Laser + IR-Laser + Laser IR + Laser IR + 적외선 레이저 + Laser IR + Laser IR + IRレーザー + ИК-лазер + Láser IR + + + IR Illuminator + IR-Taschenlampe + Illuminatore IR + Iluminator IR + 적외선 조명 + Illuminateur IR + Iluminador IR + IRイルミネーター + ИК-осветитель + Iluminador IR + + + IR Laser and Illuminator + IR-Laser und -Licht + Laser e Illuminatore IR + Laser IR i Iluminator + 적외선 레이저와 조명 + Illuminateur et laser IR + Laser e Iluminador IR + IRレーザーとイルミネーター + ИК-лазер и осветитель + Láser e Iluminador IR + + + Wide Beam + Breiter Lichtstrahl + Fascio Ampio + Szeroka Wiązka + 넓은 빔 + Faisceau large + Feixe Largo + 広角ビーム + Широкий луч + Haz Ancho + + + Medium Beam + Mittlerer Lichtstrahl + Fascio Intermedio + Średnia Wiązka + 중간 빔 + Faisceau moyen + Feixe Médio + 標準ビーム + Средний луч + Haz Medio + + + Narrow Beam + Schmaler Lichtstrahl + Fascio Stretto + Wąska Wiązka + 좁은 빔 + Faisceau étroit + Feixe Estreito + 狭角ビーム + Узкий луч + Haz Estrecho + + + <t color='#9cf953'>Use: </t>Turn Light ON/OFF<br>Double click to switch mode + <t color='#9cf953'>Benutzen: </t>Licht EIN/AUS<br>Doppelklick um Modus zu wechseln + <t color='#9cf953'>Usa: </t>Luce ACCESA/SPENTA<br>Doppio Click per cambiare modalità + <t color='#9cf953'>Użycie: </t>Iluminator WŁ/WYŁ<br>Kliknij dwukrotnie, aby zmienić tryb + <t color='#9cf953'>사용: </t>조명 켜기/끄기<br>더블 클릭으로 모드 전환 + <t color='#9cf953'>Utilisation: </t>Allumer/Eteindre la lumière<br>Double clic pour changer de mode + <t color='#9cf953'>Uso: </t>Ligar/Desligar Iluminador<br>Duplo clique para mudar o modo + <t color='#9cf953'>使用方法: </t>ライトのオン/オフ<br>ダブルクリックでモード切り替え + <t color='#9cf953'>Использование: </t>Включение / выключение освещения <br>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Luz ON/OFF<br>Doble click para cambiar estado + + + Special Purpose IR LED Illuminator + Infrarot LED Taschenlampe + Torcia LED IR + Iluminator IR LED Specjalnego Przeznaczenia + 특수목적 적외선 LED 조명 + Illuminateur LED IR à usage spécial + Iluminador LED IR de Uso Especial + 特殊用途のIR LEDイルミネーター + ИК-светодиодный осветитель специального назначения + Iluminador LED IR de Propósito Especial + + + Illuminator / Laser Momentary Switch + Licht / Laser Tastschalter + Accensione momentanea Laser/Illuminatore + Przełącznik Chwilowy Iluminator / Laser + 조명/레이저 빠르게 스위치 + Commutateur temporaire illuminateur/laser + Interruptor Momentâneo Iluminador/Laser + イルミネーター/レーザーモーメンタリースイッチ + Мгновенный переключатель осветителя/лазера + Conmutador Momentáneo Iluminador / Láser + + + diff --git a/addons/javelin/CfgEventhandlers.hpp b/addons/javelin/CfgEventhandlers.hpp index 789cfeb05c..e325095c32 100644 --- a/addons/javelin/CfgEventhandlers.hpp +++ b/addons/javelin/CfgEventhandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); }; }; diff --git a/addons/javelin/CfgSounds.hpp b/addons/javelin/CfgSounds.hpp index 9cd2627fa2..289a571e6e 100644 --- a/addons/javelin/CfgSounds.hpp +++ b/addons/javelin/CfgSounds.hpp @@ -2,12 +2,12 @@ class CfgSounds { class ACE_Javelin_Locking { name = "ACE_Javelin_Locking"; - sound[] = {PATHTOF(data\sounds\javelin_locking.ogg), db+0, 1.0}; + sound[] = {QPATHTOF(data\sounds\javelin_locking.ogg), "db+0", 1.0}; titles[] = {}; }; class ACE_Javelin_Locked { name = "ACE_Javelin_Locked"; - sound[] = {PATHTOF(data\sounds\javelin_locked.ogg), db+0, 1.0}; + sound[] = {QPATHTOF(data\sounds\javelin_locked.ogg), "db+0", 1.0}; titles[] = {}; }; }; diff --git a/addons/javelin/README.md b/addons/javelin/README.md index ecbf3743b4..cf39b60bd0 100644 --- a/addons/javelin/README.md +++ b/addons/javelin/README.md @@ -2,11 +2,3 @@ ace_javelin =============== Adds the Javelin AT launcher. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [jaynus](https://github.com/walterpearce) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/javelin/RscInGameUI.hpp b/addons/javelin/RscInGameUI.hpp index e34630dde3..ce777c2047 100644 --- a/addons/javelin/RscInGameUI.hpp +++ b/addons/javelin/RscInGameUI.hpp @@ -14,20 +14,20 @@ class RscInGameUI { onLoad = QUOTE(with uiNamespace do {ACE_RscOptics_javelin = _this select 0;};); class GVAR(mapHelper): RscMapControl { - onDraw = QUOTE(_this call FUNC(mapHelperDraw);); + onDraw = QUOTE(_this call FUNC(mapHelperDraw)); x = -10; y = -10; w = 0; h = 0; - }; - + }; + class GVAR(elements_group): RscControlsGroupNoScrollbars { x = "safeZoneX"; y = "safeZoneY"; w = "safeZoneW"; h = "safeZoneH"; idc = 170; - class Controls { + class Controls { class CA_Distance: RscOpticsValue { idc = 151; sizeEx = "0"; @@ -238,7 +238,7 @@ class RscInGameUI { y = "safeZoneY"; w = "safeZoneW"; h = "safeZoneH"; - enabled = 0; + enabled = 0; show = 0; class Controls { class ACE_TargetingConstrains: RscControlsGroupNoScrollbars { diff --git a/addons/javelin/XEH_clientInit.sqf b/addons/javelin/XEH_clientInit.sqf index 66d645968f..ecd80fb0ce 100644 --- a/addons/javelin/XEH_clientInit.sqf +++ b/addons/javelin/XEH_clientInit.sqf @@ -3,4 +3,4 @@ if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" diff --git a/addons/javelin/functions/fnc_getTarget.sqf b/addons/javelin/functions/fnc_getTarget.sqf index 7230aae64a..6fd4686eb8 100644 --- a/addons/javelin/functions/fnc_getTarget.sqf +++ b/addons/javelin/functions/fnc_getTarget.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Find a target within the optic range @@ -35,10 +35,10 @@ if (!isNull _lastTarget) then { for "_xOffset" from -2.5 to 2.5 step 0.5 do { for "_yOffset" from -2 to 1 step 0.5 do { // Find test points in the model based on the angle that we are viewing it from (not true 3d projection, but not bad) - private _testPosASL = AGLtoASL (_lastTarget modelToWorld [_xOffset * - cos _relAngle, _xOffset * sin _relAngle, _yOffset]); + private _testPosASL = _lastTarget modelToWorldWorld [_xOffset * - cos _relAngle, _xOffset * sin _relAngle, _yOffset]; private _intersectionsToCursorTarget = lineIntersectsSurfaces [_viewASL, _testPosASL, ace_player, vehicle ace_player, true, 1]; // drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [[0,1,1,1], [1,0,1,1]] select (count _intersectionsToCursorTarget), (ASLtoAGL _testPosASL), 0.25, 0.25, 0, "", 0.5, 0.025, "TahomaB"]; - if (!(_intersectionsToCursorTarget isEqualTo [])) then { + if (_intersectionsToCursorTarget isNotEqualTo []) then { (_intersectionsToCursorTarget select 0) params ["", "", "_intersectedObject"]; if (_intersectedObject isKindOf "AllVehicles") then { _intersectedObject breakOut "main"; @@ -68,7 +68,7 @@ for "_xOffset" from -14 to 14 step 2 do { private _testPosASL = AGLtoASL (positionCameraToWorld [_xOffset, _yOffset, _maxRange]); private _intersectionsToCursorTarget = lineIntersectsSurfaces [_viewASL, _testPosASL, ace_player, vehicle ace_player, true, 1]; // drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [[0,1,0,1], [1,0,0,1]] select (count _intersectionsToCursorTarget), (ASLtoAGL _testPosASL), 0.25, 0.25, 0, "", 0.5, 0.025, "TahomaB"]; - if (!(_intersectionsToCursorTarget isEqualTo [])) then { + if (_intersectionsToCursorTarget isNotEqualTo []) then { (_intersectionsToCursorTarget select 0) params ["", "", "_intersectedObject"]; if (_intersectedObject isKindOf "AllVehicles") then { _intersectedObject breakOut "main"; diff --git a/addons/javelin/functions/fnc_mapHelperDraw.sqf b/addons/javelin/functions/fnc_mapHelperDraw.sqf index 1b81fc7dd5..4f7ac84b4a 100644 --- a/addons/javelin/functions/fnc_mapHelperDraw.sqf +++ b/addons/javelin/functions/fnc_mapHelperDraw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the map helper's draw event @@ -18,7 +18,7 @@ */ if (isNil QGVAR(arguments)) then { - TRACE_1("Starting optic draw", _this); + TRACE_1("Starting optic draw",_this); // reset shooter var: private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; diff --git a/addons/javelin/functions/fnc_onOpticDraw.sqf b/addons/javelin/functions/fnc_onOpticDraw.sqf index b2de0be4e9..aacc4f5fa1 100644 --- a/addons/javelin/functions/fnc_onOpticDraw.sqf +++ b/addons/javelin/functions/fnc_onOpticDraw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus, PabstMirror * Main loop, handles scaning for targets and drawing the javelin optic @@ -14,7 +14,7 @@ * None * * Example: - * [] call ace_javelin_fnc_mapHelperDraw + * [] call ace_javelin_fnc_onOpticDraw * * Public: No */ @@ -55,6 +55,19 @@ if ((_ammoCount == 0) || // No ammo loaded _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); _this set [0, diag_frameno]; _this set [4, _fireDisabledEH]; + + // Fix weapon being in top-attack when loading AP magazine (https://feedback.bistudio.com/T171012) + if ((_currentShooter == ACE_player) && {_currentMagazine == "Titan_AP"} && {currentWeaponMode ACE_player == "TopDown"}) then { + { + _x params ["_xIndex", "", "", "", "_xMode"]; + if (_xMode == "Single") exitWith { + ACE_player action ["SwitchWeapon", _currentShooter, ACE_player, _xIndex]; + __JavelinIGUITop ctrlSetTextColor __ColorGray; + __JavelinIGUIDir ctrlSetTextColor __ColorGreen; + TRACE_2("fix top-attack for AP",weaponState _currentShooter,_x); + }; + } forEach (ACE_player weaponsInfo [_currentWeapon, true]); + }; }; @@ -91,11 +104,11 @@ if (GVAR(isLockKeyDown) && {cameraView == "GUNNER"} && {((currentVisionMode ACE_ private _boundsInput = if (_currentTarget isKindOf "CAManBase") then { [_currentTarget,[-0.5,-0.5,-0.25],[0,0,0]]; } else { - [_currentTarget,[-1,-1,-1],_currentTarget selectionPosition "zamerny"]; + [_currentTarget,[-1,-1,-1],_currentTarget selectionPosition "zamerny"]; }; private _bpos = _boundsInput call EFUNC(common,worldToScreenBounds); - + private _lockTime = if (isNull _currentTarget) then {0} else {CBA_missionTime - _lockStartTime}; private _minX = ((linearConversion [1, (__LOCKONTIME - 0.5), _lockTime, 0.5 - 0.075*safeZoneW, (_bpos select 0), true]) + _offsetX) max __ConstraintLeft; private _minY = ((linearConversion [1, (__LOCKONTIME - 0.5), _lockTime, 0.5 - 0.075*safeZoneH, (_bpos select 1), true]) + _offsetY) max __ConstraintTop; @@ -128,18 +141,18 @@ if (isNull _newTarget) then { _currentShooter setVariable ["ace_missileguidance_target", nil, false]; __JavelinIGUITargetingLines ctrlShow false; - + // Disallow fire _fireDisabledEH = [_fireDisabledEH] call FUNC(disableFire); } else { if ((!isNull _newTarget) && {_currentTarget != _newTarget}) then { - TRACE_1("New Target, reseting locking", _newTarget); + TRACE_1("New Target, reseting locking",_newTarget); _lockStartTime = CBA_missionTime; _currentTarget = _newTarget; }; if ((CBA_missionTime - _lockStartTime) > __LOCKONTIME) then { // Lock on after 3 seconds - TRACE_2("LOCKED!", _currentTarget, _lockStartTime); + TRACE_2("LOCKED!",_currentTarget,_lockStartTime); __JavelinIGUISeek ctrlSetTextColor __ColorGreen; __JavelinIGUITargetingLines ctrlShow true; diff --git a/addons/javelin/functions/fnc_showFireMode.sqf b/addons/javelin/functions/fnc_showFireMode.sqf index 589a9727aa..85ed983718 100644 --- a/addons/javelin/functions/fnc_showFireMode.sqf +++ b/addons/javelin/functions/fnc_showFireMode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Updates fire mode on javelin display (top/dir) diff --git a/addons/javelin/functions/script_component.hpp b/addons/javelin/functions/script_component.hpp deleted file mode 100644 index 21c6597c86..0000000000 --- a/addons/javelin/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\javelin\script_component.hpp" \ No newline at end of file diff --git a/addons/javelin/initKeybinds.sqf b/addons/javelin/initKeybinds.inc.sqf similarity index 100% rename from addons/javelin/initKeybinds.sqf rename to addons/javelin/initKeybinds.inc.sqf diff --git a/addons/javelin/script_component.hpp b/addons/javelin/script_component.hpp index b78032439d..3e9ad4ebfc 100644 --- a/addons/javelin/script_component.hpp +++ b/addons/javelin/script_component.hpp @@ -26,7 +26,6 @@ #define __JavelinIGUISeek (__JavelinIGUI displayCtrl 699000) #define __JavelinIGUITop (__JavelinIGUI displayCtrl 699001) #define __JavelinIGUIDir (__JavelinIGUI displayCtrl 699002) -#define __JavelinIGUIRangefinder (__JavelinIGUI displayCtrl 151) // Constrains #define __JavelinIGUITargetingConstrains (__JavelinIGUI displayCtrl 699100) diff --git a/addons/javelin/stringtable.xml b/addons/javelin/stringtable.xml index 96dc8d33ee..ab1ff30a10 100644 --- a/addons/javelin/stringtable.xml +++ b/addons/javelin/stringtable.xml @@ -3,19 +3,20 @@ Lock Target (Hold) - Ziel aufschalten + Ziel aufschalten (Halten) Захватить цель (удерживать) Zamknout cíl (držet) Namierz cel (przytrzymaj) - Verrouiller la cible (maintenir) + Javelin - Verrouiller la cible (maintenir) Célpontra állás (Lenyomva tartott) Aggangia il bersaglio Fijar objetivo (Mantener) - Travar Alvo(Segurar) - 目標を捕捉 (押しっぱ) + Travar Alvo (Segurar) + 目標を捕捉 (長押し) 표적 획득 (누르기) - 锁定目标 (按住) + 锁定目标(按住) 鎖定目標 (按住) + Hedefe Kilitlen(Basılı Tut) diff --git a/addons/kestrel4500/CfgEventHandlers.hpp b/addons/kestrel4500/CfgEventHandlers.hpp index 2bed8a2eef..851e58197c 100644 --- a/addons/kestrel4500/CfgEventHandlers.hpp +++ b/addons/kestrel4500/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/kestrel4500/CfgSound.hpp b/addons/kestrel4500/CfgSound.hpp index 957863bc9d..a657ef53f9 100644 --- a/addons/kestrel4500/CfgSound.hpp +++ b/addons/kestrel4500/CfgSound.hpp @@ -1,39 +1,32 @@ -class CfgSounds -{ - class kestrel4500_center_button_click - { +class CfgSounds { + class kestrel4500_center_button_click { name="kestrel4500_center_button_click"; - sound[]={PATHTOF(sound\kestrel_center_button_click.wav),1,1}; + sound[]={QPATHTOF(sound\kestrel_center_button_click.wav),1,1}; titles[]={}; }; - class kestrel4500_top_button_click - { + class kestrel4500_top_button_click { name="kestrel4500_top_button_click"; - sound[]={PATHTOF(sound\kestrel_top_button_click.wav),1,1}; + sound[]={QPATHTOF(sound\kestrel_top_button_click.wav),1,1}; titles[]={}; }; - class kestrel4500_right_button_click - { + class kestrel4500_right_button_click { name="kestrel4500_right_button_click"; - sound[]={PATHTOF(sound\kestrel_right_button_click.wav),1,1}; + sound[]={QPATHTOF(sound\kestrel_right_button_click.wav),1,1}; titles[]={}; }; - class kestrel4500_bottom_button_click - { + class kestrel4500_bottom_button_click { name="kestrel4500_bottom_button_click"; - sound[]={PATHTOF(sound\kestrel_bottom_button_click.wav),1,1}; + sound[]={QPATHTOF(sound\kestrel_bottom_button_click.wav),1,1}; titles[]={}; }; - class kestrel4500_left_button_click - { + class kestrel4500_left_button_click { name="kestrel4500_left_button_click"; - sound[]={PATHTOF(sound\kestrel_left_button_click.wav),1,1}; + sound[]={QPATHTOF(sound\kestrel_left_button_click.wav),1,1}; titles[]={}; }; - class kestrel4500_exit_button_click - { + class kestrel4500_exit_button_click { name="kestrel4500_exit_button_click"; - sound[]={PATHTOF(sound\kestrel_exit_button_click.wav),1,1}; + sound[]={QPATHTOF(sound\kestrel_exit_button_click.wav),1,1}; titles[]={}; }; -}; \ No newline at end of file +}; diff --git a/addons/kestrel4500/CfgWeapons.hpp b/addons/kestrel4500/CfgWeapons.hpp index ea9cd2ab2f..35930e53d9 100644 --- a/addons/kestrel4500/CfgWeapons.hpp +++ b/addons/kestrel4500/CfgWeapons.hpp @@ -12,6 +12,7 @@ class CfgWeapons { picture = QPATHTOF(UI\Kestrel4500.paa); icon = "iconObject_circle"; mapSize = 0.034; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; diff --git a/addons/kestrel4500/README.md b/addons/kestrel4500/README.md index c0b50a3555..3e4d8a94e2 100644 --- a/addons/kestrel4500/README.md +++ b/addons/kestrel4500/README.md @@ -2,10 +2,3 @@ ace_kestrel4500 =============== Adds Kestrel 4500 Pocket Weather Tracker. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/kestrel4500/RscTitles.hpp b/addons/kestrel4500/RscTitles.hpp index 276e8c4392..faae6a8f32 100644 --- a/addons/kestrel4500/RscTitles.hpp +++ b/addons/kestrel4500/RscTitles.hpp @@ -64,26 +64,26 @@ class Kestrel4500_Display { SizeEX=0.025; idc=74000; style=48; - x=safezoneX; + x="safezoneX"; y = DIALOG_SAFE_Y(0); - w=1.024; - h=1.024*4/3; + w="1.024"; + h="1.024*4/3"; colorBackground[]={1,1,1,1}; colorText[]={1,1,1,1}; - text=PATHTOF(UI\Kestrel4500.paa); + text=QPATHTOF(UI\Kestrel4500.paa); }; class POWER: Kestrel4500_RscButton { idc=-1; - x=safezoneX+0.385; + x="safezoneX+0.385"; y = DIALOG_SAFE_Y(1.125); - w=0.042; - h=0.042*4/3; + w="0.042"; + h="0.042*4/3"; action=QUOTE(7 call FUNC(buttonPressed)); onMouseButtonDown = "playSound 'kestrel4500_exit_button_click'"; }; class ENTER: POWER { idc=-1; - x=safezoneX+0.46; + x="safezoneX+0.46"; y = DIALOG_SAFE_Y(1.0); w=0.1; action=QUOTE(0 call FUNC(buttonPressed)); @@ -91,7 +91,7 @@ class Kestrel4500_Display { }; class TOP: Kestrel4500_RscButton { idc=-1; - x=safezoneX+0.46; + x="safezoneX+0.46"; y = DIALOG_SAFE_Y(0.93); w=0.1; h=0.03; @@ -106,7 +106,7 @@ class Kestrel4500_Display { }; class LEFT: Kestrel4500_RscButton { idc=-1; - x=safezoneX+0.4; + x="safezoneX+0.4"; y = DIALOG_SAFE_Y(0.97); w=0.046; h=0.11; @@ -115,27 +115,27 @@ class Kestrel4500_Display { }; class RIGHT: LEFT { idc=-1; - x=safezoneX+0.58; + x="safezoneX+0.58"; action=QUOTE(4 call FUNC(buttonPressed)); onMouseButtonDown = "playSound 'kestrel4500_right_button_click'"; }; class MEMORY: Kestrel4500_RscButton { idc=-1; - x=safezoneX+0.395; + x="safezoneX+0.395"; y = DIALOG_SAFE_Y(0.87); w=0.05; - h=0.045*4/3; + h="0.045*4/3"; action=QUOTE(5 call FUNC(buttonPressed)); }; class BACKLIGHT: MEMORY { idc=-1; - x=safezoneX+0.585; + x="safezoneX+0.585"; action=QUOTE(6 call FUNC(buttonPressed)); }; class TEXT_TOP: Kestrel4500_RscText { idc=74100; - x=safezoneX+0.40; + x="safezoneX+0.40"; y = DIALOG_SAFE_Y(0.58); w=0.22; h=0.04; @@ -223,7 +223,6 @@ class RscTitles { class RscKestrel4500 { idd=-1; onLoad="with uiNameSpace do { RscKestrel4500 = _this select 0 };"; - onUnload=(_this call FUNC(onCloseDisplay)); movingEnable=0; duration=60; fadeIn="false"; @@ -235,30 +234,30 @@ class RscTitles { moving=0; type=0; font="TahomaB"; - SizeEX=0.025*0.75; + SizeEX=".025*0.75"; style=48; - x=safezoneX+0.14; + x="safezoneX+0.14"; y = DISPLAY_SAFE_Y(0); - w=0.512*0.75; - h=1.024*4/3*0.75; + w="0.512*0.75"; + h="1.024*4/3*0.75"; colorBackground[]={1,1,1,1}; colorText[]={1,1,1,1}; - text=PATHTOF(UI\Kestrel4500_0.paa); + text=QPATHTOF(UI\Kestrel4500_0.paa); }; class RscTextTop: Kestrel4500_RscText { idc=75100; - x=safezoneX-0.05+0.40*0.75; + x="safezoneX-0.05+0.40*0.75"; y = DISPLAY_SAFE_Y(0.58*0.75); - w=0.22*0.75; - h=0.04*0.75; - SizeEx=0.04*0.75; + w="0.22*0.75"; + h="0.04*0.75"; + SizeEx="0.04*0.75"; text=""; }; class RscTextCenterBig: RscTextTop { idc=75200; y = DISPLAY_SAFE_Y(0.61*0.75); - h=0.10*0.75; - SizeEx=0.06*0.75; + h="0.10*0.75"; + SizeEx="0.06*0.75"; text=""; }; class RscTextCenter: RscTextTop { @@ -269,8 +268,8 @@ class RscTitles { idc=75300; y = DISPLAY_SAFE_Y(0.60*0.75); style=ST_LEFT; - h=0.10*0.75; - SizeEx=0.05*0.75; + h="0.10*0.75"; + SizeEx="0.05*0.75"; text=""; }; class RscTextCenterLine2Left: RscTextCenterLine1Left { @@ -308,14 +307,14 @@ class RscTitles { class RscTextBottomBig: RscTextTop { idc=75500; y = DISPLAY_SAFE_Y(0.67*0.75); - h=0.10*0.75; - SizeEx=0.06*0.75; + h="0.10*0.75"; + SizeEx="0.06*0.75"; text=""; }; class RscTextCenterLine1: RscTextTop { idc=75600; y = DISPLAY_SAFE_Y(0.58*0.75); - SizeEx=0.03*0.75; + SizeEx="0.03*0.75"; }; class RscTextCenterLine2: RscTextCenterLine1 { idc=75601; @@ -370,4 +369,4 @@ class RscTitles { }; }; }; -}; \ No newline at end of file +}; diff --git a/addons/kestrel4500/XEH_PREP.hpp b/addons/kestrel4500/XEH_PREP.hpp index 7d062c9ac8..ce9ecf95db 100644 --- a/addons/kestrel4500/XEH_PREP.hpp +++ b/addons/kestrel4500/XEH_PREP.hpp @@ -7,7 +7,6 @@ PREP(displayKestrel); PREP(generateOutputData); PREP(measureWindSpeed); PREP(onCloseDialog); -PREP(onCloseDisplay); PREP(restoreUserData); PREP(storeUserData); PREP(updateDisplay); diff --git a/addons/kestrel4500/XEH_postInit.sqf b/addons/kestrel4500/XEH_postInit.sqf index 9511041bd2..12688a6adf 100644 --- a/addons/kestrel4500/XEH_postInit.sqf +++ b/addons/kestrel4500/XEH_postInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" GVAR(Menus) = ["Date", "Direction", "Wind SPD m/s", "CROSSWIND m/s", "HEADWIND m/s", "TEMP °C", "CHILL °C", "HUMIDITY %", "HEAT INDEX °C", "DEW POINT °C", "WET BULB °C", "BARO hPA", "ALTITUDE m", "DENS ALT m", "User Screen 1", "User Screen 2"]; @@ -29,4 +29,4 @@ GVAR(ImpellerState) = 0; GVAR(Kestrel4500) = false; GVAR(Overlay) = false; -[] call FUNC(restoreUserData); \ No newline at end of file +[] call FUNC(restoreUserData); diff --git a/addons/kestrel4500/config.cpp b/addons/kestrel4500/config.cpp index 11bc51f801..5ea15f07ff 100644 --- a/addons/kestrel4500/config.cpp +++ b/addons/kestrel4500/config.cpp @@ -18,4 +18,4 @@ class CfgPatches { #include "CfgSound.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" -#include "RscTitles.hpp" \ No newline at end of file +#include "RscTitles.hpp" diff --git a/addons/kestrel4500/functions/fnc_buttonPressed.sqf b/addons/kestrel4500/functions/fnc_buttonPressed.sqf index 2edd9d17b8..df002ae2a4 100644 --- a/addons/kestrel4500/functions/fnc_buttonPressed.sqf +++ b/addons/kestrel4500/functions/fnc_buttonPressed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Handles the Kestrel 4500 dialog button actions diff --git a/addons/kestrel4500/functions/fnc_canShow.sqf b/addons/kestrel4500/functions/fnc_canShow.sqf index d577cfd4d1..c51e65b835 100644 --- a/addons/kestrel4500/functions/fnc_canShow.sqf +++ b/addons/kestrel4500/functions/fnc_canShow.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Tests if the Kestrel 4500 can be shown @@ -15,4 +15,4 @@ * Public: No */ -("ACE_Kestrel4500" in (uniformItems ACE_player)) || ("ACE_Kestrel4500" in (vestItems ACE_player)) +"ACE_Kestrel4500" in ([ACE_player] call EFUNC(common,uniqueItems)) diff --git a/addons/kestrel4500/functions/fnc_collectData.sqf b/addons/kestrel4500/functions/fnc_collectData.sqf index a05aac2667..318a5a7123 100644 --- a/addons/kestrel4500/functions/fnc_collectData.sqf +++ b/addons/kestrel4500/functions/fnc_collectData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Gathers the weather data for the Kestrel 4500 @@ -15,6 +15,8 @@ * Public: No */ +#define TEMPERATURE_SLOT_INDEX 5 + private _playerDir = getDir ACE_player; private _playerAltitude = (getPosASL ACE_player) select 2; private _temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight); @@ -41,9 +43,10 @@ if (isNil QGVAR(MIN) || isNil QGVAR(MAX)) then { [0, _playerDir] call FUNC(updateMemory); if (GVAR(MinAvgMaxMode) == 1) then { + private _useAB = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; { GVAR(ENTRIES) set [_x, (GVAR(ENTRIES) select _x) + 1]; - } count [2, 3, 4]; + } forEach [2, 3, 4]; // Wind SPD private _windSpeed = call FUNC(measureWindSpeed); @@ -51,7 +54,7 @@ if (GVAR(MinAvgMaxMode) == 1) then { // CROSSWIND private _crosswind = 0; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_useAB) then { _crosswind = abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed); } else { _crosswind = abs(sin(GVAR(RefHeading)) * _windSpeed); @@ -60,7 +63,7 @@ if (GVAR(MinAvgMaxMode) == 1) then { // HEADWIND private _headwind = 0; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_useAB) then { _headwind = cos(GVAR(RefHeading) - _playerDir) * _windSpeed; } else { _headwind = cos(GVAR(RefHeading)) * _windSpeed; @@ -74,4 +77,18 @@ if (GVAR(MinAvgMaxMode) == 1) then { GVAR(TOTAL) set [4, (GVAR(TOTAL) select 4) + _headwind]; }; -{ _x call FUNC(updateMemory); true } count [[5, _temperature],[6, _chill],[7, _humidity],[8, _heatIndex],[9, _dewPoint],[10, _wetBulb],[11, _barometricPressure],[12, _altitude],[13, _densityAltitude]]; +private _data = [ + _temperature, + _chill, + _humidity, + _heatIndex, + _dewPoint, + _wetBulb, + _barometricPressure, + _altitude, + _densityAltitude +]; + +{ + [TEMPERATURE_SLOT_INDEX + _forEachIndex, _x] call FUNC(updateMemory); +} forEach _data; diff --git a/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf b/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf index 445c6cc789..6bdaf8927a 100644 --- a/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf +++ b/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Opens the Kestrel 4500 dialog @@ -15,12 +15,10 @@ * Public: No */ -if (GVAR(Kestrel4500)) exitWith { false }; -if (underwater ACE_player) exitWith { false }; -if (!("ACE_Kestrel4500" in (uniformItems ACE_player)) && !("ACE_Kestrel4500" in (vestItems ACE_player))) exitWith { false }; +if (GVAR(Kestrel4500) || {underwater ACE_player} || {!(call FUNC(canShow))}) exitWith {false}; GVAR(Overlay) = false; -3 cutText ["", "PLAIN"]; +QGVAR(Layer) cutText ["", "PLAIN"]; GVAR(Kestrel4500) = true; createDialog 'Kestrel4500_Display'; diff --git a/addons/kestrel4500/functions/fnc_dayOfWeek.sqf b/addons/kestrel4500/functions/fnc_dayOfWeek.sqf index 932f0a72aa..f15a232a86 100644 --- a/addons/kestrel4500/functions/fnc_dayOfWeek.sqf +++ b/addons/kestrel4500/functions/fnc_dayOfWeek.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculate Current Day in the Week @@ -12,7 +12,7 @@ * Day of The Week * * Example: - * [1995, 10, 21] call ace_kestrel4500_fnc_buttonPressed + * [1995, 10, 21] call ace_kestrel4500_fnc_dayOfWeek * * Public: No */ diff --git a/addons/kestrel4500/functions/fnc_displayKestrel.sqf b/addons/kestrel4500/functions/fnc_displayKestrel.sqf index c93de715ed..ac020c800f 100644 --- a/addons/kestrel4500/functions/fnc_displayKestrel.sqf +++ b/addons/kestrel4500/functions/fnc_displayKestrel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows the Kestrel 4500 as rsc title @@ -38,11 +38,10 @@ if (GVAR(Overlay)) exitWith { GVAR(Overlay) = false; - 3 cutText ["", "PLAIN"]; + QGVAR(Layer) cutText ["", "PLAIN"]; true }; -if (underwater ACE_player) exitWith { true }; -if (!("ACE_Kestrel4500" in (uniformItems ACE_player)) && !("ACE_Kestrel4500" in (vestItems ACE_player))) exitWith { true }; +if (underwater ACE_player || {!(call FUNC(canShow))}) exitWith {true}; if (GVAR(Kestrel4500) && dialog) then { GVAR(Kestrel4500) = false; @@ -53,9 +52,9 @@ GVAR(Overlay) = true; [{ // abort condition - if (!GVAR(Overlay) || {!(("ACE_Kestrel4500" in (uniformItems ACE_player)) || ("ACE_Kestrel4500" in (vestItems ACE_player)))}) exitWith { + if (!GVAR(Overlay) || {!(call FUNC(canShow))}) exitWith { GVAR(Overlay) = false; - 3 cutText ["", "PLAIN"]; + QGVAR(Layer) cutText ["", "PLAIN"]; [_this select 1] call CBA_fnc_removePerFrameHandler; }; @@ -64,7 +63,7 @@ GVAR(Overlay) = true; private _outputData = [] call FUNC(generateOutputData); - 3 cutRsc ["RscKestrel4500", "PLAIN", 1, false]; + QGVAR(Layer) cutRsc ["RscKestrel4500", "PLAIN", 1, false]; _outputData params [ "_ctrlTop", "_ctrlCenterBig", diff --git a/addons/kestrel4500/functions/fnc_generateOutputData.sqf b/addons/kestrel4500/functions/fnc_generateOutputData.sqf index 9a9d0551fe..59bb3056dd 100644 --- a/addons/kestrel4500/functions/fnc_generateOutputData.sqf +++ b/addons/kestrel4500/functions/fnc_generateOutputData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Generates the Kestrel 4500 output text. @@ -93,7 +93,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 1: { // Direction if (!GVAR(MinAvgMax)) then { - _textCenterBig = format["%1", format["%1 %2", GVAR(Directions) select GVAR(Direction), round(_playerDir)]]; + _textCenterBig = format["%1 %2", GVAR(Directions) select GVAR(Direction), round(_playerDir)]; } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; diff --git a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf index 5dcbf681d2..9ecbca180c 100644 --- a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf +++ b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Measures the wind speed, stores the information in GVAR(MeasuredWindSpeed) and updates GVAR(ImpellerState) @@ -10,7 +10,7 @@ * wind speed * * Example: - * call ace_kestrel4500_fnc_canShow + * call ace_kestrel4500_fnc_measureWindSpeed * * Public: No */ diff --git a/addons/kestrel4500/functions/fnc_onCloseDialog.sqf b/addons/kestrel4500/functions/fnc_onCloseDialog.sqf index 8b8a88f46b..98a39f9a37 100644 --- a/addons/kestrel4500/functions/fnc_onCloseDialog.sqf +++ b/addons/kestrel4500/functions/fnc_onCloseDialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Called if Kestrel Dialog is closed diff --git a/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf b/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf deleted file mode 100644 index 09e5941a77..0000000000 --- a/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf +++ /dev/null @@ -1,19 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Ruthberg - * Called if Kestrel Display is closed - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_kestrel4500_fnc_onCloseDisplay - * - * Public: No - */ - -uiNamespace setVariable ['RscKestrel4500', nil]; -GVAR(Overlay) = false; diff --git a/addons/kestrel4500/functions/fnc_restoreUserData.sqf b/addons/kestrel4500/functions/fnc_restoreUserData.sqf index ca90f8bbcc..43953ab397 100644 --- a/addons/kestrel4500/functions/fnc_restoreUserData.sqf +++ b/addons/kestrel4500/functions/fnc_restoreUserData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Reads user data from profileNamespace @@ -10,7 +10,7 @@ * None * * Example: - * call ace_kestrel4500_fnc_restore_user_data + * call ace_kestrel4500_fnc_restoreUserData * * Public: No */ diff --git a/addons/kestrel4500/functions/fnc_storeUserData.sqf b/addons/kestrel4500/functions/fnc_storeUserData.sqf index 71338984ff..bb3cf70827 100644 --- a/addons/kestrel4500/functions/fnc_storeUserData.sqf +++ b/addons/kestrel4500/functions/fnc_storeUserData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Saves user data into profileNamespace @@ -10,7 +10,7 @@ * None * * Example: - * call ace_kestrel4500_fnc_store_user_data + * call ace_kestrel4500_fnc_storeUserData * * Public: No */ diff --git a/addons/kestrel4500/functions/fnc_updateDisplay.sqf b/addons/kestrel4500/functions/fnc_updateDisplay.sqf index 94255115db..41acd52f94 100644 --- a/addons/kestrel4500/functions/fnc_updateDisplay.sqf +++ b/addons/kestrel4500/functions/fnc_updateDisplay.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the Kestrel 4500 dialog text boxes. @@ -10,6 +10,7 @@ * None * * Example: + * None * * Public: No */ diff --git a/addons/kestrel4500/functions/fnc_updateImpellerState.sqf b/addons/kestrel4500/functions/fnc_updateImpellerState.sqf index 5692f0d276..b6e8191299 100644 --- a/addons/kestrel4500/functions/fnc_updateImpellerState.sqf +++ b/addons/kestrel4500/functions/fnc_updateImpellerState.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Updates the Kestrel 4500 Impeller state @@ -10,6 +10,7 @@ * None * * Example: + * call ace_kestrel4500_fnc_updateImpellerState * * Public: No */ diff --git a/addons/kestrel4500/functions/fnc_updateMemory.sqf b/addons/kestrel4500/functions/fnc_updateMemory.sqf index 2eff1c5a9a..c717035390 100644 --- a/addons/kestrel4500/functions/fnc_updateMemory.sqf +++ b/addons/kestrel4500/functions/fnc_updateMemory.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Update Memory of Kestrel diff --git a/addons/kestrel4500/functions/script_component.hpp b/addons/kestrel4500/functions/script_component.hpp deleted file mode 100644 index bc42218de7..0000000000 --- a/addons/kestrel4500/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\kestrel4500\script_component.hpp" diff --git a/addons/kestrel4500/initKeybinds.inc.sqf b/addons/kestrel4500/initKeybinds.inc.sqf new file mode 100644 index 0000000000..fe0c23aa18 --- /dev/null +++ b/addons/kestrel4500/initKeybinds.inc.sqf @@ -0,0 +1,58 @@ +["ACE3 Equipment", QGVAR(KestrelDialogKey), localize LSTRING(KestrelDialogKey), +{ + // Conditions: canInteract + if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if (GVAR(Kestrel4500)) exitWith { + closeDialog 0; + false + }; + // Statement + [] call FUNC(createKestrelDialog); + false +}, +{false}, +[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) + +["ACE3 Equipment", QGVAR(DisplayKestrelKey), localize LSTRING(DisplayKestrelKey), +{ + // Conditions: canInteract + if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + // Statement + [] call FUNC(displayKestrel); + false +}, +{false}, +[0, [true, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) + + +//Add deviceKey entry: +private _conditonCode = { + [] call FUNC(canShow); +}; +private _toggleCode = { + // Conditions: canInteract + if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + // Statement + if (!GVAR(Overlay)) then { + //If no overlay, show it: + [] call FUNC(displayKestrel); + } else { + //If overlay is up, switch to dialog: + [] call FUNC(createKestrelDialog); + }; +}; +private _closeCode = { + // Statement + if (GVAR(Overlay)) then { + //If dispaly is open, close it: + GVAR(Overlay) = false; + }; + if (dialog && {!isNull (uiNamespace getVariable ["Kestrel4500_Display", displayNull])}) then { + //If dialog is open, close it: + GVAR(Kestrel4500) = false; + closeDialog 0; + }; +}; +[(localize LSTRING(Name)), QPATHTOF(UI\Kestrel4500.paa), _conditonCode, _toggleCode, _closeCode] call EFUNC(common,deviceKeyRegisterNew); diff --git a/addons/kestrel4500/initKeybinds.sqf b/addons/kestrel4500/initKeybinds.sqf deleted file mode 100644 index 8be7464615..0000000000 --- a/addons/kestrel4500/initKeybinds.sqf +++ /dev/null @@ -1,58 +0,0 @@ -["ACE3 Equipment", QGVAR(KestrelDialogKey), localize LSTRING(KestrelDialogKey), -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (GVAR(Kestrel4500)) exitWith { - closeDialog 0; - false - }; - // Statement - [] call FUNC(createKestrelDialog); - false -}, -{false}, -[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) - -["ACE3 Equipment", QGVAR(DisplayKestrelKey), localize LSTRING(DisplayKestrelKey), -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - - // Statement - [] call FUNC(displayKestrel); - false -}, -{false}, -[0, [true, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) - - -//Add deviceKey entry: -private _conditonCode = { - [] call FUNC(canShow); -}; -private _toggleCode = { - // Conditions: canInteract - if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {}; - - // Statement - if (!GVAR(Overlay)) then { - //If no overlay, show it: - [] call FUNC(displayKestrel); - } else { - //If overlay is up, switch to dialog: - [] call FUNC(createKestrelDialog); - }; -}; -private _closeCode = { - // Statement - if (GVAR(Overlay)) then { - //If dispaly is open, close it: - GVAR(Overlay) = false; - }; - if (dialog && {!isNull (uiNamespace getVariable ["Kestrel4500_Display", displayNull])}) then { - //If dialog is open, close it: - GVAR(Kestrel4500) = false; - closeDialog 0; - }; -}; -[(localize LSTRING(Name)), QPATHTOF(UI\Kestrel4500.paa), _conditonCode, _toggleCode, _closeCode] call EFUNC(common,deviceKeyRegisterNew); diff --git a/addons/kestrel4500/stringtable.xml b/addons/kestrel4500/stringtable.xml index f83c875d57..50bf366fc0 100644 --- a/addons/kestrel4500/stringtable.xml +++ b/addons/kestrel4500/stringtable.xml @@ -13,9 +13,10 @@ Kestrel 4500NV Kestrel 4500NV ケストレル 4500NV - Kestrel 4500NV - 猎隼4500测风仪 + 케스트렐 4500NV + 猎隼4500 测风仪 獵隼4500測風儀 + Kestrel 4500NV Kestrel 4500 Pocket Weather Tracker @@ -28,10 +29,11 @@ Kestrel 4500 Medidor Balístico Ativo Kestrel 4500 kézi szél-és időjárásmérő Příruční meteostanice Kestrel 4500 - ケストレル 4500 携帯型風速計 - Kestrel 4500 휴대형 기상 관측기 - 猎隼4500掌上型天气追踪仪 + ケストレル 4500 携帯気象計 + 케스트렐 4500 휴대형 기상 관측기 + 猎隼4500 掌上型天气追踪仪 獵隼4500掌上型天氣追蹤儀 + Kestrel 4500 Cep Hava Durumu Izleyicisi Open Kestrel 4500 @@ -45,9 +47,10 @@ Abrir Kestrel 4500 Otevřít Kestrel 4500 Kestrel 4500 を開く - Kestrel 4500 열기 - 开启猎隼4500测风仪 + 케스트렐 4500 열기 + 开启猎隼4500 测风仪 開啟獵隼4500測風儀 + Aç Kestrel 4500 Show Kestrel 4500 @@ -61,9 +64,10 @@ Zobrazit Kestrel 4500 Mostrar Kestrel 4500 ケストレル 4500 を見る - Kestrel 4500 보이기 - 显示猎隼4500测风仪 + 케스트렐 4500 보이기 + 显示猎隼4500 测风仪 顯示獵隼4500測風儀 + Göster Kestrel 4500 Hide Kestrel 4500 @@ -77,25 +81,27 @@ Skrýt Kestrel 4500 Ocultar Kestrel 4500 Kestrel 4500 を隠す - Kestrel 4500 숨기기 - 隐藏猎隼4500测风仪 + 케스트렐 4500 숨기기 + 隐藏猎隼4500 测风仪 隱藏獵隼4500測風儀 + Gizle Kestrel 4500 Open Kestrel 4500 Otwórz Kestrel 4500 Открыть Kestrel 4500NV Ouvrir le Kestrel 4500 - Accendi Kestrel 4500 + Apri Kestrel 4500 Abrir Kestrel 4500 Kestrel 4500 öffnen Kestrel 4500 elővétele Otevřít Kestrel 4500 Abrir Kestrel 4500 ケストレル 4500 を開く - Kestrel 4500 열기 - 开启猎隼4500测风仪 + 케스트렐 4500 열기 + 开启猎隼4500 测风仪 開啟獵隼4500測風儀 + Aç Kestrel 4500 Show Kestrel 4500 @@ -109,9 +115,10 @@ Zobrazit Kestrel 4500 Mostrar Kestrel 4500 ケストレル 4500 を見る - Kestrel 4500 숨기기 - 显示猎隼4500测风仪 + 케스트렐 4500 숨기기 + 显示猎隼4500 测风仪 顯示獵隼4500測風儀 + Göster Kestrel 4500 diff --git a/addons/killtracker/$PBOPREFIX$ b/addons/killtracker/$PBOPREFIX$ new file mode 100644 index 0000000000..889d45df48 --- /dev/null +++ b/addons/killtracker/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\killtracker diff --git a/addons/killtracker/CfgEventHandlers.hpp b/addons/killtracker/CfgEventHandlers.hpp new file mode 100644 index 0000000000..4300a157b9 --- /dev/null +++ b/addons/killtracker/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/killtracker/README.md b/addons/killtracker/README.md new file mode 100644 index 0000000000..81b98a6b50 --- /dev/null +++ b/addons/killtracker/README.md @@ -0,0 +1,11 @@ +ace_killtracker +============ + +Tracks deaths/kills and logs to the end mission disaplay. +Show detailed info from player kills from ACE Medical by using `ace_killed` event. + +Note: Requires config setup in a mission, see `killtracker.inc` - has no effect if mission is not setup correctly. + +## ACEX Conversion - things still using acex prefix +- Global Var `acex_killTracker_outputText` +- `acex_killTracker` classname for `CfgDebriefingSections` diff --git a/addons/killtracker/XEH_postInit.sqf b/addons/killtracker/XEH_postInit.sqf new file mode 100644 index 0000000000..35050d1dc3 --- /dev/null +++ b/addons/killtracker/XEH_postInit.sqf @@ -0,0 +1,154 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Tracks deaths/kills and logs to the end mission disaplay + * Attemps to log kills from Medical by using "ace_killed" event. + * + * Note: Requires config setup in a mission's description.ext + * Has no effect if mission is not setup correctly. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No + */ + +if ((getText (missionconfigfile >> "CfgDebriefingSections" >> QUOTE(XADDON) >> "variable")) != QXGVAR(outputText)) exitWith { + TRACE_1("no mission debriefing config",_this); +}; + +if !(GETEGVAR(medical,enabled,false)) exitWith { + WARNING("No ACE-Medical"); + XGVAR(outputText) = "No ACE-Medical"; +}; + +private _global = missionNamespace getVariable [QGVAR(globalSync), false]; // Global Sync (e.g. for spectator) +INFO_1("Running Kill Tracking [Global: %1]",_global); + +// Variables: +GVAR(eventsArray) = []; +XGVAR(outputText) = format ["%1 0", LLSTRING(TotalKills)]; +GVAR(killCount) = 0; + +// Add Event Handlers: +[QGVAR(kill), { + params ["_name", "_killInfo"]; + TRACE_2("kill eh",_name,_killInfo); + // Increment kill counter + GVAR(killCount) = GVAR(killCount) + 1; + GVAR(eventsArray) pushBack format [LLSTRING(Kill), _name, _killInfo]; + XGVAR(outputText) = (format ["%1 %2
", LLSTRING(TotalKills), GVAR(killCount)]) + (GVAR(eventsArray) joinString "
"); + if (missionNamespace getVariable [QGVAR(globalSync), false]) then { + ACE_player setVariable [QGVAR(output), XGVAR(outputText), true]; + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(death), { + params ["_name", "_killInfo"]; + TRACE_2("death eh",_name,_killInfo); + GVAR(eventsArray) pushBack format [LLSTRING(Killer), _name, _killInfo]; + XGVAR(outputText) = (format ["%1 %2
", LLSTRING(TotalKills), GVAR(killCount)]) + (GVAR(eventsArray) joinString "
"); + if (missionNamespace getVariable [QGVAR(globalSync), false]) then { + ACE_player setVariable [QGVAR(output), XGVAR(outputText), true]; + }; +}] call CBA_fnc_addEventHandler; + +["ace_killed", { + params ["_unit", "_causeOfDeath", "_killer", "_instigator"]; + TRACE_4("ace_killed EH",_unit,_causeOfDeath,_killer,_instigator); + + if (!local _unit) exitWith {}; + + private _killInfo = []; + + if (!isNull _killer) then { + if !(_killer isKindof "CAManBase") then { // If killer is a vehicle log the vehicle type + _killInfo pushBack format [LLSTRING(Vehicle), getText ((configOf _killer) >> "displayName")]; + }; + if (isNull _instigator) then { + _instigator = effectiveCommander _killer; + TRACE_2("using effectiveCommander",_instigator,_killer); + }; + }; + private _unitIsPlayer = hasInterface && {_unit in [player, ace_player]}; // isPlayer check will fail at this point + private _instigatorIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; + TRACE_2("",_unitIsPlayer,_instigatorIsPlayer); + + // Don't do anything if neither are players + if !(_unitIsPlayer || _instigatorIsPlayer) exitWith {}; + + // Log firendly fire + private _fnc_getSideFromConfig = { + params ["_object"]; + switch (getNumber ((configOf _object) >> "side")) do { + case (0): {east}; + case (1): {west}; + case (2): {resistance}; + default {civilian}; + }; + }; + if (!isNull _instigator && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { + // Because of unconscious group switching/captives it's probably best to just use unit's config side + private _unitSide = [_unit] call _fnc_getSideFromConfig; + private _killerSide = [_instigator] call _fnc_getSideFromConfig; + if ([_unitSide, _killerSide] call BIS_fnc_areFriendly) then { + _killInfo pushBack format["%1", LLSTRING(FriendlyFire)]; + }; + }; + + // Rough cause of death from statemachine (e.g. "CardiacArrest:Timeout"), could parse this to be more human readable + _killInfo pushBack _causeOfDeath; + + // Parse info into text + _killInfo = if (_killInfo isEqualTo []) then { + "" + } else { + format [" - [%1]", (_killInfo joinString ", ")]; + }; + + // If unit was player then send event to self + if (_unitIsPlayer) then { + private _instigatorName = "Self?"; + if ((!isNull _instigator) && {_unit != _instigator}) then { + if (_instigatorIsPlayer) then { + _instigatorName = [_instigator, true, false] call EFUNC(common,getName); + } else { + _instigatorName = _instigator getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) + if (_instigatorName == "") then { + _instigatorName = format ["*AI* - %1", getText ((configOf _instigator) >> "displayName")]; + }; + }; + }; + TRACE_3("send death event",_unit,_instigatorName,_killInfo); + [QGVAR(death), [_instigatorName, _killInfo]] call CBA_fnc_localEvent; + }; + + // If shooter was player then send event to them (and optionally the whole crew) + if (_instigatorIsPlayer && {_unitIsPlayer || GVAR(trackAI)}) then { + private _unitName = ""; + if (_unitIsPlayer) then { + _unitName = [_unit, true, false] call EFUNC(common,getName); // should be same as profileName + } else { + _unitName = _unit getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) + if (_unitName == "") then { + _unitName = format ["*AI* - %1", getText ((configOf _unit) >> "displayName")]; + }; + }; + TRACE_3("send kill event",_instigator,_unitName,_killInfo); + [QGVAR(kill), [_unitName, _killInfo], _instigator] call CBA_fnc_targetEvent; + + if (GVAR(showCrewKills) && {!(_killer isKindOf "CAManBase")}) then { + private _crew = [driver _killer, gunner _killer, commander _killer] - [_instigator]; + _crew = _crew select {[_x] call EFUNC(common,isPlayer)}; + _crew = _crew arrayIntersect _crew; + TRACE_1("showCrewKills",_crew); + _killInfo = format [" - [%1, %2", localize "str_a3_rscdisplaygarage_tab_crew", _killInfo select [4]]; + { + [QGVAR(kill), [_unitName, _killInfo], _x] call CBA_fnc_targetEvent; + } forEach _crew; + }; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/killtracker/XEH_preInit.sqf b/addons/killtracker/XEH_preInit.sqf new file mode 100644 index 0000000000..7c7b764686 --- /dev/null +++ b/addons/killtracker/XEH_preInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +ADDON = false; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/killtracker/config.cpp b/addons/killtracker/config.cpp new file mode 100644 index 0000000000..7cda7110d4 --- /dev/null +++ b/addons/killtracker/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[]= {"PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" diff --git a/addons/killtracker/initSettings.inc.sqf b/addons/killtracker/initSettings.inc.sqf new file mode 100644 index 0000000000..9e4775bd7f --- /dev/null +++ b/addons/killtracker/initSettings.inc.sqf @@ -0,0 +1,17 @@ +[ + QGVAR(trackAI), + "CHECKBOX", + [LSTRING(TrackAI_DisplayName), LSTRING(TrackAI_Description)], + LSTRING(Category), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(showCrewKills), + "CHECKBOX", + [LSTRING(showCrewKills_DisplayName), LSTRING(showCrewKills_Description)], + LSTRING(Category), + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/killtracker/killtracker.inc b/addons/killtracker/killtracker.inc new file mode 100644 index 0000000000..003537177f --- /dev/null +++ b/addons/killtracker/killtracker.inc @@ -0,0 +1,20 @@ +/* + * Author: Freddo, PabstMirror + * + * Creates a killtracker debriefing section, displayed at the end mission debriefing screen. + * Include this file in description.ext of your mission. + * + * Example: + * class CfgDebriefingSections { + * #if __has_include("\z\ace\addons\killtracker\killtracker.inc") + * #include "\z\ace\addons\killtracker\killtracker.inc" + * #endif + * }; + * + * Public: Yes + */ + +class acex_killTracker { + title = "$STR_ACE_KillTracker_Title"; + variable = "acex_killTracker_outputText"; +}; diff --git a/addons/killtracker/script_component.hpp b/addons/killtracker/script_component.hpp new file mode 100644 index 0000000000..2195faa79f --- /dev/null +++ b/addons/killtracker/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT killtracker +#define COMPONENT_BEAUTIFIED KillTracker +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_KILLTRACKER + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_KILLTRACKER + #define DEBUG_SETTINGS DEBUG_SETTINGS_KILLTRACKER +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml new file mode 100644 index 0000000000..b7a97df15a --- /dev/null +++ b/addons/killtracker/stringtable.xml @@ -0,0 +1,137 @@ + + + + + ACE Kill Tracker + ACE Tracciatore di Uccisioni + ACE Kill Tracker + ACE Отслеживание убийств + ACE キル追跡 + ACE 킬트래커 + ACE Suivi des morts + ACE Abschüsse + ACE Contador de Muertes + + + ACE Killed Events + ACE キルイベント + ACE Abschusszähler + ACE Eventi di Morte + ACE Licznik Zabójstw + ACE 击杀事件 + ACE 사살 이벤트 + ACE Счётчик убийств + ACE Eventos de Muertes + ACE Evénements Morts + ACE Contagem de Abates + + + Total Kills: + Всего убийств: + Liczba zabójstw: + Toplam Öldürme: + 合計キル数: + Gesammte Abschüsse: + Uccisioni Totali: + 总击杀数: + 총 사살수: + Muertes totales: + Total de morts : + Abates totais: + + + Kill: %1 %2 + Убил: %1 %2 + Zabójstwo: %1 %2 + Öldürülen: %1 %2 + 殺害: %1 %2 + Abschuss: %1 %2 + Uccisione: %1 %2 + 击杀:%1 %2 + 사살: %1 %2 + Muertes: %1 %2 + Meurtre : %1 %2 + Abate: %1 %2 + + + Killer: %1 %2 + Убийца: %1 %2 + Zabójca: %1 %2 + Öldüren: %1 %2 + 殺害者: %1 %2 + Täter: %1 %2 + Uccisore: %1 %2 + 击杀者:%1 %2 + 사살자: %1 %2 + Asesino: %1 %2 + Tueur : %1 %2 + Assassino: %1 %2 + + + Vehicle: %1 + Техника: %1 + Pojazd: %1 + Araç :%1 + 車両: %1 + Fahrzeuge: %1 + Veicoli: %1 + 载具:%1 + 차량: %1 + Vehículo: %1 + Véhicule : %1 + Veículo: %1 + + + Friendly Fire + 誤擊友方 + Tir fratricide + Fuego aliado + Fuoco amico + Ostrzał sojuszniczy + Дружественный огонь + Teambeschuss + Střelba do vlastních! + Fogo amigo + 아군 오인사격 + 友军误击 + 同士討ち + Dost Atışı + + + Track AI units killed by player + Traccia IA uccise da giocatori + Sledovat AI zabité hráči + Отслеживание юнитов ИИ, убитых игроком + プレイヤーがキルしたAIユニットを追跡 + 플레이어가 죽인 AI 트래킹 + Suivi de l'IA tuée par les joueurs + Zähle vom Spieler getöteten KI-Einheiten + Cuenta las unidades de IA matadas por el jugador + + + Defines if killed AIs will be shown in the kill tracker during mission debriefing. + Determina se IA uccise verranno visualizzate nel tracciatore durante il debriefing della missione. + Udává zdali se zabité AI budou ukazovat v kill trackeru v průběhu debriefingu po misi. + Определяет, будут ли убитые ИИ отображаться в трекере убийств во время дебрифинга миссии. + キルしたAIをミッション終了デブリーフィング画面に表示させるかどうかを定義します。 + 사후강평 중 살해된 AI가 킬트래킹에 표시되는지 여부를 정의합니다. + Définit si les IA tuées seront affichées dans le tracker pendant le débriefing de la mission. + Legt fest, ob getötete KIs während des Endbildschirms der Mission in den Abschüssen angezeigt werden. + Define si las IAs matadas se mostrarán en el contador de muertes en el debiefring de la misión. + + + Show vehicle kills to other crew members + Показать уничтоженные машины другим членам экипажа + Zeige der Fahrzeugbesatzung die Abschüsse des Fahrzeugs + Mostra uccisioni del veicolo a membri dell'equipaggio + 車両でのキルを乗員全員に表示する + + + Show kills from a vehicle to driver, gunner and commander + Показать уничтоженную технику водителю, стрелку и командиру + Zeige Abschüsse des Fahrzeugs dem Fahrer, Richtschützen und Kommandanten an + Mostra uccisioni del veicolo al pilota, artigliere e comandante + 車両でのキルを操縦手、砲手、車長で共有して表示する + + + diff --git a/addons/laser/ACE_Settings.hpp b/addons/laser/ACE_Settings.hpp index 3584a2086f..e9755d3bb5 100644 --- a/addons/laser/ACE_Settings.hpp +++ b/addons/laser/ACE_Settings.hpp @@ -1,8 +1,5 @@ class ACE_Settings { class GVAR(dispersionCount) { - value = 2; - typeName = "SCALAR"; - displayName = CSTRING(dispersionCount_displayName); - sliderSettings[] = {0, 5, 2, -1}; + movedToSQF = 1; }; }; diff --git a/addons/laser/CfgEventhandlers.hpp b/addons/laser/CfgEventhandlers.hpp index 0e652d2459..a4f59670a9 100644 --- a/addons/laser/CfgEventhandlers.hpp +++ b/addons/laser/CfgEventhandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/laser/CfgWeapons.hpp b/addons/laser/CfgWeapons.hpp index 385f842a59..ced98b9592 100644 --- a/addons/laser/CfgWeapons.hpp +++ b/addons/laser/CfgWeapons.hpp @@ -1,7 +1,7 @@ class CfgWeapons { class Binocular; - class Laserdesignator : Binocular { + class Laserdesignator: Binocular { visionMode[] = {"Normal","NVG"}; }; }; diff --git a/addons/laser/README.md b/addons/laser/README.md index 64ea8fe045..a47c15f3a1 100644 --- a/addons/laser/README.md +++ b/addons/laser/README.md @@ -2,13 +2,3 @@ ace_laser ========= Contains various functions necessary for the realistic portrayal of laser mechanics in other components. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [walterpearce](https://github.com/walterpearce) -- [NouberNou](https://github.com/NouberNou) -- [esteldunedain](https://github.com/esteldunedain) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/laser/RscInGameUI.hpp b/addons/laser/RscInGameUI.hpp index 16d3dfcd91..753564385c 100644 --- a/addons/laser/RscInGameUI.hpp +++ b/addons/laser/RscInGameUI.hpp @@ -1,125 +1,26 @@ class RscInGameUI { class RscOptics_LaserDesignator { - idd = 300; - controls[] = {"CA_IGUI_elements_group"}; - - onLoad = "uiNameSpace setVariable ['ACE_RscOptics_LaserDesignator',(_this select 0)];"; - onUnload = "uiNameSpace setVariable ['ACE_RscOptics_LaserDesignator',nil];"; - class CA_IGUI_elements_group: RscControlsGroup { - idc = 170; - - x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; - y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; - w = "53.5 * (0.01875 * SafezoneH)"; - h = "40 * (0.025 * SafezoneH)"; - class VScrollbar: VScrollbar { - width = 0; - }; - class HScrollbar: HScrollbar { - height = 0; - }; class controls { - class CA_OpticsZoom: RscText { - idc = 180; - style = 1; - colorText[] = {0.706,0.0745,0.0196,1}; - sizeEx = "0.038*SafezoneH"; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "4.5"; - x = "43.85 * (0.01875 * SafezoneH)"; - y = "19.6 * (0.025 * SafezoneH)"; - w = "4.5 * (0.01875 * SafezoneH)"; - h = "1.1 * (0.025 * SafezoneH)"; - }; - class ACE_Distance: RscText { - idc = 123002; - style = 0; - sizeEx = "0.038*SafezoneH"; - colorText[] = {0.706,0.0745,0.0196,1}; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "2456"; - x = "24.6 * (0.01875 * SafezoneH)"; - y = "3 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.5 * (0.025 * SafezoneH)"; - }; + // Hide the vanilla distance display class CA_Distance: RscText { - idc = 151; - style = 0; - sizeEx = "0.038*SafezoneH"; - colorText[] = {0.706,0.0745,0.0196,1}; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "2456"; - x = 0; - y = 0; - w = 0; - h = 0; + idc = IDC_LASERDESIGNATOR_DISTANCE; // Purposeful overwrite, makes range update constantly, do not remove + fade = 1; + colorText[] = {0,0,0,0}; // fade doesn't work in some cases (e.g. controlling remote designator uav) }; - class CA_Elev: RscText { - idc = 175; - style = 1; - sizeEx = "0.038*SafezoneH"; + class ACE_Distance: CA_Distance { + idc = IDC_LASERDESIGNATOR_ACEDISTANCE; + fade = 0; colorText[] = {0.706,0.0745,0.0196,1}; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "80.5"; - x = "32.7 * (0.01875 * SafezoneH)"; - y = "3 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "1.5 * (0.025 * SafezoneH)"; }; - class CA_VisionMode: RscText { - idc = 179; - style = 0; - sizeEx = "0.038*SafezoneH"; - colorText[] = {0.706,0.0745,0.0196,1}; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "VIS"; - x = "6.5 * (0.01875 * SafezoneH)"; - y = "19.6 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.1 * (0.025 * SafezoneH)"; - }; - class CA_Laser: RscText { - idc = 158; - style = "0x30 + 0x800"; - sizeEx = "0.038*SafezoneH"; - colorText[] = {0.706,0.0745,0.0196,1}; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "\A3\ui_f\data\igui\rscingameui\rscoptics\laser_designator_iconLaserOn.paa"; - x = "29.2 * (0.01875 * SafezoneH)"; - y = "3 * (0.025 * SafezoneH)"; - w = "3.5 * (0.01875 * SafezoneH)"; - h = "1.5 * (0.025 * SafezoneH)"; - }; - class CA_Heading: RscText { - idc = 156; - style = 0; - sizeEx = "0.038*SafezoneH"; - colorText[] = {0.706,0.0745,0.0196,1}; - shadow = 0; - font = "EtelkaMonospacePro"; - text = "023"; - x = "16.1 * (0.01875 * SafezoneH)"; - y = "3 * (0.025 * SafezoneH)"; - w = "3.5 * (0.01875 * SafezoneH)"; - h = "1.6 * (0.025 * SafezoneH)"; - }; - - class ACE_LaserCode_Helper : RscMapControl { + class ACE_LaserCode_Helper: RscMapControl { idc = -1; onDraw = QUOTE(_this call FUNC(onLaserDesignatorDraw)); w = 0; h = 0; }; - class ACE_LaserCode : RscText { - idc = 123001; + class ACE_LaserCode: RscText { + idc = IDC_LASERDESIGNATOR_LASERCODE; style = 0; sizeEx = "0.038*SafezoneH"; colorText[] = {0.706,0.0745,0.0196,1}; diff --git a/addons/laser/XEH_PREP.hpp b/addons/laser/XEH_PREP.hpp index 6af5643e23..2d26ff81f2 100644 --- a/addons/laser/XEH_PREP.hpp +++ b/addons/laser/XEH_PREP.hpp @@ -1,16 +1,21 @@ PREP(addLaserTarget); +PREP(addMapHandler); PREP(dev_drawVisibleLaserTargets); PREP(findLaserSource); +PREP(getLaserCode); PREP(handleLaserTargetCreation); PREP(keyLaserCodeChange); PREP(laserOff); PREP(laserOn); +PREP(laserPointTrack); PREP(laserTargetPFH); PREP(onLaserDesignatorDraw); PREP(rotateVectLine); PREP(rotateVectLineGetMap); PREP(seekerFindLaserSpot); +PREP(setLaserCode); PREP(shootCone); PREP(shootRay); PREP(showVehicleHud); +PREP(toggleLST); diff --git a/addons/laser/XEH_postInit.sqf b/addons/laser/XEH_postInit.sqf index 709682853b..768752bee2 100644 --- a/addons/laser/XEH_postInit.sqf +++ b/addons/laser/XEH_postInit.sqf @@ -1,11 +1,19 @@ #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" if (hasInterface) then { -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" GVAR(pfID) = -1; - ["ace_settingsInitialized", { + ["CBA_settingsInitialized", { + // Handle Map Drawing + GVAR(mapLaserSource) = objNull; + ["ACE_controlledUAV", LINKFUNC(addMapHandler)] call CBA_fnc_addEventHandler; + ["turret", LINKFUNC(addMapHandler), false] call CBA_fnc_addPlayerEventHandler; + ["unit", LINKFUNC(addMapHandler), true] call CBA_fnc_addPlayerEventHandler; + + // Laser code display ["turret", LINKFUNC(showVehicleHud), false] call CBA_fnc_addPlayerEventHandler; ["vehicle", LINKFUNC(showVehicleHud), true] call CBA_fnc_addPlayerEventHandler; // only one of these needs the retro flag @@ -26,27 +34,61 @@ if (hasInterface) then { ["ace_laserOn", { params ["_uuid", "_args"]; TRACE_2("ace_laserOn eh",_uuid,_args); - [GVAR(laserEmitters), _uuid, _args] call CBA_fnc_hashSet; + + GVAR(laserEmitters) set [_uuid, _args]; + private _unit = _args select 0; + if (local _unit && {hasPilotCamera _unit}) then { + [_unit] call FUNC(laserPointTrack); + }; }] call CBA_fnc_addEventHandler; ["ace_laserOff", { params ["_uuid"]; TRACE_1("ace_laserOn eh",_uuid); - if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then { - [GVAR(laserEmitters), _uuid] call CBA_fnc_hashRem; - }; + GVAR(laserEmitters) deleteAt _uuid; }] call CBA_fnc_addEventHandler; [QGVAR(updateCode), { params ["_uuid", "_newCode"]; TRACE_2("ace_laser_updateCode eh",_uuid,_newCode); - if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then { - private _laserArray = [GVAR(laserEmitters), _uuid] call CBA_fnc_hashGet; + if (_uuid in GVAR(laserEmitters)) then { + private _laserArray = GVAR(laserEmitters) get _uuid; TRACE_2("updating",_newCode,_laserArray select 4); _laserArray set [4, _newCode]; }; }] call CBA_fnc_addEventHandler; +["Air", "init", { + params ["_unit"]; + if (hasPilotCamera _unit) then { + if (!alive _unit) exitWith {}; + // some helicopters just have a static downward camera for cargo loading + if ((getNumber ((configOf _unit) >> "pilotCamera" >> "controllable")) == 0) exitWith {}; + + _unit setVariable [QGVAR(hasLaserSpotTracker), true]; + _unit setVariable [QGVAR(laserSpotTrackerOn), false]; + + private _condition = { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + (_player == driver _target) + && {(_target getVariable [QGVAR(laserSpotTrackerOn), false])} + && {[_player, _target, []] call EFUNC(common,canInteractWith)} + }; + private _actionOff = ["LSTOff", localize LSTRING(LSTOff), "", {[_this select 0] call FUNC(toggleLST)}, _condition] call EFUNC(interact_menu,createAction); + [_unit, 1, ["ACE_SelfActions"], _actionOff] call EFUNC(interact_menu,addActionToObject); + + private _condition = { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + (_player == driver _target) + && {!(_target getVariable [QGVAR(laserSpotTrackerOn), false])} + && {[_player, _target, []] call EFUNC(common,canInteractWith)} + }; + private _actionOn = ["LSTOn", localize LSTRING(LSTOn), "", {[_this select 0] call FUNC(toggleLST)}, _condition] call EFUNC(interact_menu,createAction); + [_unit, 1, ["ACE_SelfActions"], _actionOn] call EFUNC(interact_menu,addActionToObject); + }; +}, true, [], true] call CBA_fnc_addClassEventHandler; + + // Shows detector and mine posistions in 3d when debug is on #ifdef DRAW_LASER_INFO addMissionEventHandler ["Draw3D", {_this call FUNC(dev_drawVisibleLaserTargets)}]; diff --git a/addons/laser/XEH_preInit.sqf b/addons/laser/XEH_preInit.sqf index 2c4e7c7f4f..00049594c6 100644 --- a/addons/laser/XEH_preInit.sqf +++ b/addons/laser/XEH_preInit.sqf @@ -11,8 +11,10 @@ ACE_DEFAULT_LASER_CODE = 1111; ACE_DEFAULT_LASER_WAVELENGTH = 1550; ACE_DEFAULT_LASER_BEAMSPREAD = 1; -GVAR(laserEmitters) = [] call CBA_fnc_hashCreate; +GVAR(laserEmitters) = createHashMap; GVAR(trackedLaserTargets) = []; GVAR(pfehID) = -1; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/laser/config.cpp b/addons/laser/config.cpp index fb6ae5e638..5bd8bf8548 100644 --- a/addons/laser/config.cpp +++ b/addons/laser/config.cpp @@ -13,15 +13,13 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" +#include "ACE_Settings.hpp" #include "CfgEventhandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" class RscControlsGroup; -class VScrollbar; -class HScrollbar; class RscText; class RscMapControl; class RscControlsGroupNoScrollbars; diff --git a/addons/laser/functions/fnc_addLaserTarget.sqf b/addons/laser/functions/fnc_addLaserTarget.sqf index 2cf99a5311..3fc02b2189 100644 --- a/addons/laser/functions/fnc_addLaserTarget.sqf +++ b/addons/laser/functions/fnc_addLaserTarget.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Adds a vanilla laser target to the tracker PFH and globaly turns it on @@ -55,5 +55,5 @@ TRACE_1("",GVAR(trackedLaserTargets)); if (GVAR(pfehID) == -1) then { TRACE_1("starting pfeh",count GVAR(trackedLaserTargets)); - GVAR(pfehID) = [DFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; + GVAR(pfehID) = [LINKFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/laser/functions/fnc_addMapHandler.sqf b/addons/laser/functions/fnc_addMapHandler.sqf new file mode 100644 index 0000000000..7e10122c05 --- /dev/null +++ b/addons/laser/functions/fnc_addMapHandler.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Add laser drawing to map + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_laser_fnc_addMapHandler + * + * Public: No + */ +TRACE_3("addMapHandler",ace_player,typeOf vehicle ace_player,ACE_controlledUAV); + +GVAR(mapLaserSource) = call { + if (GVAR(showLaserOnMap) == 0) exitWith { + TRACE_1("setting - disabled",GVAR(showLaserOnMap)); + objNull + }; + if (alive (ACE_controlledUAV # 0)) exitWith { + TRACE_1("using UAV",objNull); + ACE_controlledUAV # 0; + }; + if (GVAR(showLaserOnMap) == 1) exitWith { + TRACE_1("setting - no UAV",GVAR(showLaserOnMap)); + objNull + }; + private _player = ace_player; + private _vehicle = vehicle _player; + if ((_player != _vehicle) && {_player in [gunner _vehicle, commander _vehicle]}) exitWith { + TRACE_1("using player's vehicle",_vehicle); + _vehicle + }; + if (GVAR(showLaserOnMap) == 2) exitWith { + TRACE_1("setting - no UAV or vehicle",GVAR(showLaserOnMap)); + objNull + }; + TRACE_1("using player",_player); + _player +}; + +if (!alive GVAR(mapLaserSource)) exitWith {}; + +[{!isNull findDisplay 12}, // for some reason the display is null for the frame when starting to control drone +{ + private _map = ((findDisplay 12) displayCtrl 51); + private _ehID = _map getVariable [QGVAR(ehID), -1]; + if (_ehID > -1) exitWith {}; + _ehID = _map ctrlAddEventHandler ["Draw", { + if (!alive GVAR(mapLaserSource)) exitWith {}; + private _laserTarget = laserTarget GVAR(mapLaserSource); + if (!alive _laserTarget) exitWith {}; + + params ["_map"]; + _map drawLine [getPos _laserTarget, getPos GVAR(mapLaserSource), [1,0,0,0.333]]; + _map drawIcon [ + "\A3\ui_f\data\igui\rscingameui\rscoptics\laser_designator_iconLaserOn.paa", + [1,0,1,1], + (getPos _laserTarget), + 16, 16, + ((getDir _laserTarget) + 90) + ]; + }]; + TRACE_2("added map drawEH",_map,_ehID); + _map setVariable [QGVAR(ehID), _ehID]; +}, []] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf b/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf index 4613f510ef..4c57a61325 100644 --- a/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf +++ b/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team @@ -18,7 +18,7 @@ // Dev Debug Function -// Displays lasers and attempts to lock on to codes 1111 and 1112 from a target vehicle's view +// Displays lasers and attempts to lock on to codes 1111 and 1688 from a target vehicle's view // On Screen Debug: // Red - Vanilla Laser Targets // Yellow - Array (vehicle pos/weapon) Laser Targets @@ -27,25 +27,25 @@ // Try searching for lasers from a given vehicle position [BLUE]: private _seekerVehicle = vehicle ace_player; -private _testSeekerPosASL = AGLtoASL (_seekerVehicle modelToWorldVisual [0,0,1]); +private _testSeekerPosASL = _seekerVehicle modelToWorldVisualWorld [0,0,1]; private _testSeekerDir = vectorDirVisual _seekerVehicle; { private _code = _x; - private _results = [_testSeekerPosASL, _testSeekerDir, 45, 10000, [1550,1550], _code, _seekerVehicle] call FUNC(seekerFindLaserSpot); + private _results = [_testSeekerPosASL, _testSeekerDir, 45, 10000, [ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH], _code, _seekerVehicle] call FUNC(seekerFindLaserSpot); private _resultPos = _results select 0; if (!isNil "_resultPos") then { // Draw lock results drawLine3D [ASLtoAGL _testSeekerPosASL, ASLtoAGL _resultPos, [0,0,1,1]]; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [0,0,1,1], (ASLtoAGL _resultPos), 1.5, 1.5, 45, format ["%1 from %2", _code, _results select 1], 0.5, 0.025, "TahomaB"]; }; -} forEach [1111, 1112]; // Scan at codes 1111 and 1112 +} forEach [ACE_DEFAULT_LASER_CODE, 1688]; // Scan at codes 1111 and 1688 // Draw all lasers -[GVAR(laserEmitters), { - //IGNORE_PRIVATE_WARNING ["_key", "_value"]; - // TRACE_2("",_key,_value); - _value params ["_obj", "_owner", "_laserMethod", "_waveLength", "_laserCode", "_beamSpread"]; +{ + //IGNORE_PRIVATE_WARNING ["_x", "_y]; + // TRACE_2("",_x,_y); + _y params ["_obj", "_owner", "_laserMethod", "_waveLength", "_laserCode", "_beamSpread"]; // Draw vanila lasers [RED] if (_laserMethod isEqualTo QFUNC(findLaserSource)) then { // Normal vanilla laserTarget func @@ -53,7 +53,7 @@ private _testSeekerDir = vectorDirVisual _seekerVehicle; private _targetPosASL = getPosASL _targetObject; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _targetPosASL), 0.5, 0.5, 0, "", 0.5, 0.025, "TahomaB"]; - (_value call FUNC(findLaserSource)) params ["_laserPosASL", "_laserDir"]; + (_y call FUNC(findLaserSource)) params ["_laserPosASL", "_laserDir"]; private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay); private _rayPos = _resultsRay select 0; @@ -67,7 +67,7 @@ private _testSeekerDir = vectorDirVisual _seekerVehicle; // Draw array weapon lasers [YELLOW] if ((_laserMethod isEqualType []) && {(count _laserMethod) == 2}) then { _laserMethod params ["_modelPosition", "_weaponName"]; - private _laserPosASL = AGLtoASL (_obj modelToWorldVisual _modelPosition); + private _laserPosASL = _obj modelToWorldVisualWorld _modelPosition; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,1,0,1], (ASLtoAGL _laserPosASL), 0.5, 0.5, 0, _weaponName, 0.5, 0.025, "TahomaB"]; private _laserDir = _obj weaponDirection _weaponName; private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay); @@ -76,4 +76,4 @@ private _testSeekerDir = vectorDirVisual _seekerVehicle; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,1,0,1], (ASLtoAGL _rayPos), 2, 2, 0, _weaponName, 0.5, 0.025, "TahomaB"]; }; }; -}] call CBA_fnc_hashEachPair; +} forEach GVAR(laserEmitters); diff --git a/addons/laser/functions/fnc_findLaserSource.sqf b/addons/laser/functions/fnc_findLaserSource.sqf index dcb137fb69..9e90ef8ad7 100644 --- a/addons/laser/functions/fnc_findLaserSource.sqf +++ b/addons/laser/functions/fnc_findLaserSource.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Handler function for finding position and direction of a vanilla laser. @@ -6,7 +6,7 @@ * Arguments: * 0: Vehicle (shooter of laser) * 6: Method Args - * 0: Laser Source selection on Vehicle + * - 0: Laser Source selection on Vehicle * * Return Value: * [position, direction] @@ -28,7 +28,7 @@ if (surfaceIsWater _targetPos && {(_targetPos select 2) < 0}) then { _targetPos set [2, 0.25]; }; -private _povPos = AGLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition _ownerSelection)); +private _povPos = _vehicle modelToWorldVisualWorld (_vehicle selectionPosition _ownerSelection); private _povDir = _povPos vectorFromTo _targetPos; TRACE_4("",_vehicle,_targetObject,_povPos,_povDir); diff --git a/addons/laser/functions/fnc_getLaserCode.sqf b/addons/laser/functions/fnc_getLaserCode.sqf new file mode 100644 index 0000000000..0a0fce363f --- /dev/null +++ b/addons/laser/functions/fnc_getLaserCode.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Gets the laser code of a laser source. + * + * Argument: + * 0: Laser source + * + * Return Value: + * Laser code + * + * Example: + * player call ace_laser_fnc_getLaserCode; + * + * Public: Yes + */ + +params [["_laserSource", objNull, [objNull]]]; + +if (isNull _laserSource) exitWith { + -1 +}; + +_laserSource getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE] diff --git a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf index c619024ed4..bd42a3e5a5 100644 --- a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf +++ b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Associates a newly created laser target to it's owner @@ -24,13 +24,13 @@ TRACE_1("params",_this); private _owners = allUnits select {(lasertarget _x) == _targetObject}; if (count _owners == 1) exitWith { - TRACE_2("Laser target owner [allUnits]", _targetObject, _owners select 0); + TRACE_2("Laser target owner [allUnits]",_targetObject,_owners select 0); [_targetObject, _owners select 0] call FUNC(addLaserTarget); }; _owners = vehicles select {(lasertarget _x) == _targetObject}; if (count _owners == 1) exitWith { - TRACE_2("Laser target owner [vehicles]", _targetObject, _owners select 0); + TRACE_2("Laser target owner [vehicles]",_targetObject,_owners select 0); [_targetObject, _owners select 0] call FUNC(addLaserTarget); }; @@ -42,7 +42,7 @@ TRACE_1("params",_this); if ((alive ACE_player) && {_vehicle != ACE_player}) then { private _turretPath = if (ACE_player == (driver _vehicle)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; TRACE_1("",_turretPath); - if (!(_turretPath isEqualTo [])) then { + if (_turretPath isNotEqualTo []) then { private _currentWeapon = _vehicle currentWeaponTurret _turretPath; TRACE_1("",_currentWeapon); if ((getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> "laser")) == 1) then { @@ -58,7 +58,7 @@ TRACE_1("params",_this); }; }; if (!_foundSource) then { - WARNING_1("Laser target doesn't have owner", _targetObject); + WARNING_1("Laser target doesn't have owner",_targetObject); }; }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/laser/functions/fnc_keyLaserCodeChange.sqf b/addons/laser/functions/fnc_keyLaserCodeChange.sqf index 32d9151083..1477fe75c1 100644 --- a/addons/laser/functions/fnc_keyLaserCodeChange.sqf +++ b/addons/laser/functions/fnc_keyLaserCodeChange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Change the laser key code (both seeker and transmitter) @@ -40,20 +40,37 @@ if (isNull (ACE_controlledUAV param [0, objNull])) then { }; TRACE_2("",_currentShooter,_currentWeapon); -if (((getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> "laser")) == 0) && - {(getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(canSelect))) == 0}) exitWith {false}; +private _currentWeaponCfg = configFile >> "CfgWeapons" >> _currentWeapon; +if ( + (getNumber (_currentWeaponCfg >> "laser") == 0) && + { + !(_currentShooter getVariable [QGVAR(hasLaserSpotTracker), false]) && + {(getNumber (_currentWeaponCfg >> QGVAR(canSelect))) == 0} + } +) exitWith {false}; private _oldLaserCode = _currentShooter getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; -private _newLaserCode = _oldLaserCode; +private _newLaserCode = 0; // "Four-digit code equipment settings range from 1111 to 1788" // While there is a 0 or 9 in code, keep adding change -if (((_codeChange < 0) && {_oldLaserCode > ACE_DEFAULT_LASER_CODE}) || {(_codeChange > 0) && {_oldLaserCode < 1788}}) then { - _newLaserCode = _oldLaserCode + _codeChange; - while {(((str _newLaserCode) find "0") >= 0) || {((str _newLaserCode) find "9") >= 0}} do { - _newLaserCode = _newLaserCode + _codeChange; +_codeChange = floor((_codeChange max 0) min 2); +private _placeValue = 10 ^ _codeChange; + +private _oldDigit = (floor(_oldLaserCode / _placeValue)) % 10; +private _newDigit = _oldDigit + 1; +private _limit = 8; +if (_codeChange == 2) then {_limit = 7}; + +if (_newDigit > _limit) then {_newDigit = 1}; + +for "_i" from 0 to 3 step 1 do { + private _digit = floor(_oldLaserCode / (10 ^ _i)) mod 10; + if (_i == _codeChange) then { + _digit = _newDigit; }; + _newLaserCode = _newLaserCode + (_digit * 10 ^ _i); }; TRACE_2("",_oldLaserCode,_newLaserCode); diff --git a/addons/laser/functions/fnc_laserOff.sqf b/addons/laser/functions/fnc_laserOff.sqf index bb207f2781..98560ce30f 100644 --- a/addons/laser/functions/fnc_laserOff.sqf +++ b/addons/laser/functions/fnc_laserOff.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nou * Turn a laser designator off. diff --git a/addons/laser/functions/fnc_laserOn.sqf b/addons/laser/functions/fnc_laserOn.sqf index 4038e065ef..6e9ce7b086 100644 --- a/addons/laser/functions/fnc_laserOn.sqf +++ b/addons/laser/functions/fnc_laserOn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nou * Turn a laser designator on. @@ -7,7 +7,7 @@ * 0: Emitter * 1: Owner * 2: Method, can be code, which emitter and owner are passed to, a string function name, an array with a position memory point and weapon name, or an array with a position memory point, a vector begining memory point, and vector ending memory point. - * 3: Wavelength (1550nm is common eye safe) + * 3: Wavelength (1550nm is typical) * 4: Laser code * 5: Beam divergence (in mils off beam center) * 6: Method Args (default: nil) diff --git a/addons/laser/functions/fnc_laserPointTrack.sqf b/addons/laser/functions/fnc_laserPointTrack.sqf new file mode 100644 index 0000000000..ab249f0d5e --- /dev/null +++ b/addons/laser/functions/fnc_laserPointTrack.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Toggles laser point tracking when a laser is on, for tracking coordinates. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Nothing + * + * Example: + * [vehicle player] call ace_laser_fnc_laserPointTrack + * + * Public: No + */ +params ["_vehicle"]; + +[{ + params ["_args", "_pfhID"]; + _args params ["_vehicle"]; + if !(alive _vehicle && {local _vehicle} && {hasPilotCamera _vehicle} && {!isNull (laserTarget _vehicle)}) exitWith { + [_pfhID] call CBA_fnc_removePerFrameHandler; + }; + (getPilotCameraTarget _vehicle) params ["_isTracking", "_spotPos", "_targetObj"]; + if (!_isTracking) exitWith {}; + if (isNull _targetObj) then { + private _laserTargetPos = getPosASL laserTarget _vehicle; + private _distance = _spotPos distance _laserTargetPos; + if (_distance > 0.15) then { + private _vehPos = getPosASL _vehicle; + private _vectorToLaser = _vehPos vectorFromTo _laserTargetPos; + private _vectorToSpot = _vehPos vectorFromTo _spotPos; + if (acos (_vectorToLaser vectorCos _vectorToSpot) < 0.025) then { + _vehicle setPilotCameraTarget _laserTargetPos; + }; + }; + }; +}, 0, [_vehicle]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/laser/functions/fnc_laserTargetPFH.sqf b/addons/laser/functions/fnc_laserTargetPFH.sqf index c833aa5254..0b19b4d1c3 100644 --- a/addons/laser/functions/fnc_laserTargetPFH.sqf +++ b/addons/laser/functions/fnc_laserTargetPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Maintains the tracked lasers, deleting any laser that is turned off @@ -26,7 +26,7 @@ GVAR(trackedLaserTargets) = GVAR(trackedLaserTargets) select { // Turn off the laser in ace_laser [_laserUuid] call FUNC(laserOff); - TRACE_1("Laser off:", _laserUuid); + TRACE_1("Laser off:",_laserUuid); false } else { private _newCode = _owner getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; diff --git a/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf b/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf index e7a4994ce2..5dbbc5a4b5 100644 --- a/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf +++ b/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nou * Update distance when rangefinder laser is on @@ -15,14 +15,26 @@ * Public: No */ -private _laserCode = ACE_player getVariable[QGVAR(code), ACE_DEFAULT_LASER_CODE]; -if (!isNil "_laserCode") then { - __LaserDesignatorIGUI_LaserCode ctrlSetText format["Code: %1", [_laserCode, 4, 0, false] call CBA_fnc_formatNumber]; +params ["_ctrl"]; + +private _display = ctrlParent _ctrl; + +private _currentShooter = ACE_controlledUAV param [0, objNull]; +if (isNull _currentShooter) then { + if (ACE_player call CBA_fnc_canUseWeapon) then { + _currentShooter = ACE_player; + } else { + _currentShooter = objectParent ACE_player; + }; }; -if (! (ctrlShown __LaserDesignatorIGUI_LaserOn) ) then { - // TODO: hide distance - __LaserDesignatorIGUI_ACE_Distance ctrlSetText "----"; -} else { - __LaserDesignatorIGUI_ACE_Distance ctrlSetText (ctrlText __LaserDesignatorIGUI_CA_Distance); +private _laserCode = _currentShooter getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; +private _ctrlLaserCode = _display displayCtrl IDC_LASERDESIGNATOR_LASERCODE; +_ctrlLaserCode ctrlSetText format ["Code: %1", [_laserCode, 4, 0, false] call CBA_fnc_formatNumber]; + +private _ctrlDistanceACE = _display displayCtrl IDC_LASERDESIGNATOR_ACEDISTANCE; +if (!isLaserOn _currentShooter) exitWith { + _ctrlDistanceACE ctrlSetText "----"; }; + +_ctrlDistanceACE ctrlSetText (ctrlText (_display displayCtrl IDC_LASERDESIGNATOR_DISTANCE)); diff --git a/addons/laser/functions/fnc_rotateVectLine.sqf b/addons/laser/functions/fnc_rotateVectLine.sqf index 990234c62c..3cdf12c005 100644 --- a/addons/laser/functions/fnc_rotateVectLine.sqf +++ b/addons/laser/functions/fnc_rotateVectLine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * @@ -10,7 +10,7 @@ * None * * Example: - * call ace_laser_fnc_rotateVectline + * call ace_laser_fnc_rotateVectLine * * Public: No */ diff --git a/addons/laser/functions/fnc_rotateVectLineGetMap.sqf b/addons/laser/functions/fnc_rotateVectLineGetMap.sqf index f87aa21376..7a05660f16 100644 --- a/addons/laser/functions/fnc_rotateVectLineGetMap.sqf +++ b/addons/laser/functions/fnc_rotateVectLineGetMap.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index 7fa64665ab..4ceb15d814 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nou * Searches for a laser spot given a seekers params. @@ -9,22 +9,24 @@ * 1: Direction vector (will be normalized) * 2: Seeker FOV in degrees * 3: Seeker max distance in meters - * 4: Seeker wavelength sensitivity range, [1550,1550] is common eye safe + * 4: Seeker wavelength sensitivity range, [1550,1550] is common * 5: Seeker laser code. * 6: Ignore 1 (e.g. Player's vehicle) (default: objNull) + * 7: Ignore 2 (e.g. Attached object) (default: objNull) + * 8: Owners to ignore (e.g. Player's vehicle) (default: []) * * Return Value: * [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found * * Example: - * [getPosASL player, [0,1,0], 90, [1500, 1500], 1111, player] call ace_laser_fnc_seekerFindLaserSpot + * [getPosASL player, [0,1,0], 90, [1550, 1550], 1111, player] call ace_laser_fnc_seekerFindLaserSpot * * Public: No */ BEGIN_COUNTER(seekerFindLaserSpot); -params ["_posASL", "_dir", "_seekerFov", "_seekerMaxDistance", "_seekerWavelengths", "_seekerCode", ["_ignoreObj1", objNull]]; +params ["_posASL", "_dir", "_seekerFov", "_seekerMaxDistance", "_seekerWavelengths", "_seekerCode", ["_ignoreObj1", objNull], ["_ignoreObj2", objNull], ["_ignoreOwners", []]]; _dir = vectorNormalized _dir; _seekerWavelengths params ["_seekerWavelengthMin", "_seekerWavelengthMax"]; @@ -43,6 +45,8 @@ private _finalOwner = objNull; _x params ["_obj", "_owner", "_laserMethod", "_emitterWavelength", "_laserCode", "_divergence"]; TRACE_6("laser",_obj,_owner,_laserMethod,_emitterWavelength,_laserCode,_divergence); + if (_owner in _ignoreOwners) then {continue}; + if (alive _obj && {_emitterWavelength >= _seekerWavelengthMin} && {_emitterWavelength <= _seekerWavelengthMax} && {_laserCode == _seekerCode}) then { private _laser = []; @@ -56,10 +60,10 @@ private _finalOwner = objNull; if (IS_ARRAY(_laserMethod)) then { if (count _laserMethod == 2) then { // [modelPosition, weaponName] for _obj - _laser = [AGLtoASL (_obj modelToWorldVisual (_laserMethod select 0)), _obj weaponDirection (_laserMethod select 1)]; + _laser = [_obj modelToWorldVisualWorld (_laserMethod select 0), _obj weaponDirection (_laserMethod select 1)]; } else { if (count _laserMethod == 3) then { - _laser = [AGLtoASL (_obj modelToWorldVisual (_laserMethod select 0)), (AGLtoASL (_obj modelToWorldVisual (_laserMethod select 1))) vectorFromTo (AGLtoASL (_obj modelToWorldVisual (_laserMethod select 2)))]; + _laser = [_obj modelToWorldVisualWorld (_laserMethod select 0), (_obj modelToWorldVisualWorld (_laserMethod select 1)) vectorFromTo (_obj modelToWorldVisualWorld (_laserMethod select 2))]; }; }; }; @@ -95,11 +99,11 @@ private _finalOwner = objNull; }; }; }; -} forEach (GVAR(laserEmitters) select 2); // Go through all values in hash +} forEach (values GVAR(laserEmitters)); // Go through all values in hash -TRACE_2("",count _spots, _spots); +TRACE_2("",count _spots,_spots); -if ((count _spots) > 0) then { +if (_spots isNotEqualTo []) then { private _bucketList = nil; private _bucketPos = nil; private _c = 0; @@ -111,7 +115,7 @@ if ((count _spots) > 0) then { while { count(_spots) != count(_excludes) && _c < (count _spots) } do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x select 0; @@ -120,7 +124,7 @@ if ((count _spots) > 0) then { }; } forEach _spots; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _testPos = (_x select 0); if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then { _bucketList pushBack _x; @@ -142,7 +146,7 @@ if ((count _spots) > 0) then { _bucketList = _finalBuckets select _index; { private _testPos = (_x select 0) vectorAdd [0,0,0.05]; - private _testIntersections = lineIntersectsSurfaces [_posASL, _testPos, _ignoreObj1]; + private _testIntersections = lineIntersectsSurfaces [_posASL, _testPos, _ignoreObj1, _ignoreObj2]; if ([] isEqualTo _testIntersections) then { _bucketList pushBack _x; }; @@ -154,7 +158,7 @@ if ((count _spots) > 0) then { } forEach _buckets; private _finalBucket = _finalBuckets select _largestIndex; - private _ownersHash = [] call CBA_fnc_hashCreate; + private _ownersHash = createHashMap; TRACE_2("",_finalBucket,_finalBuckets); @@ -164,24 +168,23 @@ if ((count _spots) > 0) then { { _x params ["_xPos", "_owner"]; _finalPos = _finalPos vectorAdd _xPos; - if ([_ownersHash, _owner] call CBA_fnc_hashHasKey) then { - private _count = [_ownersHash, _owner] call CBA_fnc_hashGet; - [_ownersHash, _owner, _count + 1] call CBA_fnc_hashSet; - } else { - [_ownersHash, _owner, 1] call CBA_fnc_hashSet; - }; + private _value = _ownersHash getOrDefault [hashValue _owner, [0, _owner]]; + _value set [0, 1 + _value#0]; + _ownersHash set [hashValue _owner, _value]; } forEach _finalBucket; _finalPos = _finalPos vectorMultiply (1 / (count _finalBucket)); private _maxOwnerCount = -1; - [_ownersHash, { - //IGNORE_PRIVATE_WARNING ["_key", "_value"]; - if (_value > _maxOwnerCount) then { - _finalOwner = _key; + { + //IGNORE_PRIVATE_WARNING ["_x", "_y"]; + _y params ["_count", "_owner"]; + if (_count > _maxOwnerCount) then { + _maxOwnerCount = _count; + _finalOwner = _owner; }; - }] call CBA_fnc_hashEachPair; + } forEach _ownersHash; }; }; diff --git a/addons/laser/functions/fnc_setLaserCode.sqf b/addons/laser/functions/fnc_setLaserCode.sqf new file mode 100644 index 0000000000..23f7e5c82f --- /dev/null +++ b/addons/laser/functions/fnc_setLaserCode.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Sets the laser code on a laser source. + * + * Argument: + * 0: Laser source + * 1: Laser code + * + * Return Value: + * None + * + * Example: + * [player, 1111] call ace_laser_fnc_setLaserCode; + * + * Public: Yes + */ + +params [["_laserSource", objNull, [objNull]], ["_laserCode", ACE_DEFAULT_LASER_CODE, [0]]]; + +_laserSource setVariable [QGVAR(code), _laserCode, true]; diff --git a/addons/laser/functions/fnc_shootCone.sqf b/addons/laser/functions/fnc_shootCone.sqf index b9d64a42fa..976fb734a6 100644 --- a/addons/laser/functions/fnc_shootCone.sqf +++ b/addons/laser/functions/fnc_shootCone.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nou * Shoots multiple rays in a dispersion pattern. diff --git a/addons/laser/functions/fnc_shootRay.sqf b/addons/laser/functions/fnc_shootRay.sqf index ecd16fc0d4..862e972dd1 100644 --- a/addons/laser/functions/fnc_shootRay.sqf +++ b/addons/laser/functions/fnc_shootRay.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nou, PabstMirror * Shoots a ray from a source to a direction and finds first intersction and distance. @@ -21,7 +21,7 @@ BEGIN_COUNTER(shootRay); params ["_posASL", "_dir", ["_ignoreVehicle1", objNull], ["_ignoreVehicle2", objNull]]; -// TRACE_2("ray origin:", _posASL, _dir); +// TRACE_2("ray origin:",_posASL,_dir); private _distance = 0; private _resultPos = nil; @@ -36,17 +36,17 @@ if (_intersects isEqualTo []) then { }; }; -if (!(_intersects isEqualTo [])) then { +if (_intersects isNotEqualTo []) then { (_intersects select 0) params ["_intersectPosASL", "", "_intersectObject"]; // Move back slightly to prevents issues with it going below terrain _distance = (_posASL vectorDistance _intersectPosASL) - 0.005; _resultPos = _posASL vectorAdd (_dir vectorMultiply _distance); }; -TRACE_3("", _resultPos, _distance, _intersects); +TRACE_3("",_resultPos,_distance,_intersects); #ifdef DRAW_LASER_INFO -if !(isNil "_resultPos") then { +if (!isNil "_resultPos") then { private _text = [_distance, 4, 0] call CBA_fnc_formatNumber; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0, 1, 0, 1], ASLtoAGL _resultPos, 0.5, 0.5, 0, _text, 0.4, 0.025, "TahomaB"]; drawLine3D [ASLtoAGL _posASL, ASLtoAGL _resultPos, [0,1,0,1]]; diff --git a/addons/laser/functions/fnc_showVehicleHud.sqf b/addons/laser/functions/fnc_showVehicleHud.sqf index 3b9f0adc2f..778df61a6c 100644 --- a/addons/laser/functions/fnc_showVehicleHud.sqf +++ b/addons/laser/functions/fnc_showVehicleHud.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Shows the laser hud when vehicle is equiped with the weapon. @@ -90,7 +90,7 @@ GVAR(pfID) = [{ // Do Laser Scan: private _ammo = getText (configFile >> "CfgMagazines" >> _vehicle currentMagazineTurret _turretPath >> "ammo"); - private _laserSource = AGLtoASL (_vehicle modelToWorld (_vehicle selectionPosition _seekerSource)); + private _laserSource = _vehicle modelToWorldWorld (_vehicle selectionPosition _seekerSource); private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; private _seekerAngle = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerAngle"); private _seekerMaxRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerMaxRange"); diff --git a/addons/laser/functions/fnc_toggleLST.sqf b/addons/laser/functions/fnc_toggleLST.sqf new file mode 100644 index 0000000000..59969d014e --- /dev/null +++ b/addons/laser/functions/fnc_toggleLST.sqf @@ -0,0 +1,67 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Toggles the laser spot tracker for any enabled vehicle. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Nothing + * + * Example: + * [vehicle player] call ace_laser_fnc_toggleLST + * + * Public: No + */ + + +params ["_vehicle"]; + +if !(_vehicle getVariable [QGVAR(hasLaserSpotTracker), false]) exitWith {}; + +private _enabled = _vehicle getVariable [QGVAR(laserSpotTrackerOn), false]; +_vehicle setVariable [QGVAR(laserSpotTrackerOn), !_enabled]; + +private _LSTmessage = if (_vehicle getVariable [QGVAR(laserSpotTrackerOn), false]) then {localize LSTRING(LSTOn)} else {localize LSTRING(LSTOff)}; +private _string = format ["%1
", _LSTmessage]; +private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; +_string = format ["%1%2: %3
",_string, localize LSTRING(laserCode), _laserCode]; +[_string] call EFUNC(common,displayTextStructured); + +if (_enabled) exitWith {}; + +[{ + params ["_args", "_pfhID"]; + _args params ["_vehicle"]; + + if !(_vehicle getVariable [QGVAR(laserSpotTrackerOn), false] && {alive _vehicle}) exitWith { + [_pfhID] call CBA_fnc_removePerFrameHandler; + }; + + private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _angle = 25; + + private _pos = _vehicle modelToWorldVisualWorld [0,0,0]; + private _pilotCameraPos = getPilotCameraPosition _vehicle; + private _pilotCameraVector = _pos vectorFromTo (_vehicle modelToWorldVisualWorld (getPilotCameraDirection _vehicle)); + + (getPilotCameraTarget _vehicle) params ["_isTracking", "_spotPos"]; + + if (_isTracking) then { + _angle = 0.25; + }; + + private _laserSource = _vehicle modelToWorldWorld _pilotCameraPos; + private _laserResult = [_laserSource, _pilotCameraVector, _angle, 5000, [ACE_DEFAULT_LASER_WAVELENGTH,ACE_DEFAULT_LASER_WAVELENGTH], _laserCode, _vehicle, laserTarget _vehicle, [_vehicle]] call FUNC(seekerFindLaserSpot); + private _foundTargetPos = _laserResult select 0; + + if (_isTracking) then { + private _distance = _spotPos distance _foundTargetPos; + if (_distance > 0.75) then { + _vehicle setPilotCameraTarget _foundTargetPos; + }; + } else { + _vehicle setPilotCameraTarget _foundTargetPos; + }; +}, 0, [_vehicle]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/laser/functions/script_component.hpp b/addons/laser/functions/script_component.hpp deleted file mode 100644 index 98d00342c0..0000000000 --- a/addons/laser/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\laser\script_component.hpp" \ No newline at end of file diff --git a/addons/laser/initKeybinds.inc.sqf b/addons/laser/initKeybinds.inc.sqf new file mode 100644 index 0000000000..465c4a35c2 --- /dev/null +++ b/addons/laser/initKeybinds.inc.sqf @@ -0,0 +1,23 @@ + +["ACE3 Equipment", QGVAR(LaserCodeUpHundreds), localize LSTRING(laserCodeUpHundreds), +{ + [2] call FUNC(keyLaserCodeChange); +}, +{false}, +[DIK_Q, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+Q) + +["ACE3 Equipment", QGVAR(LaserCodeUpTens), localize LSTRING(laserCodeUpTens), +{ + + [1] call FUNC(keyLaserCodeChange); +}, +{false}, +[DIK_W, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+W) + +["ACE3 Equipment", QGVAR(LaserCodeUpOnes), localize LSTRING(laserCodeUpOnes), +{ + + [0] call FUNC(keyLaserCodeChange); +}, +{false}, +[DIK_E, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+E) diff --git a/addons/laser/initKeybinds.sqf b/addons/laser/initKeybinds.sqf deleted file mode 100644 index 418b062fec..0000000000 --- a/addons/laser/initKeybinds.sqf +++ /dev/null @@ -1,16 +0,0 @@ - - -["ACE3 Equipment", QGVAR(LaserCodeUp), localize LSTRING(laserCodeUp), -{ - [1] call FUNC(keyLaserCodeChange); -}, -{false}, -[16, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+Q) - -["ACE3 Equipment", QGVAR(LaserCodeDown), localize LSTRING(laserCodeDown), -{ - - [-1] call FUNC(keyLaserCodeChange); -}, -{false}, -[18, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+E) diff --git a/addons/laser/initSettings.inc.sqf b/addons/laser/initSettings.inc.sqf new file mode 100644 index 0000000000..a7574e55ad --- /dev/null +++ b/addons/laser/initSettings.inc.sqf @@ -0,0 +1,21 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(laser)]; + +[ + QGVAR(dispersionCount), "SLIDER", + LSTRING(dispersionCount_displayName), + _category, + [0, 5, 2, -1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(showLaserOnMap), "LIST", + [LSTRING(showLaserOnMap), LSTRING(showLaserOnMap_tooltip)], + _category, + [ + [0, 1, 2, 3], + [LELSTRING(Common,Disabled), "STR_A3_CfgEditorSubcategories_EdSubcat_Drones0", "str_dn_vehicles", LELSTRING(common,Always)], + 1 + ], + true +] call CBA_fnc_addSetting; diff --git a/addons/laser/script_component.hpp b/addons/laser/script_component.hpp index b0d9951bf3..64a9a85f13 100644 --- a/addons/laser/script_component.hpp +++ b/addons/laser/script_component.hpp @@ -17,14 +17,11 @@ #include "\z\ace\addons\main\script_macros.hpp" - -#define __LaserDesignatorIGUI (uiNamespace getVariable ["ACE_RscOptics_LaserDesignator", nil]) -#define __LaserDesignatorIGUI_LaserCode (__LaserDesignatorIGUI displayCtrl 123001) -#define __LaserDesignatorIGUI_ACE_Distance (__LaserDesignatorIGUI displayCtrl 123002) -#define __LaserDesignatorIGUI_CA_Distance (__LaserDesignatorIGUI displayCtrl 151) -#define __LaserDesignatorIGUI_LaserOn (__LaserDesignatorIGUI displayCtrl 158) - #define IDC_MODECONTROLGROUP 1000 #define IDC_ATTACKMODE 1001 #define IDC_LASERCODE 1002 #define IDC_LASERICON 1003 + +#define IDC_LASERDESIGNATOR_LASERCODE 123001 +#define IDC_LASERDESIGNATOR_ACEDISTANCE 123002 +#define IDC_LASERDESIGNATOR_DISTANCE 151 diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index 632d45708e..c6bf7cfc25 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -1,17 +1,38 @@ + + Laser + Laser + Laser + Laser + Лазер + Laser + Lézer + Láser + Laser + Laser + レーザー + 레이저 + 激光 + 雷射 + Lazer + Laser Dispersion Simulation Count レーザーの分散シミュレート数 Laserstreuung-Simulationszähler 레이저 분산 시뮬레이션 수 Wskaźnik poziomu rozproszenia wiązki lasera - Compte de la simulation de la dispersion du laser + Nombre de simulations pour la dispersion du laser Contatore di Simulazione della Dispersione del Laser - 雷射散射模拟计算 + 激光色散模拟计数 雷射散射模擬計算 Число симуляций рассеивания лазерного луча + Contador da Simulação de Dispersão de Laser + Počet simulace disperze laseru + Número de dispersión en la simulación del láser + Laser Dispersion Simulation Count Laser Code @@ -23,43 +44,130 @@ Lézerkód Código del láser Laser kód - Codice laser - レーザ コード + Codice Laser + レーザー コード 레이저 코드 - 雷射码 + 激光码 雷射碼 + Lazer Kod - - Laser - Cycle Code Up - Lasercode + - Laser - Następny kod - Laser - Code + - Лазер - увеличить частоту - Laser - Alternar Código para Cima - Lézer - kódciklus növelése - Láser - Aumentar código - Laser - Kód + - Laser - Cambia codice + - レーザ - コードの数値を増やす - 레이저 - 코드 순환 위 - 雷射 - 循环切换雷射码 上 - 雷射 - 循環切換雷射碼 上 + + Laser - Cycle Code Up - XXX# + Lasercode +XXX# + Laser - Następny kod - XXX# + Code laser +XXX# + Лазер - увеличить частоту - XXX# + Laser - Alternar Código para Cima - XXX# + Lézer - kódciklus növelése - XXX# + Láser - Aumentar código - XXX# + Laser - Kód +XXX# + Laser - Cicla Codice - XXX# + レーザー - コードの数値を増やす - XXX# + 레이저 - 코드 순환 위 - XXX# + 激光—循环切换激光码 上 - XXX# + 雷射 - 循環切換雷射碼 上 - XXX# + Lazer - Çevrim Kodu Yukarı - XXX# + + + Laser - Cycle Code Up - XX#X + Lasercode +XX#X + Laser - Następny kod - XX#X + Code laser +XX#X + Лазер - увеличить частоту - XX#X + Laser - Alternar Código para Cima - XX#X + Lézer - kódciklus növelése - XX#X + Láser - Aumentar código - 1##X + Laser - Kód +XX#X + Laser - Cicla Codice - XX#X + レーザー - コードの数値を増やす - XX#X + 레이저 - 코드 순환 위 - 1##X + 激光—循环切换激光码 上 - XX#X + 雷射 - 循環切換雷射碼 上 - XX#X + Lazer - Çevrim Kodu Yukarı - XX#X + + + Laser - Cycle Code Up - X#XX + Lasercode +X#XX + Laser - Następny kod - X#XX + Code laser +X#XX + Лазер - увеличить частоту - X#XX + Laser - Alternar Código para Cima - X#XX + Lézer - kódciklus növelése - X#XX + Láser - Aumentar código - X#XX + Laser - Kód +X#XX + Laser - Cicla Codice - X#XX + レーザー - コードの数値を増やす - X#XX + 레이저 - 코드 순환 위 - X#XX + 激光—循环切换激光码 上 - X#XX + 雷射 - 循環切換雷射碼 上 - X#XX + Lazer - Çevrim Kodu Yukarı - X#XX Laser - Cycle Code Down Lasercode - Laser - Poprzedni kod - Laser - Code - + Code laser - Лазер - уменьшить частоту Laser - Alternar Código para Baixo Lézer - kódciklus csökkentése Láser - Reducir código Laser - Kód - - Laser - Cambia codice - - レーザ - コードの数値を減らす + Laser - Cicla Codice giù + レーザー - コードの数値を減らす 레이저 - 코드 순환 아래 - 雷射 - 循环切换雷射码 下 + 激光—循环切换激光码 下 雷射 - 循環切換雷射碼 下 + Lazer - Çevrim Kodu aşağı + + + Laser Spot Tracker: On + レーザースポットトラッカー: オン + Laserowe Śledzenie Punktu: Wł. + Laserziel Verfolgung: An + Tracciamento Designazioni Laser: Attivato + 레이저 스팟 추적기: 켬 + Traqueur laser : activé + Rastreador a Laser: Ligado + Лазерный точечный трекер: Включен + Rastreador del Puntero Láser: On + + + Laser Spot Tracker: Off + レーザースポットトラッカー: オフ + Laserowe Śledzenie Punktu: Wył. + Laserziel Verfolgung: Aus + Tracciamento Designazioni Laser: Disattivato + 레이저 스팟 추적기: 끔 + Traqueur laser : désactivé + Rastreador a Laser: Desligado + Лазерный точечный трекер: выключен + Rastreador del Puntero Láser: Off + + + Draw Laser on Map + 地図上にレーザーを表示する + Rysuj Laser na Mapie + 맵에 레이저 그리기 + 在地图上绘制激光 + Отображать лазер на карте + Dibujar láser en mapa + Laser auf Karte zeichnen + Mostra Laser su Mappa + Dessiner le laser sur la carte + Desenhar Laser no Mapa + + + Active laser designator's position will be drawn on the map + アクティブな指示レーザーの位置が地図上に描画されます + Pozycja aktywnego wskaźnika laserowego będzie rysowana na mapie. + 지도에 능동 레이저 표시기의 위치가 그려집니다. + 激活的激光指示器本身及其标记的点会在地图上显示 + Точка, куда светит активный лазер, будет указана на карте + La posición del designador láser activo será dibujada en el mapa + Die Position des aktiven Lasermarkierers wird auf der Karte eingezeichnet + Mostra la posizione del proprio designatore laser sulla mappa + Active la position du désignateur laser sur la carte. + A posição do designador laser ativo será desenhada no mapa diff --git a/addons/laserpointer/ACE_Settings.hpp b/addons/laserpointer/ACE_Settings.hpp deleted file mode 100644 index 833167ba28..0000000000 --- a/addons/laserpointer/ACE_Settings.hpp +++ /dev/null @@ -1,8 +0,0 @@ -class ACE_Settings { - class GVAR(enabled) { - category = ECSTRING(common,ACEKeybindCategoryWeapons); - displayName = CSTRING(DisplayName); - typeName = "BOOL"; - value = 1; - }; -}; diff --git a/addons/laserpointer/CfgEventHandlers.hpp b/addons/laserpointer/CfgEventHandlers.hpp index 0d3301d6e0..f72363981a 100644 --- a/addons/laserpointer/CfgEventHandlers.hpp +++ b/addons/laserpointer/CfgEventHandlers.hpp @@ -1,17 +1,10 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(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)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/laserpointer/CfgJointRails.hpp b/addons/laserpointer/CfgJointRails.hpp index 7583bd03b5..8c40d678a9 100644 --- a/addons/laserpointer/CfgJointRails.hpp +++ b/addons/laserpointer/CfgJointRails.hpp @@ -6,3 +6,20 @@ class asdg_FrontSideRail: asdg_SlotInfo { ACE_acc_pointer_green_IR = 1; }; }; + +class SlotInfo; +class PointerSlot: SlotInfo { + compatibleItems[] += { + "ACE_acc_pointer_red", + "ACE_acc_pointer_green_IR", + "ACE_acc_pointer_green" + }; +}; + +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/laserpointer/CfgWeapons.hpp b/addons/laserpointer/CfgWeapons.hpp index 6afa29a344..2ac5f1fda6 100644 --- a/addons/laserpointer/CfgWeapons.hpp +++ b/addons/laserpointer/CfgWeapons.hpp @@ -1,9 +1,3 @@ - -class SlotInfo; -class PointerSlot: SlotInfo { - compatibleItems[] += {"ACE_acc_pointer_red","ACE_acc_pointer_green_IR","ACE_acc_pointer_green"}; -}; - class CfgWeapons { class ItemCore; class InventoryFlashLightItem_Base_F; @@ -15,85 +9,50 @@ class CfgWeapons { displayName = CSTRING(red); descriptionUse = CSTRING(useLaser); - }; - - class ACE_acc_pointer_red: ItemCore { - MRT_SwitchItemNextClass = "acc_pointer_IR"; - MRT_SwitchItemPrevClass = "acc_pointer_IR"; - MRT_switchItemHintText = CSTRING(Laser); - - ACE_laserpointer = 1; - - author = ECSTRING(common,ACETeam); - _generalMacro = "ACE_acc_pointer_red"; - scope = 1; - displayName = CSTRING(red); - descriptionUse = CSTRING(useLaser); - picture = "\A3\weapons_F\Data\UI\gear_accv_pointer_CA.paa"; - model = "\A3\weapons_f\acc\accv_pointer_F"; - descriptionShort = CSTRING(Description); class ItemInfo: InventoryFlashLightItem_Base_F { - mass = 6; - - class Pointer { - irLaserPos = "laser pos"; - irLaserEnd = "laser dir"; - irDistance = 5; - }; - - class FlashLight { - color[] = {0,0,0}; - ambient[] = {0,0,0}; - intensity = 0; - size = 0; - innerAngle = 0; - outerAngle = 0; - coneFadeCoef = 5; - position = "flash dir"; - direction = "flash"; - useFlare = 0; - flareSize = 0; - flareMaxDistance = "100.0f"; - dayLight = 0; - - class Attenuation { - start = 0; - constant = 0; - linear = 0; - quadratic = 0; - hardLimitStart = 0; - hardLimitEnd = 0; - }; - - scale[] = {0}; - }; + class Pointer; }; - - inertia = 0.1; }; class ACE_acc_pointer_green_IR: acc_pointer_IR { MRT_SwitchItemNextClass = "ACE_acc_pointer_green"; MRT_SwitchItemPrevClass = "ACE_acc_pointer_green"; - MRT_switchItemHintText = CSTRING(IRLaser); author = ECSTRING(common,ACETeam); _generalMacro = "ACE_acc_pointer_green"; scope = 1; displayName = CSTRING(green); + baseWeapon = "ACE_acc_pointer_green"; + }; + + class ACE_acc_pointer_red: acc_pointer_IR { + MRT_SwitchItemNextClass = "acc_pointer_IR"; + MRT_SwitchItemPrevClass = "acc_pointer_IR"; + MRT_switchItemHintText = CSTRING(Laser); + + author = ECSTRING(common,ACETeam); + _generalMacro = "ACE_acc_pointer_red"; + scope = 1; + descriptionShort = CSTRING(Description); + baseWeapon = "acc_pointer_IR"; + + class ItemInfo: ItemInfo { + POINTER_VISIBLE_RED; + }; }; class ACE_acc_pointer_green: ACE_acc_pointer_red { MRT_SwitchItemNextClass = "ACE_acc_pointer_green_IR"; MRT_SwitchItemPrevClass = "ACE_acc_pointer_green_IR"; - MRT_switchItemHintText = CSTRING(Laser); - ACE_laserpointer = 2; - - author = ECSTRING(common,ACETeam); _generalMacro = "ACE_acc_pointer_green"; scope = 2; displayName = CSTRING(green); + baseWeapon = "ACE_acc_pointer_green"; + + class ItemInfo: ItemInfo { + POINTER_VISIBLE_GREEN; + }; }; }; diff --git a/addons/laserpointer/README.md b/addons/laserpointer/README.md index f4e711513b..22d2eadf43 100644 --- a/addons/laserpointer/README.md +++ b/addons/laserpointer/README.md @@ -2,11 +2,3 @@ ace_laserpointer ================ Adds a laser pointer visible during the day. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/laserpointer/XEH_PREP.hpp b/addons/laserpointer/XEH_PREP.hpp deleted file mode 100644 index 59a28bb4cc..0000000000 --- a/addons/laserpointer/XEH_PREP.hpp +++ /dev/null @@ -1,3 +0,0 @@ -PREP(drawLaserpoint); -PREP(getNearUnits); -PREP(onDraw); diff --git a/addons/laserpointer/XEH_postInit.sqf b/addons/laserpointer/XEH_postInit.sqf deleted file mode 100644 index 7e90e29259..0000000000 --- a/addons/laserpointer/XEH_postInit.sqf +++ /dev/null @@ -1,91 +0,0 @@ -// by commy2 -#include "script_component.hpp" - -// fixes laser when being captured. Needed, because the selectionPosition of the right hand is used -[QEGVAR(captives,setHandcuffed), {if (_this select 1) then {(_this select 0) action ["GunLightOff", _this select 0]};}] call CBA_fnc_addEventHandler; - -if (!hasInterface) exitWith {}; - -GVAR(nearUnits) = []; -GVAR(index) = -1; -GVAR(laserClassesCache) = [] call CBA_fnc_createNamespace; -GVAR(redLaserUnits) = []; -GVAR(greenLaserUnits) = []; - -["ace_settingsInitialized", { - // If not enabled, dont't add draw eventhandler or PFEH (for performance) - if (!GVAR(enabled)) exitWith { - ["CBA_attachmentSwitched", { - params ["_unit", "_prevItem", "_newItem", "_currWeaponType"]; - TRACE_4("CBA_attachmentSwitched eh",_unit,_prevItem,_newItem,_currWeaponType); - if ((getNumber (configFile >> "CfgWeapons" >> _newItem >> "ACE_laserpointer")) > 0) then { - TRACE_1("removing ACE_laserpointer",getNumber (configFile >> "CfgWeapons" >> _newItem >> "ACE_laserpointer")); - [1, "prev"] call CBA_accessory_fnc_switchAttachment; - }; - }] call CBA_fnc_addEventHandler; - }; - - [{ - private _oldNearUnits = GVAR(nearUnits); - GVAR(nearUnits) = call FUNC(getNearUnits); - - // remove units that moved away - { - GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _x); - GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _x); - } forEach (_oldNearUnits - GVAR(nearUnits)); - }, 5, []] call CBA_fnc_addPerFrameHandler; - - - private _fnc_processUnit = { - params ["_unit"]; - - private _weapon = currentWeapon _unit; - if (!(_unit isFlashlightOn _weapon)) exitWith { - GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _unit); - GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _unit); - }; - - private _laser = [(_unit weaponAccessories _weapon) select 1] param [0, ""]; - if (_laser isEqualTo "") exitWith { - GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _unit); - GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _unit); - }; - - private _laserID = GVAR(laserClassesCache) getVariable _laser; - - if (isNil "_laserID") then { - _laserID = getNumber (configFile >> "CfgWeapons" >> _laser >> "ACE_laserpointer"); - GVAR(laserClassesCache) setVariable [_laser, _laserID]; - }; - TRACE_3("",_weapon,_laser,_laserID); - - if (_laserID isEqualTo 1) exitWith { - GVAR(redLaserUnits) pushBackUnique _unit; - GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _unit); - }; - - if (_laserID isEqualTo 2) exitWith { - GVAR(greenLaserUnits) pushBackUnique _unit; - GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _unit); - }; - }; - - // custom scheduler - [{ - params ["_fnc_processUnit"]; - - ACE_player call _fnc_processUnit; - - GVAR(index) = GVAR(index) + 1; - private _unit = GVAR(nearUnits) param [GVAR(index), objNull]; - - if (isNull _unit) exitWith { - GVAR(index) = -1; - }; - - _unit call _fnc_processUnit; - }, 0.1, _fnc_processUnit] call CBA_fnc_addPerFrameHandler; - - addMissionEventHandler ["Draw3D", {call FUNC(onDraw)}]; -}] call CBA_fnc_addEventHandler; diff --git a/addons/laserpointer/XEH_preInit.sqf b/addons/laserpointer/XEH_preInit.sqf index d2efe43e9c..7ab1e00588 100644 --- a/addons/laserpointer/XEH_preInit.sqf +++ b/addons/laserpointer/XEH_preInit.sqf @@ -1,16 +1,8 @@ #include "script_component.hpp" -ADDON = false; - -PREP_RECOMPILE_START; -#include "XEH_PREP.hpp" -PREP_RECOMPILE_END; - -["visionMode", { - params ["", "_visionMode"]; - - GVAR(isIR) = _visionMode isEqualTo 1; - GVAR(isTI) = _visionMode isEqualTo 2; -}] call CBA_fnc_addPlayerEventHandler; +{ + TRACE_1("blocking switching to unsupported laser mode",_x); + [_x, { false }] call CBA_fnc_addAttachmentCondition; +} forEach (keys (uiNamespace getVariable QGVAR(oldLasers))); ADDON = true; diff --git a/addons/laserpointer/XEH_preStart.sqf b/addons/laserpointer/XEH_preStart.sqf index 022888575e..41fe08e7cc 100644 --- a/addons/laserpointer/XEH_preStart.sqf +++ b/addons/laserpointer/XEH_preStart.sqf @@ -1,3 +1,5 @@ #include "script_component.hpp" -#include "XEH_PREP.hpp" +private _lasers = ((toString {(getNumber (_x >> "ACE_laserpointer")) > 0}) configClasses (configFile >> "CfgWeapons")) apply {configName _x}; +if (_lasers isNotEqualTo []) then { WARNING_1("%1 attachements still using unsupported ACE_laserpointer config",count _lasers) }; +uiNamespace setVariable [QGVAR(oldLasers), compileFinal (_lasers createHashMapFromArray [])]; diff --git a/addons/laserpointer/config.cpp b/addons/laserpointer/config.cpp index 4058157660..f405d0dfa0 100644 --- a/addons/laserpointer/config.cpp +++ b/addons/laserpointer/config.cpp @@ -14,7 +14,6 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/laserpointer/functions/fnc_drawLaserpoint.sqf b/addons/laserpointer/functions/fnc_drawLaserpoint.sqf deleted file mode 100644 index ab7724fda5..0000000000 --- a/addons/laserpointer/functions/fnc_drawLaserpoint.sqf +++ /dev/null @@ -1,96 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 and esteldunedain - * Draw a Laser Point - * - * Arguments: - * 0: Target unit - * 1: Range - * 2: is Green - * 3: Brightness - * - * Return Value: - * None - * - * Example: - * [player, 10, false, 2] call ace_laserpointer_fnc_drawLaserpoint - * - * Public: No - */ - -params ["_target", "_range", "_isGreen", "_brightness"]; - -private _unit = ACE_player; - -private _p0 = AGLToASL (_target modelToWorldVisual (_target selectionPosition "righthand")); - -// Find a system of orthogonal reference vectors -// _v1 points in the direction of the weapon -// _v2 points to the right of the weapon -// _v3 points to the top side of the weapon -private _v1 = _target weaponDirection currentWeapon _target; -private _v2 = vectorNormalized (_v1 vectorCrossProduct [0,0,1]); -private _v3 = _v2 vectorCrossProduct _v1; - -// Offset over the 3 reference axis -// This offset could eventually be configured by weapon in the config -#define OFFV1 0.31 -#define OFFV2 0 -#define OFFV3 0.08 - -// Offset _p0, the start of the laser -_p0 = _p0 vectorAdd (_v1 vectorMultiply OFFV1) vectorAdd (_v3 vectorMultiply OFFV3) vectorAdd (_v2 vectorMultiply OFFV2); - -// Calculate _p1, the potential end of the laser -private _p1 = _p0 vectorAdd (_v1 vectorMultiply _range); - -private _pL = lineIntersectsSurfaces [_p0, _p1, _unit, vehicle _unit] select 0 select 0; - -// no intersection found, quit -if (isNil "_pL") exitWith {}; - -private _distance = _p0 vectorDistance _pL; - -//systemChat str _distance; -if (_distance < 0.5) exitWith {}; - -_pL = _p0 vectorAdd (_v1 vectorMultiply _distance); - -private _pL2 = _p0 vectorAdd (_v1 vectorMultiply (_distance - 0.5)); - -_pL = ASLtoAGL _pL; - -/* -drawLine3D [ - _p0, - _pL, - [[1,0,0,1], [0,1,0,1]] select _isGreen -]; -*/ - -//systemChat str [_target, "FIRE"] intersect [_camPos, _pL]; - -private _camPos = positionCameraToWorld [0,0,0.2]; - -if (count ([_target, "FIRE"] intersect [_camPos, _pL]) > 0) exitWith {}; -if (count ([_unit, "FIRE"] intersect [_camPos, _pL]) > 0) exitWith {}; - -// Convert _camPos to ASL -_camPos = AGLToASL _camPos; - -if (terrainIntersectASL [_camPos, _pL2]) exitWith {}; -if (lineIntersects [_camPos, _pL2]) exitWith {}; - -private _size = 2 * sqrt (1 / _distance) * (call EFUNC(common,getZoom)); - -drawIcon3D [ - format ["\a3\weapons_f\acc\data\collimdot_%1_ca.paa", ["red", "green"] select _isGreen], - [[1,0.25,0.25,0.6*_brightness], [0.25,1,0.25,0.5*_brightness]] select _isGreen, - _pL, - _size, - _size, - 45, - "", - 0, - 0.05 -]; diff --git a/addons/laserpointer/functions/fnc_getNearUnits.sqf b/addons/laserpointer/functions/fnc_getNearUnits.sqf deleted file mode 100644 index 38b1a32ed9..0000000000 --- a/addons/laserpointer/functions/fnc_getNearUnits.sqf +++ /dev/null @@ -1,29 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Reports near units. - * - * Arguments: - * None - * - * Return Value: - * Near Units - * - * Example: - * call ACE_laserpointer_fnc_getNearUnits - * - * Public: No - */ - -private _camPosAGL = positionCameraToWorld [0, 0, 0]; - -// handle RHS / bugged vehicle slots -if !((_camPosAGL select 0) isEqualType 0) exitWith { [] }; - -private _nearUnits = []; - -{ - _nearUnits append crew _x; -} forEach nearestObjects [_camPosAGL, ["AllVehicles"], MAX_LASER_RANGE]; - -_nearUnits diff --git a/addons/laserpointer/functions/fnc_onDraw.sqf b/addons/laserpointer/functions/fnc_onDraw.sqf deleted file mode 100644 index bfee8a7ea6..0000000000 --- a/addons/laserpointer/functions/fnc_onDraw.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Draw the visible laser beams of all cached units. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ACE_laserpointer_fnc_onDraw - * - * Public: No - */ - -if (count GVAR(redLaserUnits) + count GVAR(greenLaserUnits) > 0 && {!GVAR(isTI)}) then { - private _brightness = 2 - call EFUNC(common,ambientBrightness); - - { - // red laser. draw green dot anyway in IR mode - [_x, 100, GVAR(isIR), _brightness] call FUNC(drawLaserpoint); - } count GVAR(redLaserUnits); - - { - // green laser - [_x, 100, true, _brightness] call FUNC(drawLaserpoint); - } count GVAR(greenLaserUnits); -}; diff --git a/addons/laserpointer/functions/script_component.hpp b/addons/laserpointer/functions/script_component.hpp deleted file mode 100644 index 727c32539f..0000000000 --- a/addons/laserpointer/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\laserpointer\script_component.hpp" \ No newline at end of file diff --git a/addons/laserpointer/script_component.hpp b/addons/laserpointer/script_component.hpp index 4b7b2e0d39..8e1d126e23 100644 --- a/addons/laserpointer/script_component.hpp +++ b/addons/laserpointer/script_component.hpp @@ -15,5 +15,4 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" - -#define MAX_LASER_RANGE 50 +#include "\z\ace\addons\laserpointer\script_macros_config.hpp" diff --git a/addons/laserpointer/script_macros_config.hpp b/addons/laserpointer/script_macros_config.hpp new file mode 100644 index 0000000000..497911dc95 --- /dev/null +++ b/addons/laserpointer/script_macros_config.hpp @@ -0,0 +1,39 @@ +/* + Usage: + + #include "\z\ace\addons\laserpointer\script_macros_config.hpp" + + class CfgWeapons { + class My_AwesomePointer_base; + class My_AwesomePointer: My_AwesomePointer_base { + class ItemInfo { + POINTER_VISIBLE_GREEN; + }; + }; + }; +*/ + +#define POINTER_VISIBLE_RED \ + class Pointer { \ + irLaserPos = "laser pos"; \ + irLaserEnd = "laser dir"; \ + irDistance = 5; \ + isIR = 0; \ + irDotSize = QUOTE(0.1/4); \ + beamThickness = 0; \ + beamMaxLength = 50; \ + dotColor[] = {16384, 0, 0}; \ + beamColor[] = {0, 0, 0}; \ + } +#define POINTER_VISIBLE_GREEN \ + class Pointer { \ + irLaserPos = "laser pos"; \ + irLaserEnd = "laser dir"; \ + irDistance = 5; \ + isIR = 0; \ + irDotSize = QUOTE(0.1/4); \ + beamThickness = 0; \ + beamMaxLength = 75; \ + dotColor[] = {0, 16384, 0}; \ + beamColor[] = {0, 0, 0}; \ + } diff --git a/addons/laserpointer/stringtable.xml b/addons/laserpointer/stringtable.xml index 17b7dbe933..b8d0a657d8 100644 --- a/addons/laserpointer/stringtable.xml +++ b/addons/laserpointer/stringtable.xml @@ -12,10 +12,11 @@ Puntero láser Puntatore laser Laser - レーザ ポインタ + レーザー ポインター 레이저 지시기 - 雷射指示器 + 激光指示器 雷射指示器 + Lazer Işaretleyici Laser Pointer (red) @@ -28,26 +29,28 @@ Puntero láser (rojo) Puntatore laser (rosso) Laser (vermelho) - レーザ ポインタ (赤) + レーザー ポインター (赤) 레이저 지시기 (빨강) - 雷射指示器 (红色) + 激光指示器(红色) 雷射指示器 (紅色) + Lazer Işaretleyici (Kırmızı) Laser Pointer (green) - Pointeur laser (vert) - Laserpointer (grün) + Pointeur laser (Vert) + Laserpointer (Grün) Лазерный прицел (зелёный) Laserové ukazovátko (Zelené) - Wskaźnik laserowy (zielony) + Wskaźnik laserowy (Zielony) Lézer-pointer (zöld) - Puntero láser (verde) - Puntatore laser (verde) - Laser (verde) - レーザ ポインタ (緑) + Puntero láser (Verde) + Puntatore laser (Verde) + Laser (Verde) + レーザー ポインター (緑) 레이저 지시기 (초록) - 雷射指示器 (绿色) + 激光指示器(绿色) 雷射指示器 (綠色) + Lazer Işaretleyici (Yeşil) Emits visible light. @@ -62,24 +65,26 @@ Emite luz visível. 可視光をだします。 밝은 곳에서도 보임 - 发射出可见光 + 发出可见激光 發射出可見光 + Görünür ışık yayar. <t color='#9cf953'>Use: </t>Turn Laser ON/OFF <t color='#9cf953'>Použití: </t>Zapnout/vypnout laser - <t color='#9cf953'>Utiliser : </t>laser allumé/éteint + <t color='#9cf953'>Utilisation : </t>Allumer/Éteindre le laser <t color='#9cf953'>Benutzen: </t>Laser EIN/AUS - <t color='#9cf953'>Uso: </t>Laser ON/OFF + <t color='#9cf953'>Utilizzo: </t>Laser ACCESO/SPENTO <t color='#9cf953'>Użyj: </t>wł./wył. laser <t color='#9cf953'>Uso: </t>Ativar/Desativar laser <t color='#9cf953'>Использовать: </t>ВКЛ/ВЫКЛ лазер <t color='#9cf953'>Usar: </t>Encender/Apagar láser <t color='#9cf953'>Használat: </t>Lézer BE/KI kapcsolása - <t color='#9cf953'>つかう: </t>レーザの起動/停止 + <t color='#9cf953'>つかう: </t>レーザーの起動/停止 <t color='#9cf953'>사용키: </t>레이저 켜기/끄기 - <t color='#9cf953'>使用: </t>雷射开启/关闭 + <t color='#9cf953'>使用:</t>激光开启/关闭 <t color='#9cf953'>使用: </t>雷射開啟/關閉 + <t color='#9cf953'>Use: </t>Turn Laser ON/OFF Laser @@ -92,10 +97,11 @@ Lézer Laser Laser - レーザ + レーザー 레이저 - 雷射 + 激光 雷射 + Lazer IR Laser @@ -108,26 +114,28 @@ Infravörös Lézer IR Laser Laser IV - 赤外線レーザ + 赤外線レーザー 적외선 레이저 - 红外线雷射 + 红外线激光 紅外線雷射 + IR Lazer Switch Laser / IR Laser Umschalten Laser / IR-Laser Przełącz Laser / Laser IR Изменить режим Лазер / ИК-лазер - Changer Laser / Laser IR - Alterna Laser / IR Laser + Alterner laser/laser IR + Alterna Laser / Laser IR Cambiar láser / Láser IR Lézer / Infravörös Lézer váltása Přepnout Laser / Infračervený Laser Alternar entre Laser / Laser IV - レーザ/赤外線レーザを切り替える - 레이저 / 적외선 레이저 전환 - 切换雷射/红外线雷射 + レーザー/赤外線レーザーを切り替える + 가시광/적외선 레이저 전환 + 切换激光/红外线激光 切換雷射/紅外線雷射 + Değiştir Lazer/IR Lazer diff --git a/addons/logistics_rope/$PBOPREFIX$ b/addons/logistics_rope/$PBOPREFIX$ new file mode 100644 index 0000000000..12790e5206 --- /dev/null +++ b/addons/logistics_rope/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\logistics_rope \ No newline at end of file diff --git a/addons/logistics_rope/CfgWeapons.hpp b/addons/logistics_rope/CfgWeapons.hpp new file mode 100644 index 0000000000..d8789c6407 --- /dev/null +++ b/addons/logistics_rope/CfgWeapons.hpp @@ -0,0 +1,67 @@ +class CfgWeapons { + class CBA_MiscItem_ItemInfo; + class ACE_ItemCore; + class ACE_ropeBase: ACE_ItemCore { + scope = 1; + picture = QPATHTOF(data\m_rope_ca.paa); + // model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; // model is Locked to Helicopter DLC + descriptionShort = CSTRING(descriptionShort); + }; + + class ACE_rope3: ACE_ropeBase { + scope = 2; + GVAR(length) = 3.2; + displayName = CSTRING(Rope_3_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 6; + }; + }; + class ACE_rope6: ACE_ropeBase { + scope = 2; + GVAR(length) = 6.2; + displayName = CSTRING(Rope_6_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 18; + }; + }; + class ACE_rope12: ACE_ropeBase { + scope = 2; + GVAR(length) = 12.2; + displayName = CSTRING(Rope_12_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 36; + }; + }; + class ACE_rope15: ACE_ropeBase { + scope = 2; + GVAR(length) = 15.2; + displayName = CSTRING(Rope_15_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 45; + }; + }; + class ACE_rope18: ACE_ropeBase { + scope = 2; + GVAR(length) = 18.3; + displayName = CSTRING(Rope_18_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 54; + }; + }; + class ACE_rope27: ACE_ropeBase { + scope = 2; + GVAR(length) = 27.4; + displayName = CSTRING(Rope_27_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 81; + }; + }; + class ACE_rope36: ACE_ropeBase { + scope = 2; + GVAR(length) = 36.6; + displayName = CSTRING(Rope_36_Display); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 108; + }; + }; +}; diff --git a/addons/logistics_rope/README.md b/addons/logistics_rope/README.md new file mode 100644 index 0000000000..948e8bb2a2 --- /dev/null +++ b/addons/logistics_rope/README.md @@ -0,0 +1,4 @@ +ace_logistics_rope +=================== + +Adds ropes. diff --git a/addons/logistics_rope/config.cpp b/addons/logistics_rope/config.cpp new file mode 100644 index 0000000000..5765cee2cb --- /dev/null +++ b/addons/logistics_rope/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {"ACE_rope3","ACE_rope6","ACE_rope12","ACE_rope15","ACE_rope18","ACE_rope27","ACE_rope36"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {""}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" + diff --git a/addons/fastroping/data/m_rope_ca.paa b/addons/logistics_rope/data/m_rope_ca.paa similarity index 100% rename from addons/fastroping/data/m_rope_ca.paa rename to addons/logistics_rope/data/m_rope_ca.paa diff --git a/addons/logistics_rope/script_component.hpp b/addons/logistics_rope/script_component.hpp new file mode 100644 index 0000000000..b5c11e5b20 --- /dev/null +++ b/addons/logistics_rope/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT logistics_rope +#define COMPONENT_BEAUTIFIED Rope +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_LOGISTICS_ROPE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_LOGISTICS_ROPE + #define DEBUG_SETTINGS DEBUG_SETTINGS_LOGISTICS_ROPE +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/logistics_rope/stringtable.xml b/addons/logistics_rope/stringtable.xml new file mode 100644 index 0000000000..b292ed9499 --- /dev/null +++ b/addons/logistics_rope/stringtable.xml @@ -0,0 +1,128 @@ + + + + + A twisted braid of fibers. Usually used for rappelling or towing. + 組み紐されたロープ。ラペリングやけん引に使用されます。 + Une corde en fibres torsadées. Généralement utilisée pour la descente en rappel ou le remorquage. + Витой канат. Обычно используется для спуска или буксирования. + Ein verdrehtes Geflecht aus Fasern. Wird normalerweise zum Abseilen oder Abschleppen verwendet. + Una Corda composta da fibre intrecciate. Usata per Fastroping o trainare veicoli. + Lina skręcona z włókien. Zwykle używana do zjazdów lub holowania. + 编织绳。通常用于索降和牵引拖曳。 + 꼬아진 섬유입니다. 주로 레펠이나 견인에 사용됩니다. + Malla trenzada de fibras. Normalmente utilizada para descolgarse desde ella o remolcar. + Uma trança torcida de fibras. Normalmente usada para rapel ou reboque. + + + Rope 3.2 meters + 3.2 Meter Seil + Corde de 3,2 mètres + Lina, długość 3,2 m. + Канат 3.2 метра + Corda (3.2m) + Corda da 3.2 metri + Lano 3.2 metrů + 3.2 metre halat + Cuerda de 3.2 metros + ロープ (3.2 メートル) + 绳索(3.2米) + 줄 (3.2m) + + + Rope 6.2 meters + 6.2 Meter Seil + Corde de 6,2 mètres + Lina, długość 6,2 m. + Канат 6.2 метров + Corda (6.2m) + Corda da 6.2 metri + Lano 6.2 metrů + 6.2 metre halat + Cuerda de 6.2 metros + ロープ (6.2 メートル) + 绳索(6.2米) + 줄 (6.2m) + + + Rope 12.2 meters + 12.2 Meter Seil + Corde de 12,2 mètres + ロープ (12.2 メートル) + Lina, długość 12,2 m. + Канат 12.2 метров + Corda (12.2m) + 繩索(12.2公尺長) + 绳索(12.2米) + Corda da 12.2 metri + Lano 12.2 metrů + 12.2 metre halat + Cuerda de 12.2 metros + 줄 (12.2m) + + + Rope 15.2 meters + 15.2 Meter Seil + Corde de 15,2 mètres + ロープ (15.2 メートル) + Lina, długość 15,2 m. + Канат 15.2 метров + Corda (15.2m) + 繩索(15.2公尺長) + 绳索(15.2米) + Corda da 15.2 metri + Lano 15.2 metrů + 15.2 metre halat + Cuerda de 15.2 metros + 줄 (15.2m) + + + Rope 18.3 meters + 18.3 Meter Seil + Corde de 18,3 mètres + ロープ (18.3 メートル) + Lina, długość 18,3 m. + Канат 18.3 метров + Corda (18.3m) + 繩索(18.3公尺長) + 绳索(18.3米) + Corda da 18.3 metri + Lano 18.3 metrů + 18.3 metre halat + Cuerda de 18.3 metros + 줄 (18.3m) + + + Rope 27.4 meters + 27.4 Meter Seil + Corde de 27,4 mètres + ロープ (27.4 メートル) + Lina, długość 27,4 m. + Канат 27.4 метров + Corda (27.4m) + 繩索(27.4公尺長) + 绳索(27.4米) + Corda da 27.4 metri + Lano 27.4 metrů + 27.4 metre halat + Cuerda de 27.4 metros + 줄 (27.4m) + + + Rope 36.6 meters + 36.6 Meter Seil + Corde de 36,6 mètres + ロープ (36.6 メートル) + Lina, długość 36,6 m. + Канат 36.6 метров + Corda (36.6m) + 繩索(36.6公尺長) + 绳索(36.6米) + Corda da 36.6 metri + Lano 36.6 metrů + 36.6 metre halat + Cuerda 36.6 metros + 줄 (36.6m) + + + diff --git a/addons/logistics_uavbattery/CfgEventHandlers.hpp b/addons/logistics_uavbattery/CfgEventHandlers.hpp index be284a9d70..8e27a9f14f 100644 --- a/addons/logistics_uavbattery/CfgEventHandlers.hpp +++ b/addons/logistics_uavbattery/CfgEventHandlers.hpp @@ -1,12 +1,12 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/logistics_uavbattery/CfgVehicles.hpp b/addons/logistics_uavbattery/CfgVehicles.hpp index 6af24e7474..068174e5d7 100644 --- a/addons/logistics_uavbattery/CfgVehicles.hpp +++ b/addons/logistics_uavbattery/CfgVehicles.hpp @@ -6,18 +6,18 @@ class CfgVehicles { }; }; class Helicopter_Base_F: Helicopter { - class ACE_Actions: ACE_Actions{ + class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions {}; }; }; class UAV_01_base_F: Helicopter_Base_F { fuelCapacity = 19; // Around 30 minutes hovering - class ACE_Actions: ACE_Actions{ + class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { class GVAR(RefuelUAV) { displayName = CSTRING(Recharge); - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRefuelUAV)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(refuelUAV)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canRefuelUAV)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(refuelUAV)); icon = QPATHTOF(ui\UAV_battery_ca.paa); }; }; @@ -25,12 +25,36 @@ class CfgVehicles { }; class UAV_06_base_F: Helicopter_Base_F { fuelCapacity = 16; // Around 25 minutes hovering - class ACE_Actions: ACE_Actions{ + class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { class GVAR(RefuelUAV) { displayName = CSTRING(Recharge); - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRefuelUAV)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(refuelUAV)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canRefuelUAV)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(refuelUAV)); + icon = QPATHTOF(ui\UAV_battery_ca.paa); + }; + }; + }; + }; + + class LandVehicle; + class Tank: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + }; + class Tank_F: Tank { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions {}; + }; + }; + class UGV_02_Base_F: Tank_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class GVAR(RefuelUAV) { + displayName = CSTRING(Recharge); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canRefuelUAV)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(refuelUAV)); icon = QPATHTOF(ui\UAV_battery_ca.paa); }; }; diff --git a/addons/logistics_uavbattery/README.md b/addons/logistics_uavbattery/README.md index d32175cb44..fbab339fd9 100644 --- a/addons/logistics_uavbattery/README.md +++ b/addons/logistics_uavbattery/README.md @@ -5,10 +5,3 @@ Adds an item that allows refueling/recharging of the Darter quadcopter UAVs. #### Items Added: `ACE_UAVBattery` - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf index d4e62afa15..3e7ce4f15c 100644 --- a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: marc_book * Tests if unit can refuel the target UAV diff --git a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf index c29be7636a..a471e82cbf 100644 --- a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: marc_book * Starts refueling/recharging the 'Dartar' UAVs @@ -17,7 +17,7 @@ */ params ["_caller", "_target"]; -if (!(_this call FUNC(canRefuelUAV))) exitWith {}; +if !(_this call FUNC(canRefuelUAV)) exitWith {}; private _onFinish = { (_this select 0) params ["_caller", "_target"]; diff --git a/addons/logistics_uavbattery/functions/script_component.hpp b/addons/logistics_uavbattery/functions/script_component.hpp deleted file mode 100644 index 56cb8114f5..0000000000 --- a/addons/logistics_uavbattery/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\logistics_uavbattery\script_component.hpp" \ No newline at end of file diff --git a/addons/logistics_uavbattery/stringtable.xml b/addons/logistics_uavbattery/stringtable.xml index 412e000d9b..9671f451b7 100644 --- a/addons/logistics_uavbattery/stringtable.xml +++ b/addons/logistics_uavbattery/stringtable.xml @@ -5,33 +5,35 @@ Drone is full Drohne ist voll El VANT está lleno - Le drone est chargé + Le drone est chargé. Dron jest naładowany A drón fel van töltve Dron je nabitý O VANT está cheio - Il drone è pieno + Il drone è carico БПЛА полностью заряжен ドローンは充電完了 - 무인기 충전완료 - 无人载具电池已充满 + 무인기 충전 완료 + 无人机电池已充满 無人載具電池已充滿 + IHA Dolu You need a UAV Battery Du brauchst eine UAV-Batterie Necesitas una batería para VANT - Le drone nécessite une batterie + Le drone nécessite une batterie. Potrzebujesz baterii UAV Szükséged van egy UAV akkumulátorra Potřebuješ UAV baterii Você precisa de uma bateria para VANTs - Hai bisogno di una Batteria UAV + Ti serve una Batteria UAV Требуется аккумулятор для БПЛА - UAV バッテリが必要です + UAV バッテリーが必要です 무인기 배터리가 필요합니다 - 你需要一个无人载具电池 + 你需要一个无人机电池 你需要一個無人載具電池 + UAV Bataryaya ihtiyacın var Recharge @@ -48,6 +50,7 @@ 재충전 充电 充電 + Şarj UAV Battery @@ -60,26 +63,28 @@ Bateria para VANT Batteria UAV Аккумулятор БПЛА - UAV バッテリ + UAV バッテリー 무인기 배터리 - 无人载具电池 + 无人机电池 無人載具電池 + UAV Batarya Used to refuel Carried UAV's Verwendet zum Aufladen von tragbaren UAVs - Usada para reabastecer el VANT - Utilisée pour recharger un drone + Usada para reabastecer el VANT transportado + Utilisée pour alimenter un drone en énergie. Używana do naładowania baterii przenośnego UAV Hordozható UAV-k feltöltéséhez való akkumulátor Používané k dobíjení UAV Usada para reabastecer o VANT - Usata per ricaricare la Batteria dell'UAV + Usata per ricaricare le batterie di UAV portabili Используется для зарядки переносных БПЛА 運んでいる UAV を充電に使う - 무인기를 재충전 할때 씁니다. - 对可携式无人载具进行充电 + 무인기를 재충전 할 때 씁니다. + 对可携式无人机进行充电 對可攜式無人載具進行充電 + Used to refuel Carried UAV's Recharging... @@ -90,12 +95,13 @@ Akku feltöltése... Dobíjení... Recarregando... - In ricarica... + Ricaricando... Заряжается... 充電しています・・・ - 充电中... + 正在充电... 充電中... - 충전중... + 충전 중... + Şarj Oluyor diff --git a/addons/logistics_wirecutter/ACE_Arsenal_Stats.hpp b/addons/logistics_wirecutter/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..e317c1a19f --- /dev/null +++ b/addons/logistics_wirecutter/ACE_Arsenal_Stats.hpp @@ -0,0 +1,23 @@ +class EGVAR(arsenal,stats) { + class statBase; + class GVAR(wireCutter): statBase { + scope = 2; + priority = -1; + stats[] = {QGVAR(hasWirecutter)}; + displayName = CSTRING(wirecutterName); + showText = 1; + textStatement = QUOTE(localize QUOTE(ELSTRING(common,yes))); + condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); + tabs[] = {{4,5}, {}}; + }; + class GVAR(wireCutterItem): statBase { + scope = 2; + priority = -1; + stats[] = {"ACE_isWirecutter"}; + displayName = CSTRING(wirecutterName); + showText = 1; + textStatement = QUOTE(localize QUOTE(ELSTRING(common,yes))); + condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); + tabs[] = {{}, {7}}; + }; +}; diff --git a/addons/logistics_wirecutter/CfgEventHandlers.hpp b/addons/logistics_wirecutter/CfgEventHandlers.hpp index 36c0fca8a3..f6503c2479 100644 --- a/addons/logistics_wirecutter/CfgEventHandlers.hpp +++ b/addons/logistics_wirecutter/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/logistics_wirecutter/CfgVehicles.hpp b/addons/logistics_wirecutter/CfgVehicles.hpp index 7dd57f207f..ab27440384 100644 --- a/addons/logistics_wirecutter/CfgVehicles.hpp +++ b/addons/logistics_wirecutter/CfgVehicles.hpp @@ -80,4 +80,19 @@ class CfgVehicles { class Land_BackAlley_01_l_1m_F: Wall_F { GVAR(isFence) = 1; }; + class Land_GameProofFence_01_l_5m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_NetFence_03_m_3m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_NetFence_03_m_3m_corner_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_NetFence_03_m_3m_hole_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_NetFence_03_m_9m_F: Wall_F { + GVAR(isFence) = 1; + }; }; diff --git a/addons/logistics_wirecutter/CfgWeapons.hpp b/addons/logistics_wirecutter/CfgWeapons.hpp index cfaa6c3259..609c84d9ba 100644 --- a/addons/logistics_wirecutter/CfgWeapons.hpp +++ b/addons/logistics_wirecutter/CfgWeapons.hpp @@ -8,6 +8,8 @@ class CfgWeapons { descriptionShort = CSTRING(wirecutterDescription); model = QPATHTOF(data\ace_wirecutter.p3d); picture = QPATHTOF(ui\item_wirecutter_ca.paa); + ACE_isWirecutter = 1; + ACE_isTool = 1; scope = 2; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 25; diff --git a/addons/logistics_wirecutter/README.md b/addons/logistics_wirecutter/README.md index b40242cd86..32a33c9337 100644 --- a/addons/logistics_wirecutter/README.md +++ b/addons/logistics_wirecutter/README.md @@ -5,10 +5,3 @@ Adds an item that allows cutting of fences in Arma 3 and AiA/CUP maps. #### Items Added: `ACE_wirecutter` - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/logistics_wirecutter/XEH_PREP.hpp b/addons/logistics_wirecutter/XEH_PREP.hpp index 6ab95824ff..09cbc1c05d 100644 --- a/addons/logistics_wirecutter/XEH_PREP.hpp +++ b/addons/logistics_wirecutter/XEH_PREP.hpp @@ -1,3 +1,4 @@ PREP(cutDownFence); +PREP(destroyFence); PREP(interactEH); PREP(isFence); diff --git a/addons/logistics_wirecutter/XEH_clientInit.sqf b/addons/logistics_wirecutter/XEH_clientInit.sqf deleted file mode 100644 index 45e93bc6bd..0000000000 --- a/addons/logistics_wirecutter/XEH_clientInit.sqf +++ /dev/null @@ -1,5 +0,0 @@ -#include "script_component.hpp" - -if (!hasInterface) exitWith {}; - -["ace_interactMenuOpened", {_this call FUNC(interactEH)}] call CBA_fnc_addEventHandler; diff --git a/addons/logistics_wirecutter/XEH_postInit.sqf b/addons/logistics_wirecutter/XEH_postInit.sqf new file mode 100644 index 0000000000..fc0a38bf26 --- /dev/null +++ b/addons/logistics_wirecutter/XEH_postInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +if (hasInterface) then { + ["ace_interactMenuOpened", LINKFUNC(interactEH)] call CBA_fnc_addEventHandler; +}; + +if (isServer) then { + [QGVAR(destroyFence), LINKFUNC(destroyFence)] call CBA_fnc_addEventHandler; +}; + +GVAR(possibleWirecutters) = call (uiNamespace getVariable [QGVAR(possibleWirecutters), {[]}]); diff --git a/addons/logistics_wirecutter/XEH_preInit.sqf b/addons/logistics_wirecutter/XEH_preInit.sqf index b47cf6628d..cd05369d60 100644 --- a/addons/logistics_wirecutter/XEH_preInit.sqf +++ b/addons/logistics_wirecutter/XEH_preInit.sqf @@ -6,4 +6,28 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +if (isServer) then { + GVAR(replacements) = createHashMapFromArray [ + ["gameprooffence_01_l_5m_f.p3d", [["Land_GameProofFence_01_l_d_F", [0, 0, 0], 0]]], + ["indfnc_3_f.p3d", [["Land_IndFnc_3_D_F", [0.039, -0.221, 0], 0]]], + ["indfnc_3_hole_f.p3d", [["Land_IndFnc_3_D_F", [0.042, -0.252, 0], 0]]], + ["indfnc_9_f.p3d", [["Land_IndFnc_3_F", [-3, -0.06, 0], 0], ["Land_IndFnc_3_D_F", [0.039, -0.281, 0], 0], ["Land_IndFnc_3_F", [3, -0.06, 0], 0]]], + ["indfnc_corner_f.p3d", [["Land_IndFnc_3_D_F", [0.116, -0.223, 0], 0]]], + ["mil_wiredfence_f.p3d", [["Land_Mil_WiredFenceD_F", [0, 0, 0], 0]]], + ["net_fence_8m_f.p3d", [["Land_Net_FenceD_8m_F", [0, 0.1, 0], 0]]], + ["netfence_01_m_4m_f.p3d", [["Land_NetFence_01_m_d_F", [0, 0, 0], 0]]], + ["netfence_01_m_8m_f.p3d", [["Land_NetFence_01_m_4m_F", [-2, 0, 0], 0], ["Land_NetFence_01_m_d_F", [2, 0, 0], 0]]], + ["netfence_03_m_3m_corner_f.p3d", [["Land_NetFence_03_m_3m_d_F", [0.104, -0.183, 0], 0]]], + ["netfence_03_m_3m_f.p3d", [["Land_NetFence_03_m_3m_d_F", [0.042, -0.236, 0], 0]]], + ["netfence_03_m_3m_hole_f.p3d", [["Land_NetFence_03_m_3m_d_F", [0.045, -0.273, 0], 0]]], + ["netfence_03_m_9m_f.p3d", [["Land_NetFence_03_m_3m_F", [-3.006, -0.073, 0], 0], ["Land_NetFence_03_m_3m_d_F", [0.038, -0.309, 0], 0], ["Land_NetFence_03_m_3m_F", [2.995, -0.073, 0], 0]]], + ["plasticnetfence_01_long_f.p3d", [["Land_PlasticNetFence_01_long_d_F", [0, 0, -0.1], 0]]], + ["wired_fence_4m_f.p3d", [["Land_Wired_Fence_4mD_F", [0, 0, 0], 0]]], + ["wired_fence_8m_f.p3d", [["Land_Wired_Fence_4m_F", [-2, 0, 0], 0], ["Land_Wired_Fence_4mD_F", [3, 0, 0], 0]]], + ["wiredfence_01_16m_f.p3d", [["Land_WiredFence_01_4m_F", [-6, 0, 0], 0], ["Land_WiredFence_01_8m_d_F", [0.34, -0.1, 0], 0]]], + ["wiredfence_01_4m_f.p3d", [["Land_WiredFence_01_pole_F", [-2, 0, 0], 150]]], + ["wiredfence_01_8m_f.p3d", [["Land_WiredFence_01_4m_F", [-2, 0, 0], 0], ["Land_WiredFence_01_pole_F", [0, 0, 0], 0]]] + ]; +}; + ADDON = true; diff --git a/addons/logistics_wirecutter/XEH_preStart.sqf b/addons/logistics_wirecutter/XEH_preStart.sqf index 022888575e..75567fe26e 100644 --- a/addons/logistics_wirecutter/XEH_preStart.sqf +++ b/addons/logistics_wirecutter/XEH_preStart.sqf @@ -1,3 +1,7 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Cache wirecutter item classes, see XEH_postInit.sqf +private _possibleWirecutters = ("getNumber (_x >> 'ACE_isWirecutter') == 1" configClasses (configFile >> "CfgWeapons")) apply {configName _x}; +uiNamespace setVariable [QGVAR(possibleWirecutters), compileFinal str _possibleWirecutters]; diff --git a/addons/logistics_wirecutter/config.cpp b/addons/logistics_wirecutter/config.cpp index c68f362be8..34107e57b1 100644 --- a/addons/logistics_wirecutter/config.cpp +++ b/addons/logistics_wirecutter/config.cpp @@ -17,3 +17,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf index 79da93cf79..2176793aed 100644 --- a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: gpgpgpgp, commy2, PabstMirror, mharis001 * Starts cutting down a fence. Triggers global "ace_wireCuttingStarted" event. @@ -22,7 +22,10 @@ TRACE_2("Fence cutting started",_unit,_fence); if (_unit != ACE_player) exitWith {}; // Get cut time based on if unit is a engineer -private _cutTime = if (_unit call EFUNC(common,isEngineer)) then {CUT_TIME_ENGINEER} else {CUT_TIME_DEFAULT}; +private _cutTime = [ + CUT_TIME_DEFAULT, + CUT_TIME_ENGINEER +] select (_unit call EFUNC(common,isEngineer)); if !(_unit call EFUNC(common,isSwimming)) then { [_unit, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); @@ -35,7 +38,7 @@ if !(_unit call EFUNC(common,isSwimming)) then { TRACE_1("Fence cutting successful",_this); (_this select 0) params ["_unit", "_fence"]; - _fence setDamage 1; + [QGVAR(destroyFence), [_fence]] call CBA_fnc_serverEvent; if !(_unit call EFUNC(common,isSwimming)) then { [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf b/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf new file mode 100644 index 0000000000..9a8bde077b --- /dev/null +++ b/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Destroys the given fence and replaces it with a destroyed fence if possible. + * + * Arguments: + * 0: Fence + * + * Return Value: + * None + * + * Example: + * [fence] call ace_logistics_wirecutter_fnc_destroyFence + * + * Public: No + */ + +params ["_fence"]; + +private _fenceModel = toLowerANSI ((getModelInfo _fence)#0); + +// If fence cannot be replaced with destroyed model, just knock it over +if !(_fenceModel in GVAR(replacements)) exitWith { + _fence setDamage 1; +}; + +// Remove old fence +if ([_fence] call CBA_fnc_isTerrainObject) then { + _fence setDamage 1; + _fence hideObjectGlobal true; +} else { + deleteVehicle _fence; +}; + +// Create replacement(s) +{ + _x params ["_type", "_position", "_dir"]; + + private _replacement = _type createVehicle [0, 0, 0]; + _replacement setPosWorld (_fence modelToWorldWorld _position); + _replacement setDir (direction _fence + _dir); +} forEach (GVAR(replacements) get _fenceModel); diff --git a/addons/logistics_wirecutter/functions/fnc_interactEH.sqf b/addons/logistics_wirecutter/functions/fnc_interactEH.sqf index 87b2a84016..6f5b3218b0 100644 --- a/addons/logistics_wirecutter/functions/fnc_interactEH.sqf +++ b/addons/logistics_wirecutter/functions/fnc_interactEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, mharis001 * Dynamically adds "Cut Fence" actions to nearby fences when interact_menu is opened. @@ -57,8 +57,8 @@ TRACE_1("Starting wirecuter interact PFH",_interactionType); && {[_player, _attachedFence, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && { // Custom LOS check for fence - private _headPos = AGLtoASL (_player modelToWorldVisual (_player selectionPosition "pilot")); - !lineIntersects [_headPos, AGLtoASL (_helper modelToWorldVisual [0, 0, 1.25]), _attachedFence, _player] + private _headPos = _player modelToWorldVisualWorld (_player selectionPosition "pilot"); + !lineIntersects [_headPos, _helper modelToWorldVisualWorld [0, 0, 1.25], _attachedFence, _player] || {!lineIntersects [_headPos, getPosASL _attachedFence, _attachedFence, _player]} } }; diff --git a/addons/logistics_wirecutter/functions/fnc_isFence.sqf b/addons/logistics_wirecutter/functions/fnc_isFence.sqf index 38610f30fb..28c6a254b8 100644 --- a/addons/logistics_wirecutter/functions/fnc_isFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_isFence.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Checks if object is a fence. Should work on any fence type, even when (typeOf == ""). @@ -19,14 +19,4 @@ params ["_object"]; TRACE_1("Checking if fence",_object); -private _typeOf = typeOf _object; - -private _returnValue = if (_typeOf != "") then { - // Check for isFence entry since we have valid typeOf - 1 == getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(isFence)); -} else { - // Check the p3d name against list (in script_component.hpp) - (getModelInfo _object select 0) in FENCE_P3DS; -}; - -_returnValue +getNumber (configOf _object >> QGVAR(isFence)) == 1 || {(getModelInfo _object select 0) in FENCE_P3DS} diff --git a/addons/logistics_wirecutter/functions/script_component.hpp b/addons/logistics_wirecutter/functions/script_component.hpp deleted file mode 100644 index 4a5c48048c..0000000000 --- a/addons/logistics_wirecutter/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\logistics_wirecutter\script_component.hpp" \ No newline at end of file diff --git a/addons/logistics_wirecutter/script_component.hpp b/addons/logistics_wirecutter/script_component.hpp index 69b2c5cdab..7335ef2e57 100644 --- a/addons/logistics_wirecutter/script_component.hpp +++ b/addons/logistics_wirecutter/script_component.hpp @@ -68,7 +68,19 @@ "gm_fence_wirefence_01_03.p3d",\ "gm_gc_g501_sm70_01.p3d",\ "gm_gc_g501_sm70_02.p3d",\ - "gm_gc_g501_sm70_03.p3d"\ + "gm_gc_g501_sm70_03.p3d",\ + "netfence_03_m_3m_f.p3d",\ + "netfence_03_m_3m_hole_f.p3d",\ + "netfence_03_m_3m_corner_f.p3d",\ + "netfence_03_m_9m_f.p3d",\ + "vineyardfence_01_f.p3d",\ + "gameprooffence_01_l_5m_f.p3d",\ + "netfence_01_m_gate_f.p3d",\ + "netfence_02_m_2m_f.p3d",\ + "netfence_02_m_4m_f.p3d",\ + "netfence_02_m_8m_f.p3d",\ + "net_fence_gate_f.p3d",\ + "new_wiredfence_10m_dam_f.p3d"\ ] #define SOUND_CLIP_TIME_SPACING 1.5 @@ -76,7 +88,7 @@ #define CUT_TIME_ENGINEER 7.5 #define HAS_WIRECUTTER(unit) (\ - "ACE_wirecutter" in (unit call EFUNC(common,uniqueItems)) \ - || {1 == getNumber (configFile >> "CfgVehicles" >> (backpack unit) >> QGVAR(hasWirecutter))} \ - || {1 == getNumber (configFile >> "CfgWeapons" >> (vest unit) >> QGVAR(hasWirecutter))} \ + ((unit call EFUNC(common,uniqueItems)) arrayIntersect GVAR(possibleWirecutters)) isNotEqualTo []\ + || {getNumber ((configOf (backpackContainer unit)) >> QGVAR(hasWirecutter)) == 1} \ + || {getNumber (configFile >> "CfgWeapons" >> (vest unit) >> QGVAR(hasWirecutter)) == 1} \ ) diff --git a/addons/logistics_wirecutter/stringtable.xml b/addons/logistics_wirecutter/stringtable.xml index dd4ce0dd2e..224d4239be 100644 --- a/addons/logistics_wirecutter/stringtable.xml +++ b/addons/logistics_wirecutter/stringtable.xml @@ -16,6 +16,7 @@ 절단기 剪铁丝网钳 剪鐵絲網鉗 + Tel Makası Wirecutter @@ -26,12 +27,13 @@ Służą do cięcia drutu i płotów Pince coupante Drótok, huzalok, és kábelek vágására alkalmas olló. - Tronchese + Tronchese per tagliare filo di metallo. Cortador de Arame ワイヤーカッター 절단기 剪铁丝网钳 剪鐵絲網鉗 + Tel Makası Cut Fence @@ -48,6 +50,7 @@ 철조망 자르기 剪断护栏 剪斷護欄 + Çiti/Teli Kes Cutting Fences / Wires... @@ -61,9 +64,10 @@ Drótok elvágása... Разрезаем забор / провода... フェンス/ワイヤを切断しています・・・ - 철망/철조망 자르는중... - 剪断护栏/刺网中... + 철망/철조망 자르는 중... + 正在剪断护栏/刺网... 剪斷護欄/刺網中... + Kesiliyor Çit/Tel Fence cut @@ -80,6 +84,7 @@ 절단됨 护栏已被剪断 護欄已被剪斷 + Çit kesme diff --git a/addons/magazinerepack/ACE_Settings.hpp b/addons/magazinerepack/ACE_Settings.hpp index b66fe5f254..dc82f4e200 100644 --- a/addons/magazinerepack/ACE_Settings.hpp +++ b/addons/magazinerepack/ACE_Settings.hpp @@ -1,26 +1,14 @@ class ACE_Settings { //Time to move a round from one magazine to another class GVAR(timePerAmmo) { - category = CSTRING(DisplayName); - displayName = CSTRING(timePerAmmo); - value = 1.5; - typeName = "SCALAR"; - sliderSettings[] = {1, 10, 1.5, 1}; + movedToSQF = 1; }; //Time to swap between magazines when repacking class GVAR(timePerMagazine) { - category = CSTRING(DisplayName); - displayName = CSTRING(timePerMagazine); - value = 2.0; - typeName = "SCALAR"; - sliderSettings[] = {1, 10, 2, 1}; + movedToSQF = 1; }; //Time to relink 2 belts together class GVAR(timePerBeltLink) { - category = CSTRING(DisplayName); - displayName = CSTRING(timePerBeltLink); - value = 8.0; - typeName = "SCALAR"; - sliderSettings[] = {1, 10, 8, 1}; + movedToSQF = 1; }; }; diff --git a/addons/magazinerepack/CfgEventHandlers.hpp b/addons/magazinerepack/CfgEventHandlers.hpp index be284a9d70..f6503c2479 100644 --- a/addons/magazinerepack/CfgEventHandlers.hpp +++ b/addons/magazinerepack/CfgEventHandlers.hpp @@ -1,12 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/magazinerepack/README.md b/addons/magazinerepack/README.md index e86adcd976..948188f328 100644 --- a/addons/magazinerepack/README.md +++ b/addons/magazinerepack/README.md @@ -2,12 +2,3 @@ ace_magazinerepack ================== Adds the ability to consolidate multiple unfull magazines. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/magazinerepack/XEH_PREP.hpp b/addons/magazinerepack/XEH_PREP.hpp index fc1861dc3d..ba58d49d52 100644 --- a/addons/magazinerepack/XEH_PREP.hpp +++ b/addons/magazinerepack/XEH_PREP.hpp @@ -1,4 +1,4 @@ - +PREP(canRepackMagazine); PREP(getMagazineChildren); PREP(magazineRepackFinish); PREP(magazineRepackProgress); diff --git a/addons/magazinerepack/XEH_postInit.sqf b/addons/magazinerepack/XEH_postInit.sqf new file mode 100644 index 0000000000..8a1cf07ca6 --- /dev/null +++ b/addons/magazinerepack/XEH_postInit.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +// Inventory context menu action to repack magazines +[ + "#Magazine", + ["CONTAINER", "MAGAZINE"], + LSTRING(RepackMagazines), + [], + QPATHTOEF(common,UI\repack_ca.paa), + [ + {true}, + { + params ["_unit", "", "_magazine"]; + + [_unit, _magazine] call FUNC(canRepackMagazine) + } + ], + { + params ["_unit", "", "_magazine"]; + + [_unit, _unit, _magazine] call FUNC(startRepackingMagazine); + } +] call CBA_fnc_addItemContextMenuOption; diff --git a/addons/magazinerepack/XEH_preInit.sqf b/addons/magazinerepack/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/magazinerepack/XEH_preInit.sqf +++ b/addons/magazinerepack/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf b/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf new file mode 100644 index 0000000000..d6d8f3b827 --- /dev/null +++ b/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Checks if the given unit can repack magazines of the given type. + * + * Arguments: + * 0: Unit + * 1: Magazine + * + * Return Value: + * Can Repack Magazine + * + * Example: + * [_unit, _magazine] call ace_magazinerepack_fnc_canRepackMagazine + * + * Public: No + */ + +params ["_unit", "_magazine"]; + +private _maxAmmoCount = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); + +{ + _x params ["_magazineType", "_ammoCount", "_isLoaded"]; + + _magazineType == _magazine // Magazine is of given type + && {_ammoCount > 0 && {_ammoCount < _maxAmmoCount}} // Is a partial magazine + && {!_isLoaded || {GVAR(repackLoadedMagazines) && {[_unit, _magazineType] call CBA_fnc_canAddItem}}} // In inventory or can be moved into it +} count magazinesAmmoFull _unit > 1 diff --git a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf index b1cdef9829..b4cf8b16ef 100644 --- a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf +++ b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, commy2, esteldunedain, Ruthberg * Gets magazine children for interaciton menu. @@ -27,7 +27,7 @@ private _unitMagCounts = []; private _xFullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _xClassname >> "count"); //for every partial magazine, that is either in inventory or can be moved there - if ((_xCount < _xFullMagazineCount) && {_xCount > 0} && {(!_xLoaded) || {_player canAdd _xClassname}}) then { + if ((_xCount < _xFullMagazineCount) && {_xCount > 0} && {(!_xLoaded) || {GVAR(repackLoadedMagazines) && {[_player, _xClassname] call CBA_fnc_canAddItem}}}) then { private _index = _unitMagazines find _xClassname; if (_index == -1) then { _unitMagazines pushBack _xClassname; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index d70899ba56..c2785c5fad 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror (based on repack from commy2, esteldunedain, Ruthberg) * Simulates repacking a set of magazines. @@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {}; // Count mags private _fullMags = 0; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf b/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf index f48d0029fa..8cd5977cca 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror (based on repack from commy2, esteldunedain, Ruthberg) * Handles each frame durring the repack progressBar. diff --git a/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf b/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf index bd7d4dae2a..4782aba840 100644 --- a/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf +++ b/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Simulates repacking a set of magazines. diff --git a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf index cd9df9b2a9..1b4c2d281e 100644 --- a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf +++ b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror (based on repack from commy2, esteldunedain, Ruthberg) * Starts repacking a specific magazine classname. @@ -39,7 +39,7 @@ private _startingAmmoCounts = []; if (_xClassname == _magazineClassname && {_xCount != _fullMagazineCount && {_xCount > 0}}) then { if (_xLoaded) then { //Try to Remove from weapon and add to inventory, otherwise ignore - if (_player canAdd _magazineClassname) then { + if (GVAR(repackLoadedMagazines) && {[_player, _magazineClassname] call CBA_fnc_canAddItem}) then { switch (_xType) do { case (1): {_player removePrimaryWeaponItem _magazineClassname}; case (2): {_player removeHandgunItem _magazineClassname}; @@ -48,6 +48,7 @@ private _startingAmmoCounts = []; }; _player addMagazine [_magazineClassname, _xCount]; _startingAmmoCounts pushBack _xCount; + [LLSTRING(repackLoadedMagazinesHint)] call EFUNC(common,displayTextStructured); }; } else { _startingAmmoCounts pushBack _xCount; @@ -60,6 +61,10 @@ if (count _startingAmmoCounts < 2) exitWith {ERROR("Not Enough Mags to Repack"); private _simEvents = [_fullMagazineCount, _startingAmmoCounts, _isBelt] call FUNC(simulateRepackEvents); private _totalTime = _simEvents select (count _simEvents - 1) select 0; +if (GVAR(repackAnimation)) then { + [_player, "Gear"] call EFUNC(common,doGesture); +}; + [ _totalTime, [_magazineClassname, _startingAmmoCounts, _simEvents], diff --git a/addons/magazinerepack/functions/script_component.hpp b/addons/magazinerepack/functions/script_component.hpp deleted file mode 100644 index d43593994d..0000000000 --- a/addons/magazinerepack/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\magazinerepack\script_component.hpp" \ No newline at end of file diff --git a/addons/magazinerepack/initSettings.inc.sqf b/addons/magazinerepack/initSettings.inc.sqf new file mode 100644 index 0000000000..0bb18f3707 --- /dev/null +++ b/addons/magazinerepack/initSettings.inc.sqf @@ -0,0 +1,41 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(timePerAmmo), "SLIDER", + LSTRING(timePerAmmo), + _category, + [1, 10, 1.5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(timePerMagazine), "SLIDER", + LSTRING(timePerMagazine), + _category, + [1, 10, 2, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(timePerBeltLink), "SLIDER", + LSTRING(timePerBeltLink), + _category, + [1, 10, 8, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(repackLoadedMagazines), "CHECKBOX", + LSTRING(repackLoadedMagazines), + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(repackAnimation), "CHECKBOX", + LSTRING(repackAnimation), + _category, + true, + 0 +] call CBA_fnc_addSetting; diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index 6eab4dd180..9ec8a0fe5a 100644 --- a/addons/magazinerepack/stringtable.xml +++ b/addons/magazinerepack/stringtable.xml @@ -10,7 +10,12 @@ 弾倉詰め替え 탄약 채우기 Przepakowywanie magazynków - Перепаковка Магазинов + Перепаковка магазинов + Preenchimento de Carregador + Remplissage des chargeurs + Přepáskování zásobníků + Şarjör Yeniden Doldurma + Reempaquetado de cargadores Time per round @@ -18,10 +23,15 @@ Durata per proiettile 每發所需時間 每发所需时间 - 弾頭毎の所有時間 - 구경 당 시간 + 弾薬毎の所要時間 + 탄알 당 시간 Czas na nabój Время на патрон + Tempo por projétil + Temps par cartouche + Čas na náboj + Süre başına mermi + Tiempo por cartucho Time per magazine @@ -29,10 +39,15 @@ Durata per caricatore 每匣所需時間 每匣所需时间 - 弾倉毎の所有時間 + 弾倉毎の所要時間 탄창 당 시간 Czas na magazynek Время на магазин + Tempo por carregador + Temps par chargeur + Čas na zásobník + Süre başına şarjör + Tiempo por cargador Time per belt link @@ -40,62 +55,69 @@ Durata per caricatore a nastro 每彈鍊所需時間 每弹炼所需时间 - ベルトリンク毎の所有時間 - 탄약띠 당 시간 + ベルトリンク毎の所要時間 + 탄띠 당 시간 Czas na taśmę Время на звено ленты + Tempo por carregador de cinto + Temps par bande + Čas na článek pásu + Tiempo por enganche de cinta Repack Magazines Magazine umpacken Reorganizar cargadores - Réorganiser les chargeurs + Remplir les chargeurs Przepakuj magazynki Přepáskovat zásobníky Riempi Caricatori - Reorganizar Carregadores + Preencher Carregadores Újratárazás Перепаковать магазины 弾倉を詰め替え 탄창 다시 채우기 重新整理弹匣 重新整理彈匣 + Şarjörleri Yeniden Doldur Repacking Magazines... Magazine umpacken... Reorganizando cargadores... - Réorganisation des chargeurs... + Remplissage des chargeurs... Przepakowywanie magazynków... Přepáskovávám zásobník... Riempendo i caricatori... - Reorganizando Carregadores... + Preenchendo Carregadores... Újratárazás... Перепаковка магазинов... 弾倉を詰め替えしています・・・ - 다시 채우는중... - 重新整理弹匣中 ... + 다시 채우는 중... + 正在整理弹匣 ... 重新整理彈匣中 ... + Şarjör Yeniden Dolduruluyor... %1 full mag(s) and %2 extra round(s) %1 volle(s) Magazin(e) und %2 übrig gebliebene Patrone(n) %1 cargador(es) completo(s) y %2 bala(s) extra(s) - %1 chargeur(s) plein(s) et %2 cartouche(s) en rab + %1 chargeur(s) plein(s) et %2 cartouche(s) en surplus. Pełnych magazynków: %1.<br/>Dodatkowych naboi: %2. %1 plný zásobník(y) a %2 munice navíc %1 caricatore(i) pieno e %2 munizione(i) extra %1 carregador(es) cheio(s) e %2 disparo(s) a mais %1 teljes tár és %2 extra lőszer %1 полных магазина(ов) и %2 патрона(ов) - %1 個の満杯の弾倉とあふれた %2 発の弾薬 + 満装填した弾倉 %1 個と<br/>残 %2 発装填の弾倉 %1개의 꽉찬 탄창과 %2발의 총알이 남았다 %1个满的弹匣与%2发额外子弹 %1個滿的彈匣與%2發額外子彈 + %1 Dolu şarjör ve %2 fazladan mermi Repacking Finished - Réorganisation terminée + Remplissage terminé. Wiederverpacken fertig Reorganización finalizada Перепаковка завершена @@ -103,15 +125,16 @@ Przepakowywanie zakończone Újratárazás befejezve Caricatori Riempiti - Reorganização Terminada - 詰め替えが完了しました + Preenchimento Completo + 詰め替えが完了しました。 탄창 채우기 끝남 - 重整完成 + 整理完成 重整完成 + Yeniden Doldurma Bitti Repacking Interrupted - Réorganisation interrompue + Remplissage interrompu. Umpacken unterbrochen Reorganización interrumpida Перепаковка прервана @@ -119,15 +142,16 @@ Przepakowywanie przerwane Újratárazás megszakítva Riempimento Interrotto - Reorganização Interrompida - 詰め替えを中断しました - 탄창 채우기 방해받음 - 重整被中断 + Preenchimento Interrompido + 詰め替えが中断されました。 + 탄창을 채우는 중 방해받음 + 弹匣整理被打断 重整被中斷 + Yeniden Doldurma Durduruldu %1 Full and %2 Partial - %1 plein(s) et %2 partiel(s) + %1 chargeur(s) plein(s) et %2 chargeur(s) partiel(s). %1 volle(s) Magazin(e) und %2 angefangene(s) Magazin(e) %1 Llenos y %2 Incompletos %1 полных и %2 неполных @@ -136,10 +160,50 @@ %1 teljes és %2 részleges %1 Pieno(i) e %2 Parziale(i) %1 Total e %2 Parcial - %1 個の満杯と %2 個の弾薬入り弾倉 - %1 꽉찼고 %2 부분참 + 満装填した弾倉 %1 個と<br/>部分装填の弾倉 %2 個 + 꽉 찬 탄창:%1<br/>부분적으로 찬 탄창: %2 %1个满的与%2个部分的 %1個滿的與%2個部分的 + %1 Dolu ve %2 Partial + + + Repack Loaded Magazines + 装填済みの弾倉も詰め替える + Remplir le chargeur engagé + Перепаковать загруженные магазины + Geladene Magazine umpacken + Riempi caricatori pieni + Przepakuj załadowane magazynki + 重新整理已上膛的弹匣 + 장전된 탄창에 총알 채우는 중 + Reorganizar cargadores llenos + Preencher Carregadores Engajados + + + Repacking magazines, weapon unloaded + 弾倉の詰め替えのため 武器から弾薬を抜きました + Remplissage des chargeurs, arme déchargée. + Перепаковка магазинов, оружие разряжено + Magazin umgepackt, Waffe entladen + Riempendo i caricatori, arma scarica + Przepakowywanie magazynków, broń rozładowana + 重新整理弹匣,武器未上膛 + 탄창 다시 채우는 중, 무기에서 탄창 뺌 + Reorganizando cargadores, arma descargada + Preenchendo carregadores, arma descarregada + + + Repack Animation + Animation für Umpacken + Animazione per il riempimento + Animacja przepakowywania + 탄약 합치기 애니메이션 + 詰め替え時のアニメーション + 整理动画 + Анимация перепаковки + Animación de reorganizar + Animation de remplissage des chargeurs + Animação de Preenchimento diff --git a/addons/main/CfgSettings.hpp b/addons/main/CfgSettings.hpp index dcb78ffb60..3d62f2d224 100644 --- a/addons/main/CfgSettings.hpp +++ b/addons/main/CfgSettings.hpp @@ -11,6 +11,11 @@ class CfgSettings { compat_rhs_afrf3[] = {"ace_compat_rhs_afrf3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhs_main')"}; compat_rhs_usf3[] = {"ace_compat_rhs_usf3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhsusf_main')"}; compat_rhs_gref3[] = {"ace_compat_rhs_gref3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhsgref_main')"}; + compat_rhs_saf3[] = {"ace_compat_rhs_saf3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhssaf_main')"}; + + //Warnings for missing DLC compat + ace_compat_sog[] = {"ace_compat_sog", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'data_f_vietnam')"}; + ace_compat_gm[] = {"ace_compat_gm", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'gm_core')"}; }; }; }; diff --git a/addons/main/README.md b/addons/main/README.md index aa401a81fa..a3589b2afd 100644 --- a/addons/main/README.md +++ b/addons/main/README.md @@ -2,12 +2,3 @@ ace_main ======== Backbone of other components, defining most of the commonly used macros. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [walterpearce](https://github.com/walterpearce) -- [NouberNou](https://github.com/NouberNou) diff --git a/addons/main/config.cpp b/addons/main/config.cpp index 4852b9ff16..7aa06bc69d 100644 --- a/addons/main/config.cpp +++ b/addons/main/config.cpp @@ -6,18 +6,16 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = { - "A3_Data_F_Enoch_Loadorder", - "A3_Data_F_Mod_Loadorder", - // CBA - "cba_ui", - "cba_xeh", - "cba_jr" - }; + requiredAddons[] = {"cba_main"}; author = ECSTRING(common,ACETeam); url = CSTRING(URL); VERSION_CONFIG; }; + + class XADDON: ADDON { // just in-case anything requires "acex_main" + units[] = {}; + weapons[] = {}; + }; }; class CfgMods { diff --git a/addons/main/script_debug.hpp b/addons/main/script_debug.hpp index bb08e34e09..72b6657094 100644 --- a/addons/main/script_debug.hpp +++ b/addons/main/script_debug.hpp @@ -10,8 +10,8 @@ Fast Recompiling via function #define PREP_RECOMPILE_END }; call _recomp; ACE_RECOMPILES pushBack _recomp; #else #define LINKFUNC(x) FUNC(x) - #define PREP_RECOMPILE_START /* */ - #define PREP_RECOMPILE_END /* */ + #define PREP_RECOMPILE_START ; /* disabled */ + #define PREP_RECOMPILE_END ; /* disabled */ #endif @@ -32,7 +32,7 @@ STACK TRACING #else #define CALLSTACK(function) function #define CALLSTACK_NAMED(function, functionName) function - #define DUMPSTACK + #define DUMPSTACK ; /* disabled */ #endif @@ -51,8 +51,8 @@ PERFORMANCE COUNTERS SECTION #define DUMP_COUNTERS ([__FILE__, __LINE__] call ACE_DUMPCOUNTERS_FNC) #else - #define CREATE_COUNTER(x) /* disabled */ - #define BEGIN_COUNTER(x) /* disabled */ - #define END_COUNTER(x) /* disabled */ - #define DUMP_COUNTERS /* disabled */ + #define CREATE_COUNTER(x) ; /* disabled */ + #define BEGIN_COUNTER(x) ; /* disabled */ + #define END_COUNTER(x) ; /* disabled */ + #define DUMP_COUNTERS ; /* disabled */ #endif diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp index 4414ad1f44..495d592e5f 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -38,6 +38,18 @@ #define GETEGVAR(var1,var2,var3) GETMVAR(EGVAR(var1,var2),var3) #define ARR_SELECT(ARRAY,INDEX,DEFAULT) (if (count ARRAY > INDEX) then {ARRAY select INDEX} else {DEFAULT}) +#define ANY_OF(ARRAY,CONDITION) (ARRAY findIf {CONDITION} != -1) + +// ACEX Merge +#define ACEX_PREFIX acex +#define XADDON DOUBLES(ACEX_PREFIX,COMPONENT) +#define XGVAR(var) DOUBLES(XADDON,var) +#define EXGVAR(var1,var2) TRIPLES(ACEX_PREFIX,var1,var2) +#define QXGVAR(var) QUOTE(XGVAR(var)) +#define QEXGVAR(var1,var2) QUOTE(EXGVAR(var1,var2)) +#define QQXGVAR(var) QUOTE(QXGVAR(var)) +#define QQEXGVAR(var1,var2) QUOTE(QEXGVAR(var1,var2)) +#define ACEX_PREP(func) PREP(func); TRIPLES(XADDON,fnc,func) = DFUNC(func) #define MACRO_ADDWEAPON(WEAPON,COUNT) class _xx_##WEAPON { \ @@ -68,6 +80,7 @@ #define TYPE_MAGAZINE_HANDGUN_AND_GL 16 // mainly #define TYPE_MAGAZINE_PRIMARY_AND_THROW 256 #define TYPE_MAGAZINE_SECONDARY_AND_PUT 512 // mainly +#define TYPE_MAGAZINE_MISSILE 768 // more types #define TYPE_BINOCULAR_AND_NVG 4096 #define TYPE_WEAPON_VEHICLE 65536 @@ -86,7 +99,11 @@ #define TYPE_SCUBA 604 // not implemented #define TYPE_HEADGEAR 605 #define TYPE_FACTOR 607 +#define TYPE_MAP 608 +#define TYPE_COMPASS 609 +#define TYPE_WATCH 610 #define TYPE_RADIO 611 +#define TYPE_GPS 612 #define TYPE_HMD 616 #define TYPE_BINOCULAR 617 #define TYPE_MEDIKIT 619 @@ -115,8 +132,7 @@ #define PFORMAT_10(MESSAGE,A,B,C,D,E,F,G,H,I,J) \ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6, F=%7, G=%8, H=%9, I=%10 J=%11', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E), RETNIL(F), RETNIL(G), RETNIL(H), RETNIL(I), RETNIL(J)] #ifdef DEBUG_MODE_FULL -#define TRACE_10(MESSAGE,A,B,C,D,E,F,G,H,I,J) \ - [THIS_FILE_, __LINE__, PFORMAT_10(MESSAGE,A,B,C,D,E,F,G,H,I,J)] call CBA_fnc_log +#define TRACE_10(MESSAGE,A,B,C,D,E,F,G,H,I,J) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_10(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G,H,I,J)) #else #define TRACE_10(MESSAGE,A,B,C,D,E,F,G,H,I,J) /* disabled */ #endif @@ -126,14 +142,38 @@ #define SD_TO_MIN_MAX(d) ((d) * 3.371) // Standard deviation -> min / max of random [min, mid, max] // Angular unit conversion -#define MRAD_TO_MOA(d) ((d) * 3.43774677) // Conversion factor: 54 / (5 * PI) -#define MOA_TO_MRAD(d) ((d) * 0.29088821) // Conversion factor: (5 * PI) / 54 -#define DEG_TO_MOA(d) ((d) * 60) // Conversion factor: 60 -#define MOA_TO_DEG(d) ((d) / 60) // Conversion factor: 1 / 60 -#define DEG_TO_MRAD(d) ((d) * 17.45329252) // Conversion factor: (50 * PI) / 9 -#define MRAD_TO_DEG(d) ((d) / 17.45329252) // Conversion factor: 9 / (50 * PI) -#define MOA_TO_RAD(d) ((d) * 0.00029088) // Conversion factor: PI / 10800 +// Conversion factor: 54 / (5 * PI) +#define MRAD_TO_MOA(d) ((d) * 3.43774677) +// Conversion factor: (5 * PI) / 54 +#define MOA_TO_MRAD(d) ((d) * 0.29088821) +// Conversion factor: 60 +#define DEG_TO_MOA(d) ((d) * 60) +// Conversion factor: 1 / 60 +#define MOA_TO_DEG(d) ((d) / 60) +// Conversion factor: (50 * PI) / 9 +#define DEG_TO_MRAD(d) ((d) * 17.45329252) +// Conversion factor: 9 / (50 * PI) +#define MRAD_TO_DEG(d) ((d) / 17.45329252) +// Conversion factor: PI / 10800 +#define MOA_TO_RAD(d) ((d) * 0.00029088) #define ZEUS_ACTION_CONDITION ([_target, {QUOTE(QUOTE(ADDON)) in curatorAddons _this}, missionNamespace, QUOTE(QGVAR(zeusCheck)), 1E11, 'ace_interactMenuClosed'] call EFUNC(common,cachedCall)) +#define SUBSKILLS ["aimingAccuracy", "aimingShake", "aimingSpeed", "spotDistance", "spotTime", "courage", "reloadSpeed", "commanding", "general"] + +// macro add a dummy cfgPatch and notLoaded entry +#define ACE_PATCH_NOT_LOADED(NAME,CAUSE) \ +class CfgPatches { \ + class DOUBLES(NAME,notLoaded) { \ + units[] = {}; \ + weapons[] = {}; \ + requiredVersion = REQUIRED_VERSION; \ + requiredAddons[] = {"ace_main"}; \ + VERSION_CONFIG; \ + }; \ +}; \ +class ace_notLoaded { \ + NAME = CAUSE; \ +}; + #include "script_debug.hpp" diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index a02c5c7bd9..12faeb07c0 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -5,15 +5,19 @@ #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.94 -#define REQUIRED_CBA_VERSION {3,11,2} +#define REQUIRED_VERSION 2.14 +#define REQUIRED_CBA_VERSION {3,16,0} -#ifdef COMPONENT_BEAUTIFIED - #define COMPONENT_NAME QUOTE(ACE3 - COMPONENT_BEAUTIFIED) -#else - #define COMPONENT_NAME QUOTE(ACE3 - COMPONENT) +#ifndef COMPONENT_BEAUTIFIED + #define COMPONENT_BEAUTIFIED COMPONENT +#endif +#ifdef SUBCOMPONENT_BEAUTIFIED + #define COMPONENT_NAME QUOTE(ACE3 - COMPONENT_BEAUTIFIED - SUBCOMPONENT_BEAUTIFIED) +#else + #define COMPONENT_NAME QUOTE(ACE3 - COMPONENT_BEAUTIFIED) #endif diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp index fe84527032..75b323ede3 100644 --- a/addons/main/script_version.hpp +++ b/addons/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 3 -#define MINOR 12 -#define PATCHLVL 6 -#define BUILD 43 +#define MINOR 17 +#define PATCHLVL 1 +#define BUILD 86 diff --git a/addons/main/stringtable.xml b/addons/main/stringtable.xml index 9f1a9d6b8d..b676359f74 100644 --- a/addons/main/stringtable.xml +++ b/addons/main/stringtable.xml @@ -6,30 +6,33 @@ ACE Logistik ACE Logistyka Logísticas ACE - ACE: логистика + ACE: Логистика ACE Logistika ACE Logística - Logistica ACE + ACE Logistica ACE Logistique ACE ロジスティクス ACE 后勤 ACE 後勤 - ACE 논리 + ACE 병참 + ACE Lojistik - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ - http://ace3mod.com/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ + https://ace3.acemod.org/ diff --git a/addons/map/CfgAmmo.hpp b/addons/map/CfgAmmo.hpp index aca4042b4f..d54ab0a2c9 100644 --- a/addons/map/CfgAmmo.hpp +++ b/addons/map/CfgAmmo.hpp @@ -1,7 +1,7 @@ class CfgAmmo { - + class Grenade; - + class ACE_FlashlightProxy_White: Grenade { effectsSmoke = "ACE_FlashlightEffect_White"; explosionTime = 0.01; @@ -12,7 +12,7 @@ class CfgAmmo { simulation = "shotSmokeX"; smokeColor[] = {1,1,1,1}; timeToLive = 1e10; - + impactArmor[] = {}; impactConcrete[] = {}; impactDefault[] = {}; @@ -30,24 +30,24 @@ class CfgAmmo { impactWater[] = {}; impactWood[] = {}; }; - + class ACE_FlashlightProxy_Red: ACE_FlashlightProxy_White { effectsSmoke = "ACE_FlashlightEffect_Red"; }; - + class ACE_FlashlightProxy_Blue: ACE_FlashlightProxy_White { effectsSmoke = "ACE_FlashlightEffect_Blue"; }; - + class ACE_FlashlightProxy_Green: ACE_FlashlightProxy_White { effectsSmoke = "ACE_FlashlightEffect_Green"; }; - + class ACE_FlashlightProxy_Yellow: ACE_FlashlightProxy_White { effectsSmoke = "ACE_FlashlightEffect_Yellow"; }; - + class ACE_FlashlightProxy_Orange: ACE_FlashlightProxy_White { effectsSmoke = "ACE_FlashlightEffect_Orange"; }; -}; \ No newline at end of file +}; diff --git a/addons/map/CfgEventHandlers.hpp b/addons/map/CfgEventHandlers.hpp index 6764ab5e7d..b3f4a0296e 100644 --- a/addons/map/CfgEventHandlers.hpp +++ b/addons/map/CfgEventHandlers.hpp @@ -1,20 +1,20 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient)); - serverInit = QUOTE(call COMPILE_FILE(XEH_postInitServer)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient)); + serverInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitServer)); }; }; diff --git a/addons/map/CfgMarkers.hpp b/addons/map/CfgMarkers.hpp index 3dd6463891..303194de00 100644 --- a/addons/map/CfgMarkers.hpp +++ b/addons/map/CfgMarkers.hpp @@ -4,7 +4,7 @@ class CfgMarkers { // Reenable NATO symbols ... class b_unknown: Flag {scope = 2;}; - + // disable all civy markers (harbor etc.) class c_unknown: b_unknown {scope = 1;}; diff --git a/addons/map/CfgVehicles.hpp b/addons/map/CfgVehicles.hpp index 3da69a1216..181978551a 100644 --- a/addons/map/CfgVehicles.hpp +++ b/addons/map/CfgVehicles.hpp @@ -5,11 +5,9 @@ class CfgVehicles { class ACE_MapFlashlight { displayName = CSTRING(Action_Flashlights); icon = QUOTE(\a3\ui_f\data\IGUI\Cfg\VehicleToggles\lightsiconon_ca.paa); - condition = QUOTE(GVAR(mapIllumination) && visibleMap && {!([] isEqualTo (_player call FUNC(getUnitFlashlights)))}); - statement = "true"; + condition = QUOTE(GVAR(mapIllumination) && visibleMap); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; - insertChildren = QUOTE(_this call DFUNC(compileFlashlightMenu)); - showDisabled = 0; + insertChildren = QUOTE(call DFUNC(compileFlashlightMenu)); }; }; }; diff --git a/addons/map/CfgWeapons.hpp b/addons/map/CfgWeapons.hpp index a9188159a3..4d44881ae8 100644 --- a/addons/map/CfgWeapons.hpp +++ b/addons/map/CfgWeapons.hpp @@ -1,10 +1,10 @@ class CfgWeapons { class ItemCore; - class InventoryFlashlightItem_Base_F; + class InventoryFlashLightItem_Base_F; class acc_flashlight: ItemCore { - class ItemInfo: InventoryFlashlightItem_Base_F { + class ItemInfo: InventoryFlashLightItem_Base_F { class FlashLight { ACE_Flashlight_Colour = "white"; ACE_Flashlight_Beam = QPATHTOF(UI\Flashlight_beam_white_ca.paa); @@ -14,7 +14,7 @@ class CfgWeapons { }; }; class acc_flashlight_pistol: ItemCore { - class ItemInfo: InventoryFlashlightItem_Base_F { + class ItemInfo: InventoryFlashLightItem_Base_F { class FlashLight { ACE_Flashlight_Colour = "white"; ACE_Flashlight_Beam = QPATHTOF(UI\Flashlight_beam_white_ca.paa); diff --git a/addons/map/Effects.hpp b/addons/map/Effects.hpp index 5258b225aa..dbd358eaba 100644 --- a/addons/map/Effects.hpp +++ b/addons/map/Effects.hpp @@ -40,4 +40,4 @@ class ACE_FlashlightEffect_Orange { simulation = "light"; type = "ACE_FlashlightLight_Orange"; }; -}; \ No newline at end of file +}; diff --git a/addons/map/MapTweaks.hpp b/addons/map/MapTweaks.hpp index 52edf29341..daafb58636 100644 --- a/addons/map/MapTweaks.hpp +++ b/addons/map/MapTweaks.hpp @@ -27,11 +27,11 @@ class Tree { }; class Legend { - x = SafeZoneX+SafeZoneW-.340; - y = SafeZoneY+SafeZoneH-.152; + x = "SafeZoneX+SafeZoneW-0.340"; + y = "SafeZoneY+SafeZoneH-0.152"; font = "RobotoCondensed"; - w = .340; - h = .152; + w = 0.340; + h = 0.152; sizeEx = 0.039210; colorBackground[] = {0.906000, 0.901000, 0.880000, 0.5}; color[] = {0, 0, 0, 0.75}; diff --git a/addons/map/README.md b/addons/map/README.md index 7567986ba5..617bf875a4 100644 --- a/addons/map/README.md +++ b/addons/map/README.md @@ -7,12 +7,3 @@ Various tweaks to the in-game map, including: - Map shaking while walking (optional) - Map illumination (optional) - Blue Force Tracker (optional) - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [esteldunedain](https://github.com/esteldunedain) -- [NouberNou](https://github.com/NouberNou) diff --git a/addons/map/XEH_PREP.hpp b/addons/map/XEH_PREP.hpp index af6e815fd7..8e2094c29b 100644 --- a/addons/map/XEH_PREP.hpp +++ b/addons/map/XEH_PREP.hpp @@ -13,3 +13,4 @@ PREP(simulateMapLight); PREP(switchFlashlight); PREP(updateMapEffects); PREP(initMainMap); +PREP(isFlashlight); diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index 1982670554..534b37da8b 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -8,7 +8,9 @@ LOG(MSG_INIT); // Calculate the maximum zoom allowed for this map call FUNC(determineZoom); -["ace_settingsInitialized", { +GVAR(flashlights) = createHashMap; + +["CBA_settingsInitialized", { if (isMultiplayer && {GVAR(DefaultChannel) != -1}) then { //Set the chat channel once the map has finished loading [{ @@ -17,19 +19,13 @@ call FUNC(determineZoom); setCurrentChannel GVAR(DefaultChannel); if (currentChannel == GVAR(DefaultChannel)) then { - // INFO_1("Channel Set - %1", currentChannel); + // INFO_1("Channel Set - %1",currentChannel); } else { - ERROR_2("Failed To Set Channel %1 (is %2)", GVAR(DefaultChannel), currentChannel); + ERROR_2("Failed To Set Channel %1 (is %2)",GVAR(DefaultChannel),currentChannel); }; }, 0, []] call CBA_fnc_addPerFrameHandler; }; - // Start Blue Force Tracking if Enabled - if (GVAR(BFT_Enabled)) then { - GVAR(BFT_markers) = []; - [FUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; - }; - //illumination settings if (GVAR(mapIllumination)) then { ["loadout", { @@ -51,7 +47,7 @@ call FUNC(determineZoom); private _unitLight = _player getVariable [QGVAR(flashlight), ["", objNull]]; _unitLight params ["_flashlight", "_glow"]; if (_mapOn) then { - if (!(_flashlight isEqualTo "") && {isNull _glow}) then { + if (_flashlight isNotEqualTo "" && {isNull _glow}) then { [_player, _flashlight] call FUNC(flashlightGlow); if ([_player, _flashlight] call FUNC(needPlaySound)) then {playSound QGVAR(flashlightClick)}; }; @@ -77,8 +73,7 @@ GVAR(hasWatch) = true; GVAR(hasWatch) = false; { if (_x isKindOf ["ItemWatch", configFile >> "CfgWeapons"]) exitWith {GVAR(hasWatch) = true;}; - false - } count (assignedItems _unit); + } forEach (assignedItems _unit); }, true] call CBA_fnc_addPlayerEventHandler; @@ -90,17 +85,20 @@ GVAR(vehicleLightColor) = [1,1,1,0]; ["vehicle", { params ["_unit", "_vehicle"]; if ((isNull _vehicle) || {_unit == _vehicle}) exitWith {}; - private _cfg = configfile >> "CfgVehicles" >> (typeOf _vehicle); + private _cfg = configOf _vehicle; GVAR(vehicleExteriorTurrets) = getArray (_cfg >> QGVAR(vehicleExteriorTurrets)); GVAR(vehicleLightColor) = [_cfg >> QGVAR(vehicleLightColor), "array", [1,1,1,0]] call CBA_fnc_getConfigEntry; // Handle vehicles with toggleable interior lights: private _vehicleLightCondition = getText (_cfg >> QGVAR(vehicleLightCondition)); if (_vehicleLightCondition == "") then { - private _userAction = toLower getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); - switch (true) do { - case ((_userAction find "cabinlights_hide") > 0): {_vehicleLightCondition = "(_vehicle animationSourcePhase 'cabinlights_hide') == 1";}; - case ((_userAction find "cargolights_hide") > 0): {_vehicleLightCondition = "(_vehicle animationSourcePhase 'cargolights_hide') == 1";}; + private _userAction = toLowerANSI getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); + if ( + false // isClass (_cfg >> "compartmentsLights") + || {_userAction find "cabinlights_hide" > 0} + || {_userAction find "cargolights_hide" > 0} + ) then { + _vehicleLightCondition = "false"; }; }; @@ -113,7 +111,7 @@ GVAR(vehicleLightColor) = [1,1,1,0]; } else { switch (true) do { case (_vehicle isKindOf "Tank"); - case (_vehicle isKindOf "Wheeled_APC"): { {true} }; + case (_vehicle isKindOf "Wheeled_APC_F"): { {true} }; case (_vehicle isKindOf "ParachuteBase"): { {false} }; case (_vehicle isKindOf "Helicopter"); case (_vehicle isKindOf "Plane"): { {(driver _vehicle == _unit) || {gunner _vehicle == _unit}} }; @@ -121,3 +119,17 @@ GVAR(vehicleLightColor) = [1,1,1,0]; }; }; }, true] call CBA_fnc_addPlayerEventHandler; + +// compartmentsLights work only when cameraView == "INTERNAL" so we switch it on map opening +["visibleMap", { + params ["_player", "_mapOn"]; + if (_mapOn) then { + if (!isClass (configOf vehicle _player >> "compartmentsLights") || {cameraView == "INTERNAL"}) exitWith {}; + GVAR(cameraViewLast) = cameraView; + vehicle _player switchCamera "INTERNAL"; + } else { + if (isNil QGVAR(cameraViewLast)) exitWith {}; + vehicle _player switchCamera GVAR(cameraViewLast); + GVAR(cameraViewLast) = nil; + }; +}] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/map/XEH_postInitServer.sqf b/addons/map/XEH_postInitServer.sqf index dc0c7f991e..80cbb73d54 100644 --- a/addons/map/XEH_postInitServer.sqf +++ b/addons/map/XEH_postInitServer.sqf @@ -6,7 +6,7 @@ addMissionEventHandler ["HandleDisconnect",{ if (!GVAR(mapGlow)) exitWith {}; private _unitLight = _disconnectedPlayer getVariable [QGVAR(flashlight), ["", objNull]]; _unitLight params ["", "_glow"]; - + if ((!isNull _disconnectedPlayer) && {!isNull _glow}) then { detach _glow; deleteVehicle _glow; diff --git a/addons/map/XEH_preInit.sqf b/addons/map/XEH_preInit.sqf index 92a7e896f3..3d0df4213e 100644 --- a/addons/map/XEH_preInit.sqf +++ b/addons/map/XEH_preInit.sqf @@ -7,6 +7,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/map/config.cpp b/addons/map/config.cpp index aab52c3536..943a63c228 100644 --- a/addons/map/config.cpp +++ b/addons/map/config.cpp @@ -100,7 +100,7 @@ class RscDisplayMainMap { class objects { class Compass: RscObject { scale = 0.7; - zoomDuration = 0; + zoomDuration = 0.1; // 0 (instant transition) breaks Arma saving position/size }; }; }; diff --git a/addons/map/functions/fnc_blueForceTrackingModule.sqf b/addons/map/functions/fnc_blueForceTrackingModule.sqf index 6569fabc35..af95ce3d6d 100644 --- a/addons/map/functions/fnc_blueForceTrackingModule.sqf +++ b/addons/map/functions/fnc_blueForceTrackingModule.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Initializes the blue force tracking module. @@ -22,4 +22,4 @@ params ["_logic"]; [_logic, QGVAR(BFT_HideAiGroups), "HideAiGroups"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(BFT_ShowPlayerNames), "ShowPlayerNames"] call EFUNC(common,readSettingFromModule); -INFO_3("Blue Force Tracking Module Initialized:", GVAR(BFT_Enabled), GVAR(BFT_Interval), GVAR(BFT_HideAiGroups)); +INFO_3("Blue Force Tracking Module Initialized:",GVAR(BFT_Enabled),GVAR(BFT_Interval),GVAR(BFT_HideAiGroups)); diff --git a/addons/map/functions/fnc_blueForceTrackingUpdate.sqf b/addons/map/functions/fnc_blueForceTrackingUpdate.sqf index 9b8e288ac4..54ce2ef87c 100644 --- a/addons/map/functions/fnc_blueForceTrackingUpdate.sqf +++ b/addons/map/functions/fnc_blueForceTrackingUpdate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Update the blue force tracking. @@ -46,7 +46,7 @@ if (GVAR(BFT_Enabled) and {(!isNil "ACE_player") and {alive ACE_player}}) then { private _markerType = [_x] call EFUNC(common,getMarkerType); private _colour = format ["Color%1", side _x]; - private _marker = createMarkerLocal [format ["ACE_BFT_%1", _forEachIndex], [(getPos _x) select 0, (getPos _x) select 1]]; + private _marker = createMarkerLocal [format ["ACE_BFT_player_%1", _forEachIndex], [(getPos _x) select 0, (getPos _x) select 1]]; _marker setMarkerTypeLocal _markerType; _marker setMarkerColorLocal _colour; _marker setMarkerTextLocal (name _x); @@ -67,7 +67,7 @@ if (GVAR(BFT_Enabled) and {(!isNil "ACE_player") and {alive ACE_player}}) then { private _markerType = [_x] call EFUNC(common,getMarkerType); private _colour = format ["Color%1", side _x]; - private _marker = createMarkerLocal [format ["ACE_BFT_%1", _forEachIndex], [(getPos leader _x) select 0, (getPos leader _x) select 1]]; + private _marker = createMarkerLocal [format ["ACE_BFT_group_%1", _forEachIndex], [(getPos leader _x) select 0, (getPos leader _x) select 1]]; _marker setMarkerTypeLocal _markerType; _marker setMarkerColorLocal _colour; _marker setMarkerTextLocal (groupId _x); diff --git a/addons/map/functions/fnc_compileFlashlightMenu.sqf b/addons/map/functions/fnc_compileFlashlightMenu.sqf index c6af389a0a..4dc24a23f6 100644 --- a/addons/map/functions/fnc_compileFlashlightMenu.sqf +++ b/addons/map/functions/fnc_compileFlashlightMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Compile list of flashlight classnames and add to the "Flashlight" parent menu. diff --git a/addons/map/functions/fnc_determineMapLight.sqf b/addons/map/functions/fnc_determineMapLight.sqf index d6a0f09a08..e747d9b400 100644 --- a/addons/map/functions/fnc_determineMapLight.sqf +++ b/addons/map/functions/fnc_determineMapLight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko and esteldunedain * Calculates the current map illumination for a given unit @@ -18,82 +18,45 @@ params ["_unit"]; -// Blend two colors -private _fnc_blendColor = { - params ["_c1", "_c2", "_alpha"]; - [(_c1 select 0) * (1 - _alpha) + (_c2 select 0) * _alpha, - (_c1 select 1) * (1 - _alpha) + (_c2 select 1) * _alpha, - (_c1 select 2) * (1 - _alpha) + (_c2 select 2) * _alpha, - (_c1 select 3) * (1 - _alpha) + (_c2 select 3) * _alpha] -}; - -// Ambient light tint depending on time of day -private _lightTint = call { - if (sunOrMoon == 1.0) exitWith {[0.5,0.5,0.5,1]}; - if (sunOrMoon > 0.80) exitWith {[[1.0 - overcast,0.2,0,1], [1,1,1,1], (sunOrMoon - 0.8) / 0.2] call _fnc_blendColor}; - if (sunOrMoon > 0.50) exitWith {[[0,0,0.1,1], [1.0 - overcast,0.2,0,1], (sunOrMoon - 0.5) / 0.3] call _fnc_blendColor}; - if (sunOrMoon <= 0.5) exitWith {[0,0,0.1,1]}; - [0,0,0,0] -}; - -private _lightLevel = 0.04 + (0.96 * call EFUNC(common,ambientBrightness)); - -// Do not obscure the map if the ambient light level is above 0.95 -if (_lightLevel > 0.95) exitWith { - [false, [1,1,1,0]] -}; - private _vehicle = vehicle _unit; // Do not obscure the map if the player is on a enclosed vehicle (assume internal illumination) -if ((_vehicle != _unit) && {(!isTurnedOut _unit)} && GVAR(vehicleLightCondition) && {!((_unit call CBA_fnc_turretPath) in GVAR(vehicleExteriorTurrets))}) exitWith { +if ( + _vehicle != _unit + && {!isTurnedOut _unit} + && GVAR(vehicleLightCondition) + && {!((_unit call CBA_fnc_turretPath) in GVAR(vehicleExteriorTurrets))} +) exitWith { TRACE_1("Player in a enclosed vehicle",GVAR(vehicleLightColor)); - [!(GVAR(vehicleLightColor) isEqualTo [1,1,1,0]), GVAR(vehicleLightColor)] + [GVAR(vehicleLightColor) isNotEqualTo [1,1,1,0], GVAR(vehicleLightColor)] }; // Player is not in a vehicle TRACE_1("Player is on foot or in an open vehicle",""); -// Check if player is near a campfires, streetlamps, units with flashlights, vehicles with lights on, etc. - 40m +getLightingAt _unit params ["_ambientLightColor", "_ambientLightBrightness", "_dynamicLightColor", "_dynamicLightBrightness"]; + +private _brightness = _ambientLightBrightness + _dynamicLightBrightness; +if (_brightness > 3000) exitWith {[false, [1,1,1,0]]}; + +private _alfa = switch (true) do { + case (_brightness <= 0.2): { 1 }; + case (_brightness <= 2): { linearConversion [0.2, 2, _brightness, 1, 0.86] }; + case (_brightness <= 10): { linearConversion [2, 10, _brightness, 0.86, 0.6] }; + case (_brightness <= 100): { linearConversion [10, 100, _brightness, 0.6, 0.3] }; + case (_brightness <= 200): { linearConversion [100, 200, _brightness, 0.3, 0.14] }; + default { linearConversion [200, 3000, _brightness, 0.14, 0] }; +}; + +private _finalLightColor = []; { - _lightLevel = _lightLevel max ([_unit, _x] call EFUNC(common,lightIntensityFromObject)); -} forEach nearestObjects [_unit, ["All"], 40]; - -// @todo: Illumination flares (timed) - -// Using chemlights -private _nearObjects = (_unit nearObjects ["Chemlight_base", 4]) select {alive _x}; - -if !(_nearObjects isEqualTo []) then { - private _nearestlight = _nearObjects select 0; - private _lightLevelTemp = (1 - ((((_unit distance _nearestlight) - 2) / 2) max 0)) * 0.4; - if (_lightLevelTemp > _lightLevel) then { - private _flareTint = getArray (configFile >> "CfgLights" >> (getText (configFile >> (getText (configFile >> "CfgAmmo" >> typeOf _nearestlight >> "EffectsSmoke")) >> "Light1" >> "type")) >> "color"); - _lightTint = [_lightTint, _flareTint, (_lightLevelTemp - _lightLevel) / (1 - _lightLevel)] call _fnc_blendColor; - _lightLevel = _lightLevelTemp; - TRACE_1("player near chemlight",""); + private _finalColor = (_ambientLightBrightness * _x + _dynamicLightBrightness * (_dynamicLightColor select _forEachIndex)) / _brightness; + if (_alfa > 0.5) then { + _finalColor = _finalColor * (1 - _alfa) / 3; }; -}; + _finalLightColor pushBack _finalColor; +} forEach _ambientLightColor; -// Do not obscure the map if the ambient light level is above 0.95 -if (_lightLevel > 0.95) exitWith { - [false, [1,1,1,0]] -}; +_finalLightColor pushBack _alfa; -// Calculate resulting map color from tint and light level -private _halfLight = _lightLevel / 0.5; - -private _finalLevel = if (_lightLevel < 0.5) then { - [(_lightTint select 0) * _halfLight, - (_lightTint select 1) * _halfLight, - (_lightTint select 2) * _halfLight, - (_lightTint select 3) * (1 - _lightLevel)] -} else { - _halfLight = (_lightLevel - 0.5) / 0.5; - [(_lightTint select 0) * (1 - _halfLight) + _halfLight, - (_lightTint select 1) * (1 - _halfLight) + _halfLight, - (_lightTint select 2) * (1 - _halfLight) + _halfLight, - (_lightTint select 3) * (1 - _lightLevel)] -}; - -[true, _finalLevel] +[true, _finalLightColor] diff --git a/addons/map/functions/fnc_determineZoom.sqf b/addons/map/functions/fnc_determineZoom.sqf index 45a6faeaf2..e8135cc4cf 100644 --- a/addons/map/functions/fnc_determineZoom.sqf +++ b/addons/map/functions/fnc_determineZoom.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko * Calculate the maximum zoom level allowed for the current map diff --git a/addons/map/functions/fnc_flashlightGlow.sqf b/addons/map/functions/fnc_flashlightGlow.sqf index 32615d014b..3263a4b9e8 100644 --- a/addons/map/functions/fnc_flashlightGlow.sqf +++ b/addons/map/functions/fnc_flashlightGlow.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Add or remove global flashlight glow for when player is looking at map. @@ -27,7 +27,7 @@ if (!isNull _glow) then { deleteVehicle _glow; }; -if !(_flashlightType isEqualTo "") then { +if (_flashlightType isNotEqualTo "") then { private _color = getText (configFile >> "CfgWeapons" >> _flashlightType >> "ItemInfo" >> "FlashLight" >> "ACE_Flashlight_Colour"); if !(_color in ["white", "red", "green", "blue", "yellow", "orange"]) then {_color = "white"}; private _class = format ["ACE_FlashlightProxy_%1", _color]; diff --git a/addons/map/functions/fnc_getUnitFlashlights.sqf b/addons/map/functions/fnc_getUnitFlashlights.sqf index d8f537380d..cedc99cfcb 100644 --- a/addons/map/functions/fnc_getUnitFlashlights.sqf +++ b/addons/map/functions/fnc_getUnitFlashlights.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Check a unit for any flashlights that can be used on map. @@ -17,22 +17,4 @@ params ["_unit"]; -private _flashlights = []; -private _cfgWeapons = configFile >> "CfgWeapons"; - -{ - private _weaponConfig = _cfgWeapons >> _x; - if ( - -1 < [ - _weaponConfig >> "ItemInfo" >> "FlashLight", - _weaponConfig >> "FlashLight" - ] findIf { - isText (_x >> "ACE_Flashlight_Colour") - || {!(getArray (_x >> "ambient") in [[], [0,0,0]])} - } - ) then { - _flashlights pushBack _x; - }; -} forEach ([_unit, true] call CBA_fnc_uniqueUnitItems); - -_flashlights +([_unit, true] call CBA_fnc_uniqueUnitItems) select {_x call FUNC(isFlashlight)} // return diff --git a/addons/map/functions/fnc_initMainMap.sqf b/addons/map/functions/fnc_initMainMap.sqf index bebfcbd999..51cb883ba3 100644 --- a/addons/map/functions/fnc_initMainMap.sqf +++ b/addons/map/functions/fnc_initMainMap.sqf @@ -1,5 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "\a3\ui_f\hpp\defineResincl.inc" +/* + * Author: commy2 + * + * Public: No +*/ params ["_display"]; if (ctrlIDD _display != IDD_MAIN_MAP) exitWith {}; @@ -7,6 +12,12 @@ if (ctrlIDD _display != IDD_MAIN_MAP) exitWith {}; private _control = _display displayCtrl IDC_MAP; GVAR(lastStillPosition) = _control ctrlMapScreenToWorld [0.5, 0.5]; +[{ + if (!GVAR(isShaking)) then { // player map position won't be correct until a frame later + GVAR(lastStillPosition) = _this ctrlMapScreenToWorld [0.5, 0.5]; + }; +}, _control] call CBA_fnc_execNextFrame; + GVAR(lastStillTime) = CBA_missionTime; GVAR(isShaking) = false; diff --git a/addons/map/functions/fnc_isFlashlight.sqf b/addons/map/functions/fnc_isFlashlight.sqf new file mode 100644 index 0000000000..ae26b41569 --- /dev/null +++ b/addons/map/functions/fnc_isFlashlight.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Checks if the given item is a flashlight. + * + * Arguments: + * 0: Item Classname + * + * Return Value: + * Is flashlight + * + * Example: + * ["acc_flashlight"] call ace_map_fnc_isFlashlight + * + * Public: No + */ + +params [["_class", "", [""]]]; + +GVAR(flashlights) getOrDefaultCall [_class, { + private _items = ([_class] + (_class call CBA_fnc_switchableAttachments)); + private _cfgWeapons = configFile >> "CfgWeapons"; + + // if this item or any of the switchable items is a flashlight + _items findIf { + private _weaponConfig = _cfgWeapons >> _x; + + [ + _weaponConfig >> "ItemInfo" >> "FlashLight", + _weaponConfig >> "FlashLight" + ] findIf { + isText (_x >> "ACE_Flashlight_Colour") + || {!(getArray (_x >> "ambient") in [[], [0,0,0]]) && {getNumber (_x >> "irLight") == 0}} + } != -1 // return + } != -1 // return +}, true] // return diff --git a/addons/map/functions/fnc_moduleMap.sqf b/addons/map/functions/fnc_moduleMap.sqf index e5747d5955..fbc99d497d 100644 --- a/addons/map/functions/fnc_moduleMap.sqf +++ b/addons/map/functions/fnc_moduleMap.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Initializes the Map module. diff --git a/addons/map/functions/fnc_needPlaySound.sqf b/addons/map/functions/fnc_needPlaySound.sqf index 0c0d34f42e..6636066d09 100644 --- a/addons/map/functions/fnc_needPlaySound.sqf +++ b/addons/map/functions/fnc_needPlaySound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Checks if sound needs to be played when flashlight is toggled. diff --git a/addons/map/functions/fnc_onDrawMap.sqf b/addons/map/functions/fnc_onDrawMap.sqf index 5ad3d42fe0..c81eb40627 100644 --- a/addons/map/functions/fnc_onDrawMap.sqf +++ b/addons/map/functions/fnc_onDrawMap.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/map/functions/fnc_simulateMapLight.sqf b/addons/map/functions/fnc_simulateMapLight.sqf index 7ec9d573a2..0d0bdd51e6 100644 --- a/addons/map/functions/fnc_simulateMapLight.sqf +++ b/addons/map/functions/fnc_simulateMapLight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Draw nearby lighting and sexy flashlight beams on main map. @@ -41,12 +41,15 @@ _lightLevel params ["_r", "_g", "_b", "_a"]; private _colourAlpha = (_r + _g + _b) min _a; private _shadeAlpha = _a; -private _colourList = [_r, _g, _b]; -_colourList sort false; -private _maxColour = _colourList select 0; +private _maxColour = selectMax [_r, _g, _b]; +private _ambientColor = if (_maxColour == 0) then { + [1, 1, 1, _colourAlpha]; +} else { + [_r / _maxColour, _g / _maxColour, _b / _maxColour, _colourAlpha]; +}; //ambient colour fill -_mapCtrl drawIcon ["#(rgb,8,8,3)color(1,1,1,1)", [_r / _maxColour, _g / _maxColour, _b / _maxColour, _colourAlpha], _mapCentre, _screenSize, _screenSize, 0, "", 0]; +_mapCtrl drawIcon ["#(rgb,8,8,3)color(1,1,1,1)", _ambientColor, _mapCentre, _screenSize, _screenSize, 0, "", 0]; if (_flashlight == "") then { //ambient shade fill diff --git a/addons/map/functions/fnc_switchFlashlight.sqf b/addons/map/functions/fnc_switchFlashlight.sqf index 5d4ed9de0a..3502bbc262 100644 --- a/addons/map/functions/fnc_switchFlashlight.sqf +++ b/addons/map/functions/fnc_switchFlashlight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: voiper * Switch flashlight on/off. diff --git a/addons/map/functions/fnc_updateMapEffects.sqf b/addons/map/functions/fnc_updateMapEffects.sqf index 4e8d65bee2..cf6e01bf21 100644 --- a/addons/map/functions/fnc_updateMapEffects.sqf +++ b/addons/map/functions/fnc_updateMapEffects.sqf @@ -1,16 +1,16 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko and esteldunedain * On map draw, updates the effects * * Arguments: - * None + * 0: Map control * * Return Value: * None * * Example: - * call ACE_map_fnc_updateMapEffects + * _mapControl call ACE_map_fnc_updateMapEffects * * Public: No */ @@ -21,7 +21,7 @@ private _mapCentre = _mapCtrl ctrlMapScreenToWorld [0.5, 0.5]; if (GVAR(mapIllumination)) then { //get nearby lighting - private _light = [[ACE_player], FUNC(determineMapLight), missionNamespace, QGVAR(mapLight), 0.1] call EFUNC(common,cachedCall); + private _light = [ACE_player] call FUNC(determineMapLight); _light params ["_applyLighting", "_lightLevel"]; diff --git a/addons/map/functions/script_component.hpp b/addons/map/functions/script_component.hpp deleted file mode 100644 index a9d4b1f265..0000000000 --- a/addons/map/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\map\script_component.hpp" diff --git a/addons/map/initSettings.inc.sqf b/addons/map/initSettings.inc.sqf new file mode 100644 index 0000000000..20665b5a71 --- /dev/null +++ b/addons/map/initSettings.inc.sqf @@ -0,0 +1,104 @@ +[ + QGVAR(mapIllumination), + "CHECKBOX", + [localize LSTRING(MapIllumination_DisplayName), localize LSTRING(MapIllumination_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + true, + true, + {[QGVAR(mapIllumination), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(mapGlow), + "CHECKBOX", + [localize LSTRING(MapGlow_DisplayName), localize LSTRING(MapGlow_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + true, + true, + {[QGVAR(mapGlow), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(mapShake), + "CHECKBOX", + [localize LSTRING(MapShake_DisplayName), localize LSTRING(MapShake_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(mapLimitZoom), + "CHECKBOX", + [localize LSTRING(MapLimitZoom_DisplayName), localize LSTRING(MapLimitZoom_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(mapShowCursorCoordinates), + "CHECKBOX", + [localize LSTRING(MapShowCursorCoordinates_DisplayName), localize LSTRING(MapShowCursorCoordinates_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(DefaultChannel), + "LIST", + [localize LSTRING(DefaultChannel_DisplayName), localize LSTRING(DefaultChannel_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + [[-1, 0, 1, 2, 3, 4, 5], [ELSTRING(common,Disabled), "STR_channel_global", "STR_channel_side", "STR_channel_command", "STR_channel_group", "STR_channel_vehicle", "STR_channel_direct"], 0], + true, + {[QGVAR(DefaultChannel), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +// Blue Force Tracking +[ + QGVAR(BFT_Enabled), + "CHECKBOX", + [localize LSTRING(BFT_Enabled_DisplayName), localize LSTRING(BFT_Enabled_Description)], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], + false, + true, + { + if (GVAR(BFT_Enabled) && {isNil QGVAR(BFT_markers)}) then { + GVAR(BFT_markers) = []; + [LINKFUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; + }; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(BFT_Interval), + "SLIDER", + [localize LSTRING(BFT_Interval_DisplayName), localize LSTRING(BFT_Interval_Description)], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], + [0, 30, 1, 1], + true, + {[QGVAR(BFT_Interval), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(BFT_ShowPlayerNames), + "CHECKBOX", + [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(BFT_HideAiGroups), + "CHECKBOX", + [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], + false, + true +] call CBA_fnc_addSetting; diff --git a/addons/map/initSettings.sqf b/addons/map/initSettings.sqf deleted file mode 100644 index d184c5c1ac..0000000000 --- a/addons/map/initSettings.sqf +++ /dev/null @@ -1,104 +0,0 @@ -[ - QGVAR(mapIllumination), - "CHECKBOX", - [localize LSTRING(MapIllumination_DisplayName), localize LSTRING(MapIllumination_Description)], - format["ACE %1", localize LSTRING(Module_DisplayName)], - true, - true, - {[QGVAR(mapIllumination), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(mapGlow), - "CHECKBOX", - [localize LSTRING(MapGlow_DisplayName), localize LSTRING(MapGlow_Description)], - format["ACE %1", localize LSTRING(Module_DisplayName)], - true, - true, - {[QGVAR(mapGlow), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(mapShake), - "CHECKBOX", - [localize LSTRING(MapShake_DisplayName), localize LSTRING(MapShake_Description)], - format["ACE %1", localize LSTRING(Module_DisplayName)], - true, - true -] call CBA_settings_fnc_init; - -[ - QGVAR(mapLimitZoom), - "CHECKBOX", - [localize LSTRING(MapLimitZoom_DisplayName), localize LSTRING(MapLimitZoom_Description)], - format["ACE %1", localize LSTRING(Module_DisplayName)], - false, - true -] call CBA_settings_fnc_init; - -[ - QGVAR(mapShowCursorCoordinates), - "CHECKBOX", - [localize LSTRING(MapShowCursorCoordinates_DisplayName), localize LSTRING(MapShowCursorCoordinates_Description)], - format["ACE %1", localize LSTRING(Module_DisplayName)], - false, - true -] call CBA_settings_fnc_init; - -[ - QGVAR(DefaultChannel), - "LIST", - [localize LSTRING(DefaultChannel_DisplayName), localize LSTRING(DefaultChannel_Description)], - format["ACE %1", localize LSTRING(Module_DisplayName)], - [[-1, 0, 1, 2, 3, 4, 5], [ELSTRING(common,Disabled), "STR_channel_global", "STR_channel_side", "STR_channel_command", "STR_channel_group", "STR_channel_vehicle", "STR_channel_direct"], 0], - true, - {[QGVAR(DefaultChannel), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -// Blue Force Tracking -[ - QGVAR(BFT_Enabled), - "CHECKBOX", - [localize LSTRING(BFT_Enabled_DisplayName), localize LSTRING(BFT_Enabled_Description)], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], - false, - true, - {[QGVAR(BFT_Enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(BFT_Interval), - "SLIDER", - [localize LSTRING(BFT_Interval_DisplayName), localize LSTRING(BFT_Interval_Description)], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], - [0, 30, 1, 1], - true, - {[QGVAR(BFT_Interval), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(BFT_ShowPlayerNames), - "CHECKBOX", - [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], - false, - true, - {[QGVAR(BFT_ShowPlayerNames), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(BFT_HideAiGroups), - "CHECKBOX", - [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], - false, - true, - {[QGVAR(BFT_HideAiGroups), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index 5052582c9d..5d91167639 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -16,6 +16,7 @@ 지도 地图 地圖 + Harita Map illumination @@ -24,28 +25,29 @@ ¿Iluminación de mapa Osvětlení mapy Iluminação do mapa - Illumination de la carte + Éclairage de la carte Térkép megvilágítása Освещение карты Illuminazione Mappa - 地図に照明 + 地図の照明 지도에 조명 地图照明 地圖照明 + Harita aydınlatması Simulate map lighting based on ambient lighting and player's items? Simuliere Kartenbeleuchtung auf Basis des Umgebungslichts sowie der mitgeführten Gegenstände? Symuluj oświetlenie mapy bazujące na oświetleniu otoczenia oraz przedmiotach gracza? - Calculer la luminosité de la carte en fonction des conditions de lumière ? + Simule l'éclairage de la carte en fonction de l'éclairage ambiant et des objets du joueur. Симулировать освещение карты на основе окружающего света и приборов игрока? Simular a luz do mapa baseado em luz ambiente e itens do jogador? Simular iluminación de mapa basada en la iluminación ambiente y los elementos de los jugadores? Simulovat nasvícení mapy v závisloti na okolí a předmětů hráče? Simula illuminazione della mappa in base alla luce ambientale e agli oggetti del giocatore? - 地図へ環境光やプレイヤーのアイテムに基づいた光のシミュレーションをおこないますか? - 주변 환경및 플레이어 조명에 의한 빛 변화를 지도에 반영할까요? - 透过环境光与玩家的手电筒来决定地图亮度. + 環境光やプレイヤーのアイテムに基づいた地図の照明をシミュレートしますか? + 주변 환경 및 플레이어 조명에 의한 빛 변화를 지도에 반영할까요? + 透过环境光与玩家的手电筒来决定地图亮度。 透過環境光與玩家的物品來決定地圖亮度? @@ -56,10 +58,10 @@ Brilho de lanterna no mapa Resplandor de linterna en el mapa Nasvícení mapy pomocí baterky - Luce della torcia in mappa - Lumière de la lampe de carte - 地図をライトで照らしますか - 지도 조명이 빛이 납니까 + Effetto luminoso sul giocatore + Lueur lampe carte + 地図用ライトの光放射 + 지도 조명 발광 增加地图亮度 增加地圖亮度 @@ -67,15 +69,15 @@ Add external glow to players who use flashlight on map? Kartenbeleuchtung mittels Taschenlampe durch Dritte erkennbar? Pokaż poświatę światła latarki na graczu, który używa latarki na widoku mapy? - Ajouter un effet de lumière sur un joueur utilisant une lampe torche sur la carte ? + Ajoute une lueur externe aux joueurs éclairant leur carte avec une lampe. Добавить свет при использовании фонаря на карте? Adicionar brilho externo para jogadores que usam lanterna no mapa? Añadir resplandor externo a los jugadores que utilizan la linterna en el mapa? Přidat externí záři hráči který používá baterku v mapě? - Aggiungi luce esterna a giocatori che usano la torcia in mappa? - プレイヤが地図上でフラッシュライトを使うと、照らすようにしますか? - 지도에 불빛을 비치는 플레이어를 조금 더 밝게 합니까? - 当玩家打开手电筒时,增加地图亮度. + Aggiungi un effetto di luce sul giocatore che sta usando la torcia in mappa, questo è visibile ad altri giocatori. + マップ上で懐中電灯を使用しているプレイヤーから辺りへの光放射を追加しますか? + 지도에 조명을 사용하는 플레이어에 외부 불빛을 추가합니까? + 当玩家打开手电筒时,增加地图亮度。 當玩家擁有手電筒時,增加地圖亮度? @@ -88,11 +90,12 @@ Tremblement de la carte Térkép-rázkódás Тряска карты - Scuoti la mappa - 地図を揺らしますか + Scuotimento della mappa + 地図の揺れ 지도 흔들림 地图震动 地圖震動 + Harita sarsıntısı Make map shake when walking? @@ -101,13 +104,13 @@ Kamerawackeln beim Gehen? Umožnit třesení mapy za pochodu? Tremer o mapa enquanto caminha? - Faire trembler la carte lors d'un déplacement? + La carte tremble lorsque le joueur marche en la regardant. Rázkódjon-e a térkép mozgáskor? Заставлять карту трястись при ходьбе? Far scuotere la mappa mentre cammini? - 歩いているときは地図を揺らしますか? - 걸을때 지도보면 흔들리게 합니까? - 走路时打开地图会产生晃动. + 歩いているときに地図を揺らしますか? + 걸을 때 지도를 보면 흔들리게 합니까? + 走路时打开地图会产生晃动。 走路時讓地圖有震動的感覺? @@ -117,11 +120,11 @@ Kartenvergrößerung einschränken Omezit přiblížení mapy Limitar zoom do mapa - Limiter le zoom de la carte + Limiter le zoom sur carte Térkép-nagyítás korlátozása Ограничить приближение карты Limita lo zoom in mappa - 地図の拡大を制限しますか + 地図の拡大を制限 지도 확대 제한 限制地图缩放倍率 限制地圖縮放倍率 @@ -133,13 +136,13 @@ Schränkt die maximale Kartenvergrößerung ein. Omezit stupeň přiblížení pro mapu? Limitar a quantidade de zoom disponível para o mapa? - Limiter le zoom maximum de la carte ? + Limite le niveau de zoom sur la carte. Korlátozva legyen-e a nagyítás mennyisége a térképnél? Ограничить максимальное приближение, доступное на карте? - Limita l'ammontare di zoom disponibile per la mappa? + Limita i livelli di zoom disponibili sulla mappa? 地図上で利用できる拡大倍率を制限しますか? 지도 확대에 제한을 둡니까? - 限制地图上可允许缩放的倍率? + 限制地图上可允许缩放的倍率? 限制地圖上可允許縮放的倍率? @@ -149,13 +152,13 @@ Zeige Mauszeiger-Koordinaten Zobrazit souřadnice u kurzoru Mostrar coordenadas no cursor - Afficher les coordonnées sur le curseur + Afficher les coordonnées du curseur Kurzor-koordináták mutatása Показывать координаты курсора Mostra coordinate sul cursore - カーソル先で座標を表示しますか - 커서에 좌표를 보이게 합니까 - 显示游标的座标 + カーソル先の座標を表示 + 커서에 좌표를 보이기 + 显示光标的座标 顯示游標的座標 @@ -165,13 +168,13 @@ Gitter-Koordinaten auf dem Mauszeiger anzeigen? Zobrazit souřadnice u kurzoru v mapě? Mostrar as coordenadas de grade no ponteiro do mouse? - Afficher les coordonnées de la grille à coté du curseur ? + Affiche les coordonnées de la grille sur le pointeur de souris. Mutatva legyen-e a kurzornál található rész rácskoordinátája? Показывать координаты около курсора мыши? - Mostra la griglia coordinate sul cursore mouse? - カーソルに合わせた先を地図座標で表示しますか? + Mostra il numero della coordinata-griglia sul cursore del mouse in mappa? + カーソルで合わせた先の地図グリッド座標を表示しますか? 지도에서 커서 옆에 좌표가 뜨게 합니까? - 显示滑鼠游标所在的网格座标? + 显示鼠标光标所在的网格座标? 顯示滑鼠游標所在的網格座標? @@ -180,14 +183,14 @@ Dieses Modul erweitert die Kartenfunktionen. Tento modul umožňuje přizpůsobit mapu s obrazem. Este módulo permite que você personalize a tela de mapa. - Ce module permet de personnaliser l'écran de la carte. + Ce module permet de personnaliser l'écran de carte. Ez a modul lehetővé teszi a térképnézet testreszabását. Этот модуль позволяет настроить отображение карты. Este módulo permite personalizar la pantalla del mapa. - Questo modulo ti permette di customizzare lo schermo della mappa. + Questo modulo ti permette di personalizzare lo schermo della mappa. このモジュールは地図画面を変更できます。 이 모듈은 지도 화면을 임의로 설정할 수 있게 해줍니다. - 此模块允许自定地图的相关效果. + 此模块允许自定地图的相关效果。 此模塊允許自定地圖的相關效果. @@ -197,13 +200,13 @@ Blue Force Tracking Blue Force Tracking Rastreio de forças azuis - Blue Force Tracking (SFA) + Suivi des Forces Alliées (SFA) Blue Force követés Система слежения Blue Force Tracking Blue Force Tracking - ブルー フォース トラッキング - GPS피아식별기 - 显示蓝方踪迹 + ブルー フォース トラッキング (BFT) + GPS 피아식별기 + 显示蓝方追踪 顯示藍方蹤跡 @@ -213,13 +216,13 @@ Aktywuj BFT Povolit BFT Activar BFT - Activer le Suivi des Forces Alliées + Activer le SFA BFT engedélyezése Включить BFT Abilita BFT BFT を有効化 - GPS피아식별기 켜기 - 蓝方踪迹启用 + GPS 피아식별기 켜기 + 蓝方追踪启用 藍方蹤跡啟用 @@ -229,13 +232,13 @@ Aktywuj Blue Force Tracking. Domyślnie: Nie Povolit Blue Force Tracking. Výchozí: Ne Activar Blue Force Tracking. Por defecto: No - Active le SFA. Défaut : non + Active le SFA. Valeur par défaut : désactivé. Blue Force követés engedélyezése. Alapértelmezett: Nem - Включает систему служения BFT. По-умолчанию: Нет - Abilita Blue Force Tracking. Default: No - ブルー フォース トラッキングを有効化します。標準: 無効 - GPS피아식별기 켭니다. 기본설정: 아니요 - 启用显示蓝方踪迹. 预设: 否 + Включает систему служения BFT. По умолчанию: Нет + Abilita Blue Force Tracking. Predefinito: No + ブルー フォース トラッキングを有効化します。 デフォルト: 無効 + GPS 피아식별기 켭니다. 기본설정: 아니요 + 启用显示蓝方追踪。预设:否 啟用顯示藍方蹤跡. 預設: 否 @@ -261,13 +264,13 @@ Wie oft sollen die Markierungen aktualisiert werden (in Sekunden) Jak často budou značky aktualizovány (v sekundách) Frequência em que os marcadores devem ser atualizados (em segundos) - Fréquence de rafraîchissement des marqueurs ? + Fréquence de rafraîchissement des marqueurs (en secondes). Milyen gyakran frissüljenek a jelölők (másodpercben) Как часто должны обновляться маркеры (в секундах) Quanto spesso vengono aggiornati i marker (in secondi) - マーカが再描画される間隔を設定できます (秒) + マーカが再描画される間隔 (秒単位) 몇 초마다 마커를 새로 갱신합니까? - 设定每多少时间重新标示出单位位置 (秒) + 设定每多少时间重新标示出单位位置(秒) 設定每多少時間重新標示出單位位置 (秒) @@ -277,13 +280,13 @@ KI-Gruppen verstecken Skrýt AI skupiny Esconder grupos de IA - Cacher les groupes d'IA + Cacher les groupes IA AI csoportok elrejtése Скрыть группы ботов - Nascondere gruppi IA - AI グループを非表示にしますか - 인공지능 그룹을 숨깁니까 - 隐藏AI小队 + Nascondi gruppi IA + AIグループを非表示 + 인공지능 그룹 숨기기 + 隐藏 AI 小队 隱藏AI小隊 @@ -293,13 +296,13 @@ Verstecke Marker für "nur KI"-Gruppen? Skrýt značky pouze pro AI skupiny? Esconder marcadores que pertencem ao grupo de IA? - Cacher les marqueurs pour les groupes d'IA seulement ? + Cache les marqueurs pour les groupes composés exclusivement d'unités IA. Jelölők elrejtése "csak AI" csoportoknál? Скрыть маркеры групп, которые состоят полностью из ботов? - Nascondi markers per gruppi di sole IA? - 'AI のみ'グループのマーカを隠しますか? + Nascondi marker per gruppi di sole IA? + 'AIのみ'のグループのマーカー表示有無を設定できます。 인공지능만 있는 그룹의 마커를 숨깁니까? - 隐藏'AI小队'的踪迹? + 隐藏'AI 小队'的追踪? 隱藏'AI小隊'的蹤跡? @@ -313,8 +316,8 @@ Itt található az a játékos nevét Показать имена игроков Mostra i nomi dei giocatori - プレイヤ名を表示しますか - 플레이어 이름을 표시합니까 + プレイヤー名を表示 + 플레이어 이름 표시 显示玩家名称 顯示玩家名稱 @@ -325,13 +328,13 @@ Zeigt die Namen der einzelnen Spieler an Zobrazit názvy jednotlivých hráčů? Mostrar nomes individuais dos jogadores? - Affiche les noms des joueurs individuels ? + Affiche les noms de tous les joueurs individuellement. Itt található az adott játékos neveket? Показать отдельные имена игроков? - Mostra i nomi dei giocatori singoli? - プレイヤの名前を表示しますか? + Mostra i nomi di singoli giocatori? + プレイヤーの名前の表示有無を設定できます。 각 플레이어의 이름을 표시합니까? - 显示玩家的个别名称? + 显示玩家的个别名称? 顯示玩家的個別名稱? @@ -344,10 +347,10 @@ Ez a modul lehetővé teszi a szövetséges egységek követését BFT térképjelzőjkkel. Этот модуль позволяет отслеживать перемещение союзных войск по карте при помощи маркеров BFT. Este módulo permite el seguimiento de las unidades aliadas con marcadores de mapa BFT. - Questo modulo permette il tracciamento di unità alleate con i marker BFT in mappa + Questo modulo permette il tracciamento di unità alleate mediante marker BFT in mappa. モジュールは BFT マップ マーカとともに、同勢力ユニットの追跡を許可します。 이 모듈은 아군을 지도상에서 추적할 수 있게 해줍니다. - 此模块将使你能在地图上看见友方单位的踪迹 + 此模块将使你能在地图上看见友方单位的追踪 此模塊將使你能在地圖上看見友方單位的蹤跡 @@ -359,11 +362,12 @@ Фонари Svítilny Linternas - Torcia + Torce フラッシュライト 손전등 手电筒 手電筒 + Fenerler NVG @@ -375,17 +379,18 @@ NVG NVG NVG - 夜間暗視装置 - 야투경 - 夜视镜 + 暗視装置 + 야간투시경 + 夜视仪 夜視鏡 + NVG On Ein Włącz Ligado - Allumé + Allumée Вкл. Zapnout Encendido @@ -394,13 +399,14 @@ 켜기 开启 開啟 + Açık Off Aus Wyłącz Desligado - Éteins + Éteinte Выкл. Vypnout Apagado @@ -409,6 +415,7 @@ 끄기 关闭 關閉 + Kapali Increase Brightness @@ -455,6 +462,7 @@ %1 켜기 开启%1 開啟%1 + %1 'i aç Turn Off %1 @@ -471,6 +479,7 @@ %1 끄기 关闭%1 關閉%1 + %1 'i Kapat Set Channel At Start @@ -481,8 +490,8 @@ Zvolit kanál po startu Imposta Canale all'Avvio Setear canal al comenzar - Mettre un canal par défaut - 開始時のチャンネルを決定 + Définir un canal par défaut + 開始時のチャンネルを指定 시작시 채널 设定游戏开始时的聊天频道 設定遊戲開始時的聊天頻道 @@ -494,11 +503,11 @@ Muda o canal do marcador no início da missão Изменить начальный канал для установки маркеров при запуске миссии Nastavit kanál po startu mise - Cambia il canale marker iniziale all'avvio di missione + Cambia il canale marker iniziale all'avvio della missione Cambiar el canal de marcadores inicial al comenzar la misión Change le canal de communication par défaut au début de la mission. - ミッション開始時にあらかじめ設定されているマーカ チャンネルを変更します - 미션시작시 마커채널을 변경합니다 + ミッション開始時に使用されるマーカーチャンネルの指定を変更します + 미션 시작시 마커채널을 변경합니다 更改任务启动时的聊天频道 更改任務啟動時的聊天頻道 @@ -506,25 +515,31 @@ Disable BFT BFT deaktivieren BFTを無効化 - GPS피아식별기 끄기 + GPS 피아식별기 끄기 Wyłącz BFT - Désactive le BFT + Désactiver le SFA Disablita BFT - 关闭友军踪迹 + 关闭友军追踪 關閉友軍蹤跡 Отключить BFT + Desativar BFT + Vypnout sledování přátelských jednotek (BFT). + Desabilitar BFT Always disable Blue Force Tracking for this group. Blue Force Tracking für diese Gruppe immer deaktivieren. このグループへのブルー フォース トラッキングを常に無効化します。 - 이 그룹에 한해 GPS피아식별기를 항상 끕니다. + 이 그룹에 한해 GPS 피아식별기를 항상 끕니다. Zawsze wyłączaj Blue Force Tracking dla tej grupy. - Désactive en permanence le Blue Force Tracking pour ce groupe. + Désactive en permanence le Suivi des Forces Alliées pour ce groupe. Disabilita sempre il Blue Force Tracking per questo gruppo. - 对此小队永远关闭友军踪迹显示 + 对此小队永远关闭友军追踪显示 對此小隊永遠關閉友軍蹤跡顯示 Всегда отключать Blue Force Tracking для этой группы + Sempre desativar Rastreio Blue Force (BFT) para esse grupo. + Vždy vypne sledování přátelských jednotek (BFT) pro tuto skupinu. + Deshabilitar siempre Blue Force Tracking para este grupo. diff --git a/addons/map_gestures/ACE_Settings.hpp b/addons/map_gestures/ACE_Settings.hpp index d74d58a1a5..668902584c 100644 --- a/addons/map_gestures/ACE_Settings.hpp +++ b/addons/map_gestures/ACE_Settings.hpp @@ -1,49 +1,20 @@ class ACE_Settings { class GVAR(enabled) { - displayName = CSTRING(enabled_displayName); - description = CSTRING(enabled_description); - category = CSTRING(mapGestures_category); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(maxRange) { - displayName = CSTRING(maxRange_displayName); - description = CSTRING(maxRange_description); - category = CSTRING(mapGestures_category); - typeName = "SCALAR"; - value = 7; - sliderSettings[] = {0, 50, 7, 1}; + movedToSQF = 1; }; class GVAR(interval) { - displayName = CSTRING(interval_displayName); - description = CSTRING(interval_description); - category = CSTRING(mapGestures_category); - typeName = "SCALAR"; - value = 0.03; - sliderSettings[] = {0, 1, 0.03, 2}; + movedToSQF = 1; }; class GVAR(nameTextColor) { - displayName = CSTRING(nameTextColor_displayName); - description = CSTRING(nameTextColor_description); - category = CSTRING(mapGestures_category); - isClientSettable = 1; - typeName = "COLOR"; - value[] = {0.2, 0.2, 0.2, 0.3}; + movedToSQF = 1; }; class GVAR(defaultLeadColor) { - displayName = CSTRING(defaultLeadColor_displayName); - description = CSTRING(defaultLeadColor_description); - category = CSTRING(mapGestures_category); - isClientSettable = 1; - typeName = "COLOR"; - value[] = {1, 0.88, 0, 0.95}; + movedToSQF = 1; }; class GVAR(defaultColor) { - displayName = CSTRING(defaultColor_displayName); - description = CSTRING(defaultColor_description); - category = CSTRING(mapGestures_category); - isClientSettable = 1; - typeName = "COLOR"; - value[] = {1, 0.88, 0, 0.7}; + movedToSQF = 1; }; }; diff --git a/addons/map_gestures/CfgEventHandlers.hpp b/addons/map_gestures/CfgEventHandlers.hpp index becf395052..053d85ed3e 100644 --- a/addons/map_gestures/CfgEventHandlers.hpp +++ b/addons/map_gestures/CfgEventHandlers.hpp @@ -1,18 +1,34 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + +class Extended_DisplayLoad_EventHandlers { + class RscDisplayCurator { + ADDON = QUOTE(((_this select 0) displayCtrl ID_CURATOR_MAP) call FUNC(initDisplayCurator)); + }; + class RscDisplayEGSpectator { + ADDON = QUOTE((((_this select 0) displayCtrl ID_EG_MAP_CONTROL) controlsGroupCtrl ID_EG_MAP_CONTROLGROUP) call FUNC(initDisplaySpectator)); + }; + + class RscDiary { // for loading saves use uiNamespace because missionNamespace is not restored before map is loaded +#ifdef DISABLE_COMPILE_CACHE + ADDON = QUOTE(((_this select 0) displayCtrl ID_DIARY_MAP) call (missionNamespace getVariable [ARR_2('DFUNC(initDisplayDiary)',uiNamespace getVariable 'DFUNC(initDisplayDiary)')])); +#else + ADDON = QUOTE(((_this select 0) displayCtrl ID_DIARY_MAP) call (uiNamespace getVariable 'DFUNC(initDisplayDiary)')); +#endif }; }; diff --git a/addons/map_gestures/XEH_PREP.hpp b/addons/map_gestures/XEH_PREP.hpp index 8d457bd7e0..5ffeeb4bd7 100644 --- a/addons/map_gestures/XEH_PREP.hpp +++ b/addons/map_gestures/XEH_PREP.hpp @@ -1,12 +1,9 @@ - PREP(addGroupColorMapping); PREP(drawMapGestures); -PREP(endTransmit); PREP(getProximityPlayers); -PREP(initTransmit); +PREP(initDisplayCurator); +PREP(initDisplayDiary); +PREP(initDisplaySpectator); PREP(isValidColorArray); PREP(moduleGroupSettings); PREP(moduleSettings); -PREP(receiverInit); -PREP(transmit); -PREP(transmitterInit); diff --git a/addons/map_gestures/XEH_postInit.sqf b/addons/map_gestures/XEH_postInit.sqf index cc3daf6a06..d5e68c1ba2 100644 --- a/addons/map_gestures/XEH_postInit.sqf +++ b/addons/map_gestures/XEH_postInit.sqf @@ -4,29 +4,7 @@ if (["STMapGestures"] call EFUNC(common,isModLoaded)) exitWith { WARNING("st_map_gestures is installed - exiting [remove st_map_gestures.pbo to allow ace version]"); }; -if (!hasInterface) exitWith {}; - -["ace_settingsInitialized", { - if (!GVAR(enabled)) exitWith {}; - - // This will set QEGVAR(common,playerOwner) var on player objects - [] call EFUNC(common,setPlayerOwner); - - GVAR(pointPosition) = [0,0,0]; - - [QGVAR(syncPos), { - params ["_unit", "_pointPos"]; - _unit setVariable [QGVAR(pointPosition), _pointPos]; - }] call CBA_fnc_addEventHandler; - - [{ - if (isNull (findDisplay 12)) exitWith {}; - - params ["", "_pfhId"]; - - call FUNC(receiverInit); - call FUNC(transmitterInit); - - [_pfhId] call CBA_fnc_removePerFrameHandler; - }, 1, []] call CBA_fnc_addPerFrameHandler; -}] call CBA_fnc_addEventHandler; +["visibleMap", { + GVAR(EnableTransmit) = false; + ACE_player setVariable [QGVAR(pointPosition), nil, true]; // Instantly transmit nil to stop drawing icon +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/map_gestures/XEH_preInit.sqf b/addons/map_gestures/XEH_preInit.sqf index 92387036e4..42090ac724 100644 --- a/addons/map_gestures/XEH_preInit.sqf +++ b/addons/map_gestures/XEH_preInit.sqf @@ -6,6 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace; +#include "initSettings.inc.sqf" + +GVAR(GroupColorCfgMappingNew) = createHashMap; ADDON = true; diff --git a/addons/map_gestures/config.cpp b/addons/map_gestures/config.cpp index b7bbf791e7..50efc35265 100644 --- a/addons/map_gestures/config.cpp +++ b/addons/map_gestures/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; + units[] = {QGVAR(moduleGroupSettings)}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; diff --git a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf index eaf319bc90..f533f9df34 100644 --- a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf +++ b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, MikeMatrix, PabstMirror * Adds a group id color mapping. @@ -25,7 +25,7 @@ TRACE_3("params",_group,_leadColor,_unitColor); if (_group isEqualType grpNull) then {_group = groupID _group}; if (_group == "") exitWith {ERROR("Group ID is blank, which is not valid.")}; -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; -if (!([_unitColor] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_unitColor] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; -GVAR(GroupColorCfgMappingNew) setVariable [_group, [_leadColor, _unitColor]]; +GVAR(GroupColorCfgMappingNew) set [toLower _group, [_leadColor, _unitColor]]; diff --git a/addons/map_gestures/functions/fnc_drawMapGestures.sqf b/addons/map_gestures/functions/fnc_drawMapGestures.sqf index 2aecd2388f..0a69c1924b 100644 --- a/addons/map_gestures/functions/fnc_drawMapGestures.sqf +++ b/addons/map_gestures/functions/fnc_drawMapGestures.sqf @@ -1,20 +1,22 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Receives and draws map gestures from nearby players. * * Arguments: * 0: Map Handle + * 1: Positions (objects or posAGLs) with render distance >> * * Return Value: * None * * Example: - * [findDisplay 12 displayCtrl 51] call ace_map_gesutres_fnc_drawMapGestures + * [findDisplay 12 displayCtrl 51, [[player, 0]]] call ace_map_gestures_fnc_drawMapGestures * * Public: No */ + BEGIN_COUNTER(draw); #define ICON_RENDER_SIZE 55 @@ -26,36 +28,28 @@ BEGIN_COUNTER(draw); #define TEXT_SIZE 0.030 #define TEXT_SHADOW 0 -if (!GVAR(enabled) || !visibleMap) exitWith {}; - -params ["_mapHandle"]; - +if (!GVAR(enabled)) exitWith {}; +params ["_mapHandle", "_positions"]; +private _players = [_positions, FUNC(getProximityPlayers), missionNamespace, QGVAR(proximityPlayersCache), 1] call EFUNC(common,cachedCall); // Iterate over all nearby players and render their pointer if player is transmitting. { - + private _pos = _x getVariable QGVAR(pointPosition); // Only render if the unit is alive and transmitting - if (alive _x && {_x getVariable [QGVAR(Transmit), false]}) then { - - private _pos = _x getVariable [QGVAR(pointPosition), [0,0,0]]; - - private _group = group _x; - private _grpName = groupID _group; - - // If color settings for the group exist, then use those, otherwise fall back to the default colors - private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable _grpName; - private _color = if (isNil "_colorMap") then { - [GVAR(defaultLeadColor), GVAR(defaultColor)] select (_x != leader _group); - } else { - _colorMap select (_x != leader _group); + if (alive _x && { !isNil "_pos" }) then { + if (_x == ACE_player && { !isNil QGVAR(cursorPosition) }) then { + _pos = GVAR(cursorPosition); }; + // If color settings for the group exist, then use those, otherwise fall back to the default colors + private _colorMap = GVAR(GroupColorCfgMappingNew) getOrDefault [toLower groupID (group _x), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; + private _color = _colorMap select (_x != leader _x); + TRACE_2("",_colorMap,_color); - + // Render icon and player name _mapHandle drawIcon ["\a3\ui_f\data\gui\cfg\Hints\icon_text\group_1_ca.paa", _color, _pos, ICON_RENDER_SIZE, ICON_RENDER_SIZE, ICON_ANGLE, "", ICON_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; - _mapHandle drawIcon ["#(argb,8,8,3)color(0,0,0,0)", GVAR(nameTextColor), _pos, TEXT_ICON_RENDER_SIZE, TEXT_ICON_RENDER_SIZE, ICON_ANGLE, name _x, TEXT_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; + _mapHandle drawIcon ["#(argb,1,1,1)color(0,0,0,0)", GVAR(nameTextColor), _pos, TEXT_ICON_RENDER_SIZE, TEXT_ICON_RENDER_SIZE, ICON_ANGLE, name _x, TEXT_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; }; - nil -} count ([ACE_player, GVAR(maxRange)] call FUNC(getProximityPlayers)); +} forEach _players; END_COUNTER(draw); diff --git a/addons/map_gestures/functions/fnc_endTransmit.sqf b/addons/map_gestures/functions/fnc_endTransmit.sqf deleted file mode 100644 index e591cd39ba..0000000000 --- a/addons/map_gestures/functions/fnc_endTransmit.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Dslyecxi, MikeMatrix - * Ensure that all variables used to indicate transmission are disabled. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_map_gestures_fnc_endTransmit - * - * Public: No - */ - -if (!GVAR(enabled)) exitWith {}; - -ACE_player setVariable [QGVAR(Transmit), false, true]; -GVAR(EnableTransmit) = false; diff --git a/addons/map_gestures/functions/fnc_getProximityPlayers.sqf b/addons/map_gestures/functions/fnc_getProximityPlayers.sqf index 9718095b01..43853da494 100644 --- a/addons/map_gestures/functions/fnc_getProximityPlayers.sqf +++ b/addons/map_gestures/functions/fnc_getProximityPlayers.sqf @@ -1,25 +1,56 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Returns all players in a given range and in the units vehicle. * * Arguments: - * 0: Unit + * 0: Positions (objects or posAGLs) * 1: Range * * Return Value: - * All units in proximity + * All units in proximity with Distances to render from >> * * Example: - * [player, 7] call ace_map_gestures_fnc_getProximityPlayers + * [[[player, 6]]] call ace_map_gestures_fnc_getProximityPlayers * * Public: No */ -params ["_unit", "_range"]; +private _proximityPlayers = []; -private _proximityPlayers = (getPos _unit) nearEntities [["CAMAnBase"], _range]; -_proximityPlayers deleteAt (_proximityPlayers find _unit); -_proximityPlayers append (crew vehicle _unit); +private _fnc_getProximitsPlayers = { + { + _x params ["_position", ["_range", GVAR(maxRange)]]; + private _temp = (_position nearEntities [["CAMAnBase"], _range]); + if (_position isEqualType objNull) then { + _temp append (crew vehicle _position); + if (GVAR(onlyShowFriendlys)) then { + _temp = _temp select { [side group _position, side _x] call BIS_fnc_areFriendly; }; + }; + }; + _proximityPlayers append _temp; + } forEach _this; +}; -_proximityPlayers select {[_x, false] call EFUNC(common,isPlayer);} +switch (_this) do { + case (0): { // All + _proximityPlayers append allUnits; + }; + case (1): { // Players in Group + _proximityPlayers append units ace_player; + }; + case (2): { // Players on Side + _proximityPlayers append (allUnits select {side (group _x) == side (group ace_player)}); + }; + case (3): { // Proximity + [[ace_player, GVAR(maxRange)]] call _fnc_getProximitsPlayers; + }; + case (4): {}; // Disabled + default { + _this call _fnc_getProximitsPlayers; + }; +}; + +_proximityPlayers = _proximityPlayers arrayIntersect _proximityPlayers; +_proximityPlayers = _proximityPlayers select { [_x, false] call EFUNC(common,isPlayer); }; +_proximityPlayers diff --git a/addons/map_gestures/functions/fnc_initDisplayCurator.sqf b/addons/map_gestures/functions/fnc_initDisplayCurator.sqf new file mode 100644 index 0000000000..1337ea4220 --- /dev/null +++ b/addons/map_gestures/functions/fnc_initDisplayCurator.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: joko // Jonas + * Binds Draw EventHandlers to Zeus map. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * _mapCtrl call ace_map_gestures_fnc_initDisplayCurator + * + * Public: No + */ +params ["_mapCtrl"]; +TRACE_1("initDisplayCurator",_mapCtrl); + +_mapCtrl ctrlAddEventHandler ["Draw", { + if (!GVAR(allowCurator)) exitWith {}; + [_this select 0, [[ACE_player, GVAR(maxRange)], [positionCameraToWorld [0, 0, 0], GVAR(maxRangeCamera)]]] call FUNC(drawMapGestures); +}]; diff --git a/addons/map_gestures/functions/fnc_initDisplayDiary.sqf b/addons/map_gestures/functions/fnc_initDisplayDiary.sqf new file mode 100644 index 0000000000..5d77b229b5 --- /dev/null +++ b/addons/map_gestures/functions/fnc_initDisplayDiary.sqf @@ -0,0 +1,60 @@ +#include "..\script_component.hpp" +/* + * Author: Dslyecxi, MikeMatrix, joko // Jonas + * Bind all required EventHandlers to Player map. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * _mapCtrl call ace_map_gestures_fnc_initDisplayDiary + * + * Public: No + */ +params ["_mapCtrl"]; +TRACE_1("initDisplayDiary",_mapCtrl); + +_mapCtrl ctrlAddEventHandler ["Draw", { + if (!GVAR(enabled)) exitWith {}; + if (getClientStateNumber < 10) then { + [_this select 0, GVAR(briefingMode)] call FUNC(drawMapGestures); + } else { + [_this select 0, [[ACE_player, GVAR(maxRange)]]] call FUNC(drawMapGestures); + }; +}]; + +// MouseMoving EH. +_mapCtrl ctrlAddEventHandler ["MouseMoving", { + if (!GVAR(enabled)) exitWith {}; + params ["_control", "_posX", "_posY"]; + GVAR(cursorPosition) = _control ctrlMapScreenToWorld [_posX, _posY]; + + // Don't transmit any data if we're using the map tools + if (!GVAR(EnableTransmit) || {(["ace_maptools"] call EFUNC(common,isModLoaded)) && {EGVAR(maptools,mapTool_isDragging) || EGVAR(maptools,mapTool_isRotating)}}) exitWith {}; + if (GVAR(cursorPosition) distance2D (ACE_player getVariable [QGVAR(pointPosition), [0, 0, 0]]) >= 1) then { + [ACE_player, QGVAR(pointPosition), GVAR(cursorPosition), GVAR(interval)] call EFUNC(common,setVariablePublic); + }; +}]; + +// MouseDown EH +_mapCtrl ctrlAddEventHandler ["MouseButtonDown", { + if (!GVAR(enabled)) exitWith {}; + params ["", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; + if (_button == 0 && {[_shift, _ctrl, _alt] isEqualTo [false, false, false]}) then { + GVAR(EnableTransmit) = true; + [ACE_player, QGVAR(pointPosition), GVAR(cursorPosition), GVAR(interval)] call EFUNC(common,setVariablePublic); + }; +}]; + +// MouseUp EH +_mapCtrl ctrlAddEventHandler ["MouseButtonUp", { + if (!GVAR(enabled)) exitWith {}; + params ["", "_button"]; + if (_button == 0) then { + GVAR(EnableTransmit) = false; + ACE_player setVariable [QGVAR(pointPosition), nil, true]; // Instantly transmit nil to stop drawing icon + }; +}]; diff --git a/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf b/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf new file mode 100644 index 0000000000..dbbd31ae65 --- /dev/null +++ b/addons/map_gestures/functions/fnc_initDisplaySpectator.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: joko // Jonas + * Binds Draw EventHandlers to Spectator map. + * + * Arguments: + * 0: Map Handle from a spectator gui + * + * Return Value: + * None + * + * Example: + * _mapCtrl call ace_map_gestures_fnc_initDisplaySpectator + * + * Public: No + */ +params ["_mapCtrl"]; +TRACE_1("initDisplaySpectator",_mapCtrl); + +_mapCtrl ctrlAddEventHandler ["Draw", { + if (!GVAR(allowSpectator)) exitWith {}; + private _targets = [[positionCameraToWorld [0, 0, 0], GVAR(maxRangeCamera)]]; + + private _aceSpectatorFocus = missionNamespace getVariable [QEGVAR(spectator,camFocus), objNull]; + if (!isNull _aceSpectatorFocus) then { + _targets pushback [_aceSpectatorFocus, GVAR(maxRange)]; + }; + private _vanillaSpectatorFocus = uiNamespace getVariable ["RscEGSpectator_focus", objNull]; + if (!isNull _vanillaSpectatorFocus) then { + _targets pushback [_vanillaSpectatorFocus, GVAR(maxRange)]; + }; + [_this select 0, _targets] call FUNC(drawMapGestures); +}]; diff --git a/addons/map_gestures/functions/fnc_initTransmit.sqf b/addons/map_gestures/functions/fnc_initTransmit.sqf deleted file mode 100644 index 782b4c9666..0000000000 --- a/addons/map_gestures/functions/fnc_initTransmit.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Dslyecxi, MikeMatrix - * Initializes transmitting map gestures. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_map_gestures_fnc_initTransmit - * - * Public: No - */ - -if (!GVAR(enabled)) exitWith {}; - -GVAR(EnableTransmit) = true; -[FUNC(transmit), GVAR(interval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/map_gestures/functions/fnc_isValidColorArray.sqf b/addons/map_gestures/functions/fnc_isValidColorArray.sqf index 8abaf4f375..bcd5fea38c 100644 --- a/addons/map_gestures/functions/fnc_isValidColorArray.sqf +++ b/addons/map_gestures/functions/fnc_isValidColorArray.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: MikeMatrix * Validate if an array is in the propper color format. @@ -20,7 +20,7 @@ scopeName "main"; params ["_colorArray"]; if (isNil "_colorArray") exitWith {false}; -if (!(_colorArray isEqualType [])) exitWith {false}; +if !(_colorArray isEqualType []) exitWith {false}; if (count _colorArray != 4) exitWith {false}; { diff --git a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf index fb87822a30..36bef695d5 100644 --- a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes Settings for the groups modules and transcodes settings to a useable format. @@ -24,9 +24,10 @@ if (!_activated) exitWith {}; // Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1] private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; + private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); -if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_color] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; // Add all synchronized groups and reference custom configuration for them { diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index 93525226ea..22913dceef 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes Settings for the module and transcodes settings to a useable format. @@ -12,7 +12,7 @@ * None * * Example: - * [module, [player], true] call ace_map_gestures_fnc_moduleGroupSettings + * [module, [player], true] call ace_map_gestures_fnc_moduleSettings * * Public: No */ @@ -29,14 +29,14 @@ if (!_activated) exitWith {}; private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; if (_defaultLeadColor != "") then { _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); - if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; + if !([_defaultLeadColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultLeadColor), _defaultLeadColor, true]] call CBA_fnc_localEvent; }; private _defaultColor = _logic getVariable ["defaultColor", ""]; if (_defaultColor != "") then { _defaultColor = call compile ("[" + _defaultColor + "]"); - if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; + if !([_defaultColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultColor), _defaultColor, true]] call CBA_fnc_localEvent; }; diff --git a/addons/map_gestures/functions/fnc_receiverInit.sqf b/addons/map_gestures/functions/fnc_receiverInit.sqf deleted file mode 100644 index 0effb9a7d5..0000000000 --- a/addons/map_gestures/functions/fnc_receiverInit.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Dslyecxi, MikeMatrix - * Initializes the receiver and hooks it to the Draw event of the map. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_map_gestures_fnc_receiverInit - * - * Public: No - */ - -ACE_player setVariable [QGVAR(Transmit), false, true]; -GVAR(EnableTransmit) = false; - -if (!isNil QGVAR(DrawMapHandlerID)) then { - (findDisplay 12 displayCtrl 51) ctrlRemoveEventHandler ["Draw", GVAR(DrawMapHandlerID)]; - GVAR(DrawMapHandlerID) = nil; -}; -GVAR(DrawMapHandlerID) = findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", {call FUNC(drawMapGestures)}]; diff --git a/addons/map_gestures/functions/fnc_transmit.sqf b/addons/map_gestures/functions/fnc_transmit.sqf deleted file mode 100644 index 1b1f462f01..0000000000 --- a/addons/map_gestures/functions/fnc_transmit.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Dslyecxi, MikeMatrix - * Transmit PFH - * - * Arguments: - * 0: Arguments - * 1: PFH ID - * - * Return Value: - * Return description - * - * Example: - * [[], 2] call ace_map_gestures_fnc_transmit - * - * Public: No - */ - -BEGIN_COUNTER(transmit); - -params ["", "_pfhId"]; - -if (!visibleMap) then { - call FUNC(endTransmit); -}; - -if (!GVAR(EnableTransmit) || !visibleMap) exitWith { - [_pfhId] call CBA_fnc_removePerFrameHandler; -}; - -{ - private _owner = _x getVariable [QEGVAR(common,playerOwner), -1]; - if (_owner > -1) then { - private _remotePos = _x getVariable [QGVAR(remotePos), [0,0,0]]; - if ((_remotePos distance2d GVAR(pointPosition)) > 1) then { // Only transmit when actually moving - [QGVAR(syncPos), [ACE_Player, GVAR(pointPosition)], _owner] call CBA_fnc_ownerEvent; - _x setVariable [QGVAR(remotePos), GVAR(pointPosition)]; - }; - }; -} count ([ACE_player, GVAR(maxRange)] call FUNC(getProximityPlayers)); - -END_COUNTER(transmit); diff --git a/addons/map_gestures/functions/fnc_transmitterInit.sqf b/addons/map_gestures/functions/fnc_transmitterInit.sqf deleted file mode 100644 index a081ef5b14..0000000000 --- a/addons/map_gestures/functions/fnc_transmitterInit.sqf +++ /dev/null @@ -1,68 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Dslyecxi, MikeMatrix - * Initializes the transmitting event handlers. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_map_gestures_fnc_transmitterInit - * - * Public: No - */ - -disableSerialization; - -private _mapCtrl = findDisplay 12 displayCtrl 51; - -// MouseMoving EH. -if (!isNil QGVAR(MouseMoveHandlerID)) then { - _mapCtrl ctrlRemoveEventHandler ["MouseMoving", GVAR(MouseMoveHandlerID)]; - GVAR(MouseMoveHandlerID) = nil; -}; -GVAR(MouseMoveHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseMoving", { - // Don't transmit any data if we're using the map tools - if (!GVAR(EnableTransmit) || {(["ace_maptools"] call EFUNC(common,isModLoaded)) && {EGVAR(maptools,mapTool_isDragging) || EGVAR(maptools,mapTool_isRotating)}}) exitWith {}; - - params ["_control", "_posX", "_posY"]; - - if (!(ACE_player getVariable QGVAR(Transmit))) then { - ACE_player setVariable [QGVAR(Transmit), true, true]; - }; - - GVAR(pointPosition) = _control ctrlMapScreenToWorld [_posX, _posY]; -}]; - -// MouseDown EH -if (!isNil QGVAR(MouseDownHandlerID)) then { - _mapCtrl ctrlRemoveEventHandler ["MouseButtonDown",GVAR(MouseDownHandlerID)]; - GVAR(MouseDownHandlerID) = nil; -}; -GVAR(MouseDownHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseButtonDown", { - if (!GVAR(enabled)) exitWith {}; - - params ["", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; - - if (_button == 0 && {[_shift, _ctrl, _alt] isEqualTo [false, false, false]}) then { - call FUNC(initTransmit); - }; -}]; - -// MouseUp EH -if (!isNil QGVAR(MouseUpHandlerID)) then { - _mapCtrl ctrlRemoveEventHandler ["MouseButtonUp", GVAR(MouseUpHandlerID)]; - GVAR(MouseUpHandlerID) = nil; -}; -GVAR(MouseUpHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseButtonUp", { - if (!GVAR(enabled)) exitWith {}; - - params ["", "_button"]; - - if (_button == 0) then { - call FUNC(endTransmit); - }; -}]; diff --git a/addons/map_gestures/functions/script_component.hpp b/addons/map_gestures/functions/script_component.hpp deleted file mode 100644 index 65841c15f9..0000000000 --- a/addons/map_gestures/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\map_gestures\script_component.hpp" diff --git a/addons/map_gestures/initSettings.inc.sqf b/addons/map_gestures/initSettings.inc.sqf new file mode 100644 index 0000000000..2d9bc6b695 --- /dev/null +++ b/addons/map_gestures/initSettings.inc.sqf @@ -0,0 +1,88 @@ +private _category = LLSTRING(mapGestures_category); +private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcategory_colors)]]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_displayName), LSTRING(enabled_description)], + _category, + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(maxRange), "SLIDER", + [LSTRING(maxRange_displayName), LSTRING(maxRange_description)], + _category, + [0,50,7,1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(maxRangeCamera), "SLIDER", + [LSTRING(maxRangeCamera_displayName), LSTRING(maxRangeCamera_description)], + _category, + [0,50,14,1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(allowSpectator), "CHECKBOX", + [LSTRING(allowSpectator_displayName), LSTRING(allowSpectator_description)], + _category, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(allowCurator), "CHECKBOX", + [LSTRING(allowCurator_displayName), LSTRING(allowCurator_description)], + _category, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(briefingMode), "LIST", + [LSTRING(briefingMode_displayName), LSTRING(briefingMode_description)], + _category, + [[0, 1, 2, 3, 4], [LSTRING(briefingMode_All), LSTRING(briefingMode_Group), LSTRING(briefingMode_Side), LSTRING(briefingMode_Proximity), LSTRING(briefingMode_Disabled)], 0] +] call CBA_fnc_addSetting; + +[ + QGVAR(onlyShowFriendlys), + "CHECKBOX", + [LSTRING(onlyShowFriendlys_displayName), LSTRING(onlyShowFriendlys_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(interval), "SLIDER", + [LSTRING(interval_displayName), LSTRING(interval_description)], + _category, + [0,1,0.03,2], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(nameTextColor), "COLOR", + [LSTRING(nameTextColor_displayName), LSTRING(nameTextColor_description)], + _categoryColors, + [0.2,0.2,0.2,0.3], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(defaultLeadColor), "COLOR", + [LSTRING(defaultLeadColor_displayName), LSTRING(defaultLeadColor_description)], + _categoryColors, + [1,0.88,0,0.95], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(defaultColor), "COLOR", + [LSTRING(defaultColor_displayName), LSTRING(defaultColor_description)], + _categoryColors, + [1,0.88,0,0.7], + false +] call CBA_fnc_addSetting; diff --git a/addons/map_gestures/script_component.hpp b/addons/map_gestures/script_component.hpp index ca428f8725..92cef1c662 100644 --- a/addons/map_gestures/script_component.hpp +++ b/addons/map_gestures/script_component.hpp @@ -15,3 +15,8 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define ID_CURATOR_MAP 50 +#define ID_EG_MAP_CONTROL 63909 +#define ID_EG_MAP_CONTROLGROUP 62609 +#define ID_DIARY_MAP 51 diff --git a/addons/map_gestures/stringtable.xml b/addons/map_gestures/stringtable.xml index feb98f2091..91f07c7cdf 100644 --- a/addons/map_gestures/stringtable.xml +++ b/addons/map_gestures/stringtable.xml @@ -1,7 +1,7 @@ - - + + Map Gestures Gestos no mapa Gesty na mapie @@ -10,13 +10,14 @@ Gesti Mappa Kartenzeichen Gestos en mapa - Gestes de carte - マップ ジェスチャ + Pointage sur carte + マップ ジェスチャー 지도 신호 - 地图标识器 + 地图指示 地圖指示器 + Harita Hareketleri - + Enabled Ativado Aktywne @@ -25,13 +26,30 @@ Abilita Aktiviert Activado - Activer + Activé 有効化 켜기 启用 啟用 + Etkin - + + Enables the Map Gestures. + Ativa os gestos no mapa + Aktywuje gesty na mapie. + Включает указания на карте. + Povolit ukazování v mapě + Abilita i Gesti in Mappa + Aktiviert die Kartenzeichen. + Activar Gestos en Mapa + Active le pointage sur carte. + マップ ジェスチャーを有効化 + 지도 신호 활성화 + 启用地图指示 + 啟用地圖指示器 + Harita hareketlerini etkinleştir. + + Map Gesture Max Range Distância para gestos no mapa Maks. zasięg gestów @@ -40,63 +58,128 @@ Distanza Massima Gesti Mappa Maximale Reichweite der Kartenzeichen Máx. dist. para gestos en mapa - Distance max. des gestes de carte - マップ ジェスチャの最大範囲 + Portée du pointage sur carte + マップ ジェスチャーの最大範囲 지도 신호 최대 거리 - 地图标识器最大范围 + 地图指示最大范围 地圖指示器最大範圍 + Harita Hareketi Max Uzaklık - - Max range between players to show the map gesture indicator [default: 7 meters] - Distância max. entre os jogadores para mostrar o indicador de gesto no mapa [padrão: 7 metros] - Maksymalny zasięg, w obrębie którego gesty będą widoczne dla graczy [domyślnie: 7 metrów] - Макс. дистанция между игроками для отображения жестов на карте [по-умолчанию: 7 метров] - Maximální vzdálenost mezi hráči pro zobrazení indikátoru ukázání v mapě [výchozí: 7 metrů] - Distanza massima tra giocatori per mostrare i gesti in mappa [default: 7 metri] - Maximale Reichweite zwischen Spielern um Kartenzeichen anzuzeigen (Standard: 7 Meter) - Máxima distancia a la cual pueden verse el indicador de gestos [defecto: 7 m] - Distance max. entre les joueurs pour montrer le pointage sur carte. (Défaut : 7m) - プレイヤのマップ ジェスチャによる表示範囲を設定します [標準:7 メートル] - 플레이어간에 지도 신호 표시거리를 설정합니다. [기본: 7 미터] - 设定地图标识器显示的最大范围距离 [预设: 7公尺] - 設定地圖指示器顯示的最大範圍距離 [預設: 7公尺] + + Max range between players to show the map gesture indicator + Distância max. entre os jogadores para mostrar o indicador de gesto no mapa + Maksymalny zasięg, w obrębie którego gesty będą widoczne dla graczy + Макс. дистанция между игроками для отображения жестов на карте + Maximální vzdálenost mezi hráči pro zobrazení indikátoru ukázání v mapě + Distanza massima tra giocatori per mostrare i gesti in mappa + Maximale Reichweite zwischen Spielern um Kartenzeichen anzuzeigen + Máxima distancia a la cual pueden verse el indicador de gestos + Définit le rayon au-delà duquel un joueur ne verra plus l'indicateur de pointage des autres joueurs. + マップ ジェスチャーのインジケーターを表示可能なプレーヤー間の最大距離 + 플레이어간에 지도 신호 표시거리를 설정합니다. + 设定地图指示显示的最大范围距离 + 設定地圖指示器顯示的最大範圍距離 - + + Update Interval + Intervalo de atualizações + Interwał aktualizacji + Интервал обновления + Interval aktualizace + Intervallo Aggiornamenti + Update-Intervall + Período de actualización + Intervalle de mise à jour + 更新間隔 + 갱신 간격 + 更新间隔 + 更新間隔 + Güncelleme aralığı + + + Time between data updates. + Tempo entre atualização de dados + Odstęp pomiędzy aktualizacjami danych + Время между обновлениями данных. + Čas mezi aktualizacemi dat. + Intervallo tra aggiornamenti dati. + Zeit zwischen Datenupdates. + Tiempo entre actualizaciones sucesivas. + Période de mise à jour des données. + データの更新間隔 + 데이터 갱신 간격 + 定义每次更新数据的时间。 + 定義每次更新數據的時間 + Veri güncellemeleri arasındaki zaman. + + + Name Text Color + Cor do texto do nome + Kolor nazw + Цвет текста имени + Barva textu pro jména + Colore Testo Nome + Farbe der Namenstexte. + Color de los nombres + Couleur du texte du nom + 名前の文字色 + 글 색상 명칭 + 名称文字颜色 + 名稱文字顏色 + Isim Metin Rengi + + + Color of the name tag text besides the map gestures mark. + Cor do texto da etiqueta de nome que fica embaixo da marcação de gestos no mapa. + Kolor nazwy gracza obok markera gestu mapy. + Цвет инмени игрока рядом с маркером жестов. + Colore del testo dei nametag accanto agli indicatori di gesti in mappa. + Farbe der Namenstexte neben der Kartenzeichen-Markierung. + Color de los nombres dibujados al lado del marcados de gestos. + Définit la couleur du texte pour le nom à côté du marqueur de pointage sur carte. + マップ ジェスチャーに添えて表示される名前の文字色。 + 지도 색상에 표시되는 이름의 색상을 결정합니다. + 定义名称文字颜色。使其与地图指示颜色有所区别。 + 定義名稱文字顏色。使其與地圖指示器顏色有所區別 + Barva jména zobrazeného vedle značky ukazovátka na mapě. + + Lead Default Color Cor padrão para o líder Domyślny kolor lidera - Лид. цвет по-умолчанию + Лид. цвет по умолчанию Výchozí barva velitele - Colore Default Caposquadra + Colore Caposquadra Predefinito Gruppenführer-Standardfarbe Color por defecto para el lider - Couleur principale de commandement. - リーダー用標準の色 + Couleur de commandement par défaut + 部隊長用の標準色 리더 기본 색상 队长预设颜色 隊長預設顏色 - + Fallback Color value for group leaders when there is no group setting. [Module: leave blank to not force on clients] Valor de cor alternativa para líderes de grupo Domyślny kolor dla liderów grup. Значение цвета для лидеров групп. - Colore di riserva dei capisquadra quando non c'è nessuna impostazione gruppo. [Modulo: lascia vuoto per non forzare su clients] + Colore di riserva per gli indicatori dei capisquadra quando non c'è nessuna impostazione per il gruppo. [Modulo: lascia vuoto per non forzare su client] Ersatz-Farbwert für Gruppenführer wenn keine Gruppeneinstellung vorhanden ist. [Modul: leer lassen um Anwendung bei Clients nicht zu erzwingen] Color por defecto para líderes cuando no está configurado [Módulo: dejar en blanco para no forzar] - Couleur par défaut pour les chefs de groupe quand il n'y a pas de réglage pour le groupe. (Module : laisser vide pour ne pas forcer chez les clients) - グループ設定が存在しない場合に、グループ リーダーへ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] - 그룹 설정이 없는 경우 리더의 예비 색상 값입니다. [모듈: 클라이언트에서 강체치 않기 위해 공백으로 비워둘것] - 当没有设定小队颜色时,此功能会定义队长的标识器颜色。[模块: 此栏留空来保持预设颜色] + Définit la couleur par défaut pour les chefs de groupe quand il n'y a pas de réglage de groupe. [Module : laisser vide pour ne pas forcer chez les clients.] + グループ設定がない場合に部隊長へ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] + 그룹 설정이 없는 경우 리더의 예비 색상 값입니다. [모듈: 클라이언트에서 강체하지 않기 위해 공백으로 비워둘 것] + 当没有设定小队颜色时,此功能会定义队长的指示颜色。[模块:此栏留空来保持预设颜色] 當沒有設定小隊顏色時,此功能會定義隊長的指示器顏色。[模塊: 此欄留空來保持預設顏色] + Záložní barva pro velitele skupin pokud není žádné skupinové nastavení [Modul: ponechat prázdné abyste nepřepsali nastavení klientů] - + Default Color Cor padrão Kolor domyślny - Цвет по-умолчанию + Цвет по умолчанию Výchozí barva - Colore Default + Colore Predefinito Standardfarbe Color por defecto Couleur par défaut @@ -104,22 +187,24 @@ 기본 색상 预设颜色 預設顏色 + Varsayılan Renk - + Fallback Color value when there is no group setting. [Module: leave blank to not force on clients] Valor alternativo de cor Kolor domyślny Значение цвета. - Colore di riserva quando non ci sono impostazioni gruppo. [Modulo: lascia vuto per non forzare sui clients] + Colore di riserva quando non c'è un'impostazione per il gruppo. [Modulo: lascia vuoto per non forzare sui client] Ersatz-Farbwert wenn keine Gruppeneinstellung vorhanden ist. [Modul: leer lassen um Anwendung bei Clients nicht zu erzwingen] Color por defecto cuando no está configurado [Módulo: dejar en blanco para no forzar] - Couleur par défaut quand il n'y a pas de réglage pour le groupe. (Module : laisser vide pour ne pas forcer chez les clients) - グループ設定が存在しない場合に、グループ リーダーへ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] - 그룹 설정이 없을 경우의 예비 색상입니다. [모듈: 클라이언트에서 강체치 않기 위해 공백으로 비워둘것] - 当没有设定小队颜色时,此功能会定义玩家的标识器颜色。[模块: 此栏留空来保持预设颜色] + Définit la couleur par défaut quand il n'y a pas de réglage pour le groupe. [Module : laisser vide pour ne pas forcer chez les clients.] + グループ設定がない場合に設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] + 그룹 설정이 없을 경우의 예비 색상입니다. [모듈: 클라이언트에서 강체하지 않기 위해 공백으로 비워둘 것] + 当没有设定小队颜色时,此功能会定义玩家的指示颜色。[模块:此栏留空来保持预设颜色] 當沒有設定小隊顏色時,此功能會定義玩家的指示器顏色。[模塊: 此欄留空來保持預設顏色] + Záložní barva pokud není žádné skupinové nastavení [Modul: ponechat prázdné abyste nepřepsali nastavení klientů] - + Lead Color Cor do líder Kolor lidera @@ -129,12 +214,12 @@ Gruppenführer-Farbe Color para el líder Couleur de commandement - リーダー用の色 + 部隊長用の色 리더 색상 队长颜色 隊長顏色 - + Color value for group leaders of groups synced with this module. Valor de cor para líderes de grupo sincronizados com este módulo. Kolor dla liderów grup zsynchronizowanych z tym modułem. @@ -142,13 +227,14 @@ Colore dei Caposquadra per gruppi sincronizzati con questo modulo. Farbwert für Gruppenführer, die mit diesem Modul synchronisiert werden. Color para los líderes de los grupos sincronizados al módulo. - Couleur pour les chefs de groupe des groupes synchronisés avec le module. - モジュールで同期されたグループのリーダー用に色の値を決定します。 - 그룹이 이 모듈에 동기화 됐을때의 리더 색상입니다. - 改变与此同步小队队长的标识器颜色。 + Couleur pour les chefs des groupes synchronisés avec ce module. + モジュールで同期されたグループの隊長に設定される色の値。 + 그룹이 이 모듈에 동기화 됐을 때의 리더 색상입니다. + 改变与此同步小队队长的指示颜色。 改變與此同步小隊隊長的指示器顏色 + Barva pro velitele skupin které jsou synchronizované s tímto modulem. - + Color Cor Kolor @@ -162,8 +248,9 @@ 색상 颜色 顏色 + Renk - + Color value for group members of groups synced with this module. Valor de cor para membros de grupo sincronizados com este módulo. Kolor dla członków grup zsynchronizowanych z tym modułem. @@ -171,13 +258,212 @@ Colore per membri di gruppi sincronizzati con questo modulo. Farbwert für Gruppenmitglieder, die mit diesem Modul synchronisiert werden. Color para los miembros de los grupos sincronizados al módulo. - Couleur pour les membres du groupe synchronisé avec ce module. - モジュールで同期されたグループのメンバ用に色の値を決定します。 - 그룹이 이 모듈에 동기화 됐을때의 멤버 색상입니다. - 改变与此同步小队队员的标识器颜色 + Couleur pour les membres des groupes synchronisés avec ce module. + モジュールで同期されたグループの隊員に設定される色の値。 + 그룹이 이 모듈에 동기화 됐을 때의 멤버 색상입니다. + 改变与此同步小队队员的指示颜色 改變與此同步小隊隊員的指示器顏色 + Barva pro členy skupin které jsou synchronizované s tímto modulem. - + + Only Show Friendly Gestures + Показывать только союзные жесты + Pokazuj jedynie sojusznicze gesty + Afficher uniquement le pointage des alliés + 友軍のジェスチャーのみ表示 + Mostrar sólo gestos de aliados + Nur Gesten befreundeter Einheiten zeigen + Mostra solo gesti di alleati + 仅显示友军指示 + 아군 신호만 보기 + Mostrar somente gestos aliados + + + Shows only Gestures from Units that are from the same side or a Friendly side. + Показывать жесты только от игроков союзной стороны. + Affiche uniquement les pointages effectués par des unités qui sont du même camp, ou d'un camp allié. + Mostra solo gesti effettuati da unità che sono della stessa fazione o una fazione alleata. + 同じ陣営または味方陣営のユニットからのジェスチャーのみを表示します。 + Muestra únicamente gestos de las unidades que son del mismo bando o de un bando aliado + Pokazuj tylko Gesty od jednostek z tej samej lub sojuszniczej strony + Nur Gesten von Einheiten der selben oder einer verbündeten Seite zeigen. + 仅显示来自同一阵营或友军的单位的指示。 + 같은 진영 혹은 아군 진영 인원들만 보이게 합니다. + Mostra somente gestos de unidades que são do mesmo lado ou de um lado aliado. + + + Max range Camera + Макс. дальность действия камеры + Portée de la caméra + カメラの最大範囲 + Máximo alcance de cámara + Maksymalny zasięg kamery + Maximale Kamerareichweite + Distanza massima per videocamere + 摄像机最大范围 + 카메라와 지도 신호의 최대 거리 + Distância máxima da câmera + + + Max range between a Camera and players to show the map gesture indicator + Устанавливает макс. дальность между игроком и камерой для отображения жестов на карте + Définit le rayon au-delà duquel une caméra ne verra plus l'indicateur de pointage des autres joueurs. + 観戦カメラから確認可能なマップ ジェスチャーのインジケーターを表示するカメラとプレーヤー間の最大距離 + Máxima distancia entre una cámara y los jugadores para mostrar el indicador de gestos en mapa + Distanza massima da cui videocamere (spettatore/zeus) può vedere i gesti di giocatori. + Maksymalny zasięg pomiędzy kamerą a graczami do pokazania gestów na mapie + Maximale Reichweite, in der eine Kamera das Kartenzeichen der Spieler zeigt + 摄像机和玩家之间的最大范围显示地图指示 + 카메라와 플레이어간 지도 신호를 볼 수 있는 최대 거리를 정합니다 + Distância máxima entre uma câmera e jogadores para mostrar o indicador de gestos no mapa + + + Allow Spectator + Разрешить видеть в спектаторе + Autoriser les spectateurs + Permetti spettatori + 観戦者に許可 + Permitir espectador + Zezwól na Obserwatora + Erlaube Zuschauer + 允许旁观者 + 관전자 허용 + Permitir espectador + + + Allows Spectator to See Map Gestures + Позволяет наблюдателю видеть жесты на карте + Permet aux spectateurs de voir le pointage des autres joueurs. + 観戦者からマップ ジェスチャーを表示できるようにします。 + Permetti agli spettatori di vedere gesti in mappa + Permitir al espectador ver los gestos de mapa + Zezwól Obserwatorowi widzieć Gesty na mapie + Erlaube, dass Zuschauer das Kartenzeichen sehen können + 允许旁观者查看地图指示 + 관전자가 지도 신호를 볼 수 있습니다 + Permite espectadores verem o indicador de gestos no mapa + + + Allow Curator + Разрешить куратору + Autoriser les curateurs + キュレーターに許可 + Permitir Curador + Zezwól na Zeusa + Erlaube Zeus + Permetti Zeus + 允许宙斯 + 큐레이터 허용 + Permitir curador + + + Allows Curator to See Map Gestures + Позволяет куратору видеть жесты на карте + Permet aux curateurs de voir le pointage des autres joueurs. + キュレーターからマップ ジェスチャーを表示できるようにします。 + Permitir al Curador ver los gestos de mapa + Permetti agli Zeus di vedere gesti in mappa + Zezwól Zeusowi widzieć gesty na mapie + Erlaube, dass Zeus das Kartenzeichen sehen kann + 允许宙斯查看地图指示 + 큐레이터가 지도 신호를 볼 수 있습니다 + Permite curadores verem o indicador de gestos no mapa + + + Briefing Mode + Режим брифинга + Visibilité lors du briefing + ブリーフィング モード + Modo de briefing + Modalità Briefing + Tryb Odprawy + Briefing-Modus + 简报模式 + 브리핑 모드 + Modo de briefing + + + What player can see what + Определяет, какая группа игроков может видеть жесты на карте во время брифинга + Définit quels pointages les joueurs peuvent voir lors du briefing. + プレイヤーが見ることができる対象 + Qué puede ver cada jugador + Quali giocatori possono vedere gesti sulla mappa in fase di briefing. + Co mogą widzieć gracze + Welcher Spieler kann was sehen + 什么玩家能看到什么 + 어떤 플레이어가 볼 수 있는지 정합니다 + O que cada jogador pode ver + + + Disabled + Отключить + Pointage désactivé + 無効化 + Deshabilitado + Disabilitata + Zablokowany + Deaktiviert + 禁用 + 비활성화 + Desativado + + + Group + Skupina + Groupe + Gruppe + Gruppo + Grupa + Grupo + Группа + Grupo + グループ + 小队 + 그룹 + + + Side + Strana + Camp + Seite + Fazione + Strona + Lado + Сторона + Bando + 陣営 + 阵营 + 진영 + + + Proximity + Все, кто рядом + Proximité + 付近のみ + Proximidad + Prossimità + Umgebung + Tylko w pobliżu + 附近 + 근처 + Proximidade + + + All + Vše + Tous + Alle + Tutto + Wszystko + Tudo + Все + Todas + 全て + 全部 + 모두 + + Map Gestures - Group Settings Gestos no mapa - Definições de Grupo Gesty na mapie - ustawienia grup @@ -186,100 +472,27 @@ Gesti Mappa - Impostazioni Gruppi Kartenzeichen - Gruppeneinstellungen Gestos en mapas - Configuración de grupos - Gestes de carte - réglages de groupe - マップ ジェスチャ - グループ設定 + Pointage sur carte - réglages de groupe + マップ ジェスチャー - グループ設定 지도 신호 - 그룹 설정 - 地图标识器 - 队伍设定 + 地图指示—队伍设定 地圖指示器 - 隊伍設定 - - Update Interval - Intervalo de atualizações - Interwał aktualizacji - Интервал обновления - Interval aktualizace - Intervallo Aggiornamento - Update-Intervall - Período de actualización - Intervalle de mise à jour - 更新間隔 - 갱신 간격 - 更新间隔 - 更新間隔 - - - Time between data updates. - Tempo entre atualização de dados - Odstęp pomiędzy aktualizacjami danych - Время между обновлениями данных. - Čas mezi aktualizacemi dat. - Intervallo tra aggiornamenti dati. - Zeit zwischen Datenupdates. - Tiempo entre actualizaciones sucesivas. - Temps entre les actualisations de données - データの更新間隔 - 데이터 갱신 간격 - 定义每次更新数据的时间. - 定義每次更新數據的時間 - - - Enables the Map Gestures. - Ativa os gestos no mapa - Aktywuje gesty na mapie. - Включает указания на карте. - Povolit ukazování v mapě - Abilita i Gesti Mappa - Aktiviert die Kartenzeichen. - Activar Gestos en Mapa - Activer les gestes de carte - マップ ジェスチャを有効化 - 지도 신호 활성화 - 启用地图标识器 - 啟用地圖指示器 - - - Name Text Color - Cor do texto do nome - Kolor nazw - Цвет текста имени - Barva textu pro jména - Colore Testo Nome - Farbe der Namenstexte. - Color de los nombres - Couleur du texte du nom - 名前への色 - 글 색상 명칭 - 名称文字颜色 - 名稱文字顏色 - - - Color of the name tag text besides the map gestures mark. - Cor do texto da etiqueta de nome que fica embaixo da marcação de gestos no mapa. - Kolor nazwy gracza obok markera gestu mapy. - Цвет инмени игрока рядом с маркером жестов. - Colore del testo dei nametag oltre a quello dei Gesti Mappa - Farbe der Namenstexte neben der Kartenzeichen-Markierung. - Color de los nombres dibujados al lado del marcados de gestos. - Couleur des tags de nom à côté de marqueur de pointage sur carte. - マップ ジェスチャに表示される、名前の色を決定します。 - 지도 색상에 표시되는 이름의 색상을 결정합니다. - 定义名称文字颜色。使其与地图标识器颜色有所区别。 - 定義名稱文字顏色。使其與地圖指示器顏色有所區別 - - - Map Gestures - Gestos no mapa - Gesty na mapie - Жесты на карте - Ukazovní v mapě - Gesti Mappa - Kartenzeichen - Gestos en mapa - Gestes de carte - マップ ジェスチャ - 지도 신호 - 地图标识器 - 地圖指示器 + + ACE Map Gestures + ACE Gestos no mapa + ACE Gesty na mapie + ACE Жесты на карте + ACE Ukazování v mapě + ACE Gesti Mappa + ACE Kartenzeichen + ACE Gestos en mapa + ACE Pointage sur carte + ACE マップ ジェスチャー + ACE 지도 신호 + ACE 地图指示 + ACE 地圖指示器 + ACE Harita Hareketleri diff --git a/addons/maptools/ACE_Settings.hpp b/addons/maptools/ACE_Settings.hpp index c0642ed4e7..ba6633e941 100644 --- a/addons/maptools/ACE_Settings.hpp +++ b/addons/maptools/ACE_Settings.hpp @@ -1,19 +1,8 @@ class ACE_Settings { class GVAR(rotateModifierKey) { - category = CSTRING(Name); - value = 1; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(rotateModifierKey_displayName); - description = CSTRING(rotateModifierKey_description); - values[] = {"$STR_A3_OPTIONS_DISABLED", "ALT", "CTRL", "SHIFT"}; + movedToSQF = 1; }; class GVAR(drawStraightLines) { - category = CSTRING(Name); - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(drawStraightLines_displayName); - description = CSTRING(drawStraightLines_description); + movedToSQF = 1; }; }; diff --git a/addons/maptools/CfgEventHandlers.hpp b/addons/maptools/CfgEventHandlers.hpp index 1f53a9b2ec..bff1c64e94 100644 --- a/addons/maptools/CfgEventHandlers.hpp +++ b/addons/maptools/CfgEventHandlers.hpp @@ -1,18 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient)); }; }; diff --git a/addons/maptools/CfgVehicles.hpp b/addons/maptools/CfgVehicles.hpp index 2e5663e251..0757aafc51 100644 --- a/addons/maptools/CfgVehicles.hpp +++ b/addons/maptools/CfgVehicles.hpp @@ -1,62 +1,204 @@ +#define EXCEPTIONS exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"} + class CfgVehicles { class Man; class CAManBase: Man { class ACE_SelfActions { class ACE_MapGpsShow { displayName = CSTRING(MapGpsShow); - condition = QUOTE((!GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); - statement = QUOTE(GVAR(mapGpsShow) = true; [GVAR(mapGpsShow)] call FUNC(openMapGps)); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + condition = QUOTE(!GVAR(mapGpsShow) && {call FUNC(canUseMapGPS)}); + statement = QUOTE(GVAR(mapGpsShow) = true); + EXCEPTIONS; showDisabled = 0; }; class ACE_MapGpsHide { displayName = CSTRING(MapGpsHide); - condition = QUOTE((GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); - statement = QUOTE(GVAR(mapGpsShow) = false; [GVAR(mapGpsShow)] call FUNC(openMapGps)); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + condition = QUOTE(GVAR(mapGpsShow) && {call FUNC(canUseMapGPS)}); + statement = QUOTE(GVAR(mapGpsShow) = false); + EXCEPTIONS; showDisabled = 0; }; class ACE_MapTools { displayName = CSTRING(MapTools_Menu); condition = QUOTE(call FUNC(canUseMapTools)); statement = ""; - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + EXCEPTIONS; showDisabled = 0; + class ACE_MapToolsHide { displayName = CSTRING(MapToolsHide); condition = QUOTE(GVAR(mapTool_Shown) != 0); - statement = QUOTE(GVAR(mapTool_Shown) = 0;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = QUOTE(GVAR(mapTool_Shown) = 0); + EXCEPTIONS; showDisabled = 1; }; class ACE_MapToolsShowNormal { displayName = CSTRING(MapToolsShowNormal); condition = QUOTE(GVAR(mapTool_Shown) != 1); - statement = QUOTE(GVAR(mapTool_Shown) = 1;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 1); + EXCEPTIONS; showDisabled = 1; }; class ACE_MapToolsShowSmall { displayName = CSTRING(MapToolsShowSmall); condition = QUOTE(GVAR(mapTool_Shown) != 2); - statement = QUOTE(GVAR(mapTool_Shown) = 2;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 2); + EXCEPTIONS; showDisabled = 1; }; - class ACE_MapToolsAlignNorth { - displayName = CSTRING(MapToolsAlignNorth); + class ACE_MapToolsAlign { + displayName = CSTRING(AlignTo); condition = QUOTE(GVAR(mapTool_Shown) != 0); - statement = QUOTE(GVAR(mapTool_angle) = 0;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_MapToolsAlignToPlottingBoardRuler { + displayName = CSTRING(ToPlottingBoardRulerLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) == 2); + statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_rulerAngle)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignToPlottingBoardAcrylic { + displayName = CSTRING(ToPlottingBoardAcrylicLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) != 0); + statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_acrylicAngle)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignToPlottingBoard { + displayName = CSTRING(ToPlottingBoardLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) != 0); + statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_angle)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignCompass { + displayName = CSTRING(ToCompassLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && {ACE_player getSlotItemName TYPE_COMPASS != ''}); + statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignNorth { + displayName = CSTRING(ToNorthLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0); + statement = QUOTE(GVAR(mapTool_angle) = 0); + EXCEPTIONS; + showDisabled = 1; + }; + }; + }; + class ACE_PlottingBoard { + displayName = CSTRING(ShowPlottingBoard); + condition = QUOTE(GVAR(plottingBoard_Shown) == 0 && {call FUNC(canUsePlottingBoard)}); + statement = QUOTE(GVAR(plottingBoard_Shown) = 1); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardHide { + displayName = CSTRING(HidePlottingBoard); + condition = QUOTE(GVAR(plottingBoard_Shown) != 0 && {call FUNC(canUsePlottingBoard)}); + statement = QUOTE(GVAR(plottingBoard_Shown) = 0); + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardRulerShow { + displayName = CSTRING(TogglePlottingBoardRuler); + condition = QUOTE(GVAR(plottingBoard_Shown) == 1); + statement = QUOTE(GVAR(plottingBoard_Shown) = 2); + EXCEPTIONS; showDisabled = 1; }; - class ACE_MapToolsAlignCompass { - displayName = CSTRING(MapToolsAlignCompass); - condition = QUOTE((GVAR(mapTool_Shown) != 0) && {'ItemCompass' in assigneditems ACE_player}); - statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + class ACE_PlottingBoardRulerHide { + displayName = CSTRING(TogglePlottingBoardRuler); + condition = QUOTE(GVAR(plottingBoard_Shown) == 2); + statement = QUOTE(GVAR(plottingBoard_Shown) = 1); + EXCEPTIONS; showDisabled = 1; }; + class ACE_PlottingBoardWipe { + displayName = CSTRING(WipeBoard); + condition = QUOTE(GVAR(plottingBoard_markers) isNotEqualTo createHashMap); + statement = QUOTE(call FUNC(wipeMarkers)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_PlottingBoardAlign { + displayName = CSTRING(AlignTo); + condition = QUOTE(GVAR(plottingBoard_Shown) != 0); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignBoard { + displayName = CSTRING(PlottingBoardLabel); + condition = QUOTE(true); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignBoardMaptool { + displayName = CSTRING(ToMapToolLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_angle) != GVAR(mapTool_angle)); + statement = QUOTE(GVAR(plottingBoard_angle) = GVAR(mapTool_angle)); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardAlignBoardUp { + displayName = CSTRING(ToUpLabel); + condition = QUOTE(GVAR(plottingBoard_angle) != 0); + statement = QUOTE(GVAR(plottingBoard_angle) = 0); + EXCEPTIONS; + showDisabled = 0; + }; + }; + class ACE_PlottingBoardAlignAcrylic { + displayName = CSTRING(PlottingBoardAcrylicLabel); + condition = QUOTE(true); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignAcrylicMaptool { + displayName = CSTRING(ToMapToolLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_acrylicAngle) != GVAR(mapTool_angle)); + statement = QUOTE(GVAR(plottingBoard_acrylicAngle) = GVAR(mapTool_angle)); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardAlignAcrylicUp { + displayName = CSTRING(ToUpLabel); + condition = QUOTE(GVAR(plottingBoard_acrylicAngle) != 0); + statement = QUOTE(GVAR(plottingBoard_acrylicAngle) = 0); + EXCEPTIONS; + showDisabled = 0; + }; + }; + class ACE_PlottingBoardAlignRuler { + displayName = CSTRING(PlottingBoardRulerLabel); + condition = QUOTE(GVAR(plottingBoard_Shown) == 2); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignRulerMaptool { + displayName = CSTRING(ToMapToolLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_rulerAngle) != GVAR(mapTool_angle)); + statement = QUOTE(GVAR(plottingBoard_rulerAngle) = GVAR(mapTool_angle)); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardAlignRulerUp { + displayName = CSTRING(ToUpLabel); + condition = QUOTE(GVAR(plottingBoard_rulerAngle) != 0); + statement = QUOTE(GVAR(plottingBoard_rulerAngle) = 0); + EXCEPTIONS; + showDisabled = 0; + }; + }; + }; }; }; }; @@ -69,30 +211,35 @@ class CfgVehicles { class Box_NATO_Support_F: NATO_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class Box_East_Support_F: EAST_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class Box_IND_Support_F: IND_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class Box_FIA_Support_F: FIA_Box_Base_F { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; }; diff --git a/addons/maptools/CfgWeapons.hpp b/addons/maptools/CfgWeapons.hpp index 31d8bc491e..ca4d4a473e 100644 --- a/addons/maptools/CfgWeapons.hpp +++ b/addons/maptools/CfgWeapons.hpp @@ -9,8 +9,22 @@ class CfgWeapons { model = QPATHTOF(data\ace_MapTools.p3d); picture = QPATHTOF(UI\maptool_item.paa); scope = 2; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.2; + }; + }; + + class ACE_PlottingBoard: ACE_ItemCore { + displayName = CSTRING(PlottingBoard_Name); + author = ECSTRING(common,ACETeam); + descriptionShort = CSTRING(PlottingBoard_Description); + model = QPATHTOF(data\ace_MapTools.p3d); + picture = QPATHTOF(UI\plottingboard_item.paa); + scope = 2; + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.5; }; }; }; diff --git a/addons/maptools/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/README.md b/addons/maptools/README.md index f03474b5c0..fe9c836c13 100644 --- a/addons/maptools/README.md +++ b/addons/maptools/README.md @@ -5,11 +5,4 @@ Adds the following map tools: - Roamer - Map drawing - Showing GPS on map - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [esteldunedain](https://github.com/esteldunedain) -- [NouberNou](https://github.com/NouberNou) +- Plotting Board diff --git a/addons/maptools/RscDisplayMainMap.hpp b/addons/maptools/RscDisplayMainMap.hpp new file mode 100644 index 0000000000..94a5d2a8d4 --- /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/UI/plottingboard_item.paa b/addons/maptools/UI/plottingboard_item.paa new file mode 100644 index 0000000000..2d89f35514 Binary files /dev/null and b/addons/maptools/UI/plottingboard_item.paa differ diff --git a/addons/maptools/XEH_PREP.hpp b/addons/maptools/XEH_PREP.hpp index eac6947431..ac9ed8b91f 100644 --- a/addons/maptools/XEH_PREP.hpp +++ b/addons/maptools/XEH_PREP.hpp @@ -5,6 +5,10 @@ PREP(drawLinesOnRoamer); PREP(handleMouseButton); PREP(handleMouseMove); PREP(isInsideMapTool); -PREP(openMapGps); PREP(openMapGpsUpdate); PREP(updateMapToolMarkers); + +PREP(canUsePlottingBoard); +PREP(isInsidePlottingBoard); +PREP(handlePlottingBoardMarkers); +PREP(wipeMarkers); diff --git a/addons/maptools/XEH_postInitClient.sqf b/addons/maptools/XEH_postInitClient.sqf index ddde7063cc..5ce1e68892 100644 --- a/addons/maptools/XEH_postInitClient.sqf +++ b/addons/maptools/XEH_postInitClient.sqf @@ -1,4 +1,4 @@ -// by esteldunedain +// by esteldunedain, LorenLuke #include "script_component.hpp" @@ -6,37 +6,52 @@ if (!hasInterface) exitWith {}; // Init variables GVAR(mapGpsShow) = true; +GVAR(mapGpsNextUpdate) = -1; GVAR(mapTool_Shown) = 0; -GVAR(mapTool_pos) = [0,0]; +GVAR(mapTool_pos) = [0, 0]; GVAR(mapTool_angle) = 0; GVAR(mapTool_isDragging) = false; GVAR(mapTool_isRotating) = false; +GVAR(mapTool_moveToMouse) = true; // used to display it in center of screen when opened -//Install the event handers for the map tools on the main in-game map -[{!isNull findDisplay 12}, -{ - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseMoving", {_this call FUNC(handleMouseMove);}]; - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseButtonDown", {[1, _this] call FUNC(handleMouseButton);}]; - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseButtonUp", {[0, _this] call FUNC(handleMouseButton)}]; - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["Draw", {_this call FUNC(updateMapToolMarkers);}]; +GVAR(plottingBoard_Shown) = 0; +GVAR(plottingBoard_pos) = [0, 0]; +GVAR(plottingBoard_angle) = 0; +GVAR(plottingBoard_acrylicAngle) = 0; +GVAR(plottingBoard_rulerAngle) = 0; +GVAR(plottingBoard_isDragging) = false; +GVAR(plottingBoard_isRotating) = -1; +GVAR(plottingBoard_moveToMouse) = true; // used to display it in center of screen when opened +GVAR(plottingBoard_markers) = createHashMap; + +// Install the event handers for the map tools on the main in-game map +[{ + !isNull findDisplay 12 +}, { + private _map = (findDisplay 12) displayCtrl 51; + + _map ctrlAddEventHandler ["MouseMoving", LINKFUNC(handleMouseMove)]; + _map ctrlAddEventHandler ["MouseButtonDown", {[1, _this] call FUNC(handleMouseButton);}]; + _map ctrlAddEventHandler ["MouseButtonUp", {[0, _this] call FUNC(handleMouseButton)}]; + _map ctrlAddEventHandler ["Draw", {call FUNC(updateMapToolMarkers); call FUNC(openMapGpsUpdate);}]; }, []] call CBA_fnc_waitUntilAndExecute; ["visibleMap", { 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; }; }] call CBA_fnc_addPlayerEventHandler; +addMissionEventHandler ["MarkerCreated", { + [_this, false] call FUNC(handlePlottingBoardMarkers); +}]; + +addMissionEventHandler ["MarkerDeleted", { + [[_this select 0, -1, objNull, _this select 1], true] call FUNC(handlePlottingBoardMarkers); +}]; GVAR(freeDrawingData) = []; GVAR(freedrawing) = false; - diff --git a/addons/maptools/XEH_preInit.sqf b/addons/maptools/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/maptools/XEH_preInit.sqf +++ b/addons/maptools/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; 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..b1d374c6f6 Binary files /dev/null and b/addons/maptools/data/MapGpsDisplay.p3d differ diff --git a/addons/maptools/data/mapToolFixed.paa b/addons/maptools/data/mapToolFixed.paa index 8f2c0febfd..964cf6da20 100644 Binary files a/addons/maptools/data/mapToolFixed.paa and b/addons/maptools/data/mapToolFixed.paa differ diff --git a/addons/maptools/data/mapToolRotatingNormal.paa b/addons/maptools/data/mapToolRotatingNormal.paa index 2ab9db6174..7437dd50c3 100644 Binary files a/addons/maptools/data/mapToolRotatingNormal.paa and b/addons/maptools/data/mapToolRotatingNormal.paa differ diff --git a/addons/maptools/data/mapToolRotatingNormalOriginal.paa b/addons/maptools/data/mapToolRotatingNormalOriginal.paa new file mode 100644 index 0000000000..fcfb11cfa7 Binary files /dev/null and b/addons/maptools/data/mapToolRotatingNormalOriginal.paa differ diff --git a/addons/maptools/data/mapToolRotatingSmall.paa b/addons/maptools/data/mapToolRotatingSmall.paa index 509d237646..b9582eadd5 100644 Binary files a/addons/maptools/data/mapToolRotatingSmall.paa and b/addons/maptools/data/mapToolRotatingSmall.paa differ diff --git a/addons/maptools/data/mapToolRotatingSmallOriginal.paa b/addons/maptools/data/mapToolRotatingSmallOriginal.paa new file mode 100644 index 0000000000..4f37dea565 Binary files /dev/null and b/addons/maptools/data/mapToolRotatingSmallOriginal.paa differ diff --git a/addons/maptools/data/plottingBoardAcrylic.paa b/addons/maptools/data/plottingBoardAcrylic.paa new file mode 100644 index 0000000000..eaa8bf2e13 Binary files /dev/null and b/addons/maptools/data/plottingBoardAcrylic.paa differ diff --git a/addons/maptools/data/plottingBoardBack.paa b/addons/maptools/data/plottingBoardBack.paa new file mode 100644 index 0000000000..79772e7cb0 Binary files /dev/null and b/addons/maptools/data/plottingBoardBack.paa differ diff --git a/addons/maptools/data/plottingBoardRuler.paa b/addons/maptools/data/plottingBoardRuler.paa new file mode 100644 index 0000000000..83160af799 Binary files /dev/null and b/addons/maptools/data/plottingBoardRuler.paa differ diff --git a/addons/maptools/functions/fnc_calculateMapScale.sqf b/addons/maptools/functions/fnc_calculateMapScale.sqf index 035946aea5..7c868d200a 100644 --- a/addons/maptools/functions/fnc_calculateMapScale.sqf +++ b/addons/maptools/functions/fnc_calculateMapScale.sqf @@ -1,21 +1,22 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain - * Returns the equivalent of 100m in screen coordinates + * Returns the equivalent of 100m in screen coordinates. * * Arguments: * None * * Return Value: - * None + * Map scale * * Example: - * call ACE_maptools_fnc_calculateMapScale + * call ace_maptools_fnc_calculateMapScale * * Public: No */ -private _pos = ((findDisplay 12) displayCtrl 51) ctrlMapScreenToWorld [0.5, 0.5]; -private _screenOffset = ((findDisplay 12) displayCtrl 51) posWorldToScreen [(_pos select 0) + 100, (_pos select 1)]; +private _mapCtrl = (findDisplay 12) displayCtrl 51; +private _pos = _mapCtrl ctrlMapScreenToWorld [0.5, 0.5]; +private _screenOffset = _mapCtrl posWorldToScreen (_pos vectorAdd [100, 0]); (_screenOffset select 0) - 0.5 diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index 80f2541cab..e9ca813288 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -1,20 +1,23 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain - * canUseMapGPS + * Returns if the GPS on the map can be used. * * Arguments: * None * * Return Value: - * Boolean + * GPS can be used * * Example: - * call ACE_map_fnc_canUseMapGPS + * call ace_maptools_fnc_canUseMapGPS * * Public: No */ -visibleMap && -{alive ACE_player} && -{"ItemGPS" in (assignedItems ACE_player)} +if (!visibleMap || {!alive ACE_player}) exitWith {false}; + +private _panels = flatten (ACE_player infoPanelComponents "left"); +private _index = _panels find "MinimapDisplayComponent"; + +_index != -1 && {_panels select (_index + 1)} diff --git a/addons/maptools/functions/fnc_canUseMapTools.sqf b/addons/maptools/functions/fnc_canUseMapTools.sqf index e09a450031..8eb918dfdc 100644 --- a/addons/maptools/functions/fnc_canUseMapTools.sqf +++ b/addons/maptools/functions/fnc_canUseMapTools.sqf @@ -1,29 +1,23 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain - * canUseMapTools + * Returns if the map tools can be used. * * Arguments: * None * * Return Value: - * Boolean + * Map tools can be used * * Example: - * call ACE_maptools_fnc_canUseMapTools + * call ace_maptools_fnc_canUseMapTools * * Public: No */ visibleMap && {alive ACE_player} && -{ - scopeName "hasMap"; - { - if (_x isKindOf ["ItemMap", configFile >> "CfgWeapons"]) exitWith {true breakOut "hasMap"}; - } forEach (assignedItems ACE_player); - false -} && -{"ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems))} && {!GVAR(mapTool_isDragging)} && -{!GVAR(mapTool_isRotating)} +{!GVAR(mapTool_isRotating)} && +{ACE_player getSlotItemName TYPE_MAP != ""} && +{[ACE_player, "ACE_MapTools"] call EFUNC(common,hasItem)} diff --git a/addons/maptools/functions/fnc_canUsePlottingBoard.sqf b/addons/maptools/functions/fnc_canUsePlottingBoard.sqf new file mode 100644 index 0000000000..9dfd2bf6b5 --- /dev/null +++ b/addons/maptools/functions/fnc_canUsePlottingBoard.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Returns if the plotting board can be used. + * + * Arguments: + * None + * + * Return Value: + * Plotting board can be used + * + * Example: + * call ace_maptools_fnc_canUsePlottingBoard + * + * Public: No + */ + +visibleMap && +{alive ACE_player} && +{!GVAR(plottingBoard_isDragging)} && +{GVAR(plottingBoard_isRotating) == -1} && +{[ACE_player, "ACE_PlottingBoard"] call EFUNC(common,hasItem)} diff --git a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf index a2ec5bfe78..782d8762a0 100644 --- a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf +++ b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf @@ -1,66 +1,74 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Prevents the cursor from entering the roamer when drawing lines and records the positions * * Arguments: - * 0: The Map + * 0: Map control * 1: Roamer Width * * Return Value: * None * * Example: - * [map, 300] call ace_maptools_fnc_drawLinesOnRoamer + * [CONTROL, 300] call ace_maptools_fnc_drawLinesOnRoamer * * Public: No */ if (!GVAR(drawStraightLines)) exitWith {}; -params ["_theMap", "_roamerWidth"]; +params ["_mapCtrl", "_roamerWidth"]; GVAR(mapTool_pos) params ["_roamerPosX", "_roamerPosY"]; private _posCenter = [_roamerPosX, _roamerPosY, 0]; private _posTopRight = [ -_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + 0 +]; private _posTopLeft = [ -_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + 0 +]; private _posBottomLeft = [ -_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + 0 +]; private _posBottomRight = [ -_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + 0 +]; -private _fnc_Distance = { // Get distance point _p is from a line made from _a to _b (uses 3d array commands, but z should be 0) +private _fnc_distance = { // Get distance point _p is from a line made from _a to _b (uses 3d array commands, but z should be 0) // Ref: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation params ["_a", "_b", "_p"]; + private _n = _b vectorDiff _a; private _pa = _a vectorDiff _p; private _c = _n vectorMultiply ((_pa vectorDotProduct _n) / (_n vectorDotProduct _n)); private _d = _pa vectorDiff _c; - sqrt (_d vectorDotProduct _d); + + sqrt (_d vectorDotProduct _d) }; -private _currentMousePos = _theMap ctrlMapScreenToWorld getMousePosition; +private _currentMousePos = _mapCtrl ctrlMapScreenToWorld getMousePosition; _currentMousePos set [2, 0]; // Break the roamer rectangle into 4 triangle, one for each side switch (true) do { case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posBottomLeft]): { // Left - private _distanceToRoamerLine = ([_posTopLeft, _posBottomLeft, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) - 90) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posTopLeft, _posBottomLeft, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle) - 90, 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["left", _currentMousePos, _currentMousePos]; } else { @@ -68,17 +76,21 @@ switch (true) do { if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomLeft)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posTopRight]): { // Top - private _distanceToRoamerLine = ([_posTopLeft, _posTopRight, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 0) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posTopLeft, _posTopRight, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle), 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["top", _currentMousePos, _currentMousePos]; } else { @@ -86,17 +98,21 @@ switch (true) do { if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 2) distance2d _posTopRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; case (_currentMousePos inPolygon [_posCenter, _posTopRight, _posBottomRight]): { // Right - private _distanceToRoamerLine = ([_posTopRight, _posBottomRight, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 90) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posTopRight, _posBottomRight, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle) + 90, 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["right", _currentMousePos, _currentMousePos]; } else { @@ -104,17 +120,21 @@ switch (true) do { if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 1) distance2d _posTopRight)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; case (_currentMousePos inPolygon [_posCenter, _posBottomLeft, _posBottomRight]): { // Bottom - private _distanceToRoamerLine = ([_posBottomLeft, _posBottomRight, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 180) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posBottomLeft, _posBottomRight, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle) + 180, 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["bottom", _currentMousePos, _currentMousePos]; } else { @@ -122,23 +142,26 @@ switch (true) do { if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posBottomLeft)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; }; #ifdef DEBUG_MODE_FULL -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopRight,24,24,getDir player,'1,1',1,0.03,'TahomaB','right']; -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopLeft,24,24,getDir player,'-1,1',1,0.03,'TahomaB','right']; -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomLeft,24,24,getDir player,'-1,-1',1,0.03,'TahomaB','right']; -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomRight,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; -if !(GVAR(freeDrawingData) isEqualTo []) then { - _theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 1,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; - _theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 2,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posTopRight,24,24,getDir player,'1,1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posTopLeft,24,24,getDir player,'-1,1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posBottomLeft,24,24,getDir player,'-1,-1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posBottomRight,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; + +if (GVAR(freeDrawingData) isNotEqualTo []) then { + _mapCtrl drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 1,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; + _mapCtrl drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 2,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; }; #endif diff --git a/addons/maptools/functions/fnc_handleMouseButton.sqf b/addons/maptools/functions/fnc_handleMouseButton.sqf index 4e1c124b2a..5c35c699d7 100644 --- a/addons/maptools/functions/fnc_handleMouseButton.sqf +++ b/addons/maptools/functions/fnc_handleMouseButton.sqf @@ -1,17 +1,17 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: esteldunedain + * Author: esteldunedain, LorenLuke * Handle mouse buttons. * * Arguments: - * 0: 1 if mouse down down, 0 if mouse button up + * 0: 1 if mouse down down, 0 if mouse button up * 1: Parameters of the mouse button event * * Return Value: - * true if event was handled + * None * * Example: - * [0, [array]] call ACE_maptools_fnc_handleMouseButton + * [0, []] call ace_maptools_fnc_handleMouseButton * * Public: No */ @@ -24,34 +24,34 @@ TRACE_2("params",_dir,_params); if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { if (GVAR(freedrawing) && {_dir == 0}) then { GVAR(freedrawing) = false; + if (_shiftKey) exitWith { TRACE_1("using vanilla straight line",_shiftKey); }; + TRACE_2("Ending Line",GVAR(freedrawing),GVAR(freeDrawingData)); + [{ - if (allMapMarkers isEqualTo []) exitWith {}; - private _markerName = allMapMarkers select (count allMapMarkers - 1); + if (GVAR(freeDrawingData) isEqualTo []) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData))}; + + private _allMarkers = allMapMarkers; + + if (_allMarkers isEqualTo []) exitWith {}; + + private _markerName = _allMarkers select -1; private _markerPos = getMarkerPos _markerName; - private _distanceCheck = _markerPos distance2d GVAR(drawPosStart); + private _distanceCheck = _markerPos distance2D GVAR(drawPosStart); TRACE_3("Line Drawn",_markerName,_markerPos,_distanceCheck); - if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!");}; - if ((count GVAR(freeDrawingData)) != 3) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData));}; + if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!")}; GVAR(freeDrawingData) params ["", "_startStraightPos", "_endStraightPos"]; - _startStraightPos set [2, 0]; - _endStraightPos set [2, 0]; - - // Convert marker to rectangle and change it's pos/size/dir - _markerName setMarkerShape "RECTANGLE"; - - private _difPos = _endStraightPos vectorDiff _startStraightPos; - private _mag = vectorMagnitude _difPos; - _markerName setMarkerPos (_startStraightPos vectorAdd (_difPos vectorMultiply 0.5)); - _markerName setMarkerSize [10, _mag / 2]; - _markerName setMarkerDir (_difPos call CBA_fnc_vectDir); + _markerName setMarkerPolyline [ + _startStraightPos#0, _startStraightPos#1, + _endStraightPos#0, _endStraightPos#1 + ]; }, []] call CBA_fnc_execNextFrame; } else { if (_ctrlKey && {_dir == 1}) then { @@ -61,63 +61,112 @@ if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { TRACE_2("Starting Line",GVAR(freedrawing),GVAR(drawPosStart)); } else { GVAR(freedrawing) = false; - TRACE_1("weird - reseting",GVAR(freedrawing)); + TRACE_1("weird - resetting",GVAR(freedrawing)); }; }; - false + + false // return +}; + +// If it's not a left button event, exit +if (_button != 0) exitWith { + false // return }; private _handled = false; -// If it's not a left button event, exit -if (_button != 0) exitWith {_handled}; - // If releasing if (_dir != 1) then { if (GVAR(mapTool_isDragging) || GVAR(mapTool_isRotating)) then { GVAR(mapTool_isDragging) = false; GVAR(mapTool_isRotating) = false; - _handled = true; + }; + + if (GVAR(plottingBoard_isDragging) || GVAR(plottingBoard_isRotating) > -1) then { + GVAR(plottingBoard_isDragging) = false; + GVAR(plottingBoard_isRotating) = -1; }; } else { // If clicking - if !(call FUNC(canUseMapTools)) exitWith {}; + if (call FUNC(canUseMapTools)) then { + GVAR(mapTool_isDragging) = false; + GVAR(mapTool_isRotating) = false; - // Transform mouse screen position to coordinates - private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; - _pos set [count _pos, 0]; + // If no map tool marker then exit + if (GVAR(mapTool_Shown) != 0) then { + // Transform mouse screen position to coordinates + private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; - GVAR(mapTool_isDragging) = false; - GVAR(mapTool_isRotating) = false; + // Check if clicking the maptool + if (_pos call FUNC(isInsideMapTool)) then { + // Store data for dragging + GVAR(mapTool_startPos) = +GVAR(mapTool_pos); + GVAR(mapTool_startDragPos) = _pos; - // If no map tool marker then exit - if (GVAR(mapTool_Shown) == 0) exitWith {}; + private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do { + case 1: {_altKey}; + case 2: {_ctrlKey}; + case 3: {_shiftKey}; + default {false}; + }; - // Check if clicking the maptool - if (_pos call FUNC(isInsideMapTool)) exitWith { - // Store data for dragging - GVAR(mapTool_startPos) = + GVAR(mapTool_pos); - GVAR(mapTool_startDragPos) = + _pos; + if (_rotateKeyPressed) then { + // Store data for rotating + GVAR(mapTool_startAngle) = GVAR(mapTool_angle); - private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do { - case (1): {_altKey}; - case (2): {_ctrlKey}; - case (3): {_shiftKey}; - default {false}; + private _pos = GVAR(mapTool_startDragPos) vectorDiff GVAR(mapTool_startPos); + GVAR(mapTool_startDragAngle) = ((_pos select 0) atan2 (_pos select 1) + 360) % 360; + + // Start rotating + GVAR(mapTool_isRotating) = true; + } else { + // Start dragging + GVAR(mapTool_isDragging) = true; + }; + }; }; + }; - if (_rotateKeyPressed) then { - // Store data for rotating - GVAR(mapTool_startAngle) = + GVAR(mapTool_angle); - GVAR(mapTool_startDragAngle) = (180 + ((GVAR(mapTool_startDragPos) select 0) - (GVAR(mapTool_startPos) select 0)) atan2 ((GVAR(mapTool_startDragPos) select 1) - (GVAR(mapTool_startPos) select 1)) mod 360); - // Start rotating - GVAR(mapTool_isRotating) = true; - } else { - // Start dragging - GVAR(mapTool_isDragging) = true; + if (call FUNC(canUsePlottingBoard)) then { + GVAR(plottingBoard_isDragging) = false; + GVAR(plottingBoard_isRotating) = -1; + + if (GVAR(plottingBoard_Shown) != 0) then { + // Transform mouse screen position to coordinates + private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; + private _click = _pos call FUNC(isInsidePlottingBoard); + + if (_click > -1) then { + GVAR(plottingBoard_startPos) = +GVAR(plottingBoard_pos); + GVAR(plottingBoard_startDragPos) = _pos; + + private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do { + case 1: {_altKey}; + case 2: {_ctrlKey}; + case 3: {_shiftKey}; + default {false}; + }; + + if (_rotateKeyPressed) then { + // Store data for rotating + private _ang = switch (_click) do { + case 1: {GVAR(plottingBoard_acrylicAngle)}; + case 2: {GVAR(plottingBoard_rulerAngle)}; + default {GVAR(plottingBoard_angle)}; + }; + + GVAR(plottingBoard_startAngle) = _ang; + + private _pos = GVAR(plottingBoard_startDragPos) vectorDiff GVAR(plottingBoard_startPos); + GVAR(plottingBoard_startDragAngle) = ((_pos select 0) atan2 (_pos select 1) + 360) % 360; + + // Start rotating + GVAR(plottingBoard_isRotating) = _click; + } else { + // Start dragging + GVAR(plottingBoard_isDragging) = true; + }; + }; }; - _handled = true; }; }; - -_handled diff --git a/addons/maptools/functions/fnc_handleMouseMove.sqf b/addons/maptools/functions/fnc_handleMouseMove.sqf index 6ba8e1938c..3092d2d532 100644 --- a/addons/maptools/functions/fnc_handleMouseMove.sqf +++ b/addons/maptools/functions/fnc_handleMouseMove.sqf @@ -1,49 +1,66 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: esteldunedain - * Handle mouse movement over the map tool. + * Author: esteldunedain, LorenLuke + * Handle mouse movement over the map tool and plotting board. * * Arguments: - * 0: Map Control - * 1: Mouse position on screen coordinates + * 0: Map control + * 1: Mouse x position + * 2: Mouse y position * * Return Value: - * true if event was handled + * None * * Example: - * [CONTROL, [0, 5, 1]] call ACE_maptools_fnc_handleMouseMove + * [CONTROL, [0, 5]] call ace_maptools_fnc_handleMouseMove * * Public: No */ -params ["_control", "_mousePosX", "_mousePosY"]; -TRACE_3("params",_control,_mousePosX,_mousePosY); +params ["_mapCtrl", "_mousePosX", "_mousePosY"]; +TRACE_3("params",_mapCtrl,_mousePosX,_mousePosY); // If have no map tools, then exit -if (((isNull ACE_player) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))})) exitWith { - false -}; +if (isNull ACE_player || { + private _uniqueItems = ACE_player call EFUNC(common,uniqueItems); + + !(("ACE_MapTools" in _uniqueItems) || {"ACE_PlottingBoard" in _uniqueItems}) +}) exitWith {}; // If map tools not shown, then exit -if (GVAR(mapTool_Shown) == 0) exitWith {false}; +if (GVAR(mapTool_Shown) == 0 && {GVAR(plottingBoard_Shown) == 0}) exitWith {false}; -private _mousePosition = _control ctrlMapScreenToWorld [_mousePosX, _mousePosY]; +private _mousePosition = _mapCtrl ctrlMapScreenToWorld [_mousePosX, _mousePosY]; -// Translation +// Map tools - translation if (GVAR(mapTool_isDragging)) exitWith { - GVAR(mapTool_pos) set [0, (GVAR(mapTool_startPos) select 0) + (_mousePosition select 0) - (GVAR(mapTool_startDragPos) select 0)]; - GVAR(mapTool_pos) set [1, (GVAR(mapTool_startPos) select 1) + (_mousePosition select 1) - (GVAR(mapTool_startDragPos) select 1)]; - - true + GVAR(mapTool_pos) = GVAR(mapTool_startPos) vectorAdd _mousePosition vectorDiff GVAR(mapTool_startDragPos); }; -// Rotation +// Map tools - rotation if (GVAR(mapTool_isRotating)) exitWith { // Get new angle - private _angle = (180 + ((_mousePosition select 0) - (GVAR(mapTool_startPos) select 0)) atan2 ((_mousePosition select 1) - (GVAR(mapTool_startPos) select 1)) mod 360); - GVAR(mapTool_angle) = GVAR(mapTool_startAngle) + _angle - GVAR(mapTool_startDragAngle); + private _pos = _mousePosition vectorDiff GVAR(mapTool_startPos); + private _angle = (_pos select 0) atan2 (_pos select 1); - true + GVAR(mapTool_angle) = ((GVAR(mapTool_startAngle) + _angle - GVAR(mapTool_startDragAngle)) % 360 + 360) % 360; }; -false +// Plotting board - translation +if (GVAR(plottingBoard_isDragging)) exitWith { + GVAR(plottingBoard_pos) = GVAR(plottingBoard_startPos) vectorAdd _mousePosition vectorDiff GVAR(plottingBoard_startDragPos); +}; + +// Plotting board - rotation +if (GVAR(plottingBoard_isRotating) > -1) exitWith { + // Get new angle + private _pos = _mousePosition vectorDiff GVAR(plottingBoard_startPos); + private _angle = (_pos select 0) atan2 (_pos select 1); + private _returnAngle = ((GVAR(plottingBoard_startAngle) + _angle - GVAR(plottingBoard_startDragAngle)) % 360 + 360) % 360; + + switch (GVAR(plottingBoard_isRotating)) do { + case 0: {GVAR(plottingBoard_angle) = _returnAngle}; + case 1: {GVAR(plottingBoard_acrylicAngle) = _returnAngle}; + case 2: {GVAR(plottingBoard_rulerAngle) = _returnAngle}; + }; +}; diff --git a/addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf b/addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf new file mode 100644 index 0000000000..b7a0c7657a --- /dev/null +++ b/addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf @@ -0,0 +1,219 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke, johnb43 + * Handle map marker creation. + * If a marker is (partially) on the plotting board, the parts on the plotting board are attached to the plotting board + * and move with the board accordingly. + * + * Arguments: + * 0: Arguments + * - 0: Marker name + * - 1: Chat channel number + * - 2: Marker owner + * - 3: Local origin + * 1: Deleted + * + * Return Value: + * None + * + * Example: + * [CONTROL, [0, 5]] call ace_maptools_fnc_handlePlottingBoardMarkers + * + * Public: No + */ + +params ["_args", "_deleted"]; +_args params ["_marker", "_channelNumber", "_owner", "_local"]; + +if (_deleted) exitWith { + GVAR(plottingBoard_markers) deleteAt _marker; +}; + +// Do not process non-local or already processed markers, don't check if the plotting board isn't shown +if (!_local || {GVAR(plottingBoard_Shown) == 0} || {QUOTE(ADDON) in _marker}) exitWith {}; + +// Check if the channel the marker was made in can be marked on the plotting board +private _continue = true; + +if (isMultiplayer) then { + switch (GVAR(plottingBoardAllowChannelDrawing)) do { + case 0: { + if (_channelNumber != 5) then {_continue = false}; + }; + case 1: { + if !(_channelNumber in [3, 5]) then {_continue = false}; + }; + }; +}; + +if (!_continue) exitWith {}; + +private _boardPos = GVAR(plottingBoard_pos); +private _boardAng = GVAR(plottingBoard_acrylicAngle); + +private _markerPolyline = markerPolyline _marker; +private _count = count _markerPolyline; + +// If the marker is not a polyline marker +if (_count == 0) exitWith { + private _diffPos = (getMarkerPos _marker) vectorDiff _boardPos; + + // If the marker is on the acrylic or ruler of the plotting board, save it + if (vectorMagnitude _diffPos < PLOTTINGBOARD_DRAWRANGE) then { + private _relPos = [[0, 0], _diffPos, _boardAng] call CBA_fnc_vectRotate2D; + + GVAR(plottingBoard_markers) set [_marker, [_relPos, [], _boardAng, +_boardPos, 1]]; + }; +}; + +// If the marker is a polyline marker, but doesn't have enough components (happens when you ctrl-left click on the map), ignore +if (_count <= 4) exitWith {}; + +// Polyine markers (lines) +private _startPos = []; +private _endPos = []; +private _dir = []; +private _diffPos = []; + +private _a = 0; +private _b = 0; +private _c = 0; +private _t1 = nil; +private _t2 = nil; +private _delta = 0; + +private _intersectionValid1 = false; +private _intersectionValid2 = false; +private _intersectPoint1 = []; +private _intersectPoint2 = []; +private _intersectClose = []; +private _intersectFar = []; + +private _polylineIndex = 0; +private _markerArray = [[]]; +private _insideArray = []; + +for "_i" from 0 to _count - 1 - 2 step 2 do { + _startPos = [_markerPolyline select _i, _markerPolyline select (_i + 1)]; + _endPos = [_markerPolyline select (_i + 2), _markerPolyline select (_i + 3)]; + _dir = _endPos vectorDiff _startPos; + _diffPos = _startPos vectorDiff _boardPos; + + // Circle-line intersection: Check for intersections between plotting board and current piece of polyline + // https://stackoverflow.com/a/1084899 + _a = _dir vectorDotProduct _dir; + _b = 2 * (_diffPos vectorDotProduct _dir); + _c = (_diffPos vectorDotProduct _diffPos) - PLOTTINGBOARD_DRAWRANGE^2; + + _delta = _b^2 - 4 * _a * _c; + + // Stretch factors + _t1 = nil; + _t2 = nil; + + if (_delta > 0) then { + _t1 = (-_b + sqrt _delta) / (2 * _a); + _t2 = (-_b - sqrt _delta) / (2 * _a); + + // Don't look for intersection points beyond the start or end points + if (_t1 < 0 || _t1 > 1) then { + _t1 = nil; + }; + + if (_t2 < 0 || _t2 > 1) then { + _t2 = nil; + }; + }; + + // The current point is always part of a polyline + (_markerArray param [_polylineIndex, []]) append _startPos; + _insideArray set [_polylineIndex, vectorMagnitude _diffPos < PLOTTINGBOARD_DRAWRANGE]; // keep track if point is within plotting board + + _intersectionValid1 = !isNil "_t1"; + _intersectionValid2 = !isNil "_t2"; + + // If no valid intersection points, continue + if (!_intersectionValid1 && {!_intersectionValid2}) then { + continue; + }; + + // Extremely rare case if the marker is tangential to the plotting board: Ignore + if (_intersectionValid1 && {_intersectionValid2} && {_t1 == _t2}) then { + continue; + }; + + if (_intersectionValid1) then { + _intersectPoint1 = _startPos vectorAdd (_dir vectorMultiply _t1); + }; + + if (_intersectionValid2) then { + _intersectPoint2 = _startPos vectorAdd (_dir vectorMultiply _t2); + }; + + // When a marker crosses the plotting board entirely (one straight line through the plotting board) + if (_intersectionValid1 && {_intersectionValid2}) then { + // Take the closer point first + _intersectClose = [_intersectPoint1, _intersectPoint2] select (_t1 > _t2); + + // Finish previous polyline with the last point being the intersection + (_markerArray select _polylineIndex) append _intersectClose; + + // Create a new polyline, with the first point being the closest intersection + _polylineIndex = _polylineIndex + 1; + _markerArray set [_polylineIndex, _intersectClose]; + + // Now take the point further away + _intersectFar = [_intersectPoint1, _intersectPoint2] select (_t1 < _t2); + + // Make a polyline between the intersection points + (_markerArray select _polylineIndex) append _intersectClose; + (_markerArray select _polylineIndex) append _intersectFar; + _insideArray set [_polylineIndex, true]; // with 2 intersections, this part of the polyline must be inside + + // Create a new polyline, with the first point being the furthest intersection + _polylineIndex = _polylineIndex + 1; + _markerArray set [_polylineIndex, _intersectFar]; + } else { + // Only 1 intersection (either point 1 or 2, exclusive or) + if (_intersectionValid2) then { + _intersectPoint1 = _intersectPoint2; + }; + + // Finish previous polyline with the last point being the intersection + (_markerArray select _polylineIndex) append _intersectPoint1; + + // Create a new polyline, with the first point being the intersection + _polylineIndex = _polylineIndex + 1; + _markerArray set [_polylineIndex, _intersectPoint1]; + }; +}; + +// If there were no polyline intersections and the marker was not on the plotting board, don't create new markers +if (_insideArray isEqualTo [false]) exitWith {}; + +private _color = getMarkerColor _marker; +private _name = ""; +private _polylineRelative = []; +private _relPos = []; + +{ + _name = format ["%1-%2-%3", _marker, _forEachIndex, QUOTE(ADDON)]; // adding an identifier allow to check if marker was already processed + createMarkerLocal [_name, [0, 0], _channelNumber, _owner]; + _name setMarkerColorLocal _color; + _name setMarkerPolyline _x; // global marker broadcast + + // If the marker was on the plotting board, take it's unrotated position and store it + if (_insideArray select _forEachIndex) then { + _polylineRelative = []; + + for "_i" from 0 to count _x - 1 step 2 do { + _relPos = [[0, 0], [_x select _i, _x select (_i + 1)] vectorDiff _boardPos, _boardAng] call CBA_fnc_vectRotate2D; + _polylineRelative append _relPos; + }; + + GVAR(plottingBoard_markers) set [_name, [[0, 0], +_polylineRelative, _boardAng, +_boardPos, 1]]; + }; +} forEach _markerArray; + +// Delete original marker +deleteMarker _marker; diff --git a/addons/maptools/functions/fnc_isInsideMapTool.sqf b/addons/maptools/functions/fnc_isInsideMapTool.sqf index 97eedf85f3..ad80357411 100644 --- a/addons/maptools/functions/fnc_isInsideMapTool.sqf +++ b/addons/maptools/functions/fnc_isInsideMapTool.sqf @@ -1,35 +1,35 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Return true if the position is inside the map marker (to allow dragging). * * Arguments: - * 0: x Position (in meters) - * 1: y Position (in meters) + * 0: x position (in meters) + * 1: y position (in meters) * * Return Value: - * Boolean + * Is inside map tool * * Example: - * [0, 5] call ACE_maptools_fnc_isInsideMapTool + * [0, 5] call ace_maptools_fnc_isInsideMapTool * * Public: No */ if (GVAR(mapTool_Shown) == 0) exitWith {false}; + private _textureWidth = [TEXTURE_WIDTH_IN_M, TEXTURE_WIDTH_IN_M / 2] select (GVAR(mapTool_Shown) - 1); -private _pos = [_this select 0, _this select 1, 0]; -private _relPos = _pos vectorDiff [GVAR(mapTool_pos) select 0, GVAR(mapTool_pos) select 1, 0]; -private _dirVector = [sin(GVAR(mapTool_angle)), cos(GVAR(mapTool_angle)), 0]; +private _relPos = _this vectorDiff GVAR(mapTool_pos); +private _dirVector = [sin GVAR(mapTool_angle), cos GVAR(mapTool_angle)]; // Projection of the relative position over the longitudinal axis of the map tool private _lambdaLong = _dirVector vectorDotProduct _relPos; + if (_lambdaLong < DIST_BOTTOM_TO_CENTER_PERC * _textureWidth) exitWith {false}; - -// Projection of the relative position over the trasversal axis of the map tool -private _lambdaTrasAbs = vectorMagnitude (_relPos vectorDiff (_dirVector vectorMultiply _lambdaLong)); if (_lambdaLong > DIST_TOP_TO_CENTER_PERC * _textureWidth) exitWith {false}; -if (_lambdaTrasAbs > DIST_LEFT_TO_CENTER_PERC * _textureWidth) exitWith {false}; -true +// Projection of the relative position over the transversal axis of the map tool +private _lambdaTransAbs = vectorMagnitude (_relPos vectorDiff (_dirVector vectorMultiply _lambdaLong)); + +_lambdaTransAbs <= DIST_LEFT_TO_CENTER_PERC * _textureWidth diff --git a/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf b/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf new file mode 100644 index 0000000000..e3e6467508 --- /dev/null +++ b/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf @@ -0,0 +1,56 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Return if the position is inside the map marker (to allow dragging) or not. + * + * Arguments: + * 0: x position (in meters) + * 1: y position (in meters) + * + * Return Value: + * Where in the plotting board it is + * -1 - Nowhere, 0 - In the Board, 1 - In the Acrylic, 2 - In the Ruler + * + * Example: + * [0, 5] call ace_maptools_fnc_isInsidePlottingBoard + * + * Public: No + */ + +if (GVAR(plottingBoard_Shown) == 0) exitWith {-1}; + +private _relPos = _this vectorDiff GVAR(plottingBoard_pos); +private _dist = vectorMagnitude _relPos; + +private _isRuler = if (GVAR(plottingBoard_Shown) == 2) then { + // If it's within these bounds, it's going to be on the ruler + if (_dist <= PLOTTINGBOARD_RULERCENTER) exitWith {true}; + + private _rulerVector = [sin GVAR(plottingBoard_rulerAngle), cos GVAR(plottingBoard_rulerAngle)]; + private _dirRightVector = [_dirVector select 1, -(_dirVector select 0)]; + private _rulerAng = acos (_rulerVector vectorCos _relPos); + + if (cos _rulerAng > 0 && {(tan _rulerAng) * _dist < PLOTTINGBOARD_RULERHALFWIDTH}) exitWith {true}; + + _dist > PLOTTINGBOARD_RULERINNERCIRCLE && {_dist < PLOTTINGBOARD_RULEROUTERCIRCLE && {abs (_rulerAng * DEGTOMILS) < PLOTTINGBOAR_RULEROUTERHALFANGLE}} +} else { + false +}; + +if (_isRuler) exitWith {2}; + +// If it's within 3000 meters, it's going to be on the acrylic +if (_dist < PLOTTINGBOARD_RULEROUTERCIRCLE) exitWith {1}; + +private _dirVector = [sin GVAR(plottingBoard_angle), cos GVAR(plottingBoard_angle)]; +private _dirRightVector = [_dirVector select 1, -(_dirVector select 0)]; + +// Projection of the relative position over the longitudinal axis of the map tool +private _ang = _dirVector vectorCos _relPos; +private _ang2 = _dirRightVector vectorCos _relPos; + +private _relPosAdjusted = [_ang2 * _dist / PLOTTINGBOARD_DRAWRANGE, _ang * _dist / PLOTTINGBOARD_DRAWRANGE]; + +if ((_relPosAdjusted select 0 > 0) && (_relPosAdjusted select 0 < 1) && (abs (_relPosAdjusted select 1) < 1)) exitWith {0}; + +-1 diff --git a/addons/maptools/functions/fnc_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..6d18436625 100644 --- a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf +++ b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf @@ -1,30 +1,39 @@ -#include "script_component.hpp" +#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 control * * 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 _mapGpsDisplay = uiNamespace getVariable [QGVAR(ui_mapGpsDisplay), displayNull]; -private _ctrl = _mapGpsDisplay displayCtrl 913590; +private _mapDisplay = ctrlParent _mapCtrl; + +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/functions/fnc_updateMapToolMarkers.sqf b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf index e9cb14d7ed..1a6d83b698 100644 --- a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf +++ b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf @@ -1,49 +1,130 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: esteldunedain - * Update the map tool markers, position, size, rotation and visibility. + * Author: esteldunedain, LorenLuke + * Update the map tool and plotting board markers. Update their position, size, rotation and visibility. * * Arguments: - * 0: The Map + * 0: Map control * * Return Value: * None * * Example: - * [CONTROL] call ACE_maptools_fnc_updateMapToolMarkers + * [CONTROL] call ace_maptools_fnc_updateMapToolMarkers * * Public: No */ -params ["_theMap"]; +params ["_mapCtrl"]; -if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))}) exitWith {}; - -private _rotatingTexture = ""; -private _textureWidth = 0; -if (GVAR(mapTool_Shown) == 1) then { - _rotatingTexture = QPATHTOF(data\mapToolRotatingNormal.paa); - _textureWidth = TEXTURE_WIDTH_IN_M; +if (GVAR(plottingBoard_Shown) == 0) then { + // Hide all plotting board markers when board is put away + { + if (_y select 4 != 0) then { + _x setMarkerAlpha 0; + _y set [4, 0]; + }; + } forEach GVAR(plottingBoard_markers); } else { - _rotatingTexture = QPATHTOF(data\mapToolRotatingSmall.paa); - _textureWidth = TEXTURE_WIDTH_IN_M / 2; + if !([ACE_player, "ACE_PlottingBoard"] call EFUNC(common,hasItem)) exitWith {}; + + if (GVAR(plottingBoard_moveToMouse)) then { + GVAR(plottingBoard_pos) = _mapCtrl ctrlMapScreenToWorld getMousePosition; + GVAR(plottingBoard_moveToMouse) = false; // we only need to do this once after opening the map tool + }; + + getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; + private _scaleX = 32 * PLOTTINGBOARD_TEXTUREWIDTH * CONSTANT_SCALE * (call FUNC(calculateMapScale)); + private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); // handle bad aspect ratios + + _mapCtrl drawIcon [QPATHTOF(data\plottingBoardBack.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_angle), "", 0]; + _mapCtrl drawIcon [QPATHTOF(data\plottingBoardAcrylic.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_acrylicAngle), "", 0]; + + // Show ruler + if (GVAR(plottingBoard_Shown) == 2) then { + _mapCtrl drawIcon [QPATHTOF(data\plottingBoardRuler.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_rulerAngle), "", 0]; + }; + + private _marker = ""; + private _angle = GVAR(plottingBoard_acrylicAngle); + private _boardPos = GVAR(plottingBoard_pos); + private _count = -1; + private _rotatedPolyPos = []; + private _rotatedPos = []; + + { + _marker = _x; + _y params ["_markerPos", "_polyline", "_lastAngle", "_lastBoardPos", "_lastAlpha"]; + + // Show all plotting board markers when the board is shown + if (_lastAlpha != 1) then { + _marker setMarkerAlpha 1; + _y set [4, 1]; + }; + + // If nothing has changed, don't update marker + if (_angle == _lastAngle && {_boardPos isEqualTo _lastBoardPos}) then { + continue; + }; + + _count = count _polyline; + + // Rotate all points of polyline + if (_count >= 4) then { // polylines need at least 2 points (2 components per point) + _rotatedPolyline = []; + + for "_i" from 0 to _count - 1 step 2 do { + _rotatedPolyPos = [[0, 0], [_polyline select _i, _polyline select (_i + 1)], -_angle] call CBA_fnc_vectRotate2D; + _rotatedPolyline append (_rotatedPolyPos vectorAdd _boardPos); + }; + + _marker setMarkerPolyline _rotatedPolyline; + }; + + // Rotate marker position, regardless of marker type + _rotatedPos = [[0, 0], _markerPos, -_angle] call CBA_fnc_vectRotate2D; + + _marker setMarkerPos (_boardPos vectorAdd _rotatedPos); + + _y set [2, _angle]; + _y set [3, +_boardPos]; + } forEach GVAR(plottingBoard_markers); }; -if (GVAR(freedrawing)) then {[_theMap, _textureWidth] call FUNC(drawLinesOnRoamer);}; +if ((GVAR(mapTool_Shown) != 0) && {[ACE_player, "ACE_MapTools"] call EFUNC(common,hasItem)}) then { + // Open map tools in center of screen when toggled to be shown + if (GVAR(mapTool_moveToMouse)) then { + GVAR(mapTool_pos) = _mapCtrl ctrlMapScreenToWorld getMousePosition; + GVAR(mapTool_moveToMouse) = false; // we only need to do this once after opening the map tool + }; -// Update scale of both parts -getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; -private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale)); -private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); //handle bad aspect ratios + private _rotatingTexture = ""; + private _textureWidth = 0; -// Position of the fixed part -private _xPos = GVAR(mapTool_pos) select 0; -private _yPos = (GVAR(mapTool_pos) select 1) + _textureWidth * CENTER_OFFSET_Y_PERC; + if (GVAR(mapTool_Shown) == 1) then { + _rotatingTexture = QPATHTOF(data\mapToolRotatingNormal.paa); + _textureWidth = TEXTURE_WIDTH_IN_M; + } else { + _rotatingTexture = QPATHTOF(data\mapToolRotatingSmall.paa); + _textureWidth = TEXTURE_WIDTH_IN_M / 2; + }; -_theMap drawIcon [QPATHTOF(data\mapToolFixed.paa), [1,1,1,1], [_xPos,_yPos], _scaleX, _scaleY, 0, "", 0]; + if (GVAR(freedrawing)) then { + [_mapCtrl, _textureWidth] call FUNC(drawLinesOnRoamer); + }; -// Position and rotation of the rotating part -_xPos = (GVAR(mapTool_pos) select 0) + sin(GVAR(mapTool_angle)) * _textureWidth * CENTER_OFFSET_Y_PERC; -_yPos = (GVAR(mapTool_pos) select 1) + cos(GVAR(mapTool_angle)) * _textureWidth * CENTER_OFFSET_Y_PERC; + // Update scale of both parts + getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; + private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale)); + private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); // handle bad aspect ratios -_theMap drawIcon [_rotatingTexture, [1,1,1,1], [_xPos,_yPos], _scaleX, _scaleY, GVAR(mapTool_angle), "", 0]; + // Position of the fixed part + private _pos = GVAR(mapTool_pos) vectorAdd [0, _textureWidth * CENTER_OFFSET_Y_PERC]; + + _mapCtrl drawIcon [QPATHTOF(data\mapToolFixed.paa), [1, 1, 1, 1], _pos, _scaleX, _scaleY, 0, "", 0]; + + // Position and rotation of the rotating part + _pos = GVAR(mapTool_pos) vectorAdd ([sin GVAR(mapTool_angle), cos GVAR(mapTool_angle)] vectorMultiply (_textureWidth * CENTER_OFFSET_Y_PERC)); + + _mapCtrl drawIcon [_rotatingTexture, [1, 1, 1, 1], _pos, _scaleX, _scaleY, GVAR(mapTool_angle), "", 0]; +}; diff --git a/addons/maptools/functions/fnc_wipeMarkers.sqf b/addons/maptools/functions/fnc_wipeMarkers.sqf new file mode 100644 index 0000000000..5131e469a3 --- /dev/null +++ b/addons/maptools/functions/fnc_wipeMarkers.sqf @@ -0,0 +1,23 @@ +#include "../script_component.hpp" +/* + * Author: LorenLuke + * Delete all markers on the plotting board. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_maptools_fnc_wipeMarkers + * + * Public: No + */ + +{ + deleteMarker _x; +} forEach (keys GVAR(plottingBoard_markers)); + +// Reset list +GVAR(plottingBoard_markers) = createHashMap; diff --git a/addons/maptools/functions/script_component.hpp b/addons/maptools/functions/script_component.hpp deleted file mode 100644 index adeb2788b5..0000000000 --- a/addons/maptools/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\maptools\script_component.hpp" diff --git a/addons/maptools/initSettings.inc.sqf b/addons/maptools/initSettings.inc.sqf new file mode 100644 index 0000000000..172054ff77 --- /dev/null +++ b/addons/maptools/initSettings.inc.sqf @@ -0,0 +1,25 @@ +private _category = format ["ACE %1", LLSTRING(Name)]; + +[ + QGVAR(rotateModifierKey), "LIST", + [LSTRING(rotateModifierKey_displayName), LSTRING(rotateModifierKey_description)], + _category, + [[0, 1, 2, 3], ["STR_A3_OPTIONS_DISABLED", "ALT", "CTRL", "SHIFT"], 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(drawStraightLines), "CHECKBOX", + [LSTRING(drawStraightLines_displayName), LSTRING(drawStraightLines_description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(plottingBoardAllowChannelDrawing), "LIST", + [LSTRING(allowChannelDrawing_displayName), LSTRING(allowChannelDrawing_description)], + _category, + [[0, 1], [LSTRING(allowDirectCommsOnly), LSTRING(allowDirectGroupComms)], 1], + 0 +] call CBA_fnc_addSetting; diff --git a/addons/maptools/script_component.hpp b/addons/maptools/script_component.hpp index 4710caa7a3..adbc1fb3f6 100644 --- a/addons/maptools/script_component.hpp +++ b/addons/maptools/script_component.hpp @@ -16,9 +16,19 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define TEXTURE_WIDTH_IN_M 6205 -#define CENTER_OFFSET_Y_PERC 0.1606 -#define CONSTANT_SCALE 0.2 +#define DEGTOMILS 17.7777778 + +#define TEXTURE_WIDTH_IN_M 6205 +#define CENTER_OFFSET_Y_PERC 0.1606 +#define CONSTANT_SCALE 0.2 #define DIST_BOTTOM_TO_CENTER_PERC -0.33 -#define DIST_TOP_TO_CENTER_PERC 0.65 -#define DIST_LEFT_TO_CENTER_PERC 0.30 +#define DIST_TOP_TO_CENTER_PERC 0.65 +#define DIST_LEFT_TO_CENTER_PERC 0.30 + +#define PLOTTINGBOARD_DRAWRANGE 3000 +#define PLOTTINGBOARD_TEXTUREWIDTH 6000 +#define PLOTTINGBOARD_RULERCENTER 450 +#define PLOTTINGBOARD_RULERHALFWIDTH 100 +#define PLOTTINGBOARD_RULERINNERCIRCLE 2900 +#define PLOTTINGBOARD_RULEROUTERCIRCLE 3000 +#define PLOTTINGBOARD_RULEROUTERHALFANGLE 100 diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index c22c654bfb..7e1d0cee97 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -12,10 +12,11 @@ Ferramentas de Mapa Térképészeti eszközök Инструменты карты - マップ ツール + マップツール 독도용 도구 地图工具 地圖工具 + Harita Araçları The Map Tools allow you to measure distances and angles on the map. @@ -28,10 +29,31 @@ As Ferramentas de Mapa permitem que você meça distâncias e ângulos no mapa. A térképészeti eszközökkel távolságokat és szögeket tudsz mérni a térképen. Картографические инструменты позволяют измерять расстояния и углы на карте. - マップ ツールは地図上で距離や角度を測れます。 + マップツールは地図上で距離や角度を測れます。 독도용 도구는 지도상에서 거리나 각도를 잴 수 있게 해줍니다. 地图工具能够让你在地图上测量距离与角度 地圖工具能夠讓你在地圖上測量距離與角度 + Harita Araçları, haritadaki mesafeleri ve açıları ölçmenize olanak tanır. + + + Plotting Board + 플로팅 보드 + 標定盤 + Tavola di calcolo + Графическая доска + Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado + + + The Plotting Board is a map tool designed for use in the directing of short range indirect fires. + 플로팅 보드는 단거리 간접 사격을 지시하는 데 사용하도록 설계된 독도용 도구입니다. + 標定盤(プロッティング・ボード)は、短距離の間接射撃の指示に使用するために設計されたマップツールです。 + La tavola di calcolo è uno strumento utilizzato per dirigere fuoco di artiglieria a corto raggio. + Графическая доска - это картографический инструмент, предназначенный для использования при ведении непрямого огня с малой дистанции. + Une planche traçante est un outil cartographique conçu pour diriger des tirs indirects à courte distance. + Das Wurfparabel-Kartenwerkzeug ist ein Werkzeug, das für die Steuerung indirekten Feuers auf kurze Distanz entwickelt wurde. + El Tablero de Trazado es una herramienta de mapa utilizada para dirigir fuego indirecto de corto alcance. Map Tools @@ -44,10 +66,11 @@ Ferramentas de Mapa Térképészeti eszközök Инструменты карты - マップ ツール + マップツール 독도용 도구 地图工具 地圖工具 + Harita Araçları Hide Map Tool @@ -60,80 +83,85 @@ Ukryj narzędzia nawigacyjne Schovat pomůcky k mapě Скрыть инструменты - マップ ツールを隠す + マップツールを 隠す 독도용 도구 숨기기 隐藏地图工具 隱藏地圖工具 + Harita Aracını gizle Show Normal Map Tool Zeige Kartenwerkzeug (normal) Mostrar herr. de mapa normal - Montrer les outils de cartographie (normaux) - Visualizza Strumenti Cartografici standard + Montrer les outils de navigation (normaux) + Visualizza Strumento Cartografico Normale Mostrar Ferramenta de Mapa Padrão Térképészeti eszköz megjelenítése (normál méret) Pokaż normalne narzędzia nawigacyjne Zobrazit pomůcku k mapě (Velkou) Показать инструменты (средн. размер) - マップ ツールを表示する + マップツールを 表示する 보통 독도용 도구로 보기 显示地图工具 顯示地圖工具 + Normal Harita Aracını Göster Show Small Map Tool Zeige Kartenwerkzeug (klein) Mostrar herr. de mapa pequeñas - Montrer les outils de cartographie (petits) - Visualizza Strumenti Cartografici piccoli + Montrer les outils de navigation (petits) + Visualizza Strumento Cartografico Piccolo Mostrar Ferramenta de Mapa Pequena Térképészeti eszköz megjelenítése (kicsinyített) Pokaż pomniejszone narzędzia nawigacyjne Zobrazit pomůcku k mapě (Malou) Показать инструменты (малый размер) - 小さいマップ ツールを表示する + 小さい マップツールを 表示する 작은 독도용 도구로 보기 显示小的地图工具 顯示小的地圖工具 + Küçük Harita Aracını Göster Align Map Tool to North Kartenwerkzeug nach Norden ausrichten Alinear herr. de mapa al norte Aligner les outils sur le nord - Allinea gli Strumenti Cartografici con il Nord + Allinea Strumento Cartografico verso Nord Alinhar Ferramenta de Mapa com o Norte Térképészeti eszköz Északhoz állítása Wyrównaj linijkę do północy Srovnat pomůcku k mapě na sever Выровнять инструменты на север - マップ ツールを北に合わせる + マップツールを 北に合わせる 독도용 도구를 북쪽으로 정렬 地图工具对准北方 地圖工具對準北方 + Harita Aracını Kuzeye Hizala Align Map Tool to Compass Kartenwerkzeug am Kompass ausrichten Alinear herr. de mapa a la brújula Aligner les outils sur la boussole - Allinea gli Strumenti Cartografici con la bussola + Allinea Strumento Cartografico con la bussola Alinhar Ferramenta de Mapa com a Bússola Térképészeti eszköz iránytűhöz állítása Wyrównaj linijkę do kompasu Srovnat pomůcku k mapě ke kompasu Выровнять инструменты по компасу - マップ ツールを方位磁石に合わせる + マップツールを 方位磁石に合わせる 독도용 도구를 나침반에 정렬 - 地图工具对准指北针 + 地图工具对准指南针 地圖工具對準指北針 + Harita Aracını Pusulaya Hizala Show GPS on Map Zeige GPS auf der Karte Mostrar el GPS sobre el mapa - Montrer le GPS + Afficher le GPS sur la carte Visualizza il GPS sulla mappa Mostrar GPS no Mapa GPS megjelenítése a térképen @@ -142,14 +170,15 @@ Показать GPS на карте 地図上に GPS を表示する GPS를 지도상에 꺼내기 - 在地图上显示GPS + 在地图上显示 GPS 在地圖上顯示GPS + Harita da GPS Göster Hide GPS on Map Verstecke GPS auf der Karte Ocultar el GPS del mapa - Ranger le GPS + Masquer le GPS sur la carte Nascondi il GPS sulla mappa Ocultar GPS no Mapa GPS elrejtése a térképről @@ -158,8 +187,9 @@ Скрыть GPS на карте 地図上から GPS を隠す GPS를 지도상에서 숨기기 - 在地图上隐藏GPS + 在地图上隐藏 GPS 在地圖上隱藏GPS + Harita da GPS'i Gizle Direction: %1° @@ -172,58 +202,277 @@ Направление: %1° Direzione: %1° Direção: %1 - 方位:%1° + 方向: %1° 방위: %1° - 方位: %1° + 方位:%1° 方位: %1° + Yön: %1° Rotate Map Tools Key - Touche de rotation des outils de naviguation + Touche de rotation des outils de navigation Клавиша поворота инструментов карты - マップ ツールの回転キー + マップツールの回転キー Klawisz obrotu narzędzi nawigacyjnych Taste zum Drehen des Kartenwerkzeugs 독도용 도구 돌리기 키 - Ruota Strumenti di Mappatura + Tasto per Ruotare Strumenti Cartografici 选转地图工具的按键 選轉地圖工具的按鍵 + Tecla para girar Ferramentas de Mapa + Klávesa pro otáčení pomůcky k mapě + Harita Aracının Yönünü Değiştirme Tuşu + Tecla para rotar herramientas de mapa Modifier key to allow rotating map tools - Touche modificatrice permettant la rotation des outils de naviguation + Touche modificatrice permettant la rotation des outils de navigation. Клавиша-модификатор, позволяющая поворачивать инструменты карты - マップ ツールを回転させるキーを編集できます。 + マップツールを回転させるキーを編集できます。 Modyfikator pozwalający na obracanie narzędzi nawigacyjnych Steuerungstaste, um Drehung des Kartenwerkzeugs zu ermöglichen. 독도용 도구를 돌리기 위한 키를 변경할 수 있습니다. - Tasto modifica per consentire strumenti di mappatura rotanti + Tasto modificatore per ruotare strumenti cartografici 修改旋转地图工具的按键 修改旋轉地圖工具的按鍵 + Tecla de Modificador para permitir girar as ferramentas de mapa + Klávesa která umožnuje otáčení pomůcky k mapě + Dönen harita araçlarına izin veren değiştirici tuş + Tecla modificadora para permitir rotar herramientas de mapa Draw straight lines with maptools - マップ ツールを使って直線を書く + マップツールを使って直線を書く Zeichne gerade Linien mit dem Kartenwerkzeug 독도용 도구로 직선 그리기 Rysuj proste linie przy użyciu narzędzi nawigacyjnych Tracer des lignes droites - Disegna linee dritte con gli strumenti di mappatura + Disegna linee dritte con gli strumenti cartografici 使用地图工具来绘制直线 使用地圖工具來繪製直線 Прямые линии с инструментами карты + Desenhar linhas retas com as ferramentas de mapa + Kreslit rovné čáry s pomůckou k mapě + Maptools ile düz çizgiler çizme + Dibujar línea recta con las herramientas de mapa Draw on the edge of maptools to draw straight lines. Note: Must hover at midpoint to delete. - マップ ツールの端から直線を書きます。メモ: 線の中央ホバーすると削除します。 + マップツールの端に線を描くことで直線を描けるようにします。 備考: 削除するには線の中間点にカーソルを合わせる必要があります。 Zeichne gerade Linien am Rand des Kartenwerkzeugs. Hinweis: zum Löschen über den Mittelpunkt der Linie fahren 독도용 도구 가장자리에 직선을 그립니다. 주의: 삭제하기 위해선 선의 중앙에 가져다 대십시요 Przeciągnij po krawędzi narzędzi nawigacyjnych by narysować prostą linię. Uwaga: aby usunąć linię - nalezy ustawić kursor nad jej środkiem. - Utiliser le bord des outils de navigation pour tracer des lignes droites. Note: l'on doit survoler le milieu du trait pour pouvoir le supprimer. - Disegna sul bordo degli strumenti di mappatura per disegnare linee dritte. Nota: Deve spostarsi al centro per essere cancellato. - 使用地图工具的边缘来绘制直线。备注: 要删除直线时,请把滑鼠移动到该线条的中央即可删除该线。 + Utilise le bord des outils de navigation pour tracer des lignes droites. Note : il faut pointer au milieu du trait pour pouvoir le supprimer. + Disegna lungo il bordo degli strumenti cartografici per disegnare linee dritte. Nota: Dovrai puntare il centro delle linee per cancellarle. + 使用地图工具的边缘来绘制直线。备注:要删除直线时,请把鼠标移动到该线条的中央即可删除该线。 使用地圖工具的邊緣來繪製直線。備註: 要刪除直線時,請把滑鼠移動到該線條的中央即可刪除該線 Рисуйте по краю инструмента карты, чтобы провести прямые линии. Примечание: при удалении линии размещайте курсор над ее серединой + Desenhe no canto da ferramenta de mapa para desenhar linhas retas. Observação: Sobreponha o meio com o mouse para deletar. + Povolit kreslení rovných čar při kreslení na okraji pomůcky k mapě. Poznámka: Pro smazání musíte mít kurzor nad středem čáry. + Düz çizgiler çizmek için maptools'un kenarına çizin. Not: Silmek için orta noktada fareyle üzerine gelmeniz gerekir. + Dibujar sobre el borde de las herramientas de mapa para dibujar líneas rectas. Nota: Debe situarse en el punto intermedio para eliminarla. + + + Allow Plotting Board Drawing channels + 標定盤への書き込みを許可するチャンネル + 플로팅 보드 그리기 채널 허용 + Canali ammessi su tavola di calcolo + Разрешить создание каналов на миллиметровой доске. + Canaux autorisés sur la planche traçante + Wurfparabel Kartenwerkzeug erlaubte Kanäle + Permitir Canales de Dibujado de Tablero de Trazado + + + Channels in which plotting board drawing is enabled. + どのチャンネルで標定盤の書き込みを有効化するか。 + 플로팅 보드 그리기가 활성화된 채널입니다. + Canali in cui si può disegnare sulla tavola di calcolo. + Каналы, в которых включено рисование на миллиметровой доске. + Canaux dans lesquels vous pouvez dessiner sur le planche traçante + Kanäle, in denen das Zeichnen mit dem Wurfparabel-Kartenwerkzeug auf der Karte erlaubt ist. + Canales en los que el tablero de trazado está habilitado. + + + Allow Direct Comms Only (Polylines Only) + 直接チャンネルのみ許可 (線のみ) + 직접교신만 허용 (선 긋기만) + Comunicazioni Dirette (solo linee) + Разрешать только прямую связь (только полилинии) + Communications directes uniquement (lignes uniquement) + Nur direkte Kommunikation zulassen (nur Polylinien) + Permitir Sólo Comunicaciones Directas (Sólo Polylineas) + + + Allow Direct/Group Comms (Polylines and Group Markers) + 直接/グループチャンネルを許可 (線とグループマーカー) + 직접교신/그룹무전망 허용 (선 긋기와 그룹 마커) + Comunicazioni dirette/gruppo (linee e marker) + Разрешить прямую/групповую связь (полилинии и групповые маркеры) + Autoriser les communications directes/de groupe (polylignes et marqueurs de groupe) + Direkte/Gruppenkommunikation zulassen (Polylinien und Gruppenmarkierungen) + Permitir Comunicaciones Directas/Grupales (Polylineas y Marcadores de Grupo) + + + Plotting Board + 標定盤 + 플로팅 보드 + Tavola di calcolo + Миллиметровая доска + Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado + + + Plotting Board Acrylic + 標定盤の アクリル板 + 플로팅 보드 (아크릴) + Acrilico tavola di calcolo + Миллиметровая доска акрилловая + Planche traçante Acrylique + Wurfparabel Kartenwerkzeug Acryl + Tablero de Trazado Acrílico + + + Plotting Board Ruler + 標定盤の 定規 + 플로팅 보드 (자) + Righello tavola di calcolo + Линейка для миллиметровой доски + Règle de la planche traçante + Wurfparabel Kartenwerkzeug Lineal + Regla de Tablero de Trazado + + + To Plotting Board + 標定盤に + 플로팅 보드에 + Su tavola di calcolo + К миллиметровой доске. + Sur la planche traçante + Zum Wurfparabel Kartenwerkzeug + A Tablero de Trazado + + + To Plotting Board Acrylic + 標定盤の アクリル板に + 플로팅 보드 (아크릴)에 + Su acrilico tavola di calcolo + К миллиметровой доске акрилловой + Sur la planche traçante Acrylique + Zum Wurfparabel Kartenwerkzeug Acryl + A Tablero de Trazado Acrílico + + + To Plotting Board Ruler + 標定盤の 定規に + 플로팅 보드 (자)에 + Su righello tavola di calcolo + К линейке миллиметровой доски. + Sur la règle de la planche traçante + Zum Wurfparabel Kartenwerkzeug Lineal + A Regla de Tablero de Trazado + + + Wipe all markers off Plotting Board + 標定盤の 全マーカーを 拭き消す + 플로팅 보드에 있는 모든 마커 지우기 + Cancella tutti i disegni dalla tavola + Сотрите все маркеры с миллиметровой доски. + Effacer tous les dessins de la planche traçante + Alle Markierungen vom Wurfparabel Kartenwerkzeug entfernen + Borrar todas las marcas del Tablero de Trazado + + + Show Plotting Board + 標定盤を 表示 + 플로팅 보드 보이기 + Mostra tavola di calcolo + Показать миллиметровую доску. + Afficher la planche traçante + Zeige Wurfparabel Kartenwerkzeug + Mostrar Tablero de Trazado + + + Hide Plotting Board + 標定盤を 隠す + 플로팅 보드 숨기기 + Nascondi tavola di calcolo + Скрыть миллиметровую доску. + Masquer la planche traçante + Verstecke Wurfparabel Kartenwerkzeug + Ocultar Tablero de Trazado + + + Toggle Plotting Board Ruler + 標定盤の 定規を 表示切替 + 플로팅 보드 (자) 토글 + Mostra/Nascondi Righello + Переключить линейку миллиметровой доски. + Afficher/masquer la règle + Schalte das Lineal des Wurfparabel-Kartenwerkzeuges um + Alternar Regla de Tablero de Trazado + + + Align + Ausrichten + Alinear + Aligner + Allinea + Alinhar + Állítása + Wyrównaj + Srovnat + Выровнять + 맞춤 기준: + 向きを合わせる + + + To North + Nach Norden + Al norte + Sur le nord + Con il Nord + Com o Norte + Északhoz + Do północy + Na sever + На север + 북쪽으로 + 北に + + + To Compass + Am Kompass + A la brújula + Sur la boussole + Con la bussola + Com a Bússola + Iránytűhöz + Do kompasu + Ke kompasu + По компасу + 方位磁石に + 나침반으로 + + + Up + 上に + 위로 + Su + Вверх + Monter + Nach oben + Arriba + + + To Maptool + マップツールに + 독도용 도구로 + Su strumento cartografico + К инструментам карты + Outil cartographique + Zum Kartenwerkzeug + A Herramienta de Mapa diff --git a/addons/marker_flags/$PBOPREFIX$ b/addons/marker_flags/$PBOPREFIX$ new file mode 100644 index 0000000000..cf7a6f6f77 --- /dev/null +++ b/addons/marker_flags/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\marker_flags diff --git a/addons/marker_flags/CfgEventHandlers.hpp b/addons/marker_flags/CfgEventHandlers.hpp new file mode 100644 index 0000000000..b468b9e8b5 --- /dev/null +++ b/addons/marker_flags/CfgEventHandlers.hpp @@ -0,0 +1,23 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + +class Extended_DisplayLoad_EventHandlers { + class RscDisplayMission { + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); + }; +}; diff --git a/addons/marker_flags/CfgVehicles.hpp b/addons/marker_flags/CfgVehicles.hpp new file mode 100644 index 0000000000..6a615ca533 --- /dev/null +++ b/addons/marker_flags/CfgVehicles.hpp @@ -0,0 +1,52 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ACE_Equipment { + class ADDON { + displayName = CSTRING(ActionPlace); + condition = QUOTE(_player call FUNC(canPlace)); + insertChildren = QUOTE(_this call FUNC(addActions)); + icon = QPATHTOF(ui\icons\white_place_icon.paa); + }; + }; + }; + }; + + class FlagMarker_01_F; + class GVAR(white): FlagMarker_01_F { + scope = 2; + scopeCurator = 2; + author = ECSTRING(common,ACETeam); + displayName = CSTRING(white); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.82,0.82,0.82,1,co)"}; + }; + class GVAR(black): GVAR(white) { + displayName = CSTRING(black); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.18,0.18,0.18,1,co)"}; + }; + class GVAR(red): GVAR(white) { + displayName = CSTRING(red); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.647,0.141,0.161,1,co)"}; + }; + class GVAR(green): GVAR(white) { + displayName = CSTRING(green); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.063,0.588,0.063,1,co)"}; + }; + class GVAR(blue): GVAR(white) { + displayName = CSTRING(blue); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.161,0.349,0.58,1,co)"}; + }; + class GVAR(yellow): GVAR(white) { + displayName = CSTRING(yellow); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.776,0.729,0.129,1,co)"}; + }; + class GVAR(orange): GVAR(white) { + displayName = CSTRING(orange); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.678,0.349,0.153,1,co)"}; + }; + class GVAR(purple): GVAR(white) { + displayName = CSTRING(purple); + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.373,0.141,0.647,1,co)"}; + }; +}; diff --git a/addons/marker_flags/CfgWeapons.hpp b/addons/marker_flags/CfgWeapons.hpp new file mode 100644 index 0000000000..13a1632f4f --- /dev/null +++ b/addons/marker_flags/CfgWeapons.hpp @@ -0,0 +1,63 @@ +class CfgWeapons { + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + class GVAR(white): ACE_ItemCore { + GVAR(vehicle) = QGVAR(white); + GVAR(icon) = QPATHTOF(ui\icons\white_place_icon.paa); + author = ECSTRING(common,ACETeam); + scope = 2; + displayName = CSTRING(white); + model = QPATHTOF(data\ace_markerpole.p3d); + picture = QPATHTOF(ui\white_ca.paa); + icon = "iconObject_1x10"; + mapSize = 0.2; + + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.5; + }; + }; + + class GVAR(black): GVAR(white) { + GVAR(vehicle) = QGVAR(black); + GVAR(icon) = QPATHTOF(ui\icons\black_place_icon.paa); + displayName = CSTRING(black); + picture = QPATHTOF(ui\black_ca.paa); + }; + class GVAR(red): GVAR(white) { + GVAR(vehicle) = QGVAR(red); + GVAR(icon) = QPATHTOF(ui\icons\red_place_icon.paa); + displayName = CSTRING(red); + picture = QPATHTOF(ui\red_ca.paa); + }; + class GVAR(green): GVAR(white) { + GVAR(vehicle) = QGVAR(green); + GVAR(icon) = QPATHTOF(ui\icons\green_place_icon.paa); + displayName = CSTRING(green); + picture = QPATHTOF(ui\green_ca.paa); + }; + class GVAR(blue): GVAR(white) { + GVAR(vehicle) = QGVAR(blue); + GVAR(icon) = QPATHTOF(ui\icons\blue_place_icon.paa); + displayName = CSTRING(blue); + picture = QPATHTOF(ui\blue_ca.paa); + }; + class GVAR(yellow): GVAR(white) { + GVAR(vehicle) = QGVAR(yellow); + GVAR(icon) = QPATHTOF(ui\icons\yellow_place_icon.paa); + displayName = CSTRING(yellow); + picture = QPATHTOF(ui\yellow_ca.paa); + }; + class GVAR(orange): GVAR(white) { + GVAR(vehicle) = QGVAR(orange); + GVAR(icon) = QPATHTOF(ui\icons\orange_place_icon.paa); + displayName = CSTRING(orange); + picture = QPATHTOF(ui\orange_ca.paa); + }; + class GVAR(purple): GVAR(white) { + GVAR(vehicle) = QGVAR(purple); + GVAR(icon) = QPATHTOF(ui\icons\purple_place_icon.paa); + displayName = CSTRING(purple); + picture = QPATHTOF(ui\purple_ca.paa); + }; +}; diff --git a/addons/marker_flags/XEH_PREP.hpp b/addons/marker_flags/XEH_PREP.hpp new file mode 100644 index 0000000000..628433ff1c --- /dev/null +++ b/addons/marker_flags/XEH_PREP.hpp @@ -0,0 +1,6 @@ +PREP(addActions); +PREP(canPlace); +PREP(getFlags); +PREP(handleScrollWheel); +PREP(pickUpFlag); +PREP(placeFlag); diff --git a/addons/marker_flags/XEH_missionDisplayLoad.sqf b/addons/marker_flags/XEH_missionDisplayLoad.sqf new file mode 100644 index 0000000000..fc336ad799 --- /dev/null +++ b/addons/marker_flags/XEH_missionDisplayLoad.sqf @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +params ["_display"]; + +_display displayAddEventHandler ["MouseZChanged", { + params ["", "_scroll"]; + [_scroll] call FUNC(handleScrollWheel); +}]; + +_display displayAddEventHandler ["MouseButtonDown", { + params ["", "_button"]; + if (GVAR(isPlacing) isNotEqualTo PLACE_WAITING) exitWith {false}; + if (_button isNotEqualTo 1) exitWith {false}; // 1 = Left mouse button + GVAR(isPlacing) = PLACE_CANCEL; +}]; diff --git a/addons/marker_flags/XEH_postInit.sqf b/addons/marker_flags/XEH_postInit.sqf new file mode 100644 index 0000000000..19011893cc --- /dev/null +++ b/addons/marker_flags/XEH_postInit.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +GVAR(isPlacing) = PLACE_CANCEL; +["ace_interactMenuOpened", {GVAR(isPlacing) = PLACE_CANCEL;}] call CBA_fnc_addEventHandler; + +private _cfgWeapons = configFile >> "CfgWeapons"; +private _weapons = (call (uiNamespace getVariable [QGVAR(flagItems), {[]}])) apply {_cfgWeapons >> _x}; + +{ + private _name = configName _x; + private _vehicleClass = getText (_x >> QGVAR(vehicle)); + private _displayName = getText (_x >> "displayName"); + private _icon = getText (_x >> QGVAR(icon)); + GVAR(flagCache) set [_name, [_vehicleClass, _displayName, _icon]]; + + private _action = [ + QGVAR(pickup), + LLSTRING(ActionPickUp), + QPATHTOF(ui\icons\white_pickup_icon.paa), + {call FUNC(pickUpFlag)}, + {[_player, _target, []] call EFUNC(common,canInteractWith)}, + {}, + [_name], + [0, 0.072, 0.2], + 2 + ] call EFUNC(interact_menu,createAction); + [_vehicleClass, 0, [], _action] call EFUNC(interact_menu,addActionToClass); +} forEach _weapons; diff --git a/addons/marker_flags/XEH_preInit.sqf b/addons/marker_flags/XEH_preInit.sqf new file mode 100644 index 0000000000..ed043fcb05 --- /dev/null +++ b/addons/marker_flags/XEH_preInit.sqf @@ -0,0 +1,13 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +GVAR(flagCache) = createHashMap; + +ADDON = true; diff --git a/addons/marker_flags/XEH_preStart.sqf b/addons/marker_flags/XEH_preStart.sqf new file mode 100644 index 0000000000..2a2bc52161 --- /dev/null +++ b/addons/marker_flags/XEH_preStart.sqf @@ -0,0 +1,6 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" + +private _weapons = (configProperties [configfile >> "CfgWeapons", QUOTE(isClass _x && {isText (_x >> QQGVAR(vehicle))}), true]) apply {configName _x}; +uiNamespace setVariable [QGVAR(flagItems), compileFinal str _weapons]; diff --git a/addons/marker_flags/config.cpp b/addons/marker_flags/config.cpp new file mode 100644 index 0000000000..078a0d8e7e --- /dev/null +++ b/addons/marker_flags/config.cpp @@ -0,0 +1,37 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = { + QGVAR(white), + QGVAR(black), + QGVAR(red), + QGVAR(green), + QGVAR(blue), + QGVAR(yellow), + QGVAR(orange), + QGVAR(purple) + }; + weapons[] = { + QGVAR(white), + QGVAR(black), + QGVAR(red), + QGVAR(green), + QGVAR(blue), + QGVAR(yellow), + QGVAR(orange), + QGVAR(purple) + }; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "ace_interaction", "ace_interact_menu"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Brett Mayson", "Timi007"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/marker_flags/data/ace_default.rvmat b/addons/marker_flags/data/ace_default.rvmat new file mode 100644 index 0000000000..782c9714b8 --- /dev/null +++ b/addons/marker_flags/data/ace_default.rvmat @@ -0,0 +1,79 @@ +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.01,0.01,0.01,1}; //amount of glossiness - the higher the number, the higher the glossiness +specularPower=500; //area of glossiness - the higher the number, the smaller the area +PixelShaderID="Super"; +VertexShaderID="Super"; + +class Stage1 { + texture="#(rgb,1,1,1)color(0.5,0.5,1,1)"; + 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="#(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,1}; + }; +}; +class Stage5 { + texture="#(rgb,1,1,1)color(0.2,0.2,1,1)"; + 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(4.7,1.2)"; + 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_ca.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/marker_flags/data/ace_markerpole.p3d b/addons/marker_flags/data/ace_markerpole.p3d new file mode 100644 index 0000000000..8722db4260 Binary files /dev/null and b/addons/marker_flags/data/ace_markerpole.p3d differ diff --git a/addons/marker_flags/functions/fnc_addActions.sqf b/addons/marker_flags/functions/fnc_addActions.sqf new file mode 100644 index 0000000000..98e62633db --- /dev/null +++ b/addons/marker_flags/functions/fnc_addActions.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson, Timi007 + * Adds the child actions for placing flags. + * + * Arguments: + * 0: Player + * + * Return Value: + * Actions + * + * Example: + * [player] call ace_marker_flags_fnc_addActions + * + * Public: No + */ + +params ["_unit"]; + +private _actions = []; + +{ + (GVAR(flagCache) get _x) params ["_vehicle", "_displayName", "_icon"]; + + _actions pushBack [ + [ + _x, + _displayName, + _icon, + {[_this select 0, _this select 2] call FUNC(placeFlag)}, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; +} forEach ([_unit] call FUNC(getFlags)); + +_actions diff --git a/addons/marker_flags/functions/fnc_canPlace.sqf b/addons/marker_flags/functions/fnc_canPlace.sqf new file mode 100644 index 0000000000..0ddeff533e --- /dev/null +++ b/addons/marker_flags/functions/fnc_canPlace.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Authors: Brett Mayson + * Checks if a flag can be placed by a unit. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Can place + * + * Example: + * player call ace_marker_flags_fnc_canPlace + * + * Public: No + */ + +params ["_unit"]; + +GVAR(placeAnywhere) || {_unit call EFUNC(common,canDig)} diff --git a/addons/marker_flags/functions/fnc_getFlags.sqf b/addons/marker_flags/functions/fnc_getFlags.sqf new file mode 100644 index 0000000000..579a63229d --- /dev/null +++ b/addons/marker_flags/functions/fnc_getFlags.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Authors: Brett Mayson + * Get the placeable flags in the unit's inventory. + * + * Arguments: + * 0: Unit + * + * Return Value: + * flags + * + * Example: + * [_unit] call ace_marker_flags_fnc_getFlags + * + * Public: No + */ + +params ["_unit"]; + +(_unit call EFUNC(common,uniqueItems)) arrayIntersect keys GVAR(flagCache) diff --git a/addons/marker_flags/functions/fnc_handleScrollWheel.sqf b/addons/marker_flags/functions/fnc_handleScrollWheel.sqf new file mode 100644 index 0000000000..e9dc7b7424 --- /dev/null +++ b/addons/marker_flags/functions/fnc_handleScrollWheel.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: Timi007 + * Handles the marker flag object height. + * + * Arguments: + * 0: Scroll amount + * + * Return Value: + * Handled + * + * Example: + * [5] call ace_marker_flags_fnc_handleScrollWheel + * + * Public: No + */ + +params ["_scrollAmount"]; + +if (GVAR(isPlacing) isNotEqualTo PLACE_WAITING) exitWith { + false +}; + +// Move object height 5cm per scroll +GVAR(objectHeight) = GVAR(objectHeight) + (_scrollAmount * 0.05); + +// Clamp height between MIN_HEIGHT and MAX_HEIGHT +GVAR(objectHeight) = MIN_HEIGHT max (GVAR(objectHeight) min MAX_HEIGHT); + +true diff --git a/addons/marker_flags/functions/fnc_pickUpFlag.sqf b/addons/marker_flags/functions/fnc_pickUpFlag.sqf new file mode 100644 index 0000000000..661f476fb6 --- /dev/null +++ b/addons/marker_flags/functions/fnc_pickUpFlag.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson, Timi007 + * Places a flag in front of the unit. + * + * Arguments: + * 0: Flag + * 1: Unit + * 2: Action Args + * + * Return Value: + * Nothing + * + * Example: + * [_flag, player, ["ace_marker_flags_white"]] call ace_marker_flags_fnc_pickupFlag + * + * Public: No + */ + +params [["_flag", objNull, [objNull]], ["_unit", objNull, [objNull]], ["_args", [""], [[]]]]; +_args params ["_item"]; +TRACE_3("pickupFlag",_unit,_flag,_itemName); + +if (isNull _flag) exitWith {}; + +[_unit, "PutDown"] call EFUNC(common,doGesture); + +[{ + params ["_flag", "_unit", "_item"]; + + [_unit, _item] call EFUNC(common,addToInventory); + deleteVehicle _flag; +}, [_flag, _unit, _item], 0.7] call CBA_fnc_waitAndExecute; diff --git a/addons/marker_flags/functions/fnc_placeFlag.sqf b/addons/marker_flags/functions/fnc_placeFlag.sqf new file mode 100644 index 0000000000..5dd2abb376 --- /dev/null +++ b/addons/marker_flags/functions/fnc_placeFlag.sqf @@ -0,0 +1,74 @@ +#include "..\script_component.hpp" +/* + * Author: Timi007 + * Starts the placing process of the marker flag for the player. + * Flags can be placed with the special marker flag items. + * + * Arguments: + * 0: Player + * 1: Flag item + * + * Return Value: + * Nothing + * + * Example: + * [player, "ace_marker_flags_white"] call ace_marker_flags_fnc_placeFlag + * + * Public: No + */ + +params [["_player", objNull, [objNull]], ["_item", QGVAR(white), [""]]]; +TRACE_2("Placing flag",_player,_item); + +(GVAR(flagCache) get _item) params ["_vehicleClass"]; + +private _flag = _vehicleClass createVehicle [0, 0, 0]; + +TRACE_1("Created flag",_flag); + +// Set flag start height +GVAR(objectHeight) = MAX_HEIGHT; + +GVAR(isPlacing) = PLACE_WAITING; + +// Add info dialog for the player which show the controls +[LLSTRING(ActionPlace), LLSTRING(ActionCancel), LLSTRING(ActionAdjustHeight)] call EFUNC(interaction,showMouseHint); + +private _mouseClickID = [_player, "DefaultAction", { + GVAR(isPlacing) isEqualTo PLACE_WAITING +}, { + GVAR(isPlacing) = PLACE_APPROVE +}] call EFUNC(common,addActionEventHandler); + +[{ + params ["_args", "_handle"]; + _args params ["_player", "_item", "_flag", "_mouseClickID"]; + + if (isNull _flag || {!([_player, _flag] call EFUNC(common,canInteractWith))}) then { + GVAR(isPlacing) = PLACE_CANCEL; + }; + + if (GVAR(isPlacing) isNotEqualTo PLACE_WAITING) exitWith { + [_handle] call CBA_fnc_removePerFrameHandler; + call EFUNC(interaction,hideMouseHint); + [_player, "DefaultAction", _mouseClickID] call EFUNC(common,removeActionEventHandler); + + if (GVAR(isPlacing) isEqualTo PLACE_APPROVE) then { + // End position of the flag + GVAR(isPlacing) = PLACE_CANCEL; + [_player, "PutDown"] call EFUNC(common,doGesture); + _player removeItem _item; + [QGVAR(placed), [_player, _flag, _item]] call CBA_fnc_localEvent; + } else { + // Action is canceled + deleteVehicle _flag; + }; + }; + + private _pos = (eyePos _player) vectorAdd ((getCameraViewDirection _player) vectorMultiply FLAG_PLACING_DISTANCE); + // Adjust height of flag with the scroll wheel + _pos set [2, ((getPosWorld _player) select 2) + GVAR(objectHeight)]; + + _flag setPosWorld _pos; + _flag setDir (getDir _player - 90); +}, 0, [_player, _item, _flag, _mouseClickID]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/marker_flags/initSettings.inc.sqf b/addons/marker_flags/initSettings.inc.sqf new file mode 100644 index 0000000000..74ae5a0721 --- /dev/null +++ b/addons/marker_flags/initSettings.inc.sqf @@ -0,0 +1,9 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(DisplayName_Settings)]; + +[ + QGVAR(placeAnywhere), "CHECKBOX", + [LSTRING(PlaceAnywhere_DisplayName), LSTRING(PlaceAnywhere_Description)], + _category, + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/marker_flags/script_component.hpp b/addons/marker_flags/script_component.hpp new file mode 100644 index 0000000000..bef8c1d423 --- /dev/null +++ b/addons/marker_flags/script_component.hpp @@ -0,0 +1,26 @@ +#define COMPONENT marker_flags +#define COMPONENT_BEAUTIFIED Marker Flags +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_MARKER_FLAGS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_ENABLED_MARKER_FLAGS + #define DEBUG_SETTINGS DEBUG_ENABLED_MARKER_FLAGS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define PLACE_WAITING -1 +#define PLACE_CANCEL 0 +#define PLACE_APPROVE 1 + +#define MIN_HEIGHT -0.3 +#define MAX_HEIGHT 0.4 + +#define FLAG_PLACING_DISTANCE 2 diff --git a/addons/marker_flags/stringtable.xml b/addons/marker_flags/stringtable.xml new file mode 100644 index 0000000000..31aab77e84 --- /dev/null +++ b/addons/marker_flags/stringtable.xml @@ -0,0 +1,205 @@ + + + + + Marker Flags + Markierungsfahnen + Bandiere segnaletiche + Chorągiewki + マーカー旗 + 마킹용 깃발 + 标记旗 + Флажки + Banderas de señalizado + Drapeaux de marquage + Bandeiras de marcação + + + Place Anywhere + Überall platzieren + Piazza ovunque + どこでも設置可能 + Umieść w dowolnym miejscu + 아무 곳에나 배치 + 随意放置 + Размещать где угодно + Colocar en cualquier lugar + Placer partout + Colocar em qualquer lugar + + + Place marker flag anywhere regardless of surface. + どのような地表でも旗を設置できるようにします + Umieść chorągiewkę w dowolnym miejscu, niezależnie od powierzchni. + 지면에 상관없이 아무곳에서나 마킹용 깃발을 배치합니다. + 不管地形表面是什么都可以放标记旗 + Размещать флажки где угодно вне зависимости от поверхности. + Permitir colocar las banderas de señalizado en cualquier lugar, al margen del tipo de superficie. + Platzieren Sie die Markierungsfahne überall, unabhängig von der Oberfläche. + Piazza bandiere segnaletiche ovunque, indipendentemente dalla superficie. + Place un drapeau de marquage n'importe où, quelle que soit la surface. + Permite colocar as bandeiras de marcação em qualquer lugar, independente do tipo de superfice + + + Place Marker Flag + Markierungsfahne platzieren + Piazza bandiera segnaletica + Postaw chorągiewkę + 마킹용 깃발 꽂기 + Поставить флажок + Colocar Bandera de señalizado + マーカー旗 を置く + Placer le drapeau de marquage + Colocar Bandeira de Marcação + + + Adjust height + Höhe anpassen + Modifica altezza + Dostosuj wysokość + 높이 조정 + Регулировать высоту + Ajustar altura + 高さを調整する + Ajuster la hauteur + Ajustar altura + + + Cancel + Abbrechen + Cancelar + Anuluj + Annuler + Zrušit + Annulla + Mégsem + Cancelar + Отмена + 中止 + 취소 + 取消 + 取消 + Iptal + + + Pick Up + 提取點 + Récupérer + Recoger + Recupera + Podnieś + Подобрать + Vyzvednutí + Pegar + 가져가기 + 提取点 + 拾う + Al + Aufheben + + + Marker Flag (White) + Markierungsfahne (Weiß) + Bandiera segnaletica (Bianca) + Chorągiewka (Biała) + マーカー旗 (白) + 마킹용 깃발(하양) + 标记旗(白) + Флажок (белый) + Bandera de señalizado (Blanca) + Drapeau de marquage (Blanc) + Bandeira de Marcação (Branca) + + + Marker Flag (Black) + Markierungsfahne (Schwarz) + Bandiera segnaletica (Nera) + Chorągiewka (Czarna) + マーカー旗 (黒) + 마킹용 깃발(검정) + 标记旗(黑) + Флажок (чёрный) + Bandera de señalizado (Negra) + Drapeau de marquage (Noir) + Bandeira de Marcação (Preta) + + + Marker Flag (Red) + Markierungsfahne (Rot) + Bandiera segnaletica (Rossa) + Chorągiewka (Czerwona) + マーカー旗 (赤) + 마킹용 깃발(빨강) + 标记旗(红) + Флажок (красный) + Bandera de señalizado (Roja) + Drapeau de marquage (Rouge) + Bandeira de Marcação (Vermelha) + + + Marker Flag (Green) + Markierungsfahne (Grün) + Bandiera segnaletica (Verde) + Chorągiewka (Zielona) + マーカー旗 (緑) + 마킹용 깃발(초록) + 标记旗(绿) + Флажок (зелёный) + Bandera de señalizado (Verde) + Drapeau de marquage (Vert) + Bandeira de Marcação (Verde) + + + Marker Flag (Blue) + Markierungsfahne (Blau) + Bandiera segnaletica (Blu) + Chorągiewka (Niebieska) + マーカー旗 (青) + 마킹용 깃발(파랑) + 标记旗(蓝) + Флажок (синий) + Bandera de señalizado (Azul) + Drapeau de marquage (Bleu) + Bandeira de Marcação (Azul) + + + Marker Flag (Yellow) + Markierungsfahne (Gelb) + Bandiera segnaletica (Gialla) + Chorągiewka (Żółta) + マーカー旗 (黄) + 마킹용 깃발(노랑) + 标记旗(黄) + Флажок (жёлтый) + Bandera de señalizado (Amarilla) + Drapeau de marquage (Jaune) + Bandeira de Marcação (Amarela) + + + Marker Flag (Orange) + Markierungsfahne (Orange) + Bandiera segnaletica (Arancione) + Chorągiewka (Pomarańczowa) + マーカー旗 (橙) + 마킹용 깃발(주황) + 标记旗(橙) + Флажок (оранжевый) + Bandera de señalizado (Naranja) + Drapeau de marquage (Orange) + Bandeira de Marcação (Laranja) + + + Marker Flag (Purple) + Markierungsfahne (Lila) + Bandiera segnaletica (Viola) + Chorągiewka (Fioletowa) + マーカー旗 (紫) + 마킹용 깃발(보라) + 标记旗(紫) + Флажок (фиолетовый) + Bandera de señalizado (Púrpura) + Drapeau de marquage (Violet) + Bandeira de Marcação (Roxa) + + + diff --git a/addons/marker_flags/ui/black_ca.paa b/addons/marker_flags/ui/black_ca.paa new file mode 100644 index 0000000000..72ac604b6b Binary files /dev/null and b/addons/marker_flags/ui/black_ca.paa differ diff --git a/addons/marker_flags/ui/blue_ca.paa b/addons/marker_flags/ui/blue_ca.paa new file mode 100644 index 0000000000..9c45de381f Binary files /dev/null and b/addons/marker_flags/ui/blue_ca.paa differ diff --git a/addons/marker_flags/ui/green_ca.paa b/addons/marker_flags/ui/green_ca.paa new file mode 100644 index 0000000000..72a2f62d6c Binary files /dev/null and b/addons/marker_flags/ui/green_ca.paa differ diff --git a/addons/marker_flags/ui/icons/black_place_icon.paa b/addons/marker_flags/ui/icons/black_place_icon.paa new file mode 100644 index 0000000000..5526fc2c92 Binary files /dev/null and b/addons/marker_flags/ui/icons/black_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/blue_place_icon.paa b/addons/marker_flags/ui/icons/blue_place_icon.paa new file mode 100644 index 0000000000..8f899cae24 Binary files /dev/null and b/addons/marker_flags/ui/icons/blue_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/green_place_icon.paa b/addons/marker_flags/ui/icons/green_place_icon.paa new file mode 100644 index 0000000000..151b597cfe Binary files /dev/null and b/addons/marker_flags/ui/icons/green_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/orange_place_icon.paa b/addons/marker_flags/ui/icons/orange_place_icon.paa new file mode 100644 index 0000000000..7477a4a07f Binary files /dev/null and b/addons/marker_flags/ui/icons/orange_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/purple_place_icon.paa b/addons/marker_flags/ui/icons/purple_place_icon.paa new file mode 100644 index 0000000000..1c5a63d8ef Binary files /dev/null and b/addons/marker_flags/ui/icons/purple_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/red_place_icon.paa b/addons/marker_flags/ui/icons/red_place_icon.paa new file mode 100644 index 0000000000..c0fcea9048 Binary files /dev/null and b/addons/marker_flags/ui/icons/red_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/white_pickup_icon.paa b/addons/marker_flags/ui/icons/white_pickup_icon.paa new file mode 100644 index 0000000000..bc5d4ac7e4 Binary files /dev/null and b/addons/marker_flags/ui/icons/white_pickup_icon.paa differ diff --git a/addons/marker_flags/ui/icons/white_place_icon.paa b/addons/marker_flags/ui/icons/white_place_icon.paa new file mode 100644 index 0000000000..c4f03200d8 Binary files /dev/null and b/addons/marker_flags/ui/icons/white_place_icon.paa differ diff --git a/addons/marker_flags/ui/icons/yellow_place_icon.paa b/addons/marker_flags/ui/icons/yellow_place_icon.paa new file mode 100644 index 0000000000..965a36185f Binary files /dev/null and b/addons/marker_flags/ui/icons/yellow_place_icon.paa differ diff --git a/addons/marker_flags/ui/orange_ca.paa b/addons/marker_flags/ui/orange_ca.paa new file mode 100644 index 0000000000..f6d8b0643a Binary files /dev/null and b/addons/marker_flags/ui/orange_ca.paa differ diff --git a/addons/marker_flags/ui/purple_ca.paa b/addons/marker_flags/ui/purple_ca.paa new file mode 100644 index 0000000000..4a8e620bd9 Binary files /dev/null and b/addons/marker_flags/ui/purple_ca.paa differ diff --git a/addons/marker_flags/ui/red_ca.paa b/addons/marker_flags/ui/red_ca.paa new file mode 100644 index 0000000000..b570688bc9 Binary files /dev/null and b/addons/marker_flags/ui/red_ca.paa differ diff --git a/addons/marker_flags/ui/white_ca.paa b/addons/marker_flags/ui/white_ca.paa new file mode 100644 index 0000000000..c69afdec28 Binary files /dev/null and b/addons/marker_flags/ui/white_ca.paa differ diff --git a/addons/marker_flags/ui/yellow_ca.paa b/addons/marker_flags/ui/yellow_ca.paa new file mode 100644 index 0000000000..c085ad2376 Binary files /dev/null and b/addons/marker_flags/ui/yellow_ca.paa differ diff --git a/addons/markers/ACE_Settings.hpp b/addons/markers/ACE_Settings.hpp index d8d72a5975..847d3eacde 100644 --- a/addons/markers/ACE_Settings.hpp +++ b/addons/markers/ACE_Settings.hpp @@ -1,7 +1,4 @@ class ACE_Settings { - class GVAR(movableMarkersEnabled) { - movedToSQF = 1; - }; class GVAR(moveRestriction) { movedToSQF = 1; }; diff --git a/addons/markers/CfgEventHandlers.hpp b/addons/markers/CfgEventHandlers.hpp index e1f9294767..818c34b9dd 100644 --- a/addons/markers/CfgEventHandlers.hpp +++ b/addons/markers/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/markers/InsertMarker.hpp b/addons/markers/InsertMarker.hpp index 5d7cc987e2..e31c7bb5a7 100644 --- a/addons/markers/InsertMarker.hpp +++ b/addons/markers/InsertMarker.hpp @@ -5,28 +5,41 @@ class RscStructuredText; class RscButtonMenuOK; class RscButtonMenuCancel; class RscButtonMenu; +class RscCheckBox; class RscEdit; class RscCombo; class RscSlider; class RscXSliderH; class RscDisplayInsertMarker { - onLoad = QUOTE(_this call DFUNC(initInsertMarker);); - onUnload = QUOTE(_this call DFUNC(placeMarker);); + onLoad = QUOTE(_this call DFUNC(initInsertMarker)); + onUnload = QUOTE(_this call DFUNC(placeMarker)); movingEnable = 1; class controls { + class TimeStampText: RscStructuredText { + idc = IDC_ACE_INSERT_MARKER_TIMESTAMP_TEXT; + }; + class TimeStamp: RscCheckBox { + idc = IDC_ACE_INSERT_MARKER_TIMESTAMP; + }; class MarkerShape: RscCombo { - idc = 1210; + idc = IDC_ACE_INSERT_MARKER_SHAPE; }; class MarkerColor: RscCombo { - idc = 1211; + idc = IDC_ACE_INSERT_MARKER_COLOR; }; class MarkerAngle: RscXSliderH { - idc = 1220; + idc = IDC_ACE_INSERT_MARKER_ANGLE; }; class MarkerAngleText: RscText { - idc = 1221; + idc = IDC_ACE_INSERT_MARKER_ANGLE_TEXT; + }; + class MarkerScale: RscXSliderH { + idc = IDC_ACE_INSERT_MARKER_SCALE; + }; + class MarkerScaleText: RscText { + idc = IDC_ACE_INSERT_MARKER_SCALE_TEXT; }; }; }; diff --git a/addons/markers/README.md b/addons/markers/README.md index aa9538f8bb..42fbfa29a1 100644 --- a/addons/markers/README.md +++ b/addons/markers/README.md @@ -2,12 +2,3 @@ ace_markers =========== Completely replaces the default marker system, allowing quicker and more precise placement of markers. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/markers/XEH_PREP.hpp b/addons/markers/XEH_PREP.hpp index bbac954b66..113b48bb82 100644 --- a/addons/markers/XEH_PREP.hpp +++ b/addons/markers/XEH_PREP.hpp @@ -6,6 +6,9 @@ PREP(onLBSelChangedChannel); PREP(onLBSelChangedColor); PREP(onLBSelChangedShape); PREP(onSliderPosChangedAngle); +PREP(onSliderMouseButtonUpAngle); +PREP(onSliderPosChangedScale); +PREP(onSliderMouseButtonUpScale); PREP(placeMarker); PREP(sendMarkersJIP); PREP(setMarkerJIP); @@ -14,3 +17,7 @@ PREP(canMove); PREP(onMouseButtonDown); PREP(onMouseButtonUp); PREP(movePFH); +PREP(canTimestamp); +PREP(onButtonClickConfirm); +PREP(onCheckedChangedTimestamp); +PREP(removeTimestamp); diff --git a/addons/markers/XEH_postInit.sqf b/addons/markers/XEH_postInit.sqf index 7f644691d3..1ae489dd82 100644 --- a/addons/markers/XEH_postInit.sqf +++ b/addons/markers/XEH_postInit.sqf @@ -2,10 +2,10 @@ #include "script_component.hpp" // recieve remote marker data -[QGVAR(setMarkerNetwork), {_this call DFUNC(setMarkerNetwork)}] call CBA_fnc_addEventHandler; +[QGVAR(setMarkerNetwork), LINKFUNC(setMarkerNetwork)] call CBA_fnc_addEventHandler; // recieve marker data for JIP -[QGVAR(setMarkerJIP), {_this call DFUNC(setMarkerJIP)}] call CBA_fnc_addEventHandler; +[QGVAR(setMarkerJIP), LINKFUNC(setMarkerJIP)] call CBA_fnc_addEventHandler; // request marker data for JIP if (isMultiplayer && {!isServer} && {hasInterface}) then { @@ -15,6 +15,7 @@ if (isMultiplayer && {!isServer} && {hasInterface}) then { GVAR(mapDisplaysWithDrawEHs) = []; GVAR(currentMarkerPosition) = []; GVAR(currentMarkerAngle) = 0; +GVAR(currentMarkerScale) = 1; GVAR(currentMarkerColorConfigName) = ""; GVAR(currentMarkerConfigName) = ""; @@ -31,7 +32,7 @@ GVAR(userPlacedMarkers) = []; if (_index < 0) exitWith { if (!isMultiplayer) exitWith {}; - WARNING_1("Could not find data for %1", _marker); + WARNING_1("Could not find data for %1",_marker); }; private _data = GVAR(allMapMarkersProperties) select _index; diff --git a/addons/markers/XEH_preInit.sqf b/addons/markers/XEH_preInit.sqf index 885a0a3068..142dedb89a 100644 --- a/addons/markers/XEH_preInit.sqf +++ b/addons/markers/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // init marker types if (isNil QGVAR(MarkersCache)) then { diff --git a/addons/markers/functions/fnc_canMove.sqf b/addons/markers/functions/fnc_canMove.sqf index 2b2eaf5e9f..a915905b79 100644 --- a/addons/markers/functions/fnc_canMove.sqf +++ b/addons/markers/functions/fnc_canMove.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: chris579 * Checks whether the player can move markers. @@ -17,6 +17,8 @@ params [["_marker",""]]; +if ((markerShape _marker) == "POLYLINE") exitWith { false }; + switch (GVAR(moveRestriction)) do { case MOVE_RESTRICTION_NOBODY: {false}; case MOVE_RESTRICTION_ALL: {true}; diff --git a/addons/markers/functions/fnc_canTimestamp.sqf b/addons/markers/functions/fnc_canTimestamp.sqf new file mode 100644 index 0000000000..5d9234f04a --- /dev/null +++ b/addons/markers/functions/fnc_canTimestamp.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Freddo + * Checks whether a unit is able to timestamp. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Whether unit is able to timestamp + * + * Example: + * [ACE_Player] call ace_markers_fnc_canTimestamp + * + * Public: No + */ + +params [["_unit", ACE_player]]; + +private _assignedItems = assignedItems _unit; + +private _index = _assignedItems findIf { + ([_x] call EFUNC(common,getItemType)) isEqualTo ["item", "watch"] +}; + +_index != -1 diff --git a/addons/markers/functions/fnc_getEnabledChannels.sqf b/addons/markers/functions/fnc_getEnabledChannels.sqf index bc665cf69c..291544f73e 100644 --- a/addons/markers/functions/fnc_getEnabledChannels.sqf +++ b/addons/markers/functions/fnc_getEnabledChannels.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, Timi007 + * Author: commy2, Timi007, LinkIsGrim * Return enabled channels. * * Arguments: @@ -17,33 +17,19 @@ params [["_localize", false, [false]]]; -private _currentChannel = currentChannel; private _enabledChannels = []; +private _currentChannel = currentChannel; -if (_localize) then { - if (setCurrentChannel 0) then { - _enabledChannels pushBack localize "str_channel_global"; - }; +// Micro-optimization so we don't rebuild the array and localize in each iteration +private _engineChannels = CHANNEL_NAMES; - if (setCurrentChannel 1) then { - _enabledChannels pushBack localize "str_channel_side"; - }; - - if (setCurrentChannel 2) then { - _enabledChannels pushBack localize "str_channel_command"; - }; - - if (setCurrentChannel 3) then { - _enabledChannels pushBack localize "str_channel_group"; - }; - - if (setCurrentChannel 4) then { - _enabledChannels pushBack localize "str_channel_vehicle"; - }; -} else { - for "_i" from 0 to 4 do { - if (setCurrentChannel _i) then { - _enabledChannels pushBack _i; +for "_channelId" from 0 to 15 do { + if (_channelId == 5) then {continue}; // Direct channel, ignore + if (setCurrentChannel _channelId) then { + if (_localize) then { + _enabledChannels pushBack (_engineChannels param [_channelId, (radioChannelInfo (_channelId - 5)) select 1]); // radioChannelInfo works off custom IDs only, offset engine channels + } else { + _enabledChannels pushBack _channelId; }; }; }; diff --git a/addons/markers/functions/fnc_initInsertMarker.sqf b/addons/markers/functions/fnc_initInsertMarker.sqf index 8a7a5f21fb..a102502b24 100644 --- a/addons/markers/functions/fnc_initInsertMarker.sqf +++ b/addons/markers/functions/fnc_initInsertMarker.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BIS, commy2, Timi007 * Sets up the marker placement @@ -25,37 +25,39 @@ //Can't place markers when can't interact if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith { - _display closeDisplay 2; //emulate "Cancel" button + _display closeDisplay 2; //emulate "Cancel" button }; //BIS Controls: - private _text = _display displayctrl 101; - private _picture = _display displayctrl 102; - private _channel = _display displayctrl 103; - private _buttonOK = _display displayctrl 1; - private _buttonCancel = _display displayctrl 2; + private _text = _display displayctrl IDC_INSERT_MARKER; + private _picture = _display displayctrl IDC_INSERT_MARKER_PICTURE; + private _channel = _display displayctrl IDC_INSERT_MARKER_CHANNELS; + private _buttonOK = _display displayctrl IDC_OK; + private _buttonCancel = _display displayctrl IDC_CANCEL; private _description = _display displayctrl 1100; private _title = _display displayctrl 1001; private _descriptionChannel = _display displayctrl 1101; //ACE Controls: - // _sizeX = _display displayctrl 1200; - // _sizeY = _display displayctrl 1201; - private _aceShapeLB = _display displayctrl 1210; - private _aceColorLB = _display displayctrl 1211; - private _aceAngleSlider = _display displayctrl 1220; - private _aceAngleSliderText = _display displayctrl 1221; + private _ctrlTimestamp = _display displayCtrl IDC_ACE_INSERT_MARKER_TIMESTAMP; + private _ctrlTimestampText = _display displayCtrl IDC_ACE_INSERT_MARKER_TIMESTAMP_TEXT; + private _aceShapeLB = _display displayctrl IDC_ACE_INSERT_MARKER_SHAPE; + private _aceColorLB = _display displayctrl IDC_ACE_INSERT_MARKER_COLOR; + private _aceAngleSlider = _display displayctrl IDC_ACE_INSERT_MARKER_ANGLE; + private _aceAngleSliderText = _display displayctrl IDC_ACE_INSERT_MARKER_ANGLE_TEXT; + private _aceScaleSlider = _display displayctrl IDC_ACE_INSERT_MARKER_SCALE; + private _aceScaleSliderText = _display displayctrl IDC_ACE_INSERT_MARKER_SCALE_TEXT; private _mapDisplay = displayParent _display; if (isNull _mapDisplay) exitWith {ERROR("No Map");}; - private _mapCtrl = _mapDisplay displayCtrl 51; + private _mapCtrl = _mapDisplay displayCtrl IDC_MAP; GVAR(editingMarker) = ""; (ctrlMapMouseOver _mapCtrl) params ["_mouseOverType", "_marker"]; //check if entity under mouse is a user marker if (_mouseOverType isEqualTo "marker") then { - if (!((_marker find "_USER_DEFINED") isEqualTo -1) && ((markerShape _marker) isEqualTo "ICON")) then { + if (((_marker find "_USER_DEFINED") isNotEqualTo -1) && ((markerShape _marker) isEqualTo "ICON")) then { GVAR(editingMarker) = _marker; //hide marker which is being edited because if the user cancels editing, it will still exist unchanged GVAR(editingMarker) setMarkerAlphaLocal 0; @@ -71,12 +73,15 @@ //////////////////// // Calculate center position of the marker placement ctrl - if !(GVAR(editingMarker) isEqualTo "") then { + if (GVAR(editingMarker) isNotEqualTo "") then { //prevent changing the original marker position GVAR(currentMarkerPosition) = markerPos GVAR(editingMarker); } else { private _pos = ctrlPosition _picture; - _pos = [(_pos select 0) + (_pos select 2) / 2, (_pos select 1) + (_pos select 3) / 2]; + _pos = [ + (_pos select 0) + (_pos select 2) / 2, + (_pos select 1) + (_pos select 3) / 2 + ]; GVAR(currentMarkerPosition) = _mapCtrl ctrlMapScreenToWorld _pos; }; @@ -86,9 +91,11 @@ // prevent vanilla key input _display displayAddEventHandler ["KeyDown", {(_this select 1) in [200, 208]}]; - if !((markerText GVAR(editingMarker)) isEqualTo "") then { - //fill text input with text from marker which is being edited - _text ctrlSetText (markerText GVAR(editingMarker)); + private _markerText = markerText GVAR(editingMarker); + if (_markerText != "") then { + // fill text input with text from marker which is being edited + _markerText = _markerText call FUNC(removeTimestamp); + _text ctrlSetText _markerText; }; //Focus on the text input @@ -98,7 +105,8 @@ private _pos = ctrlposition _text; _pos params ["_posX", "_posY", "_posW", "_posH"]; _posX = _posX + 0.01; - _posY = _posY min ((safeZoneH + safeZoneY) - (8 * _posH + 8 * BORDER)); //prevent buttons being placed below bottom edge of screen + _posY = _posY min ((safeZoneH + safeZoneY) - (11 * _posH + 11 * BORDER)); //prevent buttons being placed below bottom edge of screen + _pos set [0, _posX]; _pos set [1, _posY]; _text ctrlSetPosition _pos; @@ -112,47 +120,98 @@ //--- Description _pos set [1, _posY - 1 * _posH]; - _pos set [3,6 * _posH + 6 * BORDER]; + if (GVAR(timestampEnabled)) then { + _pos set [3,9 * _posH + 9 * BORDER]; + } else { + _pos set [3,10 * _posH + 10 * BORDER]; + }; _description ctrlEnable false; _description ctrlSetPosition _pos; _description ctrlSetStructuredText parseText format ["%1", localize "str_lib_label_description"]; _description ctrlCommit 0; + //--- Timestamp + private _timestampOffset = 0; + if (GVAR(timestampEnabled)) then { + _timestampOffset = _posH + BORDER; + + private _left = _posX; + private _top = _posY + 1 * _posH + 2 * BORDER; + private _width = _posH * safeZoneH / safeZoneW; + private _height = _posH; + + _ctrlTimestamp ctrlSetPosition [_left, _top, _width, _height]; + _ctrlTimestamp ctrlCommit 0; + + _ctrlTimestampText ctrlSetStructuredText parseText format ["%1", LLSTRING(Timestamp)]; + + _left = _left + _width; + _width = _posW - _width; + _top = _top + 0.1 * _height; + _ctrlTimestampText ctrlSetPosition [_left, _top, _width, _height]; + _ctrlTimestampText ctrlCommit 0; + + if !([ACE_player] call FUNC(canTimestamp)) then { + _ctrlTimestamp ctrlEnable false; + _ctrlTimestamp ctrlSetTooltip LLSTRING(TimestampTooltipNoWatch); + } else { + _ctrlTimestamp cbSetChecked (uiNamespace getVariable [QGVAR(timestampChecked), false]); + }; + } else { + _ctrlTimestampText ctrlEnable false; + _ctrlTimestampText ctrlShow false; + _ctrlTimestamp ctrlEnable false; + _ctrlTimestamp ctrlShow false; + }; + //--- Shape - _pos set [1, _posY + 1 * _posH + 2 * BORDER]; + _pos set [0, _posX]; + _pos set [1, _posY + 1 * _posH + 2 * BORDER + _timestampOffset]; _pos set [2, _posW]; _pos set [3, _posH]; _aceShapeLB ctrlSetPosition _pos; _aceShapeLB ctrlCommit 0; //--- Color - _pos set [1, _posY + 2 * _posH + 3 * BORDER]; + _pos set [1, _posY + 2 * _posH + 3 * BORDER + _timestampOffset]; _pos set [2, _posW]; _aceColorLB ctrlSetPosition _pos; _aceColorLB ctrlCommit 0; //--- Angle - _pos set [1, _posY + 3 * _posH + 4 * BORDER]; + _pos set [1, _posY + 3 * _posH + 4 * BORDER + _timestampOffset]; _pos set [2, _posW]; _aceAngleSlider ctrlSetPosition _pos; _aceAngleSlider ctrlCommit 0; //--- Angle Text - _pos set [1, _posY + 4 * _posH + 5 * BORDER]; + _pos set [1, _posY + 4 * _posH + 5 * BORDER + _timestampOffset]; _pos set [2, _posW]; _aceAngleSliderText ctrlSetPosition _pos; _aceAngleSliderText ctrlCommit 0; + //--- Scale + _pos set [1, _posY + 5 * _posH + 6 * BORDER + _timestampOffset]; + _pos set [2, _posW]; + _aceScaleSlider ctrlSetPosition _pos; + _aceScaleSlider ctrlCommit 0; + + //--- Scale Text + _pos set [1, _posY + 6 * _posH + 7 * BORDER + _timestampOffset]; + _pos set [2, _posW]; + _aceScaleSliderText ctrlSetPosition _pos; + _aceScaleSliderText ctrlCommit 0; + private _offsetButtons = 0; if (isMultiplayer) then { - _pos set [1,_posY + 5 * _posH + 7 * BORDER]; + _pos set [1,_posY + 7 * _posH + 9 * BORDER + _timestampOffset]; _pos set [3,_posH]; _descriptionChannel ctrlSetStructuredText parseText format ["%1:", localize "str_a3_cfgvehicles_modulerespawnposition_f_arguments_marker_0"]; _descriptionChannel ctrlSetPosition _pos; _descriptionChannel ctrlCommit 0; - _pos set [1,_posY + 6 * _posH + 7 * BORDER]; + _pos set [1,_posY + 8 * _posH + 9 * BORDER + _timestampOffset]; _pos set [3,_posH]; _channel ctrlSetPosition _pos; _channel ctrlCommit 0; @@ -164,42 +223,42 @@ while {_i < lbSize _channel} do { private _channelName = _channel lbText _i; - // _enabledChannels can not include custom channels names. Therefore also check if it's a custom one. Blame BI if the unit should not access the channel. - if (_channelName in _enabledChannels || {!(_channelName in CHANNEL_NAMES)}) then { + if (_channelName in _enabledChannels) then { _i = _i + 1; } else { _channel lbDelete _i; }; }; - private _selectChannel = if !(GVAR(editingMarker) isEqualTo "") then { + private _selectChannel = if (GVAR(editingMarker) isNotEqualTo "") then { //get the channel where the marker was placed in parseNumber ((GVAR(editingMarker) splitString "/") param [2, "3"]) } else { currentChannel }; - private _currentChannelName = CHANNEL_NAMES param [_selectChannel, localize "str_channel_group"]; + // engine channels (0-4) can use names directly, custom channels need an offset for radioChannelInfo + private _selectChannelName = CHANNEL_NAMES param [_selectChannel, radioChannelInfo (_selectChannel - 5) select 1]; // select current channel in list box, must be done after lbDelete for "_j" from 0 to (lbSize _channel - 1) do { - if (_channel lbText _j == _currentChannelName) then { + if (_channel lbText _j == _selectChannelName) then { _channel lbSetCurSel _j; - setCurrentChannel (CHANNEL_NAMES find _currentChannelName); + setCurrentChannel _selectChannel; }; }; _channel ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChangedChannel)}]; - _offsetButtons = 7 * _posH + 8 * BORDER; + _offsetButtons = 9 * _posH + 10 * BORDER; } else { _descriptionChannel ctrlShow false; _channel ctrlShow false; - _offsetButtons = 5 * _posH + 7 * BORDER; + _offsetButtons = 7 * _posH + 9 * BORDER; }; //--- ButtonOK - _pos set [1, _posY + _offsetButtons]; + _pos set [1, _posY + _offsetButtons + _timestampOffset]; _pos set [2, _posW / 2 - BORDER]; _pos set [3, _posH]; _buttonOk ctrlSetPosition _pos; @@ -207,12 +266,17 @@ //--- ButtonCancel _pos set [0, _posX + _posW / 2]; - _pos set [1, _posY + _offsetButtons]; + _pos set [1, _posY + _offsetButtons + _timestampOffset]; _pos set [2, _posW / 2]; _pos set [3, _posH]; _buttonCancel ctrlSetPosition _pos; _buttonCancel ctrlCommit 0; + //////////////////// + // init marker timestamp cb + _buttonOK ctrlAddEventHandler ["ButtonClick", FUNC(onButtonClickConfirm)]; + _ctrlTimestamp ctrlAddEventHandler ["CheckedChanged", FUNC(onCheckedChangedTimestamp)]; + //////////////////// // init marker shape lb lbClear _aceShapeLB; @@ -261,15 +325,35 @@ // init marker angle slider _aceAngleSlider sliderSetRange [-180, 180]; - if !(GVAR(editingMarker) isEqualTo "") then { + if (GVAR(editingMarker) isNotEqualTo "") then { //get the original direction GVAR(currentMarkerAngle) = markerDir GVAR(editingMarker); }; private _curSelAngle = GETGVAR(currentMarkerAngle,0); _aceAngleSlider sliderSetPosition _curSelAngle; + _aceAngleSlider ctrlSetTooltip LLSTRING(MarkerDirectionScaleSlider_Tooltip); //Update now and add eventHandler: [_aceAngleSlider, _curSelAngle] call FUNC(onSliderPosChangedAngle); _aceAngleSlider ctrlAddEventHandler ["SliderPosChanged", {_this call FUNC(onSliderPosChangedAngle)}]; + _aceAngleSlider ctrlAddEventHandler ["MouseButtonUp", {_this call FUNC(onSliderMouseButtonUpAngle)}]; + + //////////////////// + // init marker scale slider + _aceScaleSlider sliderSetRange [0.5, 2.0]; + + if (GVAR(editingMarker) isNotEqualTo "") then { + //get the original scale + GVAR(currentMarkerScale) = (markerSize GVAR(editingMarker)) param [0, 1]; + }; + + private _curSelScale = GETGVAR(currentMarkerScale,1); + _aceScaleSlider sliderSetPosition _curSelScale; + _aceScaleSlider ctrlSetTooltip LLSTRING(MarkerDirectionScaleSlider_Tooltip); + + //Update now and add eventHandler: + [_aceScaleSlider, _curSelScale] call FUNC(onSliderPosChangedScale); + _aceScaleSlider ctrlAddEventHandler ["SliderPosChanged", {_this call FUNC(onSliderPosChangedScale)}]; + _aceScaleSlider ctrlAddEventHandler ["MouseButtonUp", {_this call FUNC(onSliderMouseButtonUpScale)}]; }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/markers/functions/fnc_mapDisplayInitEH.sqf b/addons/markers/functions/fnc_mapDisplayInitEH.sqf index 3ab874c445..e5242b9067 100644 --- a/addons/markers/functions/fnc_mapDisplayInitEH.sqf +++ b/addons/markers/functions/fnc_mapDisplayInitEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles XEH DisplayLoad for the various map displays (RscDiary) diff --git a/addons/markers/functions/fnc_mapDrawEH.sqf b/addons/markers/functions/fnc_mapDrawEH.sqf index 5f3c6aed15..3fc04c6c8c 100644 --- a/addons/markers/functions/fnc_mapDrawEH.sqf +++ b/addons/markers/functions/fnc_mapDrawEH.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Draws the current temp marker. Allows rotation. + * Draws the current temp marker. Allows rotation and scale. * * Arguments: * 0: TheMap @@ -25,8 +25,8 @@ if (GVAR(currentMarkerConfigName) == "" || {GVAR(currentMarkerColorConfigName) = ERROR("Bad Data"); }; -private _sizeX = 1; -private _sizeY = 1; +private _sizeX = GVAR(currentMarkerScale); +private _sizeY = GVAR(currentMarkerScale); private _textureConfig = configFile >> "CfgMarkers" >> GVAR(currentMarkerConfigName); private _texture = getText (_textureConfig >> "icon"); diff --git a/addons/markers/functions/fnc_movePFH.sqf b/addons/markers/functions/fnc_movePFH.sqf index 962f39d328..4fd1bf5b49 100644 --- a/addons/markers/functions/fnc_movePFH.sqf +++ b/addons/markers/functions/fnc_movePFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: chris579 * When the marker is being moved. diff --git a/addons/markers/functions/fnc_onButtonClickConfirm.sqf b/addons/markers/functions/fnc_onButtonClickConfirm.sqf new file mode 100644 index 0000000000..622a306e38 --- /dev/null +++ b/addons/markers/functions/fnc_onButtonClickConfirm.sqf @@ -0,0 +1,113 @@ +#include "..\script_component.hpp" +/* + * Author: Freddo, Daniël H., johnb43 + * When the confirm button is pressed. + * + * Arguments: + * 0: Confirm button + * + * Return Value: + * None + * + * Example: + * [_buttonOk] call ACE_markers_fnc_onButtonClickConfirm + * + * Public: No + */ + +params ["_buttonOk"]; + +private _display = ctrlParent _buttonOk; +private _description = _display displayCtrl IDC_INSERT_MARKER; +private _aceTimestamp = _display displayCtrl IDC_ACE_INSERT_MARKER_TIMESTAMP; + +// Handle timestamp +if (cbChecked _aceTimestamp && {ACE_player call FUNC(canTimestamp)}) then { + // Determine marker timestamp based on time settings + private _time = switch (GVAR(timestampTimezone)) do { + case 1: { + systemTime select [3] + }; + case 2: { + systemTimeUTC params ["", "", "", "_hour", "_min", "_sec", "_msec"]; + + private _hourOffset = round GVAR(timestampUTCOffset); + _hour = _hour + _hourOffset; + + // Add or subtract minutes offset based on the negative or positive timezone + if (GVAR(timestampUTCMinutesOffset) != 0) then { + _min = if (_hourOffset < 0) then { _min - GVAR(timestampUTCMinutesOffset) } else { _min + GVAR(timestampUTCMinutesOffset) }; + + // Add/remove extra hours from minutes + _hour = _hour + floor (_min / 60); + _min = (_min % 60 + 60) % 60; // ensure that minutes are between 0 and 59 (included) + }; + + [(_hour % 24 + 24) % 24, _min, _sec, _msec] // ensure that hours are between 0 and 23 (included) + }; + default { + private _daytime = dayTime; + + private _hour = floor _daytime; + private _min = floor ((_daytime - _hour) * 60); + private _sec = floor ((((_daytime - _hour) * 60) - _min) * 60); + private _msec = floor ((((((_daytime - _hour) * 60) - _min) * 60) - _sec) * 1000); + + [_hour, _min, _sec, _msec] + }; + }; + + _time params ["_hour", "_min", "_sec", "_msec"]; + + // Add timestamp suffix + private _periodPostfix = ""; + + if (GVAR(timestampHourFormat) == 12) then { + if (_hour == 0) exitWith { + _hour = _hour + 12; + _periodPostfix = " am"; + }; + + if (_hour == 12) exitWith { + _periodPostfix = " pm"; + }; + + if (_hour < 12) then { + _periodPostfix = " am"; + } else { + _hour = _hour - 12; + _periodPostfix = " pm"; + }; + }; + + private _format = switch (GVAR(timestampFormat)) do { + case "HH": {"%1"}; + case "HH:MM": {"%1:%2"}; + case "HH:MM:SS": {"%1:%2:%3"}; + case "HH:MM:SS:MM": { // milliseconds are displayed as 0 to 59 + _msec = [_msec * 60 / 1000, 2] call CBA_fnc_formatNumber; + + "%1:%2:%3:%4" + }; + case "HH:MM:SS.mmm": { // milliseconds are displayed as 0 to 999 + _msec = [_msec, 3] call CBA_fnc_formatNumber; + + "%1:%2:%3.%4" + }; + }; + + _time = format [ + _format, + [_hour, 2] call CBA_fnc_formatNumber, + [_min, 2] call CBA_fnc_formatNumber, + [_sec, 2] call CBA_fnc_formatNumber, + _msec + ]; + + _description ctrlSetText format [ + "%1 [%2%3]", + ctrlText _description, + _time, + _periodPostfix + ]; +}; diff --git a/addons/markers/functions/fnc_onCheckedChangedTimestamp.sqf b/addons/markers/functions/fnc_onCheckedChangedTimestamp.sqf new file mode 100644 index 0000000000..5c452b6cad --- /dev/null +++ b/addons/markers/functions/fnc_onCheckedChangedTimestamp.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Freddo, commy2 + * When the timestamp checkbox is toggled. + * + * Arguments: + * 0: Checkbox + * 1: Value + * + * Return Value: + * None + * + * Example: + * [controlNull, 1] call ACE_markers_fnc_onCheckedChangedTimestamp; + * + * Public: No + */ +params ["", "_checked"]; + +uiNamespace setVariable [QGVAR(timestampChecked), _checked == 1] diff --git a/addons/markers/functions/fnc_onLBSelChangedChannel.sqf b/addons/markers/functions/fnc_onLBSelChangedChannel.sqf index 954e90470c..e7b696270f 100644 --- a/addons/markers/functions/fnc_onLBSelChangedChannel.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedChannel.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, LinkIsGrim, Avokadomos * When the channel list box is changed. * * Arguments: @@ -19,6 +19,4 @@ params ["_ctrl", "_index"]; TRACE_2("params",_ctrl,_index); -private _channelName = _ctrl lbText _index; - -setCurrentChannel (CHANNEL_NAMES find _channelName); +setCurrentChannel (parseNumber (_ctrl lbData _index)); diff --git a/addons/markers/functions/fnc_onLBSelChangedColor.sqf b/addons/markers/functions/fnc_onLBSelChangedColor.sqf index a141f7e72d..20bae84915 100644 --- a/addons/markers/functions/fnc_onLBSelChangedColor.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedColor.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * When the color list box is changed. @@ -29,10 +29,10 @@ GVAR(currentMarkerColorConfigName) = configName _config; //Set map display to same color: private _bisColorLB = switch (false) do { - case (isNull findDisplay 12): {(findDisplay 12) displayCtrl 1090}; - case (isNull findDisplay 52): {(findDisplay 52) displayCtrl 1090}; - case (isNull findDisplay 53): {(findDisplay 53) displayCtrl 1090}; - case (isNull findDisplay 37): {(findDisplay 37) displayCtrl 1090}; + case (isNull findDisplay 12): {(findDisplay 12) displayCtrl IDC_DIARY_MARKER_COLOR}; + case (isNull findDisplay 52): {(findDisplay 52) displayCtrl IDC_DIARY_MARKER_COLOR}; + case (isNull findDisplay 53): {(findDisplay 53) displayCtrl IDC_DIARY_MARKER_COLOR}; + case (isNull findDisplay 37): {(findDisplay 37) displayCtrl IDC_DIARY_MARKER_COLOR}; default {controlNull}; }; if (_ctrl != _bisColorLB) then { //Don't set what we got a EH from diff --git a/addons/markers/functions/fnc_onLBSelChangedShape.sqf b/addons/markers/functions/fnc_onLBSelChangedShape.sqf index 52a85e5c8d..62e9ca6e52 100644 --- a/addons/markers/functions/fnc_onLBSelChangedShape.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedShape.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * When the shape list box is changed. @@ -29,10 +29,10 @@ GVAR(currentMarkerConfigName) = configName _config; //Set map display to same shape: private _bisShapeLB = switch (false) do { - case (isNull findDisplay 12): {(findDisplay 12) displayCtrl 1091}; - case (isNull findDisplay 52): {(findDisplay 52) displayCtrl 1091}; - case (isNull findDisplay 53): {(findDisplay 53) displayCtrl 1091}; - case (isNull findDisplay 37): {(findDisplay 37) displayCtrl 1091}; + case (isNull findDisplay 12): {(findDisplay 12) displayCtrl IDC_DIARY_MARKER_ICON}; + case (isNull findDisplay 52): {(findDisplay 52) displayCtrl IDC_DIARY_MARKER_ICON}; + case (isNull findDisplay 53): {(findDisplay 53) displayCtrl IDC_DIARY_MARKER_ICON}; + case (isNull findDisplay 37): {(findDisplay 37) displayCtrl IDC_DIARY_MARKER_ICON}; default {controlNull}; }; if (_ctrl != _bisShapeLB) then { //Don't set what we got a EH from diff --git a/addons/markers/functions/fnc_onMouseButtonDown.sqf b/addons/markers/functions/fnc_onMouseButtonDown.sqf index ce6f99ee00..f0130c7c9d 100644 --- a/addons/markers/functions/fnc_onMouseButtonDown.sqf +++ b/addons/markers/functions/fnc_onMouseButtonDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: chris579 * Triggered when a mouse button is pressed on the map. @@ -23,7 +23,7 @@ params ["_ctrlMap", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; -if (_button != 0 || {!([_shift, _ctrl, _alt] isEqualTo [false, false, true])}) exitWith {}; +if (_button != 0 || {[_shift, _ctrl, _alt] isNotEqualTo [false, false, true]}) exitWith {}; ctrlMapMouseOver _ctrlMap params [["_type", ""], "_marker"]; @@ -37,5 +37,5 @@ if (_type == "marker" && {_marker find "_USER_DEFINED" != -1 && {_marker call FU GVAR(moving) = true; _marker setMarkerAlphaLocal 0.5; - [FUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/markers/functions/fnc_onMouseButtonUp.sqf b/addons/markers/functions/fnc_onMouseButtonUp.sqf index ffe0ed000f..8c1c1ff7fe 100644 --- a/addons/markers/functions/fnc_onMouseButtonUp.sqf +++ b/addons/markers/functions/fnc_onMouseButtonUp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: chris579 * Triggered when a mouse button is released on the map. diff --git a/addons/markers/functions/fnc_onSliderMouseButtonUpAngle.sqf b/addons/markers/functions/fnc_onSliderMouseButtonUpAngle.sqf new file mode 100644 index 0000000000..f5b485e851 --- /dev/null +++ b/addons/markers/functions/fnc_onSliderMouseButtonUpAngle.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: 10Dozen + * Angle slider clicked handler. Resets slider pos to 0 on RMB button up. + * + * Arguments: + * 0: Slider (idc 1210) is expected + * 1: Button released (0 - Left mouse btn, 1 - Right mouse btn) + * + * Return Value: + * None + * + * Example: + * [Slider, 1] call ace_markers_fnc_onSliderMouseButtonUpAngle + * + * Public: No + */ + +params ["_aceAngleSlider", "_button"]; +TRACE_2("params",_aceAngleSlider,_button); + +if (_button isNotEqualTo 1) exitWith {}; + +_aceAngleSlider sliderSetPosition 0; +[_aceAngleSlider, 0] call FUNC(onSliderPosChangedAngle); diff --git a/addons/markers/functions/fnc_onSliderMouseButtonUpScale.sqf b/addons/markers/functions/fnc_onSliderMouseButtonUpScale.sqf new file mode 100644 index 0000000000..e8f1cec429 --- /dev/null +++ b/addons/markers/functions/fnc_onSliderMouseButtonUpScale.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: 10Dozen + * Scale slider clicked handler. Resets slider pos to 1 on RMB button up. + * + * Arguments: + * 0: Slider (idc 1420) is expected + * 1: Button released (0 - Left mouse btn, 1 - Right mouse btn) + * + * Return Value: + * None + * + * Example: + * [Slider, 1] call ace_markers_fnc_onSliderMouseButtonUpScale + * + * Public: No + */ + +params ["_aceScaleSlider", "_button"]; +TRACE_2("params",_aceScaleSlider,_button); + +if (_button isNotEqualTo 1) exitWith {}; + +_aceScaleSlider sliderSetPosition 1; +[_aceScaleSlider, 1] call FUNC(onSliderPosChangedScale); diff --git a/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf b/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf index c334d0a8f0..76257b5572 100644 --- a/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf +++ b/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Angle Slider Pos changed @@ -25,6 +25,6 @@ if (_direction < 0) then { _direction = _direction + 360; }; -((ctrlParent _ctrl) displayCtrl 1221) ctrlSetText format [localize LSTRING(MarkerDirection), _direction]; +((ctrlParent _ctrl) displayCtrl IDC_ACE_INSERT_MARKER_ANGLE_TEXT) ctrlSetText format [localize LSTRING(MarkerDirection), _direction]; GVAR(currentMarkerAngle) = _data; diff --git a/addons/markers/functions/fnc_onSliderPosChangedScale.sqf b/addons/markers/functions/fnc_onSliderPosChangedScale.sqf new file mode 100755 index 0000000000..607bbb41cc --- /dev/null +++ b/addons/markers/functions/fnc_onSliderPosChangedScale.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: frankplow + * Applies scale from on slider position change. + * + * Arguments: + * 0: Slider (idc 1420) + * 1: Slider Data (scale: 0.5...2.0) + * + * Return Value: + * None + * + * Example: + * [slider, 1.5] call ace_markers_fnc_onSliderPosChangedScale + * + * Public: No + */ + +params ["_ctrl", "_data"]; +TRACE_2("params",_ctrl,_data); + +private _scale = _data * 100; +_scale = round _scale; +_scale = _scale / 100; + +((ctrlParent _ctrl) displayCtrl IDC_ACE_INSERT_MARKER_SCALE_TEXT) ctrlSetText format [localize LSTRING(MarkerScale), _scale]; + +GVAR(currentMarkerScale) = _data; diff --git a/addons/markers/functions/fnc_placeMarker.sqf b/addons/markers/functions/fnc_placeMarker.sqf index a1b136aad5..fdd758be5e 100644 --- a/addons/markers/functions/fnc_placeMarker.sqf +++ b/addons/markers/functions/fnc_placeMarker.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Timi007 * MarkerPlacement closed @@ -19,7 +19,7 @@ params ["_display", "_closeNum"]; TRACE_2("params",_display,_closeNum); -private _editingMarker = !(GVAR(editingMarker) isEqualTo ""); +private _editingMarker = (GVAR(editingMarker) isNotEqualTo ""); if (_closeNum isEqualTo 1) then { if (_editingMarker) then { @@ -48,17 +48,18 @@ if (_closeNum isEqualTo 1) then { // provide hook for external scripts [QGVAR(markerPlaced),[_newestMarker, _editingMarker]] call CBA_fnc_localEvent; - + // Add to list of user placed markers, and then filter for deleted GVAR(userPlacedMarkers) pushBack _newestMarker; - GVAR(userPlacedMarkers) = GVAR(userPlacedMarkers) select {!((getMarkerPos _x) isEqualTo [0,0,0])}; + GVAR(userPlacedMarkers) = GVAR(userPlacedMarkers) select {(getMarkerPos _x) isNotEqualTo [0,0,0]}; [QGVAR(setMarkerNetwork), [ _newestMarker, [ GETGVAR(currentMarkerConfigName,""), GETGVAR(currentMarkerColorConfigName,""), GETGVAR(currentMarkerPosition,[]), - GETGVAR(currentMarkerAngle,0) + GETGVAR(currentMarkerAngle,0), + GETGVAR(currentMarkerScale,1) ] ]] call CBA_fnc_globalEvent; diff --git a/addons/markers/functions/fnc_removeTimestamp.sqf b/addons/markers/functions/fnc_removeTimestamp.sqf new file mode 100644 index 0000000000..5d2c7c3c1f --- /dev/null +++ b/addons/markers/functions/fnc_removeTimestamp.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: commy2 + * Removes timestamp from end of a string. + * + * Arguments: + * 0: Marker text string + * + * Return Value: + * Input with timestamp removed + * + * Example: + * "abc [12:00 am]" call ace_markers_fnc_removeTimestamp // "abc" + * "[13:37]" call ace_markers_fnc_removeTimestamp // "" + * "xyz [123]" call ace_markers_fnc_removeTimestamp // "xyz [123]" + * "xyz [12]" call ace_markers_fnc_removeTimestamp // "xyz" + * "xyz [12 pm]" call ace_markers_fnc_removeTimestamp // "xyz" + * + * Public: No + */ +#define DIGITS "0123456789" + +params ["_original"]; + +// @todo, 2.02 reverse command will support STRING types +private _string = toArray _original; +reverse _string; +_string = toString _string; + +if (_string select [0, 1] != "]") exitWith {_original}; + +private _timestampLength = (_string find "[") + 1; +_string = _string select [0, _timestampLength]; + +// @todo +_string = toArray _string; +reverse _string; +_string = toString _string; + +if (_string select [0, 1] != "[") exitWith {_original}; + +private _index = 1; +private _keepCheckingDigits = true; +private _validTimestamp = true; +while {_keepCheckingDigits} do { + if !(_string select [_index, 1] in DIGITS) exitWith { _validTimestamp = false; }; + if !(_string select [_index+1, 1] in DIGITS) exitWith { _validTimestamp = false; }; + switch (_string select [_index+2, 1]) do { + case (":"): { + _index = _index + 3; + }; + case ("]"): { + _keepCheckingDigits = false; + }; + case (" "): { + _keepCheckingDigits = false; + if !(_string select [_index+3, 3] in ["am]", "pm]"]) then {_validTimestamp = false; }; + }; + default { + _keepCheckingDigits = false; + _validTimestamp = false; + }; + }; +}; + +if (_validTimestamp) then { + [_original select [0, count _original - _timestampLength], " "] call CBA_fnc_rightTrim // return +} else { + _original // return +} diff --git a/addons/markers/functions/fnc_sendMarkersJIP.sqf b/addons/markers/functions/fnc_sendMarkersJIP.sqf index 08b36181b1..99ddb4b3c4 100644 --- a/addons/markers/functions/fnc_sendMarkersJIP.sqf +++ b/addons/markers/functions/fnc_sendMarkersJIP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Server: Recives a dummy logic, sends marker data back to the owner. @@ -10,7 +10,7 @@ * None * * Example: - * [onUnloadEvent] call ace_markers_fnc_sendMarkerJIP; + * [onUnloadEvent] call ace_markers_fnc_sendMarkersJIP; * * Public: No */ diff --git a/addons/markers/functions/fnc_setMarkerJIP.sqf b/addons/markers/functions/fnc_setMarkerJIP.sqf index 9c9aea9fd7..12dfe5de77 100644 --- a/addons/markers/functions/fnc_setMarkerJIP.sqf +++ b/addons/markers/functions/fnc_setMarkerJIP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Client: Recives a marker data from server. @@ -25,7 +25,7 @@ TRACE_2("params",_allMapMarkers,_allMapMarkersProperties); if (_index != -1) then { private _data = _allMapMarkersProperties select _index; - _data params ["_markerClassname", "_colorClassname", "_pos", "_dir"]; + _data params ["_markerClassname", "_colorClassname", "_pos", "_dir", "_scale"]; private _config = (configfile >> "CfgMarkers") >> _markerClassname; @@ -47,6 +47,6 @@ TRACE_2("params",_allMapMarkers,_allMapMarkersProperties); _x setMarkerPosLocal _pos; _x setMarkerDirLocal _dir; + _x setMarkerSizeLocal [_scale, _scale]; }; - false -} count allMapMarkers; +} forEach allMapMarkers; diff --git a/addons/markers/functions/fnc_setMarkerNetwork.sqf b/addons/markers/functions/fnc_setMarkerNetwork.sqf index b59338e7d2..7d0cc0e827 100644 --- a/addons/markers/functions/fnc_setMarkerNetwork.sqf +++ b/addons/markers/functions/fnc_setMarkerNetwork.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Sets newly placed marker @@ -12,14 +12,14 @@ * None * * Example: - * [[],[],dummyLogic] call ace_markers_fnc_setMarkerJIP; + * [[],[],dummyLogic] call ace_markers_fnc_setMarkerNetwork; * * Public: No */ params ["_marker", "_data"]; TRACE_2("params",_marker,_data); -_data params ["_markerClassname", "_colorClassname", "_pos", "_dir"]; +_data params ["_markerClassname", "_colorClassname", "_pos", "_dir", "_scale"]; private _config = configfile >> "CfgMarkers" >> _markerClassname; @@ -41,6 +41,7 @@ _marker setMarkerColorLocal configName _config; _marker setMarkerPosLocal _pos; _marker setMarkerDirLocal _dir; +_marker setMarkerSizeLocal [_scale, _scale]; // save properties on server machine for JIP, marker editing ready if (isMultiplayer && {isServer}) then { diff --git a/addons/markers/functions/script_component.hpp b/addons/markers/functions/script_component.hpp deleted file mode 100644 index 26adba2431..0000000000 --- a/addons/markers/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\markers\script_component.hpp" diff --git a/addons/markers/initSettings.inc.sqf b/addons/markers/initSettings.inc.sqf new file mode 100644 index 0000000000..65bf17e8b6 --- /dev/null +++ b/addons/markers/initSettings.inc.sqf @@ -0,0 +1,95 @@ +private _categoryName = format ["ACE %1", localize ELSTRING(map,Module_DisplayName)]; + +[ + QGVAR(moveRestriction), "LIST", + [LSTRING(MoveRestriction), LSTRING(MoveRestriction_Description)], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + [ + MOVE_RESTRICTION_NOBODY, + MOVE_RESTRICTION_ALL, + MOVE_RESTRICTION_ADMINS, + MOVE_RESTRICTION_GROUP_LEADERS, + MOVE_RESTRICTION_GROUP_LEADERS_ADMINS, + MOVE_RESTRICTION_OWNER + ], + [ + LSTRING(MoveRestriction_Nobody), + LSTRING(MoveRestriction_All), + LSTRING(MoveRestriction_Admins), + LSTRING(MoveRestriction_GroupLeaders), + LSTRING(MoveRestriction_GroupLeadersAndAdmins), + LSTRING(MoveRestriction_Owner) + ], + 1 + ] +] call CBA_fnc_addSetting; + +[ + QGVAR(timestampEnabled), "CHECKBOX", + [LSTRING(TimestampEnabled), LSTRING(TimestampEnabledDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(timestampTimezone), "LIST", + [LSTRING(TimestampTimezone), LSTRING(TimestampTimezoneDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + [0, 1, 2], + [LSTRING(TimestampTimezoneIngameTime), LSTRING(TimestampTimezoneSystemTime), LSTRING(TimestampTimezoneUTCTime)], + 0 + ], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(timestampUTCOffset), "SLIDER", + [LSTRING(TimestampUTCOffset), LSTRING(TimestampUTCOffsetDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [-12, 14, 0, 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(TimestampUTCMinutesOffset), "LIST", + [LSTRING(TimestampUTCMinutesOffset), LSTRING(TimestampUTCMinutesOffsetDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + [0, 15, 30, 45], + [0, 15, 30, 45], + 0 + ] +] call CBA_fnc_addSetting; + +[ + QGVAR(timestampHourFormat), "LIST", + [LSTRING(TimestampHourFormat), LSTRING(TimestampHourFormatDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + [24, 12], + [LSTRING(TimestampHourFormat24), LSTRING(TimestampHourFormat12)], + 0 + ] +] call CBA_fnc_addSetting; + +private _formatDescription = [ + LLSTRING(TimestampFormatDescription0), + LLSTRING(TimestampFormatDescription1), + LLSTRING(TimestampFormatDescription2), + LLSTRING(TimestampFormatDescription3), + LLSTRING(TimestampFormatDescription4), + LLSTRING(TimestampFormatDescription5) +] joinString endl; + +[ + QGVAR(timestampFormat), "LIST", + [LSTRING(timestampFormat), _formatDescription], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + ["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM", "HH:MM:SS.mmm"], + ["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM", "HH:MM:SS.mmm"], + 1 + ] +] call CBA_fnc_addSetting; diff --git a/addons/markers/initSettings.sqf b/addons/markers/initSettings.sqf deleted file mode 100644 index e4aa16b00f..0000000000 --- a/addons/markers/initSettings.sqf +++ /dev/null @@ -1,24 +0,0 @@ -[ - QGVAR(moveRestriction), "LIST", - [LSTRING(MoveRestriction), LSTRING(MoveRestriction_Description)], - [format ["ACE %1", localize ELSTRING(map,Module_DisplayName)], localize LSTRING(Module_DisplayName)], - [ - [ - MOVE_RESTRICTION_NOBODY, - MOVE_RESTRICTION_ALL, - MOVE_RESTRICTION_ADMINS, - MOVE_RESTRICTION_GROUP_LEADERS, - MOVE_RESTRICTION_GROUP_LEADERS_ADMINS, - MOVE_RESTRICTION_OWNER - ], - [ - LSTRING(MoveRestriction_Nobody), - LSTRING(MoveRestriction_All), - LSTRING(MoveRestriction_Admins), - LSTRING(MoveRestriction_GroupLeaders), - LSTRING(MoveRestriction_GroupLeadersAndAdmins), - LSTRING(MoveRestriction_Owner) - ], - 1 - ] -] call cba_settings_fnc_init; diff --git a/addons/markers/script_component.hpp b/addons/markers/script_component.hpp index 8b268e2d03..8da334153d 100644 --- a/addons/markers/script_component.hpp +++ b/addons/markers/script_component.hpp @@ -15,6 +15,7 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" #define CHANNEL_NAMES [ \ localize "str_channel_global", \ @@ -30,3 +31,12 @@ #define MOVE_RESTRICTION_GROUP_LEADERS 2 #define MOVE_RESTRICTION_GROUP_LEADERS_ADMINS 3 #define MOVE_RESTRICTION_OWNER 4 + +#define IDC_ACE_INSERT_MARKER_TIMESTAMP 1210 +#define IDC_ACE_INSERT_MARKER_TIMESTAMP_TEXT 1211 +#define IDC_ACE_INSERT_MARKER_SHAPE 1220 +#define IDC_ACE_INSERT_MARKER_COLOR 1221 +#define IDC_ACE_INSERT_MARKER_ANGLE 1230 +#define IDC_ACE_INSERT_MARKER_ANGLE_TEXT 1231 +#define IDC_ACE_INSERT_MARKER_SCALE 1240 +#define IDC_ACE_INSERT_MARKER_SCALE_TEXT 1241 diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index ddb2267645..2c9dc1531b 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -1,6 +1,19 @@ + + Scale: %1 + Escala: %1 + Échelle : %1 + Масштаб: %1 + 大きさ: %1 + Skala: %1 + Skalierung: %1 + Scala: %1 + 规模:%1° + 크기: %1 + Escala: %1 + Direction: %1° Drehung: %1° @@ -12,10 +25,24 @@ Irány: %1° Direzione: %1° Direção %1 - 方位: %1° + 方向: %1° 방위: %1° - 方位: %1° + 方位:%1° 方位: %1° + Yön: %1° + + + Click RMB to reset + Нажми ПКМ чтобы сбросить + Clic droit pour réinitialiser + 右クリックでリセット + Naciśnij PPM żeby zresetować + Rechte Maustaste zum Zurücksetzen + Tasto Destro per ripristinare + 点击鼠标右键重置 + 오른쪽 클릭으로 재설정 + Click botón derecho para restaurar + Clique com o botão direito para redefinir Markers @@ -23,32 +50,46 @@ マーカー Marcatori 標誌 - 标志 - 맵마커 + 标识 + 지도 마커 Znaczniki Маркеры + Marcadores + Marqueurs + Značky + Işaretleyiciler + Marcadores Allow moving markers for Erlaube Marker zu bewegen für - 次ユーザーにマーカー移動を許可 + マーカー移動を許可する対象 마커 이동 허가 誰可以移動標誌 - 谁可以移动标志 + 谁可以移动标识 Permetti di spostare i marcatori a: Zezwól na poruszanie znaczników dla Разрешить перемещение маркеров для + Permitir que movam marcadores + Permettre le déplacement des marqueurs pour + Povolit pohyb se značkami pro + Permitir marcadores en movimiento para Restricts which players are able to move markers while holding the Alt key. Beschränkt welche Spieler Marker mit gedrückter Alt-Taste bewegen können. - どのプレイヤーが Alt キーを押しながらマーカー移動をさせられるか制限できます。 - Alt 키를 누른 상태에서 마커를 움직일 수있는 플레이어를 제한합니다. + Altキーを押しながらマーカー移動をできるプレイヤーを制限します。 + Alt 키를 누른 상태에서 마커를 움직일 수 있는 플레이어를 제한합니다. 設定誰可以透過按住Alt鍵來移動標誌 - 设定谁可以透过按住Alt键来移动标志。 - Limita quali giocatori possono spostare i marcatori mentre premono il tasto Alt. + 设定谁可以透过按住 Alt 键来移动标识。 + Limita quali giocatori possono spostare i marcatori premendo il tasto Alt. Ogranicz którzy gracze mogą poruszać znacznikami podczas trzymania przycisku Alt. Устанавливает ограничение на перемещения маркеров игроками при помощи клавиши Alt + Restringe quais jogadores podem mover os marcadores do mapa enquanto seguram a tecla ALT. + Définit quels joueurs peuvent déplacer des marqueurs en maintenant la touche Alt enfoncée. + Omezuje kdo může pohybovat se značkami při podržení klávesy Alt. + Alt tuşunu basılı tutarken hangi işaretçilerin hareket edebileceğini sınırlar. + Reestringir qué jugadores son capaces de mover los marcadores manteniendo pulsada la tecla Alt. Nobody @@ -60,6 +101,11 @@ Nessuno Nikt Никого + Ninguém + Personne + Nikdo + Hiçkimse + Ninguno All players @@ -71,6 +117,11 @@ 모든 플레이어 Wszyscy gracze Всех игроков + Todos jogadores + Tous les joueurs + Všichni hráči + Bütün Oyuncular + Todos los jugadores Admins @@ -82,6 +133,11 @@ 관리자 Administratorzy Админов + Administradores + Admins + Administrátoři + Adminler + Admins Group leaders @@ -93,6 +149,11 @@ 분대장 Przywódcy grup Лидеров групп + Líderes de grupo + Chefs de groupe + Velitelé jednotek + Grup Liderleri + Líderes de grupo Group leaders and Admins @@ -104,6 +165,11 @@ 분대장과 관리자 Przywódcy grup i Administratorzy Лидеров групп и Админов + Líderes de grupo e Administradores + Chefs de groupe et Admins + Velitelé jednotek a Administrátoři + Grup Liderleri Ve Adminler + Líderes de grupo y administradores Creator @@ -111,6 +177,314 @@ 設置者 Twórca Создателя + Criador + 放置者 + 放置者 + Créateur + Creatore + Tvůrce + Yaratıcı + Creador + 제작자 + + + Allow Timestamps + Вкл. отображение времени на метках + Permettre l'horodatage + タイムスタンプの許可 + Permitir marcas de tiempo + Zezwól na znaczniki czasu + Erlaube Zeitstempel + Permetti marca temporale + 允许时间戳 + 시간 표기 허용 + Permitir Marcação de Tempo + + + Whether to allow timestamps to be automatically applied to markers + Автоматическое отображение времени, когда поставлена метка + Active une interface permettant d'apposer un horodatage sur les marqueurs. + タイムスタンプをマーカーに自動的に適用することを許可するかどうか + Permitir que las marcas de tiempo sean automáticamente aplicadas a los marcadores + Zezwól na automatyczne stosowanie znaczników czasu do markerów + Ob Zeitstempel automatisch auf Maker angewendet werden sollen. + Se i giocatori possono scegliere di aggiungere in automatico un marco temporale ai propri marcatori. + 是否允许时间戳自动应用于标记 + 허용 시 마커를 내려놓음과 동시에 시간이 표기됩니다 + Permite que marcações de tempo sejam automaticamente aplicadas aos marcadores + + + Timestamp + Время постановки метки + Horodatage + タイムスタンプ + Marca de tiempo + Znacznik czasu + Zeitstempel + Marca temporale + 时间戳 + 시간 표기 + Marcação de Tempo + + + Watch Required + Необходимы часы + Une montre est requise. + 時計が必要 + Reloj requerido + Wymagany zegarek + Uhr benötigt + Necessario orologio + 需要手表 + 시계 필요함 + Relógio necessário + + + Time Zone + Часовой пояс + Fuseau horaire + タイムゾーン + Zona horaria + Strefa czasowa + Zeitzone + Fuso orario + 时区 + 시간대 + + + Changes the time zone for the timestamp + Измените часовой пояс для метки времени + Modifiez le fuseau horaire pour l'horodatage + タイムスタンプのタイムゾーンを変更します + Cambie la zona horaria para la marca de tiempo + Zmień strefę czasową dla znaczników czasu + Ändern Sie die Zeitzone für den Zeitstempel + Modifica il fuso orario per la marca temporale + 更改时间戳的时区 + 타임스탬프의 시간대를 변경하십시오 + + + In-game Time + Время в игре + Heure de jeu + ゲーム内時間 + Hora del juego + Czas gry + Ingame-Zeit + Ora del gioco + 游戏内时间 + 게임 시간 + + + System Time + Системное время + Heure système + システム時間 + Hora del sistema + Czas systemowy + Systemzeit + Ora del sistema + 系统时间 + 시스템 시간 + + + UTC Time + Время UTC + Heure UTC + UTC時間 + Hora UTC + Czas UTC + UTC-Zeit + Tempo-UTC + UTC时间 + UTC 시간 + + + UTC Offset + Смещение UTC + Décalage UTC + UTCオフセット + Desplazamiento UTC + Przesunięcie UTC + UTC-Verschiebung + Deviazione-UTC + UTC偏移量 + UTC 오프셋 + + + Changes the time offset for the UTC timestamp + Измените смещение времени для метки времени UTC + Modifier le décalage horaire pour l'horodatage UTC + UTCタイムスタンプの時オフセットを変更します + Cambiar el desplazamiento horario para la marca de tiempo UTC + Zmień przesunięcie czasu dla sygnatury czasowej UTC + Ändere die Zeitverschiebung für den UTC-Zeitstempel + Modifica la deviazione della marca temporale UTC. + 更改UTC时间戳的时间偏移量 + UTC 타임 스탬프의 시간 오프셋을 변경하십시오 + + + UTC Minutes Offset + UTC Минутное смещение + Décalage des minutes UTC + UTC分オフセット + Desplazamiento de minutos UTC + Przesunięcie minut UTC + UTC-Minutenversatz + Deviazione Minuti UTC + UTC分钟偏移量 + UTC 분 오프셋 + + + Change the minute offset for the UTC timestamp + Изменить минутное смещение для времени UTC + Modifier le décalage des minutes pour l'horodatage UTC + UTCタイムスタンプの分オフセットを変更します + Cambiar el desplazamiento de minutos para la marca de tiempo UTC + Zmień przesunięcie minut dla sygnatury czasowej UTC + Ändere den Minutenversatz für den UTC-Zeitstempel + Modifica la deviazione dei minuti della marca temporale UTC. + 更改UTC时间戳的分钟偏移量 + UTC 타임 스탬프의 분 오프셋을 변경하십시오 + + + Timestamp Format + Формат времени + Horodatage - Format + タイムスタンプの形式 + Formato de marca de tiempo + Format znacznika czasu + Format des Zeitstempels + Formato della marca temporale + 时间戳格式 + 시간 표기 포맷 + Formato da Marcação de Tempo + + + Changes the timestamp format + Изменение формата времени + Modifie le format de l'horodatage. + タイムスタンプの形式を変更します + Cambia el formato de marca de tiempo + Zmienia format znacznika czasu + Zeitstempel-Format anpassen + Modifica il formato dell'ora nella marca temporale + 更改时间戳格式 + 시간 표기 포맷을 바꿉니다 + Altera a formatação da marcação de tempo + + + "HH" - Hour + "ЧЧ" - Час + "HH" - Heures + "HH" - 時 + "HH" - Hora + "HH" - Godziny + "HH" - Stunden + "HH" - Ore + "HH"—时 + "HH" - 시 + HH - Horas + + + "MM" - Minute + "ММ" - Минута + "MM" - Minutes + "MM" - 分 + "MM" - Minuto + "MM" - Minuty + "MM" - Minuten + "MM" - Minuti + "MM"—分 + "MM" - 분 + MM - Minutos + + + "SS" - Seconds + "СС" - Секунда + "SS" - Secondes + "SS" - 秒 + "SS" - Segundos + "SS" - Sekundy + "SS" - Sekunden + "SS" - Secondi + "SS"—秒 + "SS" - 초 + SS - Segundos + + + "MM" - Milliseconds (from 0 to 59) + "MM" - Millisecondes (de 0 à 59) + "MS" - Milisekunden (von 0 bis 59) + "MS" - Millisecondi (da 0 a 59) + "MS" - Milissegundos (de 0 a 59) + "MS" - 밀리초 (0부터 59까지) + "MM" - ミリ秒 (0から59) + "ММ" - миллисекунды (от 0 до 59) + "MM" - Milisegundos (de 0 a 59) + + + "mmm" - Milliseconds (from 0 to 999) + "mmm" - Millisecondes (de 0 à 999) + "mmm" - Milisekunden (von 0 bis 999) + "mmm" - Millisecondi (da 0 a 999) + "mmm" - Milissegundos (de 0 a 999) + "mmm" - 밀리초 (0부터 999까지) + "mmm" - ミリ秒 (0から599) + "ммм" - миллисекунды (от 0 до 999) + "mmm" - Milisegundos (de 0 a 999) + + + Timestamp Hour Format + Часовой формат времени + Horodatage - Système horaire + タイムスタンプ時刻形式 + Formato de hora de marca de tiempo + Format Godzinnych znaczników czasu + Zeitstempel-Stundenformat + Formato ore delle marche temporali + 时间戳小时格式 + 시간 표기 시간 포맷 + Sistema Horário das Marcações de Tempo + + + 24-Hour Clock + 24 часовой формат + Format 24 heures + 24時間表記 + Reloj 24-Horas + Zegar 24-godzinny + 24-Stunden + 24-Ore + 24小时制 + 24시간제 + 24 Horas + + + 12-Hour Clock + 12 часовой формат + Format 12 heures + 12時間表記 + Reloj 12-Horas + Zegar 12-godzinny + 12-Stunden + 12-Ore + 12小时制 + 12시간제 + 12 Horas + + + Changes timestamp to use either 24-hour or 12-hour clock format + Изменяет формат времени на маркере на 24 часовой, либо 12 часовой + Permet de choisir le système d'horodatage souhaité, au format 12 ou 24 heures. + タイムスタンプの時刻を24時間表記か12時間表記かのどちらかに変更します + Cambia que la marca de tiempo sea en formato de reloj 24-horas o 12-horas + Zmienia znacznik czasu tak, aby używał formatu 24-godzinnego lub 12-godzinnego + Ändert den Zeitstempel, um entweder das 24-Stunden- oder das 12-Stunden-Format zu verwenden + Determina se le marche temporali sui marcatori saranno in formato 24-Ore o 12-Ore. + 改变时间戳以使用24小时或12小时的时钟格式 + 시간 표기를 24시간제 혹은 12시간제 에서 골라 표기합니다 + Altera a marcação de tempo para usar o formato de relógio 24-horas ou 12-horas diff --git a/addons/maverick/ACE_GuidanceConfig.hpp b/addons/maverick/ACE_GuidanceConfig.hpp index f6b9020157..948404b7cc 100644 --- a/addons/maverick/ACE_GuidanceConfig.hpp +++ b/addons/maverick/ACE_GuidanceConfig.hpp @@ -1,5 +1,5 @@ class EGVAR(missileguidance,AttackProfiles) { - class maverick { + class maverick { name = "LOAL-DIR"; nameLocked = "LOBL-DIR"; functionName = QEFUNC(missileguidance,attackProfile_DIR); diff --git a/addons/maverick/CfgAmmo.hpp b/addons/maverick/CfgAmmo.hpp index 2b48618e82..654c1fbe80 100644 --- a/addons/maverick/CfgAmmo.hpp +++ b/addons/maverick/CfgAmmo.hpp @@ -1,11 +1,11 @@ class CfgAmmo { class MissileCore; - class MissileBase : MissileCore { + class MissileBase: MissileCore { class Components; }; - class Missile_AGM_02_F : MissileBase {}; - - class GVAR(L) : Missile_AGM_02_F { + class Missile_AGM_02_F: MissileBase {}; + + class GVAR(L): Missile_AGM_02_F { author = "xrufix"; autoSeekTarget = 0; irLock = 0; diff --git a/addons/maverick/CfgMagazines.hpp b/addons/maverick/CfgMagazines.hpp index 3254f605c0..705d52010d 100644 --- a/addons/maverick/CfgMagazines.hpp +++ b/addons/maverick/CfgMagazines.hpp @@ -1,19 +1,19 @@ class CfgMagazines { class CA_Magazine; - class VehicleMagazine : CA_Magazine {}; - - class magazine_Missile_AGM_02_x1 : VehicleMagazine {}; - class PylonMissile_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 {}; - class PylonMissile_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 {}; - - class 6Rnd_Missile_AGM_02_F : VehicleMagazine {}; - class PylonRack_1Rnd_Missile_AGM_02_F : 6Rnd_Missile_AGM_02_F {}; - class PylonRack_3Rnd_Missile_AGM_02_F : PylonRack_1Rnd_Missile_AGM_02_F{}; - - class PylonRack_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 {}; - class PylonRack_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 {}; - - class GVAR(L_magazine_x1) : magazine_Missile_AGM_02_x1 { + class VehicleMagazine: CA_Magazine {}; + + class magazine_Missile_AGM_02_x1: VehicleMagazine {}; + class PylonMissile_Missile_AGM_02_x1: magazine_Missile_AGM_02_x1 {}; + class PylonMissile_Missile_AGM_02_x2: magazine_Missile_AGM_02_x1 {}; + + class 6Rnd_Missile_AGM_02_F: VehicleMagazine {}; + class PylonRack_1Rnd_Missile_AGM_02_F: 6Rnd_Missile_AGM_02_F {}; + class PylonRack_3Rnd_Missile_AGM_02_F: PylonRack_1Rnd_Missile_AGM_02_F {}; + + class PylonRack_Missile_AGM_02_x1: magazine_Missile_AGM_02_x1 {}; + class PylonRack_Missile_AGM_02_x2: magazine_Missile_AGM_02_x1 {}; + + class GVAR(L_magazine_x1): magazine_Missile_AGM_02_x1 { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -21,7 +21,7 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); }; - class GVAR(L_pylonmissile_x1) : PylonMissile_Missile_AGM_02_x1 { + class GVAR(L_pylonmissile_x1): PylonMissile_Missile_AGM_02_x1 { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -29,7 +29,7 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); pylonWeapon = QGVAR(L_Launcher); }; - class GVAR(L_pylonmissile_x2) : PylonMissile_Missile_AGM_02_x2 { + class GVAR(L_pylonmissile_x2): PylonMissile_Missile_AGM_02_x2 { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -38,7 +38,7 @@ class CfgMagazines { pylonWeapon = QGVAR(L_Launcher); }; - class GVAR(L_pylonRack_1Rnd) : PylonRack_1Rnd_Missile_AGM_02_F { + class GVAR(L_pylonRack_1Rnd): PylonRack_1Rnd_Missile_AGM_02_F { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -46,7 +46,7 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); pylonWeapon = QGVAR(L_Launcher_Plane); }; - class GVAR(L_PylonRack_3Rnd) : PylonRack_3Rnd_Missile_AGM_02_F { + class GVAR(L_PylonRack_3Rnd): PylonRack_3Rnd_Missile_AGM_02_F { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -54,8 +54,8 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); pylonWeapon = QGVAR(L_Launcher_Plane); }; - - class GVAR(L_PylonRack_x1) : PylonRack_Missile_AGM_02_x1 { + + class GVAR(L_PylonRack_x1): PylonRack_Missile_AGM_02_x1 { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -63,7 +63,7 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); pylonWeapon = QGVAR(L_Launcher); }; - class GVAR(L_PylonRack_x2) : PylonRack_Missile_AGM_02_x2 { + class GVAR(L_PylonRack_x2): PylonRack_Missile_AGM_02_x2 { ammo = QGVAR(L); author = "xrufix"; descriptionShort = CSTRING(L_MAG_DESCR); @@ -74,12 +74,12 @@ class CfgMagazines { // KH-25 class 4Rnd_Missile_AGM_01_F; - class PylonRack_1Rnd_Missile_AGM_01_F : 4Rnd_Missile_AGM_01_F {}; - class magazine_Missile_AGM_KH25_x1 : VehicleMagazine {}; - class PylonMissile_Missile_AGM_KH25_x1 : magazine_Missile_AGM_KH25_x1 {}; - class PylonMissile_Missile_AGM_KH25_INT_x1 : PylonMissile_Missile_AGM_KH25_x1 {}; + class PylonRack_1Rnd_Missile_AGM_01_F: 4Rnd_Missile_AGM_01_F {}; + class magazine_Missile_AGM_KH25_x1: VehicleMagazine {}; + class PylonMissile_Missile_AGM_KH25_x1: magazine_Missile_AGM_KH25_x1 {}; + class PylonMissile_Missile_AGM_KH25_INT_x1: PylonMissile_Missile_AGM_KH25_x1 {}; - class ace_kh25ml_pylonrack_x1 : PylonRack_1Rnd_Missile_AGM_01_F { + class ace_kh25ml_pylonrack_x1: PylonRack_1Rnd_Missile_AGM_01_F { ammo = "ace_kh25ml"; author = "xrufix"; descriptionShort = CSTRING(KH25ML_MAG_DESCR); @@ -87,14 +87,14 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); pylonWeapon = "ace_kh25ml_launcher"; }; - class ace_kh25ml_magazine_x1 : magazine_Missile_AGM_KH25_x1 { + class ace_kh25ml_magazine_x1: magazine_Missile_AGM_KH25_x1 { ammo = "ace_kh25ml"; author = "xrufix"; descriptionShort = CSTRING(KH25ML_MAG_DESCR); displayName = CSTRING(KH25ML_MAG_x1); displayNameShort = CSTRING(L_MAG_short); }; - class ace_kh25ml_pylonmissile_x1 : PylonMissile_Missile_AGM_KH25_x1 { + class ace_kh25ml_pylonmissile_x1: PylonMissile_Missile_AGM_KH25_x1 { ammo = "ace_kh25ml"; author = "xrufix"; descriptionShort = CSTRING(KH25ML_MAG_DESCR); @@ -102,7 +102,7 @@ class CfgMagazines { displayNameShort = CSTRING(L_MAG_short); pylonWeapon = "ace_kh25ml_launcher"; }; - class ace_kh25ml_pylonmissile_int_x1 : PylonMissile_Missile_AGM_KH25_INT_x1 { + class ace_kh25ml_pylonmissile_int_x1: PylonMissile_Missile_AGM_KH25_INT_x1 { ammo = "ace_kh25ml"; author = "xrufix"; descriptionShort = CSTRING(KH25ML_MAG_DESCR); diff --git a/addons/maverick/CfgWeapons.hpp b/addons/maverick/CfgWeapons.hpp index c3157f34dd..1c0ae744ef 100644 --- a/addons/maverick/CfgWeapons.hpp +++ b/addons/maverick/CfgWeapons.hpp @@ -1,12 +1,12 @@ class CfgWeapons { class LauncherCore; - class RocketPods : LauncherCore {}; - class weapon_AGM_65Launcher : RocketPods{}; + class RocketPods: LauncherCore {}; + class weapon_AGM_65Launcher: RocketPods {}; - class MissileLauncher : LauncherCore {}; - class Missile_AGM_02_Plane_CAS_01_F : MissileLauncher {}; + class MissileLauncher: LauncherCore {}; + class Missile_AGM_02_Plane_CAS_01_F: MissileLauncher {}; - class GVAR(L_Launcher) : weapon_AGM_65Launcher { + class GVAR(L_Launcher): weapon_AGM_65Launcher { author = "xrufix"; displayname = CSTRING(L); magazines[] = { @@ -26,7 +26,7 @@ class CfgWeapons { GVAR(enabled) = 1; }; - class GVAR(L_Launcher_Plane) : Missile_AGM_02_Plane_CAS_01_F { + class GVAR(L_Launcher_Plane): Missile_AGM_02_Plane_CAS_01_F { author = "xrufix"; displayname = CSTRING(L); magazines[] = { @@ -46,8 +46,8 @@ class CfgWeapons { GVAR(enabled) = 1; }; - class weapon_AGM_KH25Launcher : MissileLauncher {}; - class ace_kh25ml_launcher : weapon_AGM_KH25Launcher { + class weapon_AGM_KH25Launcher: MissileLauncher {}; + class ace_kh25ml_launcher: weapon_AGM_KH25Launcher { author = "xrufix"; displayName = CSTRING(KH25ML); magazines[] = { @@ -58,7 +58,7 @@ class CfgWeapons { }; weaponLockDelay = 0.1; weaponLockSystem = 0; - + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) EGVAR(laser,showHud) = 1; // show attack profile / lock on hud GVAR(enabled) = 1; diff --git a/addons/maverick/README.md b/addons/maverick/README.md index a931a2bc08..313ced8388 100644 --- a/addons/maverick/README.md +++ b/addons/maverick/README.md @@ -10,8 +10,3 @@ Adds pylon magazines with laser guided AGM-65 Maverick L and KH25ML. ![Laser guided Maverick](https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/US_Navy_041128-N-5345W-016_Aviation_Ordnanceman_3rd_Class_William_Miller_arms_a_AGM-65_Maverick_laser-guided_missile.jpg/1280px-US_Navy_041128-N-5345W-016_Aviation_Ordnanceman_3rd_Class_William_Miller_arms_a_AGM-65_Maverick_laser-guided_missile.jpg) -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [xrufix](https://github.com/xrufix) diff --git a/addons/maverick/config.cpp b/addons/maverick/config.cpp index dbfabf7f9d..d25878d004 100644 --- a/addons/maverick/config.cpp +++ b/addons/maverick/config.cpp @@ -1,7 +1,7 @@ #include "script_component.hpp" class CfgPatches { - class ADDON { + class ADDON { name = COMPONENT_NAME; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_missileguidance"}; @@ -9,10 +9,6 @@ class CfgPatches { authors[] = {"xrufix"}; url = ECSTRING(main,URL); VERSION_CONFIG; - ammo[] = { - GVAR(L), - "ace_kh25ml" - }; magazines[] = { QGVAR(L_magazine_x1), QGVAR(L_pylonmissile_x1), @@ -26,12 +22,12 @@ class CfgPatches { "ace_kh25ml_pylonmissile_int_x1" }; weapons[] = { - GVAR(L_Launcher_Plane), - GVAR(L_Launcher), + QGVAR(L_Launcher_Plane), + QGVAR(L_Launcher), "ace_kh25ml_launcher" }; units[] = {}; - }; + }; }; diff --git a/addons/maverick/stringtable.xml b/addons/maverick/stringtable.xml index 3b089fd42b..6bf1d80e04 100644 --- a/addons/maverick/stringtable.xml +++ b/addons/maverick/stringtable.xml @@ -1,107 +1,149 @@ - - + + - + AGM-65 Maverick L, Laser Guided Anti-Ground-Missile AGM-65 Maverick L, lasergelenkte Luft-Boden-Rakete - AGM-65 Maverick L, Guida Laser Missile Anti-Terra + AGM-65 Maverick L, Missile Aria-Terra Laserguidato AGM-65 マーベリック L、レーザー誘導対地ミサイル AGM-65"小牛"飛彈L型,雷射導引對地導彈 - AGM-65"小牛"空地L型,雷射导引对地导弹 - AGM-65 Maverick L, 레이저 유도 대지 미사일 + AGM-65"小牛"L型激光制导对地导弹 + AGM-65 매버릭 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-65L Maverick, Missile Air-Sol à Guidage Laser + AGM-65 Maverick L, Laserem naváděná střela vzduch-země + AGM-65 Maverick L, Laser Guided Anti-Ground-Missile + AGM-65 Maverick L, Misil Aire-Tierra guiado por Láser - + AGM-65 Maverick L [ACE] AGM-65 Maverick L [ACE] AGM-65 Maverick L [ACE] AGM-65 マーベリック L [ACE] AGM-65"小牛"飛彈L型 [ACE] AGM-65"小牛"空地L型 [ACE] - AGM-65 Maverick L [ACE] + AGM-65 매버릭 L [ACE] AGM-65 Maverick L [ACE] AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] + 1x AGM-65L Maverick [ACE] + AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] - + 2x AGM-65 Maverick L [ACE] 2x AGM-65 Maverick L [ACE] 2x AGM-65 Maverick L [ACE] 2x AGM-65 マーベリック L [ACE] 2x AGM-65"小牛"飛彈L型 [ACE] 2x AGM-65"小牛"空地L型 [ACE] - 2x AGM-65 Maverick L [ACE] + 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-65L Maverick [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] 3x AGM-65 Maverick L [ACE] 3x AGM-65 Maverick L [ACE] 3x AGM-65 マーベリック L [ACE] 3x AGM-65"小牛"飛彈L型 [ACE] 3x AGM-65"小牛"空地L型 [ACE] - 3x AGM-65 Maverick L [ACE] + 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-65L Maverick [ACE] + 3x AGM-65 Maverick L [ACE] + 3x AGM-65 Maverick L [ACE] + 3x AGM-65 Maverick L [ACE] - - Laser Guided - Lasergelenkt - Guida Laser - レーザー誘導 - 雷射導引 - 雷射导引 - 레이저 유도 - Kierowany laserowo - С лазерным наведением + + MAVL + MAVL + MAVL + MAVL + MAVL + MAVL + MAVL + MAVL + MAVL + MAVL + MAVL - + Kh-25ML, Laser Guided Air-to-Ground-Missile Ch-25ML, Lasergelenkte Luft-Boden-Rakete Kh-25ML, 레이저 유도 대공 미사일 Kh-25ML,雷射導引對地導彈 - Kh-25ML,镭射导引空地导弹 + Kh-25ML,激光制导空地导弹 Kh-25ML、レーザー誘導対地ミサイル - Kh-25ML, a Guida Laser Missile Aria-Terra + Kh-25ML, Missile Aria-Terra Laserguidato Kh-25ML, Kierowany laserowo pocisk powietrze-ziemia Х-25МЛ, ракета Воздух-Земля с лазерным наведением + Kh-25ML, Míssil Ar para Chão Guiado a Laser + Kh-25ML, Missile Air-Sol à Guidage Laser + Kh-25ML, Laserem naváděná střela vzduch-země + Kh-25ML, Laser Guided Air-to-Ground-Missile + Kh-25ML, Misil Aire-Tierra guiado por Láser - + 1x Kh-25ML [ACE] 1x Ch-25ML [ACE] 1x Х-25МЛ [ACE] 1x Kh-25ML [ACE] 1x Kh-25ML [ACE] - 1x Kh-25ML镭射空地导弹 [ACE] + 1x Kh-25ML 激光空地导弹 [ACE] 1x Kh-25ML [ACE] 1x Kh-25ML [ACE] 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] - + AGM-65 Maverick L AGM-65 Maverick L AGM-65 Maverick L AGM-65 マーベリック L AGM-65"小牛"空地L型 - AGM-65"小牛"飞弹L型 - AGM-65 Maverick L + AGM-65"小牛"导弹L型 + AGM-65 매버릭 L AGM-65 Maverick L AGM-65 Maverick L + AGM-65 Maverick L + AGM-65L Maverick + AGM-65 Maverick L + AGM-65 Maverick L + AGM-65 Maverick L - + Kh-25ML Ch-25ML Х-25МЛ Kh-25ML Kh-25ML - Kh-25ML镭射空地导弹 + Kh-25ML 激光空地导弹 Kh-25ML Kh-25ML Kh-25ML + Kh-25ML + Kh-25ML + Kh-25ML + Kh-25ML + Kh-25ML diff --git a/addons/medical/ACE_Settings.hpp b/addons/medical/ACE_Settings.hpp index eb84ee7f10..81984dab73 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -9,15 +9,9 @@ class ACE_Settings { values[] = {"Players only", "Players and AI"}; }; */ - /* @todo class GVAR(enableVehicleCrashes) { - category = CSTRING(Category_Medical); - displayName = CSTRING(MedicalSettings_enableVehicleCrashes_DisplayName); - description = CSTRING(MedicalSettings_enableVehicleCrashes_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; - */ class GVAR(spontaneousWakeUpChance) { movedToSQF = 1; }; diff --git a/addons/medical/CfgEventHandlers.hpp b/addons/medical/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/medical/CfgEventHandlers.hpp +++ b/addons/medical/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical/XEH_PREP.hpp b/addons/medical/XEH_PREP.hpp index 8cdc7feecf..dcbb9b016a 100644 --- a/addons/medical/XEH_PREP.hpp +++ b/addons/medical/XEH_PREP.hpp @@ -1,3 +1,5 @@ PREP(addDamageToUnit); PREP(adjustPainLevel); +PREP(deserializeState); +PREP(serializeState); PREP(setUnconscious); diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index c2d202f567..23c90b2579 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -5,11 +5,18 @@ if (!hasInterface) exitWith {}; -[missionNamespace, "ACE_setCustomAimCoef", QUOTE(ADDON), { - (linearConversion [0, 1, GET_PAIN_PERCEIVED(ACE_player), 1, 5, true]) + (ACE_player getVariable [QEGVAR(medical_engine,aimFracture), 0]) -}] call EFUNC(common,arithmeticSetSource); +// Fractures affect base sway, pain makes it worse +["baseline", { + ACE_player getVariable [QEGVAR(medical_engine,aimFracture), 0] +}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); + +// Max pain = 5x sway +["multiplier", { + 1 + (GET_PAIN_PERCEIVED(ACE_player) * 4) +}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); #ifdef DEBUG_MODE_FULL + call compile preprocessFileLineNumbers QPATHTOF(dev\reportSettings.sqf); call compile preprocessFileLineNumbers QPATHTOF(dev\watchVariable.sqf); call compile preprocessFileLineNumbers QPATHTOF(dev\debugDisplay.sqf); #endif diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index 2ebebbbd3d..894773534a 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -6,49 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" - -// 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 [ - 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) -]; +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/medical/XEH_preStart.sqf b/addons/medical/XEH_preStart.sqf index 022888575e..bc3262c38c 100644 --- a/addons/medical/XEH_preStart.sqf +++ b/addons/medical/XEH_preStart.sqf @@ -1,3 +1,5 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +[false] call compile preprocessFileLineNumbers QPATHTOF(dev\test_hitpointConfigs.sqf); diff --git a/addons/medical/addon.toml b/addons/medical/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical/config.cpp b/addons/medical/config.cpp index 6c93d1e3e8..2f1dfbc0ad 100644 --- a/addons/medical/config.cpp +++ b/addons/medical/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -21,3 +29,5 @@ class CfgPatches { class ACE_Tests { medicalHitpoints = QPATHTOF(dev\test_hitpointConfigs.sqf); }; + +#endif diff --git a/addons/medical/dev/debugDisplay.sqf b/addons/medical/dev/debugDisplay.sqf index 541aaaccba..015a71be14 100644 --- a/addons/medical/dev/debugDisplay.sqf +++ b/addons/medical/dev/debugDisplay.sqf @@ -1,4 +1,4 @@ -#include "\z\ace\addons\medical\script_component.hpp" +#include "..\script_component.hpp" [{!isNull findDisplay 46}, { INFO("Creating Debug Display"); diff --git a/addons/medical/dev/reportSettings.sqf b/addons/medical/dev/reportSettings.sqf new file mode 100644 index 0000000000..b06c3a33ee --- /dev/null +++ b/addons/medical/dev/reportSettings.sqf @@ -0,0 +1,14 @@ +#include "..\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 isNotEqualTo _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 index 8838b1d744..7bdeb189c2 100644 --- a/addons/medical/dev/test_hitpointConfigs.sqf +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -1,33 +1,36 @@ -// PabstMirror +// PabstMirror, commy2 // ["medicalHitpoints"] call ace_common_fnc_runTests; -// execVM "\z\ace\addons\medical\dev\test_hitpointConfigs.sqf" +// call compile preprocessFileLineNumbers "\z\ace\addons\medical\dev\test_hitpointConfigs.sqf" -#include "\z\ace\addons\medical\script_component.hpp" +#include "..\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 _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgVehicles = configFile >> "CfgVehicles"; + +private _uniforms = "getNumber (_x >> 'scope') == 2 && {configName _x isKindOf ['Uniform_Base', _cfgWeapons]}" configClasses _cfgWeapons; +private _units = _uniforms apply {_cfgVehicles >> getText (_x >> "ItemInfo" >> "uniformClass")}; +if (param [0, false]) then { // Check all units (if naked) + INFO("checking ALL units"); + _units append ((configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'scope')) == 2} && {configName _x isKindOf 'CAManBase'}", true])); +}; + +INFO_1("Checking uniforms for correct medical hitpoints [%1 units]",count _units); private _testPass = true; { private _typeOf = configName _x; - private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {configName _x}; + private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {toLowerANSI configName _x}; + private _expectedHitPoints = ["hitleftarm","hitrightarm","hitleftleg","hitrightleg","hithead","hitbody"]; + private _missingHitPoints = _expectedHitPoints select {!(_x in _hitpoints)}; + if (_missingHitPoints isNotEqualTo []) then { + WARNING_3("%1 missing ace hitpoints: %2 - class hitpoints: %3",_typeOf,_missingHitPoints,_hitpoints); + _testPass = false; + }; // _typeOf createUnit [position player, group player, "z = this"]; // deleteVehicle z; - - private _lastHitpoint = (_hitpoints param [(count _hitpoints) - 1, "#array"]); - if (_lastHitpoint != "ACE_HDBracket") then { - WARNING_2("%1 has bad last hitpoint: %2",_typeOf,_hitpoints); - _testPass = false; - }; - - if (((_hitpoints findIf {_x == "HitLeftArm"}) == -1) || {(_hitpoints findIf {_x == "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; +} forEach _units; _testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 1fa8157fd4..a0e064595a 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -1,4 +1,7 @@ -#include "\z\ace\addons\medical\script_component.hpp" +#include "..\script_component.hpp" + +if (missionNamespace getVariable [QGVAR(dev_watchVariableRunning), false]) exitWith {}; +GVAR(dev_watchVariableRunning) = true; ["medical", { @@ -7,10 +10,10 @@ if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; - if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; - if (!(_unit isKindOf "CAManBase")) then {_unit = ACE_player}; + if !(_unit isKindOf "CAManBase") then {_unit = cursorObject}; + if !(_unit isKindOf "CAManBase") then {_unit = ACE_player}; if ((_unit != ACE_player) && {IS_UNCONSCIOUS(ACE_player)}) then {_unit = ACE_player}; - if (!(_unit isKindOf "CAManBase")) exitWith {"No Unit?"}; + if !(_unit isKindOf "CAManBase") exitWith {"No Unit?"}; private _return = []; @@ -25,7 +28,7 @@ _return pushBack format ["State: %2", _color, _targetState]; private _hasStableVitals = ["N", "Y"] select ([_unit] call EFUNC(medical_status,hasStableVitals)); private _hasStableCondition = ["N", "Y"] select ([_unit] call EFUNC(medical_status,isInStableCondition)); - private _unconcFlag = if IS_UNCONSCIOUS(_unit) then {"[U]"} else {""}; + private _unconcFlag = ["", "[U]"] select IS_UNCONSCIOUS(_unit); private _timeLeft = _unit getVariable [QEGVAR(medical_statemachine,cardiacArrestTimeLeft), -1]; private _cardiactArrestFlag = if IN_CRDC_ARRST(_unit) then {format ["[CA %1]", _timeLeft toFixed 1]} else {""}; _return pushBack format ["[StableVitals: %1] [StableCon: %2] %3 %4", _hasStableVitals, _hasStableCondition, _unconcFlag, _cardiactArrestFlag]; @@ -35,7 +38,7 @@ private _woundBleeding = GET_WOUND_BLEEDING(_unit); private _bloodLoss = GET_BLOOD_LOSS(_unit); private _hemorrhage = GET_HEMORRHAGE(_unit); - private _isBleeding = if (IS_BLEEDING(_unit)) then {"Bleeding"} else {""}; + private _isBleeding = ["", "[Bleeding]"] select IS_BLEEDING(_unit); private _secondsToHeartstop = if (_bloodLoss != 0) then {format ["[Time Left: %1 sec]", (((_bloodVolume - BLOOD_VOLUME_CLASS_4_HEMORRHAGE) max 0) / _bloodLoss) toFixed 0]} else {""}; _return pushBack format ["Blood: %1 [Hemorrhage: %2] %3", _bloodVolume toFixed 3, _hemorrhage, _isBleeding]; _return pushBack format [" - [W: %1 T: %2] %3", _woundBleeding toFixed 4, _bloodLoss toFixed 4, _secondsToHeartstop]; @@ -45,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); @@ -57,16 +60,17 @@ // 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]; + private _limping = ["", "[ Limping ]"] select (_unit getVariable [QEGVAR(medical,isLimping), false]); + _return pushBack format ["BodyPartDamage: [H: %1] [B: %2]", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2]; _return pushBack format ["[LA:%1] [RA: %2] [LL:%3] [RL: %4]", (_damage select 2) toFixed 2, (_damage select 3) toFixed 2, (_damage select 4) toFixed 2, (_damage select 5) toFixed 2]; _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]; + private _canSprint = ["[Sprint Blocked]", ""] select (isSprintAllowed _unit); + private _forceWalk = ["", "[Forced Walking]"] select (isForcedWalk _unit); + _return pushBack format ["Fractures: %1 %2%3", _fractures, _canSprint, _forceWalk]; // Tourniquets: @@ -88,27 +92,36 @@ // Wounds: - _return pushBack "------- Wounds: -------"; + _return pushBack "------- Open Wounds: -------"; private _wounds = GET_OPEN_WOUNDS(_unit); { - _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]; + private _bodyPart = _x; + { + _x params ["_xClassID", "_xAmountOf", "_xBleeding", "_xDamage"]; + _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", _bodyPart, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; + } forEach _y; } forEach _wounds; // Bandaged Wounds: _return pushBack "------- Bandaged Wounds: -------"; private _wounds = GET_BANDAGED_WOUNDS(_unit); { - _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]; + private _bodyPart = _x; + { + _x params ["_xClassID", "_xAmountOf", "_xBleeding", "_xDamage"]; + _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", _bodyPart, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; + } forEach _y; } forEach _wounds; // Stitched Wounds: _return pushBack "------- Stitched Wounds: -------"; private _wounds = GET_STITCHED_WOUNDS(_unit); { - _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]; + private _bodyPart = _x; + { + _x params ["_xClassID", "_xAmountOf", "_xBleeding", "_xDamage"]; + _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", _bodyPart, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; + } forEach _y; } forEach _wounds; // IVs: @@ -124,17 +137,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; @@ -142,9 +149,11 @@ 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; @@ -152,6 +161,8 @@ _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 ""; diff --git a/addons/medical/functions/fnc_addDamageToUnit.sqf b/addons/medical/functions/fnc_addDamageToUnit.sqf index cde34b31d6..e490399c4b 100644 --- a/addons/medical/functions/fnc_addDamageToUnit.sqf +++ b/addons/medical/functions/fnc_addDamageToUnit.sqf @@ -1,8 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Manually Apply Damage to a unit (can cause lethal damage) - * NOTE: because of caching, this will not have instant effects (~3 frame delay) * * Arguments: * 0: The Unit @@ -10,6 +9,8 @@ * 2: Body part ("Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg") * 3: Projectile Type * 4: Source + * 5: Unused parameter maintained for backwards compatibility (default: []) + * 6: Override Invulnerability (default: true) * * Return Value: * Successful @@ -22,13 +23,27 @@ */ // #define DEBUG_TESTRESULTS -params [["_unit", objNull, [objNull]], ["_damageToAdd", -1, [0]], ["_bodyPart", "", [""]], ["_typeOfDamage", "", [""]], ["_instigator", objNull, [objNull]]]; -TRACE_5("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator); +params [ + ["_unit", objNull, [objNull]], + ["_damageToAdd", -1, [0]], + ["_bodyPart", "", [""]], + ["_typeOfDamage", "", [""]], + ["_instigator", objNull, [objNull]], + "", + ["_overrideInvuln", true, [true]] +]; +TRACE_7("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator,_damageSelectionArray,_overrideInvuln); -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}; -if (_bodyPartIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad selection %1", _this); false}; +_bodyPart = toLowerANSI _bodyPart; +private _bodyPartIndex = ALL_BODY_PARTS find _bodyPart; +if (_bodyPartIndex < 0) then { _bodyPartIndex = ALL_SELECTIONS find _bodyPart; }; // 2nd attempt with selection names ("hand_l", "hand_r", "leg_l", "leg_r") +if (_bodyPartIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad selection %1",_this); false}; +if (isNull _unit || {!local _unit} || {!alive _unit}) exitWith {ERROR_2("addDamageToUnit - badUnit %1 [local %2]",_this,local _unit); false}; +if (_damageToAdd < 0) exitWith {ERROR_1("addDamageToUnit - bad damage %1",_this); false}; + +if (!_overrideInvuln && {!((isDamageAllowed _unit) && {_unit getVariable [QEGVAR(medical,allowDamage), true]})}) exitWith { + ERROR_1("addDamageToUnit - unit invulnerable %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; @@ -39,14 +54,14 @@ if (!isNull _instigator) then { }; #ifdef DEBUG_TESTRESULTS -private _startDmg = +(_unit getVariable [QEGVAR(medical,bodyPartDamage), [-1]]); +private _startDmg = +(_unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]); private _startPain = GET_PAIN(_unit); #endif -[QEGVAR(medical,woundReceived), [_unit, _bodyPart, _damageToAdd, _instigator, _typeOfDamage]] call CBA_fnc_localEvent; +[QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, _typeOfDamage]] call CBA_fnc_localEvent; #ifdef DEBUG_TESTRESULTS -private _endDmg = _unit getVariable [QEGVAR(medical,bodyPartDamage), [-1]]; +private _endDmg = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; private _endPain = GET_PAIN(_unit); private _typeOfDamageAdj = _typeOfDamage call EFUNC(medical_damage,getTypeOfDamage); private _config = configFile >> "ACE_Medical_Injuries" >> "damageTypes" >> _typeOfDamageAdj; @@ -54,7 +69,7 @@ private _selectionSpecific = true; if (isClass _config) then { _selectionSpecific = (getNumber (_config >> "selectionSpecific")) == 1; } else { - WARNING_2("Damage type not in config [%1:%2]", _typeOfDamage, _config); + WARNING_2("Damage type not in config [%1:%2]",_typeOfDamage,_config); }; INFO_4("Debug AddDamageToUnit: Type [%1] - Selection Specific [%2] - HitPoint [%3 -> %4]",_typeOfDamage,_selectionSpecific,_startDmg select _bodyPartIndex,_endDmg select _bodyPartIndex); INFO_4("Pain Change [%1 -> %2] - BodyPartDamage Change [%3 -> %4]",_startPain,_endPain,_startDmg,_endDmg); diff --git a/addons/medical/functions/fnc_adjustPainLevel.sqf b/addons/medical/functions/fnc_adjustPainLevel.sqf index 233638180f..f5c3d9a35d 100644 --- a/addons/medical/functions/fnc_adjustPainLevel.sqf +++ b/addons/medical/functions/fnc_adjustPainLevel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Public interface to allow external modules to safely adjust pain levels. diff --git a/addons/medical/functions/fnc_deserializeState.sqf b/addons/medical/functions/fnc_deserializeState.sqf new file mode 100644 index 0000000000..b7846bf901 --- /dev/null +++ b/addons/medical/functions/fnc_deserializeState.sqf @@ -0,0 +1,128 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Deserializes the medical state of a unit and applies it. + * + * Arguments: + * 0: Unit + * 1: State as JSON + * + * Return Value: + * None + * + * Example: + * [player, _json] call ace_medical_fnc_deserializeState + * + * Public: Yes + */ +params [["_unit", objNull, [objNull]], ["_json", "{}", [""]]]; + +// Don't run in scheduled environment +if (canSuspend) exitWith { + [FUNC(deserializeState), _this] call CBA_fnc_directCall +}; + +if (isNull _unit) exitWith {}; +if (!local _unit) exitWith { ERROR_1("unit [%1] is not local",_unit) }; + +// If unit is not initialized yet, wait until event is raised +if !(_unit getVariable [QGVAR(initialized), false]) exitWith { + [QEGVAR(medical_status,initialized), { + params ["_unit"]; + _thisArgs params ["_target"]; + + if (_unit == _target) then { + _thisArgs call FUNC(deserializeState); + [_thisType, _thisId] call CBA_fnc_removeEventHandler; + }; + }, _this] call CBA_fnc_addEventHandlerArgs; +}; + +private _state = [_json] call CBA_fnc_parseJSON; + +// Migration from old array wounding storage serialized in old versions (<= 3.16.0) +{ + if ((_state getVariable [_x, createHashMap]) isEqualType []) then { + private _migratedWounds = createHashMap; + + { + _x params ["_class", "_bodyPartIndex", "_amountOf", "_bleeding", "_damage"]; + + private _partWounds = _migratedWounds getOrDefault [ALL_BODY_PARTS select _bodyPartIndex, [], true]; + _partWounds pushBack [_class, _amountOf, _bleeding, _damage]; + } forEach (_state getVariable _x); + + _state setVariable [_x, _migratedWounds]; + }; +} forEach [VAR_OPEN_WOUNDS, VAR_BANDAGED_WOUNDS, VAR_STITCHED_WOUNDS]; + +// Set medical variables +{ + _x params ["_var", "_default"]; + private _value = _state getVariable _x; + + // Handle wound hashmaps deserialized as CBA_namespaces + if (typeName _value == "LOCATION") then { + private _keys = allVariables _value; + private _values = _keys apply {_value getVariable _x}; + _value = _keys createHashMapFromArray _values; + }; + + // Treat null as nil + if (_value isEqualTo objNull) then { + _value = _default; + }; + + _unit setVariable [_var, _value, true]; +} forEach [ + [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME], + [VAR_HEART_RATE, DEFAULT_HEART_RATE], + [VAR_BLOOD_PRESS, [80, 120]], + [VAR_PERIPH_RES, DEFAULT_PERIPH_RES], + // State transition should handle this + // [VAR_CRDC_ARRST, false], + [VAR_HEMORRHAGE, 0], + [VAR_PAIN, 0], + [VAR_IN_PAIN, false], + [VAR_PAIN_SUPP, 0], + [VAR_OPEN_WOUNDS, createHashMap], + [VAR_BANDAGED_WOUNDS, createHashMap], + [VAR_STITCHED_WOUNDS, createHashMap], + [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES], + // State transition should handle this + // [VAR_UNCON, false], + [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES], + [QEGVAR(medical,occludedMedications), nil], + [QEGVAR(medical,ivBags), nil], + [QEGVAR(medical,triageLevel), 0], + [QEGVAR(medical,triageCard), []], + [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]] + // Offset needs to be converted + // [VAR_MEDICATIONS, []] +]; + +// Reset timers +_unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; + +// Convert medications offset to time +private _medications = _state getVariable [VAR_MEDICATIONS, []]; +{ + _x set [1, _x#1 + CBA_missionTime]; +} forEach _medications; +_unit setVariable [VAR_MEDICATIONS, _medications, true]; + +// Update effects +[_unit] call EFUNC(medical_engine,updateDamageEffects); +[_unit] call EFUNC(medical_status,updateWoundBloodLoss); + +// Transition within statemachine +private _currentState = [_unit, GVAR(STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; +private _targetState = _state getVariable [QGVAR(statemachineState), "Default"]; +[_unit, GVAR(STATE_MACHINE), _currentState, _targetState] call CBA_statemachine_fnc_manualTransition; + +// Manually call wake up tranisition if necessary +if (_currentState in ["Unconscious", "CardiacArrest"] && {_targetState in ["Default", "Injured"]}) then { + [_unit, false] call EFUNC(medical_status,setUnconsciousState); +}; + +_state call CBA_fnc_deleteNamespace; diff --git a/addons/medical/functions/fnc_serializeState.sqf b/addons/medical/functions/fnc_serializeState.sqf new file mode 100644 index 0000000000..67783e85d9 --- /dev/null +++ b/addons/medical/functions/fnc_serializeState.sqf @@ -0,0 +1,66 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Serializes the medical state of a unit into a string. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Serialized state as JSON string + * + * Example: + * [player] call ace_medical_fnc_serializeState + * + * Public: Yes + */ +params [["_unit", objNull, [objNull]]]; + +private _state = [] call CBA_fnc_createNamespace; + +// For variables, see: EFUNC(medical_status,initUnit) +{ + _x params ["_var"]; + _state setVariable [_var, _unit getVariable _x]; +} forEach [ + [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME], + [VAR_HEART_RATE, DEFAULT_HEART_RATE], + [VAR_BLOOD_PRESS, [80, 120]], + [VAR_PERIPH_RES, DEFAULT_PERIPH_RES], + // State transition should handle this + // [VAR_CRDC_ARRST, false], + [VAR_HEMORRHAGE, 0], + [VAR_PAIN, 0], + [VAR_IN_PAIN, false], + [VAR_PAIN_SUPP, 0], + [VAR_OPEN_WOUNDS, createHashMap], + [VAR_BANDAGED_WOUNDS, createHashMap], + [VAR_STITCHED_WOUNDS, createHashMap], + [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES], + // State transition should handle this + // [VAR_UNCON, false], + [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES], + [QEGVAR(medical,occludedMedications), nil], + [QEGVAR(medical,ivBags), nil], + [QEGVAR(medical,triageLevel), 0], + [QEGVAR(medical,triageCard), []], + [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]] + // Time needs to be converted + // [VAR_MEDICATIONS, []] +]; + +// Convert medications time to offset +private _medications = _unit getVariable [VAR_MEDICATIONS, []]; +{ + _x set [1, _x#1 - CBA_missionTime]; +} forEach _medications; +_state setVariable [VAR_MEDICATIONS, _medications]; + +// Medical statemachine state +private _currentState = [_unit, GVAR(STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; +_state setVariable [QGVAR(statemachineState), _currentState]; + +// Serialize & return +private _json = [_state] call CBA_fnc_encodeJSON; +_state call CBA_fnc_deleteNamespace; +_json diff --git a/addons/medical/functions/fnc_setUnconscious.sqf b/addons/medical/functions/fnc_setUnconscious.sqf index f6f39b03c5..a1de71c36b 100644 --- a/addons/medical/functions/fnc_setUnconscious.sqf +++ b/addons/medical/functions/fnc_setUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Sets a unit in the unconscious state. @@ -38,7 +38,7 @@ if (!local _unit) exitWith { }; if (_knockOut isEqualTo IS_UNCONSCIOUS(_unit)) exitWith { - WARNING_2("setUnconscious called with no change [Unit %1] [State [%2]", _unit, _knockOut); + WARNING_2("setUnconscious called with no change [Unit %1] [State [%2]",_unit,_knockOut); false }; diff --git a/addons/medical/functions/script_component.hpp b/addons/medical/functions/script_component.hpp deleted file mode 100644 index ea579c04a5..0000000000 --- a/addons/medical/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical\script_component.hpp" \ No newline at end of file diff --git a/addons/medical/initSettings.inc.sqf b/addons/medical/initSettings.inc.sqf new file mode 100644 index 0000000000..3c54f47cee --- /dev/null +++ b/addons/medical/initSettings.inc.sqf @@ -0,0 +1,48 @@ +[ + 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, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(fractures), + "LIST", + [LSTRING(Fractures_DisplayName), LSTRING(Fractures_Description)], + LSTRING(Category), + [[0, 1, 2, 3], [ELSTRING(common,Disabled), LSTRING(Fractures_SplintHealsFully), LSTRING(Fractures_SplintHealsNoSprint), LSTRING(Fractures_SplintHealsNoJog)], 1], + true, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(fractureChance), + "SLIDER", + [LSTRING(FractureChance_DisplayName), LSTRING(FractureChance_Description)], + LSTRING(Category), + [0, 1, 0.8, 2, true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(spontaneousWakeUpChance), + "SLIDER", + [LSTRING(SpontaneousWakeUpChance_DisplayName), LSTRING(SpontaneousWakeUpChance_Description)], + LSTRING(Category), + [0, 1, 0.05, 2, true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(spontaneousWakeUpEpinephrineBoost), + "SLIDER", + [LSTRING(spontaneousWakeUpEpinephrineBoost_DisplayName), LSTRING(spontaneousWakeUpEpinephrineBoost_Description)], + LSTRING(Category), + [1, 30, 1, 1], + true +] call CBA_fnc_addSetting; diff --git a/addons/medical/initSettings.sqf b/addons/medical/initSettings.sqf deleted file mode 100644 index 9b1aee8464..0000000000 --- a/addons/medical/initSettings.sqf +++ /dev/null @@ -1,30 +0,0 @@ -[ - 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; diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index af61c91714..6a081fa648 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -3,7 +3,7 @@ ACE Medical - ACE: медицина + ACE Медицина ACE Opcje medyczne Médico ACE ACE-Medicsystem @@ -11,143 +11,264 @@ ACE Médico ACE Médical ACE Orvosi Rendszer - ACE Medical - ACE 医療 + ACE Medica ACE 의료 - ACE 医疗系统 + ACE 医疗 ACE 醫療系統 + ACE Medikal + ACE 医療 + + + ACE Medical Interface + ACE Медицина Интерфейс + ACE Opcje medyczne Interfejs + Médico ACE Interfaz + ACE-Medicsystem Interface + ACE Zdravotnické Rozhraní + ACE Interface Médica + ACE Médical Interface + ACE Interfaccia Medica + ACE 의료 인터페이스 + ACE 医疗 界面 + ACE 醫療系統 介面 + ACE Medikal Arayüz + ACE 医療 インターフェース Unconscious Wake Up Chance - Wahrscheinlichkeit aufzuwachen - 気絶から覚醒する可能性 + Wahrscheinlichkeit um aufzuwachen + 無意識状態時の覚醒確率 Шанс очнуться при потере сознания + Chance de reprendre connaissance + Chance de recuperar consciência + 從無意識中甦醒機率 + ACE 从无意识中苏醒概率 + Probabilità di rinvenire + Pravděpodobnost probuzení se z bezvědomí + Szansa na wybudzenie nieprzytomnego + Posibilidad de recuperar la conciencia + Bayılmış Bir Kişinin Uyanma Şansı + 기절 회복 확률 - 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 秒毎に確認) + The probability that a person with stable vitals will wake up from unconsciousness (checked every 15 seconds). + Wahrscheinlichkeit, dass eine bewusstlose Person mit stabilen Vitalwerten wieder aufwacht (Überprüfung alle 15 Sekunden) + 容体が安定しているユニットが無意識状態から意識回復する確率を設定します。(15 秒毎に確認) Вероятность, что стабилизированный юнит очнется от потери сознания (Проверяется каждые 15 сек) + La probabilité pour qu'une unité inconsciente en état stable reprenne conscience spontanément (état vérifié toutes les 15 secondes). + A probabilidade que uma unidade com vitais estabilizados possa recuperar consciências (verificado a cada 15 segundos) + 生命跡象穩定的單位從無意識狀態中甦醒的機率(每十五秒確認一次) + 生命迹象稳定的单位从无意识状态中苏醒的概率(每十五秒确认一次) + La probabilità che un'unità con segni vitali stabili si risvegli dall'incoscienza (controllata ogni 15 secondi). + Pravděpodobnost, že se jednotka se stabilními životními známkami probudí z bezvědomí (zkoušeno každých 15 vteřin). + Prawdopodobieństwo, że jednostka ze stabilnymi parametrami życiowymi obudzi się z nieprzytomności (sprawdzane co 15 sekund). + La probabilidad de que una unidad estabilizada recupere la conciencia y se levante (se comprueba cada 15 segundos) + Hayati değerleri stabil olan bir kişinin bilinçsizlikten uyanma olasılığı (her 15 saniyede bir kontrol edilir). + 기절하고 안정화된 상태에서 깨어날 확률을 정합니다 (매 15초 마다 갱신됨) + + + Epinephrine Wake Up Chance Boost + L'épinéphrine augmente les chances de réveil + Zwiększenie szansy na wybudzenie po podaniu epinefryny + 腎上腺素甦醒率加成 + 肾上腺素苏醒概率加成 + Erhöhung der Aufwachüberprüfungsrate durch Epinephrin + Rinvenimento più veloce da Epinefrina + アドレナリンによる覚醒確率上昇 + Zvýšení pravděpodobnosti probuzení s Epinefrinem + Увеличение шанса очнуться от адреналина + Epinefrin Uyanma Şansı Artışı + Aumento de probabilidad de despertarse por epinefrina + 에피네프린 사용 시 추가 회복 확률 + Aumento da Chance de Acordar com Epinefrina + + + When an unconscious patient has Epinephrine in their system, the time between spontaneous wake up checks is divided by this value. + 無意識状態の患者の体内に投与されたアドレナリンがある場合、 覚醒確率計算の実施間隔が値で除算されます。 + 增加因病患的循環系統裡面的腎上腺素自我甦醒的機率。 + 增加因病患的循环系统里面的肾上腺素自我苏醒的机率。 + Augmente la fréquence des tests de réveil lorsque le patient a de l'épinéphrine dans son système sanguin.\n(L'épinéphrine n'accélère pas la reprise de conscience si la valeur est définie sur 1.) + Quando un paziente svenuto ha Epinefrina in circolo, il tempo tra verifiche della probabilità di rinvenire viene diviso per questo valore. + Zvyšuje jak často je proveden test na probuzení z bezvědomí pokud má pacient Epinefrin ve svém krevním oběhu. + Zwiększa częstotliwość spontanicznych wybudzeń, gdy pacjent ma epinefrynę w swoim organizmie. + Aumenta o quão frequentemente checagens de acordar acontecem quando o paciente possui epinefrina no seu sistema + Incrementa con que frecuencia se comprueba el despertar cuando el paciente tiene epinefrina en su sistema + Erhöht wie oft Aufwachprüfungen passieren, wenn ein Patient Epinephrin im Blutkreislauf hat. + Увеличивает частоту проверок на спонтанное пробуждение, когда пациент под действием адреналина. + Hastanın sisteminde Epinefrin olduğunda rasgele uyanma kontrollerinin ne sıklıkla gerçekleştiğini artırır. + 에피네프린 투여 후 환자가 일어날 확률을 얼마나 추가할 지 정합니다. Limping Хромота - 跛行 + 足の引きずり(跛行) + Boitement + Mancando + 跛腳 + 跛脚 + Zoppicare + Kulhání + Kuśtykanie + Cojera + Humpeln + Topallama + 절뚝거림 - Limp when unit has leg wounds...(todo) - Хромота, когда юнит имеет ранения ног... - 足を負傷時に引きずって歩くようにします・・・(TODO) + Controls whether open or bandaged wounds cause a person to limp. + 開放状態の負傷や包帯で治療した負傷がある時、\n足を引きずる(跛行する)かを設定します。 + 控制裂開或者已包紮傷口是否會讓人跛腳。 + 控制裂开或者已包扎伤口是否会让人跛脚。 + Permet de définir si les plaies ouvertes ou pansées font boiter une personne. + Controlla se le ferite aperte o bendate fanno zoppicare un'unità. + Nastavuje zda otevřená nebo zavázaná zranění způsobují kulhání. + Kontroluje, czy otwarte lub zabandażowane rany powodują utykanie jednostki. + Controla se ferimentos abertos ou atados causam a pessoa a mancar. + Controla si las heridas abiertas o vendadas hacen que una persona cojee. + Stellt ein, ob offene oder bandagierte Wunden eine Person zum Humpeln bringen. + Контролирует хромоту в случае открытых или забинтованных ран. + Açık veya sargılı yaraların bir kişinin topallamasına neden olup olmadığını kontrol eder. + 붕대로 묶인 상처가 플레이어를 절게 만들지 결정합니다. - Limp on open wounds + Limp on Open Wounds Хромота при открытых ранах - 創傷開放時に跛行 + 開放創傷で跛行 + Boiter si plaies ouvertes + Mancar se possuir feridas abertas + 傷口裂開時跛腳 + 伤口裂开时跛脚 + Zoppica per via di ferite aperte + Kulhat s otevřeným zraněním + Kuśtykanie przy otwartych ranach + Cojera en heridas abiertas + Humpeln bei offenen Wunden + Açık Yaralarda Topallama + 상처 개방 시 절뚝거림 - Limp on open or bandaged wounds + Limp on Open or Bandaged Wounds Хромота при открытых или забинтованых ранах - 負傷時は引きずって歩くようにします + 開放創傷または包帯創傷で跛行 + Boiter si plaies ouvertes ou pansées + Mancar se possuir feridas abertas ou atadas + 使裂開或者包紮過的傷口讓人跛腳 + 使裂开或者包扎过的伤口让人跛脚 + Zoppica per via di ferite aperte o bendate + Kulhat s otevřeným i zavázaným zraněním + Kuśtykanie przy otwartych ranach lub zabandażowanych ranach + Cojera en heridas abiertas o vendadas + Humpeln bei offenen oder bandagierten Wunden + Açık veya Sargılı Yaralarda Topallama + 상처 개방 혹은 붕대질 후에도 절뚝거림 Fractures Переломы 骨折 + Fractures + Fraturas + 骨折 + 骨折 + Fratture + Zlomeniny + Złamania + Fracturas + Brüche + Kırıklar + 골절 - Limp fractures... (todo) - Хромота при переломах... - 骨折時は引きずって歩くようにします・・・ (TODO) + Controls the effect of using splints to treat fractures.\nWhen disabled, injuries will not cause fractures. + 骨折の治療に添え木を使用した際の効果を設定します。\n無効にすると、骨折しません。 + 控制是否讓固定版能夠治療骨折。\n當停用時,受傷時不會導致骨折發生。 + 控制是否让固定板能够治疗骨折。 \n当停用时,受伤时不会导致骨折发生。 + Permet de définir le niveau d'efficacité des attelles pour le traitement des fractures.\nSi l'option est désactivée, les blessures ne causent pas de fractures. + Controlla l'effetto dell'utilizzo di gessature per curare le fratture.\nSe disabilitato, le ferite non causano fratture. + Nastavuje efekt dlahy při léčení zlomenin.\nPokud je tato možnost vypnuta, zranění nebudou způsobovat zlomeniny. + Kontroluje efekt użycia szyn do leczenia złamań.\n Po wyłączeniu obrażenia nie powodują złamań. + Controla o efeito de uso de talas para tratar fraturas.\nQuando desabilitado, ferimentos não causam fraturas. + Controla el efecto del uso de férulas para tratar fracturas. \n Cuando está desactivado, las lesiones no causan fracturas. + Kontrolliert den Effekt wenn Schienen verwendet werden, um Knochenbrüche zu behandeln.\nWenn diese Einstellung nicht aktiviert ist, verursachen Verletzungen keine Knochenbrüche. + Управляет эффектом использования шин для лечения переломов.\nПри отключении травмы не вызывают переломов. + Kırıkları tedavi etmek için atel kullanmanın etkisini kontrol eder. \ Devre dışı bırakıldığında, yaralanmalar kırılmaya neden olmaz. + 부목이 골절을 어떻게 치료할 지 결정합니다\n비활성화 시 골절이 일어나지 않습니다. - Splints fully heal fractures + Splints Fully Heal Fractures Шины полностью лечат перелом 添え木で骨折完治 + Les attelles guérissent complètement les fractures + Talas curam fraturas completamente + 固定板完全治癒骨折 + 固定板完全治愈骨折 + Le gessature curano completamente le fratture + Dlahy kompletně léčí zlomeniny + Szyny leczą zupełnie złamania + Férulas sanan completamente las fracturas + Schienen heilen Knochenbrüche vollständig + Ateller Kırıkları Tamamen İyileştirir + 부목이 골절을 완전히 치료 - - Splints heal (but cannot sprint) + + Splints Heal, but Cannot Sprint Шины вылечивают, но не дают бегать - 添え木で治療しますが、走れません + 添え木で治癒可能、走れないように + Les attelles guérissent les fractures, mais empêchent de sprinter + Talas curam, mas não permitem correr + 固定版能治癒骨折,但無法奔跑 + 固定板能治愈骨折,但无法奔跑 + Le gessature curano, ma non puoi scattare + Dlahy léčí, ale zněmožňují sprintování + Szyny leczą, ale uniemożliwiają sprint + Las férulas sanan, pero no pueden correr + Schienen heilen, aber ermöglichen kein Sprinten + Ateller İyileştirir, ancak Koşamaz + 부목이 치료는 하지만 달릴 수는 없음 - - Remote Controlled AI - Ferngesteuerte KI-Einheiten - IA controlada remotamente - IA controlada remotamente - Zdalnie sterowane AI - Vzdáleně ovládané AI - Contrôle à distance des IA - Távvezérelt AI - Зевса считать ботом - IA Controllate in Remoto - 遠隔操作された AI - 인공지능 원격조종 - 遥控AI - 遙控AI + + Splints Heal, but Cannot Jog + Les attelles guérissent les fractures, mais empêchent de courir + 添え木で治癒可能、駆け足できないように + Le gessature curano, ma non puoi correre + Ateller İyileştirir, Ama Koşu Yapamaz + Las férulas sanan, pero no pueden trotar + Шины вылечивают, но не дают бежать трусцой + Szyny leczą, ale uniemożliwiają trucht + Schiene heilt, aber verhindert Sprinten + 부목이 치료는 하지만 빨리 걷지 못함 + 固定板能治愈骨折,但无法慢跑 + Talas curam, mas não permitem trotar - - Treat remote controlled units as AI not players? - Legt fest, ob ferngesteuerte Einheiten als KI anstatt als Spieler behandelt werden sollen. - ¿Tratar unidades remotamente controladas como IA? - 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? - 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? - 遠隔操作された AI は、非プレイヤーとして扱いますか? - 원격 조작하는 AI는 비 플레이어로 취급합니까? - 以医疗AI的方式医疗被遥控的单位 - 以醫療AI的方式醫療被遙控的單位 + + Fracture Chance + Chance de fracture + 骨折確率 + 骨折概率 + Probabilità di frattura + Šance na zlomeninu + Шанс перелома + Szansa na złamanie + Kırılma Şansı + Probabilidad de fractura + Wahrscheinlichkeit einer Fraktur + 골절 확률 + Chance de Fratura - - Prevent instant death - Откл. мгновенную смерть - Wyłącz natychmiastową śmierć - Prevenir muerte instantánea - Verhindere direkten Tod - Zabránit okamžité smrti - Previnir morte instantânea - Empêcher la mort instantanée - Azonnali halál kiiktatása - Previeni morte istantanea - 即死の防止 - 즉사 방지 - 防止当场死亡 - 防止當場死亡 - - - Have a unit move to unconscious instead of death - Бойцы теряют сознание вместо того, чтобы умирать - Spraw, aby jednostka została przeniesiona do stanu nieprzytomności zamiast ginąć na miejscu od śmiertelnych obrażeń - Mover una unidad a inconsciente en vez de a muerta - 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 - Egy egység kerüljön eszméletlen állapotba a halott helyett - Imposta un'unità come incosciente invece di morta - ユニットの即死を防止するために、気絶へ移行させます - 인원의 즉사를 방지코자 즉사 대신 기절시킵니다 - 伤者最严重只会立即进入昏迷,而非立即死亡 - 傷者最嚴重只會立即進入昏迷,而非立即死亡 - - - Provides a medical system for both players and AI. - Включает медицинскую систему как для игроков, так и для ботов. - Moduł ten dostarcza system medyczny dla graczy oraz AI. - Proporciona un sistema médico para jugadores e IA. - 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. - Egy orvosi rendszert ad játékosok és AI-k számára. - Fornisce un sistema medico sia per giocatori che IA. - プレイヤーと AI の両方へ医療システムを提供します。 - 의료 시스템을 플레이어 및 인공지능에게 제공합니다. - 医疗系统将同时对玩家与AI发生作用 - 醫療系統將同時對玩家與AI發生作用 + + The probability of a fracture causing wound resulting in a fracture. + La probabilité pour qu'une blessure pouvant causer une fracture en crée effectivement une. + La probabilità che una ferita in grado di causare una frattura, causerà veramente una frattura. + 骨折の原因となる負傷が骨折に至る確率を設定します。 + 骨折导致的伤口再次骨折的可能性。 + Výška šance kdy zranění způsobující zlomeniny skutečně způsobí zlomeninu. + Вероятность перелома при получении соответствующих ран. + Prawdopodobieństwo złamania kości w wyniku rany mogącej powodować złamania. + Yaraya neden olan bir kırığın kırılma olasılığı. + La probabilidad de que una herida que pueda provocar una fractura, provoque una fractura. + Die Wahrscheinlichkeit, dass eine Wunde, die eine Fraktur verursachen würde, tatsächlich zu einer Fraktur führt. + 상처를 입을 때 골절에 얼마나 관여할지를 결정합니다. + A probabilidade de uma ferida passível de fratura causar uma fratura. Enabled for @@ -164,6 +285,7 @@ 활성 被启用给 被啟用給 + İçin etkinleştirildi Select what units the advanced medical system will be enabled for @@ -173,13 +295,14 @@ 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 - 選択されたユニットが、アドバンスド医療が使えるようになります + Seleziona per quali unità verrà abilitato il sistema medico avanzato + 選択されたユニットが、高度な医療システムを使えるようになります 어느 인원에게 고급 의료 시스템을 적용시킬지 선택하십시요. - 选择进阶医疗系统影响的对象 + 选择进阶医疗系统影响的物体 選擇進階醫療系統影響的對象 + Gelişmiş tıbbi sistemin hangi üniteler için etkinleştirileceğini seçin Players only @@ -189,13 +312,14 @@ Nur Spieler Pouze hráči Somente jogadores - Joueur uniquement + Joueurs uniquement Csak játékosok Solo giocatori プレイヤーのみ 플레이어만 只限玩家 只限玩家 + Sadece oyuncular Players and AI @@ -208,10 +332,11 @@ Joueurs et IA Játékosok és AI Giocatori ed IA - プレイヤーと AI + プレイヤーとAI 플레이어 및 인공지능 - 玩家与AI + 玩家与 AI 玩家與AI + Oyuncular ve AI Vehicle Crashes @@ -221,13 +346,14 @@ Fahrzeugunfälle Poškození z kolize Batidas de veículos - Accident en véhicule + Accidents en véhicule Járműbalesetek Schianto Veicoli 車両の衝突 차량 사고 载具碰撞 載具碰撞 + Araç Kazaları Do units take damage from a vehicle crash? @@ -237,55 +363,14 @@ 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? - ユニットは車両の衝突による損傷を受けるようにしますか? + ユニットが車両の衝突による負傷を受けるようにしますか? 차량 사고시 인원들이 부상을 입습니까? - 设定人员是否会因为载具冲撞别的物件而产生伤害? + 设定人员是否会因为载具冲撞别的物体而产生伤害? 設定人員是否會因為載具衝撞別的物件而產生傷害? - - - Heal hitpoints - Heile Trefferpunkte - Lecz hitpointy - Curar puntos de vida - Исцелять части тела - Curar hitpoints - Léčit hitponty - Cura Hitpoints - Soigner les blessures - ヒットポイントの回復 - 체력 회복 - 完整治疗 - 完整治療 - - - Heal fully bandaged hitpoints - Heile verbundene Trefferpunkte - Po bandażowaniu ulecz hitpointy, usuwając z nich ślady krwi i przywracając im pełną sprawność. - Curar miembros totalmente vendados - Исцелять полностью перебинтованные части тела - Curar totalmente hitpoints enfaixados - Heal fully bandaged hitpoints - Cura Hitpoints completamente bendati - Soigner les plaies entièrement bandées. - 包帯によりヒットポイントを完全に回復する - 붕대를 감아서 체력을 회복 - - - Configure the treatment settings from ACE Basic Medical - 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 - Configura le impostazioni trattamenti per ACE Medical di base - Configura as opções de tratamento do sistema médico básico do ACE - Настройка лечения в базовой медицинской системе ACE - ACE ベーシック医療による設定で、治療を設定する - ACE 기본 의료에 대한 치료 설정 수정 - 设定ACE基本医疗的规则 - 設定ACE基本醫療的規則 + Birimler bir araç kazasından hasar alır mı? Anytime @@ -302,6 +387,7 @@ 언제나 任何时间 任何時間 + Her Zaman Stable @@ -314,10 +400,11 @@ Estável После стабилизации Stabile - 安静下 + 安定下 안정된 稳定状态下 穩定狀態下 + Dengeli Medical @@ -330,10 +417,11 @@ Медик Médico Orvosi - 治療 + 医療 의료 医疗设定 醫療設定 + Medikal Distance to %1 has become too far for treatment @@ -343,34 +431,45 @@ A distância de %1 está muito longe para tratamento La distancia hasta %1 se ha agrandado demasiado para el tratamiento %1 je příliš daleko, léčba není možná - Distanza da %1 è diventata troppo alta per permettere trattamento - %1 est trop loin pour être soigné - %1 は治療をできない所まで離れた + Distanza da %1 è diventata troppo alta per permettere trattamenti + %1 est trop loin pour être soigné. + %1 は離れすぎていて治療出来ない %1 부터의 거리가 너무 멀어 치료할 수 없습니다 设定当距离超过%1将不能使用治疗动作 設定當距離超過%1將不能使用治療動作 + % 1'e olan mesafe tedavi için çok uzak Open lid Deckel aufklappen フタを開ける - Apri lid + Apri coperchio 打開蓋子 打开盖子 뚜껑 열기 Otwórz pokrywę Открыть крышку + Ouvrir le couvercle + Abrir Tampa + Otevřít víko + Abrir tapa + Açık Gözkapağı Close lid Deckel zuklappen フタを閉める - Chiudi lid + Chiudi coperchio 關閉蓋子 关闭盖子 뚜껑 닫기 Zamknij pokrywę Закрыть крышку + Fermer le couvercle + Fechar Tampa + Zavřít víko + Cerrar tapa + Kapalı Gözkapağı diff --git a/addons/medical_ai/CfgEventHandlers.hpp b/addons/medical_ai/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/medical_ai/CfgEventHandlers.hpp +++ b/addons/medical_ai/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_ai/README.md b/addons/medical_ai/README.md index db0073b208..689c18a031 100644 --- a/addons/medical_ai/README.md +++ b/addons/medical_ai/README.md @@ -3,8 +3,3 @@ ace_medical_ai Makes AI units heal themselves and each other. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [BaerMitUmlaut](https://github.com/BaerMitUmlaut) diff --git a/addons/medical_ai/XEH_PREP.hpp b/addons/medical_ai/XEH_PREP.hpp index 9300f0cbb3..de4ac3c38a 100644 --- a/addons/medical_ai/XEH_PREP.hpp +++ b/addons/medical_ai/XEH_PREP.hpp @@ -4,6 +4,7 @@ PREP(healSelf); PREP(healUnit); PREP(isInjured); PREP(isSafe); +PREP(itemCheck); PREP(playTreatmentAnim); PREP(requestMedic); PREP(wasRequested); diff --git a/addons/medical_ai/XEH_postInit.sqf b/addons/medical_ai/XEH_postInit.sqf index d8676e9695..0b225c7f0b 100644 --- a/addons/medical_ai/XEH_postInit.sqf +++ b/addons/medical_ai/XEH_postInit.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" -["ace_settingsInitialized", { - TRACE_1("settingsInitialized", GVAR(enabledFor)); +["CBA_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 @@ -9,6 +9,16 @@ _unit setVariable [QGVAR(lastFired), CBA_missionTime]; }] call CBA_fnc_addEventHandler; - #include "stateMachine.sqf" -}] call CBA_fnc_addEventHandler; + ["CAManBase", "Hit", { + params ["_unit"]; + _unit setVariable [QGVAR(lastHit), CBA_missionTime]; + }] call CBA_fnc_addClassEventHandler; + ["CAManBase", "Suppressed", { + params ["_unit"]; + _unit setVariable [QGVAR(lastSuppressed), CBA_missionTime]; + }] call CBA_fnc_addClassEventHandler; + + #include "stateMachine.inc.sqf" + +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_ai/XEH_preInit.sqf b/addons/medical_ai/XEH_preInit.sqf index 9361d05015..5725d1e119 100644 --- a/addons/medical_ai/XEH_preInit.sqf +++ b/addons/medical_ai/XEH_preInit.sqf @@ -6,6 +6,13 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +// default time values for AI being ready to heal, used in fnc_isSafe +if (isNil QGVAR(timeSafe_shoot)) then { GVAR(timeSafe_shoot) = 30; }; +if (isNil QGVAR(timeSafe_hit)) then { GVAR(timeSafe_hit) = 30; }; +if (isNil QGVAR(timeSafe_suppressed)) then { GVAR(timeSafe_suppressed) = 30; }; + +GVAR(itemHash) = uinamespace getVariable QGVAR(itemHash); ADDON = true; diff --git a/addons/medical_ai/XEH_preStart.sqf b/addons/medical_ai/XEH_preStart.sqf index 022888575e..b4d795cbbf 100644 --- a/addons/medical_ai/XEH_preStart.sqf +++ b/addons/medical_ai/XEH_preStart.sqf @@ -1,3 +1,27 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + + +private _itemHash = createHashMap; +// key is Treatment Type (prefix @ represents a group of treatments) +// value is hash of item/treatment pairs +{ + _x params ["_itemType", "_treatments"]; + private _typeHash = createHashMap; + { + private _items = getArray (configFile >> "ace_medical_treatment_actions" >> _x >> "items"); + if (_items isEqualTo []) then { ERROR_1("bad action %1",_x); }; + private _itemClassname = configName (configFile >> "CfgWeapons" >> _items # 0); + private _treatment = ["", _x] select ((count _treatments) > 1); + _typeHash set [_itemClassname, _treatment]; + } forEach _treatments; + _itemHash set [_itemType, _typeHash]; +} forEach [ + ["@bandage", ["FieldDressing", "PackingBandage", "ElasticBandage", "QuikClot"]], + ["@iv", ["SalineIV", "SalineIV_500", "SalineIV_250", "BloodIV", "BloodIV_500", "BloodIV_250", "PlasmaIV", "PlasmaIV_500", "PlasmaIV_250"]], + ["splint", ["splint"]], + ["morphine", ["morphine"]], + ["epinephrine", ["epinephrine"]] +]; +uinamespace setVariable [QGVAR(itemHash), compileFinal _itemHash]; diff --git a/addons/medical_ai/addon.toml b/addons/medical_ai/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_ai/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_ai/config.cpp b/addons/medical_ai/config.cpp index c42fc98f95..62a387cc05 100644 --- a/addons/medical_ai/config.cpp +++ b/addons/medical_ai/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -16,3 +24,5 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" + +#endif diff --git a/addons/medical_ai/functions/fnc_canRequestMedic.sqf b/addons/medical_ai/functions/fnc_canRequestMedic.sqf index c2a29c1c9f..685bd57f54 100644 --- a/addons/medical_ai/functions/fnc_canRequestMedic.sqf +++ b/addons/medical_ai/functions/fnc_canRequestMedic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if there is a medic available in the unit's group. @@ -19,7 +19,8 @@ // we ignore this here. We need to "notice" the medic that he should // treat other units, or else he won't do anything on his own. -if ([_this] call EFUNC(medical_treatment,isMedic) || {vehicle _this != _this}) exitWith {false}; +private _isMedic = [_this] call EFUNC(medical_treatment,isMedic); +if (_isMedic && {!IS_UNCONSCIOUS(_this)} || {vehicle _this != _this}) exitWith {false}; // Search for a medic, prioritize unitReady private _medic = objNull; diff --git a/addons/medical_ai/functions/fnc_healSelf.sqf b/addons/medical_ai/functions/fnc_healSelf.sqf index 524625f3c3..5747637995 100644 --- a/addons/medical_ai/functions/fnc_healSelf.sqf +++ b/addons/medical_ai/functions/fnc_healSelf.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Makes the unit heal itself. diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index 158de90f36..ad867d2570 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Makes a medic heal the next unit that needs treatment. diff --git a/addons/medical_ai/functions/fnc_healingLogic.sqf b/addons/medical_ai/functions/fnc_healingLogic.sqf index d2beec1a2d..fa35b49284 100644 --- a/addons/medical_ai/functions/fnc_healingLogic.sqf +++ b/addons/medical_ai/functions/fnc_healingLogic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, PabstMirror * Applies healing to target @@ -17,13 +17,19 @@ */ params ["_healer", "_target"]; -(_healer getVariable [QGVAR(currentTreatment), [-1]]) params ["_finishTime", "_treatmentTarget", "_treatmentEvent", "_treatmentArgs"]; +(_healer getVariable [QGVAR(currentTreatment), [-1]]) params ["_finishTime", "_treatmentTarget", "_treatmentEvent", "_treatmentArgs", "_treatmentItem"]; // 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); + TRACE_5("treatment finished",_finishTime,_treatmentTarget,_treatmentEvent,_treatmentArgs,_treatmentItem); _healer setVariable [QGVAR(currentTreatment), nil]; + if ((GVAR(requireItems) > 0) && {_treatmentItem != ""}) then { + ([_healer, _treatmentItem] call FUNC(itemCheck)) params ["_itemOk", "_itemClassname", "_treatmentClass"]; + if (!_itemOk) exitWith { _treatmentEvent = "#fail"; }; // no item after delay + _healer removeItem _itemClassname; + if (_treatmentClass != "") then { _treatmentArgs set [2, _treatmentClass]; }; + }; if ((_treatmentTarget == _target) && {(_treatmentEvent select [0, 1]) != "#"}) then { [_treatmentEvent, _treatmentArgs, _target] call CBA_fnc_targetEvent; #ifdef DEBUG_MODE_FULL @@ -41,42 +47,65 @@ private _fractures = GET_FRACTURES(_target); private _treatmentEvent = "#none"; private _treatmentArgs = []; private _treatmentTime = 6; +private _treatmentItem = ""; switch (true) do { - case (GET_WOUND_BLEEDING(_target) > 0): { + case ((GET_WOUND_BLEEDING(_target) > 0) + && {([_healer, "@bandage"] call FUNC(itemCheck)) # 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; + private _foundBleeding = _y findIf { + _x params ["", "_amount", "_percentage"]; + (_amount * _percentage) > 0 + }; + if (_foundBleeding != -1) exitWith { _selection = _x; }; + } forEach GET_OPEN_WOUNDS(_target); _treatmentEvent = QEGVAR(medical_treatment,bandageLocal); _treatmentTime = 5; _treatmentArgs = [_target, _selection, "FieldDressing"]; + _treatmentItem = "@bandage"; }; - case (_isMedic && {GET_BLOOD_VOLUME(_target) < BLOOD_VOLUME_CLASS_2_HEMORRHAGE}): { - private _bloodBags = _target getVariable [QEGVAR(medical,ivBags), []]; - if ((count _bloodBags) >= 2) exitWith { + case (IN_CRDC_ARRST(_target) && {EGVAR(medical_treatment,cprSuccessChanceMin) > 0}): { + _treatmentEvent = QEGVAR(medical_treatment,cprLocal); + _treatmentArgs = [_healer, _target]; + _treatmentTime = 15; + }; + case (_isMedic && {GET_BLOOD_VOLUME(_target) < MINIMUM_BLOOD_FOR_STABLE_VITALS} + && {([_healer, "@iv"] call FUNC(itemCheck)) # 0}): { + // Check if patient's blood volume + remaining IV volume is enough to allow the patient to wake up + private _totalIvVolume = 0; //in ml + { + _x params ["_volumeRemaining"]; + _totalIvVolume = _totalIvVolume + _volumeRemaining; + } forEach (_target getVariable [QEGVAR(medical,ivBags), []]); + + if (GET_BLOOD_VOLUME(_target) + (_totalIvVolume / 1000) > MINIMUM_BLOOD_FOR_STABLE_VITALS) exitWith { _treatmentEvent = "#waitForBlood"; }; _treatmentEvent = QEGVAR(medical_treatment,ivBagLocal); _treatmentTime = 5; _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "SalineIV"]; + _treatmentItem = "@iv"; }; case ((count (_target getVariable [VAR_MEDICATIONS, []])) >= 6): { _treatmentEvent = "#tooManyMeds"; }; - case ((_fractures select 4) == 1): { + case (((_fractures select 4) == 1) + && {([_healer, "splint"] call FUNC(itemCheck)) # 0}): { _treatmentEvent = QEGVAR(medical_treatment,splintLocal); _treatmentTime = 6; _treatmentArgs = [_healer, _target, "leftleg"]; + _treatmentItem = "splint"; }; - case ((_fractures select 5) == 1): { + case (((_fractures select 5) == 1) + && {([_healer, "splint"] call FUNC(itemCheck)) # 0}): { _treatmentEvent = QEGVAR(medical_treatment,splintLocal); _treatmentTime = 6; _treatmentArgs = [_healer, _target, "rightleg"]; + _treatmentItem = "splint"; }; - case (IS_UNCONSCIOUS(_target) || {_heartRate <= 50}): { + case ((IS_UNCONSCIOUS(_target) || {_heartRate <= 50}) + && {([_healer, "epinephrine"] call FUNC(itemCheck)) # 0}): { if (CBA_missionTime < (_target getVariable [QGVAR(nextEpinephrine), -1])) exitWith { _treatmentEvent = "#waitForEpinephrineToTakeEffect"; }; @@ -87,8 +116,10 @@ switch (true) do { _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); _treatmentTime = 2.5; _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Epinephrine"]; + _treatmentItem = "epinephrine"; }; - case ((GET_PAIN_PERCEIVED(_target) > 0.25) || {_heartRate >= 180}): { + case (((GET_PAIN_PERCEIVED(_target) > 0.25) || {_heartRate >= 180}) + && {([_healer, "morphine"] call FUNC(itemCheck)) # 0}): { if (CBA_missionTime < (_target getVariable [QGVAR(nextMorphine), -1])) exitWith { _treatmentEvent = "#waitForMorphineToTakeEffect"; }; @@ -99,10 +130,11 @@ switch (true) do { _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); _treatmentTime = 2.5; _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Morphine"]; + _treatmentItem = "morphine"; }; }; -_healer setVariable [QGVAR(currentTreatment), [CBA_missionTime + _treatmentTime, _target, _treatmentEvent, _treatmentArgs]]; +_healer setVariable [QGVAR(currentTreatment), [CBA_missionTime + _treatmentTime, _target, _treatmentEvent, _treatmentArgs, _treatmentItem]]; // Play animation if ((_treatmentEvent select [0,1]) != "#") then { diff --git a/addons/medical_ai/functions/fnc_isInjured.sqf b/addons/medical_ai/functions/fnc_isInjured.sqf index d022770f6d..a163a4c808 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if a unit needs treatment. diff --git a/addons/medical_ai/functions/fnc_isSafe.sqf b/addons/medical_ai/functions/fnc_isSafe.sqf index b18adbdc1c..04da058ce0 100644 --- a/addons/medical_ai/functions/fnc_isSafe.sqf +++ b/addons/medical_ai/functions/fnc_isSafe.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if a unit is currently considered safe enough to treat itself. * * Arguments: - * None + * Unit * * Return Value: * Is unit safe enough @@ -15,4 +15,7 @@ * Public: No */ -(getSuppression _this == 0) && {CBA_missionTime - (_this getVariable [QGVAR(lastFired), -30]) > 30} + (CBA_missionTime - (_this getVariable [QGVAR(lastFired), -999999]) > GVAR(timeSafe_shoot)) +&& {CBA_missionTime - (_this getVariable [QGVAR(lastHit), -999999]) > GVAR(timeSafe_hit)} +&& {CBA_missionTime - (_this getVariable [QGVAR(lastSuppressed), -999999]) > GVAR(timeSafe_suppressed)} +&& {!(_this getVariable [QEGVAR(captives,isHandcuffed), false])} diff --git a/addons/medical_ai/functions/fnc_itemCheck.sqf b/addons/medical_ai/functions/fnc_itemCheck.sqf new file mode 100644 index 0000000000..6d91594ce4 --- /dev/null +++ b/addons/medical_ai/functions/fnc_itemCheck.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Checks if AI healer has items + * + * Arguments: + * 0: Healer + * 1: Treatment Type + * + * Return Value: + * 0: Has Item + * 1: Item Classname (Optional) + * 2: Treatment (Optional) + * + * Example: + * [cursorObject, "@bandage"] call ACE_medical_ai_fnc_itemCheck + * + * Public: No + */ + +if (GVAR(requireItems) == 0) exitWith { [true] }; + +params ["_healer", "_treatementType"]; + +private _return = [false]; +private _items = _healer call EFUNC(common,uniqueItems); +private _treatment = GVAR(itemHash) get _treatementType; +{ + if (_x in _items) exitWith { + _return = [true, _x, _y]; + }; +} forEach _treatment; + +_return diff --git a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf index 5b594edae2..b8e77aab43 100644 --- a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf +++ b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Plays the corresponding treatment animation. @@ -19,7 +19,7 @@ params ["_unit", "_actionName", "_isSelfTreatment"]; TRACE_3("playTreatmentAnim",_unit,_actionName,_isSelfTreatment); -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; private _configProperty = "animationMedic"; if (_isSelfTreatment) then { diff --git a/addons/medical_ai/functions/fnc_requestMedic.sqf b/addons/medical_ai/functions/fnc_requestMedic.sqf index 450911c801..9e59181204 100644 --- a/addons/medical_ai/functions/fnc_requestMedic.sqf +++ b/addons/medical_ai/functions/fnc_requestMedic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Sends a request to the units assigned medic to heal it. diff --git a/addons/medical_ai/functions/fnc_wasRequested.sqf b/addons/medical_ai/functions/fnc_wasRequested.sqf index 479dc0c880..3b6c1cf059 100644 --- a/addons/medical_ai/functions/fnc_wasRequested.sqf +++ b/addons/medical_ai/functions/fnc_wasRequested.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit was requested to treat another unit. @@ -16,4 +16,4 @@ */ private _healQueue = _this getVariable [QGVAR(healQueue), []]; -!(_healQueue isEqualTo []) +(_healQueue isNotEqualTo []) diff --git a/addons/medical_ai/functions/script_component.hpp b/addons/medical_ai/functions/script_component.hpp deleted file mode 100644 index e0adc75020..0000000000 --- a/addons/medical_ai/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_ai\script_component.hpp" diff --git a/addons/medical_ai/initSettings.inc.sqf b/addons/medical_ai/initSettings.inc.sqf new file mode 100644 index 0000000000..a2b06519a4 --- /dev/null +++ b/addons/medical_ai/initSettings.inc.sqf @@ -0,0 +1,39 @@ +private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; + +[ + QGVAR(enabledFor), "LIST", + [LLSTRING(enableFor_title), LLSTRING(enableFor_desc)], + _categoryArray, + [ + [0, 1, 2], + [LELSTRING(Common,Disabled), LLSTRING(enabledFor_OnlyServerAndHC), LELSTRING(Common,Enabled)], + 2 + ], + true, // isGlobal + {[QGVAR(enabledFor), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(requireItems), "LIST", + [LSTRING(requireItems_title), LSTRING(requireItems_desc)], + _categoryArray, + [ + [0, 1, 2], + [LELSTRING(Common,Disabled), LELSTRING(Common,Enabled), format ["%1 - %2", LELSTRING(Common,Enabled), LLSTRING(requireItems_autoReplaceItems)]], + 0 + ], + true, // isGlobal + { + if (GVAR(requireItems) != 2) exitWith {}; + ["CAManBase", "initPost", { + [{ + params ["_unit"]; + if ((!local _unit) || {!alive _unit} || {isPlayer _unit}) exitWith {}; + TRACE_2("replacing medical items on AI",_unit,typeOf _unit); + [_unit] call EFUNC(common,replaceRegisteredItems); + }, _this] call CBA_fnc_execNextFrame; // need to delay a frame before modifying items in a backpack + }, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler; + }, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/medical_ai/initSettings.sqf b/addons/medical_ai/initSettings.sqf deleted file mode 100644 index 6fada00db5..0000000000 --- a/addons/medical_ai/initSettings.sqf +++ /dev/null @@ -1,17 +0,0 @@ -// CBA Settings [ADDON: ace_medical_ai]: - -private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; - -[ - QGVAR(enabledFor), "LIST", - [LLSTRING(enableFor_title), LLSTRING(enableFor_desc)], - _categoryArray, - [ - [0, 1, 2], - [LELSTRING(Common,Disabled), LLSTRING(enabledFor_OnlyServerAndHC), LELSTRING(Common,Enabled)], - 2 - ], - 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.inc.sqf b/addons/medical_ai/stateMachine.inc.sqf new file mode 100644 index 0000000000..03483f4981 --- /dev/null +++ b/addons/medical_ai/stateMachine.inc.sqf @@ -0,0 +1,69 @@ +//pragma SKIP_COMPILE - Inline file + +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/stateMachine.sqf b/addons/medical_ai/stateMachine.sqf deleted file mode 100644 index 48d5a6ef8e..0000000000 --- a/addons/medical_ai/stateMachine.sqf +++ /dev/null @@ -1,67 +0,0 @@ -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 13a57f26f3..54f0c2714c 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -1,30 +1,88 @@ - - + + Medic AI Sanitäts KI - AI 衛生兵 + 衛生兵AI ИИ Медик + Médecine IA + IA Médica + AI 医疗兵 + AI醫療兵 + IA Medica + Zdravotnická AI + Medyk AI + Médico para IA + Medikal AI + 인공지능 의무병 - + AI will respond to injury and unconsciousness KI reagiert auf Verletzungen und Bewusstlosigkeit - AI が負傷者と気絶している人に対して行動するようになります。 + AIが負傷者と無意識状態の人に対して行動するようになります。 ИИ будет реагировать на травмы и потерю сознания + Les unités IA seront sensibles aux blessures, ainsi qu'à la perte de connaissance. + A IA irá responder a ferimentos e perdas de consciência + AI 对于受伤及无意识单位会有所反应 + AI對於受傷及無意識單位會有所反應 + L'intelligenza artificiale risponderà a lesioni e perdita di coscienza + UI reaguje na zranění a bezvědomí + AI zareaguje na obrażenia i utratę przytomności + La IA responderá a heridas e inconsciencia + 인공지능이 기절이나 부상에 대응합니다 - + 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 + Pouze Server a HC + Sadece Sunucu ve HC de + + + Require Items + Wymagane Przedmioty + Erfordere Gegenstände + Richiede risorse mediche + 아이템 필요 + Items requis + Exigir Itens + アイテムを要求 + Требуемые предметы + Requerir Objetos + + + AI will only perform medical treatment if they have the necessary items in their inventory. + AI będzie wykonywać zabiegi medyczne tylko wtedy, gdy ma w ekwipunku niezbędne przedmioty. + Die KI führt nur dann medizinische Behandlungen durch, wenn sie die erforderlichen Gegenstände in ihrem Inventar hat. + L'IA effettua trattamenti medici solo se è equipaggiata delle risorse mediche necessarie. + 소지품에 필요한 아이템이 있을 경우에만 인공지능이 치료를 진행합니다. + Les IA n'effectueront un traitement médical que si elles ont le matériel nécessaire dans leur inventaire. + A IA só irá realizar tratamento médico se tiver os itens necessários em seu inventário. + AIのインベントリに必要なアイテムがある場合にのみ治療を実行します。 + Искусственный интеллект будет оказывать медицинскую помощь только в том случае, если в его инвентаре есть необходимые предметы. + La IA sólo realizará el tratamiento médico en caso de que dispongan de los objetos necesarios en su inventario. + + + Auto Convert Items for AI + Automatyczna Konwersja Przedmiotów dla AI + 인공지능 아이템 자동 변환 + Conversion automatique des items pour les IA + Automatische Konvertierung von Gegenständen der KI + Conversione automatica di risorse mediche per IA + Conversão automática de itens para IA + AIのアイテムを自動変換 + Автоматическое преобразование элементов для ИИ + Auto Convertir Objetos para la IA diff --git a/addons/medical_blood/CfgEventHandlers.hpp b/addons/medical_blood/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/medical_blood/CfgEventHandlers.hpp +++ b/addons/medical_blood/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_blood/README.md b/addons/medical_blood/README.md index 848f8f0308..edc127ee0c 100644 --- a/addons/medical_blood/README.md +++ b/addons/medical_blood/README.md @@ -3,9 +3,3 @@ ace_medical_blood Creates blood drops on the ground near bleeding units. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Glowbal](https://github.com/Glowbal) -- [commy2](https://github.com/commy2) diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index 02201f5506..b08921b441 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -1,18 +1,16 @@ #include "script_component.hpp" -GVAR(useAceMedical) = ["ace_medical"] call EFUNC(common,isModLoaded); - // To support public API regardless of component settings -[QGVAR(spurt), FUNC(spurt)] call CBA_fnc_addEventHandler; +[QGVAR(spurt), LINKFUNC(spurt)] call CBA_fnc_addEventHandler; if (isServer) then { GVAR(bloodDrops) = []; [QGVAR(bloodDropCreated), { - params ["_bloodDrop"]; + params ["_bloodDrop", "_source"]; - // Add to created queue with format: [expire time, blood object] - private _index = GVAR(bloodDrops) pushBack [CBA_missionTime + GVAR(bloodLifetime), _bloodDrop]; + // Add to created queue with format: [expire time, blood object, source unit] + private _index = GVAR(bloodDrops) pushBack [CBA_missionTime + GVAR(bloodLifetime), _bloodDrop, _source]; if (count GVAR(bloodDrops) >= GVAR(maxBloodObjects)) then { (GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"]; @@ -21,7 +19,7 @@ if (isServer) then { // Start the cleanup loop if (_index == 0) then { - [FUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; + [LINKFUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; }; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/medical_blood/XEH_preInit.sqf b/addons/medical_blood/XEH_preInit.sqf index ae4de9d026..93da039be5 100644 --- a/addons/medical_blood/XEH_preInit.sqf +++ b/addons/medical_blood/XEH_preInit.sqf @@ -6,21 +6,10 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // blood object model namespace -GVAR(models) = [] call CBA_fnc_createNamespace; - -{ - _x params ["_name", "_model"]; - - // createSimpleObject expects a path without the leading slash - if ((_model select [0,1]) isEqualTo "\") then { - _model = _model select [1]; - }; - - GVAR(models) setVariable [_name, _model]; -} forEach [ +GVAR(models) = createHashMapFromArray [ // higher number means bigger model ["blooddrop_1", QPATHTOF(data\ace_drop_1.p3d)], ["blooddrop_2", QPATHTOF(data\ace_drop_2.p3d)], diff --git a/addons/medical_blood/XEH_preStart.sqf b/addons/medical_blood/XEH_preStart.sqf index 022888575e..e2683ff586 100644 --- a/addons/medical_blood/XEH_preStart.sqf +++ b/addons/medical_blood/XEH_preStart.sqf @@ -1,3 +1,7 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Damage types which do not cause blood spurts +private _noBloodDamageTypes = "getNumber (_x >> 'noBlood') == 1" configClasses (configFile >> "ACE_Medical_Injuries" >> "damageTypes"); +uiNamespace setVariable [QGVAR(noBloodDamageTypes), compileFinal (_noBloodDamageTypes createHashMapFromArray [])]; diff --git a/addons/medical_blood/addon.toml b/addons/medical_blood/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_blood/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_blood/config.cpp b/addons/medical_blood/config.cpp index 3e5d5227da..d5cf4b0088 100644 --- a/addons/medical_blood/config.cpp +++ b/addons/medical_blood/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -16,3 +24,5 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "ACE_Settings.hpp" + +#endif diff --git a/addons/medical_blood/functions/fnc_cleanupLoop.sqf b/addons/medical_blood/functions/fnc_cleanupLoop.sqf index e8461b2e31..92d0a5f3bb 100644 --- a/addons/medical_blood/functions/fnc_cleanupLoop.sqf +++ b/addons/medical_blood/functions/fnc_cleanupLoop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles cleaning up blood objects that have reached the end of their lifetime. diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index e54247d02e..fbff6cc3c6 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Creates a blood object and handles its cleanup. @@ -7,25 +7,26 @@ * Arguments: * 0: Blood Drop Type * 1: Position + * 2: Source * * Return Value: * Blood Drop * * Example: - * ["blooddrop_2", getPos player] call ace_medical_blood_fnc_createBlood + * ["blooddrop_2", getPos player, player] call ace_medical_blood_fnc_createBlood * * Public: No */ -params ["_type", "_position"]; -TRACE_2("Creating blood",_type,_position); +params ["_type", "_position", "_source"]; +TRACE_3("Creating blood",_type,_position,_source); -private _model = GVAR(models) getVariable _type; +private _model = GVAR(models) get _type; private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; _bloodDrop setDir random 360; _bloodDrop setPos _position; -[QGVAR(bloodDropCreated), _bloodDrop] call CBA_fnc_serverEvent; +[QGVAR(bloodDropCreated), [_bloodDrop, _source]] call CBA_fnc_serverEvent; _bloodDrop diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 7447cac52f..53d5d2361b 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" +#include "..\script_component.hpp" /* * Author: Glowbal, commy2 * Handles the wounds received event by triggering any needed blood creation. * * Arguments: * 0: Unit - * 1: Body Part (not used) - * 2: Damage - * 3: Shooter + * 1: Damage done to each body part + * 2: Shooter + * 3: Ammo classname or damage type * * Return Value: * None @@ -18,13 +18,17 @@ * Public: No */ -params ["_unit", "", "_damage", "_shooter"]; +params ["_unit", "_allDamages", "_shooter", "_damageType"]; +(_allDamages select 0) params ["_damage"]; + +// Don't bleed if damage type does not cause bleeding +if (_damageType in (uiNamespace getVariable QGVAR(noBloodDamageTypes))) exitWith {}; // Don't bleed when players only and a non-player unit is wounded if (GVAR(enabledFor) == BLOOD_ONLY_PLAYERS && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; // Don't bleed on the ground if in a vehicle -if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; +if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; private _bulletDir = if (isNull _shooter) then { random 360 // Cannot calculate the direction properly, pick a random direction diff --git a/addons/medical_blood/functions/fnc_init.sqf b/addons/medical_blood/functions/fnc_init.sqf index 336d964de7..6392a6e451 100644 --- a/addons/medical_blood/functions/fnc_init.sqf +++ b/addons/medical_blood/functions/fnc_init.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Initializes the medical blood system based on the given mode. @@ -60,6 +60,6 @@ private _listCode = if (_mode == BLOOD_ONLY_PLAYERS) then { GVAR(stateMachine) = [_listCode, true] call CBA_statemachine_fnc_create; [GVAR(stateMachine), LINKFUNC(onBleeding), {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; -GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; +GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), LINKFUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; TRACE_3("Set up state machine and wounds event",_mode,GVAR(stateMachine),GVAR(woundReceivedEH)); diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf index 14aecbb55b..a21a50913a 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks if the given unit is bleeding. Handles both ACE Medical and Vanilla. @@ -17,7 +17,7 @@ params ["_unit"]; -if (GVAR(useAceMedical)) exitWith { +if (GETEGVAR(medical,enabled,false)) exitWith { IS_BLEEDING(_unit); }; diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 8b6bcbb8f6..4963aaa21d 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Handles periodically creating blood for a bleeding unit. @@ -22,10 +22,10 @@ params ["_unit"]; if !(_unit call FUNC(isBleeding)) exitWith {}; // Don't bleed on the ground if in a vehicle -if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; +if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; if (CBA_missionTime > (_unit getVariable [QGVAR(nextTime), -10])) then { - private _bloodLoss = (if (GVAR(useAceMedical)) then {GET_BLOOD_LOSS(_unit) * 2.5} else {getDammage _unit * 2}) min 6; + private _bloodLoss = ([damage _unit * 2, GET_BLOOD_LOSS(_unit) * 2.5] select GETEGVAR(medical,enabled,false)) min 6; _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); @@ -35,5 +35,5 @@ if (CBA_missionTime > (_unit getVariable [QGVAR(nextTime), -10])) then { _position set [2, 0]; private _bloodDrop = ["blooddrop_1", "blooddrop_2", "blooddrop_3", "blooddrop_4"] select floor (_bloodLoss min 3); - [_bloodDrop, _position] call FUNC(createBlood); + [_bloodDrop, _position, _unit] call FUNC(createBlood); }; diff --git a/addons/medical_blood/functions/fnc_spurt.sqf b/addons/medical_blood/functions/fnc_spurt.sqf index fd5c7a9fc0..ab2be414b5 100644 --- a/addons/medical_blood/functions/fnc_spurt.sqf +++ b/addons/medical_blood/functions/fnc_spurt.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Sickboy * Spurts blood on the ground based on the direction and damage. @@ -27,7 +27,7 @@ private _distanceBetweenDrops = DISTANCE_BETWEEN_DROPS * _damage; private _offset = OFFSET + _distanceBetweenDrops; private _position = _unit getPos [_offset, _direction]; -["blooddrop_2", _position, _direction] call FUNC(createBlood); +["blooddrop_2", _position, _unit] call FUNC(createBlood); private _dropAmount = ceil (MAXIMUM_DROPS * _damage); TRACE_2("Spurting blood",_dropAmount,_damage); @@ -35,6 +35,6 @@ TRACE_2("Spurting blood",_dropAmount,_damage); if (_dropAmount > 1) then { for "_i" from 2 to _dropAmount do { _position = _position getPos [_distanceBetweenDrops, _direction]; - ["blooddrop_1", _position, _direction] call FUNC(createBlood); + ["blooddrop_1", _position, _unit] call FUNC(createBlood); }; }; diff --git a/addons/medical_blood/functions/script_component.hpp b/addons/medical_blood/functions/script_component.hpp deleted file mode 100644 index 8f2dd066de..0000000000 --- a/addons/medical_blood/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_blood\script_component.hpp" diff --git a/addons/medical_blood/initSettings.inc.sqf b/addons/medical_blood/initSettings.inc.sqf new file mode 100644 index 0000000000..c4ad57d4d7 --- /dev/null +++ b/addons/medical_blood/initSettings.inc.sqf @@ -0,0 +1,27 @@ +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(bloodLifetime), + "TIME", + [LSTRING(BloodLifetime_DisplayName), LSTRING(BloodLifetime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [1, 3600, 900], + true +] call CBA_fnc_addSetting; diff --git a/addons/medical_blood/initSettings.sqf b/addons/medical_blood/initSettings.sqf deleted file mode 100644 index c2c52f93b8..0000000000 --- a/addons/medical_blood/initSettings.sqf +++ /dev/null @@ -1,27 +0,0 @@ -[ - 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(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/stringtable.xml b/addons/medical_blood/stringtable.xml index 1186a01ee6..a63de99ea0 100644 --- a/addons/medical_blood/stringtable.xml +++ b/addons/medical_blood/stringtable.xml @@ -13,6 +13,9 @@ Sangue 혈흔 血痕 + 血迹 + 血跡 + Kan Enable Blood Drops @@ -20,31 +23,95 @@ Aktiviere Blutspritzer 피흘리기 활성화 Włącz ślady krwi na ziemi - Active les gouttes de sang - Abilita Perdite di Sangue + Activer les gouttes de sang + Abilita Chiazze di Sangue 开启血液滴落效果 開啟血液滴落效果 Разрешить капли крови + Permitir gotas de sangue + Povolit kapky krve + Habilitar manchas de sangre + Kan Damlalarıı Etkinleştir 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. + 当单位失血或受伤的时,启用出血效果。 + 啟用出血效果當單位失血或受傷的時候。 + Povoluje vytváření kapek krve na zemi když jednotka krvácí nebo utrpí zranění. + Umożliwia tworzenie śladów krwi, gdy jednostki krwawią lub otrzymują obrażenia. + Habilita la creación de sangrecuando la unidad está sangrando o recibe daño + Kişiler kanarken veya hasar alırken kan damlası oluşumunu sağlar. + Abilita la formazione di chiazze di sangue quando un'unità sta sanguinando o viene ferita. + Ermöglicht das Erstellen von Blutstropfen, wenn Einheiten am Bluten sind oder Schaden nehmen. + 출혈이나 부상 시 핏자국이 생기는것을 활성화합니다. Max Blood Objects - 最大血痕数 + 血痕最大数 + Quantité de sang à afficher + Макс. кол-во капель крови + Limite de objetos de sangue + 最大血迹数 + 最大血跡數 + Massimo numero di chiazze di sangue + Maximum objektů krve + Maksymalna ilość śladów krwi + Máxima cantidad de objetos de sangre + Maksimum Kan Objeleri + Maximale Anzahl an Blutstropfen-Objekten + 최대 피의 양 Sets the maximum number of blood drop objects which can be spawned, excessive amounts can cause FPS lag. - 生成される血痕オブジェクト数を設定できます。極端に増やすと FPS ラグを引き起こします。 + 生成される血痕オブジェクト数を設定できます。極端に設定すると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. + 设置最大可存在的血迹数量。过量会导致帧数低下或卡顿 + 設定最大可存在的血跡數量。太極端的數量會導致幀數低落或卡頓 + Imposta il numero massimo di chiazze di sangue che possono essere generate, quantità eccessive possono causare lag di FPS. + Nastavuje maximum objektů krve na zemi, příliš mnoho může způsobit pokles FPS + Definiuje maksymalną ilość śladów krwi, które mogą zostać stworzone, nadmierne ilości mogą powodować spadki FPS. + Fija el límite de objetos de sangre que aparecerán, cantidades excesivas pueden causar caídas de FPS + Ortaya çıkabilecek maksimum kan damlası sayısını ayarlar, aşırı miktarlar FPS düşmesine neden olabilir. + Legt die maximale Anzahl an Blutstropfen-Objekten fest, die erscheinen können. Eine zu hoch eingestellte Anzahl kann Lags verursachen. + 스폰되는 피의 최대량을 결정합니다. 너무 많은 양은 FPS 랙이 생길 수 있습니다. Blood Lifetime 血痕の寿命 + Durée d'affichage du sang + Время жизни капель крови + Duração do Sangue + 血迹时长 + 血跡時長 + Durata del sangue + Životnost krve + Czas trwania śladów krwi + Duración de la sangre + Kan Ömrü + Anzeigedauer der Blutstropfen + 피 잔존기간 Controls the lifetime of blood drop objects. - 血痕オブジェクトの寿命を決定します。 + 血痕オブジェクトの寿命を制御します。 + Définit la durée d'affichage des traces de sang. + Управляет временем жизни объектов капель крови. + Controla o tempo de vida que um objeto de gota de sangue tem. + 控制血迹在地上的时长 + 控制血跡在地上的時長 + Controlla la durata di permanenza delle chiazze di sangue. + Nastavuje jak dlouho objekty krve na zemi vydrží. + Kontroluje czas trwania śladów krwi. + Controla el tiempo de vida que tendrán los objetos de sangre + Kan objelerinin silinme süresini belirler. + Kontrolliert die Anzeigedauer der Blutstropfen-Objekte. + 떨어진 피의 잔존 기간을 정합니다. Only Players @@ -54,9 +121,13 @@ Tylko gracze Joueurs seulement Solo Giocatori - 只有玩家 + 仅玩家 只有玩家 Только игроки + Apenas Jogadores + Pouze hráči + Solo jugadores + Sadece Oyuncular diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index 4dfc066993..e3ffb7bfde 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -7,126 +7,312 @@ class ACE_Medical_Injuries { // Source: Scarle // Also called scrapes, they occur when the skin is rubbed away by friction against another rough surface (e.g. rope burns and skinned knees). class Abrasion { - causes[] = {"falling", "ropeburn", "vehiclecrash", "collision", "unknown"}; bleeding = 0.001; pain = 0.4; - minDamage = 0.01; - maxDamage = 0.30; }; // 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.1; pain = 1.0; - minDamage = 0.01; causeLimping = 1; }; // 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; pain = 0.3; - minDamage = 0.02; - maxDamage = 0.35; }; // Occur when a heavy object falls onto a person, splitting the skin and shattering or tearing underlying structures. class Crush { - causes[] = {"falling", "vehiclecrash", "collision", "punch", "unknown"}; bleeding = 0.05; 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.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; - minDamage = 0.01; }; // 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.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 { - causes[] = {"stab", "grenade"}; bleeding = 0.05; pain = 0.4; - minDamage = 0.02; causeLimping = 1; }; + // Pain wound that is caused by making or being in contact with heat + class ThermalBurn { + bleeding = 0; + pain = 0.7; + minDamage = 0; + }; }; + class damageTypes { - // thresholds[] {{, }, {...}} + // thresholds[] {{, }, {...}} + // if damage is between two points, number is interpolated and then rounded by chance based on the decimal part + // e.g. a value of 2.7 has 70% chance to give 3 and 30% to give 2 + // put damage values in descending order; uses the first value found that is below the wound damage, and the point immediately before that thresholds[] = {{0.1, 1}}; + + // if 1, wounds are only applied to the hitpoint that took the most damage. othewrise, wounds are applied to all damaged hitpoints selectionSpecific = 1; + // list of damage handlers, which will be called in reverse order + // each entry should be a SQF expression that returns a function + // this can also be overridden for each damage type + class woundHandlers { + ADDON = QFUNC(woundsHandlerBase); + }; + class bullet { - // above damage, amount. Put the highest threshold to the left and lower the threshold with the elements to the right of it. - thresholds[] = {{0.1, 1}}; + // bullets only create multiple wounds when the damage is very high + thresholds[] = {{20, 10}, {4.5, 2}, {3, 1}, {0, 1}}; selectionSpecific = 1; + + class Avulsion { + // at damage, weight. between points, weight is interpolated then wound is chosen by weighted random. + // as with thresholds, but result is not rounded (decimal values used as-is) + weighting[] = {{1, 1}, {0.35, 0}}; + /* + damageMultiplier = 1; + sizeMultiplier = 1; + bleedingMultiplier = 1; + painMultiplier = 1; + fractureMultiplier = 1; + */ + }; + class Contusion { + weighting[] = {{0.35, 0}, {0.35, 1}}; + // bruises caused by bullets hitting the plate are big + sizeMultiplier = 3.2; + // increase the pain to allow for bruises to actually knock out on repeated hits + painMultiplier = 2.2; + }; + class VelocityWound { + // velocity wounds are only in the 0.35-1.5 range + weighting[] = {{1.5, 0}, {1.5, 1}, {0.35, 1}, {0.35, 0}}; + // velocity wounds will tend to be medium or large + sizeMultiplier = 0.9; + }; }; class grenade { - thresholds[] = {{0.1, 3}, {0, 1}}; + // at low damage numbers, chance to create no wounds - makes it a bit more random instead of consistently covering people in bruises + thresholds[] = {{20, 10}, {10, 5}, {4, 3}, {1.5, 2}, {0.8, 2}, {0.3, 1}, {0, 0}}; selectionSpecific = 0; + class Avulsion { + weighting[] = {{1.5, 1}, {1.1, 0}}; + }; + class VelocityWound { + weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}}; + }; + class PunctureWound { + weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}}; + }; + class Cut { + weighting[] = {{0.7, 0}, {0.35, 1}, {0.35, 0}}; + }; + class Contusion { + weighting[] = {{0.5, 0}, {0.35, 1}}; + sizeMultiplier = 2; + painMultiplier = 0.9; + }; }; class explosive { - thresholds[] = {{1, 6}, {0.1, 4}, {0, 1}}; + // explosives create more and smaller wounds than grenades + thresholds[] = {{20, 15}, {8, 7}, {2, 3}, {1.2, 2}, {0.4, 1}, {0,0}}; selectionSpecific = 0; + class Avulsion { + weighting[] = {{1, 1}, {0.8, 0}}; + }; + class Cut { + weighting[] = {{1.5, 0}, {0.35, 1}, {0, 0}}; + }; + class Contusion { + weighting[] = {{0.5, 0}, {0.35, 1}}; + sizeMultiplier = 2; + painMultiplier = 0.9; + }; }; class shell { - thresholds[] = {{1, 7}, {0.1, 5}, {0, 1}}; + // shells tend to involve big pieces of shrapnel, so create fewer and larger wounds + thresholds[] = {{20, 10}, {10, 5}, {4.5, 2}, {2, 2}, {0.8, 1}, {0.2, 1}, {0, 0}}; selectionSpecific = 0; + class Avulsion { + weighting[] = {{1.5, 1}, {1.1, 0}}; + }; + class VelocityWound { + weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}}; + }; + class PunctureWound { + weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}}; + }; + class Cut { + weighting[] = {{0.7, 0}, {0.35, 1}, {0.35, 0}}; + }; + class Contusion { + weighting[] = {{0.5, 0}, {0.35, 1}}; + sizeMultiplier = 2; + painMultiplier = 0.9; + }; + }; + class vehiclehit: explosive { + // vehicle explosions are usually caused by explosive damage and should behave similarly + thresholds[] = {{6, 3}, {4.5, 2}, {2, 2}, {0.8, 1}, {0.2, 1}, {0, 0}}; + class woundHandlers: woundHandlers { + GVAR(vehiclehit) = QFUNC(woundsHandlerVehiclehit); + }; }; class vehiclecrash { - thresholds[] = {{0.5, 5}, {0.3, 2}, {0.05, 1}}; + thresholds[] = {{1.5, 3}, {1.5, 2}, {1, 2}, {1, 1}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; + class woundHandlers: woundHandlers { + GVAR(vehiclecrash) = QFUNC(woundsHandlerVehiclecrash); + }; + class Abrasion { + weighting[] = {{0.30, 0}, {0.30, 1}}; + }; + class Avulsion { + weighting[] = {{0.01, 1}, {0.01, 0}}; + }; + class Contusion { + weighting[] = {{0.35, 0}, {0.35, 1}}; + }; + class Crush { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + class Cut { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + class Laceration { + + }; }; class collision { - thresholds[] = {{0.5, 5}, {0.3, 2}, {0.05, 1}}; + thresholds[] = {{8, 4}, {1, 1}, {0.3, 1}, {0.15, 0.5}, {0, 0.3}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; - }; - class backblast { - thresholds[] = {{1, 6}, {0.55, 5}, {0, 2}}; - selectionSpecific = 0; - }; - class stab { - thresholds[] = {{0.1, 1}}; - selectionSpecific = 1; - }; - class punch { - thresholds[] = {{0.1, 1}}; - selectionSpecific = 1; + class Avulsion { + weighting[] = {{1, 2}, {0.5, 0.5}, {0.5, 0}}; + }; + class Abrasion { + weighting[] = {{0.4, 0}, {0.2, 1}, {0, 0}}; + }; + class Contusion { + weighting[] = {{0.4, 0}, {0.2, 1}}; + }; + class Crush { + weighting[] = {{0.4, 1}, {0.2, 0}}; + }; + class Cut { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + class Laceration { + }; }; class falling { - thresholds[] = {{0.6, 4}, {0.35, 2}, {0.1, 1}}; + thresholds[] = {{8, 4}, {1, 1}, {0.2, 1}, {0.1, 0.7}, {0, 0.5}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered + selectionSpecific = 0; + class Abrasion { + weighting[] = {{0.4, 0}, {0.2, 1}, {0, 0}}; + sizeMultiplier = 3; + }; + class Contusion { + weighting[] = {{0.4, 0}, {0.2, 1}}; + sizeMultiplier = 3; + }; + class Crush { + weighting[] = {{0.4, 1}, {0.2, 0}}; + sizeMultiplier = 1.5; + }; + }; + class backblast { + thresholds[] = {{1, 6}, {1, 5}, {0.55, 5}, {0.55, 2}, {0, 2}}; + selectionSpecific = 0; + class Avulsion { + weighting[] = {{0.30, 0}, {0.30, 1}}; + }; + class Contusion { + weighting[] = {{0.35, 0}, {0.35, 1}}; + }; + class Cut { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + }; + class stab { + thresholds[] = {{0.1, 1}, {0.1, 0}}; selectionSpecific = 1; + class Cut { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + class PunctureWound { + weighting[] = {{0.02, 1}, {0.02, 0}}; + }; + }; + class punch { + thresholds[] = {{0.1, 1}, {0.1, 0}}; + selectionSpecific = 1; + class Contusion { + weighting[] = {{0.35, 0}, {0.35, 1}}; + }; + class Crush { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + class Laceration { + + }; }; class ropeburn { - thresholds[] = {{0.1, 1}}; + thresholds[] = {{0.1, 1}, {0.1, 0}}; selectionSpecific = 1; + noBlood = 1; + class Abrasion { + weighting[] = {{0.30, 1}}; + }; }; - //No related wounds as drowning should not cause wounds/bleeding. Can be extended for internal injuries if they are added. class drowning { + //No related wounds as drowning should not cause wounds/bleeding. Can be extended for internal injuries if they are added. thresholds[] = {{0, 0}}; + noBlood = 1; + class woundHandlers {}; + }; + class fire { + noBlood = 1; + // custom handling for environmental fire sources + // passes damage to "burn" so doesn't need its own wound stats + class woundHandlers { + ADDON = QFUNC(woundsHandlerBurning); + }; + }; + class burn { + thresholds[] = {{0, 1}}; + selectionSpecific = 0; + noBlood = 1; + class ThermalBurn { + weighting[] = {{0, 1}}; + }; }; class unknown { - thresholds[] = {{0.1, 1}}; + thresholds[] = {{0.1, 1}, {0.1, 0}}; + class Abrasion { + weighting[] = {{0.30, 0}, {0.30, 1}}; + }; + class Cut { + weighting[] = {{0.1, 1}, {0.1, 0}}; + }; + class VelocityWound { + weighting[] = {{0.35, 1}, {0.35, 0}}; + }; }; }; }; diff --git a/addons/medical_damage/CfgAmmo.hpp b/addons/medical_damage/CfgAmmo.hpp new file mode 100644 index 0000000000..7ef0834161 --- /dev/null +++ b/addons/medical_damage/CfgAmmo.hpp @@ -0,0 +1,93 @@ +class CfgAmmo { + class BulletCore; + class BulletBase: BulletCore { + ACE_damageType = "bullet"; + }; + class ShotgunCore; + class ShotgunBase: ShotgunCore { + ACE_damageType = "bullet"; + }; + + class Default; + class FuelExplosion: Default { + ACE_damageType = "explosive"; + }; + class Grenade: Default { + ACE_damageType = "grenade"; + }; + class GrenadeCore; + class GrenadeBase: GrenadeCore { + ACE_damageType = "grenade"; + }; + + class MineCore; + class MineBase: MineCore { + ACE_damageType = "explosive"; + }; + class PipeBombCore; + class PipeBombBase: PipeBombCore { + ACE_damageType = "explosive"; + }; + class DirectionalBombCore; + class DirectionalBombBase: DirectionalBombCore { + ACE_damageType = "explosive"; + }; + class BoundingMineCore; + class BoundingMineBase: BoundingMineCore { + ACE_damageType = "explosive"; + }; + + class RocketCore; + class RocketBase: RocketCore { + ACE_damageType = "explosive"; + }; + class MissileCore; + class MissileBase: MissileCore { + ACE_damageType = "explosive"; + }; + + class SubmunitionCore; + class SubmunitionBase: SubmunitionCore { + ACE_damageType = "explosive"; + }; + class SubmunitionBullet: SubmunitionBase { + ACE_damageType = "bullet"; + }; + + class ShellCore; + class ShellBase: ShellCore { + ACE_damageType = "shell"; + }; + + // There is no BombBase so we modify these separately + class BombCore; + class Bo_Mk82: BombCore { + ACE_damageType = "explosive"; + }; + class LaserBombCore; + class ammo_Bomb_LaserGuidedBase: LaserBombCore { + ACE_damageType = "explosive"; + }; + class BombDemine_01_Ammo_F: BombCore { + ACE_damageType = "explosive"; + }; + + // Autocannon rounds are special (#7401) + class B_19mm_HE: BulletBase { + ACE_damageType = "explosive"; + }; + class B_20mm: BulletBase { + ACE_damageType = "explosive"; + }; + class B_25mm: BulletBase { + ACE_damageType = "explosive"; + }; + class B_35mm_AA: BulletBase { + ACE_damageType = "explosive"; + }; + + // These are also special + class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { + ACE_damageType = "explosive"; + }; +}; diff --git a/addons/medical_damage/CfgEden.hpp b/addons/medical_damage/CfgEden.hpp new file mode 100644 index 0000000000..23c6ea6762 --- /dev/null +++ b/addons/medical_damage/CfgEden.hpp @@ -0,0 +1,49 @@ +class Cfg3DEN { + class Attributes { + class Slider; + class GVAR(slider): Slider { + attributeLoad = "params [""_ctrlGroup""];\ + private _slider = _ctrlGroup controlsGroupCtrl 100;\ + private _edit = _ctrlGroup controlsGroupCtrl 101;\ + _slider sliderSetPosition _value;\ + _edit ctrlSetText (if (_value < 0.1) then {localize ""str_disp_default""} else {[_value, 1, 1] call CBA_fnc_formatNumber});"; + attributeSave = "params [""_ctrlGroup""];\ + sliderPosition (_ctrlGroup controlsGroupCtrl 100); "; + onLoad = "params [""_ctrlGroup""];\ + private _slider = _ctrlGroup controlsGroupCtrl 100;\ + private _edit = _ctrlGroup controlsGroupCtrl 101;\ + _slider sliderSetRange [0, 10];\ + _slider ctrlAddEventHandler [""SliderPosChanged"", {\ + params [""_slider""];\ + private _edit = (ctrlParentControlsGroup _slider) controlsGroupCtrl 101;\ + private _value = sliderPosition _slider;\ + _edit ctrlSetText (if (_value < 0.1) then {localize ""str_disp_default""} else {[_value, 1, 1] call CBA_fnc_formatNumber});\ + }];\ + _edit ctrlAddEventHandler [""KillFocus"", {\ + params [""_edit""];\ + private _slider = (ctrlParentControlsGroup _edit) controlsGroupCtrl 100;\ + private _value = ((parseNumber ctrlText _edit) min 10) max 0;\ + _slider sliderSetPosition _value;\ + _edit ctrlSetText (if (_value < 0.1) then { localize ""str_disp_default"" } else {[_value, 1, 1] call CBA_fnc_formatNumber});\ + }];"; + }; + }; + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class GVAR(threshold) { + property = QUOTE(threshold); + control = QGVAR(slider); + displayName = CSTRING(Eden_threshold_DisplayName); + tooltip = CSTRING(Eden_threshold_Description); + expression = QUOTE(if (_value >= 0.1) then {_this setVariable [ARR_3(QQEGVAR(medical,damageThreshold),_value,true)]}); + typeName = "NUMBER"; + condition = "objectControllable"; + defaultValue = 0; + }; + }; + }; + }; + }; +}; diff --git a/addons/medical_damage/CfgEventHandlers.hpp b/addons/medical_damage/CfgEventHandlers.hpp index 93e3311cf2..865276cfba 100644 --- a/addons/medical_damage/CfgEventHandlers.hpp +++ b/addons/medical_damage/CfgEventHandlers.hpp @@ -1,11 +1,11 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index ad2055ccc5..a17e7d739c 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -1,5 +1,12 @@ +PREP(debug_explosiveTest); +PREP(determineIfFatal); PREP(getTypeOfDamage); PREP(handleIncapacitation); +PREP(interpolatePoints); PREP(parseConfigForInjuries); -PREP(woundsHandler); -PREP(woundsHandlerSQF); +PREP(parseWoundHandlersCfg); +PREP(woundReceived); +PREP(woundsHandlerBase); +PREP(woundsHandlerBurning); +PREP(woundsHandlerVehiclecrash); +PREP(woundsHandlerVehiclehit); diff --git a/addons/medical_damage/XEH_preInit.sqf b/addons/medical_damage/XEH_preInit.sqf index 081b0cf48b..344b9c81ee 100644 --- a/addons/medical_damage/XEH_preInit.sqf +++ b/addons/medical_damage/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" call FUNC(parseConfigForInjuries); @@ -16,20 +16,6 @@ addMissionEventHandler ["Loaded",{ call FUNC(parseConfigForInjuries); }]; -// decide which woundsHandler to use by whether the extension is present or not -// 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"]; - - private _typeOfDamage = _ammo call FUNC(getTypeOfDamage); - [_unit, _woundedHitPoint, _receivedDamage, _typeOfDamage] call FUNC(woundsHandlerActive); -}] call CBA_fnc_addEventHandler; +[QEGVAR(medical,woundReceived), LINKFUNC(woundReceived)] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/medical_damage/addon.toml b/addons/medical_damage/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_damage/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_damage/config.cpp b/addons/medical_damage/config.cpp index 5e420a173e..4df519a648 100644 --- a/addons/medical_damage/config.cpp +++ b/addons/medical_damage/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -17,7 +25,15 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "ACE_Medical_Injuries.hpp" #include "CfgEventHandlers.hpp" +#include "CfgAmmo.hpp" +#include "CfgEden.hpp" +/* class ACE_Extensions { - extensions[] += {"ace_medical"}; + class ace_medical { + // Not yet used + }; }; + */ + +#endif diff --git a/addons/medical_damage/functions/fnc_debug_explosiveTest.sqf b/addons/medical_damage/functions/fnc_debug_explosiveTest.sqf new file mode 100644 index 0000000000..d17b268c15 --- /dev/null +++ b/addons/medical_damage/functions/fnc_debug_explosiveTest.sqf @@ -0,0 +1,63 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Testing function that spawns AI units in a spiral around the given point and optionally spawns a projectile at the center + * Used for observing the effects of explosive munitions + * + * Arguments: + * 0: Center position, format PositionAGL + * 1: Distance to spawn units + * 0: Min (default: 1) + * 1: Max (default: 10) + * 2: Step (default: 1) + * 2: Unit class to spawn (default: "B_Soldier_F") + * 3: Ammo class to spawn, "" or nil to skip (default: "") + * 4: Delay between unit placement and ammo spawning in seconds (default: 1) + * 5: Function to run on each unit that is spawned (optional) params [_unit, _center, _ammoClass] + * + * ReturnValue: + * Nothing + * + * Example: + * [position player, [20, 80, 5]] call ace_medical_damage_fnc_debug_explosiveTest + * + * Public: No + */ +params [ + "_center", + ["_distances", []], + ["_unitClass", "B_Soldier_F"], + ["_ammoClass", ""], + ["_delay", 1], + "_initCode" +]; + +_distances params [["_min", 1], ["_max", 10], ["_step", 1]]; + +if (isNil "_center") exitwith {}; + +_max = _max max _min; +private _nSteps = 0 max ceil ((_max - _min) / _step); +private _angleStep = 360 / (_nSteps + 1); + +for "_distance" from _min to _max step _step do { + private _i = (_distance - _min) / _step; + private _angle = _i * _angleStep; + private _offset = [_distance * sin _angle, _distance * cos _angle, 0]; + private _position = _center vectorAdd _offset; + private _unit = (createGroup west) createUnit [_unitClass, _position, [], 0, "CAN_COLLIDE"]; + if !(isNil "_initCode") then { + [_unit, _center, _ammoClass] call _initCode; + }; +}; + +// spawn the ammo above the ground falling. necessary for shells, doesn't cause problems for grenades etc. +if (_ammoClass != "") then { + [{ + params ["_ammoClass", "_center"]; + private _position = _center vectorAdd [0, 0, 5]; + private _obj = _ammoClass createVehicle _position; + _obj setVectorDirAndUp [[0, 0, -1], [0, 1, 0]]; + _obj setVelocity [0, 0, -20]; + }, [_ammoClass, _center], _delay] call CBA_fnc_waitAndExecute; +}; diff --git a/addons/medical_damage/functions/fnc_determineIfFatal.sqf b/addons/medical_damage/functions/fnc_determineIfFatal.sqf new file mode 100644 index 0000000000..1e5c533e98 --- /dev/null +++ b/addons/medical_damage/functions/fnc_determineIfFatal.sqf @@ -0,0 +1,59 @@ +#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 + */ + +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 = GET_DAMAGE_THRESHOLD(_unit); + 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/FATAL_SUM_DAMAGE_WEIBULL_L)^FATAL_SUM_DAMAGE_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_getTypeOfDamage.sqf b/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf index 53645f7b8b..80542359f6 100644 --- a/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf +++ b/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Get the type of damage based upon the projectile. * * Arguments: - * 0: The projectile classname or object + * 0: The projectile classname OR the name of a damage type * * Return Value: * Type of damage @@ -17,24 +17,24 @@ params ["_typeOfProjectile"]; -// --- projectiles -if (_typeOfProjectile isKindOf "BulletBase") exitWith {"bullet"}; -if (_typeOfProjectile isKindOf "ShotgunBase") exitWith {"bullet"}; -if (_typeOfProjectile isKindOf "GrenadeCore") exitWith {"grenade"}; -if (_typeOfProjectile isKindOf "TimeBombCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "MineCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "FuelExplosion") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "ShellBase") exitWith {"shell"}; -if (_typeOfProjectile isKindOf "RocketBase") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "MissileBase") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "LaserBombCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "BombCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "Grenade") exitWith {"grenade"}; +private _damageType = GVAR(damageTypeCache) get _typeOfProjectile; -// --- non-projectiles reported by custom handleDamge wrapper -if ((_typeOfProjectile select [0,1]) isEqualTo "#") then { - _typeOfProjectile = _typeOfProjectile select [1]; +if (isNil "_damageType") then { + if (isText (configFile >> "CfgAmmo" >> _typeOfProjectile >> "ACE_damageType")) then { + _damageType = getText (configFile >> "CfgAmmo" >> _typeOfProjectile >> "ACE_damageType"); + } else { + WARNING_1("Ammo type [%1] has no ACE_damageType",_typeOfProjectile); + _damageType = "unknown"; + }; + + // config may define an invalid damage type + if !(_damageType in GVAR(damageTypeDetails)) then { + WARNING_2("Damage type [%1] for ammo [%2] not found",_damageType,_typeOfProjectile); + _damageType = "unknown"; + }; + + TRACE_2("getTypeOfDamage caching",_typeOfProjectile,_damageType); + GVAR(damageTypeCache) set [_typeOfProjectile, _damageType]; }; -// --- otherwise -toLower _typeOfProjectile +_damageType // return diff --git a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf index 1a5b2a313b..b352564b45 100644 --- a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf +++ b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Handle incapacitation due to damage and pain @@ -24,17 +24,14 @@ _bodyPartDamage params ["_headDamage", "_bodyDamage", "_leftArmDamage", "_rightA // Exclude non penetrating body damage { - _x params ["", "_bodyPartN", "_amountOf", "", "_damage"]; - if (_bodyPartN == 1 && {_damage < PENETRATION_THRESHOLD}) then { + _x params ["", "_amountOf", "", "_damage"]; + if (_damage < PENETRATION_THRESHOLD) then { _bodyDamage = _bodyDamage - (_amountOf * _damage); }; -} forEach GET_OPEN_WOUNDS(_unit); +} forEach (GET_OPEN_WOUNDS(_unit) getOrDefault ["body", []]); -private _damageThreshold = [ - EGVAR(medical,AIDamageThreshold), - EGVAR(medical,playerDamageThreshold) -] select (isPlayer _unit); +private _damageThreshold = GET_DAMAGE_THRESHOLD(_unit); -if ((_headDamage > _damageThreshold / 2) || {_bodyDamage > _damageThreshold} || {(_painLevel >= PAIN_UNCONSCIOUS) && {random 1 < 0.1}}) then { +if ((_headDamage > _damageThreshold / 2) || {_bodyDamage > _damageThreshold} || {(_painLevel >= PAIN_UNCONSCIOUS) && {random 1 < EGVAR(medical,painUnconsciousChance)}}) then { [QEGVAR(medical,CriticalInjury), _unit] call CBA_fnc_localEvent; }; diff --git a/addons/medical_damage/functions/fnc_interpolatePoints.sqf b/addons/medical_damage/functions/fnc_interpolatePoints.sqf new file mode 100644 index 0000000000..b343417837 --- /dev/null +++ b/addons/medical_damage/functions/fnc_interpolatePoints.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Returns the image of a value on a linear piecewise function defined by given points + * Force integer causes decimals to be rounded up or down by chance based on their decimal part, i.e. 2.7 has a 70% chance to return 3 and 30% to return 2 + * + * Arguments: + * 0: Input value + * 1: Function points, must be in descending order by X (input) value + * 2: Whether to force integer + * + * ReturnValue: + * Interpolated result + * + * Example: + * [0.2, [[1,0], [0.5,1], [0,0]]] call ace_medical_damage_fnc_interpolatePoints + * + * Public: No + */ +params ["_input", "_points", ["_randomRound", false]]; + +if (_points isEqualTo []) exitWith { + //TODO: sensible default/error value + 0 +}; +if (count _points == 1) exitWith {_points select 0 select 1}; + +private _output = 0; +private _lower = _points findIf {(_x select 0) < _input}; +if (_lower == 0) exitWith {_points select 0 select 1}; +if (_lower == -1) exitWith {_points select (count _points - 1) select 1}; +private _upper = _points select (_lower-1); +_lower = _points select _lower; +_output = linearConversion [_lower select 0, _upper select 0, _input, _lower select 1, _upper select 1, true]; + +if (_randomRound) then { + // chance to round up is equal to the decimal part + _output = ceil (_output - random 1); +}; + +_output //return diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index 89da4bca4e..4dfcbe840a 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, commy2 * Parse the ACE_Medical_Advanced config for all injury types. @@ -20,7 +20,7 @@ private _injuriesConfigRoot = configFile >> "ACE_Medical_Injuries"; // --- parse wounds GVAR(woundClassNames) = []; GVAR(woundClassNamesComplex) = []; // index = 10 * classID + category; [will contain nils] e.g. ["aMinor", "aMed", "aLarge", nil, nil..."bMinor"] -GVAR(woundsData) = []; +GVAR(woundDetails) = createHashMap; private _woundsConfig = _injuriesConfigRoot >> "wounds"; private _classID = 0; @@ -32,50 +32,63 @@ private _classID = 0; private _selections = GET_ARRAY(_entry >> "selections",["All"]); private _bleeding = GET_NUMBER(_entry >> "bleeding",0); private _pain = GET_NUMBER(_entry >> "pain",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) == 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, _causeFracture]; - { - GVAR(woundClassNamesComplex) set [10 * _classID + _forEachIndex, format ["%1%2", _className, _x]]; - } forEach ["Minor", "Medium", "Large"]; - _classID = _classID + 1; - }; + private _details = [_selections, _bleeding, _pain, _causeLimping, _causeFracture]; + GVAR(woundDetails) set [_className, _details]; + GVAR(woundDetails) set [_classID, _details]; + + GVAR(woundClassNames) pushBack _className; + { + GVAR(woundClassNamesComplex) set [10 * _classID + _forEachIndex, format ["%1%2", _className, _x]]; + } forEach ["Minor", "Medium", "Large"]; + _classID = _classID + 1; } forEach configProperties [_woundsConfig, "isClass _x"]; // --- parse damage types -GVAR(allDamageTypesData) = [] call CBA_fnc_createNamespace; +GVAR(damageTypeDetails) = createHashMap; +// cache for ammunition -> damageType +GVAR(damageTypeCache) = createHashMap; // minimum lethal damage collection, mapped to damageTypes private _damageTypesConfig = _injuriesConfigRoot >> "damageTypes"; private _thresholdsDefault = getArray (_damageTypesConfig >> "thresholds"); private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionSpecific"); +private _defaultWoundHandlers = []; +if (isClass (_damageTypesConfig >> "woundHandlers")) then { + _defaultWoundHandlers = [_damageTypesConfig >> "woundHandlers"] call FUNC(parseWoundHandlersCfg); + reverse _defaultWoundHandlers; +}; +TRACE_1("Found default wound handlers",count _defaultWoundHandlers); + // Collect all available damage types from the config { private _entry = _x; private _className = configName _entry; - // 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 = []; - { - if (_className in (_x select 5)) then { - _woundTypes pushBack _x; - }; - } forEach GVAR(woundsData); + if (_className == "woundHandlers") then {continue}; + + GVAR(damageTypeCache) set [_className, _className]; + GVAR(damageTypeCache) set ["#"+_className, _className]; private _damageTypeSubClassConfig = _damageTypesConfig >> _className; private _thresholds = GET_ARRAY(_damageTypeSubClassConfig >> "thresholds",_thresholdsDefault); private _selectionSpecific = GET_NUMBER(_damageTypeSubClassConfig >> "selectionSpecific",_selectionSpecificDefault); - GVAR(allDamageTypesData) setVariable [_className, [_thresholds, _selectionSpecific > 0, _woundTypes]]; + private _woundHandlers = []; + if (isClass (_damageTypeSubClassConfig >> "woundHandlers")) then { + _woundHandlers = [_damageTypeSubClassConfig >> "woundHandlers"] call FUNC(parseWoundHandlersCfg); + reverse _woundHandlers; + TRACE_2("Damage type found wound handlers",_className,count _woundHandlers); + } else { + _woundHandlers = _defaultWoundHandlers; + TRACE_1("Damage type has no wound handlers, using default",_className); + }; + /* // extension loading private _minDamageThresholds = (_thresholds apply {str (_x select 0)}) joinString ":"; private _amountThresholds = (_thresholds apply {str (_x select 1)}) joinString ":"; @@ -93,8 +106,30 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS // private _extensionRes = "ace_medical" callExtension _extensionArgs; // TRACE_1("",_extensionRes); + */ + + // parse config for each wound this damage type can cause + private _damageWoundDetails = []; + { + private _woundType = configName _x; + if (_woundType == "woundHandlers") then {continue}; + if (_woundType in GVAR(woundDetails)) then { + private _weighting = GET_ARRAY(_x >> "weighting",[[ARR_2(0,1)]]); + private _dmgMulti = GET_NUMBER(_x >> "damageMultiplier",1); + private _bleedMulti = GET_NUMBER(_x >> "bleedingMultiplier",1); + private _sizeMulti = GET_NUMBER(_x >> "sizeMultiplier",1); + private _painMulti = GET_NUMBER(_x >> "painMultiplier",1); + private _fractureMulti = GET_NUMBER(_x >> "fractureMultiplier",1); + _damageWoundDetails pushBack [_woundType, _weighting, _dmgMulti, _bleedMulti, _sizeMulti, _painMulti, _fractureMulti]; + } else { + WARNING_2("Damage type %1 refers to wound %2, but it doesn't exist: skipping.",_className,configName _x); + }; + } forEach configProperties [_damageTypeSubClassConfig, "isClass _x"]; + + GVAR(damageTypeDetails) set [_className, [_thresholds, _selectionSpecific, _woundHandlers, _damageWoundDetails]]; } forEach configProperties [_damageTypesConfig, "isClass _x"]; +/* // extension loading { _x params ["_classID", "_selections", "_bleedingRate", "_pain", "_damageExtrema", "_causes", "_displayName"]; @@ -128,3 +163,4 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS } forEach GVAR(woundsData); // "ace_medical" callExtension "ConfigComplete"; +*/ diff --git a/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf b/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf new file mode 100644 index 0000000000..0dad747c68 --- /dev/null +++ b/addons/medical_damage/functions/fnc_parseWoundHandlersCfg.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Read a list of wound handler entries from config, accounting for inheritance + * + * Arguments: + * 0: The config class containing the entries + * + * ReturnValue: + * None + * + * Example: + * [configFile >> "ace_medical_injuries" >> "damageTypes"] call ace_medical_damage_fnc_parseWoundHandlersCfg + * + * Public: No + */ +params ["_config"]; + +// read all valid entries from config and store +private _entries = []; +{ + private _entryResult = call compile getText _x; + if !(isNil "_entryResult") then { + _entries pushBack _entryResult; + } +} forEach configProperties [_config, "isText _x", false]; + +private _parent = inheritsFrom _config; +if (isNull _parent) exitWith {_entries}; + +// recursive call for parent +// can't use configProperties for inheritance since it returns entries in the wrong order +([_parent] call FUNC(parseWoundHandlersCfg)) + _entries; diff --git a/addons/medical_damage/functions/fnc_woundReceived.sqf b/addons/medical_damage/functions/fnc_woundReceived.sqf new file mode 100644 index 0000000000..a7e3861dee --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundReceived.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Handle woundReceived event and pass to individual wound handlers + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Shooter + * 3: Ammo classname or damage type + * + * ReturnValue: + * None + * + * Example: + * [_target, [[0.5, "LeftLeg", 1]], _shooter, "B_65x39_Caseless"] call ace_medical_damage_fnc_woundReceived + * + * Public: No + */ +params ["_unit", "_allDamages", "_shooter", "_ammo"]; + +private _typeOfDamage = _ammo call FUNC(getTypeOfDamage); +if (_typeOfDamage in GVAR(damageTypeDetails)) then { + (GVAR(damageTypeDetails) get _typeOfDamage) params ["", "", "_woundHandlers"]; + + private _damageData = [_unit, _allDamages, _typeOfDamage]; + { + _damageData = _damageData call _x; + TRACE_1("Wound handler returned",_damageData); + if !(_damageData isEqualType [] && {(count _damageData) >= 3}) exitWith { + TRACE_1("Return invalid, terminating wound handling",_damageData); + }; + } forEach _woundHandlers; +}; diff --git a/addons/medical_damage/functions/fnc_woundsHandler.sqf b/addons/medical_damage/functions/fnc_woundsHandler.sqf deleted file mode 100644 index 630f387fa5..0000000000 --- a/addons/medical_damage/functions/fnc_woundsHandler.sqf +++ /dev/null @@ -1,144 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal, commy2 - * Handling of the open wounds & injuries upon the handleDamage eventhandler. - * - * Arguments: - * 0: Unit That Was Hit - * 1: Name Of Body Part - * 2: Amount Of Damage - * 3: Type of the damage done - * - * Return Value: - * None - * - * Example: - * [player, "Body", 0.5, "bullet"] call ace_medical_damage_fnc_woundsHandler - * - * 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); - -if (_typeOfDamage isEqualTo "") then { - _typeOfDamage = "unknown"; -}; - -if (isNil {GVAR(allDamageTypesData) getVariable _typeOfDamage} ) then { - _typeOfDamage = "unknown"; -}; - -// Administration for open wounds and ids -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); -private _extensionOutput = "ace_medical" callExtension format ["HandleDamageWounds,%1,%2,%3,%4", _bodyPart, _damage, _typeOfDamage, _woundID]; -TRACE_1("",_extensionOutput); - -// these are default values and modified by _extensionOutput -private _painToAdd = 0; -private _woundsCreated = []; - -call compile _extensionOutput; - -// 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 -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); -{ - _x params ["", "_woundClassIDToAdd", "_bodyPartNToAdd", "", "_bleeding"]; - - _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 - - // The higher the nastiness likelihood the higher the change to get a painful and bloody wound - private _nastinessLikelihood = linearConversion [0, 20, _woundDamage, 0.5, 30, true]; - private _bleedingModifier = 0.25 + 8 * exp ((random [-4.5, -5, -6]) / _nastinessLikelihood); - private _painModifier = 0.05 + 2 * exp (-2 / _nastinessLikelihood); - - TRACE_3("",_nastinessLikelihood,_bleedingModifier,_painModifier); - - _bleeding = _bleeding * _bleedingModifier; - private _pain = (((GVAR(woundsData) select _woundClassIDToAdd) select 3) * _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]; - - _x set [4, _bleeding]; - _x set [5, _woundDamage]; - _x set [6, _category]; - - - 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; - }; - }; - }; - - // 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); - }; - - // 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; - }; - }; - } forEach _openWounds; - - if (_createNewWound) then { - _openWounds pushBack _x; - }; -} forEach _woundsCreated; - -_unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; -_unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; - -[_unit] call EFUNC(medical_status,updateWoundBloodLoss); - -_bodyPartVisParams call EFUNC(medical_engine,updateBodyPartVisuals); - -[QEGVAR(medical,injured), [_unit, _painLevel]] call CBA_fnc_localEvent; - -if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { - [_unit] call FUNC(handleIncapacitation); -}; - -TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit),_woundsCreated); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf b/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf new file mode 100644 index 0000000000..fb82f383b6 --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf @@ -0,0 +1,215 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, commy2 + * Handling of the open wounds & injuries upon the handleDamage eventhandler. + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "Body", 1]], "bullet"] call ace_medical_damage_fnc_woundsHandlerBase + * + * Public: No + */ + +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerBase",_unit,_allDamages,_typeOfDamage); + + +if !(_typeOfDamage in GVAR(damageTypeDetails)) then { + WARNING_1("damage type not found",_typeOfDamage); + _typeOfDamage = "unknown"; +}; + +GVAR(damageTypeDetails) get _typeOfDamage params ["_thresholds", "_selectionSpecific", "", "_damageWoundDetails"]; + +// Administration for open wounds and ids +private _openWounds = GET_OPEN_WOUNDS(_unit); + +private _createdWounds = false; +private _updateDamageEffects = false; +private _painLevel = 0; +private _criticalDamage = 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); + +// process wounds separately for each body part hit +{ // forEach _allDamages + _x params ["_damage", "_bodyPart"]; + _bodyPart = toLowerANSI _bodyPart; + + // silently ignore structural damage + if (_bodyPart == "#structural") then {continue}; + + // Convert the selectionName to a number and ensure it is a valid selection. + private _bodyPartNToAdd = ALL_BODY_PARTS find _bodyPart; + if (_bodyPartNToAdd < 0) then { + ERROR_1("invalid body part %1",_bodyPart); + continue + }; + + // determine how many wounds to create + private _nWounds = [_damage, _thresholds, true] call FUNC(interpolatePoints); + if (_nWounds < 1) then { + TRACE_2("Damage created zero wounds",_damage,_typeOfDamage); + continue + }; + private _dmgPerWound = _damage/_nWounds; + + // find the available injuries for this damage type and damage amount + private _weightedWoundTypes = []; + { + private _weighting = _x select 1; + private _woundWeight = [_dmgPerWound, _weighting] call FUNC(interpolatePoints); + _weightedWoundTypes pushBack _x; + _weightedWoundTypes pushBack _woundWeight; + } forEach _damageWoundDetails; + + if (_weightedWoundTypes isEqualTo []) then { + TRACE_2("No valid wounds",_damage,_typeOfDamage); + continue + }; + + for "_i" from 1 to _nWounds do { + + // Select the injury we are going to add + selectRandomWeighted _weightedWoundTypes params ["_woundTypeToAdd", "", "_dmgMultiplier", "_bleedMultiplier", "_sizeMultiplier", "_painMultiplier", "_fractureMultiplier"]; + if (isNil "_woundTypeToAdd") then { + WARNING_4("No valid wound types",_damage,_dmgPerWound,_typeOfDamage,_bodyPart); + continue + }; + GVAR(woundDetails) get _woundTypeToAdd params ["","_injuryBleedingRate","_injuryPain","_causeLimping","_causeFracture"]; + private _woundClassIDToAdd = GVAR(woundClassNames) find _woundTypeToAdd; + + // Add a bit of random variance to wounds + private _woundDamage = _dmgPerWound * _dmgMultiplier * random [0.9, 1, 1.1]; + + _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 + + // Anything above this value is guaranteed worst wound possible + private _worstDamage = 2; + + #define LARGE_WOUND_THRESHOLD 0.5 + + // Config specifies bleeding and pain for worst possible wound + // Worse wound correlates to higher damage, damage is not capped at 1 + private _woundSize = linearConversion [0.1, _worstDamage, _woundDamage * _sizeMultiplier, LARGE_WOUND_THRESHOLD^3, 1, true]; + + private _pain = _woundSize * _painMultiplier * _injuryPain; + _painLevel = _painLevel + _pain; + + private _bleeding = _woundSize * _bleedMultiplier * _injuryBleedingRate; + + // large wounds are > LARGE_WOUND_THRESHOLD + // medium is > LARGE_WOUND_THRESHOLD^2 + // minor is > LARGE_WOUND_THRESHOLD^3 + private _category = 0 max (2 - floor (ln _woundSize / ln LARGE_WOUND_THRESHOLD)) min 2; + + private _classComplex = 10 * _woundClassIDToAdd + _category; + + // Create a new injury. Format [0:classComplex, 1:amountOf, 2:bleedingRate, 3:woundDamage] + private _injury = [_classComplex, 1, _bleeding, _woundDamage]; + + if (_bodyPart isEqualTo "head" || {_bodyPart isEqualTo "body" && {_woundDamage > PENETRATION_THRESHOLD}}) then { + _criticalDamage = true; + }; + if ([_unit, _bodyPartNToAdd, _bodyPartDamage, _woundDamage] call FUNC(determineIfFatal)) then { + if (!isPlayer _unit || {random 1 < EGVAR(medical,deathChance)}) then { + TRACE_1("determineIfFatal returned true",_woundDamage); + [QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent; + }; + }; + + #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} + && {random 1 < (_fractureMultiplier * EGVAR(medical,fractureChance))} + ): { + private _fractures = GET_FRACTURES(_unit); + _fractures set [_bodyPartNToAdd, 1]; + _unit setVariable [VAR_FRACTURES, _fractures, true]; + + [QEGVAR(medical,fracture), [_unit, _bodyPartNToAdd]] call CBA_fnc_localEvent; + TRACE_1("Limb fracture",_bodyPartNToAdd); + + _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; + private _existingWounds = _openWounds getOrDefault [_bodyPart, [], true]; + { + _x params ["_classID", "_oldAmountOf", "_oldBleeding", "_oldDamage"]; + if ( + (_classComplex == _classID) && + {(_bodyPart isNotEqualTo "body") || {(_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 [1, _newAmountOf]; + private _newBleeding = (_oldAmountOf * _oldBleeding + _bleeding) / _newAmountOf; + _x set [2, _newBleeding]; + private _newDamage = (_oldAmountOf * _oldDamage + _woundDamage) / _newAmountOf; + _x set [3, _newDamage]; + _createNewWound = false; + }; + } forEach _existingWounds; + + if (_createNewWound) then { + TRACE_1("adding new wound",_injury); + _existingWounds pushBack _injury; + }; + _createdWounds = true; + }; + + // selection-specific damage only hits the first part + if (_selectionSpecific > 0) then { + break; + }; +} forEach _allDamages; + +if (_updateDamageEffects) then { + [_unit] call EFUNC(medical_engine,updateDamageEffects); +}; + +if (_createdWounds) then { + _unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; + _unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; + + [_unit] call EFUNC(medical_status,updateWoundBloodLoss); + + _bodyPartVisParams call EFUNC(medical_engine,updateBodyPartVisuals); + + [QEGVAR(medical,injured), [_unit, _painLevel]] call CBA_fnc_localEvent; + + if (_criticalDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { + [_unit] call FUNC(handleIncapacitation); + }; + + TRACE_4("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit)); +}; + +[] //return, no further damage handling diff --git a/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf b/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf new file mode 100644 index 0000000000..47c625684a --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerBurning.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Custom wound handler for burns. Stores up small damage events until there's enough to create a wound. + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "Body", 0.5]], "burning"] call ace_medical_damage_fnc_woundsHandlerBurning + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerBurning",_unit,_allDamages,_typeOfDamage); + +#define FIRE_DAMAGE_INTERVAL 1 + +{ + _x params ["_damage", "_bodyPart"]; + + if (_bodyPart != "#structural") then { + continue + }; + + private _storedDamage = _unit getVariable [QGVAR(storedBurnDamage), 0]; + private _newDamage = _storedDamage + _damage; + + // schedule a task to convert stored damage to wounds after a delay + // the task resets stored damage to zero, so if it isn't currently zero that means there is a task already waiting + if (_storedDamage == 0 && _newDamage > 0) then { + [{ + params ["_unit"]; + + _bodyPart = selectRandom ["body", "leftleg", "rightleg"]; + private _storedDamage = _unit getVariable [QGVAR(storedBurnDamage), 0]; + [QEGVAR(medical,woundReceived), [_unit, [[_storedDamage, _bodyPart, _storedDamage]], _unit, "burn"]] call CBA_fnc_localEvent; + _unit setVariable [QGVAR(storedBurnDamage), 0, true]; + }, + [_unit], FIRE_DAMAGE_INTERVAL] call CBA_fnc_waitAndExecute; + }; + + _unit setVariable [QGVAR(storedBurnDamage), _newDamage]; +} forEach _allDamages; + +[] //return, no further damage handling for this event diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf deleted file mode 100644 index f7ec2dd540..0000000000 --- a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf +++ /dev/null @@ -1,202 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal, commy2 - * Handling of the open wounds & injuries upon the handleDamage eventhandler. - * - * Arguments: - * 0: Unit That Was Hit - * 1: Name Of Body Part - * 2: Amount Of Damage - * 3: Type of the damage done - * - * Return Value: - * None - * - * Example: - * [player, "Body", 0.5, "bullet"] call ace_medical_damage_fnc_woundsHandlerSQF - * - * Public: No - */ - -params ["_unit", "_bodyPart", "_damage", "_typeOfDamage"]; -TRACE_4("woundsHandlerSQF",_unit,_bodyPart,_damage,_typeOfDamage); - -// 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 { ERROR_1("invalid body part %1",_bodyPart); }; - -if ((_typeOfDamage isEqualTo "") || {isNil {GVAR(allDamageTypesData) getVariable _typeOfDamage}}) then { - WARNING_1("damage type [%1] not found",_typeOfDamage); - _typeOfDamage = "unknown"; -}; - -// Get the damage type information. Format: [typeDamage thresholds, selectionSpecific, woundTypes] -// WoundTypes are the available wounds for this damage type. Format [[classID, selections, bleedingRate, pain], ..] -private _damageTypeInfo = [GVAR(allDamageTypesData) getVariable _typeOfDamage] param [0, [[], false, []]]; -_damageTypeInfo params ["_thresholds", "_isSelectionSpecific", "_woundTypes"]; - -// find the available injuries for this damage type and damage amount -private _highestPossibleSpot = -1; -private _highestPossibleDamage = -1; -private _allPossibleInjuries = []; - -{ - _x params ["", "_selections", "", "", "_damageExtrema"]; - _damageExtrema params ["_minDamage", "_maxDamage"]; - - // 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! - - // 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 { - _highestPossibleSpot = _forEachIndex; - _highestPossibleDamage = _minDamage; - }; - - // 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 { TRACE_2("no wounds possible",_damage,_highestPossibleSpot); }; - -// Administration for open wounds and ids -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); - -{ - _x params ["_thresholdMinDam", "_thresholdWoundCount"]; - if (_damage > _thresholdMinDam) exitWith { - private _woundDamage = _damage / (_thresholdWoundCount max 1); // If the damage creates multiple wounds - 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", "", "", "", "_causeLimping", "_causeFracture"]; - - private _bodyPartNToAdd = [floor random 6, _bodyPartN] select _isSelectionSpecific; // 6 == count ALL_BODY_PARTS - - _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 - - - // 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; - - // 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.25-0.5], medium [0.5-0.75], large [0.75+]) - private _category = floor linearConversion [0.25, 0.75, _bleedModifier, 0, 2, true]; - - private _classComplex = 10 * _woundClassIDToAdd + _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; - }; - }; - 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"]; - 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; - }; - }; - }; -} forEach _thresholds; - -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); - -_bodyPartVisParams call EFUNC(medical_engine,updateBodyPartVisuals); - -[QEGVAR(medical,injured), [_unit, _painLevel]] call CBA_fnc_localEvent; - -if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { - [_unit] call FUNC(handleIncapacitation); -}; - -TRACE_4("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit)); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclecrash.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclecrash.sqf new file mode 100644 index 0000000000..9aaaf4a382 --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclecrash.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus + * Custom wound handler for vehicle crashes, sends damage to a random hitpoint + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "#structural", 1.5]], "vehicleCrash"] call ace_medical_damage_fnc_woundsHandlerVehicleCrash + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerVehicleCrash",_unit,_allDamages,_typeOfDamage); + +// randomise all hit selections +private _newDamages = _allDamages apply { + [_x select 0, selectRandom ALL_BODY_PARTS, _x select 2]; +}; + +TRACE_1("Vehicle crash handled, passing damage",_newDamages); +[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf new file mode 100644 index 0000000000..8f9af8262c --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "#structural", 1.5]], "vehiclehit"] call ace_medical_damage_fnc_woundsHandlerVehiclehit + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerVehiclehit",_unit,_allDamages,_typeOfDamage); + +// this should only trigger for hits to just structural +if (count _allDamages > 1) exitWith {_this}; + +// damage can sometimes be negative (why?) +// damage to structural is low unless it's a very large explosion, in which case it is typically >= 1 +private _damageToApply = (abs (_allDamages select 0 select 0)); + +private _damageMap = createHashMap; +private _bodyPart = ""; +private _allBodyParts = ALL_BODY_PARTS; // micro-optimization here and above, don't recreate this array every time + +// hitpoints are randomized, more damage means more wounds in different body parts +// use a hashmap so we only create one entry in _newDamages per body part +for "_i" from 1 to (_damageToApply * 6) do { + _bodyPart = selectRandom _allBodyParts; + _damageMap set [_bodyPart, (_damageMap getOrDefault [_bodyPart, 0]) + _damageToApply]; +}; + +private _newDamages = []; +{ + _newDamages pushBack [_damageMap get _x, _x, _damageToApply]; +} forEach (keys _damageMap); // micro-optimization again, two 'get's is still faster than iterating over a hashmap + +TRACE_1("Vehicle explosion handled, passing damage",_newDamages); +[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_damage/functions/script_component.hpp b/addons/medical_damage/functions/script_component.hpp deleted file mode 100644 index 66d3d51283..0000000000 --- a/addons/medical_damage/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_damage\script_component.hpp" \ No newline at end of file diff --git a/addons/medical_damage/initSettings.inc.sqf b/addons/medical_damage/initSettings.inc.sqf new file mode 100644 index 0000000000..229b086505 --- /dev/null +++ b/addons/medical_damage/initSettings.inc.sqf @@ -0,0 +1,53 @@ +[ + 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)], 2], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,playerDamageThreshold), + "SLIDER", + [LSTRING(PlayerDamageThreshold_DisplayName), LSTRING(PlayerDamageThreshold_Description)], + ELSTRING(medical,Category), + [0, 25, 1, 2], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,AIDamageThreshold), + "SLIDER", + [LSTRING(AIDamageThreshold_DisplayName), LSTRING(AIDamageThreshold_Description)], + ELSTRING(medical,Category), + [0, 25, 1, 2], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,painUnconsciousChance), + "SLIDER", + [LSTRING(PainUnconsciousChance_DisplayName), LSTRING(PainUnconsciousChance_Description)], + ELSTRING(medical,Category), + [0, 1, 0.1, 2, true], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,painUnconsciousThreshold), + "SLIDER", + [LSTRING(PainUnconsciousThreshold_DisplayName), LSTRING(PainUnconsciousThreshold_Description)], + ELSTRING(medical,Category), + [0, 1, 0.5, 2, false], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,deathChance), + "SLIDER", + [LSTRING(deathChance_DisplayName), LSTRING(deathChance_Description)], + ELSTRING(medical,Category), + [0, 1, 1, 2, true], + true +] call CBA_fnc_addSetting; diff --git a/addons/medical_damage/initSettings.sqf b/addons/medical_damage/initSettings.sqf deleted file mode 100644 index 25a153739c..0000000000 --- a/addons/medical_damage/initSettings.sqf +++ /dev/null @@ -1,17 +0,0 @@ -[ - 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)], - 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 dbe8205775..3f274dd37a 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -3,26 +3,71 @@ Player Critical Damage Threshold - プレイヤーのクリティカル ダメージしきい値 + プレイヤーのクリティカルダメージしきい値 + Seuil de dégât critique du joueur + Порог критического урона игрока + Limite de Dano Crítico do Jogador + 玩家重擊承受量 + 玩家临界伤害阈值 + Soglia danni critici del giocatore + Kritická míra poškození pro hráče + Próg Obrażeń Krytycznych Gracza + Límite de daño crítico al jugador + Schwelle für kritischen Spielerschaden + 플레이어 치명상 한계점 - Sets the amount of damage a player can receive before going unconscious. - プレイヤーが気絶になる前に受けられるダメージ量を決定できます。 + Sets the amount of damage a player can receive before going unconscious (and dying if "Sum of Trauma" is enabled). + プレイヤーが無意識状態に陥るまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) + Définit la quantité de dégâts qu'un joueur peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée). + Устанавливает количество урона, которое может получить игрок, прежде чем потеряет сознание (и умирает, если включена функция "Сумма травм"). + Define a quantidade de dano que um jogador pode receber antes de ficar inconsciente. + 設定玩家在無意識前能承受多少傷害。 + 设置玩家在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 + Imposta la quantità di danno che un giocatore può ricevere prima di perdere conoscenza. + Nastavuje kolik poškození hráč může obdržet než upadne do bezvědomí. + Definiuje ilość obrażeń jaką może przyjąć gracz przed straceniem przytomności (oraz śmierci gdy "Suma urazów" jest włączona). + Fijar la cantidad de daño que un jugador puede recivir antes de caer inconsciente + Legt die Höhe des Schadens fest, den ein Spieler erhalten kann, bevor er ohnmächtig wird (oder stirbt, wenn "Summe aller Traumata" aktiviert ist). + Bir oyuncunun bayılmadan önce alabileceği hasar miktarını belirler. + 플레이어가 치명상으로 인해 기절까지 가기 전의 한계점을 정합니다. ("피해량 중첩"이 켜져있으면 죽기도 합니다) AI Critical Damage Threshold - AI のクリティカル ダメージしきい値 + AIのクリティカルダメージしきい値 + Seuil de dégât critique de l'IA + Порог критического урона AI + Limite de Dano Crítico da IA + AI重擊承受量 + AI 临界伤害阈值 + Soglia dei danni critici dell'IA + Kritická míra poškození pro AI + Próg Obrażeń Krytycznych AI + Límite de daño crítico de la IA + Schwelle für kritischen KI-Schaden + 인공지능 치명상 한계점 - Sets the amount of damage an AI unit can receive before going unconscious. - AI が気絶になる前に受けられるダメージ量を決定できます。 + Sets the amount of damage an AI unit can receive before going unconscious (or dying when "Sum of Trauma" is enabled). + AIが無意識状態に陥るまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) + Définit la quantité de dégâts qu'une unité IA peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée). + Устанавливает количество урона, которое может получить ИИ, прежде чем потеряет сознание (или умирает, когда включена функция "Сумма травм").. + Define a quantidade de dano que uma IA pode receber antes de ficar inconsciente. + 設定AI在無意識之前能承受多少傷害 + 设置 AI 在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 + Imposta la quantità di danno che un'unità IA può ricevere prima di perdere conoscenza. + Nastavuje kolik poškození AI může obdržet než upadne do bezvědomí. + Definiuje ilość obrażeń jaką może przyjąć AI przed straceniem przytomności (oraz śmierci gdy "Suma urazów" jest włączona). + Fijar la cantidad de daño que la IA puede recivir antes de caer inconsciente + Legt die Höhe des Schadens fest, den eine KI-Einheit erhalten kann, bevor sie ohnmächtig wird (oder stirbt, wenn "Summe aller Traumata" aktiviert ist). + 인공지능이 치명상으로 인해 기절까지 가기 전의 한계점을 정합니다. ("피해량 중첩"이 켜져있으면 죽기도 합니다) Scrape Kratzer Scorticatura Ссадина - Eraflure + Écorchure Draśnięcie Arañazo Horzsolás @@ -30,13 +75,16 @@ Odřenina 擦り傷 긁힘 + 擦傷 + Sıyrık + 擦伤 Minor Scrape Kleiner Kratzer Minima Scorticatura Малая ссадина - Petite éraflure + Petite écorchure Pomniejsze draśnięcie Arañazo menor Kis horzsolás @@ -44,13 +92,16 @@ Malá odřenina 小さな擦り傷 조금 긁힘 + 小擦傷 + Küçük Sıyrık + 轻度擦伤 Medium Scrape Mittlerer Kratzer Media Scorticatura Средняя ссадина - Moyenne éraflure + Moyenne écorchure Średnie draśnięcie Arañazo medio Közepes horzsolás @@ -58,13 +109,16 @@ Středně velká odřenina 中くらいの擦り傷 꽤 긁힘 + 中度擦傷 + Orta Sıyrık + 中度擦伤 Large Scrape Großer Kratzer - Alta Scorticatura + Ampia Scorticatura Большая ссадина - Grande éraflure + Grande écorchure Duże draśnięcie Arañazo severo Nagy horzsolás @@ -72,6 +126,9 @@ Velká odřenina 大きな擦り傷 심하게 긁힘 + 嚴重擦傷 + Büyük Sıyrık + 重度擦伤 Avulsion @@ -85,12 +142,15 @@ Avulsão Avulze 剥離傷 - 떨어져나감 + 찢김 + 撕除傷 + Kopma + 撕脱伤 Minor Avulsion Kleine Avulsion - Minima Avulsione + Piccola Avulsione Малая Авульсия Petite avulsion Pomniejsza rana płatowa @@ -99,7 +159,10 @@ Avulsão leve Malá avulze 小さな剥離傷 - 조금 떨어져나감 + 조금 찢김 + 小撕除傷 + Küçük Kopuk + 轻度撕脱伤 Medium Avulsion @@ -113,12 +176,15 @@ Avulsão média Střední avulze 中くらいの剥離傷 - 꽤 떨어져나감 + 꽤 찢김 + 中度撕除傷 + Orta Kopuk + 中度撕脱伤 Large Avulsion Große Avulsion - Alta Avulsione + Grande Avulsione Большая Авульсия Grande avulsion Duża rana płatowa @@ -127,7 +193,10 @@ Avulsão grave Velká avulze 大きな剥離傷 - 크게 떨어져나감 + 크게 찢김 + 嚴重撕除傷 + Büyük Kopuk + 重度撕脱伤 Bruise @@ -140,43 +209,52 @@ Zúzódás Contusão Modřina - 打ち傷 + 打撲傷 + 挫傷 + Yara + 挫伤 Minor Bruise Kleine Prellung - Minima Contusione - Малый ушиб + Piccola Contusione + Слабый ушиб Petit hématome Pomniejsze stłuczenie Contusión menor Kis zúzódás Contusão leve Malá modřina - 小さな打ち傷 + 小さな打撲傷 조금 멍듬 + 小挫傷 + Küçük Yara + 轻度挫伤 Medium Bruise Mittlere Prellung Media Contusione Средний ушиб - Hématome moyen + Moyen hématome Średnie stłuczenie Contusión media Közepes zúzódás Contusão média Středně velká modřina - 中くらいの打ち傷 + 中くらいの打撲傷 꽤 멍듬 + 中度挫傷 + Orta Yara + 中度挫伤 Large Bruise Große Prellung - Alta Contusione - Большой ушиб - Hématome important + Grande Contusione + Сильный ушиб + Grand hématome Duże stłuczenie Contusión severa Nagy zúzódás @@ -184,12 +262,15 @@ Velká modřina 大きな打撲傷 심하게 멍듬 + 嚴重挫傷 + Büyük Yara + 重度挫伤 - Crushed tissue + Crushed Tissue Quetschverletzung Tessuto Schiacciato - Компресионная травма + Компрессионная травма Tissu écrasé Zgniecienie tkanek miękkich Tejido triturado @@ -198,13 +279,16 @@ Zhmoždění měkkých tkání 圧挫傷 뭉개짐 + 壓迫傷 + Ezilmiş Doku + 挤压伤 - Minor crushed tissue + Minor Crushed Tissue Kleine Quetschverletzung - Minimo Tessuto Schiacciato - Малая компрессионная травма - Tissu écrasé léger + Poco Tessuto Schiacciato + Слабая компрессионная травма + Tissu légèrement écrasé Pomniejsze zgniecienie tkanek miękkich Tejido triturado menor Kis zúzott szövet @@ -212,13 +296,16 @@ Malé zhmoždění měkkých tkání 小さな圧挫傷 조금 뭉개짐 + 小壓迫傷 + Küçük Ezilmiş Doku + 轻度挤压伤 - Medium crushed tissue + Medium Crushed Tissue 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 @@ -226,13 +313,16 @@ Střední zhmoždění měkkých tkání 中くらいの圧挫傷 꽤 뭉개짐 + 中度壓迫傷 + Orta Ezilmiş Doku + 中度挤压伤 - Large crushed tissue + Large Crushed Tissue Große Quetschverletzung - Alto Tessuto Schiacciato - Большая компрессионная травма - Tissu écrasé large + Molto Tessuto Schiacciato + Сильная компрессионная травма + Tissu fortement écrasé Duże zgniecienie tkanek miękkich Tejido triturado severo Nagy zúzött szövet @@ -240,12 +330,15 @@ Velké zhmoždění měkkých tkání 大きな圧挫傷 심하게 뭉개짐 + 嚴重壓迫傷 + Büyük Ezilmiş Doku + 重度挤压伤 Cut Schnittwunde Taglio - Резаная рана + Порез Coupure Rana cięta Corte @@ -254,12 +347,15 @@ Řezná rána 切り傷 베임 + 割傷 + Kesik + 割伤 Small Cut Kleine Schnittwunde Piccolo Taglio - Малая резаная рана + Мелкий порез Pomniejsza rana cięta Corte menor Kis vágás @@ -268,26 +364,32 @@ Malá řezná rána 小さな切り傷 조금 베임 + 小割傷 + Küçük Kesik + 轻度割伤 Medium Cut Mittlere Schnittwunde Medio Taglio - Средняя резаная рана + Средний порез Średnia rana cięta Corte mediano Közepes vágás - Moyenne coupure + Coupure moyenne Corte médio Střední řezná rána 中くらいの切り傷 꽤 베임 + 中度割傷 + Orta Kesik + 中度割伤 Large Cut Große Schnittwunde Grande Taglio - Большая резаная рана + Сильный порез Duża rana cięta Corte severo Nagy vágás @@ -296,6 +398,9 @@ Velká řezná rána 大きな切り傷 심하게 베임 + 嚴重割傷 + Büyük Kesik + 重度割伤 Tear @@ -303,13 +408,16 @@ Strappo Рваная рана Rozerwanie skóry - Déchirure + Lacération Desgarro Szakadás Ruptura Tržná rána 裂傷 - 찢어짐 + 열상 + 撕裂傷 + Yırtık + 撕裂伤 Small Tear @@ -317,13 +425,16 @@ Piccolo Strappo Малая рваная рана Pomniejsze rozerwanie skóry - Petite Déchirure + Petite lacération Desgarro menor Kis szakadás Ruptura leve Malá tržná rána 小さな裂傷 - 조금 찢어짐 + 조그마한 열상 + 小撕裂傷 + Küçük Yırtık + 轻度撕裂伤 Medium Tear @@ -333,11 +444,14 @@ Ś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 中くらいの裂傷 - 꽤 찢어짐 + 꽤 큰 열상 + 中度撕裂傷 + Orta Yırtık + 中度撕裂伤 Large Tear @@ -347,123 +461,387 @@ Duże rozerwanie skóry Desgarro severo Nagy szakadás - Large déchirure + Grande lacération Ruptura grave Velká tržná rána 大きな裂傷 - 심하게 찢어짐 + 심한 열상 + 嚴重撕裂傷 + 重度撕裂伤 + Büyük Yırtık Velocity Wound Ballistisches Trauma - Velocità Ferita + Ferita Balistica Огнестрельная рана 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 Střelné poranění 銃創 총상 + 槍傷 + Hız Yarası + 穿透伤 Small Velocity Wound Kleines Ballistisches Trauma - Lenta Velocità Ferita + Piccola Ferita Balistica Малая огнестрельная рана 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í 小さな銃創 소형 총상 + 小槍傷 + Küçük Hız Yarası + 轻度穿透伤 Medium Velocity Wound Mittleres Ballistisches Trauma - Media Velocità Ferita + Media Ferita Balistica Средняя огнестрельная рана Ś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í 中くらいの銃創 중형 총상 + 中度槍傷 + Orta Hız Yarası + 中度穿透伤 Large Velocity Wound Großes Ballistisches Trauma - Alta Velocità Ferita + Grande Ferita Balistica Большая огнестрельная рана 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í 大きな銃創 대형 총상 + 嚴重槍傷 + Büyük Hız Yarası + 重度穿透伤 Puncture Wound Stichwunde - Puntura Ferita + Ferita Perforante Колотая рана Rana kłuta - Blessure de perforation + Blessure par perforation Herida punzante Szúrt seb Ferimento por perfuração Bodná rána 刺し傷 관통상 + 刺傷 + Delinme Yarası + 刺伤 Minor Puncture Wound Kleine Stichwunde - Piccola Puntura Ferita + Piccola Ferita Perforante Малая колотая рана 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 小さな刺し傷 소형 관통상 + 小刺傷 + Küçük Delinme Yarası + 轻度刺伤 Medium Puncture Wound Mittlere Stichwunde - Media Puntura Ferita + Media Ferita Perforante Средняя колотая рана Ś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 中くらいの刺し傷 중형 관통상 + 中度刺傷 + Orta Delinme Yarası + 中度刺伤 Large Puncture Wound Große Stichwunde - Grande Puntura Ferita + Grande Ferita Perforante Большая колотая рана 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 大きな刺し傷 대형 관통상 + 嚴重刺傷 + Büyük Delinme Yarası + 重度刺伤 + + + Fatal Damage Source + Причина смертельного урона + 致命ダメージの原因 + 致命傷來源 + 致命伤来源 + Cause de blessure mortelle + Fonte di danni letali + Zdroj smrtelné škody + Źródło obrażeń krytycznych + Fonte de Dano Fatal + Origen de daño fatal + Ölümcül Hasar Kaynağı + Quelle für tödlichen Schaden + 치명상의 원인 + + + Determines what damage can be fatal + Определяет какой урон будет смертельным + 致命となるダメージの種類を定義します。 + 決定何種傷害為致命 + 确定哪些伤害可能是致命的 + Determina quali danni possono essere letali + Détermine le type de blessures pouvant être fatales. + Nastavuje jaké poškození může být smrtelné + Określa jakie obrażenia mogą być śmiertelne + Determina qual dano pode ser fatal + Determina qué daño puede ser fatal + Hangi hasarın ölümcül olabileceğini belirler + Bestimmt welcher Schaden tödlich ist. + 어떤 피해가 치명상으로 작용할 지 정합니다 + + + Only large hits to vital organs + Только серьезные попадания в жизненно важные органы + 重要臓器に大きな被弾があった時のみ + 只有重要器官之重傷 + 只有重要器官受到重创 + Grosses blessures sur organes vitaux + Solo grandi colpi agli organi vitali + Pouze zásahy do životně důležitých orgánů + Tylko duże trafienia w ważne narządy + Apenas danos graves a órgãos vitais + Solo grandes heridas en organos vitales + Sadece hayati organlara büyük vuruşlar + Nur schwere Treffer an lebenswichtigen Organen + 주요 장기에 큰 피해를 입음 + + + Sum of trauma + Совокупность травмы + 外傷の合計 + 外部創傷累計 + 创伤总和 + Somme des traumatismes + Somma dei traumi + Celkové množství úrazů + Suma urazów + Soma do trauma + Suma de traumatismos + Summe aller Traumata + 피해량 중첩 + + + Either + Оба + どちらか + 兩者都是 + 二者之一 + Les deux + Entrambi + Kterýkoliv ze dvou + Zarówno + Ambos + Ambos + Ikisinden biri + Beide + 둘 다 + + + Thermal Burn + 熱傷 + Brûlure thermique + Термический ожог + Ustione Termica + Thermische Verbrennung + Oparzenie + 热灼伤 + 화상 + Quemadura térmica + Queimadura Térmica + + + Minor Thermal Burn + 軽度の熱傷 + Légère brûlure thermique + Leggera Ustione Termica + Незначительный термический ожог + Leichte thermische Verbrennung + Pomniejsze oparzenie + 轻微热灼伤 + 작은 화상 + Quemadura térmica menor + Queimadura Térmica Leve + + + Medium Thermal Burn + 中度の熱傷 + Brûlure thermique modérée + Media Ustione Termica + Средний термический ожог + Mittlere thermische Verbrennung + Średnie oparzenie + 中度热灼伤 + 꽤 큰 화상 + Quemadura térmica media + Queimadura Térmica Média + + + Major Thermal Burn + 重度の熱傷 + Sévère brûlure thermique + Severa Ustione Termica + Сильный термический ожог + Schwere thermische Verbrennung + Duże oparzenie + 重度热灼伤 + 심각한 화상 + Quemadura térmica severa + Queimadura Térmica Grave + + + Unit Damage Threshold + Schwelle für Schaden + Seuil de dégâts + Soglia di danni critici + ユニットのダメージしきい値 + Práh poškození + Порог урона + Próg obrażeń jednostki + Birim Hasar Katsayısı + Umbral de daño de unidad + 单位伤害阈值 + 유닛 피해 한계점 + Limite de Dano em Unidade + + + Sets the amount of damage a unit can receive before going unconscious. (0 for mission default) + Legt die Höhe des Schadens fest, den eine Einheit erhalten kann, bevor diese ohnmächtig wird. (0 für Misionsnormalwert) + Determina il livello di danni sopportabili da un'unità senza svenire. (0 per il valore predefinito dalla missione) + Définit la quantité de dégâts que l'unité peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée).\n(0 utilise la valeur définie dans la mission.) + このユニットが無意識状態に陥るまでに受けられるダメージ量を設定します。 (ミッション標準は0) + Určuje kolik poškození může jednotka utrpět než upadne do bezvědomí. (pro použití standardní hodnoty mise zadejte 0) + Устанавливает количество урона, которое может получить юнит перед тем, как потерять сознание. (0 для значения миссии) + Ustawia próg obrażeń jakie może otrzymać jednostka przed utratą przytomności. (0 jako ustawienie domyślne misji) + Bilinçsiz duruma geçmeden önce bir birimin alabileceği hasar miktarını ayarlar. (Görev varsayılanı için 0) + Determina la cantidad de daño que puede recibir una unidad antes de quedar inconsciente (0 para predeterminado de misión) + 设定一个单位在昏迷前所能承受的伤害量。(任务默认为0) + 이 유닛이 얼마나 많은 피해를 받아야 기절할 지 정합니다. (0은 미션 기본 설정을 사용합니다) + Define a quantidade de dano que uma unidade pode receber antes de ficar inconsciente. (0 para o padrão da missão) + + + Pain Unconscious Chance + Шанс потерять сознание от боли + Szansa na nieprzytomność przez ból + Probabilità Svenimento da Dolore + 痛みによる無意識化確率 + Probabilidad de inconsciencia por dolor + Douleur - Chance d'évanouissement + Chance für Bewusslosigkeit durch Schmerz + 疼痛昏厥概率 + 고통으로 인한 기절 확률 + Chance de Inconsciência por Dor + + + The probability of a person falling unconscious when their pain is above the tolerance threshold upon receiving damage. + Шанс, что человек потеряет сознание, когда его боль выше допустимого порога при получении травмы. + La probabilità che un'unità perda i sensi quando il suo dolore è sopra la soglia critica ricevendo danni. + Szansa że osoba straci przytomność gdy jej ból jest powyżej tolerowalnego progu podczas otrzymywania obrażeń. + ユニットがダメージを受けた時の痛みが許容しきい値を超えていた場合に無意識状態に陥る確率を設定します。 + La probabilidad de que una persona caiga inconsciente cuando su dolor está por encima del umbral al haber recibido daño. + La probabilité pour qu'une personne perde connaissance lorsque la douleur ressentie est supérieure à son seuil de tolérance. + Die Wahrscheinlichkeit, dass eine Person bewusstlos wird, wenn ihre Schmerzen bei einer Verwundung über der Toleranzschwelle liegen. + 当一个人的疼痛超过承受能力的极限时,他陷入昏迷的概率。 + 고통 한계점을 넘을 시 기절하는 확률을 정합니다. + A probabilidade de uma pessoa ficar inconsciente quando sua dor está acima do limite de tolerância ao receber dano. + + + Pain Unconscious Threshold + Порог боли для потери сознания + Soglia Critica di Dolore + Seuil d'inconscience par la douleur. + 無意識状態に陥る痛みのしきい値 + Próg Nieprzytomności od Bólu + Schmerz-Bewusstlosigkeit-Grenze + 고통 기절 한계점 + Limite de Dor Antes da Inconsciência + Umbral de Dolor de Inconsciencia + + + Sets the threshold for severe pain, above which a person can fall unconscious upon receiving damage. + Устанавливает количество боли от полученной травмы, при котором юнит может потерять сознание. + Determina la soglia per forte dolore, al di sopra di cui una persona può svenire se riceve danni. + Définis le niveau de douleur à partir duquel une personne peut perdre connaissance. Cf PainUnconsciousChance. + 激しい痛みのしきい値を設定します。このしきい値を超えた状態でダメージを受けると意識を失う可能性があります。 + Ustawia próg silnego bólu, powyżej którego osoba może stracić przytomność po otrzymaniu obrażeń. + Legt die Grenze für starke Schmerzen fest, oberhalb derer eine Person bei erlittenem Schaden bewusstlos werden kann. + 사람이 데미지를 입었을 때 의식불명 상태가 될 수 있는 심각한 고통의 한계점을 설정합니다. + Define o limite para dor severa, acima do qual uma pessoa pode ficar inconsciente ao receber dano. + Establece el umbral para dolor severo, sobre el cual una persona puede caer inconsciente una vez reciba daño. + + + Fatal Injury Death Chance + Вероятность смерти от смертельной травмы + Probabilidad de muerte por herida fatal + Probabilità di morte da ferita letale + Blessure mortelle - Chance de décès + Szana na śmierć przy śmiertelej ranie + 致命傷による死亡確率 + Tödliche Verletzung - Wahrscheinlichkeit des Todes + 致命伤死亡概率 + 치명상 사망 확률 + Chance de Morte por Ferimento Fatal + + + The chance of dying to a fatal injury. + Шанс умереть от смертельной травмы. + La probabilidad de morir a causa de una herida fatal. + La probabilità che una ferita letale provochi la morte dell'unità. + La probabilité de mourir lors d'une "blessure mortelle".\nUne blessure mortelle est définie par des dommages importants à la tête ou au cœur. + Szansa na śmierć po otrzymaniu śmiertelnej rany. + 致命傷による死亡確率を設定します。 + Die Wahrscheinlichkeit, an einer eigentlich tödlichen Verletzung zu sterben. + 死于致命伤的概率。 + 치명상으로 인해 사망할 확률을 정합니다. + A chance de morrer para um ferimento fatal. diff --git a/addons/medical_engine/CfgActions.hpp b/addons/medical_engine/CfgActions.hpp index 64ecf717db..425b33dbce 100644 --- a/addons/medical_engine/CfgActions.hpp +++ b/addons/medical_engine/CfgActions.hpp @@ -13,4 +13,25 @@ class CfgActions { class FirstAid: None { show = 0; }; + class UnloadUnconsciousUnits: None { + show = 0; + }; + class UnloadFromDriver: None { + show = 0; + }; + class UnloadFromPilot: None { + show = 0; + }; + class UnloadFromCargo: None { + show = 0; + }; + class UnloadFromCommander: None { + show = 0; + }; + class UnloadFromGunner: None { + show = 0; + }; + class UnloadFromTurret: None { + show = 0; + }; }; diff --git a/addons/medical_engine/CfgEventHandlers.hpp b/addons/medical_engine/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/medical_engine/CfgEventHandlers.hpp +++ b/addons/medical_engine/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_engine/CfgExtendedAnimation.hpp b/addons/medical_engine/CfgExtendedAnimation.hpp index 8f9525f0a5..03fde9fee4 100644 --- a/addons/medical_engine/CfgExtendedAnimation.hpp +++ b/addons/medical_engine/CfgExtendedAnimation.hpp @@ -1,10 +1,9 @@ -// we want the face down animation every time class CfgExtendedAnimation { class Revive { - left = "Unconscious"; - right = "Unconscious"; - front = "Unconscious"; - back = "Unconscious"; + left = QUNCON_ANIM(faceLeft); + right = QUNCON_ANIM(faceRight); + front = QUNCON_ANIM(faceDown); + back = QUNCON_ANIM(faceUp); }; }; diff --git a/addons/medical_engine/CfgFunctions.hpp b/addons/medical_engine/CfgFunctions.hpp new file mode 100644 index 0000000000..7b6fc41278 --- /dev/null +++ b/addons/medical_engine/CfgFunctions.hpp @@ -0,0 +1,10 @@ +class CfgFunctions { + class A3_Mark { + class Revive { + class reviveInit { + // Disable BI medical system + postInit = 0; + }; + }; + }; +}; diff --git a/addons/medical_engine/CfgMoves.hpp b/addons/medical_engine/CfgMoves.hpp index d7d304c7f8..34f0572479 100644 --- a/addons/medical_engine/CfgMoves.hpp +++ b/addons/medical_engine/CfgMoves.hpp @@ -1,4 +1,3 @@ - class CfgMovesBasic; class CfgMovesMaleSdr: CfgMovesBasic { class States { @@ -8,6 +7,92 @@ class CfgMovesMaleSdr: CfgMovesBasic { weaponIK = 0; }; + class DeadState; + class UNCON_ANIM(1): DeadState { + // Prevents AI from moving torso and head when unconscious + aiming = "aimingNo"; + aimingBody = "aimingUpNo"; + head = "headNo"; + + file = QPATHTO_T(data\ace_unconscious_1.rtm); + }; + + class UNCON_ANIM(2): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_2.rtm); + }; + + class UNCON_ANIM(3): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_3.rtm); + }; + + class UNCON_ANIM(4): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_4.rtm); + }; + + class UNCON_ANIM(5): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_5.rtm); + }; + + class UNCON_ANIM(6): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_6.rtm); + }; + + class UNCON_ANIM(7): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_7.rtm); + }; + + class UNCON_ANIM(8): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_8.rtm); + }; + + class UNCON_ANIM(1_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_1_1.rtm); + }; + + class UNCON_ANIM(2_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_2_1.rtm); + }; + + class UNCON_ANIM(3_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_3_1.rtm); + }; + + class UNCON_ANIM(4_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_4_1.rtm); + }; + + class UNCON_ANIM(5_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_5_1.rtm); + }; + + class UNCON_ANIM(6_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_6_1.rtm); + }; + + class UNCON_ANIM(7_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_7_1.rtm); + }; + + class UNCON_ANIM(8_1): UNCON_ANIM(1) { + file = QPATHTO_T(data\ace_unconscious_8_1.rtm); + }; + + /* added for the "ace_unc" part */ + class KIA_passenger_boat_holdleft; + class UNCON_ANIM(9): KIA_passenger_boat_holdleft {}; + + class KIA_driver_boat01; + class UNCON_ANIM(10): KIA_driver_boat01 {}; + + class Unconscious; + class UNCON_ANIM(faceDown): Unconscious {}; + + class UNCON_ANIM(faceLeft): Unconscious {}; + + class UNCON_ANIM(faceRight): Unconscious {}; + + class UNCON_ANIM(faceUp): Unconscious {}; + class AmovPpneMstpSnonWnonDnon; class ACE_UnconsciousOutProne: AmovPpneMstpSnonWnonDnon { //file = "\A3\anims_f\Data\Anim\Sdr\dth\pne\stp\ras\Rfl\AdthPpneMstpSrasWrflDnon_1"; diff --git a/addons/medical_engine/CfgVehicles.hpp b/addons/medical_engine/CfgVehicles.hpp index 58a4b47114..ac744031e3 100644 --- a/addons/medical_engine/CfgVehicles.hpp +++ b/addons/medical_engine/CfgVehicles.hpp @@ -4,7 +4,9 @@ class CfgVehicles { class CAManBase: Man { // General class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; @@ -12,12 +14,16 @@ class CfgVehicles { class B_Soldier_base_F; class B_Soldier_04_f: B_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class B_Soldier_05_f: B_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; @@ -25,12 +31,16 @@ class CfgVehicles { class I_Soldier_base_F; class I_Soldier_03_F: I_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class I_Soldier_04_F: I_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; @@ -38,79 +48,117 @@ class CfgVehicles { class SoldierEB; class O_Soldier_base_F: SoldierEB { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class O_Soldier_02_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class O_officer_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class O_Soldier_diver_base_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; // Virtual Reality class B_Soldier_VR_F: B_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class B_Protagonist_VR_F: B_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class O_Soldier_VR_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class I_Soldier_VR_F: I_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class I_Protagonist_VR_F: I_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class O_Protagonist_VR_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class C_man_1; class C_Protagonist_VR_F: C_man_1 { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; // Civilians class C_Soldier_VR_F: C_man_1 { class HitPoints { - ADD_ACE_HITPOINTS(1,1); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; // APEX class O_V_Soldier_Viper_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(3,3); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; class O_V_Soldier_base_F: O_Soldier_base_F { class HitPoints { - ADD_ACE_HITPOINTS(3,3); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; + }; + }; + + // Enoch + class I_E_Man_Base_F; + class I_E_Uniform_01_coveralls_F: I_E_Man_Base_F { + class HitPoints { + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; }; diff --git a/addons/medical_engine/README.md b/addons/medical_engine/README.md index c609f506cc..e3a128d9f4 100644 --- a/addons/medical_engine/README.md +++ b/addons/medical_engine/README.md @@ -2,10 +2,3 @@ ace_medical_engine =============== Links Arma 3 soldier health simulation to ACE medical system. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/medical_engine/XEH_PREP.hpp b/addons/medical_engine/XEH_PREP.hpp index 0bacdd97e7..ffc3543745 100644 --- a/addons/medical_engine/XEH_PREP.hpp +++ b/addons/medical_engine/XEH_PREP.hpp @@ -1,6 +1,12 @@ -PREP(handleDamage); +PREP(applyAnimAfterRagdoll); PREP(damageBodyPart); -PREP(updateBodyPartVisuals); -PREP(updateDamageEffects); +PREP(disableThirdParty); +PREP(getHitpointArmor); +PREP(getItemArmor); +PREP(handleDamage); +PREP(lockUnconsciousSeat); PREP(setStructuralDamage); PREP(setUnconsciousAnim); +PREP(unlockUnconsciousSeat); +PREP(updateBodyPartVisuals); +PREP(updateDamageEffects); diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 2a6aa2b717..ed66091498 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -6,33 +6,29 @@ [_new] call FUNC(updateDamageEffects); // Run on new controlled unit to update QGVAR(aimFracture) }, true] call CBA_fnc_addPlayerEventHandler; - ["CAManBase", "init", { params ["_unit"]; - // Check if last hit point is our dummy. - private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; - reverse _allHitPoints; + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber (configOf _unit >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit);}; - if (_allHitPoints param [0, ""] != "ACE_HDBracket") then { - private _config = [_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)}; + private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; + if ((GVAR(customHitpoints) arrayIntersect _allHitPoints) isNotEqualTo GVAR(customHitpoints)) exitWith { ERROR_1("Bad hitpoints for unit type ""%1""",typeOf _unit); - } else { - // Calling this function inside curly brackets allows the usage of - // "exitWith", which would be broken with "HandleDamage" otherwise. - _unit setVariable [ - QEGVAR(medical,HandleDamageEHID), - _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] - ]; }; + + // Calling this function inside curly brackets allows the usage of + // "exitWith", which would be broken with "HandleDamage" otherwise. + _unit setVariable [ + QEGVAR(medical,HandleDamageEHID), + _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] + ]; }, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler; #ifdef DEBUG_MODE_FULL [QEGVAR(medical,woundReceived), { - params ["_unit", "_woundedHitPoint", "_receivedDamage", "_shooter", "_ammo"]; - TRACE_5("wound",_unit,_woundedHitPoint, _receivedDamage, _shooter, _ammo); + params ["_unit", "_damages", "_shooter", "_ammo"]; + TRACE_4("wound",_unit,_damages,_shooter,_ammo); //systemChat str _this; }] call CBA_fnc_addEventHandler; #endif @@ -41,10 +37,57 @@ // this handles moving units into vehicles via load functions or zeus // needed, because the vanilla INCAPACITATED state does not handle vehicles ["CAManBase", "GetInMan", { - params ["_unit"]; - if (!local _unit) exitWith {}; + params ["_unit", "", "_vehicle"]; - if (lifeState _unit == "INCAPACITATED") then { + if (local _unit && {lifeState _unit == "INCAPACITATED"}) then { [_unit, true] call FUNC(setUnconsciousAnim); }; + + if (local _vehicle) then { + [_unit] call FUNC(lockUnconsciousSeat); + }; }] call CBA_fnc_addClassEventHandler; + +["CAManBase", "GetOutMan", { + params ["_unit", "", "_vehicle"]; + + if (local _vehicle) then { + [_unit] call FUNC(unlockUnconsciousSeat); + }; +}] call CBA_fnc_addClassEventHandler; + +// Fixes units being stuck in unconscious animation when being knocked over by a PhysX object +["CAManBase", "AnimDone", { + params ["_unit", "_anim"]; + if (local _unit && {_anim find QUNCON_ANIM(face) != -1 && {lifeState _unit != "INCAPACITATED"}}) then { + [_unit, false] call FUNC(setUnconsciousAnim); + }; +}] call CBA_fnc_addClassEventHandler; + +["ace_unconscious", { + params ["_unit", "_unconscious"]; + TRACE_3("unit uncon",_unit,objectParent _unit,local _unit); + if (!isNull objectParent _unit && {local objectParent _unit}) then { + if (_unconscious) then { + [_unit] call FUNC(lockUnconsciousSeat); + } else { + [_unit] call FUNC(unlockUnconsciousSeat); + }; + }; +}] call CBA_fnc_addEventHandler; + +["ace_killed", { // global event + params ["_unit"]; + TRACE_3("unit Killed",_unit,objectParent _unit,local _unit); + if (!isNull objectParent _unit && {local objectParent _unit}) exitWith { + [_unit] call FUNC(lockUnconsciousSeat); + }; +}] call CBA_fnc_addEventHandler; + +["CAManBase", "Deleted", { + params ["_unit"]; + TRACE_3("unit deleted",_unit,objectParent _unit,local _unit); + if ((!isNull objectParent _unit) && {local objectParent _unit}) then { + [_unit] call FUNC(unlockUnconsciousSeat); + }; +}, true, []] call CBA_fnc_addClassEventHandler; diff --git a/addons/medical_engine/XEH_preInit.sqf b/addons/medical_engine/XEH_preInit.sqf index 18bc483c55..035b9f4b05 100644 --- a/addons/medical_engine/XEH_preInit.sqf +++ b/addons/medical_engine/XEH_preInit.sqf @@ -6,11 +6,49 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +// Define "Constants" variables (both are macros defined in script_macros_medical.hpp, look there for actual variable names) +if (isNil QUOTE(SPONTANEOUS_WAKE_UP_INTERVAL)) then {SPONTANEOUS_WAKE_UP_INTERVAL = SPONTANEOUS_WAKE_UP_INTERVAL_DEFAULT}; +if (isNil QUOTE(MINIMUM_BLOOD_FOR_STABLE_VITALS)) then {MINIMUM_BLOOD_FOR_STABLE_VITALS = MINIMUM_BLOOD_FOR_STABLE_VITALS_DEFAULT}; +if (isNil QUOTE(HEAD_DAMAGE_THRESHOLD)) then {HEAD_DAMAGE_THRESHOLD = HEAD_DAMAGE_THRESHOLD_DEFAULT}; +if (isNil QUOTE(ORGAN_DAMAGE_THRESHOLD)) then {ORGAN_DAMAGE_THRESHOLD = ORGAN_DAMAGE_THRESHOLD_DEFAULT}; +if (isNil QUOTE(HEART_HIT_CHANCE)) then {HEART_HIT_CHANCE = HEART_HIT_CHANCE_DEFAULT}; +if (isNil QUOTE(PENETRATION_THRESHOLD)) then {PENETRATION_THRESHOLD = PENETRATION_THRESHOLD_DEFAULT}; +if (isNil QUOTE(BLOOD_LOSS_KNOCK_OUT_THRESHOLD)) then {BLOOD_LOSS_KNOCK_OUT_THRESHOLD = BLOOD_LOSS_KNOCK_OUT_THRESHOLD_DEFAULT}; +if (isNil QUOTE(PAIN_FADE_TIME)) then {PAIN_FADE_TIME = PAIN_FADE_TIME_DEFAULT}; +if (isNil QUOTE(LIMPING_DAMAGE_THRESHOLD)) then {LIMPING_DAMAGE_THRESHOLD = LIMPING_DAMAGE_THRESHOLD_DEFAULT}; +if (isNil QUOTE(FRACTURE_DAMAGE_THRESHOLD)) then {FRACTURE_DAMAGE_THRESHOLD = FRACTURE_DAMAGE_THRESHOLD_DEFAULT}; +if (isNil QUOTE(CARDIAC_OUTPUT_MIN)) then {CARDIAC_OUTPUT_MIN = CARDIAC_OUTPUT_MIN_DEFAULT}; +// Derive the alternate fatal damage coefficents +if (isNil QUOTE(FATAL_SUM_DAMAGE_WEIBULL_K) || isNil QUOTE(FATAL_SUM_DAMAGE_WEIBULL_L)) then { + private _x1 = 0.5; + private _y1 = 0.1; + private _x2 = 0.8; + private _y2 = 0.9; + private _b1 = -ln (1-_y1); + private _b2 = -ln (1-_y2); + FATAL_SUM_DAMAGE_WEIBULL_K = ln(_b1/_b2) / ln(_x1/_x2); + FATAL_SUM_DAMAGE_WEIBULL_L = _x1 / _b1^(1/FATAL_SUM_DAMAGE_WEIBULL_K); +}; + +// Cache for armor values of equipped items (vests etc) +GVAR(armorCache) = createHashMap; + // Hack for #3168 (units in static weapons do not take any damage): // Doing a manual pre-load with a small distance seems to fix the LOD problems // with handle damage not returning full results. GVAR(fixedStatics) = []; +GVAR(animations) = createHashMapFromArray [ + [toLowerANSI QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]], + [toLowerANSI QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]], + [toLowerANSI QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]], + [toLowerANSI QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]] +]; + +GVAR(customHitpoints) = ["hitleftarm", "hitrightarm", "hitleftleg", "hitrightleg"]; + private _fnc_fixStatic = { params ["_vehicle"]; private _type = typeOf _vehicle; @@ -30,4 +68,26 @@ addMissionEventHandler ["Loaded", { } forEach GVAR(fixedStatics); }]; +["ace_unconscious", { + params ["_unit", "_active"]; + if (_active) then { + // Use object reference to indicate the waitUnit is already running (this prevents issues with respawning units keeping SetVars) + if ((_unit getVariable [QGVAR(waitForAnim), objNull]) == _unit) exitWith {}; + _unit setVariable [QGVAR(waitForAnim), _unit]; + [{(animationState _this) find QUNCON_ANIM(face) != -1}, { + [_this, animationState _this] call FUNC(applyAnimAfterRagdoll); + }, _unit, 20] call CBA_fnc_waitUntilAndExecute; + } else { + _unit setVariable [QGVAR(waitForAnim), nil]; + if (local _unit) then { + [_unit, _active] call FUNC(setUnconsciousAnim); + }; + }; +}] call CBA_fnc_addEventhandler; + +[] call FUNC(disableThirdParty); + +// Future-proofing +EGVAR(medical,enabled) = true; // TODO: remove when medical enable setting is implemented + ADDON = true; diff --git a/addons/medical_engine/addon.toml b/addons/medical_engine/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_engine/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_engine/config.cpp b/addons/medical_engine/config.cpp index 698428a632..2d7926aa41 100644 --- a/addons/medical_engine/config.cpp +++ b/addons/medical_engine/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -14,10 +22,12 @@ class CfgPatches { }; }; -#include "CfgEventHandlers.hpp" - #include "CfgActions.hpp" -#include "CfgMoves.hpp" +#include "CfgEventHandlers.hpp" #include "CfgExtendedAnimation.hpp" +#include "CfgFunctions.hpp" +#include "CfgMoves.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" + +#endif diff --git a/addons/medical_engine/data/ace_unconscious_1.rtm b/addons/medical_engine/data/ace_unconscious_1.rtm new file mode 100644 index 0000000000..9c34d6ffcd Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_1_1.rtm b/addons/medical_engine/data/ace_unconscious_1_1.rtm new file mode 100644 index 0000000000..c988670ade Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_1_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_2.rtm b/addons/medical_engine/data/ace_unconscious_2.rtm new file mode 100644 index 0000000000..0a37e2424c Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_2.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_2_1.rtm b/addons/medical_engine/data/ace_unconscious_2_1.rtm new file mode 100644 index 0000000000..3173fa18fb Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_2_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_3.rtm b/addons/medical_engine/data/ace_unconscious_3.rtm new file mode 100644 index 0000000000..5498e928df Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_3.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_3_1.rtm b/addons/medical_engine/data/ace_unconscious_3_1.rtm new file mode 100644 index 0000000000..19a4de3971 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_3_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_4.rtm b/addons/medical_engine/data/ace_unconscious_4.rtm new file mode 100644 index 0000000000..4fcf5653f0 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_4.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_4_1.rtm b/addons/medical_engine/data/ace_unconscious_4_1.rtm new file mode 100644 index 0000000000..df30a96f78 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_4_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_5.rtm b/addons/medical_engine/data/ace_unconscious_5.rtm new file mode 100644 index 0000000000..7915a09112 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_5.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_5_1.rtm b/addons/medical_engine/data/ace_unconscious_5_1.rtm new file mode 100644 index 0000000000..f4fe14d92c Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_5_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_6.rtm b/addons/medical_engine/data/ace_unconscious_6.rtm new file mode 100644 index 0000000000..bfe38f3e28 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_6.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_6_1.rtm b/addons/medical_engine/data/ace_unconscious_6_1.rtm new file mode 100644 index 0000000000..27c22ef1fa Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_6_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_7.rtm b/addons/medical_engine/data/ace_unconscious_7.rtm new file mode 100644 index 0000000000..8ec1f7e78f Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_7.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_7_1.rtm b/addons/medical_engine/data/ace_unconscious_7_1.rtm new file mode 100644 index 0000000000..bd4c090ac9 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_7_1.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_8.rtm b/addons/medical_engine/data/ace_unconscious_8.rtm new file mode 100644 index 0000000000..53cd2fb3cd Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_8.rtm differ diff --git a/addons/medical_engine/data/ace_unconscious_8_1.rtm b/addons/medical_engine/data/ace_unconscious_8_1.rtm new file mode 100644 index 0000000000..09f5ec1ec9 Binary files /dev/null and b/addons/medical_engine/data/ace_unconscious_8_1.rtm differ diff --git a/addons/medical_engine/data/model.cfg b/addons/medical_engine/data/model.cfg new file mode 100644 index 0000000000..58bc63eb8d --- /dev/null +++ b/addons/medical_engine/data/model.cfg @@ -0,0 +1,175 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; + + class OFP2_ManSkeleton { + isDiscrete = 0; + skeletonInherit = ""; + skeletonBones[] = { + "Pelvis","", + "Spine","Pelvis", + "Spine1","Spine", + "Spine2","Spine1", + "Spine3","Spine2", + "Camera","Pelvis", + "weapon","Spine1", + "launcher","Spine1", + + // Head skeleton in hierarchy + "neck","Spine3", + "neck1","neck", + "head","neck1", + + // New facial features + "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", + + // 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" + }; + + // location of pivot points (local axes) for hierarchical animation + pivotsModel = "A3\anims_f\data\skeleton\SkeletonPivots.p3d"; + }; +}; + +class CfgModels { + class Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = ""; + }; + + class ArmaMan: Default { + htMin = 60; // Minimum half-cooling time (in seconds) + htMax = 1800; // Maximum half-cooling time (in seconds) + afMax = 30; // Maximum temperature in case the model is alive (in celsius) + mfMax = 0; // Maximum temperature when the model is moving (in celsius) + mFact = 1; // Metabolism factor - number from interval <0, 1> (0 - metabolism has no influence, 1 - metabolism has full influence (no other temperature source will be considered)). + tBody = 37; // Metabolism temperature of the model (in celsius) + + sections[] = { + "osobnost", + "Head_Injury", + "Body_Injury", + "l_leg_injury", + "l_arm_injury", + "r_arm_injury", + "r_leg_injury", + "injury_body", + "injury_legs", + "injury_hands", + "clan", + "clan_sign", + "Camo", + "CamoB", + "Camo1", + "Camo2", + "personality", + "hl", + "injury_head", + "insignia", + "ghillie_hide" + }; + + skeletonName = "OFP2_ManSkeleton"; + }; +}; diff --git a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf new file mode 100644 index 0000000000..726a606344 --- /dev/null +++ b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: diwako + * Apply a fitting unconscious animation to a knocked out unit + * + * Arguments: + * 0: Unit + * 1: Animation + * + * Return Value: + * None + * + * Example: + * [_unit, _anim] call ace_medical_engine_fnc_applyAnimAfterRagdoll; + * + * Public: No + */ + +params ["_unit", "_anim"]; +TRACE_2("applyAnimAfterRagdoll",_unit,_anim); + +if !(IS_UNCONSCIOUS(_unit) && // do not run if unit is conscious + {alive _unit && // do not run if unit is dead + {isNull objectParent _unit}}) exitWith {}; // do not run if unit in any vehicle + +private _animsArray = GVAR(animations) getOrDefault [toLowerANSI _anim, [""]]; +private _random = (toArray (hashValue _unit)) param [0, 0]; +private _index = _random % (count _animsArray); +private _unconsciousAnimation = _animsArray select _index; + +if (_unconsciousAnimation isEqualTo "") exitWith { + // not a valid animation found + ERROR_1("No valid animation found! [from anim: %1]",_anim); +}; + +// Apply the animation only locally on the machine and do not broadcast it to others +// Reason is the nature of setUnconscious' end of ragdoll animation is not synced on all machines either +// Not synced animations are preferred over units snapping from one to another animation +TRACE_2("switchMove",_unit,_unconsciousAnimation); +_unit switchMove _unconsciousAnimation; diff --git a/addons/medical_engine/functions/fnc_damageBodyPart.sqf b/addons/medical_engine/functions/fnc_damageBodyPart.sqf index a435632801..f69bce2cae 100644 --- a/addons/medical_engine/functions/fnc_damageBodyPart.sqf +++ b/addons/medical_engine/functions/fnc_damageBodyPart.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Damages a body part of a local unit. Does not kill the unit. @@ -28,7 +28,7 @@ TRACE_3("damageBodyPart",_unit,_selection,_damage); _damage = [0, DAMAGED_MIN_THRESHOLD] select _damage; -switch (toLower _selection) do { +switch (toLowerANSI _selection) do { case ("head"): { _unit setHitPointDamage ["HitHead", _damage]; }; diff --git a/addons/medical_engine/functions/fnc_disableThirdParty.sqf b/addons/medical_engine/functions/fnc_disableThirdParty.sqf new file mode 100644 index 0000000000..4a9bacd088 --- /dev/null +++ b/addons/medical_engine/functions/fnc_disableThirdParty.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Detects and disables third party medical systems. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_medical_engine_fnc_disableThirdParty + * + * Public: No + */ + +// SOG:PF CDLC revive system +// Pretend revive system was already initialized. +// See: vn_fnc_module_advancedrevive +vn_advanced_revive_started = true; + +// Farooq Revive +// Overwrite player initialization. +far_player_init = compileFinal ""; +[{!isNil "far_debugging"}, { + far_isDragging = nil; // Disable "Drag & Carry animation fix" loop - cannot be killed because spawned while true. + far_muteRadio = nil; // Disable initialization hint. + far_muteACRE = nil; // Same, but for very old versions. + far_debugging = false; // Disable adding event handlers to AI in SP. +}, [], 5] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf new file mode 100644 index 0000000000..d4fdd00fd3 --- /dev/null +++ b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf @@ -0,0 +1,54 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Checks a unit's equipment to calculate the total armor on a hitpoint. + * + * Arguments: + * 0: Unit + * 1: Hitpoint + * + * Return Value: + * Total armor and scaled armor for the given hitpoint + * + * Example: + * [player, "HitChest"] call ace_medical_engine_fnc_getHitpointArmor + * + * Public: No + */ + +params ["_unit", "_hitpoint"]; + +private _uniform = uniform _unit; +// If unit is naked, use its underwear class instead +if (_uniform isEqualTo "") then { + _uniform = getText (configOf _unit >> "nakedUniform"); +}; + +private _gear = [ + _uniform, + vest _unit, + headgear _unit +]; + +private _rags = _gear joinString "$"; +private _var = format [QGVAR(armorCache$%1), _hitpoint]; +_unit getVariable [_var, ["", 0, 0]] params ["_prevRags", "_armor", "_armorScaled"]; + +if (_rags != _prevRags) then { + _armor = 0; + _armorScaled = 0; + + { + ([_x, _hitpoint] call FUNC(getItemArmor)) params ["_itemArmor", "_itemArmorScaled"]; + _armor = _armor + _itemArmor; + _armorScaled = _armorScaled + _itemArmorScaled; + } forEach _gear; + + // Armor should be at least 1 to prevent dividing by 0 + _armor = _armor max 1; + _armorScaled = _armorScaled max 1; + + _unit setVariable [_var, [_rags, _armor, _armorScaled]]; +}; + +[_armor, _armorScaled] // return diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf new file mode 100644 index 0000000000..01e6719a0f --- /dev/null +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Returns the regular and scaled armor values the given item provides to a particular hitpoint, either from a cache or by reading the item config. + * + * Arguments: + * 0: Item Class + * 1: Hitpoint + * + * Return Value: + * Regular and scaled item armor for the given hitpoint + * + * Example: + * ["V_PlateCarrier_rgr", "HitChest"] call ace_medical_engine_fnc_getItemArmor + * + * Public: No + */ + +params ["_item", "_hitpoint"]; + +private _key = format ["%1$%2", _item, _hitpoint]; +private _return = GVAR(armorCache) get _key; + +if (isNil "_return") then { + private _armor = 0; + private _armorScaled = 0; + private _passThrough = 1; + TRACE_2("Cache miss",_item,_hitpoint); + if ("" in [_item, _hitpoint]) exitWith { + _return = [_armor, _armorScaled]; + GVAR(armorCache) set [_key, _return]; + }; + + private _itemInfo = configFile >> "CfgWeapons" >> _item >> "ItemInfo"; + private _itemType = getNumber (_itemInfo >> "type"); + private _passThroughEffect = [1, 0.6] select (_itemType == TYPE_VEST); + + if (_itemType == TYPE_UNIFORM) then { + private _unitCfg = configFile >> "CfgVehicles" >> getText (_itemInfo >> "uniformClass"); + if (_hitpoint == "#structural") then { + // TODO: I'm not sure if this should be multiplied by the base armor value or not + _armor = getNumber (_unitCfg >> "armorStructural"); + } else { + private _entry = _unitCfg >> "HitPoints" >> _hitpoint; + _armor = getNumber (_unitCfg >> "armor") * (1 max getNumber (_entry >> "armor")); + _passThrough = 0.1 max getNumber (_entry >> "passThrough") min 1; // prevent dividing by 0 + }; + } else { + private _condition = format ["getText (_x >> 'hitpointName') == '%1'", _hitpoint]; + private _entry = configProperties [_itemInfo >> "HitpointsProtectionInfo", _condition] param [0, configNull]; + if (!isNull _entry) then { + _armor = getNumber (_entry >> "armor"); + _passThrough = 0.1 max getNumber (_entry >> "passThrough") min 1; + }; + }; + + // Scale armor using passthrough to fix explosive-resistant armor (#9063) + // Skip scaling for uniforms and items that don't cover the hitpoint to prevent infinite armor + if (_armor > 0) then { + if (_itemType == TYPE_UNIFORM) then { + _armorScaled = _armor; + } else { + _armorScaled = (log (_armor / (_passThrough ^ _passThroughEffect))) * 10; + }; + }; + _return = [_armor, _armorScaled]; + GVAR(armorCache) set [_key, _return]; +}; + +_return // return diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index d810960f4d..168203366c 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -1,9 +1,9 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, SilentSpike + * Author: commy2, kymckay, LinkIsGrim * HandleDamage EH where wound events are raised based on incoming damage. * Be aware that for each source of damage, the EH can fire multiple times (once for each hitpoint). - * We store these incoming damages and compare them on our final hitpoint: "ace_hdbracket". + * We store these incoming damages and compare them on last iteration of the event (_context == 2). * * Arguments: * Handle damage EH @@ -13,18 +13,16 @@ * * Public: No */ -// for travis -#define HIT_STRUCTURAL QGVAR($#structural) - -params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint"]; +params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint", "_directHit", "_context"]; // HD sometimes triggers for remote units - ignore. if !(local _unit) exitWith {nil}; // Get missing meta info private _oldDamage = 0; +private _structuralDamage = _context == 0; -if (_hitPoint isEqualTo "") then { +if (_structuralDamage) then { _hitPoint = "#structural"; _oldDamage = damage _unit; } else { @@ -34,74 +32,140 @@ if (_hitPoint isEqualTo "") then { // Damage can be disabled with old variable or via sqf command allowDamage if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {_oldDamage}; -// Damages are stored for "ace_hdbracket" event triggered last private _newDamage = _damage - _oldDamage; -_unit setVariable [format [QGVAR($%1), _hitPoint], _newDamage]; -// Engine damage to these hitpoints controls blood visuals, limping, weapon sway -// Handled in fnc_damageBodyPart, persist here -if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDamage}; +// _newDamage == 0 happens occasionally for vehiclehit events (see line 80 onwards), just exit early to save some frametime +// context 4 is engine "bleeding". For us, it's just a duplicate event for #structural which we can ignore without any issues +if (_context != 2 && {_context == 4 || _newDamage == 0}) exitWith { + TRACE_4("Skipping engine bleeding or zero damage",_ammo,_newDamage,_directHit,_context); + _oldDamage +}; + +// Get scaled armor value of hitpoint and calculate damage before armor +// We scale using passThrough to handle explosive-resistant armor properly (#9063) +// We need realDamage to determine which limb was hit correctly +[_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; +private _realDamage = _newDamage * _armor; +if (!_structuralDamage) then { + private _armorCoef = _armor/_armorScaled; + private _damageCoef = linearConversion [0, 1, GVAR(damagePassThroughEffect), 1, _armorCoef]; + _newDamage = _newDamage * _damageCoef; +}; +TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_directHit,_context); + +// Drowning doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) +// Damage occurs in consistent increments +if ( + _structuralDamage && + {getOxygenRemaining _unit <= 0.5} && + {_damage isEqualTo (_oldDamage + 0.005)} +) exitWith { + TRACE_5("Drowning",_unit,_shooter,_instigator,_damage,_newDamage); + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, "Body", _newDamage]], _unit, "drowning"]] call CBA_fnc_localEvent; + + 0 +}; + +// Faster than (vehicle _unit), also handles dead units +private _vehicle = objectParent _unit; +private _inVehicle = !isNull _vehicle; +private _environmentDamage = _ammo == ""; + +// Crashing a vehicle doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) +// It does fire the EH multiple times, but this seems to scale with the intensity of the crash +if ( + EGVAR(medical,enableVehicleCrashes) && + {_environmentDamage && _inVehicle && _structuralDamage} && + {vectorMagnitude (velocity _vehicle) > 5} + // todo: no way to detect if stationary and another vehicle hits you +) exitWith { + TRACE_5("Crash",_unit,_shooter,_instigator,_damage,_newDamage); + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehiclecrash"]] call CBA_fnc_localEvent; + + 0 +}; + +// Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint +// This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions +if ( + (!_environmentDamage && _inVehicle && _structuralDamage) && + { + private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; + GET_NUMBER(_ammoCfg >> "explosive",0) > 0 || + {GET_NUMBER(_ammoCfg >> "indirectHit",0) > 0} + } +) exitwith { + TRACE_5("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage); -// This hitpoint is set to trigger last, evaluate all the stored damage values -// to determine where wounds are applied -if (_hitPoint isEqualTo "ace_hdbracket") exitWith { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; - private _damageStructural = _unit getVariable [HIT_STRUCTURAL, 0]; + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _shooter, "vehiclehit"]] call CBA_fnc_localEvent; + + 0 +}; + +// Damages are stored for last iteration of the HandleDamage event (_context == 2) +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; + +// Ref https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HandleDamage +// Context 2 means this is the last iteration of HandleDamage, so figure out which hitpoint took the most real damage and send wound event +// Don't exit, as the last iteration can be one of the hitpoints that we need to keep _oldDamage for +if (_context == 2) then { + _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; + _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; + + private _damageStructural = _unit getVariable [QGVAR($#structural), [0,0]]; // --- Head - private _damageFace = _unit getVariable [QGVAR($HitFace), 0]; - private _damageNeck = _unit getVariable [QGVAR($HitNeck), 0]; - private _damageHead = (_unit getVariable [QGVAR($HitHead), 0]) max _damageFace max _damageNeck; + private _damageHead = [ + _unit getVariable [QGVAR($HitFace), [0,0]], + _unit getVariable [QGVAR($HitNeck), [0,0]], + _unit getVariable [QGVAR($HitHead), [0,0]] + ]; + _damageHead sort false; + _damageHead = _damageHead select 0; // --- Body - private _damagePelvis = _unit getVariable [QGVAR($HitPelvis), 0]; - private _damageAbdomen = _unit getVariable [QGVAR($HitAbdomen), 0]; - private _damageDiaphragm = _unit getVariable [QGVAR($HitDiaphragm), 0]; - private _damageChest = _unit getVariable [QGVAR($HitChest), 0]; - private _damageBody = (_unit getVariable [QGVAR($HitBody), 0]) max _damagePelvis max _damageAbdomen max _damageDiaphragm max _damageChest; + private _damageBody = [ + _unit getVariable [QGVAR($HitPelvis), [0,0]], + _unit getVariable [QGVAR($HitAbdomen), [0,0]], + _unit getVariable [QGVAR($HitDiaphragm), [0,0]], + _unit getVariable [QGVAR($HitChest), [0,0]] + // HitBody removed as it's a placeholder hitpoint and the high armor value (1000) throws the calculations off + ]; + _damageBody sort false; + _damageBody = _damageBody select 0; // --- Arms and Legs - private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), 0]; - private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), 0]; - private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), 0]; - private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), 0]; + private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), [0,0]]; + private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), [0,0]]; + private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), [0,0]]; + private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), [0,0]]; - // Find hit point that received the maxium damage - // Priority used for sorting if incoming damage is equivalent (e.g. max which is 4) + // Find hit point that received the maximum damage + // Priority used for sorting if incoming damage is equal + // _realDamage, priority, _newDamage, body part name private _allDamages = [ - [_damageHead, PRIORITY_HEAD, "Head"], - [_damageBody, PRIORITY_BODY, "Body"], - [_damageLeftArm, PRIORITY_LEFT_ARM, "LeftArm"], - [_damageRightArm, PRIORITY_RIGHT_ARM, "RightArm"], - [_damageLeftLeg, PRIORITY_LEFT_LEG, "LeftLeg"], - [_damageRightLeg, PRIORITY_RIGHT_LEG, "RightLeg"] + [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, "Head"], + [_damageBody select 0, PRIORITY_BODY, _damageBody select 1, "Body"], + [_damageLeftArm select 0, PRIORITY_LEFT_ARM, _damageLeftArm select 1, "LeftArm"], + [_damageRightArm select 0, PRIORITY_RIGHT_ARM, _damageRightArm select 1, "RightArm"], + [_damageLeftLeg select 0, PRIORITY_LEFT_LEG, _damageLeftLeg select 1, "LeftLeg"], + [_damageRightLeg select 0, PRIORITY_RIGHT_LEG, _damageRightLeg select 1, "RightLeg"], + [_damageStructural select 0, PRIORITY_STRUCTURAL, _damageStructural select 1, "#structural"] ]; TRACE_2("incoming",_allDamages,_damageStructural); _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"; - }; + _allDamages = _allDamages apply {[_x select 2, _x select 3, _x select 0]}; // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them - if (_ammo isEqualTo "") then { + if (_environmentDamage) then { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { - _ammo = "#collision"; - /* If shooter != unit then they hit unit, otherwise it could be: - Unit hitting anything at speed @@ -110,43 +174,24 @@ 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"]; - TRACE_5("Fall",_unit,_shooter,_instigator,_damage,_receivedDamage); + _ammo = "falling"; + TRACE_5("Fall",_unit,_shooter,_instigator,_damage,_allDamages); } else { - _woundedHitPoint = selectRandom ["RightArm", "LeftArm", "RightLeg", "LeftLeg"]; - TRACE_5("Collision",_unit,_shooter,_instigator,_damage,_receivedDamage); - }; - - // Significant damage suggests high relative velocity - // Momentum transfers to body/head for worse wounding - // 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]; + _ammo = "collision"; + TRACE_5("Collision",_unit,_shooter,_instigator,_damage,_allDamages); }; } else { // Anything else is almost guaranteed to be fire damage - _woundedHitPoint = selectRandom ["LeftLeg", "RightLeg", "Body"]; - _ammo = "#unknown"; - - // Fire damage can occur as lots of minor damage events - // Combine these until significant enough to wound - private _combinedDamage = _receivedDamage + (_unit getVariable [QGVAR(trivialDamage), 0]); - if (_combinedDamage > 0.1) then { - _unit setVariable [QGVAR(trivialDamage), 0]; - _receivedDamage = _combinedDamage; - TRACE_5("Burning",_unit,_shooter,_instigator,_damage,_receivedDamage); - } else { - _unit setVariable [QGVAR(trivialDamage), _combinedDamage]; - _receivedDamage = 0; - }; + _ammo = "fire"; + TRACE_5("Fire Damage",_unit,_shooter,_instigator,_damage,_allDamages); }; }; // 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); + // TODO check if this needs to be changed for burning damage (occurs as lots of small events that we add together) + if ((_allDamages select 0 select 0) > 1E-3) then { + TRACE_1("received",_allDamages); + [QEGVAR(medical,woundReceived), [_unit, _allDamages, _shooter, _ammo]] call CBA_fnc_localEvent; }; // Clear stored damages otherwise they will influence future damage events @@ -156,40 +201,12 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { } forEach [ QGVAR($HitFace),QGVAR($HitNeck),QGVAR($HitHead), QGVAR($HitPelvis),QGVAR($HitAbdomen),QGVAR($HitDiaphragm),QGVAR($HitChest),QGVAR($HitBody), - QGVAR($HitLeftArm),QGVAR($HitRightArm),QGVAR($HitLeftLeg),QGVAR($HitRightLeg) + QGVAR($HitLeftArm),QGVAR($HitRightArm),QGVAR($HitLeftLeg),QGVAR($HitRightLeg), + QGVAR($#structural) ]; - - 0 }; -// Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs -// Damage occurs in consistent increments -if ( - _hitPoint isEqualTo "#structural" && - {getOxygenRemaining _unit <= 0.5} && - {_damage isEqualTo (_oldDamage + 0.005)} -) exitWith { - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning"]] call CBA_fnc_localEvent; - TRACE_5("Drowning",_unit,_shooter,_instigator,_damage,_newDamage); - - 0 -}; - -// Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs -// It does fire the EH multiple times, but this seems to scale with the intensity of the crash -private _vehicle = vehicle _unit; -if ( - _hitPoint isEqualTo "#structural" && - {_ammo isEqualTo ""} && - {_vehicle != _unit} && - {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; - TRACE_5("Crash",_unit,_shooter,_instigator,_damage,_newDamage); - - 0 -}; - -// We store our own damage values so engine damage is unnecessary -0 +// Engine damage to these hitpoints controls blood visuals, limping, weapon sway +// Handled in fnc_damageBodyPart, persist here +// For all other hitpoints, we store our own damage values, so engine damage is unnecessary +[0, _oldDamage] select (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) diff --git a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf new file mode 100644 index 0000000000..cc29e75cc1 --- /dev/null +++ b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Locks the seat of an unconscious or dead unit to prevent automatic unloading. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Public: No + */ +if (missionNamespace getVariable [QGVAR(disableSeatLocking), false]) exitWith {}; +params ["_unit"]; + +private _vehicle = objectParent _unit; +TRACE_3("lockUnconsciousSeat",_unit,_vehicle,lifeState _unit); + +if (isNull _vehicle) exitWith {}; +if (alive _unit && {lifeState _unit != "INCAPACITATED"}) exitWith {}; + +switch (true) do { + case (_unit isEqualTo (driver _vehicle)): { + _vehicle lockDriver true; + _unit setVariable [QGVAR(lockedSeat), [_vehicle, "driver"], true]; + }; + + case (_vehicle getCargoIndex _unit != -1): { + private _cargoIndex = _vehicle getCargoIndex _unit; + _vehicle lockCargo [_cargoIndex, true]; + _unit setVariable [QGVAR(lockedSeat), [_vehicle, "cargo", _cargoIndex], true]; + }; + + case ((_vehicle unitTurret _unit) isNotEqualTo []): { + private _turretPath = _vehicle unitTurret _unit; + _vehicle lockTurret [_turretPath, true]; + _unit setVariable [QGVAR(lockedSeat), [_vehicle, "turret", _turretPath], true]; + }; +}; +TRACE_1("locked",_unit getVariable QGVAR(lockedSeat)); diff --git a/addons/medical_engine/functions/fnc_setStructuralDamage.sqf b/addons/medical_engine/functions/fnc_setStructuralDamage.sqf index 5e3dcd7b05..6094c3d78e 100644 --- a/addons/medical_engine/functions/fnc_setStructuralDamage.sqf +++ b/addons/medical_engine/functions/fnc_setStructuralDamage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Set structural damage of an object without modifying the individual hit points. @@ -18,9 +18,7 @@ params [["_unit", objNull, [objNull]], ["_damage", 0, [0]]]; -if (!local _unit) exitWith { - ERROR("Unit not local or null"); -}; +if (!local _unit) exitWith { ERROR_2("setStructuralDamage: Unit not local or null [%1:%2]",_unit,typeOf _unit); }; private _hitPointDamages = getAllHitPointsDamage _unit param [2, []]; diff --git a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf index aa7f3f7db5..4ed63253c7 100644 --- a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf +++ b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Force local unit into ragdoll / unconsciousness animation. @@ -17,42 +17,51 @@ */ 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; if (_isUnconscious) then { // eject from static weapon - if (vehicle _unit isKindOf "StaticWeapon") then { + if (vehicle _unit isKindOf "StaticWeapon" && {!(vehicle _unit isKindOf "Pod_Heli_Transport_04_crewed_base_F")}) then { + TRACE_2("ejecting from static weapon",_unit,vehicle _unit); [_unit] call EFUNC(common,unloadPerson); }; // set animation inside vehicles - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { private _unconAnim = _unit call EFUNC(common,getDeathAnim); + TRACE_2("inVehicle - playing death anim",_unit,_unconAnim); [_unit, _unconAnim] call EFUNC(common,doAnimation); }; } else { // reset animation inside vehicles - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { private _awakeAnim = _unit call EFUNC(common,getAwakeAnim); + TRACE_2("inVehicle - playing awake anim",_unit,_awakeAnim); [_unit, _awakeAnim, 2] call EFUNC(common,doAnimation); } else { // and on foot - [_unit, "AmovPpneMstpSnonWnonDnon"] call EFUNC(common,doAnimation); + TRACE_1("onfoot - playing standard anim",_unit); + [_unit, "AmovPpneMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation); if (currentWeapon _unit == secondaryWeapon _unit && {currentWeapon _unit != ""}) then { - [_unit, "AmovPknlMstpSrasWlnrDnon"] call EFUNC(common,doAnimation); + [_unit, "AmovPknlMstpSrasWlnrDnon", 2] call EFUNC(common,doAnimation); }; [{ 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) + private _animation = animationState _unit; + if ((_animation == "unconscious" || {_animation == "deadstate" || {_animation find QGVAR(uncon_anim) != -1}}) && {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_unlockUnconsciousSeat.sqf b/addons/medical_engine/functions/fnc_unlockUnconsciousSeat.sqf new file mode 100644 index 0000000000..5214a32201 --- /dev/null +++ b/addons/medical_engine/functions/fnc_unlockUnconsciousSeat.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Unlocks the seat of an unconscious or dead unit after getting moved out or waking up. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Public: No + */ +params ["_unit"]; + +private _seat = _unit getVariable [QGVAR(lockedSeat), []]; +_seat params ["_vehicle", "_type", "_position"]; + +TRACE_2("unlockUnconsciousSeat",_unit,_seat); +if (_seat isEqualTo []) exitWith {}; + +switch (_type) do { + case "driver": { + _vehicle lockDriver false; + }; + + case "cargo": { + _vehicle lockCargo [_position, false]; + }; + + case "turret": { + _vehicle lockTurret [_position, false]; + }; +}; + +_unit setVariable [QGVAR(lockedSeat), nil, true]; diff --git a/addons/medical_engine/functions/fnc_updateBodyPartVisuals.sqf b/addons/medical_engine/functions/fnc_updateBodyPartVisuals.sqf index 3e240b807b..a4403ffa7d 100644 --- a/addons/medical_engine/functions/fnc_updateBodyPartVisuals.sqf +++ b/addons/medical_engine/functions/fnc_updateBodyPartVisuals.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Damages a body part of a local unit. Does not kill the unit. diff --git a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf index 9adfc2e855..7dc73e04f4 100644 --- a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf +++ b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf @@ -1,11 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, PabstMirror - * Updates damage effects for limping and fractures + * Updates damage effects for limping and fractures. * * Arguments: * 0: Unit - * 1: Limping (optional, default: true) * * Return Value: * None @@ -18,7 +17,7 @@ params [["_unit", objNull, [objNull]]]; -if (!local _unit) exitWith { ERROR("Unit not local or null"); }; +if (!local _unit) exitWith { ERROR_2("updateDamageEffects: Unit not local or null [%1:%2]",_unit,typeOf _unit); }; private _isLimping = false; @@ -33,31 +32,47 @@ if (EGVAR(medical,fractures) > 0) then { 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 (EGVAR(medical,fractures) in [2, 3]) then { // the limp with a splint will still cause effects + // Block sprint / force walking based on fracture setting and leg splint status + private _hasLegSplint = (_fractures select 4) == -1 || {(_fractures select 5) == -1}; + if (EGVAR(medical,fractures) == 2) then { + [_unit, "blockSprint", QEGVAR(medical,fracture), _hasLegSplint] call EFUNC(common,statusEffect_set); + } else { + [_unit, "forceWalk", QEGVAR(medical,fracture), _hasLegSplint] call EFUNC(common,statusEffect_set); }; - if ((_fractures select 2) == 1) then { _aimFracture = _aimFracture + 2; }; - if ((_fractures select 3) == 1) then { _aimFracture = _aimFracture + 2; }; + + 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); + private _openWounds = GET_OPEN_WOUNDS(_unit); + + // Want a copy of combined arrays to prevent wound mixing + private _legWounds = (_openWounds getOrDefault ["leftleg", []]) + + (_openWounds getOrDefault ["rightleg", []]); + if (EGVAR(medical,limping) == 2) then { - _woundsToCheck = _woundsToCheck + GET_BANDAGED_WOUNDS(_unit); // do not append + private _bandagedWounds = GET_BANDAGED_WOUNDS(_unit); + _legWounds = _legWounds + + (_bandagedWounds getOrDefault ["leftleg", []]) + + (_bandagedWounds getOrDefault ["rightleg", []]); }; + { - _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 + _x params ["_xClassID", "_xAmountOf", "", "_xDamage"]; + if ( + (_xAmountOf > 0) + && {_xDamage > LIMPING_DAMAGE_THRESHOLD} + // select _causeLimping from woundDetails + && {(EGVAR(medical_damage,woundDetails) get (_xClassID / 10)) select 3} + ) exitWith { TRACE_1("limping because of wound",_x); _isLimping = true; }; - } forEach _woundsToCheck; + } forEach _legWounds; }; _unit setVariable [QEGVAR(medical,isLimping), _isLimping, true]; diff --git a/addons/medical_engine/functions/script_component.hpp b/addons/medical_engine/functions/script_component.hpp deleted file mode 100644 index c28da622f0..0000000000 --- a/addons/medical_engine/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_engine\script_component.hpp" diff --git a/addons/medical_engine/initSettings.inc.sqf b/addons/medical_engine/initSettings.inc.sqf new file mode 100644 index 0000000000..062e2a0822 --- /dev/null +++ b/addons/medical_engine/initSettings.inc.sqf @@ -0,0 +1,17 @@ +[ + QEGVAR(medical,enableVehicleCrashes), + "CHECKBOX", + [LSTRING(EnableVehicleCrashes_DisplayName), LSTRING(EnableVehicleCrashes_Description)], + ELSTRING(medical,Category), + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(damagePassThroughEffect), + "SLIDER", + [LSTRING(damagePassThroughEffect_displayName), LSTRING(damagePassThroughEffect_description)], + ELSTRING(medical,Category), + [0, 1, 1, 2, true], + true +] call CBA_fnc_addSetting; diff --git a/addons/medical_engine/script_component.hpp b/addons/medical_engine/script_component.hpp index 5166324b1e..59cd015080 100644 --- a/addons/medical_engine/script_component.hpp +++ b/addons/medical_engine/script_component.hpp @@ -19,11 +19,11 @@ #include "\z\ace\addons\medical_engine\script_macros_config.hpp" #define PRELOAD_CLASS(class) \ - INFO_1("Starting preload for (%1)",class);\ + TRACE_1("Starting preload",class);\ [{\ 1 preloadObject _this;\ }, {\ - INFO_1("Preload done for (%1)",_this);\ + TRACE_1("Preload done",_this);\ }, class] call CBA_fnc_waitUntilAndExecute #define PRIORITY_HEAD 3 @@ -32,7 +32,11 @@ #define PRIORITY_RIGHT_ARM (1 + random 1) #define PRIORITY_LEFT_LEG (1 + random 1) #define PRIORITY_RIGHT_LEG (1 + random 1) +#define PRIORITY_STRUCTURAL 1 // don't change, these reflect hard coded engine behaviour #define DAMAGED_MIN_THRESHOLD 0.45 #define LIMPING_MIN_DAMAGE 0.5 + +#define UNCON_ANIM(var1) DOUBLES(GVAR(uncon_anim),var1) +#define QUNCON_ANIM(var1) QUOTE(UNCON_ANIM(var1)) diff --git a/addons/medical_engine/script_macros_config.hpp b/addons/medical_engine/script_macros_config.hpp index b29f9dd958..4c276d7b18 100644 --- a/addons/medical_engine/script_macros_config.hpp +++ b/addons/medical_engine/script_macros_config.hpp @@ -7,58 +7,37 @@ class My_AwesomeUnit_base; class My_AwesomeUnit: My_AwesomeUnit_base { class HitPoints { - ADD_ACE_HITPOINTS(2,2); + class HitHands; + class HitLegs; + ADD_ACE_HITPOINTS; }; }; }; */ // Our method for adding left and right arm and leg armor. Uses those selections -// that are used for animations and therefore exist in all third party units -// usage: arm_armor and leg_armor are the armor values of of HitHands and -// HitLegs respectively. -// "ACE_HDBracket" is a special hit point. It is designed in a way where the -// "HandleDamage" event handler will compute it at the end of every damage -// calculation step. This way we can figure out which hit point took the most -// damage from one projectile and should be receiving the ACE medical wound. -// the hit point itself should not take any damage -// It is important that the "ACE_HDBracket" hit point is the last in the config, -// but has the same selection as the first one (always "HitHead" for soldiers). -#define ADD_ACE_HITPOINTS(arm_armor,leg_armor)\ - class HitLeftArm {\ - armor = arm_armor;\ +// that are used for animations and therefore exist in all third party units. +// This used to take the armor values as parameters; it now inherits the values +// of `armor`, `passThrough` and `explosionShielding` from the existing hitpoints +// for vanilla consistency. +#define ADD_ACE_HITPOINTS\ + class HitLeftArm: HitHands {\ material = -1;\ name = "hand_l";\ - passThrough = 1;\ radius = 0.08;\ - explosionShielding = 1;\ visual = "injury_hands";\ minimalHit = 0.01;\ };\ class HitRightArm: HitLeftArm {\ name = "hand_r";\ };\ - class HitLeftLeg {\ - armor = leg_armor;\ + class HitLeftLeg: HitLegs {\ material = -1;\ name = "leg_l";\ - passThrough = 1;\ radius = 0.1;\ - explosionShielding = 1;\ visual = "injury_legs";\ minimalHit = 0.01;\ };\ class HitRightLeg: HitLeftLeg {\ name = "leg_r";\ - };\ - class ACE_HDBracket {\ - armor = 1;\ - material = -1;\ - name = "head";\ - passThrough = 0;\ - radius = 1;\ - explosionShielding = 1;\ - visual = "";\ - minimalHit = 0;\ - depends = "HitHead";\ } diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index 13084d8ae0..167765c576 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -4,15 +4,28 @@ #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 ALL_HITPOINTS ["HitHead", "HitChest", "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 +#define HEAD_DAMAGE_THRESHOLD EGVAR(medical,const_headDamageThreshold) +#define HEAD_DAMAGE_THRESHOLD_DEFAULT 1 +#define ORGAN_DAMAGE_THRESHOLD EGVAR(medical,const_organDamageThreshold) +#define ORGAN_DAMAGE_THRESHOLD_DEFAULT 0.6 +// Consts for determineIfFatal: sum of damage (values are calcualted at runtime in preInit) +#define FATAL_SUM_DAMAGE_WEIBULL_K EGVAR(medical,const_fatalSumDamageWeibull_K) +#define FATAL_SUM_DAMAGE_WEIBULL_L EGVAR(medical,const_fatalSumDamageWeibull_L) // Chance to hit heart based on ratio of 70kg (approx. 70L) body to 70mL stroke volume of heart // Assuming torso is 50% of the body volume (35L) -#define HEART_HIT_CHANCE 0.05 +#define HEART_HIT_CHANCE EGVAR(medical,const_heartHitChance) +#define HEART_HIT_CHANCE_DEFAULT 0.05 #define MEDICAL_ACTION_DISTANCE 1.75 @@ -29,6 +42,7 @@ #define GET_ARRAY(config,default) (if (isArray (config)) then {getArray (config)} else {default}) #define DEFAULT_HEART_RATE 80 +#define DEFAULT_SPO2 97 #define DEFAULT_PERIPH_RES 100 // --- blood @@ -39,17 +53,24 @@ #define BLOOD_VOLUME_CLASS_2_HEMORRHAGE 5.100 // lost more than 15% blood, Class II Hemorrhage #define BLOOD_VOLUME_CLASS_3_HEMORRHAGE 4.200 // lost more than 30% blood, Class III Hemorrhage #define BLOOD_VOLUME_CLASS_4_HEMORRHAGE 3.600 // lost more than 40% blood, Class IV Hemorrhage -#define BLOOD_VOLUME_FATAL 3.0 // Lost more than 50% blood, Unrecoverable +// Lost more than 50% blood, Unrecoverable +#define BLOOD_VOLUME_FATAL 3.0 + +// Minimum blood volume, in liters, for a patient to have the chance to wake up +#define MINIMUM_BLOOD_FOR_STABLE_VITALS EGVAR(medical,const_stableVitalsBloodThreshold) +#define MINIMUM_BLOOD_FOR_STABLE_VITALS_DEFAULT BLOOD_VOLUME_CLASS_2_HEMORRHAGE // IV Change per second calculation: // 250 ml should take 60 seconds to fill. 250 ml / 60 s ~ 4.1667 ml/s. #define IV_CHANGE_PER_SECOND 4.1667 // in milliliters per second // Minimum amount of damage required for penetrating wounds (also minDamage for velocity wounds) -#define PENETRATION_THRESHOLD 0.35 +#define PENETRATION_THRESHOLD EGVAR(medical,const_penetrationThreshold) +#define PENETRATION_THRESHOLD_DEFAULT 0.35 // To be replaced by a proper blood pressure calculation -#define BLOOD_LOSS_KNOCK_OUT_THRESHOLD 0.5 // 50% of cardiac output +#define BLOOD_LOSS_KNOCK_OUT_THRESHOLD EGVAR(medical,const_bloodLossKnockOutThreshold) +#define BLOOD_LOSS_KNOCK_OUT_THRESHOLD_DEFAULT 0.5 // 50% of cardiac output // Used to color interaction icons and body image selections #define BLOOD_LOSS_RED_THRESHOLD 0.5 @@ -57,31 +78,46 @@ #define DAMAGE_BLUE_THRESHOLD 0.8 #define DAMAGE_TOTAL_COLORS 10 -// --- pain -#define PAIN_UNCONSCIOUS 0.5 +// Qualitative bleed rate thresholds as a fraction of knock out blood loss +// Note that half of knock out blood loss is considered unstable, and knock out blood loss is considered critical +#define BLEED_RATE_SLOW 0.1 // Slow - One fifth of unstable blood loss +#define BLEED_RATE_MODERATE 0.5 // Moderate - Vitals considered stable +#define BLEED_RATE_SEVERE 1.0 // Severe - Vitals considered unstable +// Massive - Vitals considered critical + +// Pain above which a unit can go unconscious upon receiving damage +#define PAIN_UNCONSCIOUS EGVAR(medical,painUnconsciousThreshold) // Pain fade out time (time it takes until pain is guaranteed to be completly gone) -#define PAIN_FADE_TIME 900 +#define PAIN_FADE_TIME EGVAR(medical,const_painFadeTime) +#define PAIN_FADE_TIME_DEFAULT 900 // Only relevant when advanced medication is disabled // Morphine pain suppression fade out time (time it takes until pain suppression is guaranteed to be completly gone) #define PAIN_SUPPRESSION_FADE_TIME 1800 // Chance to wake up when vitals are stable (checked once every SPONTANEOUS_WAKE_UP_INTERVAL seconds) -#define SPONTANEOUS_WAKE_UP_INTERVAL 15 +#define SPONTANEOUS_WAKE_UP_INTERVAL EGVAR(medical,const_wakeUpCheckInterval) +#define SPONTANEOUS_WAKE_UP_INTERVAL_DEFAULT 15 // Minimum leg damage required for limping -#define LIMPING_DAMAGE_THRESHOLD 0.30 +#define LIMPING_DAMAGE_THRESHOLD EGVAR(medical,const_limpingDamageThreshold) +#define LIMPING_DAMAGE_THRESHOLD_DEFAULT 0.30 // Minimum limb damage required for fracture -#define FRACTURE_DAMAGE_THRESHOLD 0.50 +#define FRACTURE_DAMAGE_THRESHOLD EGVAR(medical,const_fractureDamageThreshold) +#define FRACTURE_DAMAGE_THRESHOLD_DEFAULT 0.50 + +// Minimum cardiac output +#define CARDIAC_OUTPUT_MIN EGVAR(medical,const_minCardiacOutput) +#define CARDIAC_OUTPUT_MIN_DEFAULT 0.05 // Minimum body part damage required for blood effect on uniform #define VISUAL_BODY_DAMAGE_THRESHOLD 0.35 // Empty wound data, used for some default return values -// [classID, bodypartIndex, amountOf, bloodloss, damage] -#define EMPTY_WOUND [-1, -1, 0, 0, 0] +// [classID, amountOf, bloodloss, damage] +#define EMPTY_WOUND [-1, 0, 0, 0] // Base time to bandage each wound category #define BANDAGE_TIME_S 4 @@ -123,6 +159,8 @@ #define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding) #define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest) #define VAR_HEART_RATE QEGVAR(medical,heartRate) +#define VAR_SPO2 QEGVAR(medical,spo2) +#define VAR_OXYGEN_DEMAND QEGVAR(medical,oxygenDemand) #define VAR_PAIN QEGVAR(medical,pain) #define VAR_PAIN_SUPP QEGVAR(medical,painSuppress) #define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance) @@ -145,6 +183,7 @@ #define GET_BLOOD_VOLUME(unit) (unit getVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME]) #define GET_WOUND_BLEEDING(unit) (unit getVariable [VAR_WOUND_BLEEDING, 0]) #define GET_HEART_RATE(unit) (unit getVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE]) +#define GET_SPO2(unit) (unit getVariable [VAR_SPO2, DEFAULT_SPO2]) #define GET_HEMORRHAGE(unit) (unit getVariable [VAR_HEMORRHAGE, 0]) #define GET_PAIN(unit) (unit getVariable [VAR_PAIN, 0]) #define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP, 0]) @@ -154,9 +193,10 @@ #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 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, []]) +#define GET_OPEN_WOUNDS(unit) (unit getVariable [VAR_OPEN_WOUNDS, createHashMap]) +#define GET_BANDAGED_WOUNDS(unit) (unit getVariable [VAR_BANDAGED_WOUNDS, createHashMap]) +#define GET_STITCHED_WOUNDS(unit) (unit getVariable [VAR_STITCHED_WOUNDS, createHashMap]) +#define GET_DAMAGE_THRESHOLD(unit) (unit getVariable [QEGVAR(medical,damageThreshold), [EGVAR(medical,AIDamageThreshold),EGVAR(medical,playerDamageThreshold)] select (isPlayer unit)]) // 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_engine/stringtable.xml b/addons/medical_engine/stringtable.xml new file mode 100644 index 0000000000..cf19713202 --- /dev/null +++ b/addons/medical_engine/stringtable.xml @@ -0,0 +1,55 @@ + + + + + Enable Vehicle Crash Damage + Вкл. урон при аварии в транспорте + Activar daño por accidente de vehículo + Blessures de collision (véhicules) + Włącz obrażenia od kolizji pojazdu + 車両衝突ダメージを有効化 + Aktiviere Verletzungen durch Fahrzeugunfälle + Abilita danni da schianti del veicolo + 启用车辆碰撞损坏 + 차량 충돌 피해 활성화 + Habilitar Dano por Colisão de Veículo + + + Controls whether crew receives damage from vehicle collisions. + Контролирует, получает ли экипаж урон от столкновения транспортного средства. + Controla si la tripulación recibe daño debido a colisiones en vehículo. + Définit si les passagers à bord des véhicules peuvent être blessés en cas d'accident. + Kontroluje czy załoga pojazdu otrzyma obrażenia podczas kolizji pojazdu. + 車両が衝突をすると乗員がダメージを受けるかどうかを制御します。 + Kontrolliert, ob Besatzung eines Fahrzeugs Schaden durch Unfälle erleiden soll + Determina se i passeggeri di un veicolo subiranno danni da schianti o incidenti. + 控制乘员是否受到车辆碰撞的伤害。 + 차량 충돌로 인해 탑승인원들이 피해를 받을 지 결정합니다. + Controla se a tripulação recebe dano de colisões de veículos. + + + Armor PassThrough Effect + Efekt penetracji pancerza + 방어구 PassThrough 효과 + Effet de pénétration d'armure + Effekt des Panzerungsdurchschlags + Fattore di Trapasso Armatura + Efeito de Penetração de Blindagem + 装甲貫通効果 + Эффект сквозного прохождения брони + Efecto de Atravesar Armadura + + + Controls effect of armor 'passThrough' on final damage. Makes high armor values, like ones used in GL rigs, less effective.\nUse 0% for pre 3.16.0 armor behavior.\nOnly touch this if you know what you're doing! + Kontroluje wpływ "penetracji" pancerza na ostateczne obrażenia. Sprawia, że wysokie wartości pancerza, takie jak te używane w kamizelkach GL, są mniej skuteczne.\nUżyj 0% dla zachowania pancerza sprzed wersji 3.16.0.\nZmień wartość tylko jeśli wiesz co robisz! + 최종 데미지에 대한 방어구의 'PassThrough' 효과를 조정합니다. GL 리그에 사용되는 것과 같은 높은 방호값을 덜 효과적으로 만듭니다\n3.16.0 이전의 방어구 동작에는 0%를 사용하십시오.\n당신이 뭘 하고 있는지 알고 있는 경우에만 이걸 설정하세요! + Contrôle l'effet de la "pénétration" de l'armure sur les dégâts finaux. Rend les valeurs d'armures élevées, comme celles utilisées dans les gilets GL, moins efficaces.\nUtilisez 0% pour le comportement des armures des versions antérieures à 3.16.0.\nNe modifiez la valeur que si vous savez ce que vous faîtes ! + Steuert den Effekt des „Durchschlagens“ von Panzerung auf den Gesamtschaden. Macht hohe Panzerungswerte, wie sie in GL-Westen verwendet werden, weniger effektiv.\nVerwende 0% für das Panzerungsverhalten vor 3.16.0.\nÄndere den Wert nur, wenn du weißt, was du tust! + Determina l'effetto di danni sul corpo che 'trapassano' l'armatura. Rende alti valori di protezione, come quelli su corpetti GL, meno efficaci.\nUtilizza 0% per il comportamento prima di v3.16.0.\nModifica questo valore solo se sai cosa stai facendo! + Controla o efeito de penetração (passThrough) da blindagem no dano final. Torna valores de blindagem altos, como os usados em coletes GL, menos eficazes.\nUse 0% para o comportamento de blindagem anterior à versão 3.16.0.\nSó mexa nisso se souber o que está fazendo! + ボディアーマーの'passThrough'値が最終的な身体ダメージに与える影響を調整します。擲弾兵リグで使用されるような高い装甲値では効果が低くなります。\n3.16.0以前の挙動にするには0%にしてください。\nこれが何かわからない場合は変更しないことをお勧めします。 + Контролирует эффект `passThrough` при нанесении конечного урона. Делает высокие значения брони, подобные тем, которые используются в GL rigs, менее эффективными.\nИспользуйте 0% для поведения брони до версии 3.16.0.n\Прикасайтесь к этому, только если знаете, что делаете! + Controla el efecto de 'passThrough' de armadura en el daño final. Hace que los valores altos de armadura, como los usados en los chalecos GL, sean menos efectivos.\nUsar 0% para comportamiento de armadura en versiones anteriores a 3.16.0.\nSólo modifica esto si sabes lo que estás haciendo! + + + diff --git a/addons/medical_feedback/ACE_Settings.hpp b/addons/medical_feedback/ACE_Settings.hpp deleted file mode 100644 index a42a2d0e59..0000000000 --- a/addons/medical_feedback/ACE_Settings.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class ACE_Settings { - /* - // Not currently used anywhere - class GVAR(enableScreams) { - category = ECSTRING(medical,Category_Medical); - displayName = CSTRING(enableScreams_DisplayName); - description = CSTRING(enableScreams_Description); - typeName = "BOOL"; - value = 1; - }; - */ -}; diff --git a/addons/medical_feedback/CfgEventHandlers.hpp b/addons/medical_feedback/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/medical_feedback/CfgEventHandlers.hpp +++ b/addons/medical_feedback/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_feedback/CfgSounds.hpp b/addons/medical_feedback/CfgSounds.hpp index be641ef27f..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,6 +35,8 @@ 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}; @@ -54,4 +57,2204 @@ class CfgSounds { 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/RscInGameUI.hpp b/addons/medical_feedback/RscInGameUI.hpp new file mode 100644 index 0000000000..ca422840a7 --- /dev/null +++ b/addons/medical_feedback/RscInGameUI.hpp @@ -0,0 +1,40 @@ +// Workaround required for new HEMTT, vanilla macros requires the use of auto-quote +#undef IGUI_GRID_STANCE_X +#undef IGUI_GRID_STANCE_Y +#define ace_IGUI_GRID_STANCE_X (profilenamespace getvariable ['IGUI_GRID_STANCE_X',IGUI_GRID_STANCE_XDef]) +#define ace_IGUI_GRID_STANCE_Y (profilenamespace getvariable ['IGUI_GRID_STANCE_Y',IGUI_GRID_STANCE_YDef]) + +class RscPictureKeepAspect; +class RscInGameUI { + class RscStanceInfo { + controls[] += { + QGVAR(bloodVolumeIndicator), + QGVAR(stateIndicator1), + QGVAR(stateIndicator2), + QGVAR(stateIndicator3) + }; + class GVAR(bloodVolumeIndicator): RscPictureKeepAspect { + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(bloodVolumeIndicator),_this select 0)]); + x = QUOTE(ace_IGUI_GRID_STANCE_X); + y = QUOTE(ace_IGUI_GRID_STANCE_Y); + w = QUOTE(IGUI_GRID_STANCE_WAbs / 4); + h = QUOTE(IGUI_GRID_STANCE_HAbs / 4); + }; + + class GVAR(stateIndicator1): RscPictureKeepAspect { + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(stateIndicator1),_this select 0)]); + x = QUOTE(ace_IGUI_GRID_STANCE_X + IGUI_GRID_STANCE_WAbs * 3 / 4); + y = QUOTE(ace_IGUI_GRID_STANCE_Y); + w = QUOTE(IGUI_GRID_STANCE_WAbs / 4); + h = QUOTE(IGUI_GRID_STANCE_HAbs / 4); + }; + class GVAR(stateIndicator2): GVAR(stateIndicator1) { + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(stateIndicator2),_this select 0)]); + y = QUOTE(ace_IGUI_GRID_STANCE_Y + IGUI_GRID_STANCE_HAbs / 4); + }; + class GVAR(stateIndicator3): GVAR(stateIndicator1) { + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(stateIndicator3),_this select 0)]); + y = QUOTE(ace_IGUI_GRID_STANCE_Y + IGUI_GRID_STANCE_HAbs * 2 / 4); + }; + }; +}; diff --git a/addons/medical_feedback/XEH_PREP.hpp b/addons/medical_feedback/XEH_PREP.hpp index ee4b453bbe..85dcd64d43 100644 --- a/addons/medical_feedback/XEH_PREP.hpp +++ b/addons/medical_feedback/XEH_PREP.hpp @@ -1,9 +1,11 @@ PREP(effectBleeding); PREP(effectBloodVolume); +PREP(effectBloodVolumeIcon); PREP(effectHeartBeat); PREP(effectIncapacitated); PREP(effectPain); PREP(effectUnconscious); +PREP(handleHUDIndicators); PREP(handleEffects); PREP(initEffects); PREP(playInjuredSound); diff --git a/addons/medical_feedback/XEH_postInit.sqf b/addons/medical_feedback/XEH_postInit.sqf index 37b2c4c2e6..f01394e919 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), { @@ -10,21 +14,23 @@ [_unit, "moan", PAIN_TO_MOAN(_painLevel)] call FUNC(playInjuredSound); }] call CBA_fnc_addEventHandler; +if (!hasInterface) exitWith {}; + [QEGVAR(medical,fracture), { params ["_unit"]; - if (_unit == ACE_player) then { playSound SND_FRACTURE; }; }] call CBA_fnc_addEventHandler; -if (!hasInterface) exitWith {}; - 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); +[LINKFUNC(handleEffects), 1, false] call CBA_fnc_addPerFrameHandler; ["ace_unconscious", { params ["_unit", "_unconscious"]; @@ -37,18 +43,14 @@ GVAR(heartBeatEffectRunning) = false; ACE_player switchCamera "INTERNAL"; }; - // Toggle unconscious player's ability to talk in radio addons - if (["task_force_radio"] call EFUNC(common,isModLoaded)) then { - _unit setVariable ["tf_voiceVolume", [1, 0] select _unconscious, true]; - _unit setVariable ["tf_unable_to_use_radio", _unconscious]; // Only used locally - }; - if (["acre_main"] call EFUNC(common,isModLoaded)) then { - _unit setVariable ["acre_sys_core_isDisabled", _unconscious, true]; - }; + [!_unconscious, _unit] call EFUNC(common,setVolume); + // Greatly reduce player's hearing ability while unconscious (affects radio addons) - [QUOTE(ADDON), VOL_UNCONSCIOUS, _unconscious] call EFUNC(common,setHearingCapability); + private _volume = missionNamespace getVariable [QEGVAR(hearing,unconsciousnessVolume), VOL_UNCONSCIOUS]; + [QUOTE(ADDON), _volume, _unconscious] call EFUNC(common,setHearingCapability); [_unconscious, 1] call FUNC(effectUnconscious); + [true] call FUNC(handleEffects); ["unconscious", _unconscious] call EFUNC(common,setDisableUserInputStatus); }] call CBA_fnc_addEventHandler; @@ -57,13 +59,9 @@ GVAR(heartBeatEffectRunning) = false; params ["_unit"]; if (_unit != ACE_player) exitWith {}; - if (["task_force_radio"] call EFUNC(common,isModLoaded)) then { - _unit setVariable ["tf_voiceVolume", 1, true]; - _unit setVariable ["tf_unable_to_use_radio", false]; - }; - if (["acre_main"] call EFUNC(common,isModLoaded)) then { - _unit setVariable ["acre_sys_core_isDisabled", false, true]; - }; + // Players always able to hear for any systems that might run while dead (e.g. spectator) + [true, _unit] call EFUNC(common,setVolume); + [QUOTE(ADDON), 1, false] call EFUNC(common,setHearingCapability); }] call CBA_fnc_addEventHandler; @@ -72,18 +70,55 @@ GVAR(heartBeatEffectRunning) = false; params ["_new"]; private _status = IS_UNCONSCIOUS(_new); - if (["task_force_radio"] call EFUNC(common,isModLoaded)) then { - _new setVariable ["tf_voiceVolume", [1, 0] select _status, true]; - _new setVariable ["tf_unable_to_use_radio", _status]; - }; - if (["acre_main"] call EFUNC(common,isModLoaded)) then { - _new setVariable ["acre_sys_core_isDisabled", _status, true]; - }; - [QUOTE(ADDON), VOL_UNCONSCIOUS, _status] call EFUNC(common,setHearingCapability); - [_status, 0] call FUNC(effectUnconscious); + [!_status, _new] call EFUNC(common,setVolume); + + private _volume = missionNamespace getVariable [QEGVAR(hearing,unconsciousnessVolume), VOL_UNCONSCIOUS]; + [QUOTE(ADDON), _volume, _status] call EFUNC(common,setHearingCapability); + [true] call FUNC(handleEffects); ["unconscious", _status] call EFUNC(common,setDisableUserInputStatus); }] call CBA_fnc_addPlayerEventHandler; +// Update effects for featureCamera (curator, arsenal, etc) +["featureCamera", { + params ["_unit", "_newCamera"]; + + [true] call FUNC(handleEffects); + + private _volume = missionNamespace getVariable [QEGVAR(hearing,unconsciousnessVolume), VOL_UNCONSCIOUS]; + + if (_newCamera == "") then { // switched back to player view + private _status = IS_UNCONSCIOUS(_unit); + [!_status, _unit] call EFUNC(common,setVolume); + [QUOTE(ADDON), _volume, _status] call EFUNC(common,setHearingCapability); + ["unconscious", _status] call EFUNC(common,setDisableUserInputStatus); + } else { // camera view + [true, _unit] call EFUNC(common,setVolume); + [QUOTE(ADDON), 1, false] call EFUNC(common,setHearingCapability); + ["unconscious", false] call EFUNC(common,setDisableUserInputStatus); + }; +}] call CBA_fnc_addPlayerEventHandler; + +// Forced say3D +[QGVAR(forceSay3D), { + params ["_unit", "_sound", "_distance"]; + + if (ACE_player distance _unit > _distance) exitWith {}; + + if (isNull objectParent _unit) then { + // say3D waits for the previous sound to finish, so use a dummy instead + private _dummy = "#dynamicsound" createVehicleLocal [0, 0, 0]; + _dummy attachTo [_unit, [0, 0, 0], "camera"]; + _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 8572cef792..894773534a 100644 --- a/addons/medical_feedback/XEH_preInit.sqf +++ b/addons/medical_feedback/XEH_preInit.sqf @@ -6,745 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" 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",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_2",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_3",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_4",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_5",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_6",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_7",1.5848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_8",1.5848932,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] -]]]; +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/medical_feedback/addon.toml b/addons/medical_feedback/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_feedback/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_feedback/config.cpp b/addons/medical_feedback/config.cpp index f56bf8e99f..d6e78aebbf 100644 --- a/addons/medical_feedback/config.cpp +++ b/addons/medical_feedback/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -14,9 +22,11 @@ class CfgPatches { }; }; -// #include "ACE_Settings.hpp" // ToDo: setting not used #include "CfgEventHandlers.hpp" #include "CfgInGameUI.hpp" #include "CfgSounds.hpp" #include "CfgVehicles.hpp" #include "RscTitles.hpp" +#include "RscInGameUI.hpp" + +#endif diff --git a/addons/medical_feedback/data/bloodVolume_1.paa b/addons/medical_feedback/data/bloodVolume_1.paa new file mode 100644 index 0000000000..04ddeaae2c Binary files /dev/null and b/addons/medical_feedback/data/bloodVolume_1.paa differ diff --git a/addons/medical_feedback/data/bloodVolume_2.paa b/addons/medical_feedback/data/bloodVolume_2.paa new file mode 100644 index 0000000000..550d510271 Binary files /dev/null and b/addons/medical_feedback/data/bloodVolume_2.paa differ diff --git a/addons/medical_feedback/data/bloodVolume_3.paa b/addons/medical_feedback/data/bloodVolume_3.paa new file mode 100644 index 0000000000..8a24a5692a Binary files /dev/null and b/addons/medical_feedback/data/bloodVolume_3.paa differ diff --git a/addons/medical_feedback/data/bloodVolume_4.paa b/addons/medical_feedback/data/bloodVolume_4.paa new file mode 100644 index 0000000000..c859576881 Binary files /dev/null and b/addons/medical_feedback/data/bloodVolume_4.paa differ diff --git a/addons/medical_feedback/data/bloodVolume_5.paa b/addons/medical_feedback/data/bloodVolume_5.paa new file mode 100644 index 0000000000..7f2061a31a Binary files /dev/null and b/addons/medical_feedback/data/bloodVolume_5.paa differ diff --git a/addons/medical_feedback/data/bloodVolume_6.paa b/addons/medical_feedback/data/bloodVolume_6.paa new file mode 100644 index 0000000000..22e3b0c304 Binary files /dev/null and b/addons/medical_feedback/data/bloodVolume_6.paa differ diff --git a/addons/medical_feedback/data/fracture.paa b/addons/medical_feedback/data/fracture.paa new file mode 100644 index 0000000000..b1a48138d7 Binary files /dev/null and b/addons/medical_feedback/data/fracture.paa differ diff --git a/addons/medical_feedback/data/splint.paa b/addons/medical_feedback/data/splint.paa new file mode 100644 index 0000000000..a82349885d Binary files /dev/null and b/addons/medical_feedback/data/splint.paa differ diff --git a/addons/medical_feedback/data/tourniquet.paa b/addons/medical_feedback/data/tourniquet.paa new file mode 100644 index 0000000000..59e0076ed2 Binary files /dev/null and b/addons/medical_feedback/data/tourniquet.paa differ diff --git a/addons/medical_feedback/functions/fnc_effectBleeding.sqf b/addons/medical_feedback/functions/fnc_effectBleeding.sqf index cf87d2eb35..b018948f23 100644 --- a/addons/medical_feedback/functions/fnc_effectBleeding.sqf +++ b/addons/medical_feedback/functions/fnc_effectBleeding.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the bleeding effect. @@ -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_effectBloodVolume.sqf b/addons/medical_feedback/functions/fnc_effectBloodVolume.sqf index e4a8e27053..08a200cbd0 100644 --- a/addons/medical_feedback/functions/fnc_effectBloodVolume.sqf +++ b/addons/medical_feedback/functions/fnc_effectBloodVolume.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the blood volume effect. @@ -18,9 +18,11 @@ params ["_enable", "_intensity"]; +if (isNil QGVAR(ppBloodVolume)) exitWith {}; if ((!_enable) || {_intensity == 0}) exitWith { GVAR(ppBloodVolume) ppEffectEnable false; }; + GVAR(ppBloodVolume) ppEffectEnable true; GVAR(ppBloodVolume) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [1, 1, 1, 1 - _intensity], [0.2, 0.2, 0.2, 0]]; GVAR(ppBloodVolume) ppEffectCommit 1; diff --git a/addons/medical_feedback/functions/fnc_effectBloodVolumeIcon.sqf b/addons/medical_feedback/functions/fnc_effectBloodVolumeIcon.sqf new file mode 100644 index 0000000000..b03867e4bb --- /dev/null +++ b/addons/medical_feedback/functions/fnc_effectBloodVolumeIcon.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: 10Dozen + * Handles the blood volume icon. + * + * Arguments: + * 0: Enable + * 1: Intensity 0...6 + * + * Return Value: + * None + * + * Example: + * [true, 4] call ace_medical_feedback_fnc_effectBloodVolumeIcon + * + * Public: No + */ + +params ["_enable", "_intensity"]; + +private _indicatorCtrl = uiNamespace getVariable [QGVAR(bloodVolumeIndicator), controlNull]; + +if (!_enable || !GVAR(showBloodVolumeIcon)) exitWith { + _indicatorCtrl ctrlSetText ""; +}; + +private _text = ""; +private _color = ICON_BLOODVOLUME_COLOR_NONE; + +if (_intensity > 0) then { + _text = ICON_BLOODVOLUME_PATH(_intensity); + if (_intensity > 2) then { + _color = [ICON_BLOODVOLUME_COLOR_ORANGE, ICON_BLOODVOLUME_COLOR_RED] select (_intensity > 4); + } else { + _color = ICON_BLOODVOLUME_COLOR_WHITE; + }; +}; + +// --- Affecting UI icon with proper image and color +_indicatorCtrl ctrlSetText _text; +_indicatorCtrl ctrlSetTextColor _color; diff --git a/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf b/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf index 1c5c9ef968..89d98883fc 100644 --- a/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf +++ b/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the hear beat sound. @@ -15,8 +15,12 @@ * Public: No */ -private _heartRate = GET_HEART_RATE(ACE_player); +if (EGVAR(common,OldIsCamera)) exitWith { + TRACE_2("Ending heart beat effect - scripted camera",_heartRate,EGVAR(common,OldIsCamera)); + GVAR(heartBeatEffectRunning) = false; +}; +private _heartRate = GET_HEART_RATE(ACE_player); if (_heartRate == 0) exitWith { TRACE_1("Ending heart beat effect - zero",_heartRate); GVAR(heartBeatEffectRunning) = false; @@ -28,13 +32,12 @@ private _waitTime = 60 / _heartRate; switch (true) do { case (_heartRate > 160): { // playSound SND_HEARBEAT_FAST; // Array doesn't blend together well, just play one file consistently - playSound "ACE_heartbeat_fast_1"; + if (isGameFocused) then { playSound "ACE_heartbeat_fast_1"; }; [FUNC(effectHeartBeat), [], _waitTime] call CBA_fnc_waitAndExecute; }; case (_heartRate < 60): { - playSound SND_HEARBEAT_SLOW; + if (isGameFocused) then { 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_effectIncapacitated.sqf b/addons/medical_feedback/functions/fnc_effectIncapacitated.sqf index 73526d462a..2607a69db3 100644 --- a/addons/medical_feedback/functions/fnc_effectIncapacitated.sqf +++ b/addons/medical_feedback/functions/fnc_effectIncapacitated.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Creates the incapacitation effect. diff --git a/addons/medical_feedback/functions/fnc_effectPain.sqf b/addons/medical_feedback/functions/fnc_effectPain.sqf index 1cfa68ff1c..0df6cde5dd 100644 --- a/addons/medical_feedback/functions/fnc_effectPain.sqf +++ b/addons/medical_feedback/functions/fnc_effectPain.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Triggers the pain effect (single flash). @@ -19,26 +19,42 @@ params ["_enable", "_intensity"]; if (!_enable || {_intensity == 0}) exitWith { - GVAR(ppPain) ppEffectEnable false; + if (GVAR(ppPain) != -1) then { GVAR(ppPain) ppEffectEnable false; }; + GVAR(ppPainBlur) ppEffectEnable false; }; -GVAR(ppPain) ppEffectEnable true; +if (GVAR(ppPain) != -1) then { 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_effectUnconscious.sqf b/addons/medical_feedback/functions/fnc_effectUnconscious.sqf index 3cd15bd405..5780b8ea5f 100644 --- a/addons/medical_feedback/functions/fnc_effectUnconscious.sqf +++ b/addons/medical_feedback/functions/fnc_effectUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the unconscious effect. diff --git a/addons/medical_feedback/functions/fnc_handleEffects.sqf b/addons/medical_feedback/functions/fnc_handleEffects.sqf index e4e536c4f4..2066527461 100644 --- a/addons/medical_feedback/functions/fnc_handleEffects.sqf +++ b/addons/medical_feedback/functions/fnc_handleEffects.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles any visual effects of medical. * 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,11 +15,13 @@ * * Public: No */ +params [["_manualUpdate", false]]; if (EGVAR(common,OldIsCamera) || {!alive ACE_player}) exitWith { [false, 0] call FUNC(effectUnconscious); [false] call FUNC(effectPain); [false] call FUNC(effectBloodVolume); + [false] call FUNC(effectBloodVolumeIcon); [false] call FUNC(effectBleeding); }; @@ -41,13 +43,24 @@ if ((!GVAR(heartBeatEffectRunning)) && {_heartRate != 0} && {(_heartRate > 160) // - Visual effects ----------------------------------------------------------- [_unconscious, 2] call FUNC(effectUnconscious); [ - true, linearConversion [BLOOD_VOLUME_CLASS_2_HEMORRHAGE, BLOOD_VOLUME_CLASS_4_HEMORRHAGE, _bloodVolume, 0, 1, true] + true, + linearConversion [BLOOD_VOLUME_CLASS_2_HEMORRHAGE, BLOOD_VOLUME_CLASS_4_HEMORRHAGE, _bloodVolume, 0, 1, true] ] call FUNC(effectBloodVolume); +[ + true, + ceil linearConversion [ + BLOOD_VOLUME_CLASS_2_HEMORRHAGE, BLOOD_VOLUME_CLASS_4_HEMORRHAGE, + _bloodVolume, + ICON_BLOODVOLUME_IDX_MIN, ICON_BLOODVOLUME_IDX_MAX, true + ] +] call FUNC(effectBloodVolumeIcon); -if (!_unconscious) then { - [true, _pain] call FUNC(effectPain); +[!_unconscious, _pain] call FUNC(effectPain); +[!_unconscious, _bleedingStrength, _manualUpdate] call FUNC(effectBleeding); + +// - Tourniquets, fractures and splints indication --------------------------------------- +if (GVAR(enableHUDIndicators)) then { + [] call FUNC(handleHUDIndicators); }; -[true, _bleedingStrength] call FUNC(effectBleeding); - END_COUNTER(handleEffects); diff --git a/addons/medical_feedback/functions/fnc_handleHUDIndicators.sqf b/addons/medical_feedback/functions/fnc_handleHUDIndicators.sqf new file mode 100644 index 0000000000..0f065c6d34 --- /dev/null +++ b/addons/medical_feedback/functions/fnc_handleHUDIndicators.sqf @@ -0,0 +1,64 @@ +#include "..\script_component.hpp" +/* + * Author: 10Dozen + * Handles indication of the fractures, applied tourniquets and splints over Stance indicator. + * Draws an icon if there is at least 1 fracture/splint/tourniquet applied. + * + * Arguments: + * 0: Flag to drop all indicators (optional) + * + * Return Value: + * None + * + * Example: + * [false] call ace_medical_feedback_fnc_handleHUDIndicators + * + * Public: No + */ +params [["_dropAllIndicators", false]]; + +private _indicatorSlots = [ + uiNamespace getVariable [QGVAR(stateIndicator1), controlNull], + uiNamespace getVariable [QGVAR(stateIndicator2), controlNull], + uiNamespace getVariable [QGVAR(stateIndicator3), controlNull] +]; + +// --- Removes any indication and exit +if (_dropAllIndicators) exitWith { + { + _x ctrlSetText ""; + } forEach _indicatorSlots; +}; + +// --- Tourniquets +private _hasTourniquets = GET_TOURNIQUETS(ACE_player) findIf {_x > 0} > -1; +private _tourniquetIcon = ["", ICON_TOURNIQUET_PATH] select _hasTourniquets; + +// --- Fractures and Splints +private _fractureSettings = EGVAR(medical,fractures); +private _fractureIcon = ""; +private _splintIcon = ""; + +if (_fractureSettings > 0) then { + // --- Fractures enabled: check for fracture indication + private _hasFractures = GET_FRACTURES(ACE_player) findIf {_x > 0} > -1; + _fractureIcon = ["", ICON_FRACTURE_PATH] select _hasFractures; + + if (_fractureSettings > 1) then { + // --- Fractures can not be fully healed: check for splint indication + private _hasSplints = GET_FRACTURES(ACE_player) findIf {_x == -1} > -1; + _splintIcon = ["", ICON_SPLINT_PATH] select _hasSplints; + }; +}; + +// --- Get prioritized list of icons to apply +private _icons = [ + _fractureIcon, + _tourniquetIcon, + _splintIcon +] select {_x isNotEqualTo ""}; + +// --- Apply icons to indicator slots, if no icon for slot - remove slot's text +{ + _x ctrlSetText (_icons param [_forEachIndex, ""]); +} forEach _indicatorSlots; diff --git a/addons/medical_feedback/functions/fnc_initEffects.sqf b/addons/medical_feedback/functions/fnc_initEffects.sqf index 504b77f2fc..ccaaffa976 100644 --- a/addons/medical_feedback/functions/fnc_initEffects.sqf +++ b/addons/medical_feedback/functions/fnc_initEffects.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Initializes visual effects of medical. * * Arguments: - * 0: Just Pain Effects + * 0: Update pain and low blood volume effects only * * Return Value: * None @@ -15,9 +15,9 @@ * Public: No */ -params [["_justPain", false]]; +params [["_updateOnly", false]]; -TRACE_1("initEffects",_justPain); +TRACE_1("initEffects",_updateOnly); private _fnc_createEffect = { params ["_type", "_layer", "_default"]; @@ -33,29 +33,75 @@ private _fnc_createEffect = { // - Pain --------------------------------------------------------------------- if (!isNil QGVAR(ppPain)) then { TRACE_1("delete pain",GVAR(ppPain)); - ppEffectDestroy GVAR(ppPain) + if (GVAR(ppPain) != -1) then { ppEffectDestroy GVAR(ppPain); }; }; -if (GVAR(painEffectType) == 0) then { - GVAR(ppPain) = [ - "ColorCorrections", - 13502, - [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]] - ] 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; + }; + default { GVAR(ppPain) = -1; }; +}; +// 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)); -if (_justPain) exitWith {}; +// - Blood volume ------------------------------------------------------------- +private _ppBloodVolumeSettings = [ + "ColorCorrections", + 13503, + [1, 1, 0, [0, 0, 0, 0], [1, 1, 1, 1], [0.2, 0.2, 0.2, 0]] +]; +GVAR(showBloodVolumeIcon) = false; + +if (!isNil QGVAR(ppBloodVolume)) then { + TRACE_1("delete blood volume",GVAR(ppBloodVolume)); + ppEffectDestroy GVAR(ppBloodVolume); + GVAR(ppBloodVolume) = nil; +}; +switch (GVAR(bloodVolumeEffectType)) do { + case FX_BLOODVOLUME_COLOR_CORRECTION: { + GVAR(ppBloodVolume) = _ppBloodVolumeSettings call _fnc_createEffect; + }; + case FX_BLOODVOLUME_ICON: { + GVAR(showBloodVolumeIcon) = true; + }; + case FX_BLOODVOLUME_BOTH: { + GVAR(showBloodVolumeIcon) = true; + GVAR(ppBloodVolume) = _ppBloodVolumeSettings call _fnc_createEffect; + }; +}; + +if (_updateOnly) exitWith {}; // - Unconscious -------------------------------------------------------------- GVAR(ppUnconsciousBlur) = [ "DynamicBlur", - 813, // 135xx does not work + 814, // 135xx does not work [0] ] call _fnc_createEffect; @@ -65,14 +111,6 @@ GVAR(ppUnconsciousBlackout) = [ [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] ] call _fnc_createEffect; - -// - Blood volume ------------------------------------------------------------- -GVAR(ppBloodVolume) = [ - "ColorCorrections", - 13503, - [1, 1, 0, [0, 0, 0, 0], [1, 1, 1, 1], [0.2, 0.2, 0.2, 0]] -] call _fnc_createEffect; - // - Incapacitation ----------------------------------------------------------- GVAR(ppIncapacitationGlare) = [ "ColorCorrections", @@ -82,6 +120,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..c278e6e08a 100644 --- a/addons/medical_feedback/functions/fnc_playInjuredSound.sqf +++ b/addons/medical_feedback/functions/fnc_playInjuredSound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Play random injured sound for a unit. The sound is broadcasted across MP. @@ -18,68 +18,52 @@ * Public: No */ #define TIME_OUT_HIT 1 -#define TIME_OUT_MOAN 5 +#define TIME_OUT_MOAN [12, 7.5, 5] params [["_unit", objNull, [objNull]], ["_type", "hit", [""]], ["_severity", 0, [0]]]; // TRACE_3("",_unit,_type,_severity); -if (!local _unit) exitWith { - ERROR("Unit not local or null"); -}; +if (!local _unit) exitWith { ERROR_2("playInjuredSound: Unit not local or null [%1:%2]",_unit,typeOf _unit); }; if !(_unit call EFUNC(common,isAwake)) exitWith {}; -private _timeOut = [TIME_OUT_HIT, TIME_OUT_MOAN] select (_type == "moan"); +// Limit network traffic by only sending the event to players who can potentially hear it +private _distance = if (_type == "hit") then { + [50, 60, 70] select _severity; +} else { + [10, 15, 20] select _severity; +}; +private _targets = allPlayers inAreaArray [ASLToAGL getPosASL _unit, _distance, _distance, 0, false, _distance]; +if (_targets isEqualTo []) exitWith {}; // Handle timeout if (_unit getVariable [QGVAR(soundTimeout) + _type, -1] > CBA_missionTime) exitWith {}; +private _timeOut = if (_type == "moan") then { TIME_OUT_MOAN # _severity } else { TIME_OUT_HIT }; _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 _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); }; -// 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"); -}; - -// 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]; +[QGVAR(forceSay3D), [_unit, _sound, _distance], _targets] call CBA_fnc_targetEvent; diff --git a/addons/medical_feedback/functions/script_component.hpp b/addons/medical_feedback/functions/script_component.hpp deleted file mode 100644 index ff9d04881c..0000000000 --- a/addons/medical_feedback/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_feedback\script_component.hpp" diff --git a/addons/medical_feedback/initSettings.inc.sqf b/addons/medical_feedback/initSettings.inc.sqf new file mode 100644 index 0000000000..1268335b21 --- /dev/null +++ b/addons/medical_feedback/initSettings.inc.sqf @@ -0,0 +1,56 @@ +[ + QGVAR(painEffectType), + "LIST", + [LSTRING(PainEffectType_DisplayName), LSTRING(PainEffectType_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [ + [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("painEffectType setting - before postInit",_this); + }; + + TRACE_1("painEffectType setting - resetting effect",_this); + [true] call FUNC(initEffects); + } +] call CBA_fnc_addSetting; + +[ + QGVAR(bloodVolumeEffectType), + "LIST", + [LSTRING(BloodVolumeEffectType_DisplayName), LSTRING(BloodVolumeEffectType_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [ + [FX_BLOODVOLUME_COLOR_CORRECTION, FX_BLOODVOLUME_ICON, FX_BLOODVOLUME_BOTH], + [LSTRING(BloodVolumeEffectType_colorCorrection), LSTRING(BloodVolumeEffectType_icon), LSTRING(BloodVolumeEffectType_both)], + 0 + ], + false, + { + if (isNil QGVAR(showBloodVolumeIcon)) exitWith { + TRACE_1("bloodVolumeEffect setting - before postInit",_this); + }; + + TRACE_1("bloodVolumeEffect setting - resetting effect",_this); + [true] call FUNC(initEffects); + } +] call CBA_fnc_addSetting; + +[ + QGVAR(enableHUDIndicators), + "CHECKBOX", + [LSTRING(EnableHUDIndicators_DisplayName), LSTRING(EnableHUDIndicators_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + true, + false, + { + // --- Drop indication on disabling + if (!_this) exitWith { + [true] call FUNC(handleHUDIndicators); + }; + } +] call CBA_fnc_addSetting; diff --git a/addons/medical_feedback/initSettings.sqf b/addons/medical_feedback/initSettings.sqf deleted file mode 100644 index 36c7dafc0c..0000000000 --- a/addons/medical_feedback/initSettings.sqf +++ /dev/null @@ -1,16 +0,0 @@ -[ - QGVAR(painEffectType), - "LIST", - [LSTRING(PainEffectType_DisplayName), LSTRING(PainEffectType_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - [[0, 1], [LSTRING(PainEffectType_WhiteFlashing), LSTRING(PainEffectType_PulsingBlur)], 0], - false, - { - 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 dc2c3baf9c..99167c08a7 100644 --- a/addons/medical_feedback/script_component.hpp +++ b/addons/medical_feedback/script_component.hpp @@ -14,6 +14,7 @@ #define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_FEEDBACK #endif +#include "\a3\ui_f\hpp\defineCommonGrids.inc" #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" @@ -37,3 +38,24 @@ #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 + +#define FX_BLOODVOLUME_COLOR_CORRECTION 0 +#define FX_BLOODVOLUME_ICON 1 +#define FX_BLOODVOLUME_BOTH 2 + +#define ICON_BLOODVOLUME_IDX_MIN 0 +#define ICON_BLOODVOLUME_IDX_MAX 6 +#define ICON_BLOODVOLUME_PATH(num) format [QPATHTOF(data\bloodVolume_%1.paa), num] +#define ICON_BLOODVOLUME_COLOR_NONE [0, 0, 0, 0] +#define ICON_BLOODVOLUME_COLOR_WHITE [1, 1, 1, 1] +#define ICON_BLOODVOLUME_COLOR_ORANGE [1, 0.6, 0, 1] +#define ICON_BLOODVOLUME_COLOR_RED [0.8, 0.2, 0, 1] + +#define ICON_TOURNIQUET_PATH QPATHTOF(data\tourniquet.paa) +#define ICON_SPLINT_PATH QPATHTOF(data\splint.paa) +#define ICON_FRACTURE_PATH QPATHTOF(data\fracture.paa) diff --git a/addons/medical_feedback/stringtable.xml b/addons/medical_feedback/stringtable.xml index 2774ad6a38..d1ef189611 100644 --- a/addons/medical_feedback/stringtable.xml +++ b/addons/medical_feedback/stringtable.xml @@ -3,58 +3,212 @@ Feedback - Feedback + Rückmeldung フィードバック Реакция на ранения + Réaction aux blessures + Reação a Lesões + 視覺回饋 + 受伤反应 + Commenti + Zpětná vazba + Informacje Zwrotne + Reacción + Geri Bildirim + 피드백 Pain Effect Type Schmerzeffekt-Typ Rodzaj efektu bólu Визуальный эффект боли - Pain Effect Type + Effetto del dolore Tipo de efecto de dolor - Type d'effet de douleur + Effet de douleur Fájdalom-effekt típusa Tipo do efeito de dor - Typ bolesti - efekt + Efekt pro bolest 痛み効果の種類 고통 효과 종류 + 疼痛效果類型 + 疼痛效果类型 + Ağrı Etkisi Türü Selects the used pain effect type. - 痛みの効果の種類を選択できます。 + 痛みの画面効果を選択できます。 + Permet de choisir quel effet provoque la douleur. + Выбирает тип визуализации болевого эффекта. + Selecione o tipo de efeito de dor. + 選擇哪一個視覺效果用於回饋疼痛 + 选择反馈的疼痛效果类型。 + Seleziona il tipo di effetto causato dal dolore. + Nastavuje který efekt bolesti bude používán. + Wybiera rodzaj efektu bólu. + Selecciona el tipo de efecto de dolor + Kullanılan ağrı efekti tipini seçer. + Wählt den zu benutzenden Schmerzeffekt aus. + 고통 시 어떤 효과로 나타낼 지 결정합니다. White Flashing Weißes blinken 白く点滅 Белые вспышки + Flash blancs + Flashes Brancos + 白光閃爍 + 白光闪烁 + Bianco lampeggiante + Blikání bílé barvy + Miganie na biało + Destello blanco + Beyaz Yanıp Sönüyor + 반짝이는 하얀색 Pulsing Blur Wiederkehrende Unschärfe - ボケの強弱 + ぼかしの強弱 Пульсирующее размытие + Pulsations floues + Borrão Pulsante + 脈動模糊 + 脉冲式模糊 + Sfocatura pulsante + Pulzující rozmazání + Pulsujące rozmycie + Enborronamiento pulsante + Titreşimli Bulanıklık + 두근대는 흐려짐 + + + Chromatic Aberration + Chromatische Aberration + Aberracja chromatyczna + Хроматическая аберрация + Aberrazione cromatica + Aberración cromática + Aberration chromatique + Kromatikus aberráció + Chromatická aberace + Aberração cromática + 色収差 + 색수차 + 色差 + 色差 + Renk sapmaları + + + Only high pain effect + 強い痛み効果のみ + 只有在強烈疼痛時使用 + 仅在剧烈疼痛下启用 + Juste un fort effet douloureux + Solo effetto di elevato dolore + Pouze efekt vysoké bolesti + Tylko efekt mocnego bólu + Apenas efeito de dor alta + Solo efecto de dolor fuerte + Sadece yüksek ağrı etkisi + Nur bei starken Schmerzen + Эффект только сильной боли + 강한 고통 때만 보여짐 + + + Low Blood Volume Effect Type + Визуальный эффект низкого объема крови + Effet de faible volume sanguin + Effetto di poco sangue + 低血液量時効果の種類 + Efekt pro nízké množství krve + Efekt po utracie znacznej ilości krwi + Düşük Kan Efekt Türü + Tipo de efecto por volumen bajo de sangre + Effektart für "Niedriges Blutvolumen" + 低血容量影响类型 + 혈액량 부족 시 효과 종류 + Tipo de efeito por volume baixo de sangue + + + Selects the used low blood volume effect type. + Выбирает тип визуализации эффекта низкого объема крови. + Permet de choisir quel effet provoque un faible volume sanguin. + Seleziona il tipo di effetto causato da un volume di sangue molto ridotto. + 低血液量時の画面効果を選択できます。 + Nastavuje který efekt pro nízké množství krve bude používán. + Wybiera efekt ktory będzie pokazywany po utracie znacznej ilości krwi. + Kullanılan düşük kan hacmi efekt türünü seçer. + Selecciona el tipo de efecto a causa de un volumen bajo de sangre. + Wählt die verwendete Effektart für niedriges Blutvolumen. + 选择低血容量下的效果类型。 + 혈액량이 부족할 때 어떤 효과로 나타낼지 결정합니다. + Seleciona o tipo de efeito visual quando o volume de sangue está baixo. + + + Color Fading + Потеря цветности + Atténuation des couleurs + Sbiadimento dei colori + 退色 + Ztráta barev + Zanikanie kolorów + Renk Soldurma + Atenuación del color + Farbverblassen + 褪色 + 색바램 + Atenuação de cores + + + Icon + Иконка + Icône + Icona + アイコン + Ikona + Ikona + Simge + Icono + Symbol + 图标 + 아이콘 + Ícone + + + Icon + Color Fading + Иконка + Потеря цветности + Icône + Atténuation des couleurs + Icona + Sbiadimento dei colori + アイコンと退色 + Ikona + Ztráta barev + Ikona + Zanikanie kolorów + Simge + Renk Soldurma + Icono + Atenuación del color + Symbol + Farbverblassen + 图标+褪色 + 아이콘 및 색바램 + Ícone + Atenuação de cores - + Enable Screams - Включить крики + Вкл. крики Aktywuj wrzaski Activar gritos Schreie aktivieren Povolit křik Ativar gritos - Activer les hurlements + Activer les cris Kiáltások engedélyezése Abilita Grida - 叫びを有効化 + 悲鳴を有効化 비명 활성화 - 启用尖叫 + 启用惨叫 啟用尖叫 + Çığlıkları Etkinleştir - + Enable screaming by injured units Включить крики раненных бойцов Aktywuj wrzeszczenie z bólu przez ranne jednostki @@ -62,13 +216,40 @@ 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 - 負傷したユニットを叫ぶようにします。 - 부상당한 인원이 소리지르는것을 활성화합니다 - 启用伤者的尖叫声 + Abilita Grida da parte di unità ferite + 負傷したユニットが悲鳴をあげるようにします。 + 부상당한 인원이 소리지르는 것을 활성화합니다 + 启用伤者的惨叫声 啟用傷者的尖叫聲 + Yaralı birimler tarafından çığlık atmayı etkinleştir + + + Enable Fracture/Tourniquet/Splint Indicators + Вкл. индикаторы переломов/жгутов/шин + 骨折/止血帯/添え木の表記を有効化 + Indicateurs de fractures/garrots/attelles + Fraktur-/Tourniquet-/Schienen-Indikatoren aktivieren + Abilita indicatori di Frattura/Gessatura/Laccio Emostatico + Włącz wskaźniki złamań/stazy/szyny + 启用骨折/止血带/夹板指示器 + 골절/지혈대/부목 표시 활성화 + Habilitar indicadores de Fractura/Torniquete + Habilitar indicadores de Fratura/Torniquete/Tala + + + Enables indicators for fractures and applied tourniquets and splints over the Stance Indicator. + Включает индикацию переломов, наложенных шин и жгутов поверх индикатора положения тела. + 体勢インジケータに骨折や添え木、止血帯の有無を表示するかどうかを設定できます。 + Affiche des icônes au niveau de l'indicateur de posture, indiquant si le personnage souffre de fractures ou si des garrots ou des attelles sont appliqués. + Aktiviert Indikatoren für Frakturen mit angelegte Tourniquets und Schienen über dem Haltungsindikator. + Abilita indicatori per la presenza di fratture, gessature o lacci emostatici applicati sopra l'indicatore di postura. + Włącza wskaźniki złamań oraz założonej staz/szyn przy ikonie stanu postawy + 在姿态指示器上启用骨折、应用止血带和夹板指示器。 + 자세 표시기 옆에 골절, 지혈대, 부목의 여부를 표시합니다. + Habilita los indicadores para fracturas y torniquetes apllicados y férulas sobre el indicador de posición del personaje. + Habilita indicadores para fraturas, torniquetes e talas sobre o indicador de posição do personagem. diff --git a/addons/medical_gui/CfgEventHandlers.hpp b/addons/medical_gui/CfgEventHandlers.hpp index da45b1d12e..e681bffde5 100644 --- a/addons/medical_gui/CfgEventHandlers.hpp +++ b/addons/medical_gui/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_gui/CfgUIGrids.hpp b/addons/medical_gui/CfgUIGrids.hpp new file mode 100644 index 0000000000..1a7716503f --- /dev/null +++ b/addons/medical_gui/CfgUIGrids.hpp @@ -0,0 +1,30 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + GVAR(patientInfo)[] = { + { + QUOTE(PATIENT_INFO_IGUI_BASE_X), + QUOTE(PATIENT_INFO_IGUI_BASE_Y), + QUOTE(POS_W(9)), + QUOTE(POS_H(20)) + }, + QUOTE(GUI_GRID_W), + QUOTE(GUI_GRID_H) + }; + }; + }; + }; + + class Variables { + class GVAR(patientInfo) { + displayName = ECSTRING(medical,Category); + description = CSTRING(IGUI_PatientInfo); + preview = QPATHTOF(ui\patient_info_preview_ca.paa); + saveToProfile[] = {0, 1}; + canResize = 0; + }; + }; + }; +}; diff --git a/addons/medical_gui/CfgVehicles.hpp b/addons/medical_gui/CfgVehicles.hpp index eecae9a359..502039325a 100644 --- a/addons/medical_gui/CfgVehicles.hpp +++ b/addons/medical_gui/CfgVehicles.hpp @@ -5,8 +5,8 @@ class CfgVehicles { class ACE_Medical { displayName = CSTRING(Medical); condition = QGVAR(enableSelfActions); - exceptions[] = {"isNotInside", "isNotSitting"}; - statement = QUOTE([ARR_2(_target,0)] call FUNC(displayPatientInformation)); + exceptions[] = {"isNotInside", "isNotSitting", "isNotSwimming"}; + statement = QUOTE([ARR_2(_target,-1)] call FUNC(displayPatientInformation)); runOnHover = 1; icon = QPATHTOF(ui\cross.paa); #define ACTION_CONDITION condition = "true"; @@ -19,6 +19,7 @@ class CfgVehicles { exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE(_target call FUNC(openMenu)); icon = QPATHTOF(ui\cross.paa); + modifierFunction = QUOTE(call FUNC(modifyActionTriageLevel)); }; }; class ACE_Actions { @@ -26,18 +27,20 @@ class CfgVehicles { #include "InteractionBodyParts.hpp" #undef ACTION_CONDITION class ACE_MainActions { + modifierFunction = QUOTE(call FUNC(modifyActionTriageLevel)); class ACE_Medical_Menu { displayName = CSTRING(MedicalMenu); condition = QUOTE([ARR_2(ACE_player,_target)] call FUNC(canOpenMenu)); exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE(_target call FUNC(openMenu)); icon = QPATHTOF(ui\cross.paa); + modifierFunction = QUOTE(call FUNC(modifyActionTriageLevel)); }; class ACE_Medical_Radial { displayName = CSTRING(Medical); - condition = QUOTE((GVAR(enableActions) == 1 || {GVAR(enableActions) != 2 && {vehicle _target != _target && {vehicle _target == vehicle _player}}})); + condition = QUOTE((GVAR(enableActions) == 1 || {GVAR(enableActions) != 2 && {!isNull objectParent _target && {objectParent _target isEqualTo objectParent _player}}})); exceptions[] = {"isNotInside", "isNotSitting"}; - statement = QUOTE([ARR_2(_target,0)] call FUNC(displayPatientInformation)); + statement = QUOTE([ARR_2(_target,-1)] call FUNC(displayPatientInformation)); runOnHover = 1; icon = QPATHTOF(ui\cross.paa); #define ACTION_CONDITION condition = "true"; @@ -46,17 +49,17 @@ class CfgVehicles { }; class ACE_LoadPatient { displayName = CSTRING(LoadPatient); - condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {alive _target} && {vehicle _target == _target}); + condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {alive _target} && {isNull objectParent _target} && {(_target call EFUNC(common,nearestVehiclesFreeSeat)) isNotEqualTo []}); exceptions[] = {"isNotDragging", "isNotCarrying"}; - statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,loadUnit)); + statement = QUOTE([ARR_2(_player,_target)] call EFUNC(medical_treatment,loadUnit)); icon = QPATHTOF(ui\cross.paa); insertChildren = QUOTE(call DEFUNC(medical_treatment,addLoadPatientActions)); }; class ACE_UnloadPatient { displayName = CSTRING(UnloadPatient); - condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {vehicle _target != _target} && {vehicle _player == _player}); + condition = QUOTE([ARR_2(_player,_target)] call EFUNC(medical_treatment,canUnloadUnit)); exceptions[] = {"isNotDragging", "isNotCarrying", "isNotInside"}; - statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,unloadUnit)); + statement = QUOTE([ARR_2(_player,_target)] call EFUNC(medical_treatment,unloadUnit)); icon = QPATHTOF(ui\cross.paa); }; }; diff --git a/addons/medical_gui/InteractionBodyParts.hpp b/addons/medical_gui/InteractionBodyParts.hpp index b06e24c2e7..928ec330ed 100644 --- a/addons/medical_gui/InteractionBodyParts.hpp +++ b/addons/medical_gui/InteractionBodyParts.hpp @@ -5,7 +5,7 @@ class ACE_Head { exceptions[] = {"isNotInside", "isNotSitting"}; ACTION_CONDITION statement = QUOTE([ARR_2(_target,0)] call FUNC(displayPatientInformation)); - modifierFunction = QUOTE([ARR_3(_target,0,_this select 3)] call FUNC(modifyAction)); + modifierFunction = QUOTE([ARR_3(_target,""head"",_this select 3)] call FUNC(modifyAction)); runOnHover = 1; }; class ACE_Torso { @@ -15,7 +15,7 @@ class ACE_Torso { exceptions[] = {"isNotInside", "isNotSitting"}; ACTION_CONDITION statement = QUOTE([ARR_2(_target,1)] call FUNC(displayPatientInformation)); - modifierFunction = QUOTE([ARR_3(_target,1,_this select 3)] call FUNC(modifyAction)); + modifierFunction = QUOTE([ARR_3(_target,""body"",_this select 3)] call FUNC(modifyAction)); runOnHover = 1; class TriageCard { displayName = CSTRING(Actions_TriageCard); @@ -32,7 +32,7 @@ class ACE_ArmLeft { exceptions[] = {"isNotInside", "isNotSitting"}; ACTION_CONDITION statement = QUOTE([ARR_2(_target,2)] call FUNC(displayPatientInformation)); - modifierFunction = QUOTE([ARR_3(_target,2,_this select 3)] call FUNC(modifyAction)); + modifierFunction = QUOTE([ARR_3(_target,""leftarm"",_this select 3)] call FUNC(modifyAction)); runOnHover = 1; }; class ACE_ArmRight { @@ -42,7 +42,7 @@ class ACE_ArmRight { exceptions[] = {"isNotInside", "isNotSitting"}; ACTION_CONDITION statement = QUOTE([ARR_2(_target,3)] call FUNC(displayPatientInformation)); - modifierFunction = QUOTE([ARR_3(_target,3,_this select 3)] call FUNC(modifyAction)); + modifierFunction = QUOTE([ARR_3(_target,""rightarm"",_this select 3)] call FUNC(modifyAction)); runOnHover = 1; }; class ACE_LegLeft { @@ -52,7 +52,7 @@ class ACE_LegLeft { exceptions[] = {"isNotInside", "isNotSitting"}; ACTION_CONDITION statement = QUOTE([ARR_2(_target,4)] call FUNC(displayPatientInformation)); - modifierFunction = QUOTE([ARR_3(_target,4,_this select 3)] call FUNC(modifyAction)); + modifierFunction = QUOTE([ARR_3(_target,""leftleg"",_this select 3)] call FUNC(modifyAction)); runOnHover = 1; }; class ACE_LegRight { @@ -62,6 +62,6 @@ class ACE_LegRight { exceptions[] = {"isNotInside", "isNotSitting"}; ACTION_CONDITION statement = QUOTE([ARR_2(_target,5)] call FUNC(displayPatientInformation)); - modifierFunction = QUOTE([ARR_3(_target,5,_this select 3)] call FUNC(modifyAction)); + modifierFunction = QUOTE([ARR_3(_target,""rightleg"",_this select 3)] call FUNC(modifyAction)); runOnHover = 1; }; diff --git a/addons/medical_gui/README.md b/addons/medical_gui/README.md index 37bd6250fd..71b194c80d 100644 --- a/addons/medical_gui/README.md +++ b/addons/medical_gui/README.md @@ -3,9 +3,3 @@ ace_medical_gui Implements the interaction menu actions, medical menu, information display, and triage card. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Glowbal](https://github.com/Glowbal) -- [mharis001](https://github.com/mharis001) diff --git a/addons/medical_gui/XEH_PREP.hpp b/addons/medical_gui/XEH_PREP.hpp index c53b693bdf..3d1ace8b4e 100644 --- a/addons/medical_gui/XEH_PREP.hpp +++ b/addons/medical_gui/XEH_PREP.hpp @@ -2,13 +2,17 @@ PREP(addTreatmentActions); PREP(bloodLossToRGBA); PREP(canOpenMenu); PREP(collectActions); +PREP(countTreatmentItems); PREP(damageToRGBA); PREP(displayPatientInformation); PREP(displayTriageCard); +PREP(formatItemCounts); PREP(handleToggle); PREP(handleTriageSelect); PREP(menuPFH); PREP(modifyAction); +PREP(modifyActionTriageLevel); +PREP(onKeyDown); PREP(onMenuClose); PREP(onMenuOpen); PREP(openMenu); diff --git a/addons/medical_gui/XEH_postInit.sqf b/addons/medical_gui/XEH_postInit.sqf index c6dd4e2722..2b7fb8ce52 100644 --- a/addons/medical_gui/XEH_postInit.sqf +++ b/addons/medical_gui/XEH_postInit.sqf @@ -12,13 +12,16 @@ GVAR(pendingReopen) = false; GVAR(menuPFH) = -1; +GVAR(peekLastOpenedOn) = -1; +GVAR(peekOnHitLastOpenedOn) = -1; + GVAR(selfInteractionActions) = []; [] call FUNC(addTreatmentActions); [] call FUNC(collectActions); [QEGVAR(interact_menu,newControllableObject), { params ["_type"]; // string of the object's classname - if (!(_type isKindOf "CAManBase")) exitWith {}; + if !(_type isKindOf "CAManBase") exitWith {}; { _x set [0, _type]; _x call EFUNC(interact_menu,addActionToClass); @@ -33,13 +36,26 @@ GVAR(selfInteractionActions) = []; }] call CBA_fnc_addEventHandler; ["ACE3 Common", QGVAR(openMedicalMenuKey), localize LSTRING(OpenMedicalMenu), { - // Get target (cursorTarget and cursorObject), if not valid then target is ACE_player + // Get target (cursorTarget, cursorObject, and lineIntersectsSurfaces along camera to maxDistance), if not valid then target is ACE_player TRACE_3("Open menu key",cursorTarget,cursorObject,ACE_player); private _target = cursorTarget; if !(_target isKindOf "CAManBase" && {[ACE_player, _target] call FUNC(canOpenMenu)}) then { _target = cursorObject; if !(_target isKindOf "CAManBase" && {[ACE_player, _target] call FUNC(canOpenMenu)}) then { - _target = ACE_player; + private _start = AGLToASL positionCameraToWorld [0, 0, 0]; + private _end = AGLToASL positionCameraToWorld [0, 0, GVAR(maxDistance)]; + private _intersections = lineIntersectsSurfaces [_start, _end, ACE_player, objNull, true, -1, "FIRE"]; + { + _x params ["", "", "_intersectObject"]; + // Only look "through" player and player's vehicle + if (!(_intersectObject isKindOf "CAManBase") && {_intersectObject != vehicle ACE_player}) exitWith {}; + if (_intersectObject != ACE_player && {_intersectObject isKindOf "CAManBase" && {[ACE_player, _intersectObject] call FUNC(canOpenMenu)}}) exitWith { + _target =_intersectObject + }; + } forEach _intersections; + if (!(_target isKindOf "CAManBase") || {!([ACE_player, _target] call FUNC(canOpenMenu))}) then { + _target = ACE_player; + }; }; }; @@ -58,8 +74,43 @@ GVAR(selfInteractionActions) = []; false }, [DIK_H, [false, false, false]], false, 0] call CBA_fnc_addKeybind; +["ACE3 Common", QGVAR(peekMedicalInfoKey), localize LSTRING(PeekMedicalInfo), +{ + // Conditions: canInteract + if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false}; + + // Statement + [ACE_player, -1] call FUNC(displayPatientInformation); + false +}, { + if (CBA_missionTime - GVAR(peekLastOpenedOn) > GVAR(peekMedicalInfoReleaseDelay)) then { + [{ + CBA_missionTime - GVAR(peekLastOpenedOn) > GVAR(peekMedicalInfoReleaseDelay) + }, {QGVAR(RscPatientInfo) cutFadeOut 0.3}] call CBA_fnc_waitUntilAndExecute; + }; + GVAR(peekLastOpenedOn) = CBA_missionTime; + false +}, [DIK_H, [false, true, false]], false, 0] call CBA_fnc_addKeybind; + // Close patient information display when interaction menu is closed ["ace_interactMenuClosed", { QGVAR(RscPatientInfo) cutFadeOut 0.3; }] call CBA_fnc_addEventHandler; + +[QEGVAR(medical,woundReceived), { + params ["_unit", "_allDamages", ""]; + if !(GVAR(peekMedicalOnHit) && {_unit == ACE_player}) exitWith {}; + + private _bodypart = toLowerANSI (_allDamages select 0 select 1); + private _bodypartIndex = ALL_BODY_PARTS find _bodypart; + + [ACE_player, _bodypartIndex] call FUNC(displayPatientInformation); + + if (CBA_missionTime - GVAR(peekOnHitLastOpenedOn) > GVAR(peekMedicalOnHitDuration)) then { + [{ + CBA_missionTime - GVAR(peekOnHitLastOpenedOn) > GVAR(peekMedicalOnHitDuration) + }, {QGVAR(RscPatientInfo) cutFadeOut 0.3}] call CBA_fnc_waitUntilAndExecute; + }; + GVAR(peekOnHitLastOpenedOn) = CBA_missionTime; +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_gui/XEH_preInit.sqf b/addons/medical_gui/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/medical_gui/XEH_preInit.sqf +++ b/addons/medical_gui/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/medical_gui/addon.toml b/addons/medical_gui/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_gui/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_gui/config.cpp b/addons/medical_gui/config.cpp index 10efc9d90f..aa5072d4a5 100644 --- a/addons/medical_gui/config.cpp +++ b/addons/medical_gui/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -14,6 +22,9 @@ class CfgPatches { }; }; +#include "CfgUIGrids.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "gui.hpp" + +#endif diff --git a/addons/medical_gui/data/body_image/arm_left_s.paa b/addons/medical_gui/data/body_image/arm_left_s.paa new file mode 100644 index 0000000000..4c55e6143e Binary files /dev/null and b/addons/medical_gui/data/body_image/arm_left_s.paa differ diff --git a/addons/medical_gui/data/body_image/arm_right_s.paa b/addons/medical_gui/data/body_image/arm_right_s.paa new file mode 100644 index 0000000000..daff9d099e Binary files /dev/null and b/addons/medical_gui/data/body_image/arm_right_s.paa differ diff --git a/addons/medical_gui/data/body_image/head_s.paa b/addons/medical_gui/data/body_image/head_s.paa new file mode 100644 index 0000000000..9acf69a155 Binary files /dev/null and b/addons/medical_gui/data/body_image/head_s.paa differ diff --git a/addons/medical_gui/data/body_image/leg_left_s.paa b/addons/medical_gui/data/body_image/leg_left_s.paa new file mode 100644 index 0000000000..1f25d44b81 Binary files /dev/null and b/addons/medical_gui/data/body_image/leg_left_s.paa differ diff --git a/addons/medical_gui/data/body_image/leg_right_s.paa b/addons/medical_gui/data/body_image/leg_right_s.paa new file mode 100644 index 0000000000..4fcace26ed Binary files /dev/null and b/addons/medical_gui/data/body_image/leg_right_s.paa differ diff --git a/addons/medical_gui/data/body_image/torso_s.paa b/addons/medical_gui/data/body_image/torso_s.paa new file mode 100644 index 0000000000..58614f277f Binary files /dev/null and b/addons/medical_gui/data/body_image/torso_s.paa differ diff --git a/addons/medical_gui/data/categories/carry.paa b/addons/medical_gui/data/categories/carry.paa index 7ebb830b03..27a9185d29 100644 Binary files a/addons/medical_gui/data/categories/carry.paa and b/addons/medical_gui/data/categories/carry.paa differ diff --git a/addons/medical_gui/data/categories/toggle_self.paa b/addons/medical_gui/data/categories/toggle_self.paa deleted file mode 100644 index 73108e5a98..0000000000 Binary files a/addons/medical_gui/data/categories/toggle_self.paa and /dev/null differ diff --git a/addons/medical_gui/data/categories/toggle_to_other.paa b/addons/medical_gui/data/categories/toggle_to_other.paa new file mode 100644 index 0000000000..59f2096b8a Binary files /dev/null and b/addons/medical_gui/data/categories/toggle_to_other.paa differ diff --git a/addons/medical_gui/data/categories/toggle_to_self.paa b/addons/medical_gui/data/categories/toggle_to_self.paa new file mode 100644 index 0000000000..653a6bbdb4 Binary files /dev/null and b/addons/medical_gui/data/categories/toggle_to_self.paa differ diff --git a/addons/medical_gui/functions/fnc_addTreatmentActions.sqf b/addons/medical_gui/functions/fnc_addTreatmentActions.sqf index 541c308ff0..b27801766b 100644 --- a/addons/medical_gui/functions/fnc_addTreatmentActions.sqf +++ b/addons/medical_gui/functions/fnc_addTreatmentActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, mharis001 * Creates actions for treatments from config and adds them to the interaction menu. @@ -36,14 +36,14 @@ private _fnc_condition = { private _displayName = getText (_x >> "displayName"); private _icon = getText (_x >> "icon"); - private _allowedBodyParts = getArray (_x >> "allowedSelections") apply {toLower _x}; + private _allowedBodyParts = getArray (_x >> "allowedSelections") apply {toLowerANSI _x}; if (_allowedBodyParts isEqualTo ["all"]) then { - _allowedBodyParts = ALL_BODY_PARTS apply {toLower _x}; + _allowedBodyParts = ALL_BODY_PARTS apply {toLowerANSI _x}; }; { private _bodyPart = _x; - private _actionPath = _actionPaths select (ALL_BODY_PARTS find toLower _bodyPart); + private _actionPath = _actionPaths select (ALL_BODY_PARTS find toLowerANSI _bodyPart); private _action = [ _actionName, diff --git a/addons/medical_gui/functions/fnc_bloodLossToRGBA.sqf b/addons/medical_gui/functions/fnc_bloodLossToRGBA.sqf index b2852e1a2a..acc2181aac 100644 --- a/addons/medical_gui/functions/fnc_bloodLossToRGBA.sqf +++ b/addons/medical_gui/functions/fnc_bloodLossToRGBA.sqf @@ -1,9 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: ShackTac, SilentSpike + * Author: ShackTac, kymckay * Converts a blood loss value into a representative RGBA colour. - * Blood loss colouring follows a "white, yellow, red" colour scale with 10 steps, Bezier interpolation and Correct lightness gradient. - * See: https://gka.github.io/palettes * * Arguments: * 0: The blood loss value (range [0,1]) @@ -22,15 +20,4 @@ params ["_bloodLoss"]; private _frBL = 0 max (_bloodLoss / BLOOD_LOSS_RED_THRESHOLD) min 1; private _colorInt = ceil (_frBL * (BLOOD_LOSS_TOTAL_COLORS - 1)); -[ - [1.00, 1.00, 1.00, 1], // #ffffff - [1.00, 0.95, 0.63, 1], // #fff1a1 - [1.00, 0.88, 0.46, 1], // #ffe075 - [1.00, 0.80, 0.33, 1], // #ffcb55 - [1.00, 0.72, 0.24, 1], // #ffb73c - [1.00, 0.63, 0.15, 1], // #ffa127 - [1.00, 0.53, 0.08, 1], // #ff8815 - [1.00, 0.43, 0.02, 1], // #ff6d05 - [1.00, 0.29, 0.00, 1], // #ff4b00 - [1.00, 0.00, 0.00, 1] // #ff0000 -] select _colorInt; +missionNamespace getVariable format ["%1_%2", QGVAR(bloodLossColor), _colorInt] diff --git a/addons/medical_gui/functions/fnc_canOpenMenu.sqf b/addons/medical_gui/functions/fnc_canOpenMenu.sqf index f94c73bb9e..fc2ac3879e 100644 --- a/addons/medical_gui/functions/fnc_canOpenMenu.sqf +++ b/addons/medical_gui/functions/fnc_canOpenMenu.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal, mharis001 + * Author: Glowbal, mharis001, johnb43 * Checks if the player can open the Medical Menu for the target. * * Arguments: @@ -18,8 +18,14 @@ params ["_player", "_target"]; -alive _player -&& {!IS_UNCONSCIOUS(_player)} -&& {!isNull _target} -&& {_player distance _target < GVAR(maxDistance) || {vehicle _player == vehicle _target}} -&& {GVAR(enableMedicalMenu) == 1 || {GVAR(enableMedicalMenu) == 2 && {vehicle _player != _player || {vehicle _target != _target}}}} +// If in Zeus +if (!isNull findDisplay 312) exitWith { + !isNull _target && + {missionNamespace getVariable [QGVAR(enableZeusModule), true]} && + {GVAR(enableMedicalMenu) > 0} +}; + +_player call EFUNC(common,isAwake) && +{!isNull _target} && +{_player distance _target < GVAR(maxDistance) || {vehicle _player == vehicle _target}} && +{GVAR(enableMedicalMenu) == 1 || {GVAR(enableMedicalMenu) == 2 && {vehicle _player != _player || {vehicle _target != _target}}}} diff --git a/addons/medical_gui/functions/fnc_collectActions.sqf b/addons/medical_gui/functions/fnc_collectActions.sqf index 088ddb29fa..1620b2c5cb 100644 --- a/addons/medical_gui/functions/fnc_collectActions.sqf +++ b/addons/medical_gui/functions/fnc_collectActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Collect treatment actions for medical menu from config. @@ -11,7 +11,7 @@ * None * * Example: - * [] call ace_medical_gui_fnc_collectAction + * [] call ace_medical_gui_fnc_collectActions * * Public: No */ @@ -22,16 +22,17 @@ GVAR(actions) = []; private _configName = configName _x; private _displayName = getText (_x >> "displayName"); private _category = getText (_x >> "category"); - private _condition = compile format [QUOTE([ARR_4(ACE_player, GVAR(target), %1 select GVAR(selectedBodyPart), '%2')] call DEFUNC(medical_treatment,canTreatCached)), ALL_BODY_PARTS, _configName]; - private _statement = compile format [QUOTE([ARR_4(ACE_player, GVAR(target), %1 select GVAR(selectedBodyPart), '%2')] call DEFUNC(medical_treatment,treatment)), ALL_BODY_PARTS, _configName]; + private _condition = compile format [QUOTE([ARR_4(ACE_player,GVAR(target),%1 select GVAR(selectedBodyPart),'%2')] call DEFUNC(medical_treatment,canTreatCached)), ALL_BODY_PARTS, _configName]; + private _statement = compile format [QUOTE([ARR_4(ACE_player,GVAR(target),%1 select GVAR(selectedBodyPart),'%2')] call DEFUNC(medical_treatment,treatment)), ALL_BODY_PARTS, _configName]; + private _items = getArray (_x >> "items"); - GVAR(actions) pushBack [_displayName, _category, _condition, _statement]; + GVAR(actions) pushBack [_displayName, _category, _condition, _statement, _items]; } forEach configProperties [configFile >> QEGVAR(medical_treatment,actions), "isClass _x"]; if ("ace_dragging" call EFUNC(common,isModLoaded)) then { GVAR(actions) pushBack [ - localize ELSTRING(dragging,Drag), "drag", + LELSTRING(dragging,Drag), "drag", {ACE_player != GVAR(target) && {[ACE_player, GVAR(target)] call EFUNC(dragging,canDrag)}}, { GVAR(pendingReopen) = false; @@ -40,7 +41,7 @@ if ("ace_dragging" call EFUNC(common,isModLoaded)) then { ]; GVAR(actions) pushBack [ - localize ELSTRING(dragging,Carry), "drag", + LELSTRING(dragging,Carry), "drag", {ACE_player != GVAR(target) && {[ACE_player, GVAR(target)] call EFUNC(dragging,canCarry)}}, { GVAR(pendingReopen) = false; @@ -48,3 +49,8 @@ if ("ace_dragging" call EFUNC(common,isModLoaded)) then { } ]; }; + +// testing code for multi-line +// for "_i" from 0 to 12 do { +// GVAR(actions) pushBack [format ["Example %1", _i], "medication", {true}, compile format ['systemChat "%1"', _i]] +// }; diff --git a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf new file mode 100644 index 0000000000..ac7c4857e6 --- /dev/null +++ b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: AmsteadRayle + * Counts how many of the given items are present between the medic and patient. + * If medic or patient are in a vehicle then vehicle's inventory will also be checked. + * + * Arguments: + * 0: Items + * + * Return Value: + * Counts (can be nil) + * + * Example: + * [items] call ace_medical_gui_fnc_countTreatmentItems + * + * Public: No + */ + +params ["_items"]; + +private _medicCount = 0; +private _patientCount = nil; +private _vehicleCount = nil; + +// Medic +{ + _medicCount = _medicCount + ([ACE_player, _x] call EFUNC(common,getCountOfItem)); +} forEach _items; + +// Patient +if (ACE_player != GVAR(target)) then { + _patientCount = 0; + { + _patientCount = _patientCount + ([GVAR(target), _x] call EFUNC(common,getCountOfItem)); + } forEach _items; +}; + +// Vehicle +private _medicVehicle = objectParent ACE_player; +private _patientVehicle = objectParent GVAR(target); +private _vehicle = [_patientVehicle, _medicVehicle] select (!isNull _medicVehicle); + +if (!isNull _vehicle) then { + _vehicleCount = 0; + private _magazineItems = []; + private _itemItems = []; + { + if (isClass (configFile >> "CfgMagazines" >> _x)) then { + _magazineItems pushBack _x; + } else { + _itemItems pushBack _x; + }; + } forEach _items; + if (_magazineItems isNotEqualTo []) then { + (getMagazineCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + { + _vehicleCount = _vehicleCount + (_itemCounts param [_itemTypes find _x, 0]); + } forEach _magazineItems; + }; + if (_itemItems isNotEqualTo []) then { + (getItemCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + { + _vehicleCount = _vehicleCount + (_itemCounts param [_itemTypes find _x, 0]); + } forEach _itemItems; + }; +}; + +[_medicCount, _patientCount, _vehicleCount] diff --git a/addons/medical_gui/functions/fnc_damageToRGBA.sqf b/addons/medical_gui/functions/fnc_damageToRGBA.sqf index f487a332d1..56bd9a256f 100644 --- a/addons/medical_gui/functions/fnc_damageToRGBA.sqf +++ b/addons/medical_gui/functions/fnc_damageToRGBA.sqf @@ -1,9 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: ShackTac, SilentSpike + * Author: ShackTac, kymckay * Converts a damage value into a representative RGBA colour. - * Damage colouring follows a "white, cyan, blue" colour scale with 10 steps, Bezier interpolation and Correct lightness gradient. - * See: https://gka.github.io/palettes * * Arguments: * 0: The damage value (range [0,1]) @@ -22,15 +20,4 @@ params ["_damage"]; private _frD = 0 max (_damage / DAMAGE_BLUE_THRESHOLD) min 1; private _colorInt = ceil (_frD * (DAMAGE_TOTAL_COLORS - 1)); -[ - [1.00, 1.00, 1.00, 1], // #ffffff - [0.75, 0.95, 1.00, 1], // #bff2ff - [0.63, 0.87, 1.00, 1], // #a0ddff - [0.54, 0.77, 1.00, 1], // #8ac4ff - [0.48, 0.67, 1.00, 1], // #7aacff - [0.42, 0.57, 1.00, 1], // #6c91ff - [0.37, 0.47, 1.00, 1], // #5e77ff - [0.31, 0.35, 1.00, 1], // #4e5aff - [0.22, 0.23, 1.00, 1], // #383bff - [0.00, 0.00, 1.00, 1] // #0000ff -] select _colorInt +missionNamespace getVariable format ["%1_%2", QGVAR(damageColor), _colorInt] diff --git a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf index ac76d34012..65660eec79 100644 --- a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Opens the patient information display for given target. @@ -18,7 +18,7 @@ #define MAX_DISTANCE 4 -params ["_target", "_selectionN"]; +params ["_target", ["_selectionN", -1]]; private _display = uiNamespace getVariable [QGVAR(RscPatientInfo), displayNull]; @@ -34,7 +34,7 @@ if (isNull _display) then { }; private _target = _display getVariable [QGVAR(target), objNull]; - private _selectionN = _display getVariable [QGVAR(selectionN), 0]; + private _selectionN = _display getVariable [QGVAR(selectionN), -1]; // Close display if target moved too far away (ignore if in same vehicle) if (ACE_player distance _target > MAX_DISTANCE && {vehicle _target != vehicle ACE_player}) exitWith { @@ -45,7 +45,7 @@ if (isNull _display) then { // Update body image private _ctrlBodyImage = _display displayCtrl IDC_BODY_GROUP; - [_ctrlBodyImage, _target] call FUNC(updateBodyImage); + [_ctrlBodyImage, _target, _selectionN] call FUNC(updateBodyImage); // Update injury list private _ctrlInjuries = _display displayCtrl IDC_INJURIES; diff --git a/addons/medical_gui/functions/fnc_displayTriageCard.sqf b/addons/medical_gui/functions/fnc_displayTriageCard.sqf index 3a7f8c4adf..75db6bf6a3 100644 --- a/addons/medical_gui/functions/fnc_displayTriageCard.sqf +++ b/addons/medical_gui/functions/fnc_displayTriageCard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Displays the triage card for the target. diff --git a/addons/medical_gui/functions/fnc_formatItemCounts.sqf b/addons/medical_gui/functions/fnc_formatItemCounts.sqf new file mode 100644 index 0000000000..7ef294f4eb --- /dev/null +++ b/addons/medical_gui/functions/fnc_formatItemCounts.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: AmsteadRayle + * Format item counts to be shown in the tooltip. + * + * Arguments: + * 0: Medic count + * 1: Patient count + * 2: Vehicle count + * + * Return Value: + * Item count string + * + * Example: + * [medicCount, patientCount, vehicleCount] call ace_medical_gui_fnc_formatItemCounts + * + * Public: No + */ + +params ["_medicCount", "_patientCount", "_vehicleCount"]; + +private _countStrings = [format ["%1 %2", _medicCount, LLSTRING(TreatmentItemCount_Medic)]]; + +if ((EGVAR(medical_treatment,allowSharedEquipment) != 2) && {!isNil "_patientCount"}) then { + _countStrings pushBack format ["%1 %2", _patientCount, LLSTRING(TreatmentItemCount_Patient)]; +}; + +if (!isNil "_vehicleCount") then { + _countStrings pushBack format ["%1 %2", _vehicleCount, LLSTRING(TreatmentItemCount_Vehicle)]; +}; + +_countStrings joinString "\n" diff --git a/addons/medical_gui/functions/fnc_handleToggle.sqf b/addons/medical_gui/functions/fnc_handleToggle.sqf index c2634affdb..48232790c1 100644 --- a/addons/medical_gui/functions/fnc_handleToggle.sqf +++ b/addons/medical_gui/functions/fnc_handleToggle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Handles toggling of Medical Menu between the player and previous target. @@ -15,16 +15,18 @@ * Public: No */ + // If in Zeus, ignore + if (!isNull findDisplay 312) exitWith {}; + // Find new target to switch to -private _target = if ( +private _target = [ + ACE_player, + GVAR(previousTarget) +] select ( GVAR(target) == ACE_player && {[ACE_player, GVAR(previousTarget)] call EFUNC(common,canInteractWith)} && {[ACE_player, GVAR(previousTarget)] call FUNC(canOpenMenu)} -) then { - GVAR(previousTarget); -} else { - ACE_player; -}; +); // Exit if new target is same as old if (GVAR(target) == _target) exitWith {}; diff --git a/addons/medical_gui/functions/fnc_handleTriageSelect.sqf b/addons/medical_gui/functions/fnc_handleTriageSelect.sqf index 31a25e18ee..2c28aaded3 100644 --- a/addons/medical_gui/functions/fnc_handleTriageSelect.sqf +++ b/addons/medical_gui/functions/fnc_handleTriageSelect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Handles clicking the triage select buttons. diff --git a/addons/medical_gui/functions/fnc_menuPFH.sqf b/addons/medical_gui/functions/fnc_menuPFH.sqf index c2dc7a277f..b3d51c2dc9 100644 --- a/addons/medical_gui/functions/fnc_menuPFH.sqf +++ b/addons/medical_gui/functions/fnc_menuPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Handles updating the Medical Menu UI for the current target. @@ -16,7 +16,10 @@ */ // Check if menu should stay open for target -if !([ACE_player, GVAR(target), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith) && {[ACE_player, GVAR(target)] call FUNC(canOpenMenu)}) then { +if !( + ([ACE_player, GVAR(target), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith) || {!isNull findDisplay 312}) && // Allow player to look at himself when unconsious and in Zeus + {[ACE_player, GVAR(target)] call FUNC(canOpenMenu)} +) then { closeDialog 0; // Show hint if distance condition failed if ((ACE_player distance GVAR(target) > GVAR(maxDistance)) && {vehicle ACE_player != vehicle GVAR(target)}) then { @@ -40,7 +43,7 @@ private _ctrlInjuries = _display displayCtrl IDC_INJURIES; // Update body image private _ctrlBodyImage = _display displayCtrl IDC_BODY_GROUP; -[_ctrlBodyImage, GVAR(target)] call FUNC(updateBodyImage); +[_ctrlBodyImage, GVAR(target), GVAR(selectedBodyPart)] call FUNC(updateBodyImage); // Update activity and quick view logs private _ctrlActivityLog = _display displayCtrl IDC_ACTIVITY; diff --git a/addons/medical_gui/functions/fnc_modifyAction.sqf b/addons/medical_gui/functions/fnc_modifyAction.sqf index 422c73a475..177eb4e091 100644 --- a/addons/medical_gui/functions/fnc_modifyAction.sqf +++ b/addons/medical_gui/functions/fnc_modifyAction.sqf @@ -1,36 +1,34 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: esteldunedain, SilentSpike, mharis001 + * Author: esteldunedain, kymckay, mharis001 * Modifies the medical action icons to show blood loss and tourniquets. * * Arguments: * 0: Unit - * 1: Body part index + * 1: Body part * 2: Action data * * Return Value: * None * * Example: - * [_target, 0, _actionData] call ace_medical_gui_fnc_modifyAction + * [_target, "head", _actionData] call ace_medical_gui_fnc_modifyAction * * Public: No */ #define COLOR_SCALE ["#ffffff", "#fff1a1", "#ffe075", "#ffcb55", "#ffb73c", "#ffa127", "#ff8815", "#ff6d05", "#ff4b00", "#ff0000"] -params ["_target", "_partIndex", "_actionData"]; +params ["_target", "_bodyPart", "_actionData"]; +private _partIndex = ALL_BODY_PARTS find _bodyPart; private _bloodLossOnBodyPart = 0; // Add all bleeding from wounds on selection { - _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; - - if (_bodyPartN == _partIndex) then { - _bloodLossOnBodyPart = _bloodLossOnBodyPart + (_amountOf * _bleeding); - }; -} forEach GET_OPEN_WOUNDS(_target); + _x params ["", "_amountOf", "_bleeding"]; + _bloodLossOnBodyPart = _bloodLossOnBodyPart + (_amountOf * _bleeding); +} forEach (GET_OPEN_WOUNDS(_target) getOrDefault [_bodyPart, []]); 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_modifyActionTriageLevel.sqf b/addons/medical_gui/functions/fnc_modifyActionTriageLevel.sqf new file mode 100644 index 0000000000..b8cca898f2 --- /dev/null +++ b/addons/medical_gui/functions/fnc_modifyActionTriageLevel.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Modifies the action color to match the triage level. + * + * Arguments: + * 0: Target + * 1: Player + * 2: Args + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, [], []] call ace_medical_gui_fnc_modifyActionTriageLevel + * + * Public: No + */ + +params ["_target", "_player", "", "_actionData"]; +if ( + GVAR(interactionMenuShowTriage) == 1 // Anyone + || {GVAR(interactionMenuShowTriage) == 2 && {[_player] call EFUNC(medical_treatment,isMedic)}} // Medics & Doctors +) then { + private _colorHex = switch (_target getVariable [QEGVAR(medical,triageLevel), 0]) do { + case 1: { + [TRIAGE_COLOR_MINIMAL] call BIS_fnc_colorRGBtoHTML + }; + case 2: { + [TRIAGE_COLOR_DELAYED] call BIS_fnc_colorRGBtoHTML + }; + case 3: { + [TRIAGE_COLOR_IMMEDIATE] call BIS_fnc_colorRGBtoHTML + }; + case 4: { + [TRIAGE_COLOR_DECEASED] call BIS_fnc_colorRGBtoHTML + }; + default { + "#FFFFFF" + }; + }; + + _actionData params ["", "", "_icon"]; + _icon set [1, _colorHex]; +}; diff --git a/addons/medical_gui/functions/fnc_onKeyDown.sqf b/addons/medical_gui/functions/fnc_onKeyDown.sqf new file mode 100644 index 0000000000..6b9013f8be --- /dev/null +++ b/addons/medical_gui/functions/fnc_onKeyDown.sqf @@ -0,0 +1,100 @@ +#include "..\script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" +/* + * Author: AmsteadRayle + * Handles keyboard inputs in medical menu. + * + * Arguments: + * 1: Args + * - 0: Menu display + * - 1: Key being pressed + * - 2: Shift state + * - 3: Ctrl state + * - 4: Alt state + * + * Return Value: + * None + * + * Example: + * ["", [displayNull, 5, false, false, false]] call ace_medical_gui_fnc_onKeyDown + * + * Public: No +*/ +// TODO: Is the airway category ever visible? Can the dynamic category stuff be removed? + +#define NUMBER_KEYS [DIK_1, DIK_2, DIK_3, DIK_4, DIK_5, DIK_6, DIK_7, DIK_8, DIK_9, DIK_0] +#define ALL_CATEGORIES ["triage", "examine", "bandage", "medication", "airway", "advanced", "drag", "toggle"] + +params ["", "_args"]; +_args params ["_display", "_keyPressed", "_shiftState", "_ctrlState", "_altState"]; + +private _return = true; // Override existing keybinds for keys used here + +private _visibleCategories = [ + "bandage","medication","airway","advanced","drag" +] select { + private _category = _x; + (GVAR(actions) findIf {_category == _x select 1}) > -1 +}; + +private _allCategories = ["triage", "examine"] + _visibleCategories + ["toggle"]; + +// Use hashmap as a shortcut to "zip" two arrays together +// Use categories as keys in hashmap because there are fewer, +// otherwise the hashmap is padded with nil +private _keyCategoryPairs = _allCategories createHashMapFromArray NUMBER_KEYS; + +private _temp_category = ""; +private _temp_idc = 0; + +switch (true) do { +// Dynamically assign number keys to visible categories + { + _temp_category = _x; // _x does not exist inside case code + _temp_idc = IDC_TRIAGE + (ALL_CATEGORIES find _temp_category) * 10; + case (_keyPressed == _y && {GVAR(selectedCategory) != _temp_category}): { + if (ctrlEnabled _temp_idc) then { + if (_temp_category == "toggle") then { + call FUNC(handleToggle); + } else { + GVAR(selectedCategory) = _temp_category; + }; + } else { + _return = false; + }; + }; + } forEach _keyCategoryPairs; + +// Select body part through similar keyboard layout: +// w +// a s d +// z x + case (_keyPressed == DIK_W && {GVAR(selectedBodyPart) != 0}): { + GVAR(selectedBodyPart) = 0; + }; + case (_keyPressed == DIK_S && {GVAR(selectedBodyPart != 1)}): { + GVAR(selectedBodyPart) = 1; + }; + case (_keyPressed == DIK_D && {GVAR(selectedBodyPart) != 2}): { + GVAR(selectedBodyPart) = 2; + }; + case (_keyPressed == DIK_A && {GVAR(selectedBodyPart) != 3}): { + GVAR(selectedBodyPart) = 3; + }; + case (_keyPressed == DIK_X && {GVAR(selectedBodyPart) != 4}): { + GVAR(selectedBodyPart) = 4; + }; + case (_keyPressed == DIK_Z && {GVAR(selectedBodyPart) != 5}): { + GVAR(selectedBodyPart) = 5; + }; + + default { + _return = false; // Do not override existing keybinds for keys not used here + }; +}; + +if (_return) then { + playSound ["SoundClick", true] +}; + +_return diff --git a/addons/medical_gui/functions/fnc_onMenuClose.sqf b/addons/medical_gui/functions/fnc_onMenuClose.sqf index a531eca4e8..01165d8479 100644 --- a/addons/medical_gui/functions/fnc_onMenuClose.sqf +++ b/addons/medical_gui/functions/fnc_onMenuClose.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: joko // Jonas * Handles closing the Medical Menu. Called from onUnload event. diff --git a/addons/medical_gui/functions/fnc_onMenuOpen.sqf b/addons/medical_gui/functions/fnc_onMenuOpen.sqf index b6c326f590..12b27b60d9 100644 --- a/addons/medical_gui/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_gui/functions/fnc_onMenuOpen.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Handles opening the Medical Menu. Called from onLoad event. @@ -26,8 +26,8 @@ if (EGVAR(interact_menu,menuBackground) == 2) then {0 cutRsc [QEGVAR(interact_me [{setMousePosition _this}, _this] call CBA_fnc_execNextFrame; }, getMousePosition] call CBA_fnc_execNextFrame; -// Set target name as title -private _ctrlTitle = _display displayCtrl IDC_TITLE; +// Set middle header as target name +private _ctrlTitle = _display displayCtrl IDC_NAME; _ctrlTitle ctrlSetText ([GVAR(target)] call EFUNC(common,getName)); // Initially hide the triage select buttons @@ -41,7 +41,7 @@ if (GVAR(menuPFH) != -1) exitWith { TRACE_1("Menu PFH already running",GVAR(menuPFH)); }; -GVAR(menuPFH) = [FUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; +GVAR(menuPFH) = [LINKFUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; // Hide categories if they don't have any actions (airway) private _list = [ @@ -59,9 +59,25 @@ private _countEnabled = { 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)); +private _offsetX = POS_X(1.5) + 0.5 * (POS_X(12.33) - POS_X(_countEnabled * 1.5) - POS_W(2 * 0.2)); +// 0.2 - divider gap size + +// Set divider position +private _ctrl = _display displayCtrl IDC_TRIAGE_DIVIDER; +_ctrl ctrlSetPositionX _offsetX + POS_W(1.5) + POS_W(0.085); // 0.085 = (0.2 - 0.03) / 2 +_ctrl ctrlCommit 0; + +_ctrl = _display displayCtrl IDC_TOGGLE_DIVIDER; +_ctrl ctrlSetPositionX _offsetX + POS_W(1.5*(_countEnabled - 1)) + POS_W(0.2) + POS_W(0.085); +_ctrl ctrlCommit 0; + { _x params ["_idc", "_enabled"]; + + if (_forEachIndex == 1 || {_forEachIndex == count _list - 1}) then { + _offsetX = _offsetX + POS_W(0.2); + }; + private _ctrl = _display displayCtrl _idc; if (_enabled) then { _ctrl ctrlSetPositionX _offsetX; @@ -71,3 +87,13 @@ private _offsetX = POS_X(1.5) + 0.5 * (POS_X(12) - POS_X(_countEnabled * 1.5)); _ctrl ctrlShow false; }; } forEach _list; + +// Set toggle button icon and tooltip +private _ctrl = _display displayCtrl IDC_TOGGLE; +if (GVAR(target) == ACE_player) then { + _ctrl ctrlSetText QPATHTOF(data\categories\toggle_to_other.paa); + _ctrl ctrlSetTooltip LLSTRING(ToggleToOther); +} else { + _ctrl ctrlSetText QPATHTOF(data\categories\toggle_to_self.paa); + _ctrl ctrlSetTooltip LLSTRING(ToggleToSelf); +}; diff --git a/addons/medical_gui/functions/fnc_openMenu.sqf b/addons/medical_gui/functions/fnc_openMenu.sqf index cd8f71274c..4c9f21f62a 100644 --- a/addons/medical_gui/functions/fnc_openMenu.sqf +++ b/addons/medical_gui/functions/fnc_openMenu.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Opens the Medical Menu for given target. diff --git a/addons/medical_gui/functions/fnc_toggleTriageSelect.sqf b/addons/medical_gui/functions/fnc_toggleTriageSelect.sqf index 11281692e3..4b9ca1a750 100644 --- a/addons/medical_gui/functions/fnc_toggleTriageSelect.sqf +++ b/addons/medical_gui/functions/fnc_toggleTriageSelect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Toggles showing of the triage select buttons. diff --git a/addons/medical_gui/functions/fnc_updateActions.sqf b/addons/medical_gui/functions/fnc_updateActions.sqf index def2466009..6d52b8ccdf 100644 --- a/addons/medical_gui/functions/fnc_updateActions.sqf +++ b/addons/medical_gui/functions/fnc_updateActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Updates the action buttons based currently avaiable treatments. @@ -19,39 +19,66 @@ params ["_display"]; private _selectedCategory = GVAR(selectedCategory); -// Clear all action buttons -{ - private _ctrl = _display displayCtrl _x; - _ctrl ctrlRemoveAllEventHandlers "ButtonClick"; - _ctrl ctrlShow false; -} forEach IDCS_ACTION_BUTTONS; +private _group = _display displayCtrl IDC_ACTION_BUTTON_GROUP; +private _actionButons = allControls _group; // Handle triage list (no actions shown) private _ctrlTriage = _display displayCtrl IDC_TRIAGE_CARD; private _showTriage = _selectedCategory == "triage"; _ctrlTriage ctrlEnable _showTriage; +_group ctrlEnable !_showTriage; lbClear _ctrlTriage; if (_showTriage) exitWith { + { ctrlDelete _x } forEach _actionButons; [_ctrlTriage, GVAR(target)] call FUNC(updateTriageCard); }; // Show treatment options on action buttons -private _idcIndex = 0; - +private _shownIndex = 0; { - _x params ["_displayName", "_category", "_condition", "_statement"]; + _x params ["_displayName", "_category", "_condition", "_statement", "_items"]; // Check action category and condition if (_category == _selectedCategory && {call _condition}) then { - private _ctrl = _display displayCtrl (IDCS_ACTION_BUTTONS select _idcIndex); + private _ctrl = if (_shownIndex >= count _actionButons) then { + _actionButons pushBack (_display ctrlCreate ["ACE_Medical_Menu_ActionButton", -1, _group]); + }; + _ctrl = _actionButons # _shownIndex; + _ctrl ctrlRemoveAllEventHandlers "ButtonClick"; + _ctrl ctrlSetPositionY POS_H(1.1 * _shownIndex); + _ctrl ctrlCommit 0; + + private _countText = ""; + if (_items isNotEqualTo []) then { + if ("ACE_surgicalKit" in _items && {EGVAR(medical_treatment,consumeSurgicalKit) == 2}) then { + _items = ["ACE_suture"]; + }; + private _counts = [_items] call FUNC(countTreatmentItems); + _countText = _counts call FUNC(formatItemCounts); + }; + _ctrl ctrlSetTooltipColorText [1, 1, 1, 1]; + _ctrl ctrlSetTooltip _countText; + + // Show warning if tourniquet will interfere with action + if ( + GVAR(tourniquetWarning) && + {(_category in ["examine", "medication"]) || (_items findIf {"IV" in _x}) > -1} && + {HAS_TOURNIQUET_APPLIED_ON(GVAR(target),GVAR(selectedBodyPart))} + ) then { + _ctrl ctrlSetTooltipColorText [1, 1, 0, 1]; + _ctrl ctrlSetTooltip LLSTRING(TourniquetWarning); + }; + _ctrl ctrlSetText _displayName; _ctrl ctrlShow true; _ctrl ctrlAddEventHandler ["ButtonClick", _statement]; _ctrl ctrlAddEventHandler ["ButtonClick", {GVAR(pendingReopen) = true}]; - _idcIndex = _idcIndex + 1; + _shownIndex = _shownIndex + 1; }; } forEach GVAR(actions); + +{ ctrlDelete _x } forEach (_actionButons select [_shownIndex, 9999]); diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index 3841f58d2e..b8ee8ee240 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -1,36 +1,46 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal, SilentSpike, mharis001 + * Author: Glowbal, kymckay, mharis001 * Updates the body image for given target. * * Arguments: * 0: Body image controls group * 1: Target + * 2: Body part * * Return Value: * None * * Example: - * [CONTROL, _target] call ace_medical_menu_fnc_updateBodyImage + * [CONTROL, _target, 0] call ace_medical_gui_fnc_updateBodyImage * * Public: No */ -params ["_ctrlGroup", "_target"]; +params ["_ctrlGroup", "_target", "_selectionN"]; // 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 _damageThreshold = GET_DAMAGE_THRESHOLD(_target); private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; { - _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; - _bodyPartBloodLoss set [_bodyPartN, (_bodyPartBloodLoss select _bodyPartN) + (_bleeding * _amountOf)]; + private _partIndex = ALL_BODY_PARTS find _x; + { + _x params ["", "_amountOf", "_bleeding"]; + _bodyPartBloodLoss set [_partIndex, (_bodyPartBloodLoss select _partIndex) + (_bleeding * _amountOf)]; + } forEach _y; } forEach GET_OPEN_WOUNDS(_target); { - _x params ["_bodyPartIDC", ["_tourniquetIDC", -1], ["_fractureIDC", -1]]; + _x params ["_bodyPartIDC", "_selectedIDC", ["_tourniquetIDC", -1], ["_fractureIDC", -1]]; + + private _selected = _forEachIndex == _selectionN; + private _ctrlSelected = _ctrlGroup controlsGroupCtrl _selectedIDC; + _ctrlSelected ctrlSetTextColor GVAR(bodypartOutlineColor); + _ctrlSelected ctrlShow _selected; // Show or hide the tourniquet icon if (_tourniquetIDC != -1) then { @@ -51,7 +61,7 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; _ctrlBone ctrlSetTextColor [1, 0, 0, 1]; }; case -1: { - if (EGVAR(medical,fractures) == 2) then { + if (EGVAR(medical,fractures) in [2, 3]) then { _ctrlBone ctrlShow true; _ctrlBone ctrlSetTextColor [0, 0, 1, 1]; } else { @@ -67,16 +77,33 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; [_bloodLoss] call FUNC(bloodLossToRGBA); } else { private _damage = _bodyPartDamage select _forEachIndex; + switch (true) do { // torso damage threshold doesn't need scaling + case (_forEachIndex > 3): { // legs: index 4 & 5 + _damageThreshold = LIMPING_DAMAGE_THRESHOLD * 4; + }; + case (_forEachIndex > 1): { // arms: index 2 & 3 + _damageThreshold = FRACTURE_DAMAGE_THRESHOLD * 4; + }; + case (_forEachIndex == 0): { // head: index 0 + _damageThreshold = _damageThreshold * 1.25; + }; + default { // torso: index 1 + _damageThreshold = _damageThreshold * 1.5 + }; + }; + _damage = (_damage / (0.01 max _damageThreshold)) min 1; [_damage] call FUNC(damageToRGBA); }; private _ctrlBodyPart = _ctrlGroup controlsGroupCtrl _bodyPartIDC; _ctrlBodyPart ctrlSetTextColor _bodyPartColor; } forEach [ - [IDC_BODY_HEAD], - [IDC_BODY_TORSO], - [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] + [IDC_BODY_HEAD, IDC_BODY_HEAD_S], + [IDC_BODY_TORSO, IDC_BODY_TORSO_S], + [IDC_BODY_ARMLEFT, IDC_BODY_ARMLEFT_S, IDC_BODY_ARMLEFT_T, IDC_BODY_ARMLEFT_B], + [IDC_BODY_ARMRIGHT, IDC_BODY_ARMRIGHT_S, IDC_BODY_ARMRIGHT_T, IDC_BODY_ARMRIGHT_B], + [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_S, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B], + [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_S, IDC_BODY_LEGRIGHT_T, IDC_BODY_LEGRIGHT_B] ]; + +[QGVAR(updateBodyImage), [_ctrlGroup, _target, _selectionN]] call CBA_fnc_localEvent; diff --git a/addons/medical_gui/functions/fnc_updateCategories.sqf b/addons/medical_gui/functions/fnc_updateCategories.sqf index ac1c068fb7..c2f1d2a11c 100644 --- a/addons/medical_gui/functions/fnc_updateCategories.sqf +++ b/addons/medical_gui/functions/fnc_updateCategories.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Updates the category buttons based currently avaiable treatments. @@ -21,12 +21,24 @@ params ["_display"]; _x params ["_idc", "_category"]; private _ctrl = _display displayCtrl _idc; - private _enable = GVAR(actions) findIf {_category == _x select 1 && {call (_x select 2)}} > -1; + private _enable = if (_category == "triage") then { true } else { + GVAR(actions) findIf {_category == _x select 1 && {call (_x select 2)}} > -1 + }; _ctrl ctrlEnable _enable; + private _selectedColor = [ + profileNamespace getVariable ["GUI_BCG_RGB_R", 0.13], + profileNamespace getVariable ["GUI_BCG_RGB_G", 0.54], + profileNamespace getVariable ["GUI_BCG_RGB_B", 0.21], + profileNamespace getVariable ["GUI_BCG_RGB_A", 0.8] + ]; private _color = [[0.4, 0.4, 0.4, 1], [1, 1, 1, 1]] select _enable; + _color = [_color, _selectedColor] select (GVAR(selectedCategory) isEqualTo _category); _ctrl ctrlSetTextColor _color; + _color set [-1, 0.8]; // Mouseover change + _ctrl ctrlSetActiveColor _color; } forEach [ + [IDC_TRIAGE, "triage"], [IDC_EXAMINE, "examine"], [IDC_BANDAGE, "bandage"], [IDC_MEDICATION, "medication"], diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 2770dc04ea..3219eb025f 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Updates injury list for given body part for the target. @@ -6,7 +6,7 @@ * Arguments: * 0: Injury list * 1: Target - * 2: Body part + * 2: Body part, -1 to only show overall health info * * Return Value: * None @@ -20,6 +20,134 @@ params ["_ctrl", "_target", "_selectionN"]; private _entries = []; +private _nonissueColor = [1, 1, 1, 0.33]; + +// Indicate if unit is bleeding at all +if (IS_BLEEDING(_target)) then { + switch (GVAR(showBleeding)) do { + case 1: { + // Just show whether the unit is bleeding at all + _entries pushBack [localize LSTRING(Status_Bleeding), [1, 0, 0, 1]]; + }; + case 2: { + // Give a qualitative description of the rate of bleeding + private _cardiacOutput = [_target] call EFUNC(medical_status,getCardiacOutput); + private _bleedRate = GET_BLOOD_LOSS(_target); + private _bleedRateKO = BLOOD_LOSS_KNOCK_OUT_THRESHOLD * (_cardiacOutput max 0.05); + // Use nonzero minimum cardiac output to prevent all bleeding showing as massive during cardiac arrest + switch (true) do { + case (_bleedRate < _bleedRateKO * BLEED_RATE_SLOW): { + _entries pushBack [localize LSTRING(Bleed_Rate1), [1, 1, 0, 1]]; + }; + case (_bleedRate < _bleedRateKO * BLEED_RATE_MODERATE): { + _entries pushBack [localize LSTRING(Bleed_Rate2), [1, 0.67, 0, 1]]; + }; + case (_bleedRate < _bleedRateKO * BLEED_RATE_SEVERE): { + _entries pushBack [localize LSTRING(Bleed_Rate3), [1, 0.33, 0, 1]]; + }; + default { + _entries pushBack [localize LSTRING(Bleed_Rate4), [1, 0, 0, 1]]; + }; + }; + }; + }; +} else { + _entries pushBack [localize LSTRING(Status_Nobleeding), _nonissueColor]; +}; + +if (GVAR(showBloodlossEntry)) then { + // Give a qualitative description of the blood volume lost + switch (GET_HEMORRHAGE(_target)) do { + case 0: { + _entries pushBack [localize LSTRING(Lost_Blood0), _nonissueColor]; + }; + case 1: { + _entries pushBack [localize LSTRING(Lost_Blood1), [1, 1, 0, 1]]; + }; + case 2: { + _entries pushBack [localize LSTRING(Lost_Blood2), [1, 0.67, 0, 1]]; + }; + case 3: { + _entries pushBack [localize LSTRING(Lost_Blood3), [1, 0.33, 0, 1]]; + }; + case 4: { + _entries pushBack [localize LSTRING(Lost_Blood4), [1, 0, 0, 1]]; + }; + }; +}; +// Show receiving IV volume remaining +private _totalIvVolume = 0; +private _saline = 0; +private _blood = 0; +private _plasma = 0; +{ + _x params ["_volumeRemaining", "_type"]; + switch (_type) do { + case "Saline": { + _saline = _saline + _volumeRemaining; + }; + case "Blood": { + _blood = _blood + _volumeRemaining; + }; + case "Plasma": { + _plasma = _plasma + _volumeRemaining; + }; + }; + _totalIvVolume = _totalIvVolume + _volumeRemaining; +} forEach (_target getVariable [QEGVAR(medical,ivBags), []]); + +if (_totalIvVolume > 0) then { + if (_saline > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingSalineIvVolume), floor _saline], [1, 1, 1, 1]]; + }; + if (_blood > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingBloodIvVolume), floor _blood], [1, 1, 1, 1]]; + }; + if (_plasma > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingPlasmaIvVolume), floor _plasma], [1, 1, 1, 1]]; + }; +} else { + _entries pushBack [localize ELSTRING(medical_treatment,Status_NoIv), _nonissueColor]; +}; + +// Indicate the amount of pain the unit is in +if (_target call EFUNC(common,isAwake)) then { + private _pain = GET_PAIN_PERCEIVED(_target); + if (_pain > 0) then { + private _painText = switch (true) do { + case (_pain > PAIN_UNCONSCIOUS): { + ELSTRING(medical_treatment,Status_SeverePain); + }; + case (_pain > (PAIN_UNCONSCIOUS / 5)): { + ELSTRING(medical_treatment,Status_Pain); + }; + default { + ELSTRING(medical_treatment,Status_MildPain); + }; + }; + _entries pushBack [localize _painText, [1, 1, 1, 1]]; + } else { + _entries pushBack [localize ELSTRING(medical_treatment,Status_NoPain), _nonissueColor]; + }; +}; + +// Skip the rest as they're body part specific +if (_selectionN == -1) exitWith { + // Add all entries to injury list + lbClear _ctrl; + + { + _x params ["_text", "_color"]; + + _ctrl lbSetColor [_ctrl lbAdd _text, _color]; + } forEach _entries; + + _ctrl lbSetCurSel -1; +}; + +[QGVAR(updateInjuryListGeneral), [_ctrl, _target, _selectionN, _entries]] call CBA_fnc_localEvent; + +_entries pushBack ["", [1, 1, 1, 1]]; // Add selected body part name private _bodyPartName = [ @@ -33,24 +161,40 @@ private _bodyPartName = [ _entries pushBack [localize _bodyPartName, [1, 1, 1, 1]]; -// Indicate if unit is bleeding at all -if (IS_BLEEDING(_target)) then { - _entries pushBack [localize LSTRING(Status_Bleeding), [1, 0, 0, 1]]; -}; - -// Give a qualitative description of the blood volume lost -switch (GET_HEMORRHAGE(_target)) do { - case 1: { - _entries pushBack [localize LSTRING(Lost_Blood1), [1, 0, 0, 1]]; - }; - case 2: { - _entries pushBack [localize LSTRING(Lost_Blood2), [1, 0, 0, 1]]; - }; - case 3: { - _entries pushBack [localize LSTRING(Lost_Blood3), [1, 0, 0, 1]]; - }; - case 4: { - _entries pushBack [localize LSTRING(Lost_Blood4), [1, 0, 0, 1]]; +// Damage taken tooltip +if (GVAR(showDamageEntry)) then { + private _bodyPartDamage = (_target getVariable [QEGVAR(medical,bodyPartDamage), [0, 0, 0, 0, 0, 0]]) select _selectionN; + if (_bodyPartDamage > 0) then { + private _damageThreshold = GET_DAMAGE_THRESHOLD(_target); + switch (true) do { + case (_selectionN > 3): { // legs: index 4 & 5 + _damageThreshold = LIMPING_DAMAGE_THRESHOLD * 4; + }; + case (_selectionN > 1): { // arms: index 2 & 3 + _damageThreshold = FRACTURE_DAMAGE_THRESHOLD * 4; + }; + case (_selectionN == 0): { // head: index 0 + _damageThreshold = _damageThreshold * 1.25; + }; + default { // torso: index 1 + _damageThreshold = _damageThreshold * 1.5; + }; + }; + _bodyPartDamage = (_bodyPartDamage / _damageThreshold) min 1; + switch (true) do { + case (_bodyPartDamage isEqualTo 1): { + _entries pushBack [localize LSTRING(traumaSustained4), [_bodyPartDamage] call FUNC(damageToRGBA)]; + }; + case (_bodyPartDamage >= 0.75): { + _entries pushBack [localize LSTRING(traumaSustained3), [_bodyPartDamage] call FUNC(damageToRGBA)]; + }; + case (_bodyPartDamage >= 0.5): { + _entries pushBack [localize LSTRING(traumaSustained2), [_bodyPartDamage] call FUNC(damageToRGBA)]; + }; + case (_bodyPartDamage >= 0.25): { + _entries pushBack [localize LSTRING(traumaSustained1), [_bodyPartDamage] call FUNC(damageToRGBA)]; + }; + }; }; }; @@ -65,88 +209,51 @@ switch (GET_FRACTURES(_target) select _selectionN) do { _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]]; + if (EGVAR(medical,fractures) in [2, 3]) then { // Ignore if the splint has no effect + _entries pushBack [localize LSTRING(Status_SplintApplied), [0.2, 0.2, 1, 1]]; }; }; }; -// Indicate the amount of pain the unit is in -if ([_target] call EFUNC(common,isAwake)) then { - private _pain = GET_PAIN_PERCEIVED(_target); - if (_pain > 0) then { - private _painText = switch (true) do { - case (_pain > 0.5): { - ELSTRING(medical_treatment,Status_SeverePain); - }; - case (_pain > 0.1): { - ELSTRING(medical_treatment,Status_Pain); - }; - default { - ELSTRING(medical_treatment,Status_MildPain); - }; - }; - _entries pushBack [localize _painText, [1, 1, 1, 1]]; - }; -}; - -// Show receiving IV volume remaining -private _totalIvVolume = 0; -{ - _x params ["_volumeRemaining"]; - _totalIvVolume = _totalIvVolume + _volumeRemaining; -} forEach (_target getVariable [QEGVAR(medical,ivBags), []]); - -if (_totalIvVolume >= 1) then { - _entries pushBack [format [localize ELSTRING(medical_treatment,receivingIvVolume), floor _totalIvVolume], [1, 1, 1, 1]]; -}; +[QGVAR(updateInjuryListPart), [_ctrl, _target, _selectionN, _entries, _bodyPartName]] call CBA_fnc_localEvent; // Add entries for open, bandaged, and stitched wounds private _woundEntries = []; -private _fnc_getWoundDescription = { - 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]; - }; +private _fnc_processWounds = { + params ["_wounds", "_format", "_color"]; + + { + _x params ["_woundClassID", "_amountOf"]; + + if (_amountOf > 0) then { + private _classIndex = _woundClassID / 10; + private _category = _woundClassID % 10; + + private _className = EGVAR(medical_damage,woundClassNames) select _classIndex; + private _suffix = ["Minor", "Medium", "Large"] select _category; + private _woundName = localize format [ELSTRING(medical_damage,%1_%2), _className, _suffix]; + + private _woundDescription = if (_amountOf >= 1) then { + format ["%1x %2", ceil _amountOf, _woundName] + } else { + format [localize LSTRING(PartialX), _woundName] + }; + + _woundEntries pushBack [format [_format, _woundDescription], _color]; + }; + } forEach (_wounds getOrDefault [ALL_BODY_PARTS select _selectionN, []]); }; -{ - _x params ["_woundClassID", "_bodyPartN", "_amountOf"]; - if (_selectionN == _bodyPartN) then { - if (_amountOf > 0) then { - _woundEntries pushBack [call _fnc_getWoundDescription, [1, 1, 1, 1]]; - } else { - if !(EGVAR(medical_treatment,advancedBandages) && {EGVAR(medical_treatment,woundReopening)}) then { - _woundEntries pushBack [format ["[B] %1", call _fnc_getWoundDescription], [0.7, 0.7, 0.7, 1]]; - }; - }; - }; -} forEach GET_OPEN_WOUNDS(_target); +[GET_OPEN_WOUNDS(_target), "%1", [1, 1, 1, 1]] call _fnc_processWounds; +[GET_BANDAGED_WOUNDS(_target), "[B] %1", [0.88, 0.7, 0.65, 1]] call _fnc_processWounds; +[GET_STITCHED_WOUNDS(_target), "[S] %1", [0.7, 0.7, 0.7, 1]] call _fnc_processWounds; -{ - _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 GET_BANDAGED_WOUNDS(_target); - -{ - _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 GET_STITCHED_WOUNDS(_target); +[QGVAR(updateInjuryListWounds), [_ctrl, _target, _selectionN, _woundEntries, _bodyPartName]] call CBA_fnc_localEvent; // Handle no wound entries if (_woundEntries isEqualTo []) then { - _entries pushBack [localize ELSTRING(medical_treatment,NoInjuriesBodypart), [1, 1, 1, 1]]; + _entries pushBack [localize ELSTRING(medical_treatment,NoInjuriesBodypart), _nonissueColor]; } else { _entries append _woundEntries; }; @@ -156,7 +263,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 fb83640698..51240705f9 100644 --- a/addons/medical_gui/functions/fnc_updateLogList.sqf +++ b/addons/medical_gui/functions/fnc_updateLogList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Updates list control with given logs. @@ -23,6 +23,8 @@ lbClear _ctrl; { _x params ["_message", "_timeStamp", "_arguments"]; + private _unlocalizedMessage = _message; + // Localize message and arguments if (isLocalized _message) then { _message = localize _message; @@ -33,5 +35,7 @@ lbClear _ctrl; // Format message with arguments _message = format ([_message] + _arguments); - _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; + private _row = _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; + + [QGVAR(logListAppended), [_ctrl, _row, _message, _unlocalizedMessage, _timeStamp, _arguments]] call CBA_fnc_localEvent; } forEach _logs; diff --git a/addons/medical_gui/functions/fnc_updateTriageCard.sqf b/addons/medical_gui/functions/fnc_updateTriageCard.sqf index b4e1977d42..40bd196c66 100644 --- a/addons/medical_gui/functions/fnc_updateTriageCard.sqf +++ b/addons/medical_gui/functions/fnc_updateTriageCard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Updates the triage card for the given target. diff --git a/addons/medical_gui/functions/fnc_updateTriageStatus.sqf b/addons/medical_gui/functions/fnc_updateTriageStatus.sqf index 9a50e4f6c0..0ec694409a 100644 --- a/addons/medical_gui/functions/fnc_updateTriageStatus.sqf +++ b/addons/medical_gui/functions/fnc_updateTriageStatus.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Updates the triage status control for the given target. diff --git a/addons/medical_gui/functions/script_component.hpp b/addons/medical_gui/functions/script_component.hpp deleted file mode 100644 index d2302a9920..0000000000 --- a/addons/medical_gui/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_gui\script_component.hpp" diff --git a/addons/medical_gui/gui.hpp b/addons/medical_gui/gui.hpp index 06db05ad38..f9cb0b40a3 100644 --- a/addons/medical_gui/gui.hpp +++ b/addons/medical_gui/gui.hpp @@ -4,22 +4,23 @@ class RscPicture; class RscListBox; class RscActivePicture; class RscButtonMenu; +class RscControlsGroup; class RscControlsGroupNoScrollbars; class GVAR(BodyImage): RscControlsGroupNoScrollbars { idc = IDC_BODY_GROUP; - x = POS_X(13.33); - y = POS_Y(2.73); - w = POS_W(12.33); - h = POS_H(12.33); + x = QUOTE(POS_X(13.83)); + y = QUOTE(POS_Y(2.73)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(12.33)); class controls { class Background: RscPicture { idc = -1; text = QPATHTOF(data\body_image\background.paa); x = 0; y = 0; - w = POS_W(12.33); - h = POS_H(12.33); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(12.33)); }; class Head: Background { idc = IDC_BODY_HEAD; @@ -81,16 +82,42 @@ class GVAR(BodyImage): RscControlsGroupNoScrollbars { idc = IDC_BODY_LEGRIGHT_T; text = QPATHTOF(data\body_image\leg_right_t.paa); }; + class HeadS: Background { + idc = IDC_BODY_HEAD_S; + text = QPATHTOF(data\body_image\head_s.paa); + colorText[] = {1.0, 1.0, 1.0, 1.0}; + show = 0; + }; + class TorsoS: HeadS { + idc = IDC_BODY_TORSO_S; + text = QPATHTOF(data\body_image\torso_s.paa); + }; + class ArmLeftS: HeadS { + idc = IDC_BODY_ARMLEFT_S; + text = QPATHTOF(data\body_image\arm_left_s.paa); + }; + class ArmRightS: HeadS { + idc = IDC_BODY_ARMRIGHT_S; + text = QPATHTOF(data\body_image\arm_right_s.paa); + }; + class LegLeftS: HeadS { + idc = IDC_BODY_LEGLEFT_S; + text = QPATHTOF(data\body_image\leg_left_s.paa); + }; + class LegRightS: HeadS { + idc = IDC_BODY_LEGRIGHT_S; + text = QPATHTOF(data\body_image\leg_right_s.paa); + }; }; }; class GVAR(TriageToggle): RscButton { idc = -1; onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(toggleTriageSelect)); - x = POS_X(13.33); - y = POS_Y(15.5); - w = POS_W(12.33); - h = POS_H(1.1); + x = QUOTE(POS_X(13.83)); + y = QUOTE(POS_Y(15.5)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(1.1)); colorFocused[] = {0, 0, 0, 0}; colorBackground[] = {0, 0, 0, 0}; colorBackgroundActive[] = {0, 0, 0, 0}; @@ -98,10 +125,10 @@ class GVAR(TriageToggle): RscButton { class GVAR(TriageSelect): RscControlsGroupNoScrollbars { idc = IDC_TRIAGE_SELECT; - x = POS_X(13.33); - y = POS_Y(16.6); - w = POS_W(12.33); - h = POS_H(5.5); + x = QUOTE(POS_X(13.83)); + y = QUOTE(POS_Y(16.6)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(5.5)); class controls { class None: RscButton { idc = -1; @@ -110,8 +137,8 @@ class GVAR(TriageSelect): RscControlsGroupNoScrollbars { text = ECSTRING(medical_treatment,Triage_Status_None); x = 0; y = 0; - w = POS_W(12.33); - h = POS_H(1.1); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(1.1)); shadow = 0; colorText[] = {TRIAGE_TEXT_COLOR_NONE}; colorFocused[] = {TRIAGE_COLOR_NONE}; @@ -121,7 +148,7 @@ class GVAR(TriageSelect): RscControlsGroupNoScrollbars { class Minimal: None { onButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0),GVAR(target),1)] call FUNC(handleTriageSelect)); text = ECSTRING(medical_treatment,Triage_Status_Minimal); - y = POS_H(1.1); + y = QUOTE(POS_H(1.1)); colorText[] = {TRIAGE_TEXT_COLOR_MINIMAL}; colorFocused[] = {TRIAGE_COLOR_MINIMAL}; colorBackground[] = {TRIAGE_COLOR_MINIMAL}; @@ -130,7 +157,7 @@ class GVAR(TriageSelect): RscControlsGroupNoScrollbars { class Delayed: None { onButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0),GVAR(target),2)] call FUNC(handleTriageSelect)); text = ECSTRING(medical_treatment,Triage_Status_Delayed); - y = POS_H(2.2); + y = QUOTE(POS_H(2.2)); colorText[] = {TRIAGE_TEXT_COLOR_DELAYED}; colorFocused[] = {TRIAGE_COLOR_DELAYED}; colorBackground[] = {TRIAGE_COLOR_DELAYED}; @@ -139,7 +166,7 @@ class GVAR(TriageSelect): RscControlsGroupNoScrollbars { class Immediate: None { onButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0),GVAR(target),3)] call FUNC(handleTriageSelect)); text = ECSTRING(medical_treatment,Triage_Status_Immediate); - y = POS_H(3.3); + y = QUOTE(POS_H(3.3)); colorText[] = {TRIAGE_TEXT_COLOR_IMMEDIATE}; colorFocused[] = {TRIAGE_COLOR_IMMEDIATE}; colorBackground[] = {TRIAGE_COLOR_IMMEDIATE}; @@ -148,7 +175,7 @@ class GVAR(TriageSelect): RscControlsGroupNoScrollbars { class Deceased: None { onButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0),GVAR(target),4)] call FUNC(handleTriageSelect)); text = ECSTRING(medical_treatment,Triage_Status_Deceased); - y = POS_H(4.4); + y = QUOTE(POS_H(4.4)); colorText[] = {TRIAGE_TEXT_COLOR_DECEASED}; colorFocused[] = {TRIAGE_COLOR_DECEASED}; colorBackground[] = {TRIAGE_COLOR_DECEASED}; @@ -157,33 +184,51 @@ class GVAR(TriageSelect): RscControlsGroupNoScrollbars { }; }; +class ACE_Medical_Menu_ActionButton: RscButtonMenu { + idc = -1; + style = ST_LEFT; + x = 0; + y = 0; + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(1)); + size = QUOTE(POS_H(0.9)); + class Attributes { + align = "center"; + color = "#E5E5E5"; + font = "RobotoCondensed"; + shadow = "false"; + }; +}; + class ACE_Medical_Menu { idd = IDD_MEDICAL_MENU; movingEnable = 1; enableSimulation = 1; onLoad = QUOTE(_this call FUNC(onMenuOpen)); onUnload = QUOTE(_this call FUNC(onMenuClose)); + onKeyDown = QUOTE([ARR_3('onKeyDown',_this,QQGVAR(display))] call FUNC(onKeyDown)); class controlsBackground { class Title: RscText { idc = IDC_TITLE; - x = POS_X(1); - y = POS_Y(0); - w = POS_W(38); - h = POS_H(1); + text = CSTRING(MedicalMenu); + x = QUOTE(POS_X(1)); + y = QUOTE(POS_Y(0)); + w = QUOTE(POS_W(38)); + h = QUOTE(POS_H(1)); colorBackground[] = GUI_BCG_COLOR; moving = 1; }; class Center: RscText { idc = -1; - x = POS_X(1); - y = POS_Y(1.1); - w = POS_W(38); - h = POS_H(16); + x = QUOTE(POS_X(1)); + y = QUOTE(POS_Y(1.1)); + w = QUOTE(POS_W(38)); + h = QUOTE(POS_H(16)); colorBackground[] = {0, 0, 0, 0.7}; }; class Bottom: Center { - y = POS_Y(17.6); - h = POS_H(9); + y = QUOTE(POS_Y(17.6)); + h = QUOTE(POS_H(9)); }; }; class controls { @@ -191,27 +236,28 @@ class ACE_Medical_Menu { idc = -1; style = ST_CENTER; text = CSTRING(EXAMINE_TREATMENT); - x = POS_X(1); - y = POS_Y(1.5); - w = POS_W(12.33); - h = POS_H(1); - sizeEx = POS_H(1.2); + x = QUOTE(POS_X(1.5)); + y = QUOTE(POS_Y(1.5)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(1)); + sizeEx = QUOTE(POS_H(1.2)); colorText[] = {1, 1, 1, 0.9}; }; - class StatusHeader: TreatmentHeader { - text = CSTRING(STATUS); - x = POS_X(13.33); + class NameHeader: TreatmentHeader { + idc = IDC_NAME; + x = QUOTE(POS_X(13.83)); }; class OverviewHeader: TreatmentHeader { text = CSTRING(OVERVIEW); - x = POS_X(25.66); + w = QUOTE(POS_W(12.34)); // 12.33 + 12.33 + 12.34 = 37.00 + x = QUOTE(POS_X(26.16)); }; class HeaderLine: RscText { idc = -1; - x = POS_X(1.5); - y = POS_Y(2.6); - w = POS_W(37); - h = POS_H(0.03); + x = QUOTE(POS_X(1.5)); + y = QUOTE(POS_Y(2.6)); + w = QUOTE(POS_W(37)); + h = QUOTE(POS_H(0.03)); colorBackground[] = {1, 1, 1, 0.5}; }; class Triage: RscActivePicture { @@ -219,11 +265,12 @@ class ACE_Medical_Menu { onButtonClick = QUOTE(GVAR(selectedCategory) = 'triage'); text = QPATHTOF(data\categories\triage_card.paa); tooltip = CSTRING(ViewTriageCard); - x = POS_X(1.5); - y = POS_Y(2.73); - w = POS_W(1.5); - h = POS_H(1.5); + x = QUOTE(POS_X(1.75)); + y = QUOTE(POS_Y(2.75)); + w = QUOTE(POS_W(1.5)); + h = QUOTE(POS_H(1.5)); color[] = {1, 1, 1, 1}; + colorActive[] = {1, 1, 1, 0.8}; soundClick[] = {"\a3\ui_f\data\sound\rscbutton\soundClick", 0.09, 1}; soundEnter[] = {"\a3\ui_f\data\sound\rscbutton\soundEnter", 0.09, 1}; soundEscape[] = {"\a3\ui_f\data\sound\rscbutton\soundEscape", 0.09, 1}; @@ -234,57 +281,67 @@ class ACE_Medical_Menu { onButtonClick = QUOTE(GVAR(selectedCategory) = 'examine'); text = QPATHTOF(data\categories\examine_patient.paa); tooltip = CSTRING(ExaminePatient); - x = POS_X(3); + x = QUOTE(POS_X(3.25)); }; class Bandage: Triage { idc = IDC_BANDAGE; onButtonClick = QUOTE(GVAR(selectedCategory) = 'bandage'); text = QPATHTOF(data\categories\bandage_fracture.paa); tooltip = CSTRING(BandageFractures); - x = POS_X(4.5); + x = QUOTE(POS_X(4.75)); }; class Medication: Triage { idc = IDC_MEDICATION; onButtonClick = QUOTE(GVAR(selectedCategory) = 'medication'); text = QPATHTOF(data\categories\medication.paa); tooltip = CSTRING(Medication); - x = POS_X(6); + x = QUOTE(POS_X(6.25)); }; class Airway: Triage { idc = IDC_AIRWAY; onButtonClick = QUOTE(GVAR(selectedCategory) = 'airway'); text = QPATHTOF(data\categories\airway_management.paa); tooltip = CSTRING(AirwayManagement); - x = POS_X(7.5); + x = QUOTE(POS_X(7.75)); }; class Advanced: Triage { idc = IDC_ADVANCED; onButtonClick = QUOTE(GVAR(selectedCategory) = 'advanced'); text = QPATHTOF(data\categories\advanced_treatment.paa); tooltip = CSTRING(AdvancedTreatment); - x = POS_X(9); + x = QUOTE(POS_X(9.25)); }; class Drag: Triage { idc = IDC_DRAG; onButtonClick = QUOTE(GVAR(selectedCategory) = 'drag'); text = QPATHTOF(data\categories\carry.paa); tooltip = CSTRING(DragCarry); - x = POS_X(10.5); + x = QUOTE(POS_X(10.75)); }; class Toggle: Triage { idc = IDC_TOGGLE; onButtonClick = QUOTE(call FUNC(handleToggle)); - text = QPATHTOF(data\categories\toggle_self.paa); - tooltip = CSTRING(ToggleSelf); - x = POS_X(12); + text = QPATHTOF(data\categories\toggle_to_other.paa); + x = QUOTE(POS_X(12)); + }; + class TriageDivider: HeaderLine { + idc = IDC_TRIAGE_DIVIDER; + x = QUOTE(POS_X(3.265)); + y = QUOTE(POS_Y(3.0)); + w = QUOTE(POS_W(0.03)); + h = QUOTE(POS_H(1.0)); + }; + class ToggleDivider: TriageDivider { + idc = IDC_TOGGLE_DIVIDER; + x = QUOTE(POS_X(3.265)); }; class TriageCard: RscListBox { idc = IDC_TRIAGE_CARD; - x = POS_X(1.5); - y = POS_Y(4.4); - w = POS_W(12); - h = POS_H(10); - sizeEx = POS_H(0.7); + x = QUOTE(POS_X(1.5)); + y = QUOTE(POS_Y(4.4)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(12.2)); + sizeEx = QUOTE(POS_H(0.7)); colorSelect[] = {1, 1, 1, 1}; colorSelect2[] = {1, 1, 1, 1}; colorBackground[] = {0, 0, 0, 0.2}; @@ -292,62 +349,22 @@ class ACE_Medical_Menu { colorSelectBackground2[] = {0, 0, 0, 0}; colorScrollbar[] = {0.9, 0.9, 0.9, 1}; }; - class Action1: RscButtonMenu { - idc = IDC_ACTION_1; - style = ST_LEFT; - x = POS_X(1.5); - y = POS_Y(4.4); - w = POS_W(12); - h = POS_H(1); - size = POS_H(0.9); - class Attributes { - align = "center"; - color = "#E5E5E5"; - font = "RobotoCondensed"; - shadow = "false"; - }; - }; - class Action2: Action1 { - idc = IDC_ACTION_2; - y = POS_Y(5.5); - }; - class Action3: Action1 { - idc = IDC_ACTION_3; - y = POS_Y(6.6); - }; - class Action4: Action1 { - idc = IDC_ACTION_4; - y = POS_Y(7.7); - }; - class Action5: Action1 { - idc = IDC_ACTION_5; - y = POS_Y(8.8); - }; - class Action6: Action1 { - idc = IDC_ACTION_6; - y = POS_Y(9.9); - }; - class Action7: Action1 { - idc = IDC_ACTION_7; - y = POS_Y(11); - }; - class Action8: Action1 { - idc = IDC_ACTION_8; - y = POS_Y(12.1); - }; - class Action9: Action1 { - idc = IDC_ACTION_9; - y = POS_Y(13.2); + class ActionButtonGroup: RscControlsGroup { + idc = IDC_ACTION_BUTTON_GROUP; + x = QUOTE(POS_X(1.5)); + y = QUOTE(POS_Y(4.4)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(12.2)); }; class BodyImage: GVAR(BodyImage) {}; class SelectHead: RscButton { idc = -1; onButtonClick = QUOTE(GVAR(selectedBodyPart) = 0); tooltip = CSTRING(SelectHead); - x = POS_X(18.8); - y = POS_Y(3.2); - w = POS_W(1.4); - h = POS_H(1.8); + x = QUOTE(POS_X(19.3)); + y = QUOTE(POS_Y(3.2)); + w = QUOTE(POS_W(1.4)); + h = QUOTE(POS_H(1.8)); colorFocused[] = {0, 0, 0, 0}; colorBackground[] = {0, 0, 0, 0}; colorBackgroundActive[] = {0, 0, 0, 0}; @@ -355,128 +372,153 @@ class ACE_Medical_Menu { class SelectTorso: SelectHead { onButtonClick = QUOTE(GVAR(selectedBodyPart) = 1); tooltip = CSTRING(SelectTorso); - x = POS_X(18.4); - y = POS_Y(5); - w = POS_W(2.2); - h = POS_H(3.8); + x = QUOTE(POS_X(18.9)); + y = QUOTE(POS_Y(5)); + w = QUOTE(POS_W(2.2)); + h = QUOTE(POS_H(3.8)); }; class SelectArmLeft: SelectHead { onButtonClick = QUOTE(GVAR(selectedBodyPart) = 2); tooltip = CSTRING(SelectLeftArm); - x = POS_X(20.6); - y = POS_Y(5.1); - w = POS_W(1.1); - h = POS_H(4.6); + x = QUOTE(POS_X(21.1)); + y = QUOTE(POS_Y(5.1)); + w = QUOTE(POS_W(1.1)); + h = QUOTE(POS_H(4.6)); }; class SelectArmRight: SelectArmLeft { onButtonClick = QUOTE(GVAR(selectedBodyPart) = 3); tooltip = CSTRING(SelectRightArm); - x = POS_X(17.4); + x = QUOTE(POS_X(17.8)); }; class SelectLegLeft: SelectHead { onButtonClick = QUOTE(GVAR(selectedBodyPart) = 4); tooltip = CSTRING(SelectLeftLeg); - x = POS_X(19.5); - y = POS_Y(8.8); - w = POS_W(1.1); - h = POS_H(5.8); + x = QUOTE(POS_X(20.0)); + y = QUOTE(POS_Y(8.8)); + w = QUOTE(POS_W(1.1)); + h = QUOTE(POS_H(5.8)); }; class SelectLegRight: SelectLegLeft { onButtonClick = QUOTE(GVAR(selectedBodyPart) = 5); tooltip = CSTRING(SelectRightLeg); - x = POS_X(18.4); + x = QUOTE(POS_X(18.9)); }; class Injuries: TriageCard { idc = IDC_INJURIES; - x = POS_X(25.66); - w = POS_W(12.33); + x = QUOTE(POS_X(26.17)); + y = QUOTE(POS_Y(3.3)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_Y(13.3)); }; class ActivityHeader: TreatmentHeader { text = CSTRING(ACTIVITY_LOG); - y = POS_Y(17.6); - w = POS_W(18.5); - sizeEx = POS_H(1); + y = QUOTE(POS_Y(17.6)); + w = QUOTE(POS_W(18.5)); + sizeEx = QUOTE(POS_H(1)); colorText[] = {0.6, 0.7, 1, 1}; }; class QuickViewHeader: ActivityHeader { text = CSTRING(QUICK_VIEW); - x = POS_X(19.5); + x = QUOTE(POS_X(20.0)); }; class LowerLine: HeaderLine { - y = POS_Y(18.5); + y = QUOTE(POS_Y(18.5)); + }; + class LowerDivider: HeaderLine { + x = QUOTE(POS_X(19.985)); + y = QUOTE(POS_Y(18.75)); + w = QUOTE(POS_W(0.03)); + h = QUOTE(POS_H(7.6)); }; class Activity: Injuries { idc = IDC_ACTIVITY; - x = POS_X(1.5); - y = POS_Y(18.5); - w = POS_W(18.5); - h = POS_H(6.5); + x = QUOTE(POS_X(1.5)); + y = QUOTE(POS_Y(18.5)); + w = QUOTE(POS_W(18.5)); + h = QUOTE(POS_H(7.6)); colorBackground[] = {0, 0, 0, 0}; }; class QuickView: Activity { idc = IDC_QUICKVIEW; - x = POS_X(21.5); + x = QUOTE(POS_X(20.0)); }; class TriageStatus: RscText { idc = IDC_TRIAGE_STATUS; style = ST_CENTER; - x = POS_X(13.33); - y = POS_Y(15.5); - w = POS_W(12.33); - h = POS_H(1.1); + x = QUOTE(POS_X(13.83)); + y = QUOTE(POS_Y(15.5)); + w = QUOTE(POS_W(12.33)); + h = QUOTE(POS_H(1.1)); shadow = 0; }; class TriageToggle: GVAR(TriageToggle) {}; class TriageSelect: GVAR(TriageSelect) {}; + class BodyLabelLeft: RscText { + idc = -1; + style = ST_RIGHT; + text = CSTRING(BodyLabelLeft); + font = "RobotoCondensedBold"; + x = QUOTE(POS_X(17.0)); + y = QUOTE(POS_Y(10.5)); + w = QUOTE(POS_W(6.0)); + h = QUOTE(POS_H(2.0)); + sizeEx = QUOTE(POS_H(1.4)); + colorText[] = {1, 1, 1, 0.33}; + shadow = 0; + }; + class BodyLabelRight: BodyLabelLeft { + style = ST_LEFT; + text = CSTRING(BodyLabelRight); + }; }; }; class GVAR(RscTriageCard) { idd = -1; movingEnable = 1; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(RscTriageCard), _this select 0)]); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(RscTriageCard),_this select 0)]); class controls { class Background: RscText { idc = -1; - x = POS_X(12.5); - y = POS_Y(0); - w = POS_W(15); - h = POS_H(19); + x = QUOTE(POS_X(12.5)); + y = QUOTE(POS_Y(0)); + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(19)); colorBackground[] = {1, 1, 1, 1}; moving = 1; }; class CornerLeft: RscPicture { idc = -1; text = QPATHTOF(data\triage_card\corner_left.paa); - x = POS_X(12.5); - y = POS_Y(0); - w = POS_W(5); - h = POS_H(5); + x = QUOTE(POS_X(12.5)); + y = QUOTE(POS_Y(0)); + w = QUOTE(POS_W(5)); + h = QUOTE(POS_H(5)); colorText[] = {1, 1, 0, 1}; }; class CornerRight: CornerLeft { text = QPATHTOF(data\triage_card\corner_right.paa); - x = POS_X(22.5); + x = QUOTE(POS_X(22.5)); }; class Title: RscText { idc = -1; style = ST_CENTER; text = CSTRING(Actions_TriageCard); - x = POS_X(12.5); - y = POS_Y(3); - w = POS_W(15); - h = POS_H(0.9); - sizeEx = POS_H(0.9); + x = QUOTE(POS_X(12.5)); + y = QUOTE(POS_Y(3)); + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(0.9)); + sizeEx = QUOTE(POS_H(0.9)); shadow = 0; colorText[] = {0, 0, 0, 1}; }; class TriageCard: RscListBox { idc = IDC_TRIAGE_CARD; - x = POS_X(13.5); - y = POS_Y(5); - w = POS_W(13); - h = POS_H(13); - sizeEx = POS_H(0.7); + x = QUOTE(POS_X(13.5)); + y = QUOTE(POS_Y(5)); + w = QUOTE(POS_W(13)); + h = QUOTE(POS_H(13)); + sizeEx = QUOTE(POS_H(0.7)); colorText[] = {0, 0, 0, 1}; colorSelect[] = {0, 0, 0, 1}; colorSelect2[] = {0, 0, 0, 1}; @@ -488,36 +530,36 @@ class GVAR(RscTriageCard) { class TriageStatus: RscText { idc = IDC_TRIAGE_STATUS; style = ST_CENTER; - x = POS_X(12.5); - y = POS_Y(19); - w = POS_W(15); - h = POS_H(1.1); + x = QUOTE(POS_X(12.5)); + y = QUOTE(POS_Y(19)); + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(1.1)); shadow = 0; }; class TriageToggle: GVAR(TriageToggle) { - x = POS_X(12.5); - y = POS_Y(19); - w = POS_W(15); + x = QUOTE(POS_X(12.5)); + y = QUOTE(POS_Y(19)); + w = QUOTE(POS_W(15)); }; class TriageSelect: GVAR(TriageSelect) { - x = POS_X(12.5); - y = POS_Y(20); - w = POS_W(15); + x = QUOTE(POS_X(12.5)); + y = QUOTE(POS_Y(20)); + w = QUOTE(POS_W(15)); class controls: controls { class None: None { - w = POS_W(15); + w = QUOTE(POS_W(15)); }; class Minimal: Minimal { - w = POS_W(15); + w = QUOTE(POS_W(15)); }; class Delayed: Delayed { - w = POS_W(15); + w = QUOTE(POS_W(15)); }; class Immediate: Immediate { - w = POS_W(15); + w = QUOTE(POS_W(15)); }; class Deceased: Deceased { - w = POS_W(15); + w = QUOTE(POS_W(15)); }; }; }; @@ -531,118 +573,151 @@ class RscTitles { fadeOut = 0.3; duration = 999999; movingEnable = 0; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(RscPatientInfo), _this select 0)]); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(RscPatientInfo),_this select 0)]); class controls { - class BodyImage: GVAR(BodyImage) { - x = safeZoneX + POS_W(2.25); - y = safeZoneY + POS_H(1.5); - w = POS_W(8.5); - h = POS_H(8.5); - class controls: controls { - class Background: Background { - w = POS_W(8.5); - h = POS_H(8.5); + class PatientInfoContainer: RscControlsGroupNoScrollbars { + idc = -1; + x = QUOTE(safeZoneX + PATIENT_INFO_IGUI_OFFSET_X); + y = QUOTE(safeZoneY + PATIENT_INFO_IGUI_OFFSET_Y); + w = "safeZoneW"; + h = "safeZoneH"; + class controls { + class BodyImage: GVAR(BodyImage) { + x = QUOTE(POS_W(2.25)); + y = QUOTE(POS_H(1.5)); + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + class controls: controls { + class Background: Background { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class Head: Head { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class Torso: Torso { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmLeft: ArmLeft { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmRight: ArmRight { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegLeft: LegLeft { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegRight: LegRight { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmLeftB: ArmLeftB { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmRightB: ArmRightB { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegLeftB: LegLeftB { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegRightB: LegRightB { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmLeftT: ArmLeftT { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmRightT: ArmRightT { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegLeftT: LegLeftT { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegRightT: LegRightT { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class HeadS: HeadS { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class TorsoS: TorsoS { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmLeftS: ArmLeftS { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class ArmRightS: ArmRightS { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegLeftS: LegLeftS { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + class LegRightS: LegRightS { + w = QUOTE(POS_W(8.5)); + h = QUOTE(POS_H(8.5)); + }; + }; }; - class Head: Head { - w = POS_W(8.5); - h = POS_H(8.5); + class InjuriesLabel: RscText { + idc = -1; + text = CSTRING(INJURIES); + x = QUOTE(POS_W(2)); + y = QUOTE(POS_H(10.2)); + w = QUOTE(POS_W(9)); + h = QUOTE(POS_H(0.7)); + sizeEx = QUOTE(POS_H(0.7)); + colorBackground[] = GUI_BCG_COLOR; }; - class Torso: Torso { - w = POS_W(8.5); - h = POS_H(8.5); + class Injuries: RscListBox { + idc = IDC_INJURIES; + x = QUOTE(POS_W(2)); + y = QUOTE(POS_H(11)); + w = QUOTE(POS_W(9)); + h = QUOTE(POS_H(9)); + sizeEx = QUOTE(POS_H(0.7)); + colorSelect[] = {1, 1, 1, 1}; + colorSelect2[] = {1, 1, 1, 1}; + colorBackground[] = {0, 0, 0, 0.2}; + colorSelectBackground[] = {0, 0, 0, 0}; + colorSelectBackground2[] = {0, 0, 0, 0}; + colorScrollbar[] = {0.9, 0.9, 0.9, 1}; }; - class ArmLeft: ArmLeft { - w = POS_W(8.5); - h = POS_H(8.5); + class TriageStatus: RscText { + idc = IDC_TRIAGE_STATUS; + x = QUOTE(POS_W(2)); + y = QUOTE(POS_H(20.2)); + w = QUOTE(POS_W(9)); + h = QUOTE(POS_H(0.7)); + sizeEx = QUOTE(POS_H(0.7)); + shadow = 0; }; - class ArmRight: ArmRight { - w = POS_W(8.5); - h = POS_H(8.5); - }; - class LegLeft: LegLeft { - w = POS_W(8.5); - h = POS_H(8.5); - }; - class LegRight: LegRight { - 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); - }; - class ArmRightT: ArmRightT { - w = POS_W(8.5); - h = POS_H(8.5); - }; - class LegLeftT: LegLeftT { - w = POS_W(8.5); - h = POS_H(8.5); - }; - class LegRightT: LegRightT { - w = POS_W(8.5); - h = POS_H(8.5); + class Activity: Injuries { + idc = IDC_ACTIVITY; + x = QUOTE(POS_W(1.75)); + y = QUOTE(POS_H(21)); + w = QUOTE(POS_W(15)); + h = QUOTE(POS_H(7)); + shadow = 2; + colorBackground[] = {0, 0, 0, 0}; }; }; }; - class InjuriesLabel: RscText { - idc = -1; - text = CSTRING(INJURIES); - x = safeZoneX + POS_W(2); - y = safeZoneY + POS_H(10.2); - w = POS_W(9); - h = POS_H(0.7); - sizeEx = POS_H(0.7); - colorBackground[] = GUI_BCG_COLOR; - }; - class Injuries: RscListBox { - idc = IDC_INJURIES; - x = safeZoneX + POS_W(2); - y = safeZoneY + POS_H(11); - w = POS_W(9); - h = POS_H(9); - sizeEx = POS_H(0.7); - colorSelect[] = {1, 1, 1, 1}; - colorSelect2[] = {1, 1, 1, 1}; - colorBackground[] = {0, 0, 0, 0.2}; - colorSelectBackground[] = {0, 0, 0, 0}; - colorSelectBackground2[] = {0, 0, 0, 0}; - colorScrollbar[] = {0.9, 0.9, 0.9, 1}; - }; - class TriageStatus: RscText { - idc = IDC_TRIAGE_STATUS; - x = safeZoneX + POS_W(2); - y = safeZoneY + POS_H(20.2); - w = POS_W(9); - h = POS_H(0.7); - sizeEx = POS_H(0.7); - shadow = 0; - }; - class Activity: Injuries { - idc = IDC_ACTIVITY; - x = safeZoneX + POS_W(1.75); - y = safeZoneY + POS_H(21); - w = POS_W(15); - h = POS_H(7); - shadow = 2; - colorBackground[] = {0, 0, 0, 0}; - }; }; }; }; diff --git a/addons/medical_gui/initSettings.inc.sqf b/addons/medical_gui/initSettings.inc.sqf new file mode 100644 index 0000000000..dfcbe48925 --- /dev/null +++ b/addons/medical_gui/initSettings.inc.sqf @@ -0,0 +1,182 @@ +[ + QGVAR(enableActions), + "LIST", + [LSTRING(EnableActions_DisplayName), LSTRING(EnableActions_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [[0, 1, 2], [LSTRING(Selections3D), LSTRING(Radial), ELSTRING(common,Disabled)], 0], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(enableSelfActions), + "CHECKBOX", + [LSTRING(EnableSelfActions_DisplayName), LSTRING(EnableSelfActions_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + true, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(enableMedicalMenu), + "LIST", + [LSTRING(EnableMedicalMenu_DisplayName), LSTRING(EnableMedicalMenu_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), ELSTRING(common,VehiclesOnly)], 1], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(openAfterTreatment), + "CHECKBOX", + [LSTRING(OpenAfterTreatment_DisplayName), LSTRING(OpenAfterTreatment_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + true, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(maxDistance), + "SLIDER", + [LSTRING(MaxDistance_DisplayName), LSTRING(MaxDistance_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [0, 10, 3, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(interactionMenuShowTriage), + "LIST", + [LSTRING(InteractionMenuShowTriage_DisplayName), LSTRING(InteractionMenuShowTriage_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(Medical_Treatment,Anyone), ELSTRING(Medical_Treatment,Medics)], 1], + false +] call CBA_fnc_addSetting; + +/* +* Default blood loss colouring follows a "white, yellow, red" colour scale with 10 steps, Bezier interpolation and Correct lightness gradient. +* See: https://gka.github.io/palettes +*/ +private _bloodLossColors = [ + [0.00, 0.00, 0.00, 1], + [1.00, 0.95, 0.64, 1], + [1.00, 0.87, 0.46, 1], + [1.00, 0.80, 0.33, 1], + [1.00, 0.72, 0.24, 1], + [1.00, 0.63, 0.15, 1], + [1.00, 0.54, 0.08, 1], + [1.00, 0.43, 0.02, 1], + [1.00, 0.30, 0.00, 1], + [1.00, 0.00, 0.00, 1] +]; + +/* +* Default damage colouring follows a "white, cyan, blue" colour scale with 10 steps, Bezier interpolation and Correct lightness gradient. +* See: https://gka.github.io/palettes +*/ +private _damageColors = [ + [0.00, 0.00, 0.00, 1], + [0.75, 0.95, 1.00, 1], + [0.62, 0.86, 1.00, 1], + [0.54, 0.77, 1.00, 1], + [0.48, 0.67, 1.00, 1], + [0.42, 0.57, 1.00, 1], + [0.37, 0.47, 1.00, 1], + [0.31, 0.36, 1.00, 1], + [0.22, 0.23, 1.00, 1], + [0.00, 0.00, 1.00, 1] +]; + +private _categoryColors = [ELSTRING(medical,Interface_Category), format ["| %1 |", LELSTRING(common,subcategory_colors)]]; +{ + [ + format ["%1_%2", QGVAR(bloodLossColor), _forEachIndex], + "COLOR", + [format [localize LSTRING(BloodLossColorX_DisplayName), _forEachIndex], LSTRING(BloodLossColor_Description)], + _categoryColors, + _x, + false // isGlobal + ] call CBA_fnc_addSetting; +} forEach _bloodLossColors; + +{ + [ + format ["%1_%2", QGVAR(damageColor), _forEachIndex], + "COLOR", + [format [localize LSTRING(DamageColorX_DisplayName), _forEachIndex], LSTRING(DamageColor_Description)], + _categoryColors, + _x, + false // isGlobal + ] call CBA_fnc_addSetting; +} forEach _damageColors; + +[ + QGVAR(showDamageEntry), + "CHECKBOX", + [LSTRING(showDamageEntry_DisplayName), LSTRING(showDamageEntry_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(showBloodlossEntry), + "CHECKBOX", + [LSTRING(ShowBloodlossEntry_DisplayName), LSTRING(ShowBloodlossEntry_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + true, + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(showBleeding), + "LIST", + [LSTRING(showBleeding_DisplayName), LSTRING(showBleeding_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(ShowBleeding_Rate)], 2], + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(bodyPartOutlineColor), + "COLOR", + [LSTRING(bodyPartOutlineColor_DisplayName), LSTRING(bodyPartOutlineColor_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [1.00, 1.00, 1.00, 1], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(peekMedicalInfoReleaseDelay), + "TIME", + [LSTRING(PeekMedicalInfoReleaseDelay_DisplayName), LSTRING(PeekMedicalInfoReleaseDelay_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [0, 5, 1], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(peekMedicalOnHit), + "CHECKBOX", + [LSTRING(PeekMedicalOnHit_DisplayName), LSTRING(PeekMedicalOnHit_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + false, + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(peekMedicalOnHitDuration), + "TIME", + [LSTRING(PeekMedicalOnHitDuration_DisplayName), LSTRING(PeekMedicalOnHitDuration_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [0, 5, 1], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(tourniquetWarning), + "CHECKBOX", + [LSTRING(TourniquetWarning_DisplayName), LSTRING(TourniquetWarning_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + false, + false +] call CBA_fnc_addSetting; diff --git a/addons/medical_gui/initSettings.sqf b/addons/medical_gui/initSettings.sqf deleted file mode 100644 index be7dc60fa6..0000000000 --- a/addons/medical_gui/initSettings.sqf +++ /dev/null @@ -1,44 +0,0 @@ -[ - QGVAR(enableActions), - "LIST", - [LSTRING(EnableActions_DisplayName), LSTRING(EnableActions_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - [[0, 1, 2], [LSTRING(Selections3D), LSTRING(Radial), ELSTRING(common,Disabled)], 0], - false -] call CBA_settings_fnc_init; - -[ - QGVAR(enableSelfActions), - "CHECKBOX", - [LSTRING(EnableSelfActions_DisplayName), LSTRING(EnableSelfActions_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - true, - false -] call CBA_settings_fnc_init; - -[ - QGVAR(enableMedicalMenu), - "LIST", - [LSTRING(EnableMedicalMenu_DisplayName), LSTRING(EnableMedicalMenu_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), ELSTRING(common,VehiclesOnly)], 1], - false -] call CBA_settings_fnc_init; - -[ - QGVAR(openAfterTreatment), - "CHECKBOX", - [LSTRING(OpenAfterTreatment_DisplayName), LSTRING(OpenAfterTreatment_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - true, - false -] call CBA_settings_fnc_init; - -[ - QGVAR(maxDistance), - "SLIDER", - [LSTRING(MaxDistance_DisplayName), LSTRING(MaxDistance_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - [0, 10, 3, 1], - true -] call CBA_settings_fnc_init; diff --git a/addons/medical_gui/script_component.hpp b/addons/medical_gui/script_component.hpp index 04565dc5b6..d69fb65434 100644 --- a/addons/medical_gui/script_component.hpp +++ b/addons/medical_gui/script_component.hpp @@ -27,9 +27,17 @@ #define POS_W(N) ((N) * GUI_GRID_W) #define POS_H(N) ((N) * GUI_GRID_H) +#define PATIENT_INFO_IGUI_BASE_X (safeZoneX + POS_W(2)) +#define PATIENT_INFO_IGUI_BASE_Y (safeZoneY + POS_H(1)) +#define PATIENT_INFO_IGUI_X (profilenamespace getVariable ['TRIPLES(IGUI,GVAR(patientInfo),X)', 0]) +#define PATIENT_INFO_IGUI_Y (profilenamespace getVariable ['TRIPLES(IGUI,GVAR(patientInfo),Y)', 0]) +#define PATIENT_INFO_IGUI_OFFSET_X (PATIENT_INFO_IGUI_X - PATIENT_INFO_IGUI_BASE_X) +#define PATIENT_INFO_IGUI_OFFSET_Y (PATIENT_INFO_IGUI_Y - PATIENT_INFO_IGUI_BASE_Y) + #define IDD_MEDICAL_MENU 38580 #define IDC_TITLE 1200 +#define IDC_NAME 1210 #define IDC_TRIAGE 1300 #define IDC_EXAMINE 1310 #define IDC_BANDAGE 1320 @@ -38,23 +46,15 @@ #define IDC_ADVANCED 1350 #define IDC_DRAG 1360 #define IDC_TOGGLE 1370 +#define IDC_TRIAGE_DIVIDER 1380 +#define IDC_TOGGLE_DIVIDER 1390 #define IDC_TRIAGE_CARD 1400 #define IDC_INJURIES 1410 #define IDC_ACTIVITY 1420 #define IDC_QUICKVIEW 1430 -#define IDC_ACTION_1 1500 -#define IDC_ACTION_2 1510 -#define IDC_ACTION_3 1520 -#define IDC_ACTION_4 1530 -#define IDC_ACTION_5 1540 -#define IDC_ACTION_6 1550 -#define IDC_ACTION_7 1560 -#define IDC_ACTION_8 1570 -#define IDC_ACTION_9 1580 - -#define IDCS_ACTION_BUTTONS [IDC_ACTION_1, IDC_ACTION_2, IDC_ACTION_3, IDC_ACTION_4, IDC_ACTION_5, IDC_ACTION_6, IDC_ACTION_7, IDC_ACTION_8, IDC_ACTION_9] +#define IDC_ACTION_BUTTON_GROUP 1599 #define IDC_BODY_GROUP 6000 #define IDC_BODY_HEAD 6005 @@ -71,6 +71,13 @@ #define IDC_BODY_ARMRIGHT_B 6060 #define IDC_BODY_LEGLEFT_B 6065 #define IDC_BODY_LEGRIGHT_B 6070 +#define IDC_BODY_GROUP_S 6075 +#define IDC_BODY_HEAD_S 6080 +#define IDC_BODY_TORSO_S 6085 +#define IDC_BODY_ARMLEFT_S 6090 +#define IDC_BODY_ARMRIGHT_S 6095 +#define IDC_BODY_LEGLEFT_S 6100 +#define IDC_BODY_LEGRIGHT_S 6105 #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 a6116ecb0e..b88d9cbbf1 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -1,21 +1,53 @@ - + GUI GUI + Interface graphique + Медицинский интерфейс + GUI + 界面 + 界面 + Interfaccia Grafica + GUI + Graficzny Interfejs Użytkownika + Interfaz gráfica + GUI + Graphische Benutzeroberfläche + GUI Enable Medical Actions Aktiviere Sanitätsaktionen - 医療行為を有効化 + 医療インタラクションの有効化 Разрешить Медицинские действия + Activer les actions médicales + Ativar Ações Médicas + 啟用醫療行為 + 启用医疗措施 + Attiva azioni mediche + Povolit zdravotnické akce + Włącza opcje medyczne + Habilitar acciones médicas + Medikal hareketleri etkinleştir + 의료 행동 활성화 Enables medical actions for the Interaction Menu and selects their style. Aktiviert die Sanitätsaktionen für das Interaktionsmenü und legt das Aussehen fest - インタラクション メニューから選択した表示方式で医療行為をできるようになります。 + インタラクションメニューから選択した表示方式で医療行為をできるようになります。 Включает медицинские действия для меню взаимодействия и выбирает их стиль. + Permet d'afficher les actions médicales dans le menu d'interaction, et de définir leur style visuel. + Ativa as ações médicas para o menu de interação e seleciona seus estilos. + 為互動選單啟用醫療行為以及選擇其風格。 + 为交互式菜单启用医疗操作,并选择其样式。 + Abilita le azioni mediche nel Menù Interazioni e scegli il loro stile. + Povolit zdravotnické akce pro menu interakcí a vybrat jejich styl. + Umożliwia akcje medyczne w menu interakcji i wybiera ich styl. + Habilita acciones médicas para el menú de interacción y selecciona su estilo. + Etkileşim Menüsü için tıbbi eylemleri etkinleştirir ve stillerini seçer. + 상호작용 메뉴에서 의료 행동을 하는 것을 허락합니다. Selections (3D) @@ -27,11 +59,12 @@ Seleção (3d) Választékok (3D) 3D výběr - Selezione (3D) + Selezioni (3D) 選択 (3D) 선택 (3d) - 选择 (3D) + 选择(3D) 選擇 (3D) + Seçimler (3D) Radial @@ -48,54 +81,159 @@ 다이얼형 放射状 放射狀 + Radyal Enable Medical Self Actions Medizinische Selbst-Interaktionen anzeigen - 自分への医療行為を有効化 + 医療セルフインタラクションの有効化 Разрешить Медицинские действия на себе + Activer les actions médicales sur soi-même + Ativar ações médicas em si mesmo + 啟用自我醫療行為 + 启用医疗自我措施 + Abilitare le azioni di automedicazione + Povolit zdravotnické vlastní akce + Włącza akcje medyczne na sobie + Habilitar las acciones médicas en uno mismo + Kendine Tıbbi Müdahele Etmeyi Etkinleştir + 자가 의료 행동 활성화 Enables medical actions for the Self Interaction Menu. Medizinische Interaktionen bei Selbst-Interaktionen anzeigen - セルフ インタラクション メニューで医療行為をできるようになります。 + セルフインタラクションメニューで医療行為をできるようになります。 Включает медицинские действия для меню взаимодействия с собой. + Active les actions médicales du menu d'interaction personnel. + Ativa as ações médicas do menu de interação pessoal. + 為自我互動選單啟用醫療行為。 + 为自我交互菜单启用医疗操作。 + Abilita il menù per le interazioni mediche personali + Povoluje zdravotnické akce v menu vlastních interakcí. + Umożliwia działania medyczne w menu własnej interakcji. + Activa las acciones médicas para el menú de interacción personal + Kişisel Etkileşim Menüsü için tıbbi eylemleri etkinleştirir. + 자기 상호작용 메뉴에서 의료 행동을 하는 것을 허락합니다. Enable Medical Menu Aktiviere das Sanitätsmenü 医療メニューを有効化 Разрешить Медицинское меню + Activer le menu médical + Ativar Menu Médico + 啟用醫療選單 + 启用医疗菜单 + Abilita il menù medico + Povolit Zdravotnické menu + Włącz Menu Medyczne + Activar menú médico + Medikal Menüyü Etkinleştir + 의료 메뉴 활성화 Enables the use of the Medical Menu through the keybind or interaction menu. Aktiviere die Nutzung des Sanitätsmenüs durch eine Tastenkombination oder durch das Interaktionsmenü - 割り当てられたキーかインタラクション メニューから医療メニューを使えるようになります。 + 割り当てられたキーかインタラクションメニューから医療メニューを使えるようになります。 Позволяет использовать Медицинское меню через связку клавиш или меню взаимодействия. + Permet l'utilisation du menu médical via le menu d'interaction ou l'appui d'une touche. + Ativa o uso do Menu Médico através da Tecla ou Menu de Interação. + 啟用以互動選單或者按鍵綁定所呼出的高效醫療選單 + 通过按键绑定或交互菜单启用医疗菜单。 + Abilita l'uso del Menù Medico attraverso il menù tastiera o il menu di interazione. + Povoluje používání Zdravotnického menu klávesovou zkratku nebo skrze menu interakcí. + Umożliwia korzystanie z menu medycznego poprzez skrót lub menu interakcji. + Activa el uso del menú médico a través de la tecla o del menú de interacción + Medikal Menünün bir tuşla veya etkileşim menüsü aracılığıyla kullanılmasını sağlar. + 단축키나 상호작용을 통해 의료 메뉴를 활성화 할지 정합니다. Reopen Medical Menu Sanitätsmenü wieder öffnen - 医療メニューの再使用 + 医療メニューの再表示 Открывать меню после лечения + Rouvrir le menu médical + Reabrir Menu Médico + 醫療選單二度開啟 + 重新打开医疗菜单 + Riapri il menù medico + Znovu otevřít Zdravotnické menu + Otwiera ponownie menu medyczne + Reabrir menú médico + Medikal Menüyü Yeniden Aç + 의료 메뉴 다시 열기 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 + 當治療完成後二度打開醫療選單 + 治疗成功后,重新打开医疗菜单。 + Riapri il menù medico dopo un trattamento eseguito con successo. + Otevře Zdravotnické menu po úspěšném dokončení zdravotnické akce. + Otwiera ponownie menu medyczne po udanym leczeniu. + Reabrir menú médico después de completar un tratamiento + Başarılı bir tedaviden sonra Tıbbi Menüyü yeniden açın. + 성공적으로 치료한 뒤 의료 메뉴를 다시 열지 결정합니다. Maximum Distance Maximale Entfernung 最大距離 Макс. дистанция + Distance maximale + Distância Máxima + 最大醫療距離 + 最大医疗距离 + Distanza Massima + Maximální vzdálenost + Maksymalny dystans + Distancia máxima + Maksimum Mesafe + 최대 거리 Maximum distance from which the Medical Menu can be opened. Maximale Entfernung, um das Sanitätsmenü zu öffnen. - 治療メニューを開いたままにできる最大距離を決定します。 + 医療メニューを開いたままにできる最大距離。 Максимальное расстояние, с которого можно открыть Медицинское меню. + Définit la distance (en mètres) à partir de laquelle il n'est plus possible d'activer le menu médical pour traiter un patient. + A Distância máxima do paciente para que o Menu Médico possa ser aberto. + 設定距離多遠以內可以對目標使用醫療選單 + 设定距离多远以内可以对目标使用医疗菜单 + Distanza massima da cui si può aprire il Menù Medico. + Maximální vzdálenost ze které je možné otevřít Zdravotnické menu. + Maksymalny dystans w którym menu medyczne może zostać otwarte. + Distancia máxima desde el paciente para que el menú pueda ser abierto + Tıbbi Menünün açılabileceği maksimum mesafe. + 의료 메뉴를 열 수 있는 최대 거리를 지정합니다. + + + Show Triage Level in Interaction Menu + Couleur de triage dans le menu d'interaction + Mostra livello di Triage nel Menù d'Interazione + インタラクションにトリアージ レベルを表示 + Mostrar nivel de triado en menú de interacción + Показать уровень триажа в меню взаимодействия + Pokaż poziom Triażu w menu interakcji + Zeige Triage-Einstufung im Interaktionsmenü + 在交互式菜单中显示分诊级别 + 상호작용 메뉴에서 부상자 카드 보기 + + + Shows the patient's triage level by changing the color of the main and medical menu actions. + Modifie la couleur du menu d'interactions et du sous-menu médical en fonction de la fiche de triage du patient. + Modifica il colore di interazioni e menù medico a seconda del livello di triage. + メニューと医療メニューの色を変更し、患者のトリアージ レベルを表示します。 + Mostrar el nivel de triado en el paciente cambiando el color de acciones de menú principales y médicas + Отображает установленную группу карты медицинской сортировки (триажа), изменяя цвет действий основного и медицинского меню. + Pokazuje poziom Triażu pacjenta poprzez zmianę koloru ikony w menu interakcji. + Zeigt die Triage-Einstufung des Patienten durch Ändern der Farbe der Aktionen des Hauptmenüs und des medizinischen Menüs an. + 通过改变主菜单和医疗菜单动作的颜色来显示伤员的分诊级别。 + 환자의 부상자 카드를 상호작용에서 볼 수 있게 합니다. Medical @@ -108,25 +246,27 @@ Медик Médico Orvosi - 治療 + 医療 치료 医疗 醫療 + Medikal Medical Menu Sanitätsmenü Menu medyczne - Menu médico + Menu Médico Медицинское меню Menú médico - Zdravotnikcá nabídka + Zdravotnická nabídka Menù Medico Menu médical - 治療メニュー + 医療メニュー 의료 메뉴 - 医疗选单 + 医疗菜单 醫療選單 + Medikal Menü Open Medical Menu @@ -138,10 +278,44 @@ Otevřít zdravotnickou nabídku Apri Menù Medico Ouvir le menu médical - 治療メニューを開く + 医療メニューを開く 의료 메뉴 열기 - 开起医疗选单 + 打开医疗菜单 開起醫療選單 + Medikal Menüyü Aç + + + Peek Medical Info + Podgląd Informacji Medycznych + 의료 정보 보기 + Aperçu des informations médicales + Sbircia Info Mediche + Medizinische Info anzeigen + 医療情報一時表示 + Просмотр медицинской информации + Ojear Información Médica + + + Medical Peek Duration + Czas Trwania Podglądu Medycznego + 의료 정보 보기 지속 시간 + Durée de l'aperçu des informations médicales + Durata di sbirciamento di info mediche + Dauer zum Anzeigen der medizinischen Info + 医療情報一時表示の表示時間 + Продолжительность медицинского осмотра + Duración del Ojear Información Médica + + + How long the medical info peek remains open after releasing the key. + Jak długo podgląd informacji medycznych pozostaje otwarty po zwolnieniu przycisku. + 키를 놓은 후 의료 정보가 열린 상태로 유지되는 시간입니다. + Durée d'affichage des informations médicales après avoir relâché la touche. + Wie lange die medizinische Info-Anzeige nach dem Loslassen der Taste geöffnet bleibt. + Durata di visualizzazione delle Info Mediche dopo aver rilasciato il tasto. + 医療情報一時表示キーを放してからどれだけ長く情報表示するか。 + Как долго окно просмотра медицинской информации остается открытым после отпускания клавиши. + Durante cuánto tiempo la información médica ojeada permanece abierta una ves se deje de apretar la tecla. Load Patient @@ -156,8 +330,9 @@ Naložit pacienta 患者を載せる 환자 싣기 - 将伤者放入 + 将伤者装入 將傷者放入 + Kişiyi Bindir Unload Patient @@ -165,7 +340,7 @@ Выгрузить пациента Patient ausladen Wyładuj pacjenta - Le patient débarque + Débarquer le patient Sebesült kihúzása Scarica il paziente Descarregar Paciente @@ -174,21 +349,23 @@ 환자 내리기 将伤者背出 將傷者背出 + Kişiyi Indir EXAMINE & TREATMENT Untersuchung & Behandlung ОСМОТР И ЛЕЧЕНИЕ EXAMINAR & TRATAMIENTO - EXAMINER & TRAITEMENTS + EXAMENS & TRAITEMENTS BADANIE & LECZENIE EXAMINAR & TRATAMENTO VYŠETŘENÍ & LÉČBA ESAMINA & TRATTA - 診断 & 治療 + 診断と治療 검사 / 치료 检查 & 治疗 檢查 & 治療 + MUAYENE & TEDAVİ STATUS @@ -204,6 +381,7 @@ 상태 状态 狀態 + DURUM OVERVIEW @@ -215,10 +393,11 @@ VISÃO GERAL PŘEHLED PANORAMICA - オーバービュー + 概況 개요 - 概述 + 总览 概述 + GENEL BAKIŞ ACTIVITY LOG @@ -232,8 +411,9 @@ LOG ATTIVITA' 治療履歴 활동 로그 - 医疗纪录 + 医疗记录 醫療紀錄 + AKTIVITE GÜNLÜĞÜ QUICK VIEW @@ -245,10 +425,11 @@ VISÃO RÁPIDA RYCHLÝ NÁHLED VISTA RAPIDA - クイック ビュー + 簡易概況 퀵 뷰 快速检查 快速檢查 + HIZLI GÖRÜNÜM INJURIES @@ -263,23 +444,25 @@ FERIMENTOS 負傷 부상 - 受伤 + 负伤 受傷 + YARALANMALARI View Triage Card Zeige Triagekarte Смотреть первичную карточку Ver Triage - Voir Carte de Triage + Voir Fiche de Triage Pokaż kartę segregacyjną Ver cartão de triagem Zkontrolovat štítek - Guarda Triage Card - トリアージ カードを見る + Guarda Scheda Triage + トリアージカードを見る 부상자 카드 보기 - 查看诊断卡 + 查看分诊卡 查看診斷卡 + Triyaj Kartını Görüntüle Examine Patient @@ -291,40 +474,43 @@ Examinar paciente Zkontrolovat pacienta Esamina Paziente - 患者を調べる + 患者の診察 환자 검사하기 - 检查伤者 + 检查伤员 檢查傷者 + Hastayı Incele Bandage / Fractures Bandagen / Brüche Раны / переломы Vendajes/Fracturas - Bandages / Fractures + Bandages/Attelles Bandaże / Złamania Bandagens / Fraturas Bandáž / Zlomeniny - Bendaggi/Fratture + Bendaggi / Fratture 包帯 / 骨折 붕대 / 골절 - 绷带 / 骨折 + 包扎/骨折 繃帶 / 骨折 + Bandaj / Kırıklar Medication Medikamentation Медикаменты Medicación - Médications + Médication Leki Medicação Léky - Medicazione - 薬物による治療 + Medicazioni + 投薬 약물 치료 药物 藥物 + Ilaç Airway Management @@ -336,10 +522,11 @@ Dýchací systém Gestione Vie Respiratorie Atemwegssicherung - 気道を確保 + 気道管理 기도 관리 呼吸道管理 呼吸道管理 + Hava Yolu Yönetimi Advanced Treatments @@ -355,36 +542,45 @@ 고급 치료 进阶治疗 進階治療 + Gelişmiş Tedaviler Drag / Carry Ziehen / Tragen Тащить / нести Arrastrar / Cargar - Traîner / Porter + Traîner/Porter Ciągnij / Nieś Arrastar / Carregar Táhnout / Nést Trascina / Trasporta 引きずる / 担ぐ 끌기 / 들기 - 拖 / 背 + 拖/背 拖 / 背 + Sürükle / Taşı - - Toggle (Self) - Umschalter (Selbst) - Лечить себя/другого раненого - Basculer (soi) - Przełącz (na siebie) - Alternar - Alternar (Si mesmo) - Přepnout (na sebe) - Attiva (Te Stesso) - 切り替え (自分) - 토글 (자신) - 切换 (自己) - 切換 (自己) + + Switch to self + Zmień na siebie + 자신으로 전환 + Passer à soi-même + Wechseln zu selbst + Passa a te stesso + 自分に切り替え + Переключиться на себя + Cambiar a uno mismo + + + Switch to target + Zmień na pacjenta + 대상으로 전환 + Passer à la cible + Wechseln zu Ziel + Passa al paziente + 相手に切り替え + Переключиться на цель + Cambiar al objetivo Head @@ -393,13 +589,14 @@ Cabeza Tête Głowa - Caebça + Cabeça Hlava Testa 頭部 머리 头部 頭部 + Kafa Torso @@ -413,8 +610,9 @@ Torso 胴体 몸통 - 身体 + 躯干 身體 + Gövde Left Arm @@ -427,9 +625,10 @@ Levá Ruka Braccio Sinistro 左腕 - 왼쪽 팔 - 左手 + 왼팔 + 左臂 左手 + Sol Kol Right Arm @@ -442,9 +641,10 @@ Pravá Ruka Braccio Destro 右腕 - 오른쪽 팔 - 右手 + 오른팔 + 右臂 右手 + Sağ Kol Left Leg @@ -457,9 +657,10 @@ Levá Noha Gamba Sinistra 左足 - 왼쪽 다리 - 左脚 + 왼다리 + 左腿 左腳 + Sol Bacak Right Leg @@ -472,9 +673,10 @@ Pravá Noha Gamba Destra 右足 - 오른쪽 다리 - 右脚 + 오른다리 + 右腿 右腳 + Sağ Bacak Select Head @@ -486,10 +688,11 @@ Selecionar Cabeça Vybrat Hlavu Seleziona Testa - 頭部を選ぶ + 頭部を選択 머리 선택 选择头部 選擇頭部 + Kafayı Seç Select Torso @@ -501,10 +704,11 @@ Selecionar Torso Vybrat Trup Seleziona Torso - 胴体を選ぶ + 胴体を選択 몸통 선택 - 选择身体 + 选择躯干 選擇身體 + Gövdeyi Seç Select Left Arm @@ -516,10 +720,11 @@ Selecionar Braço Esquerdo Vybrat Levou ruku Seleziona Braccio Sinistro - 左腕を選ぶ - 왼쪽 팔 선택 - 选择左手 + 左腕を選択 + 왼팔 선택 + 选择左臂 選擇左手 + Sol Kolu Seç Select Right Arm @@ -531,10 +736,11 @@ Selecionar Braço Direito Vybrat Pravou ruku Seleziona Braccio Destro - 右腕を選ぶ - 오른쪽 팔 선택 - 选择右手 + 右腕を選択 + 오른팔 선택 + 选择右臂 選擇右手 + Sağ Kolu Seç Select Left Leg @@ -546,10 +752,11 @@ Selecionar Perna Esquerda Vybrat Levou nohu Seleziona Gamba Sinistra - 左足を選ぶ - 왼쪽 다리 선택 - 选择左脚 + 左足を選択 + 왼다리 선택 + 选择左腿 選擇左腳 + Sol Bacağı Seç Select Right Leg @@ -561,10 +768,11 @@ Selecionar Perna Direita Vybrat Pravou nohu Seleziona Gamba Destra - 右足を選ぶ - 오른쪽 다리 선택 - 选择右脚 + 右足を選択 + 오른다리 선택 + 选择右腿 選擇右腳 + Sağ Bacağı Seç Small @@ -576,10 +784,11 @@ Pequeno Malý Piccolo - 小さい - + + 작은 + Küçük Medium @@ -591,10 +800,11 @@ Médio Střední Medio - 中くらい - + + 중간의 + Orta Large @@ -606,100 +816,107 @@ Grande Velký Grande - 大きい - + + + Büyük There are %2 %1 Open Wounds 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 Ci sono %2 %1 Ferite Aperte - 開いている傷口が %2 %1 ほどあるようだ + 開いた状態の %1 が %2 個ある 여기 %2 %1 크기의 열린 상처가 있다 - 有 %2 %1 开放性伤口 + 有 %2 处未处理的 %1 伤口 有 %2 %1 開放性傷口 + % 2% 1 Açık Yara Var There is 1 %1 Open Wound 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 - C'è 1 %1 Ferita Aperta - 1 つの空いている %1 傷口 + C'è una %1 Ferita Aperta + 開いた状態の %1 が 1 個ある 여기 %1 크기의 열린 상처가 있다 - 有 1 %1 开放性伤口 + 有 1 处未处理的 %1 伤口 有 1 %1 開放性傷口 + % 1 Açık Yara Var There is a partial %1 Open wound 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 - C'è 1 parziale %1 Ferita Aperta - 部分的に開いている %1 の傷口がある + C'è una parziale %1 Ferita Aperta + 開いた状態の 部分的な %1 がある 여기 부분적으로 %1 크기의 상처가 있다 - 有部分 %1 开放性伤口 + 有未完全处理的 %1 伤口 有部分 %1 開放性傷口 + % 1 Yarım Açık yara var There are %2 %1 Bandaged Wounds 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 Ci sono %2 %1 Ferite Bendate - ここには %2 %1 の処置された傷がある + 包帯を巻いた %1 が %2 個ある 여기에 붕대를 감은 %2 %1 크기의 상처가 있다 - 有 %2 %1 包扎过伤口 + 有 %2 处包扎过的 %1 伤口 有 %2 %1 包紮過傷口 + % 2% 1 Sargılı Yaralar Var There is 1 %1 Bandaged Wound 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 - C'è 1 %1 Ferita Bendata - 1 つの包帯で巻かれている %1 傷 + C'è una %1 Ferita Bendata + 包帯を巻いた %1 が 1 個ある 여기에 붕대를 감은 %1 크기의 상처가 있다 - 有 1 %1 包扎过伤口 + 有 1 处包扎过的 %1 伤口 有 1 %1 包紮過傷口 + % 1 Sargılı Yara Var There is a partial %1 Bandaged wound 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 - C'è 1 parziale %1 Ferita Bendata - 患者には %1 の包帯で処置された傷がある + C'è una parziale %1 Ferita Bendata + 包帯を巻いた 部分的な %1 がある 여기 부분적으로 붕대질한 %1 크기의 상처가 있다 - 有部分 %1 包扎过伤口 + 有未包扎完全的 %1 伤口 有部分 %1 包紮過傷口 + i% 1 Yarı sargılı yara var Normal breathing @@ -711,10 +928,11 @@ Respiração normal Normální dýchání Respirazione Normale - 通常の呼吸 + 正常な呼吸 정상 호흡 - 正常呼吸 + 呼吸正常 正常呼吸 + Normal solunum No breathing @@ -726,10 +944,11 @@ Sem respiração Nedýchá Nessuna Respirazione - 息をしていない + 呼吸していない 호흡이 없음 没有呼吸 沒有呼吸 + Solunum yok Difficult breathing @@ -741,25 +960,27 @@ Dificuldade para respirar Potíže s dýcháním Difficoltà Respiratorie - 呼吸が難しそうだ + 呼吸が厳しそうだ 호흡 곤란 呼吸困难 呼吸困難 + Nefes almada zorluk Almost no breathing Beinahe keine Atmung Дыхания почти нет Casi sin respirar - Respiration faible + Respiration très faible Prawie brak oddechu Quase sem respiração Téměř nedýchá Quasi nessuna Respirazione ほとんど呼吸していない 호흡이 거의 없음 - 几乎没有呼吸 + 呼吸微弱 幾乎沒有呼吸 + Neredeyse hiç nefes almıyor Bleeding @@ -773,8 +994,64 @@ Sanguinamento 出血中 출혈 - 出血中 + 正在流血 出血中 + Kanama var + + + No bleeding + Brak krwawienia + 출혈 없음 + Pas de saignement + Keine Blutung + Nessuna emorragia + 出血はしていない + Кровотечения нет + Sin sangrado + + + Slow bleeding + Słabe krwawienie + 느린 출혈 + Saignement lent + Langsame Blutung + Debole emorragia + 出血は穏やか + Медленное кровотечение + Sangrado lento + + + Moderate bleeding + Umiarkowane krwawienie + 중간 출혈 + Saignement modéré + Mäßige Blutung + Emorraggia moderata + 出血はそこそこ速い + Умеренное кровотечение + Sangrado moderado + + + Severe bleeding + Poważne krwawienie + 심한 출혈 + Saignement grave + Schwere Blutung + Forte emorragia + 出血は激しい + Сильное кровотечение + Sangrado severo + + + Massive bleeding + Bardzo silne krwawienie + 과다 출혈 + Saignement massif + Massive Blutung + Gravissima emorragia + 出血は酷く多い + Огромное кровотечение + Sangrado masivo in Pain @@ -785,11 +1062,12 @@ W bólu Com dor v bolestech - in Dolore + Dolorante 痛みがある 고통 疼痛中 疼痛中 + Ağrısı var Lost a lot of Blood @@ -800,58 +1078,121 @@ Stracił dużo krwi Perdeu muito sangue Ztratil hodně krve - Perso molto Sangue - 大量失血している + Ha perso molto Sangue + 大量失血した 많은 피를 흘림 - 大量失血 + 失血 大量失血 + Çok fazla kan kaybı var Fractured Перелом 骨折している + Fracturé + Fraturado + 骨折 + Frattura + Zlomené + Złamanie + Fracturada + 骨折 + Kırık + Gebrochen + 골절됨 Splint Applied Наложена шина - 添え木が当てている + 添え木を当てた + Attelle appliquée + Tala Aplicada + 已使用固定板 + Gessatura applicata + Dlaha aplikována + Szyna założona + Tablilla aplicada + 已用夹板固定 + Atel Uygulandı + Schiene angelegt + 부목 적용함 - + + No blood loss + Brak utraty krwi + 피를 잃지 않음 + Pas de perte de sang + Kein Blutverlust + Nessuna perdita di sangue + 失血なし + Потери крови нет + Sin pérdida de sangre + + Lost some blood Hat etwas Blut verloren - いくらか失血している + いくらか失血 Небольшая кровопотеря + A perdu une faible quantité de sang + Perdeu um pouco de Sangue + 輕微失血 + Ha perso un po' di sangue + Ztratil trochu krve + Stracił trochę krwi + Algo de sangre perdida + Az kan kaybı var + 轻微失血 + 피를 조금 잃음 Lost a lot of blood Hat eine große Menge Blut verloren Большая кровопотеря Mucha sangre perdida - A perdu beaucoup de sang + A perdu une quantité modérée de sang Stracił dużo krwi Ztratil hodně krve Sok vért vesztett Ha perso parecchio sangue Perdeu muito sangue - 大量失血している - 많은 양의 혈액을 잃음 - 大量失血中 + 大量失血 + 피를 꽤 잃음 + 大量失血 大量失血中 + Çok fazla kan kaybı var Lost a large amount of blood Hat eine sehr große Menge Blut verloren - かなり酷く大量失血している + かなり酷い量の失血 Огромная кровопотеря + A perdu une importante quantité de sang + Perdeu uma quantidade grande de sangue + 極大量失血中 + Ha perso una grande quantità di sangue + Ztratil velké množství krve + Stracił dużą ilość krwi + Perdida gran cantidad de sangre + Çok miktarda kan kaybetti + 严重失血 + 피를 많이 잃음 Lost a fatal amount of blood Hat eine kritische Menge an Blut verloren - 致命的な程失血している + 致命的な量の失血 Фатальная кровопотеря + A perdu une quantité critique de sang + Perdeu uma quantidade fatal de sangue + 致命性失血中 + Ha perso una quantità fatale di sangue + Vykrvácel + Stracił krytyczną ilość krwi + Perdida una cantidad fatal de sangre + Ölümcül miktarda kan kaybetti + 致命失血 + 피를 심각할 만큼 잃음 Tourniquet [CAT] @@ -859,29 +1200,31 @@ Жгут Torniquete [CAT] Garrot [CAT] - Opaska uciskowa [CAT] + Staza Taktyczna [CAT] Torniquete [CAT] Škrtidlo [CAT] Laccio Emostatico [CAT] 止血帯 [CAT] 지혈대 [CAT] - 军用止血带 + 止血带(军用型) 軍用止血帶 + Turnike [CAT] Nasopharyngeal Tube [NPA] 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] Tubo Nasofaringeo [NPA] 鼻咽頭チューブ [NPA] - 비-인두 기도기 [NPA] + 기관삽입기 [NPA] 鼻咽管 鼻咽管 + Nazofarengeal Tüp [NPA] Triage Card @@ -892,12 +1235,414 @@ Štítek Fiche de triage Orvosi lap - Triage Card + Scheda Triage Cartão de Triagem - トリアージ カード + トリアージカード 부상자 분류 카드 - 检伤分类卡 + 分诊卡 檢傷分類卡 + Triyaj Kartı + + + Partial %1 + 部分的な %1 + 部分 %1 + Partiel %1 + Parziale %1 + Parciální %1 + Częściowe %1 + Parcial%1 + Parcial %1 + Partiell %1 + Parsiyel %1 + Частичное %1 + 未完全处理的 %1 + 부분 %1 + + + Patient Info + Informacje o pacjencie + Informations patient + Informazioni sul paziente + Информация о пациенте + 伤员信息 + 患者情報 + Hasta Bilgileri + Información de paciente + Patienteninformation + 환자 정보 + + + Blood Loss Colors + Цвета кровопотери + 失血量の色 + Couleurs des hémorragies + Colori di emorragie + Farben für Blutverlust + Kolory utraty krwi + 失血颜色 + 출혈 색상 + Colores de pérdida de sangre + + + Defines the 10 color gradient used to indicate blood loss in Medical GUIs. + Цвета кровопотери, которые используются в Медицинском интерфейсе. Градиент из 10 цветов. + 医療 GUI 内で失血量を 10 段階の色で表します。 + Couleurs utilisées pour afficher les hémorragies dans l'interface médicale. Dégradé de 10 couleurs. + Definisce i 10 gradienti di colori usati per indicare perdite di sangue nel menù medico + Farben für Blutverlust, die in dem Medizinischen Menü verwendet werden. 10-Farben Farbverlauf. + Kolory używane do wyświetlania krwawienia w interfejsie medycznym. Gradient 10 kolorów. + 失血颜色,用于医学图形用户界面。10种渐变颜色。 + 출혈로 인한 의료 GUI의 색상을 변경합니다. 총 10가지 색상이 있습니다. + Define los 10 gradientes de color utilizados para indicar la pérdida de sangre en la interfaz gráfica del sistema Médico. + + + Blood Loss Color %1 + Цвет кровопотери %1 + 失血量の色 %1 + Hémorragies - couleur %1 + Emorragia - colore %1 + Blutverlustfarbe %1 + Krwawienie - kolor %1 + 失血颜色 %1 + 출혈 색상 %1 + Color de pérdida de sangre %1 + + + Damage Colors + Цвета урона + 負傷の色 + Couleur des dégâts + Colori di danni + Farben für Schaden + Kolory obrażeń + 负伤颜色 + 피해 색상 + Colores de daño + + + Defines the 10 color gradient used to indicate damage in Medical GUIs. + Цвета урона, которые используются в Медицинском интерфейсе. Градиент из 10 цветов. + 医療 GUI 内で負傷を 10 段階の色で表します。 + Couleurs utilisées pour afficher les dégâts dans l'interface médicale. Dégradé de 10 couleurs. + Definisce i 10 gradienti di colori usati per indicare danni nel menù medico + Farben für Schaden, die in dem medizinischen Menü verwendet werden. 10-Farben Farbverlauf. + Kolory używane do wyświetlania obrażeń w interfejsie medycznym. Gradient 10 kolorów. + 负伤颜色,用于医学图形用户界面。10种渐变颜色。 + 의료 GUI에 쓰이는 피해 색상입니다. 총 10가지 색상이 있습니다. + Define los 10 gradientes de color utilizados para indicar el daño en la interfaz gráfiica del sistema Médico. + + + Damage Color %1 + Цвет урона %1 + 負傷の色 %1 + Dégâts - couleur %1 + Danni - colore %1 + Schadensfarbe %1 + Obrażenia - kolor %1 + 负伤颜色 %1 + 피해 색상 %1 + Color de daño %1 + + + Show Blood Loss + Blutverlust anzeigen + Mostra perdita di sangue + 혈액 손실 표시 + Pokaż utratę krwi + 失血量の表示 + 显示失血量 + Показывать кровопотерю + Mostrar pérdida de sangre + Afficher les pertes de sang + + + Show qualitative blood loss in the injury list. + Qualitativen Blutverlust in der Verletzungsliste anzeigen. + Mostra quantità di sangue persa nella lista delle ferite. + 부상 목록에 혈액 손실량을 표시합니다. + Pokaż jakościową utratę krwi na liście ran. + 負傷リストに段階的な失血量を表示します。 + 在负伤列表中显示失血阶段 + Показывать тяжесть кровопотери в списке ранений. + Mostrar la pérdida de sangre cualitativa en la lista de heridas. + Afficher la quantité de sang perdue + + + Show Bleeding State + Mostrar estado de sangrado + Blutungsstatus anzeigen + Mostra stato di sanguinamento + Mostrar estado de sangramento + 出血状態の表示 + 출혈 상태 표시 + Afficher l'état des saignements + Показать состояние кровотечения + + + Display if the patient is bleeding, optionally with rate + Mostrar si el paciente está sangrando, opcionalmente con tasa + Zeigt an, dass der Patient blutet, optional mit Rate + Mostra se il paziente sta sanguinando, opzionalmente con rateo + Mostrar se o paciente está sangrando, opcionalmente com taxa + 患者が出血しているかどうかを表示します。オプションで出血速度も表示します + 환자가 출혈 중인지 여부를 표시합니다(선택적으로 출혈 속도 포함) + Indique si le patient saigne, éventuellement avec le taux de saignement + Показывает, есть ли у пациента кровотечение, опционально с указанием частоты + + + Show Bleeding Rate + Mostrar tasa de sangrado + Blutungsrate anzeigen + Mostra rateo di sanguinamento + Mostrar taxa de sangramento + 出血速度の表示 + 출혈 속도 표시 + Afficher le taux de saignement + Показать частоту кровотечения + + + Peek Medical Info on Hit + Podgląd Informacji Medycznych po Zranieniu + 맞을 시 의료 정보 보기 + 点击查看医疗信息 + Aperçu des informations médicales lors d'une blessure + Mostra info mediche se colpito + Zeige medizinische Info beim Treffer an + 被弾時の医療情報一時表示 + Показать медицинскую информацию о попадании + Ojear Información Médica en Impacto + + + Temporarily show medical info when injured. + Tymczasowe wyświetlanie informacji medycznych po zranieniu. + 부상을 입었을 때 일시적으로 의료 정보를 표시합니다. + 受伤时暂时显示医疗信息。 + Afficher temporairement les informations médicales lors d'une blessure. + Mostra temporaneamente le info mediche quando si viene feriti. + Bei Verletzungen vorübergehend medizinische Info anzeigen. + 被弾時に医療情報を一時的に表示します。 + Временно показывать медицинскую информацию при травме. + Temporalmente muestra la información médica cuando es herido. + + + Medical Peek Duration on Hit + Czas trwania podglądu informacji medycznych po zranieniu + 맞을 시 의료 정보 보기 지속 시간 + 击中时的医疗信息显示持续时间 + Durée de l'aperçu des informations médicales lors d'une blessure + Durata di info mediche quando colpito + Dauer der Anzeige bei einem Treffer. + 被弾時の医療情報一時表示の表示時間 + Продолжительность медицинского осмотра при попадании + Duración de Ojear la Información Médica cuando hay Impacto + + + How long the medical info peek remains open after being injured. + Jak długo podgląd informacji medycznych pozostaje otwarty po otrzymaniu obrażeń. + 부상을 입은 후에도 의료 정보가 열린 상태로 지속되는 시간입니다. + 受伤后医疗信息会开放多长时间? + Durée de l'affichage des informations médicales lors d'une blessure. + Quanto tempo verranno visualizzate le info mediche quando si viene feriti. + Wie lange die medizinische Info nach einer Verletzung angezeigt wird. + 被弾時の医療情報の一時表示をどれだけ長く表示するか。 + Как долго окно просмотра медицинской информации остается открытым после получения травмы. + Durante cuánto tiempo la información médica ojeada permanece abierta una tras haber sido herido. + + + Show Trauma Sustained + Mostrar Traumatismo Sofrido + 外傷状態の表示 + Pokaż Doznane Urazy + Zeigen Sie das erlittene Trauma + Mostra trauma sofferto + 외상 지속 표시 + 显示遭受的创伤 + Afficher les traumatismes subis + Показать полученную травму + Mostrar Trauma Sostenido + + + Show trauma sustained in the injury list. + Mostrar traumatismo sofrido na lista de feridas. + 負傷リストに外傷状態を表示する。 + Pokaż odniesione obrażenia na liście obrażeń. + Zeigen Sie das erlittene Trauma in der Verletzungsliste an. + Mostra il trauma ricevuto nella lista delle ferite. + 부상 목록에 발생한 외상을 표시합니다. + 在伤情表上显示创伤 + Afficher les traumatismes subis dans la liste des blessures. + Показать полученную травму в списке травм. + Mostrar trauma sostenido en la lista de heridas + + + Body Part Outline Color + Kolor Konturu Części Ciała + 신체부위 윤곽선 색상 + 身体部位轮廓颜色 + Couleur des contours des parties du corps + Colore del contorno di parti del corpo + Umrissfarbe des Körperteils + 身体部位の輪郭表示の色 + Цвет контура части тела + Color de Contorno de las Partes del Cuerpo + + + Color of outline around selected body part. + Kolor konturu wokół wybranej części ciała. + 선택한 신체부위 주위의 윤곽선 색상입니다. + 选定身体部位周围的轮廓颜色。 + Couleur des contours autour des parties du corps sélectionnées. + Colore del contorno della parte del corpo selezionata. + Farbe des Umrisses um das ausgewählten Körperteil. + 選択した身体部位の輪郭表示の色。 + Цвет контура вокруг выбранной части тела. + Color del contorno alrededor de la parte del cuerpo seleccionada. + + + Minor Trauma + Traumatismo Leve + 軽度の外傷 + Niewielki Uraz + Kleineres Trauma + Trauma piccolo + 약한 외상 + 轻微创伤 + Traumatisme mineur + Незначительная травма + Trauma Menor + + + Major Trauma + Traumatismo Significante + 中度の外傷 + Poważny Uraz + Großes Trauma + Trauma grande + 중간 외상 + 中度创伤 + Traumatisme majeur + Серьезная травма + Trauma mayor + + + Severe Trauma + Traumatismo Severo + 重度の外傷 + Ciężki Uraz + Schweres Trauma + Trauma severo + 강한 외상 + 重度创伤 + Traumatisme grave + Тяжелая травма + Trauma Severo + + + Chronic Trauma + Traumatismo Crônico + 重篤な外傷 + Przewlekły Uraz + Chronisches Trauma + Trauma cronico + 심각한 외상 + 慢性创伤 + Traumatisme chronique + Хроническая травма + Trauma Crónico + + + L + L + + L + G + Sx + L + + Лево + I + + + R + P + + R + D + Dx + R + + Право + D + + + in your inventory + w twoim ekwipunku + 개: 당신의 소지품 + 在你的库存中 + dans votre inventaire + Nel proprio inventario + im Inventar + 個あなたが保有 + в вашем инвентаре + en tu inventario + + + in patient's inventory + w ekwipunku pacjenta + 개: 환자의 소지품 + 在病人库存中 + dans l'inventaire du patient + Nell'inventario del paziente + im Inventar des Patienten + 個患者が保有 + в инвентаре пациента + en el inventario del paciente + + + in vehicle's inventory + w ekwipunku pojazdu + 在车辆库存中 + dans l'inventaire du véhicule + 개: 차량의 소지품 + im Inventar des Fahrzeuges + Nell'inventario del veicolo + 個車両内に保有 + в инвентаре транспорта + en el inventario del vehículo + + + No effect until tourniquet removed + 止血带取下后才有效果 + Aucun effet jusqu'à ce que le garrot soit retiré + 지혈대를 제거할 때까지 효과 없음 + Keine Wirkung, bis das Tourniquet entfernt wurde + Nessun effetto fino alla rimozione del laccio emostatico + 止血帯を外すまで効果を発揮しません + Никакого эффекта до тех пор, пока жгут не будет снят + Sin efecto hasta que se quita el torniquete + + + Show Tourniquet Warning + 显示止血带警告 + Afficher l'avertissement du garrot + 지혈 경고 표시 + Tourniquet-Warnung anzeigen + Mostra avviso di laccio emostatico + 止血帯の警告を表示 + Показать предупреждение о наложении жгута + Mostrar Advertencia de Torniquete + + + Show a warning tooltip when a tourniquet will interfere with a medical action. + 当止血带干扰医疗操作时,显示警告提示。 + Affiche un avertissement lorsqu'un garrot interfère avec une action médicale. + 지혈대가 의료 조치를 방해할 경우 경고 툴팁을 표시합니다. + Zeigt einen Hinweis an, wenn ein Tourniquet eine medizinische Maßnahme beeinträchtigt. + Mostra un avviso se un laccio emostatico impedisce un trattamento medico. + 止血帯が医療行為を妨げる場合には、警告ツールチップを表示します。 + Показать всплывающую подсказку с предупреждением, когда жгут помешает медицинскому вмешательству. + Muestra un mensaje de advertencia cuando un torniquete interfiera con una acción médica. diff --git a/addons/medical_gui/ui/grave.paa b/addons/medical_gui/ui/grave.paa new file mode 100644 index 0000000000..ccd786d73c Binary files /dev/null and b/addons/medical_gui/ui/grave.paa differ diff --git a/addons/medical_gui/ui/painkillers.paa b/addons/medical_gui/ui/painkillers.paa new file mode 100644 index 0000000000..3c5da9b30b Binary files /dev/null and b/addons/medical_gui/ui/painkillers.paa differ diff --git a/addons/medical_gui/ui/patient_info_preview_ca.paa b/addons/medical_gui/ui/patient_info_preview_ca.paa new file mode 100644 index 0000000000..17c974a436 Binary files /dev/null and b/addons/medical_gui/ui/patient_info_preview_ca.paa differ diff --git a/addons/medical_statemachine/CfgEventHandlers.hpp b/addons/medical_statemachine/CfgEventHandlers.hpp index ab659e1cda..b9150d8564 100644 --- a/addons/medical_statemachine/CfgEventHandlers.hpp +++ b/addons/medical_statemachine/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_statemachine/Statemachine.hpp b/addons/medical_statemachine/Statemachine.hpp index 1516c680e2..d3888140c0 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 = QFUNC(enteredStateUnconscious); class DeathAI { targetState = "Dead"; - condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); + condition = QUOTE(!(_this getVariable [ARR_2(QQGVAR(AIUnconsciousness),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,24 +64,18 @@ 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 { @@ -90,8 +83,10 @@ class ACE_Medical_StateMachine { 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"; @@ -108,6 +103,7 @@ class ACE_Medical_StateMachine { }; class Bleedout { targetState = "Dead"; + condition = QUOTE((GVAR(cardiacArrestBleedoutEnabled))); // wrap to ensure cba uses this as code and not a direct variable events[] = {QEGVAR(medical,Bleedout)}; }; }; diff --git a/addons/medical_statemachine/XEH_PREP.hpp b/addons/medical_statemachine/XEH_PREP.hpp index 8e2725d3da..df481ae634 100644 --- a/addons/medical_statemachine/XEH_PREP.hpp +++ b/addons/medical_statemachine/XEH_PREP.hpp @@ -1,14 +1,15 @@ PREP(conditionCardiacArrestTimer); PREP(conditionExecutionDeath); +PREP(conditionSecondChance); PREP(enteredStateCardiacArrest); PREP(enteredStateDeath); PREP(enteredStateFatalInjury); +PREP(enteredStateUnconscious); PREP(handleStateCardiacArrest); PREP(handleStateDefault); PREP(handleStateInjured); PREP(handleStateUnconscious); PREP(leftStateCardiacArrest); PREP(localityChangedEH); -PREP(localityTransfer); PREP(resetStateDefault); PREP(transitionSecondChance); diff --git a/addons/medical_statemachine/XEH_postInit.sqf b/addons/medical_statemachine/XEH_postInit.sqf index 89d8891fdb..a7c7740a39 100644 --- a/addons/medical_statemachine/XEH_postInit.sqf +++ b/addons/medical_statemachine/XEH_postInit.sqf @@ -1,3 +1,14 @@ #include "script_component.hpp" -[QGVAR(localityTransfer), LINKFUNC(localityTransfer)] call CBA_fnc_addEventHandler; +["ace_killed", { // global event + params ["_unit"]; + + // Prevent second ragdoll of uncon units when they're killed + if ( + IS_UNCONSCIOUS(_unit) && !isAwake _unit // uncon and not ragdolling + && {isPlayer _unit || {_unit getVariable [QGVAR(AIUnconsciousness), GVAR(AIUnconsciousness)]}} + ) then { + _unit enableSimulation false; + [{_this enableSimulation true}, _unit, 2] call CBA_fnc_waitAndExecute; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_statemachine/XEH_preInit.sqf b/addons/medical_statemachine/XEH_preInit.sqf index d77d8067a8..65621f775b 100644 --- a/addons/medical_statemachine/XEH_preInit.sqf +++ b/addons/medical_statemachine/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" EGVAR(medical,STATE_MACHINE) = (configFile >> "ACE_Medical_StateMachine") call CBA_statemachine_fnc_createFromConfig; diff --git a/addons/medical_statemachine/addon.toml b/addons/medical_statemachine/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_statemachine/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_statemachine/config.cpp b/addons/medical_statemachine/config.cpp index 23a55f5258..c368eb25a7 100644 --- a/addons/medical_statemachine/config.cpp +++ b/addons/medical_statemachine/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -16,3 +24,5 @@ class CfgPatches { #include "Statemachine.hpp" #include "CfgEventHandlers.hpp" + +#endif diff --git a/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf b/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf index b28459db53..1e91e6f54d 100644 --- a/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf +++ b/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the cardiac arrest timer ran out. diff --git a/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf b/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf index a409069fba..0812e3b74c 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" +#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..432e6ce30f --- /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 0c5e184029..313baf6505 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles a unit entering cardiac arrest (calls for a status update). @@ -17,6 +17,9 @@ */ params ["_unit"]; +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + WARNING_1("enteredStateCardiacArrest: State transition on dead or null unit - %1",_unit); +}; // 10% possible variance in cardiac arrest time private _time = GVAR(cardiacArrestTime); @@ -28,4 +31,4 @@ _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..8be1d358df 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Handles a unit reaching the point of death (calls for a status update). * * Arguments: @@ -16,10 +16,16 @@ */ params ["_unit"]; +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + if ((_unit getVariable [QEGVAR(medical,causeOfDeath), ""]) == "#scripted") exitWith {}; + WARNING_1("enteredStateDeath: State transition on dead or null unit - %1",_unit); +}; -// TODO: Probably also needs additional logic to deal with edge cases +//IGNORE_PRIVATE_WARNING ["_thisOrigin", "_thisTransition"]; // vars provided by CBA_statemachine +TRACE_4("enteredStateDeath",_this,_thisOrigin,_thisTransition,CBA_missionTime); -// Send a local event before death -[QEGVAR(medical,death), [_unit]] call CBA_fnc_localEvent; +private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; +private _source = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; +private _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; -[_unit] call EFUNC(medical_status,setDead); +[_unit, _causeOfDeath, _source, _instigator] call EFUNC(medical_status,setDead); diff --git a/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf b/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf index 04121b1c95..d5d81889dd 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Raises the transition to the next state instantly when fatally injured. @@ -16,5 +16,8 @@ */ params ["_unit"]; +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + WARNING_1("enteredStateFatalInjury: State transition on dead or null unit - %1",_unit); +}; [QEGVAR(medical,FatalInjuryInstantTransition), _unit] call CBA_fnc_localEvent; diff --git a/addons/medical_statemachine/functions/fnc_enteredStateUnconscious.sqf b/addons/medical_statemachine/functions/fnc_enteredStateUnconscious.sqf new file mode 100644 index 0000000000..c80481bad2 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_enteredStateUnconscious.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Grim + * Handles a unit reaching the point of unconsciousness (calls for a status update). + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_statemachine_fnc_enteredStateUnconscious + * + * Public: No + */ +params ["_unit"]; + +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + WARNING_1("enteredStateUnconscious: State transition on dead or null unit - %1",_unit); +}; + +//IGNORE_PRIVATE_WARNING ["_thisOrigin", "_thisTransition"]; // vars provided by CBA_statemachine +TRACE_4("enteredStateUnconscious",_this,_thisOrigin,_thisTransition,CBA_missionTime); + +[_unit, true] call EFUNC(medical_status,setUnconsciousState); diff --git a/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf index b9e49adfe3..7e7860bb12 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the unconscious state @@ -18,8 +18,7 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); @@ -34,4 +33,3 @@ if (_timeDiff >= 1) then { _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 33cb1d29c0..89e09b0d4c 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the default state @@ -18,12 +18,11 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; -[_unit] call EFUNC(medical_vitals,handleUnitVitals); - -private _painLevel = GET_PAIN_PERCEIVED(_unit); -if (_painLevel > 0) then { - [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; +if ([_unit] call EFUNC(medical_vitals,handleUnitVitals)) then { // returns true when update ran + private _painLevel = GET_PAIN_PERCEIVED(_unit); + if (_painLevel > 0) then { + [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; + }; }; diff --git a/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf b/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf index 50f4a6bfa6..ad407c0191 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the injured state @@ -18,12 +18,11 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; -[_unit] call EFUNC(medical_vitals,handleUnitVitals); - -private _painLevel = GET_PAIN_PERCEIVED(_unit); -if (_painLevel > 0) then { - [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; +if ([_unit] call EFUNC(medical_vitals,handleUnitVitals)) then { // returns true when update ran + private _painLevel = GET_PAIN_PERCEIVED(_unit); + if (_painLevel > 0) then { + [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; + }; }; diff --git a/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf b/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf index 9968e26645..aa93d44932 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Handles the unconscious state @@ -22,11 +22,6 @@ if (!alive _unit || {!local _unit}) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); -private _painLevel = GET_PAIN_PERCEIVED(_unit); -if (_painLevel > 0) then { - [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; -}; - // Handle spontaneous wake up from unconsciousness if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { if (_unit call EFUNC(medical_status,hasStableVitals)) then { @@ -39,7 +34,13 @@ if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; }; - if (CBA_missionTime - _lastWakeUpCheck > SPONTANEOUS_WAKE_UP_INTERVAL) then { + 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]; diff --git a/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf index 5b077be771..a83e971fe7 100644 --- a/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: RedBery * Handles a unit leaving cardiac arrest (calls for a status update). @@ -22,4 +22,4 @@ TRACE_1("leftStateCardiacArrest",_unit); _unit setVariable [QGVAR(cardiacArrestTimeLeft), nil]; _unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), nil]; -[_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 index 1bcc9a9bde..6f6ee43c6f 100644 --- a/addons/medical_statemachine/functions/fnc_localityChangedEH.sqf +++ b/addons/medical_statemachine/functions/fnc_localityChangedEH.sqf @@ -1,7 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror - * Handles locality switch. + * 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 @@ -19,15 +20,50 @@ params ["_unit", "_isLocal"]; TRACE_2("localityChangedEH",_unit,_isLocal); -if (!alive _unit) exitWith {TRACE_1("dead", _this)}; - -if (!_isLocal) then { - // If locality changed, broadcast the last medical state - _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) exitWith {}; +if (_isLocal) then { private _currentState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; - TRACE_2("sending current state",_unit,_currentState); - [QGVAR(localityTransfer), [_unit, _currentState], _unit] call CBA_fnc_targetEvent; + 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), 1e38]; + 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/functions/fnc_localityTransfer.sqf b/addons/medical_statemachine/functions/fnc_localityTransfer.sqf deleted file mode 100644 index abf4ddd5a3..0000000000 --- a/addons/medical_statemachine/functions/fnc_localityTransfer.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * Handles locality switch. - * - * Arguments: - * 0: Unit - * 1: State - * - * Return Value: - * None - * - * Example: - * [player, "Injured"] call ace_medical_statemachine_fnc_localityTransfer - * - * Public: No - */ - -params ["_unit", "_currentState"]; -TRACE_2("localityTransfer",_unit,_currentState); - -private _oldState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; -if (_oldState != _currentState) then { - TRACE_2("changing state",_oldState,_currentState); - [_unit, EGVAR(medical,STATE_MACHINE), _oldState, _currentState, {}, "LocalityChange"] call CBA_statemachine_fnc_manualTransition; -}; diff --git a/addons/medical_statemachine/functions/fnc_resetStateDefault.sqf b/addons/medical_statemachine/functions/fnc_resetStateDefault.sqf index 4cffd47076..d05d0939a2 100644 --- a/addons/medical_statemachine/functions/fnc_resetStateDefault.sqf +++ b/addons/medical_statemachine/functions/fnc_resetStateDefault.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Resets the default state on a unit after respawning. * * Arguments: @@ -17,7 +17,4 @@ params ["_unit"]; -// Statemachine only handles local units -if !(local _unit) exitWith {}; - [_unit, EGVAR(medical,STATE_MACHINE), "Dead", "Default"] call CBA_statemachine_fnc_manualTransition; diff --git a/addons/medical_statemachine/functions/fnc_transitionSecondChance.sqf b/addons/medical_statemachine/functions/fnc_transitionSecondChance.sqf index bdee0f9432..ea90b3e962 100644 --- a/addons/medical_statemachine/functions/fnc_transitionSecondChance.sqf +++ b/addons/medical_statemachine/functions/fnc_transitionSecondChance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Gives the unit a second chance and prevents death for 1 second. diff --git a/addons/medical_statemachine/functions/script_component.hpp b/addons/medical_statemachine/functions/script_component.hpp deleted file mode 100644 index 5dd15bb8b4..0000000000 --- a/addons/medical_statemachine/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_statemachine\script_component.hpp" diff --git a/addons/medical_statemachine/initSettings.inc.sqf b/addons/medical_statemachine/initSettings.inc.sqf new file mode 100644 index 0000000000..c129223931 --- /dev/null +++ b/addons/medical_statemachine/initSettings.inc.sqf @@ -0,0 +1,52 @@ +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(AIUnconsciousness), + "CHECKBOX", + [LSTRING(AIUnconsciousness_DisplayName), LSTRING(AIUnconsciousness_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(cardiacArrestTime), + "TIME", + [LSTRING(CardiacArrestTime_DisplayName), LSTRING(CardiacArrestTime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [1, 3600, 300], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(cardiacArrestBleedoutEnabled), + "CHECKBOX", + [LSTRING(CardiacArrestBleedout_DisplayName), LSTRING(CardiacArrestBleedout_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + true +] call CBA_fnc_addSetting; diff --git a/addons/medical_statemachine/initSettings.sqf b/addons/medical_statemachine/initSettings.sqf deleted file mode 100644 index 2dfe27463e..0000000000 --- a/addons/medical_statemachine/initSettings.sqf +++ /dev/null @@ -1,35 +0,0 @@ -[ - QGVAR(fatalInjuryCondition), - "LIST", - [LSTRING(FatalInjuryCondition_DisplayName), LSTRING(FatalInjuryCondition_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - [[0, 1, 2], [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], 0], - true -] call CBA_settings_fnc_init; - -[ - QGVAR(fatalInjuryConditionAI), - "CHECKBOX", - [LSTRING(FatalInjuryConditionAI_DisplayName), LSTRING(FatalInjuryConditionAI_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - true, - true -] call CBA_settings_fnc_init; - -[ - QGVAR(AIUnconsciousness), - "CHECKBOX", - [LSTRING(AIUnconsciousness_DisplayName), LSTRING(AIUnconsciousness_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - true, - true -] call CBA_settings_fnc_init; - -[ - 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 8652e02e77..2b828d506e 100644 --- a/addons/medical_statemachine/stringtable.xml +++ b/addons/medical_statemachine/stringtable.xml @@ -6,30 +6,80 @@ Zustände 状態 Состояния + États + Estados + 狀態 + 状态 + Stato + Stavy + Stany + Devletler + Estados + 현재 상태 - - Fatal Injury Player + + Player Fatal Injuries + Lesões Fatais do Jogador + プレイヤーの致命傷 + 玩家致命傷 + 玩家致命伤 + Décès si blessure mortelle (joueurs) + Smrtelná zranění hráčů + Śmiertelne Obrażenia Gracza + Ferite letali su giocatori + Oyuncu Ölümcül Yaralanmaları Tödliche Spielerverletzungen - 致命傷プレイヤー - Смертельные ранения игрока + Смертельные травмы игрока + Heridas mortales del jugador + 플레이어 중태 - - Controls when a player can receive a fatal injury. - Definiert wann ein Spieler tödliche Verletzungen bekommen kann - プレイヤーが致命傷から蘇生できるかどうか決定します - Определяет, когда игрок может получить смертельное ранение + + Controls when players can receive fatal injuries. A fatal injury is caused by significant damage to the head or torso. + Controla quando os jogadores podem receber lesões fatais. Uma lesão fatal é causada por um dano significante na cabeça ou tronco. + プレイヤーが致命傷を受けた時の挙動を管理できます。頭部や胸部に受ける大きなダメージは致命傷になります。 + 控制當玩家受致命傷時是否能救起。致命傷是指對頭部或身體造成可觀傷害所造成的。 + 控制当玩家受致命伤时是否能救起。致命伤是指对头部或躯干遭受重大伤害。 + Détermine si les joueurs décèdent en cas de blessure mortelle. Une blessure mortelle est définie par des dommages importants à la tête ou au cœur. + Oyuncuların ölümcül yaralanmaları ne zaman alabileceğini kontrol eder. Ölümcül bir yaralanma, kafaya veya vücuda önemli hasar verir. + Nastavuje zda hráči mohou utrpět smrtelné zranění. Smrtelné zranění je utrpěto významným poškozením hlavy nebo trupu. + Controlla quando i giocatori possono ricevere infortuni mortali. Una ferita letale è causata da un danno significativo alla testa o al torso. + Definiuje, kiedy gracze mogą otrzymać śmiertelne obrażenia. Śmiertelne obrażenia są spowodowane znacznym uszkodzeniem głowy lub torsu. + Legt fest, wann Spieler tödliche Verletzungen erleiden können. Eine tödliche Verletzung wird bei erheblichem Schaden an Kopf oder Torso verursacht. + Определяет, могут ли игроки получить смертельные травмы. Смертельная травма вызывается значительным повреждением головы или туловища. + Controla cuándo los jugadores pueden sufrir lesiones fatales. Una lesión fatal es causada por un daño significativo en la cabeza o el cuerpo. + 플레이어가 언제 중태로 빠질 지 결정합니다. 중태는 머리나 몸통에 심각한 피해를 입는 경우 발생합니다. - - AI Instant Death - Direkter Tod KI - AI の即死 - Мгновенная смерть ИИ + + AI Fatal Injuries + Lesões Fatais da IA + AIの致命傷 + AI致命傷 + AI 致命伤 + Décès si blessure mortelle (IA) + Smrtelná zranění AI + Śmiertelne obrażenia AI. + Ferite letali su IA + AI Ölümcül Yaralanmaları + Tödliche KI-Verletzungen + Смертельные травмы ИИ + Heridas mortales IA + 인공지능 중태 - - Controls if AI units are able to die instantly. - Legt fest, ob eine KI direkt sterben kann - AI が即死できるかどうか決定します - Определяет, сможет ли ИИ мгновенно умереть + + Controls when AI can receive fatal injuries. A fatal injury is caused by significant damage to the head or troso.\nWhen set to "Always", this effectively produces "AI Instant Death" behaviour as AI will immediately die from any fatal injury.\nNOTE: Any mode other than "Always" requires AI Unconsciousness to be enabled. + Controla quando a IA pode receber lesões fatais. Uma lesão fatal é causada por um dano significante na cabeça ou tronco.\nQuando definido para "Sempre", isso efetivamente causa a "Morte Instantânea da IA", pois a IA irá imediatamente morrer para qualquer lesão fatal.\nNOTA: Qualquer opção além de "Sempre" requer que Inconsciência de IA esteja ativada. + AIが致命傷を受けた時の挙動を管理できます。頭部や胸部に受ける大きなダメージは致命傷になります。\n"常に"に設定されていると、いかなる致命傷でも"AIの即死"効果が生まれます。\n注: "常に"以外のモードでは"AIの無意識状態化"を有効化させる必要があります。 + 控制當AI受致命傷時是否能救起。致命傷是指對頭部或身體造成可觀傷害所造成的。\n當設置為"總是"時,這會使其與"AI 瞬間死亡"同一個效果,在AI受到致命傷時瞬間死亡。\n備註:選了"總是"以外的選項的話必須開啟「AI無意識」的選項。 + 控制当 AI 受致命伤时是否能救起。致命伤是指对头部或躯干遭受重大伤害。\n当设置为"总是"时,这将有效地产生"AI 即时死亡"行为,因为 AI 将立即死于任何致命伤。\n注意:"总是"以外的任何模式都需要启用 AI 无意识。 + Détermine si les unités IA décèdent en cas de blessure mortelle. Une blessure mortelle est définie par des dommages importants à la tête ou au cœur.\nSi réglé sur "Toujours", cela produit effectivement un comportement de "Mort instantanée" car les unités IA mourront immédiatement de toute blessure mortelle.\nNOTE : Tout mode autre que "Toujours" nécessite l'activation de l'option "Inconscience IA". + AI'nın ölümcül yaralanmaları ne zaman alabileceğini kontrol eder. Ölümcül bir yaralanma, kafa veya vücudun önemli hasar görmesinden kaynaklanır. \"Her zaman" olarak ayarlandığında, AI herhangi bir ölümcül yaralanmadan hemen öleceği için bu etkili bir şekilde "AI Anında Ölüm" davranışı üretir.\ NOT: "Her zaman" "Yapay Zeka Bilinci'nin etkinleştirilmesini gerektirir. + Nastavuje zda AI může utrpět smrtelné zranění. Smrtelné zranění je utrpěto významným poškozením hlavy nebo trupu.\nPokud je tato možnost nastavena na "Vždy", efektivně nastává stav "Povolit okamžitou smrt AI", protože AI okamžitě zemře při jakémkoliv smrtelném zranění.\nPOZNÁMKA: Jakýkoliv jiný stav než "Vždy" potřebuje zapnutou možnost "Bezvědomí AI". + Controlla quando l'IA può ricevere infortuni mortali. Una ferita letale è causata da un danno significativo alla testa o al torso.\nSe impostato su "Sempre", questo produce efficacemente il comportamento "Morte istantanea AI", poiché l'IA morirà immediatamente a causa di qualsiasi lesione mortale.\nNOTA: Qualsiasi modalità diversa da "Sempre" richiede l'attivazione dell'Incoscienza IA. + Definiuje, kiedy AI może otrzymać śmiertelne obrażenia. Śmiertelne obrażenia są spowodowane znacznym uszkodzeniem głowy lub torsu.\n Ustawienie "Zawsze" powoduje "Natychmiastową śmierć AI", ponieważ AI natychmiast umiera z powodu śmiertelnych obrażeń.\n UWAGA: Każdy inny tryb niż "Zawsze" wymaga włączenia nieprzytomności AI. + Legt fest, wann KI-Einheiten tödliche Verletzungen erleiden können. Eine tödliche Verletzung wird bei erheblichem Schaden an Kopf oder Körper verursacht.\nWenn "Immer" eingestellt ist, erzeugt diese Einstellung das "KI Sofort-Tod" Verhalten. KI-Einheiten sterben sofort durch jede tödliche Verletzung.\nBEACHTE: Eine andere Einstellung als "Immer" bedingt, dass "KI-Bewusstlosigkeit" verwendet wird. + Определяет могут ли игроки получить смертельные травмы. Смертельная травма вызывается значительным повреждением головы или туловища.\nКогда установлено «Всегда», это вызывает поведение «Мгновенной смерти ИИ», так как ИИ немедленно умрет от любой смертельной травмы.\nПРИМЕЧАНИЕ: Любой режим, кроме «Всегда», требует включения функции «Потеря сознания». + Controla cuándo la IA puede sufrir lesiones fatales. Una lesión fatal es causada por un daño significativo en la cabeza o el cuerpo. \n Cuando se establece en "Siempre", esto produce efectivamente un comportamiento de "Muerte instantánea de IA", ya que la IA morirá inmediatamente por cualquier lesión fatal. \n NOTA: Cualquier modo que no sea "Siempre" requiere que la inconsciencia de la IA esté habilitada. + 인공지능이 언제 중태로 빠질 지 결정합니다. 중태는 머리나 몸통에 심각한 피해를 입는 경우 발생합니다.\n "언제나"로 설정하면 "인공지능 즉사" 기능이 즉각 적용됩니다.\n 참고: "언제나"를 제외한 다른 모드는 인공지능의 기절이 활성화가 필요합니다. AI Unconsciousness @@ -39,33 +89,102 @@ KI-Bewusstlosigkeit Bezvědomí AI Inconsciência da IA - Inconscience des IA + Inconscience IA AI eszméletlenség Incoscienza IA - AI の気絶 + AIの無意識状態化 인공지능 기절 - AI无意识 + AI 无意识 AI無意識 + Yapay Zeka Bilinci - Allows AI to go unconscious instead of dying. - 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. + AIが即死する代わりに無意識状態化するかどうかを制御します。\nこれは "AIの致命傷" 設定と連動します。何故ならば、ユニットを心停止させるためには無意識状態に陥る必要がある為です。\nしかし、これらの設定は、致命的ではない負傷の経過による重症状態化でユニットが無意識状態に陥ることが出来るようにするため、分割されています。\n要するに、AIユニットの心停止を有効にするには、この設定を有効にする必要があるということです。 + 控制AI是否能進入無意識狀態而非立刻原地死亡。\n這個選項會與「AI致命傷」的選項聯動,使單位心搏停止的話必須先讓其無意識。\n然而,兩個設定分開之原因是使單位能因從非致命傷的攻擊情況下進入生命危險的狀態。\n簡單來說,你想要讓AI單位有心搏停止可能的話,該選項必須啟用。 + 控制 AI 是否可以进入昏迷状态而不是立即死亡。\n这个设置与"AI 致命伤"设置一起工作,因为进入心脏骤停需要单位能够昏迷。\n然而,这些设置是分开的,因为单位可能会因非致命伤害导致的关键生命体征而昏迷过去。\n从本质上讲,这意味着为了使 AI 单位的心脏骤停,必须启用此设置。 + Définit si les unités IA peuvent perdre connaissance au lieu de mourir immédiatement.\nCe paramètre fonctionne conjointement avec l'option "Décès si blessure mortelle (IA)" car, pour qu'une unité IA subisse un arrêt cardiaque, elle doit également pouvoir perdre connaissance.\nCependant, ces paramètres sont séparés car les unités peuvent s'évanouir suite à des signes vitaux critiques résultant de blessures non mortelles.\nEn résumé, cela signifie que ce paramètre doit absolument être activé pour qu'une unité IA puisse entrer en état d'arrêt cardiaque. + Nastavuje zda AI může upadnout do bezvědomí namísto okamžité smrti.\nToto nastavení funguje společně s "Smrtelná zranění AI" protože srdeční zástava potřebuje možnost upadnout do bezvědomí.\nTyto možnosti jsou separované, protože jednotky mohou upadnout do bezvědomí kvůli kritickému stavu způsobenému ne smrtelnými zraněními.\nV podstatě to znamená, že pokud chcete zapnout srdeční zástavu pro AI, tato možnost musí být zapnutá. + Definiuje, czy AI może stracić przytomność zamiast natychmiast zginąć.\n Ta opcja działa razem z ustawieniem "Śmiertelne urazy AI", ponieważ przejście do zatrzymania akcji serca wymaga, aby jednostka mogła stracić przytomność.\n Jednak te ustawienia są rozdzielone, ponieważ jednostki mogą stracić przytomność z powodu krytycznych czynności życiowych powstałych w wyniku urazów innych niż śmiertelne.\n W istocie oznacza to, że aby umożliwić zatrzymanie akcji serca dla jednostek AI, to ustawienie musi być włączone. + Controlla se l'IA può perdere i sensi invece di morire immediatamente. Questa impostazione funziona insieme all'impostazione "Ferite letali IA" poiché, per andare in arresto cardiaco, è necessario che l'unità sia in grado di perdere i sensi. Tuttavia, queste impostazioni sono separate perché le unità possono perdere i sensi da segni vitali critici derivanti da ferite non letali. + Kontrolliert, ob KI bewusstlos werden kann anstatt sofort zu sterben.\nDiese Einstellung funktioniert zusammen mit der Einstellung "Tödliche KI-Verletzungen". Denn wenn eine Einheit einen Herzstillstand erleiden soll, muss diese auch in der Lage sein, bewusstlos zu werden.\nDennoch sind diese beiden Einstellungen voneinander getrennt, da Einheiten auch durch kritische Vitalwerte bewusstlos werden können, die durch nicht tödliche Verletzungen aufgetreten sind.\nZusammengefasst bedeutet das, dass wenn KI-Einheiten einen Herzstillstand erleiden sollen, diese Einstellung aktiviert sein muss. + Управляет тем, может ли ИИ потерять сознание, вместо того, чтобы немедленно умереть.\nЭтот параметр работает вместе с параметром «Смертельные раны ИИ», поскольку при остановке сердца требуется, чтобы юнит мог потерять сознание.\nОднако эти настройки разделены, потому что юниты могут потерять сознание из-за критических ранений жизненно важных органов, полученных в результате несмертельных травм.\nВ сущности, это означает, что для включения остановки сердца для ИИ этот параметр должен быть включен. + Yapay zekanın hemen ölmek yerine bilinçsiz duruma geçip geçemeyeceğini kontrol eder. \ Bu ayar, "Yapay Zeka Ölümcül Yaralanmalar" ayarı ile birlikte çalışır, çünkü kalp durması, ünitenin bilinçsiz duruma geçebilmesini gerektirir. \ Özünde, bunun anlamı şudur: AI birimleri için kalp durmasını etkinleştirirseniz, bu ayar etkinleştirilmelidir. + Controla si la IA puede quedar inconsciente en lugar de morir de inmediato. \n Esta configuración funciona junto con la configuración de "Heridas mortales IA", ya que, sufrir un paro cardíaco requiere que la unidad pueda quedar inconsciente. \n Sin embargo, estas configuraciones están separadas porque las unidades pueden perder el conocimiento de los signos vitales críticos como resultado de lesiones no mortales. \n En esencia, esto significa que para habilitar el paro cardíaco en las unidades de IA, esta configuración debe estar habilitada. + 인공지능이 즉사하기보다 기절하는걸 설정합니다.\n이 기능은 "인공지능 중태" 기능과 같이 사용시 심정지를 구현합니다. Cardiac Arrest Time - Zeit bis zum Herzstillstand + Überlebenszeit im Herzstillstand 心停止時間 Длительность остановки сердца + Durée de l'arrêt cardiaque + Tempo de Parada Cardíaca + 心搏停止時間 + 心脏骤停时间 + Tempo d'arresto cardiaco + Délka srdeční zástavy + Czas Zatrzymania Akcji Serca + Kalp Durma Süresi + Tiempo de paro cardíaco + 심정지 시간 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. + 控制心搏停止後多久死亡 + 控制心脏骤停后多久单位死亡 + Determina quanto tempo ci vuole per morire di arresto cardiaco. + Nastavuje po jak dlouhé době pacient zemře kvůli srdeční zástavě. + Definiuje czas potrzebny na śmierć z powodu zatrzymania akcji serca. + Bestimmt die Dauer bis zum Tod durch Herzstillstand. + Ne kadar süre de kalbi durarak ölmesini belirleyin. + Controla cuanto tiempo dura el paro cardiaco antes de morir. + 심정지 후 얼마나 지나야 죽는지 결정합니다. In Cardiac Arrest Herzstillstand 心停止中 При остановке сердца + Provoquer un arrêt cardiaque + Em Parada Cardíaca + 心搏停止中 + 心脏骤停中 + In arresto cardiaco + V srdeční zástavě + Zatrzymanie Akcji Serca + Kalbi Durdu + En parada cardíaca + 심정지가 옴 + + + Bleedout During Cardiac Arrest + Кровотечение во время остановки сердца + Ausbluten im Herzstillstand + Dissanguamento in arresto cardiaco + Saignement durant l'arrêt cardiaque + 心停止中の失血死 + Desangrado durante parada cardíaca + Wykrwawienie podczas zatrzymanej akcji serca + 心脏骤停期间失血情况 + 심정지 중 출혈 + + + Controls whether a person can die in cardiac arrest by blood loss before the cardiac arrest time runs out. + Определяет, можно ли умереть от потери крови во время остановки сердца, даже если время жизни при остановке сердца еще не истекло. + Legt fest, ob man während des Herzstillstands durch Blutverlust sterben kann, auch wenn die Überlebenszeit im Herzstillstand noch nicht ausgelaufen ist. + Determina se è possibile morire per eccessiva perdita di sangue anche se non è ancora scaduto il 'tempo d'arresto cardiaco'. + Définit si un joueur en arrêt cardiaque peut mourir par exsanguination, avant que la durée de l'arrêt cardiaque définie ci-dessus ne soit écoulée. + 心停止中の失血によって心停止時間よりも早く死亡するかどうかを制御します。 + COntrola si una persona puede morir en parada cardíaca por causa de pérdida de sangre antes de que se termine el contador de parada cardíaca + Kontroluje czy śmierć osoby może nastąpić poprzez wykrwawienie zanim wyczerpię się Czas Zatrzymania Akcji Serca. + 控制单位是否会在心脏骤停时间耗完之前因失血过多而死亡。 + 지정한 심정지 시간이 다 되기 전에 출혈로 인해 사망할 수 있는 지를 결정합니다. diff --git a/addons/medical_status/CfgEventHandlers.hpp b/addons/medical_status/CfgEventHandlers.hpp index 94a04d1af3..4c75d4795a 100644 --- a/addons/medical_status/CfgEventHandlers.hpp +++ b/addons/medical_status/CfgEventHandlers.hpp @@ -1,25 +1,25 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_Init_EventHandlers { class CAManBase { class ADDON { - init = QUOTE([ARR_2((_this select 0), false)] 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..77f9712eb1 100644 --- a/addons/medical_status/XEH_PREP.hpp +++ b/addons/medical_status/XEH_PREP.hpp @@ -1,15 +1,20 @@ +PREP(addInventoryActions); PREP(addMedicationAdjustment); PREP(adjustPainLevel); PREP(getBloodLoss); PREP(getBloodPressure); PREP(getBloodVolumeChange); PREP(getCardiacOutput); +PREP(getMedicationCount); +PREP(handleKilled); +PREP(handleKilledMission); PREP(hasStableVitals); PREP(initUnit); PREP(isBeingCarried); PREP(isBeingDragged); PREP(isInStableCondition); -PREP(setCardiacArrest); +PREP(setCardiacArrestState); PREP(setDead); -PREP(setUnconscious); +PREP(setStatusEffects); +PREP(setUnconsciousState); PREP(updateWoundBloodLoss); diff --git a/addons/medical_status/XEH_postInit.sqf b/addons/medical_status/XEH_postInit.sqf index 9b7d186b46..3f342987c9 100644 --- a/addons/medical_status/XEH_postInit.sqf +++ b/addons/medical_status/XEH_postInit.sqf @@ -2,3 +2,35 @@ // Handle pain changes on injury [QEGVAR(medical,injured), LINKFUNC(adjustPainLevel)] call CBA_fnc_addEventHandler; + + +// Add inventory and open backpack actions to units +[QGVAR(addInventoryActions), LINKFUNC(addInventoryActions)] call CBA_fnc_addEventHandler; +// apply to all living and dead now +{ + [QGVAR(addInventoryActions), _x] call CBA_fnc_localEvent; +} forEach (allUnits + allDeadMen); +// apply to all future units +["CAManBase", "init", LINKFUNC(addInventoryActions), true, [], false] call CBA_fnc_addClassEventHandler; +// Respawn is called locally +["CAManBase", "respawn", { + params ["_unit"]; + if (!local _unit) exitWith {}; + [QGVAR(addInventoryActions), _unit] call CBA_fnc_globalEvent; +}, true] call CBA_fnc_addClassEventHandler; + + +// Handle comms status effects for spectator +// Separate from medical_feedback as these affect unit behavior rather than what the player sees +["featureCamera", { + params ["_unit", "_newCamera"]; + + if (_unit isNotEqualTo ACE_player) exitWith {}; + + if (_newCamera == "") then { // switched back to player view + private _status = IS_UNCONSCIOUS(_unit); + [_unit, _status] call FUNC(setStatusEffects); + } else { + [_unit, false, true] call FUNC(setStatusEffects); + }; +}] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/medical_status/XEH_preInit.sqf b/addons/medical_status/XEH_preInit.sqf index 9361d05015..82146d82e1 100644 --- a/addons/medical_status/XEH_preInit.sqf +++ b/addons/medical_status/XEH_preInit.sqf @@ -6,6 +6,22 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +// Add vanilla killed EH to unit to set correct killer +["CAManBase", "init", { + params ["_unit"]; + + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber ((configOf _unit) >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit)}; + + // Hopefully this EH gets added first as it can only effect other EH called after it + private _ehIndex = _unit addEventHandler ["Killed", {_this call FUNC(handleKilled)}]; + #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; + +addMissionEventHandler ["EntityKilled", {_this call FUNC(handleKilledMission)}]; ADDON = true; diff --git a/addons/medical_status/addon.toml b/addons/medical_status/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_status/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_status/config.cpp b/addons/medical_status/config.cpp index 69c1b2fd27..954c35e64d 100644 --- a/addons/medical_status/config.cpp +++ b/addons/medical_status/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -16,3 +24,5 @@ class CfgPatches { #include "ACE_settings.hpp" #include "CfgEventHandlers.hpp" + +#endif diff --git a/addons/medical_status/functions/fnc_addInventoryActions.sqf b/addons/medical_status/functions/fnc_addInventoryActions.sqf new file mode 100644 index 0000000000..8041eb0613 --- /dev/null +++ b/addons/medical_status/functions/fnc_addInventoryActions.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim, johnb43 + * Adds inventory and open backpack actions to uncon units. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [cursorTarget] call ace_medical_status_fnc_addInventoryActions + * + * Public: No + */ + +if (!hasInterface) exitWith {}; + +params ["_unit"]; + +// Gear Action - For Unconscious Units +private _id = _unit addAction ["", { + params ["_target", "_caller"]; + + _caller action ["Gear", _target]; +}, nil, 5.1, true, true, "gear", toString { + (_target isNotEqualTo ACE_player) && + {(lifeState _target) isEqualTo "INCAPACITATED"} +}, 2]; + +_unit setUserActionText [_id, localize "STR_ACTION_GEAR", ""]; + +// Open Bag Action - For Dead Units +_unit addAction ["OpenBag", { + params ["_target", "_caller"]; + + _caller action ["OpenBag", _target]; +}, nil, 5.2, true, true, "", toString { + private _backpackContainer = backpackContainer _target; + private _backpackConfig = configOf _backpackContainer; + + (_target isNotEqualTo ACE_player) && + {!((lifeState _target) in ["HEALTHY", "INJURED", "INCAPACITATED"])} && + {!isNull _backpackContainer} && + {!lockedInventory _backpackContainer} && + {maxLoad _backpackContainer > 0} && + {getNumber (_backpackConfig >> "disableInventory") != 1} && + {_target setUserActionText [_actionId, format [localize "STR_ACTION_OPEN_BAG", getText (_backpackConfig >> "displayName")]]; true} +}, 2]; diff --git a/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf b/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf index 524b242b1a..8770eaf0ae 100644 --- a/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf +++ b/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, PabstMirror * Adds a medication and it's effects @@ -7,16 +7,18 @@ * 0: The Unit * 1: Medication * 2: Time in system for the adjustment to reach its peak - * 3: Duration the adjustment will have an effect - * 4: Heart Rate Adjust - * 5: Pain Suppress Adjust - * 6: Flow Adjust + * 3: Duration the adjustment will have an effect + * 4: Heart Rate Adjust + * 5: Pain Suppress Adjust + * 6: Flow Adjust * * Return Value: * None * * Example: * [player, "Morphine", 120, 60, -10, 0.8, -10] call ace_medical_status_fnc_addMedicationAdjustment + * + * Public: No */ params ["_unit", "_medication", "_timeToMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust"]; TRACE_7("addMedicationAdjustment",_unit,_medication,_timeToMaxEffect,_maxTimeInSystem,_hrAdjust,_painAdjust,_flowAdjust); diff --git a/addons/medical_status/functions/fnc_adjustPainLevel.sqf b/addons/medical_status/functions/fnc_adjustPainLevel.sqf index c6df1adda3..9e7362d3e9 100644 --- a/addons/medical_status/functions/fnc_adjustPainLevel.sqf +++ b/addons/medical_status/functions/fnc_adjustPainLevel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Interface to allow external modules to affect the pain level diff --git a/addons/medical_status/functions/fnc_getBloodLoss.sqf b/addons/medical_status/functions/fnc_getBloodLoss.sqf index ca3cba77cd..c2a6604679 100644 --- a/addons/medical_status/functions/fnc_getBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_getBloodLoss.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Calculate the total blood loss of a unit. @@ -23,4 +23,10 @@ if (_woundBleeding == 0) exitWith {0}; private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); // even if heart stops blood will still flow slowly (gravity) -(_woundBleeding * (_cardiacOutput max 0.05) * EGVAR(medical,bleedingCoefficient)) +private _bloodLoss = (_woundBleeding * (_cardiacOutput max CARDIAC_OUTPUT_MIN) * EGVAR(medical,bleedingCoefficient)); + +private _eventArgs = [_unit, _bloodLoss]; // Pass by reference + +[QGVAR(getBloodLoss), _eventArgs] call CBA_fnc_localEvent; + +_eventArgs select 1 // return diff --git a/addons/medical_status/functions/fnc_getBloodPressure.sqf b/addons/medical_status/functions/fnc_getBloodPressure.sqf index bbb0e5b65e..a6a8ccd65d 100644 --- a/addons/medical_status/functions/fnc_getBloodPressure.sqf +++ b/addons/medical_status/functions/fnc_getBloodPressure.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Calculate the blood pressure of a unit. diff --git a/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf b/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf index c46338a475..61f5353583 100644 --- a/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf +++ b/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Calculates the blood volume change and decreases the IVs given to the unit. diff --git a/addons/medical_status/functions/fnc_getCardiacOutput.sqf b/addons/medical_status/functions/fnc_getCardiacOutput.sqf index cf405b52bc..3253f684ab 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" +#include "..\script_component.hpp" /* - * Author: Glowbal, SilentSpike + * Author: Glowbal, kymckay * Get the cardiac output from the Heart, based on current Heart Rate and Blood Volume. * * Arguments: diff --git a/addons/medical_status/functions/fnc_getMedicationCount.sqf b/addons/medical_status/functions/fnc_getMedicationCount.sqf new file mode 100644 index 0000000000..e98707c721 --- /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..6c01e4135e --- /dev/null +++ b/addons/medical_status/functions/fnc_handleKilled.sqf @@ -0,0 +1,59 @@ +#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); + +// ensure event is only called once +if (_unit isEqualTo (_unit getVariable [QGVAR(killed), objNull])) exitWith { + _this set [0, objNull]; + _this set [1, objNull]; + _this set [2, objNull]; +}; +_unit setVariable [QGVAR(killed), _unit]; + +private _causeOfDeath = _unit getVariable [QEGVAR(medical,causeOfDeath), "#scripted"]; +private _modifyKilledArray = missionNamespace getVariable [QEGVAR(medical,modifyKilledArray), true]; // getVar so this can be disabled + +// if undefined then it's a death not caused by ace's setDead (mission setDamage, disconnect, forced respawn while conscious) +if (_causeOfDeath != "#scripted") then { + _killer = _unit getVariable [QEGVAR(medical,lastDamageSource), _killer]; // vehicle + _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), _instigator]; // unit in the turret +} else { + // call setDead manually to prevent any issues + [_unit, "#scripted"] call FUNC(setDead); +}; + +// All Killed EHs uses the same array, so we can modify it now to pass the correct killer/instigator +if (_modifyKilledArray) then { + _this set [1, _killer]; + _this set [2, _instigator]; +}; +TRACE_3("killer info",_killer,_instigator,_causeOfDeath); + +if (_unit == player) then { + // Enable user input before respawn, in case mission is using respawnTemplates + ["unconscious", false] call EFUNC(common,setDisableUserInputStatus); +}; + +// Remove status effects before respawn, in case mission is using spectator +[_unit, false] call FUNC(setStatusEffects); + +["ace_killed", [_unit, _causeOfDeath, _killer, _instigator]] call CBA_fnc_globalEvent; diff --git a/addons/medical_status/functions/fnc_handleKilledMission.sqf b/addons/medical_status/functions/fnc_handleKilledMission.sqf new file mode 100644 index 0000000000..d77c08e6f7 --- /dev/null +++ b/addons/medical_status/functions/fnc_handleKilledMission.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Vanilla EntityKilled mission EH, attempts to set correct source/killer for other killed event handlers. + * + * Arguments: + * 0: Unit + * 1: Killer + * 2: Instigator + * 3: Use Effects + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player, true] call ace_medical_status_fnc_handleKilledMission + * + * Public: No + */ + +params ["_unit", "_killer", "_instigator", "_useEffects"]; +TRACE_4("handleKilledMission",_unit,_killer,_instigator,_useEffects); + +// ensure event is only called once +if (_unit isEqualTo (_unit getVariable [QGVAR(killedMission), objNull])) exitWith { + _this set [0, objNull]; + _this set [1, objNull]; + _this set [2, objNull]; +}; +_unit setVariable [QGVAR(killedMission), _unit]; + +private _causeOfDeath = _unit getVariable [QEGVAR(medical,causeOfDeath), "#scripted"]; +private _modifyKilledArray = missionNamespace getVariable [QEGVAR(medical,modifyKilledArray), true]; // getVar so this can be disabled + +// if undefined then it's a death not caused by ace's setDead (mission setDamage, disconnect, forced respawn while conscious) +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 (_modifyKilledArray) then { + _this set [1, _killer]; + _this set [2, _instigator]; +}; +TRACE_3("killer mission info",_killer,_instigator,_causeOfDeath); diff --git a/addons/medical_status/functions/fnc_hasStableVitals.sqf b/addons/medical_status/functions/fnc_hasStableVitals.sqf index 90e2caac93..29424c96b0 100644 --- a/addons/medical_status/functions/fnc_hasStableVitals.sqf +++ b/addons/medical_status/functions/fnc_hasStableVitals.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Check if a unit has stable vitals (required to become conscious) @@ -17,7 +17,7 @@ params ["_unit"]; -if (GET_BLOOD_VOLUME(_unit) < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) exitWith { false }; +if (GET_BLOOD_VOLUME(_unit) < MINIMUM_BLOOD_FOR_STABLE_VITALS) exitWith { false }; if IN_CRDC_ARRST(_unit) exitWith { false }; private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); diff --git a/addons/medical_status/functions/fnc_initUnit.sqf b/addons/medical_status/functions/fnc_initUnit.sqf index 4700d78393..278163d90b 100644 --- a/addons/medical_status/functions/fnc_initUnit.sqf +++ b/addons/medical_status/functions/fnc_initUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Initializes unit variables. @@ -32,13 +32,15 @@ if (damage _unit > 0) then { if (_isRespawn) then { TRACE_1("reseting all vars on respawn",_isRespawn); // note: state is handled by ace_medical_statemachine_fnc_resetStateDefault - // - Blood and heart ---------------------------------------------------------- + // - Vitals ------------------------------------------------------------------ _unit setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true]; _unit setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true]; _unit setVariable [VAR_BLOOD_PRESS, [80, 120], true]; _unit setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true]; _unit setVariable [VAR_CRDC_ARRST, false, true]; _unit setVariable [VAR_HEMORRHAGE, 0, true]; + _unit setVariable [VAR_SPO2, DEFAULT_SPO2, true]; + _unit setVariable [VAR_OXYGEN_DEMAND, 0, true]; // - Pain --------------------------------------------------------------------- _unit setVariable [VAR_PAIN, 0, true]; @@ -46,9 +48,9 @@ if (_isRespawn) then { _unit setVariable [VAR_PAIN_SUPP, 0, true]; // - Wounds ------------------------------------------------------------------- - _unit setVariable [VAR_OPEN_WOUNDS, [], true]; - _unit setVariable [VAR_BANDAGED_WOUNDS, [], true]; - _unit setVariable [VAR_STITCHED_WOUNDS, [], true]; + _unit setVariable [VAR_OPEN_WOUNDS, createHashMap, true]; + _unit setVariable [VAR_BANDAGED_WOUNDS, createHashMap, true]; + _unit setVariable [VAR_STITCHED_WOUNDS, createHashMap, true]; _unit setVariable [QEGVAR(medical,isLimping), false, true]; _unit setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; @@ -74,11 +76,16 @@ if (_isRespawn) then { _unit setVariable [VAR_MEDICATIONS, [], true]; // Unconscious spontanious wake up chance - _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil, true]; + + // Cause of death + _unit setVariable [QEGVAR(medical,causeOfDeath), nil, true]; }; [{ params ["_unit"]; TRACE_3("Unit Init",_unit,local _unit,typeOf _unit); + + _unit setVariable [QEGVAR(medical,initialized), true, true]; [QGVAR(initialized), [_unit]] call CBA_fnc_localEvent; }, [_unit], 0.5] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_status/functions/fnc_isBeingCarried.sqf b/addons/medical_status/functions/fnc_isBeingCarried.sqf index 7e58efc1ed..2c4d6552f4 100644 --- a/addons/medical_status/functions/fnc_isBeingCarried.sqf +++ b/addons/medical_status/functions/fnc_isBeingCarried.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Returns if a target is being carried. (from ace_dragging) diff --git a/addons/medical_status/functions/fnc_isBeingDragged.sqf b/addons/medical_status/functions/fnc_isBeingDragged.sqf index e8c21bdb56..e5b3c5da88 100644 --- a/addons/medical_status/functions/fnc_isBeingDragged.sqf +++ b/addons/medical_status/functions/fnc_isBeingDragged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Returns if a target is being dragged. (from ace_dragging) diff --git a/addons/medical_status/functions/fnc_isInStableCondition.sqf b/addons/medical_status/functions/fnc_isInStableCondition.sqf index 56226d3024..dedb2513f3 100644 --- a/addons/medical_status/functions/fnc_isInStableCondition.sqf +++ b/addons/medical_status/functions/fnc_isInStableCondition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if a unit is in a stable condition, needed for PersonalAidKit treatment @@ -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_setCardiacArrest.sqf deleted file mode 100644 index e79d09d28b..0000000000 --- a/addons/medical_status/functions/fnc_setCardiacArrest.sqf +++ /dev/null @@ -1,34 +0,0 @@ -#include "script_component.hpp" -/* - * 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_setCardiacArrest - * - * Public: No - */ - -params ["_unit", "_active"]; -TRACE_2("setCardiacArrest",_unit,_active); - -// No change to make -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); - -["ace_cardiacArrest", [_unit, _active]] call CBA_fnc_localEvent; diff --git a/addons/medical_status/functions/fnc_setCardiacArrestState.sqf b/addons/medical_status/functions/fnc_setCardiacArrestState.sqf new file mode 100644 index 0000000000..b806cef195 --- /dev/null +++ b/addons/medical_status/functions/fnc_setCardiacArrestState.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * 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 { 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, but only set when entering Cardiac arrest +if (_active) then { + [_unit, true] 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..138948c038 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Kills a local unit. @@ -6,6 +6,8 @@ * Arguments: * 0: The unit * 1: Reason for death + * 2: Killer + * 3: Instigator * * Return Value: * None @@ -13,16 +15,37 @@ * Public: No */ -params ["_unit", ["_reason", "unknown"]]; +params ["_unit", ["_reason", "#setDead"], ["_source", objNull], ["_instigator", objNull]]; +TRACE_4("setDead",_unit,_reason,_source,_instigator); // No heart rate or blood pressure to measure when dead _unit setVariable [VAR_HEART_RATE, 0, true]; _unit setVariable [VAR_BLOOD_PRESS, [0, 0], true]; +// Clear uncon variable just to be safe +_unit setVariable [VAR_UNCON, nil, true]; + +_unit setVariable [QEGVAR(medical,causeOfDeath), _reason, true]; + +// Send a local event before death +[QEGVAR(medical,death), [_unit]] call CBA_fnc_localEvent; + +// Update the state machine if necessary (forced respawn, scripted death, etc) +private _unitState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; +if (_unitState isNotEqualTo "Dead") then { + [_unit, EGVAR(medical,STATE_MACHINE), _unitState, "Dead"] call CBA_statemachine_fnc_manualTransition; +}; + +// (#8803) Reenable damage if disabled to prevent having live units in dead state +// Keep this after death event for compatibility with third party hooks +if (!isDamageAllowed _unit) then { + WARNING_1("setDead executed on unit with damage blocked - %1",_this); + _unit allowDamage true; +}; + // Kill the unit without changing visual apperance -[_unit, 1] call EFUNC(medical_engine,setStructuralDamage); +private _prevDamage = _unit getHitPointDamage "HitHead"; -private _lastShooter = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; -private _lastInstigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; +_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; -["ace_killed", [_unit, _reason, _lastShooter, _lastInstigator]] call CBA_fnc_globalEvent; +_unit setHitPointDamage ["HitHead", _prevDamage, true, _source, _instigator]; diff --git a/addons/medical_status/functions/fnc_setStatusEffects.sqf b/addons/medical_status/functions/fnc_setStatusEffects.sqf new file mode 100644 index 0000000000..4d093464de --- /dev/null +++ b/addons/medical_status/functions/fnc_setStatusEffects.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Sets status effects for a unit. + * For Internal Use: Called by FUNC(setUnconsciousState), FUNC(handleKilled), and on featureCamera changes. + * + * Arguments: + * 0: The unit + * 1: Status effects value + * 2: Skip setHidden (default: false) + * + * Return Value: + * None + * + * Public: No + */ + +params ["_unit", "_set", ["_skipSetHidden", false]]; +TRACE_3("setStatusEffect",_unit,_set,_skipSetHidden); + +// Block radio on unconsciousness for compatibility with captive module +[_unit, "blockRadio", "ace_unconscious", _set] call EFUNC(common,statusEffect_set); + +// Block speaking on unconsciousness +[_unit, "blockSpeaking", "ace_unconscious", _set] call EFUNC(common,statusEffect_set); + +if (_skipSetHidden) exitWith {}; + +// Stop AI firing at unconscious units in most situations (global effect) +[_unit, "setHidden", "ace_unconscious", _set] call EFUNC(common,statusEffect_set); diff --git a/addons/medical_status/functions/fnc_setUnconscious.sqf b/addons/medical_status/functions/fnc_setUnconscious.sqf deleted file mode 100644 index 07d67b7af6..0000000000 --- a/addons/medical_status/functions/fnc_setUnconscious.sqf +++ /dev/null @@ -1,55 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Sets a unit in the unconscious state. - * For Internal Use: Called from the state machine. - * - * Arguments: - * 0: The unit that will be put in an unconscious state - * 1: Set unconscious - * - * Return Value: - * Success - * - * Example: - * [player, true] call ace_medical_status_fnc_setUnconscious - * - * Public: No - */ - -params ["_unit", "_active"]; - -// No change to make -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 { - 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 { - if (visibleMap) then {openMap false}; - - while {dialog} do { - closeDialog 0; - }; - }; -} else { - // Unit has woken up, no longer need to track this - _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; -}; - -// This event doesn't correspond to unconscious in statemachine -// It's for any time a unit changes consciousness (including cardiac arrest) -["ace_unconscious", [_unit, _active]] call CBA_fnc_globalEvent; diff --git a/addons/medical_status/functions/fnc_setUnconsciousState.sqf b/addons/medical_status/functions/fnc_setUnconsciousState.sqf new file mode 100644 index 0000000000..5981343c18 --- /dev/null +++ b/addons/medical_status/functions/fnc_setUnconsciousState.sqf @@ -0,0 +1,77 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal + * Sets a unit in the unconscious state. + * For Internal Use: Called from the state machine. + * + * Arguments: + * 0: The unit that will be put in an unconscious state + * 1: Set unconscious + * + * Return Value: + * None + * + * 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) || {!alive _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); + +// Handle hiding from AI and talking blocks. +[_unit, _active] call FUNC(setStatusEffects); + +if (_active) then { + // Don't bother setting this if not used + if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { + 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 { + if (visibleMap) then {openMap false}; + + while {dialog} do { + closeDialog 0; + }; + + if (EGVAR(medical,dropWeaponUnconsciousChance) != 0 && {random 1 <= EGVAR(medical,dropWeaponUnconsciousChance)}) then { + _unit call EFUNC(common,throwWeapon); + }; + }; + + // Unlock controls for copilot if unit is pilot of aircraft + if (vehicle _unit isKindOf "Air" && {_unit == driver vehicle _unit}) then { + TRACE_1("pilot of air vehicle - unlocking controls",vehicle _unit); + // Do "Unlock controls" user action, co-pilot will then have to do the "Take Controls" actions + _unit action ["UnlockVehicleControl", vehicle _unit]; + }; + + // Disable AI talking (yes, this needs to be explicit) + if (!isPlayer _unit && {_unit checkAIFeature "RADIOPROTOCOL"}) then { + _unit disableAI "RADIOPROTOCOL"; + _unit setVariable [QGVAR(reenableRadioProtocol), true, true]; + }; +} else { + // Unit has woken up, no longer need to track this + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; + + if (_unit getVariable [QGVAR(reenableRadioProtocol), false]) then { + _unit enableAI "RADIOPROTOCOL"; + }; +}; + +// This event doesn't correspond to unconscious in statemachine +// It's for any time a unit changes consciousness (including cardiac arrest) +["ace_unconscious", [_unit, _active]] call CBA_fnc_globalEvent; diff --git a/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf b/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf index fe38aabadc..8696349642 100644 --- a/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Update total wound bleeding based on open wounds and tourniquets @@ -21,9 +21,12 @@ params ["_unit"]; private _tourniquets = GET_TOURNIQUETS(_unit); private _bodyPartBleeding = [0,0,0,0,0,0]; { - _x params ["", "_bodyPart", "_amountOf", "_bleeeding"]; - if (_tourniquets select _bodyPart == 0) then { - _bodyPartBleeding set [_bodyPart, (_bodyPartBleeding select _bodyPart) + (_amountOf * _bleeeding)]; + private _partIndex = ALL_BODY_PARTS find _x; + if (_tourniquets select _partIndex == 0) then { + { + _x params ["", "_amountOf", "_bleeeding"]; + _bodyPartBleeding set [_partIndex, (_bodyPartBleeding select _partIndex) + (_amountOf * _bleeeding)]; + } forEach _y; }; } forEach GET_OPEN_WOUNDS(_unit); diff --git a/addons/medical_status/functions/script_component.hpp b/addons/medical_status/functions/script_component.hpp deleted file mode 100644 index 9b83bfbc4f..0000000000 --- a/addons/medical_status/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_status\script_component.hpp" diff --git a/addons/medical_status/initSettings.inc.sqf b/addons/medical_status/initSettings.inc.sqf new file mode 100644 index 0000000000..849b10ef8c --- /dev/null +++ b/addons/medical_status/initSettings.inc.sqf @@ -0,0 +1,35 @@ +[ + QEGVAR(medical,bleedingCoefficient), + "SLIDER", + [LSTRING(BleedingCoefficient_DisplayName), LSTRING(BleedingCoefficient_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,painCoefficient), + "SLIDER", + [LSTRING(PainCoefficient_DisplayName), LSTRING(PainCoefficient_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,ivFlowRate), + "SLIDER", + [LSTRING(IvFlowRate_DisplayName), LSTRING(IvFlowRate_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,dropWeaponUnconsciousChance), + "SLIDER", + [LSTRING(DropWeaponUnconsciousChance_DisplayName), LSTRING(DropWeaponUnconsciousChance_Description)], + ELSTRING(medical,Category), + [0, 1, 0, 2, true], + true +] call CBA_fnc_addSetting; diff --git a/addons/medical_status/initSettings.sqf b/addons/medical_status/initSettings.sqf deleted file mode 100644 index 95231b0acc..0000000000 --- a/addons/medical_status/initSettings.sqf +++ /dev/null @@ -1,26 +0,0 @@ -[ - 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)], - [ELSTRING(medical,Category), LSTRING(SubCategory)], - [0, 25, 1, 1], - true -] call CBA_settings_fnc_init; - -[ - 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 1bbea55902..ea3f77429b 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -6,22 +6,33 @@ Zustand 状態 Статус + Statut + Status + 狀態 + 状态 + Stato + Stav + Status + Estado + Durum + 결과 상태 Bleeding Coefficient - Коэффициент кровопотери + Коэф. кровопотери Mnożnik krwawienia Coeficiente de sangrado Verblutungsmultiplikator Koeficient krvácení Coeficiente de sangramento - Coéfficient de saignement + Coefficient de saignement Vérzési koefficiens Coefficiente sanguinamento 出血の係数 출혈 계수 流血系数 流血係數 + Kanama Katsayısı Coefficient for controlling the bleeding speed. @@ -31,29 +42,31 @@ Multiplikator um die Verblutungsgeschwindigkeit zu verändern Koeficient rychlosti krvácení Coeficiente para modificar a velocidade do sangramento - Modifie le débit des saignements + 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 この係数では出血速度を変更できます 출혈의 속도를 계수만큼 변경합니다 修改流血速度 修改流血速度 + Kanama hızını kontrol etme katsayısı. Pain Coefficient - Коэффициент боли + Коэф. боли Mnożnik bólu Coeficiente de dolor Schmerzmultiplikator Koeficient bolesti Coeficiente de dor - Coéfficient de douleur + Coefficient de douleur Fájdalmi koefficiens Coefficiente dolore 痛みの係数 고통 계수 疼痛系数 疼痛係數 + Ağrı Katsayısı Coefficient for controlling the intensity of pain adjustments. @@ -62,26 +75,69 @@ 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 + Coeficiente para modificar a intensidade 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 この係数では痛みの強さを変更できます 고통의 정도를 계수만큼 변경합니다 修改疼痛强度的系数 修改疼痛強度的係數 + Ağrı ayarlamalarının yoğunluğunu kontrol etmek için katsayı. IV Transfusion Flow Rate Transfusions Fließrate - IV 輸血の流量 + IV 輸液の流量 Скорость внутривенного переливания + Débit de transfusion IV + Velocidade de Transferência de Sangue + 點滴輸血流量 + 点滴输血流量 + Velocità di trasfusione EV + Rychlost IV transfuze + Natężenie Przepływu Transfuzji IV + IV Flujo de transfusión + IV Transfüzyon Akış Hızı + 수혈 속도 Controls how quickly fluid flows out of IV Bags. The IV Bag volume change is calculated as:\ntime interval (s) * iv change per second (4.1667 mL/s) * flow rate (this coefficient). Wie schnell der Effekt der Transfusion eintritt - IV による輸血速度を変更できます - Определяет, насколько быстро подействуют эффекты внутривенного переливания + IV 輸液パックから輸液が流出する速度を制御します。 IV 輸液バッグの容量変化は次のように計算されます:\n時間間隔(秒) x 点滴速度毎秒(4.1667 mL/秒) x 流量(この係数) + Определяет, насколько быстро подействуют эффекты внутривенного переливания как:\nвременной интервал (s) * изменение внутривенного вливания в секунду (4,1667 мл/с) * скорость потока (этот коэффициент). + Définit la vitesse à laquelle le liquide s'écoule des poches de perfusion.\nLa variation du volume de poche IV est calculée selon la formule suivante :\n intervalle de temps (s) * variation IV par seconde (4,1667 ml/s) * débit (ce coefficient). + Controla o quão rápido fluidos são extraídos de bolsas de IV. A mudança no volume da bolsa d IV é calculado assim:\nIntervalo de tempo (s) * mudança de iv por segundo (4.1667 mL/s) * Velocidade de transferência (esse valor) + 控制從點滴輸入人體的液體流量多快。點滴的體積更改是以\n時間間隔(單位秒)乘上點滴每秒速度(4.1667毫升/秒)乘上流量(該係數)。 + 控制从点滴输入人体的液体流量多快。静脉输液袋容积变化的计算方法是:\n时间间隔(秒)x点滴每秒速度(4.1667毫升/秒)x流量(该系数)。 + Determina la velocità con cui il fluido esce dalle sacche per flebo. La variazione di volume delle sacche EV è calcolata come:\intervallo di tempo (s) * variazione EV al secondo (4,1667 mL/s) * velocità (questo coefficiente). + Nastavuje jak rychle tekutiny vytékají z IV sáčku. Zbývající objem IV sáčku je vypočítáván následovně:\nčasový interval (s) * změna iv za sekundu (4,1667 mL/s) * rychlost toku (tento koeficient). + Kontroluje, jak szybko płyn wypływa z worków IV. Zmiana objętości worka IV jest obliczana jako:\n przedział czasowy * zmiana iv na sekundę (4,1667 mL/s) * natężenie przepływu (ten współczynnik). + Controla la rapidez con que fluye el líquido de las bolsas intravenosas. El cambio de volumen de la bolsa IV se calcula como: \n intervalo (s) de tiempo * cambio iv por segundo (4.1667 mL/s) * velocidad de flujo (este coeficiente). + IV Torbalardan sıvının ne kadar hızlı aktığını kontrol eder. IV Torba hacim değişikliği şu şekilde hesaplanır: zaman aralıkları iv saniye başına değişim (4.1667 mL / s) akış hızı (bu katsayı). + 수액용기에서 액체가 얼마나 빠르게 흘러들어가는지를 제어합니다. 수액용기 부피 변화는 다음과 같이 계산됩니다:\n시간 간격 (초) x 초 당 수액 변화량(4.1667mL/s) x 흘러들어가는 양 (해당 계수). + + + Weapon Drop Chance + Szansa Upuszczenia Broni + Wahrscheinlichkeit, die Waffe fallen zu lassen + Probabilità di far cadere l'arma + 무기 떨어뜨릴 확률 + Risque de perte d'arme + 武器を落とす確率 + Шанс выпадения оружия + Probabilidad de Soltar Arma + + + Chance for a player to drop their weapon when going unconscious.\nHas no effect on AI. + Szansa na upuszczenie broni przez gracza, przy utracie przytomności. \nNie ma wpływu na AI. + Chance für einen Spieler, seine Waffe fallen zu lassen, wenn er bewusstlos wird.\nHat keine Auswirkung auf die KI. + Probabilità che un giocatore faccia cadere l'arma attualmente selezionata quando sviene.\nNon ha effetto sulle IA. + 플레이어가 기절할 때 무기를 떨어뜨릴 확률입니다.\nAI는 영향을 받지 않습니다. + Pourcentage de chances pour un joueur de lâcher son arme lorsqu'il perd connaissance.\nAucun effet sur les IA. + プレーヤーが意識を失ったときに武器を落とす可能性。\nAI には影響しません。 + Шанс для игрока выронить свое оружие, когда он теряет сознание.\nНе влияет на ИИ + Probabilidad del jugador de soltar su arma cuando quedan inconscientes.\nNo tiene efecto sobre la IA. diff --git a/addons/medical_treatment/ACE_Medical_Facilities.hpp b/addons/medical_treatment/ACE_Medical_Facilities.hpp index 32ab19d233..443fa93d17 100644 --- a/addons/medical_treatment/ACE_Medical_Facilities.hpp +++ b/addons/medical_treatment/ACE_Medical_Facilities.hpp @@ -23,4 +23,9 @@ class EGVAR(medical,facilities) { "RU_WarfareBFieldhHospital", "USMC_WarfareBFieldhHospital" }; + GM[] = { + "gm_ge_army_shelteraceI_medic", + "gm_ge_army_shelteraceII_medic", + "gm_gc_army_shelterlakII_medic" + }; }; diff --git a/addons/medical_treatment/ACE_Medical_Treatment.hpp b/addons/medical_treatment/ACE_Medical_Treatment.hpp index 19181287a8..267a45dd44 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment.hpp @@ -154,7 +154,7 @@ class ADDON { }; }; - class PackingBandage: fieldDressing { + class PackingBandage: FieldDressing { class Abrasion { effectiveness = 3; reopeningChance = 0.6; @@ -289,7 +289,7 @@ class ADDON { }; }; - class ElasticBandage: fieldDressing { + class ElasticBandage: FieldDressing { class Abrasion { effectiveness = 4; reopeningChance = 0.6; @@ -297,7 +297,7 @@ class ADDON { reopeningMaxDelay = 150; }; class AbrasionMinor: Abrasion { - effectiveness = 43; + effectiveness = 4; }; class AbrasionMedium: Abrasion { effectiveness = 3; @@ -424,7 +424,7 @@ class ADDON { }; }; - class QuikClot: fieldDressing { + class QuikClot: FieldDressing { class Abrasion { effectiveness = 2; reopeningChance = 0.3; @@ -440,7 +440,7 @@ class ADDON { }; class AbrasionLarge: Abrasion { effectiveness = 0.7; - reopeningChance = 5; + reopeningChance = 0.5; }; class Avulsion: Abrasion { @@ -494,7 +494,6 @@ class ADDON { }; class CutMinor: Cut { effectiveness = 2; - reopeningChance = 0.3; }; class CutMedium: Cut { effectiveness = 1; @@ -566,8 +565,11 @@ class ADDON { timeInSystem = 120; // How long until the maximum effect is reached timeTillMaxEffect = 30; - // How many of this type of medication can be in the system before the patient overdoses? + // How many of this type of medication can be in the system before the patient can possibly overdose? maxDose = 4; + // The number of doses over maxDose where there is a chance to overdose. + // Example with maxDose = 4 and maxDoseDeviation = 2: Dose 4: Safe | Dose 5 and 6: Possible overdose | Dose 7: Guaranteed overdose + maxDoseDeviation = 2; // Function to execute upon overdose. Arguments passed to call back are 0: unit , 1: medicationClassName onOverDose = ""; // The viscosity of a fluid is a measure of its resistance to gradual deformation by shear stress or tensile stress. For liquids, it corresponds to the informal concept of "thickness". This value will increase/decrease the viscoty of the blood with the percentage given. Where 100 = max. Using the minus will decrease viscosity @@ -592,7 +594,7 @@ class ADDON { hrIncreaseHigh[] = {10, 40}; timeInSystem = 120; timeTillMaxEffect = 10; - maxDose = 10; + maxDose = 9; incompatibleMedication[] = {}; }; class Adenosine { @@ -602,24 +604,17 @@ class ADDON { hrIncreaseHigh[] = {-15, -35}; timeInSystem = 120; timeTillMaxEffect = 15; - maxDose = 6; - incompatibleMedication[] = {}; - }; - class Atropine { - painReduce = 0; - hrIncreaseLow[] = {-2, -5}; - hrIncreaseNormal[] = {-10, -15}; - hrIncreaseHigh[] = {-5, -20}; - timeInSystem = 120; - timeTillMaxEffect = 15; - maxDose = 6; + maxDose = 5; incompatibleMedication[] = {}; }; class PainKillers { - painReduce = 0.1; - timeInSystem = 600; + painReduce = 0.35; + hrIncreaseLow[] = {-5, -10}; + hrIncreaseNormal[] = {-5, -15}; + hrIncreaseHigh[] = {-5, -17}; + timeInSystem = 420; timeTillMaxEffect = 60; - maxDose = 10; + maxDose = 5; incompatibleMedication[] = {}; viscosityChange = 5; }; diff --git a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp index 950d1a2e29..4058132e3d 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp @@ -79,10 +79,11 @@ class GVAR(actions) { icon = QPATHTOEF(medical_gui,ui\tourniquet.paa); allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; items[] = {"ACE_tourniquet"}; - treatmentTime = 7; + treatmentTime = QGVAR(treatmentTimeTourniquet); condition = QUOTE(!([ARR_2(_patient,_bodyPart)] call FUNC(hasTourniquetAppliedTo))); callbackSuccess = QFUNC(tourniquet); litter[] = {}; + allowedUnderwater = 1; }; class RemoveTourniquet: ApplyTourniquet { displayName = CSTRING(Actions_RemoveTourniquet); @@ -90,6 +91,7 @@ class GVAR(actions) { items[] = {}; condition = QUOTE([ARR_2(_patient,_bodyPart)] call FUNC(hasTourniquetAppliedTo)); callbackSuccess = QFUNC(tourniquetRemove); + allowedUnderwater = 1; }; // - Splint --------------------------------------------------------------- @@ -100,7 +102,7 @@ class GVAR(actions) { icon = QPATHTOEF(medical_gui,ui\splint.paa); allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; items[] = {"ACE_splint"}; - treatmentTime = 7; + treatmentTime = QGVAR(treatmentTimeSplint); callbackSuccess = QFUNC(splint); condition = QFUNC(canSplint); litter[] = { @@ -117,7 +119,7 @@ class GVAR(actions) { category = "medication"; items[] = {"ACE_morphine"}; condition = ""; - treatmentTime = 5; + treatmentTime = QGVAR(treatmentTimeAutoinjector); callbackSuccess = QFUNC(medication); animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; sounds[] = {{QPATHTO_R(sounds\Inject.ogg),1,1,50}}; @@ -130,13 +132,6 @@ class GVAR(actions) { items[] = {"ACE_adenosine"}; litter[] = {{"ACE_MedicalLitter_adenosine"}}; }; - class Atropine: Morphine { - displayName = CSTRING(Inject_Atropine); - displayNameProgress = CSTRING(Injecting_Atropine); - condition = QGVAR(advancedMedication); - items[] = {"ACE_atropine"}; - litter[] = {{"ACE_MedicalLitter_atropine"}}; - }; class Epinephrine: Morphine { displayName = CSTRING(Inject_Epinephrine); displayNameProgress = CSTRING(Injecting_Epinephrine); @@ -146,6 +141,19 @@ class GVAR(actions) { litter[] = {{"ACE_MedicalLitter_epinephrine"}}; }; + // - Generic Medication --------------------------------------------------- + class Painkillers: Morphine { + displayName = CSTRING(Administer_Painkillers); + displayNameProgress = CSTRING(Administering_Painkillers); + icon = QPATHTOEF(medical_gui,ui\painkillers.paa); + allowedSelections[] = {"Head"}; + medicRequired = 0; + items[] = {"ACE_painkillers"}; + treatmentTime = 4; + sounds[] = {{QPATHTO_R(sounds\Pills.ogg),1,1,50}}; + litter[] = {{"Land_PainKillers_F"}}; // just use BI's model as litter + }; + // - IV Bags -------------------------------------------------------------- class BloodIV: BasicBandage { displayName = CSTRING(Actions_Blood4_1000); @@ -154,9 +162,10 @@ class GVAR(actions) { allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; allowSelfTreatment = QGVAR(allowSelfIV); category = "advanced"; - medicRequired = 1; - treatmentTime = 12; + medicRequired = QGVAR(medicIV); + treatmentTime = QGVAR(treatmentTimeIV); items[] = {"ACE_bloodIV"}; + treatmentLocations = QGVAR(locationIV); condition = ""; callbackSuccess = QFUNC(ivBag); animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; @@ -210,7 +219,7 @@ class GVAR(actions) { medicRequired = 0; treatmentTime = 2.5; items[] = {}; - condition = QUOTE(!GVAR(advancedDiagnose)); + condition = QUOTE(GVAR(advancedDiagnose) == 0); callbackSuccess = QFUNC(diagnose); callbackFailure = ""; callbackProgress = ""; @@ -222,7 +231,7 @@ class GVAR(actions) { displayName = CSTRING(Actions_CheckPulse); displayNameProgress = CSTRING(Check_Pulse_Content); allowedSelections[] = {"All"}; - condition = QGVAR(advancedDiagnose); + condition = QUOTE(GVAR(advancedDiagnose) != 0); callbackSuccess = QFUNC(checkPulse); animationMedicProne = ""; animationMedicSelfProne = ""; @@ -243,20 +252,38 @@ class GVAR(actions) { // - Misc ----------------------------------------------------------------- class BodyBag: BasicBandage { - displayName = CSTRING(PlaceInBodyBag); + displayName = CSTRING(PlaceInBodyBagBlack); displayNameProgress = CSTRING(PlacingInBodyBag); icon = QPATHTOEF(medical_gui,ui\bodybag.paa); category = "advanced"; treatmentLocations = TREATMENT_LOCATIONS_ALL; allowSelfTreatment = 0; medicRequired = 0; - treatmentTime = 15; + treatmentTime = QGVAR(treatmentTimeBodyBag); items[] = {"ACE_bodyBag"}; - condition = QUOTE(!alive _patient); + condition = QFUNC(canPlaceInBodyBag); callbackSuccess = QFUNC(placeInBodyBag); consumeItem = 1; litter[] = {}; }; + class BodyBagBlue: BodyBag { + displayName = CSTRING(PlaceInBodyBagBlue); + items[] = {"ACE_bodyBag_blue"}; + }; + class BodyBagWhite: BodyBag { + displayName = CSTRING(PlaceInBodyBagWhite); + items[] = {"ACE_bodyBag_white"}; + }; + class Grave: BodyBag { + displayName = CSTRING(DigGrave); + displayNameProgress = CSTRING(DiggingGrave); + icon = QPATHTOEF(medical_gui,ui\grave.paa); + treatmentTime = QGVAR(treatmentTimeGrave); + condition = QFUNC(canDigGrave); + callbackSuccess = QFUNC(placeInGrave); + items[] = {}; + consumeItem = 0; + }; class CPR: BasicBandage { displayName = CSTRING(Actions_CPR); displayNameProgress = CSTRING(Actions_PerformingCPR); @@ -266,7 +293,7 @@ class GVAR(actions) { allowedSelections[] = {"Body"}; allowSelfTreatment = 0; medicRequired = 0; - treatmentTime = 15; + treatmentTime = QGVAR(treatmentTimeCPR); items[] = {}; condition = QFUNC(canCPR); callbackSuccess = QFUNC(cprSuccess); @@ -292,8 +319,9 @@ class GVAR(actions) { treatmentTime = QFUNC(getStitchTime); condition = QFUNC(canStitch); callbackSuccess = ""; + callbackStart = QFUNC(surgicalKitStart); callbackProgress = QFUNC(surgicalKitProgress); - consumeItem = QGVAR(consumeSurgicalKit); + consumeItem = QGVAR(consumeSurgicalKit); // setting can be 0,1,2 - only 1 will consume items[] animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; litter[] = {{"ACE_MedicalLitter_gloves"}}; }; @@ -305,6 +333,7 @@ class GVAR(actions) { condition = QUOTE(_patient call EFUNC(medical_status,isInStableCondition)); items[] = {"ACE_personalAidKit"}; treatmentLocations = QGVAR(locationPAK); + allowSelfTreatment = QGVAR(allowSelfPAK); medicRequired = QGVAR(medicPAK); treatmentTime = QFUNC(getHealTime); callbackSuccess = QFUNC(fullHeal); diff --git a/addons/medical_treatment/Cfg3DEN.hpp b/addons/medical_treatment/Cfg3DEN.hpp index 04c3fc3efd..0df2b498e6 100644 --- a/addons/medical_treatment/Cfg3DEN.hpp +++ b/addons/medical_treatment/Cfg3DEN.hpp @@ -23,9 +23,9 @@ class Cfg3DEN { class Title: Title {}; class Value: ctrlToolbox { idc = 100; - x = 48 * GRID_3DEN_W; - w = 82 * GRID_3DEN_W; - h = 5 * GRID_3DEN_H; + x = QUOTE(48 * GRID_3DEN_W); + w = QUOTE(82 * GRID_3DEN_W); + h = QUOTE(5 * GRID_3DEN_H); rows = 1; columns = 4; strings[] = { diff --git a/addons/medical_treatment/CfgEventHandlers.hpp b/addons/medical_treatment/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/medical_treatment/CfgEventHandlers.hpp +++ b/addons/medical_treatment/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/medical_treatment/CfgMagazines.hpp b/addons/medical_treatment/CfgMagazines.hpp new file mode 100644 index 0000000000..c4daafab76 --- /dev/null +++ b/addons/medical_treatment/CfgMagazines.hpp @@ -0,0 +1,16 @@ +class CfgMagazines { + class CA_Magazine; + class ACE_painkillers: CA_Magazine { + scope = 2; + author = ECSTRING(common,ACETeam); + displayName = CSTRING(painkillers_Display); + model = "\A3\Structures_F_EPA\Items\Medical\PainKillers_F.p3d"; + picture = QPATHTOF(ui\painkillers_ca.paa); + descriptionShort = CSTRING(painkillers_Desc_Short); + descriptionUse = CSTRING(painkillers_Desc_Use); + ACE_isMedicalItem = 1; + ACE_asItem = 1; + count = 10; + mass = 1; + }; +}; diff --git a/addons/medical_treatment/CfgReplacementItems.hpp b/addons/medical_treatment/CfgReplacementItems.hpp index 295935e055..16a45d01cc 100644 --- a/addons/medical_treatment/CfgReplacementItems.hpp +++ b/addons/medical_treatment/CfgReplacementItems.hpp @@ -1,11 +1,14 @@ +// 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) { - FirstAidKit[] = { + DOUBLES(ItemType,TYPE_FIRST_AID_KIT)[] = { {"ACE_fieldDressing", 1}, {"ACE_packingBandage", 1}, {"ACE_morphine", 1}, {"ACE_tourniquet", 1} }; - Medikit[] = { + DOUBLES(ItemType,TYPE_MEDIKIT)[] = { {"ACE_fieldDressing", 1}, {"ACE_packingBandage", 2}, {"ACE_epinephrine", 1}, @@ -14,5 +17,7 @@ class EGVAR(medical,replacementItems) { {"ACE_tourniquet", 1}, {"ACE_splint", 2} }; - // todo: add GM medical items + ACE_atropine[] = { + {"ACE_adenosine", 1} + }; }; diff --git a/addons/medical_treatment/CfgVehicles.hpp b/addons/medical_treatment/CfgVehicles.hpp index d7e0ed50d3..4f922eb199 100644 --- a/addons/medical_treatment/CfgVehicles.hpp +++ b/addons/medical_treatment/CfgVehicles.hpp @@ -7,19 +7,20 @@ class CfgVehicles { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + displayName = "$STR_a3_cfgvehicles_land_bodybag_01_black_f0"; scope = 1; - scopeCurator = 2; + scopeCurator = 1; side = -1; - model = QPATHTOEF(apl,ace_bodybag.p3d); icon = ""; - displayName = CSTRING(Bodybag_Display); EGVAR(dragging,canDrag) = 1; EGVAR(dragging,dragPosition)[] = {0,1.2,0}; EGVAR(dragging,dragDirection) = 0; EGVAR(cargo,size) = 1; EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; + model = "\A3\Props_F_Orange\Humanitarian\Camps\Bodybag_01_F.p3d"; hiddenSelections[] = {"camo"}; - hiddenSelectionsTextures[] = {QPATHTOEF(apl,data\bodybag_co.paa)}; + hiddenSelectionsTextures[] = {"\A3\Props_F_Orange\Humanitarian\Camps\Data\Bodybag_01_black_CO.paa"}; class ACE_Actions { class ACE_MainActions { displayName = ECSTRING(interaction,MainAction); @@ -28,9 +29,38 @@ class CfgVehicles { statement = ""; icon = "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa"; selection = ""; + class GVAR(buryBodyBag) { + displayName = CSTRING(DigGrave); + condition = QUOTE([ARR_2(_this#1,_this#0)] call FUNC(canDigGrave)); + statement = QUOTE(_this call FUNC(placeBodyBagInGrave)); + icon = QPATHTOEF(medical_gui,ui\grave.paa); + }; }; }; }; + class ACE_bodyBagObject_blue: ACE_bodyBagObject { + displayName = "$STR_a3_cfgvehicles_land_bodybag_01_blue_f0"; + hiddenSelectionsTextures[] = {"\A3\Props_F_Orange\Humanitarian\Camps\Data\Bodybag_01_blue_CO.paa"}; + }; + class ACE_bodyBagObject_white: ACE_bodyBagObject { + displayName = "$STR_a3_cfgvehicles_land_bodybag_01_white_f0"; + hiddenSelectionsTextures[] = {"\A3\Props_F_Orange\Humanitarian\Camps\Data\Bodybag_01_white_CO.paa"}; + }; + class ACE_bodyBagObject_old: ACE_bodyBagObject { + displayName = CSTRING(Bodybag_Display); + model = QPATHTOEF(apl,ace_bodybag.p3d); + hiddenSelections[] = {"camo"}; + hiddenSelectionsTextures[] = {QPATHTOEF(apl,data\bodybag_co.paa)}; + }; + + // Grave vehicle + class Land_Grave_dirt_F; + class ACE_Grave: Land_Grave_dirt_F { + model = QPATHTOF(data\ACE_grave.p3d); + hiddenSelections[] = {"camo"}; + hiddenSelectionsTextures[] = {QPATHTOF(data\Grave_co.paa)}; + }; + // Medical litter classes class Thing; @@ -77,6 +107,9 @@ class CfgVehicles { class ACE_MedicalLitter_splint: ACE_MedicalLitterBase { model = QPATHTOF(data\littergeneric_splint.p3d); }; + class ACE_MedicalLitter_suture: ACE_MedicalLitterBase { + model = QPATHTOF(data\littergeneric_suture.p3d); + }; // Treatment items class Item_Base_F; @@ -151,8 +184,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"; @@ -231,6 +264,16 @@ class CfgVehicles { MACRO_ADDITEM(ACE_surgicalKit,1); }; }; + class ACE_sutureItem: Item_Base_F { + scope = 2; + scopeCurator = 2; + displayName = CSTRING(Suture_Display); + author = ECSTRING(common,ACETeam); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_suture,1); + }; + }; class ACE_bodyBagItem: Item_Base_F { scope = 2; scopeCurator = 2; @@ -241,6 +284,16 @@ class CfgVehicles { MACRO_ADDITEM(ACE_bodyBag,1); }; }; + class ACE_painkillersItem: Item_Base_F { + scope = 2; + scopeCurator = 2; + displayName = CSTRING(painkillers_Display); + author = "Alganthe"; + vehicleClass = "Items"; + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,1); + }; + }; // Medical supply crates class ThingX; @@ -258,7 +311,11 @@ class CfgVehicles { accuracy = 1000; displayName = CSTRING(medicalSupplyCrate); model = QPATHTOF(data\ace_medcrate.p3d); + editorPreview = QPATHTOF(data\ACE_medicalSupplyCrate.jpg); author = ECSTRING(common,ACETeam); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,25); + }; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,50); MACRO_ADDITEM(ACE_morphine,25); @@ -266,6 +323,8 @@ class CfgVehicles { MACRO_ADDITEM(ACE_bloodIV,15); MACRO_ADDITEM(ACE_bloodIV_500,15); MACRO_ADDITEM(ACE_bloodIV_250,15); + MACRO_ADDITEM(ACE_tourniquet,10); + MACRO_ADDITEM(ACE_splint,10); MACRO_ADDITEM(ACE_bodyBag,10); }; class AnimationSources { @@ -284,14 +343,14 @@ class CfgVehicles { class ACE_OpenLid { displayName = ECSTRING(medical,openLid); condition = QUOTE(alive _target && {_target animationPhase 'Cover' < 0.5}); - statement = QUOTE(_target animate ARR_2(['Cover',1])); + statement = QUOTE(_target animate [ARR_2('Cover',1)]); showDisabled = 0; priority = -1; }; class ACE_CloseLid { displayName = ECSTRING(medical,closeLid); condition = QUOTE(alive _target && {_target animationPhase 'Cover' >= 0.5}); - statement = QUOTE(_target animate ARR_2(['Cover',0])); + statement = QUOTE(_target animate [ARR_2('Cover',0)]); showDisabled = 0; priority = -1; }; @@ -300,6 +359,9 @@ class CfgVehicles { }; class ACE_medicalSupplyCrate_advanced: ACE_medicalSupplyCrate { displayName = CSTRING(medicalSupplyCrate_advanced); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,15); + }; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,25); MACRO_ADDITEM(ACE_packingBandage,25); @@ -308,7 +370,6 @@ class CfgVehicles { 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); @@ -323,6 +384,17 @@ class CfgVehicles { MACRO_ADDITEM(ACE_personalAidKit,3); MACRO_ADDITEM(ACE_surgicalKit,2); MACRO_ADDITEM(ACE_bodyBag,5); + MACRO_ADDITEM(ACE_suture,60); }; }; + + class Van_02_base_F; + class Van_02_medevac_base_F: Van_02_base_F { + GVAR(patientSeats)[] = {3,4}; + }; + + class Heli_Transport_04_base_F; + class O_Heli_Transport_04_medevac_F: Heli_Transport_04_base_F { + GVAR(patientSeats)[] = {0,1,2}; + }; }; diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index afbf3faa4a..7b31e10bee 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -8,12 +8,14 @@ class CfgWeapons { class FirstAidKit: ItemCore { type = 0; + ACE_isMedicalItem = 1; class ItemInfo: InventoryFirstAidKitItem_Base_F { mass = 4; }; }; class Medikit: ItemCore { type = 0; + ACE_isMedicalItem = 1; class ItemInfo: MedikitItem { mass = 60; }; @@ -27,8 +29,9 @@ class CfgWeapons { displayName = CSTRING(Bandage_Basic_Display); descriptionShort = CSTRING(Bandage_Basic_Desc_Short); descriptionUse = CSTRING(Bandage_Basic_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 0.6; }; }; class ACE_packingBandage: ACE_ItemCore { @@ -39,8 +42,9 @@ class CfgWeapons { model = QPATHTOF(data\packingbandage.p3d); descriptionShort = CSTRING(Packing_Bandage_Desc_Short); descriptionUse = CSTRING(Packing_Bandage_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 0.6; }; }; class ACE_elasticBandage: ACE_ItemCore { @@ -51,8 +55,9 @@ class CfgWeapons { model = "\A3\Structures_F_EPA\Items\Medical\Bandage_F.p3d"; descriptionShort = CSTRING(Bandage_Elastic_Desc_Short); descriptionUse = CSTRING(Bandage_Elastic_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 0.6; }; }; class ACE_tourniquet: ACE_ItemCore { @@ -63,8 +68,9 @@ class CfgWeapons { model = QPATHTOF(data\tourniquet.p3d); descriptionShort = CSTRING(Tourniquet_Desc_Short); descriptionUse = CSTRING(Tourniquet_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_splint: ACE_ItemCore { @@ -74,6 +80,7 @@ class CfgWeapons { picture = QPATHTOF(ui\splint_ca.paa); model = QPATHTOF(data\splint.p3d); descriptionShort = CSTRING(splint_Desc_Short); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; @@ -86,8 +93,9 @@ class CfgWeapons { model = QPATHTOF(data\morphine.p3d); descriptionShort = CSTRING(Morphine_Desc_Short); descriptionUse = CSTRING(Morphine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_adenosine: ACE_ItemCore { @@ -98,20 +106,22 @@ class CfgWeapons { model = QPATHTOF(data\adenosine.p3d); descriptionShort = CSTRING(adenosine_Desc_Short); descriptionUse = CSTRING(adenosine_Desc_Use); + ACE_isMedicalItem = 1; 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\atropine_ca.paa); model = QPATHTOF(data\atropine.p3d); descriptionShort = CSTRING(Atropine_Desc_Short); descriptionUse = CSTRING(Atropine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_epinephrine: ACE_ItemCore { @@ -122,8 +132,9 @@ class CfgWeapons { model = QPATHTOF(data\epinephrine.p3d); descriptionShort = CSTRING(Epinephrine_Desc_Short); descriptionUse = CSTRING(Epinephrine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; @@ -137,6 +148,7 @@ class CfgWeapons { picture = QPATHTOF(ui\plasmaIV_ca.paa); descriptionShort = CSTRING(Plasma_IV_Desc_Short); descriptionUse = CSTRING(Plasma_IV_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -167,6 +179,7 @@ class CfgWeapons { hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_1000ml_ca.paa)}; descriptionShort = CSTRING(Blood_IV_Desc_Short); descriptionUse = CSTRING(Blood_IV_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -197,6 +210,7 @@ class CfgWeapons { picture = QPATHTOF(ui\salineIV_ca.paa); descriptionShort = CSTRING(Saline_IV_Desc_Short); descriptionUse = CSTRING(Saline_IV_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -225,8 +239,9 @@ class CfgWeapons { picture = QPATHTOF(ui\quickclot_ca.paa); descriptionShort = CSTRING(QuikClot_Desc_Short); descriptionUse = CSTRING(QuikClot_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 0.6; }; }; class ACE_personalAidKit: ACE_ItemCore { @@ -236,6 +251,7 @@ class CfgWeapons { picture = QPATHTOF(ui\personal_aid_kit_ca.paa); descriptionShort = CSTRING(Aid_Kit_Desc_Short); descriptionUse = CSTRING(Aid_Kit_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -248,20 +264,50 @@ class CfgWeapons { picture = QPATHTOF(ui\surgicalKit_ca.paa); descriptionShort = CSTRING(SurgicalKit_Desc_Short); descriptionUse = CSTRING(SurgicalKit_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 15; }; }; + class ACE_suture: ACE_ItemCore { + scope = 2; + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Suture_Display); + model = QPATHTOF(data\suture.p3d); + picture = QPATHTOF(ui\suture_ca.paa); + descriptionShort = CSTRING(Suture_Desc_Short); + descriptionUse = CSTRING(Suture_Desc_Use); + ACE_isMedicalItem = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.1; + }; + }; class ACE_bodyBag: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); - displayName= CSTRING(Bodybag_Display); + displayName = "$STR_a3_cfgvehicles_land_bodybag_01_black_f0"; model = QPATHTOF(data\bodybagItem.p3d); picture = QPATHTOF(ui\bodybag_ca.paa); descriptionShort = CSTRING(Bodybag_Desc_Short); descriptionUse = CSTRING(Bodybag_Desc_Use); + ACE_isMedicalItem = 1; + GVAR(bodyBagObject) = "ACE_bodyBagObject"; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 7; }; }; + class ACE_bodyBag_blue: ACE_bodyBag { + displayName = "$STR_a3_cfgvehicles_land_bodybag_01_blue_f0"; + picture = QPATHTOF(ui\bodybag_blue_ca.paa); + hiddenSelections[] = {"camo"}; + hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_blue_co.paa)}; + GVAR(bodyBagObject) = "ACE_bodyBagObject_blue"; + }; + class ACE_bodyBag_white: ACE_bodyBag { + displayName = "$STR_a3_cfgvehicles_land_bodybag_01_white_f0"; + picture = QPATHTOF(ui\bodybag_white_ca.paa); + hiddenSelections[] = {"camo"}; + hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_white_co.paa)}; + GVAR(bodyBagObject) = "ACE_bodyBagObject_white"; + }; }; diff --git a/addons/medical_treatment/XEH_PREP.hpp b/addons/medical_treatment/XEH_PREP.hpp index 5b18bba14e..709c97952f 100644 --- a/addons/medical_treatment/XEH_PREP.hpp +++ b/addons/medical_treatment/XEH_PREP.hpp @@ -6,13 +6,16 @@ PREP(bandageLocal); PREP(bodyCleanupLoop); PREP(canBandage); PREP(canCPR); +PREP(canDigGrave); +PREP(canPlaceInBodyBag); PREP(canSplint); PREP(canStitch); PREP(canTreat); PREP(canTreatCached); +PREP(canTreat_holsterCheck); +PREP(canUnloadUnit); PREP(checkBloodPressure); PREP(checkBloodPressureLocal); -PREP(checkItems); PREP(checkPulse); PREP(checkPulseLocal); PREP(checkResponse); @@ -24,7 +27,7 @@ PREP(cprStart); PREP(createLitter); PREP(createLitterServer); PREP(diagnose); -PREP(findMostEffectiveWound); +PREP(findMostEffectiveWounds); PREP(fullHeal); PREP(fullHealLocal); PREP(getBandageTime); @@ -45,12 +48,17 @@ PREP(loadUnit); PREP(medication); PREP(medicationLocal); PREP(onMedicationUsage); +PREP(placeBodyBagInGrave); PREP(placeInBodyBag); +PREP(placeInBodyBagOrGrave); +PREP(placeInGrave); PREP(removeBody); +PREP(scanMedicalItems); PREP(setTriageStatus); PREP(splint); PREP(splintLocal); PREP(surgicalKitProgress); +PREP(surgicalKitStart); PREP(tourniquet); PREP(tourniquetLocal); PREP(tourniquetRemove); diff --git a/addons/medical_treatment/XEH_postInit.sqf b/addons/medical_treatment/XEH_postInit.sqf index 1896d8d9f1..4c7a780fc3 100644 --- a/addons/medical_treatment/XEH_postInit.sqf +++ b/addons/medical_treatment/XEH_postInit.sqf @@ -9,12 +9,8 @@ } forEach (_unit getVariable [QEGVAR(medical,allLogs), []]); _unit setVariable [QEGVAR(medical,allLogs), [], true]; - - [_unit] call FUNC(checkItems); }] call CBA_fnc_addEventHandler; -["loadout", LINKFUNC(checkItems)] call CBA_fnc_addPlayerEventHandler; - // Handle body removal and litter on server if (isServer) then { [QGVAR(createLitterServer), LINKFUNC(createLitterServer)] call CBA_fnc_addEventHandler; @@ -29,10 +25,76 @@ if (isServer) then { [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(placeInBodyBagOrGrave), LINKFUNC(placeInBodyBagOrGrave)] call CBA_fnc_addEventHandler; [QGVAR(splintLocal), LINKFUNC(splintLocal)] call CBA_fnc_addEventHandler; [QGVAR(tourniquetLocal), LINKFUNC(tourniquetLocal)] call CBA_fnc_addEventHandler; // Logging events [QGVAR(addToLog), LINKFUNC(addToLog)] call CBA_fnc_addEventHandler; [QGVAR(addToTriageCard), LINKFUNC(addToTriageCard)] call CBA_fnc_addEventHandler; + +// replace medical items with their ACE equivalents +["CBA_settingsInitialized", { + TRACE_1("CBA_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; + +if (["ace_trenches"] call EFUNC(common,isModLoaded)) then { + if (hasInterface) then { + private _checkHeadstoneAction = [ + QGVAR(checkHeadstone), + LLSTRING(checkHeadstoneName), + QPATHTOEF(medical_gui,ui\grave.paa), + { + [ + [_target getVariable QGVAR(headstoneData)], + true + ] call CBA_fnc_notify; + }, + {!isNil {_target getVariable QGVAR(headstoneData)}} + ] call EFUNC(interact_menu,createAction); + + [missionNameSpace getVariable [QGVAR(graveClassname), "ACE_Grave"], 0, [], _checkHeadstoneAction] call EFUNC(interact_menu,addActionToClass); + }; + + if (isServer) then { + ["ace_placedInBodyBag", { + params ["_target", "_restingPlace"]; + TRACE_2("ace_placedInBodyBag eh",_target,_restingPlace); + if (isNull _restingPlace) exitWith {}; + + private _targetName = ""; + if (_target isKindOf "ACE_bodyBagObject") then { + _targetName = _target getVariable [QGVAR(headstoneData), ""]; + } else { + _targetName = [_target, false, true] call EFUNC(common,getName); + }; + + if (_targetName == "") exitWith {}; + _restingPlace setVariable [QGVAR(headstoneData), _targetName, true]; + }] call CBA_fnc_addEventHandler; + }; +}; diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index 79949c2479..e6210a7372 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -6,33 +6,31 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +#define ARSENAL_CATEGORY_ICON (["\A3\ui_f\data\igui\cfg\actions\heal_ca.paa", QPATHTOEF(medical_gui,data\categories\bandage_fracture.paa)] select (["ace_medical_gui"] call EFUNC(common,isModLoaded))) // config to determine animation acceleration coefficient // adjusting these is trail and error // if the animation is cut of ingame, increase these values // if the unit idles too much, decrease them -GVAR(animDurations) = [] call CBA_fnc_createNamespace; - -{ - GVAR(animDurations) setVariable _x; -} forEach [ - ["AinvPknlMstpSlayWnonDnon_medic", 7.5], - ["AinvPpneMstpSlayWnonDnon_medic", 7], - ["AinvPknlMstpSlayWrflDnon_medic", 7], - ["AinvPpneMstpSlayWrflDnon_medic", 9.5], - ["AinvPknlMstpSlayWlnrDnon_medic", 9], - ["AinvPknlMstpSlayWpstDnon_medic", 9.5], - ["AinvPpneMstpSlayWpstDnon_medic", 10], - ["AinvPknlMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPpneMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPknlMstpSlayWrflDnon_medicOther", 7], - ["AinvPpneMstpSlayWrflDnon_medicOther", 9], - ["AinvPknlMstpSlayWlnrDnon_medicOther", 9], - ["AinvPknlMstpSlayWpstDnon_medicOther", 10], - ["AinvPpneMstpSlayWpstDnon_medicOther", 8.5], - ["AinvPknlMstpSnonWnonDnon_medic1", 10], - ["AinvPknlMstpSnonWnonDr_medic0", 12] +GVAR(animDurations) = createHashMapFromArray [ + ["ainvpknlmstpslaywnondnon_medic", 7.5], + ["ainvppnemstpslaywnondnon_medic", 7], + ["ainvpknlmstpslaywrfldnon_medic", 7], + ["ainvppnemstpslaywrfldnon_medic", 9.5], + ["ainvpknlmstpslaywlnrdnon_medic", 9], + ["ainvpknlmstpslaywpstdnon_medic", 9.5], + ["ainvppnemstpslaywpstdnon_medic", 10], + ["ainvpknlmstpslaywnondnon_medicother", 8.5], + ["ainvppnemstpslaywnondnon_medicother", 8.5], + ["ainvpknlmstpslaywrfldnon_medicother", 7], + ["ainvppnemstpslaywrfldnon_medicother", 9], + ["ainvpknlmstpslaywlnrdnon_medicother", 9], + ["ainvpknlmstpslaywpstdnon_medicother", 10], + ["ainvppnemstpslaywpstdnon_medicother", 8.5], + ["ainvpknlmstpsnonwnondnon_medic1", 10], + ["ainvpknlmstpsnonwnondr_medic0", 12] ]; // class names of medical facilities (config case) @@ -44,9 +42,9 @@ GVAR(facilityClasses) = []; } forEach getArray _x; } forEach configProperties [configFile >> QEGVAR(medical,facilities), "isArray _x"]; -// array of medical items to replace and their ACE equivalents -GVAR(replacementItems) = configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"] apply { - [configName _x, getArray _x] +// Custom Arsenal tab +if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [MEDICAL_TREATMENT_ITEMS, LLSTRING(medicalTab), ARSENAL_CATEGORY_ICON, -1, true] call EFUNC(arsenal,addRightPanelButton); }; ADDON = true; diff --git a/addons/medical_treatment/XEH_preStart.sqf b/addons/medical_treatment/XEH_preStart.sqf index 022888575e..420bffaf71 100644 --- a/addons/medical_treatment/XEH_preStart.sqf +++ b/addons/medical_treatment/XEH_preStart.sqf @@ -1,3 +1,5 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +call FUNC(scanMedicalItems); diff --git a/addons/medical_treatment/addon.toml b/addons/medical_treatment/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_treatment/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index 29c11c18ad..3782645019 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -1,10 +1,18 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; - weapons[] = {}; + units[] = {"ACE_fieldDressingItem","ACE_packingBandageItem","ACE_elasticBandageItem","ACE_tourniquetItem","ACE_splintItem","ACE_painkillersItem","ACE_morphineItem","ACE_adenosineItem","ACE_epinephrineItem","ACE_plasmaIVItem","ACE_bloodIVItem","ACE_salineIVItem","ACE_quikClotItem","ACE_personalAidKitItem","ACE_surgicalKitItem","ACE_sutureItem","ACE_bodyBagItem","ACE_medicalSupplyCrate","ACE_medicalSupplyCrate_advanced"}; + weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_painkillers","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_medical_status", "ace_medical_damage", "ace_apl"}; author = ECSTRING(common,ACETeam); @@ -22,3 +30,6 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "Cfg3DEN.hpp" +#include "CfgMagazines.hpp" + +#endif diff --git a/addons/medical_treatment/data/ACE_grave.p3d b/addons/medical_treatment/data/ACE_grave.p3d new file mode 100644 index 0000000000..10b1d4e9f8 Binary files /dev/null and b/addons/medical_treatment/data/ACE_grave.p3d differ diff --git a/addons/medical_treatment/data/ACE_medicalSupplyCrate.jpg b/addons/medical_treatment/data/ACE_medicalSupplyCrate.jpg new file mode 100644 index 0000000000..7c351645d6 Binary files /dev/null and b/addons/medical_treatment/data/ACE_medicalSupplyCrate.jpg differ diff --git a/addons/medical_treatment/data/Grave_as.paa b/addons/medical_treatment/data/Grave_as.paa new file mode 100644 index 0000000000..f34c503618 Binary files /dev/null and b/addons/medical_treatment/data/Grave_as.paa differ diff --git a/addons/medical_treatment/data/Grave_co.paa b/addons/medical_treatment/data/Grave_co.paa new file mode 100644 index 0000000000..79e61db1bb Binary files /dev/null and b/addons/medical_treatment/data/Grave_co.paa differ diff --git a/addons/medical_treatment/data/Grave_nohq.paa b/addons/medical_treatment/data/Grave_nohq.paa new file mode 100644 index 0000000000..0ddce42bbc Binary files /dev/null and b/addons/medical_treatment/data/Grave_nohq.paa differ diff --git a/addons/medical_treatment/data/Grave_smdi.paa b/addons/medical_treatment/data/Grave_smdi.paa new file mode 100644 index 0000000000..0586c5dbc2 Binary files /dev/null and b/addons/medical_treatment/data/Grave_smdi.paa differ diff --git a/addons/medical_treatment/data/bodybagItem.p3d b/addons/medical_treatment/data/bodybagItem.p3d index 5195fd59d9..e6c16e8dbe 100644 Binary files a/addons/medical_treatment/data/bodybagItem.p3d and b/addons/medical_treatment/data/bodybagItem.p3d differ diff --git a/addons/medical_treatment/data/bodybagItem_blue_co.paa b/addons/medical_treatment/data/bodybagItem_blue_co.paa new file mode 100644 index 0000000000..190abe5b89 Binary files /dev/null and b/addons/medical_treatment/data/bodybagItem_blue_co.paa differ diff --git a/addons/medical_treatment/data/bodybagItem_co.paa b/addons/medical_treatment/data/bodybagItem_co.paa index d04f8ec64c..30b1042845 100644 Binary files a/addons/medical_treatment/data/bodybagItem_co.paa and b/addons/medical_treatment/data/bodybagItem_co.paa differ diff --git a/addons/medical_treatment/data/bodybagItem_nohq.paa b/addons/medical_treatment/data/bodybagItem_nohq.paa index 5699ec5e04..775246571f 100644 Binary files a/addons/medical_treatment/data/bodybagItem_nohq.paa and b/addons/medical_treatment/data/bodybagItem_nohq.paa differ diff --git a/addons/medical_treatment/data/bodybagItem_smdi.paa b/addons/medical_treatment/data/bodybagItem_smdi.paa index cf4cf805e3..33a1da4ab3 100644 Binary files a/addons/medical_treatment/data/bodybagItem_smdi.paa and b/addons/medical_treatment/data/bodybagItem_smdi.paa differ diff --git a/addons/medical_treatment/data/bodybagItem_white_co.paa b/addons/medical_treatment/data/bodybagItem_white_co.paa new file mode 100644 index 0000000000..eaea0e8f6b Binary files /dev/null and b/addons/medical_treatment/data/bodybagItem_white_co.paa differ diff --git a/addons/medical_treatment/data/grave.rvmat b/addons/medical_treatment/data/grave.rvmat new file mode 100644 index 0000000000..9a28f4af13 --- /dev/null +++ b/addons/medical_treatment/data/grave.rvmat @@ -0,0 +1,82 @@ +class StageTI +{ + texture="a3\data_f\default_ti_ca.paa"; +}; +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.3,0.3,0.3,1}; +specularPower=10; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\medical_treatment\data\grave_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[]={0,9,0}; + up[]={4.5,0,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0)"; + 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\grave_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\grave_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(3.21,4.01)"; + uvSource="none"; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="none"; +}; diff --git a/addons/medical_treatment/data/littergeneric_suture.p3d b/addons/medical_treatment/data/littergeneric_suture.p3d new file mode 100644 index 0000000000..eb4a1fc9dd Binary files /dev/null and b/addons/medical_treatment/data/littergeneric_suture.p3d differ diff --git a/addons/medical_treatment/data/model.cfg b/addons/medical_treatment/data/model.cfg index 344141e28e..433488a8ba 100644 --- a/addons/medical_treatment/data/model.cfg +++ b/addons/medical_treatment/data/model.cfg @@ -45,7 +45,11 @@ class CfgModels { class adenosine: Default {}; class atropine: Default {}; class bandage: Default {}; - class bodybagItem: Default {}; + class bodybagItem: Default { + sectionsInherit = ""; + sections[] = {"camo"}; + skeletonName = ""; + }; class epinephrine: Default {}; class splint: Default {}; @@ -58,6 +62,8 @@ class CfgModels { class IVBag_500ml: IVBagBase {}; class IVBag_1000ml: IVBagBase {}; + class ACE_grave: IVBagBase {}; + class littergeneric: Default {}; class littergeneric_adenosine: Default {}; class littergeneric_atropine: Default {}; diff --git a/addons/medical_treatment/data/suture.p3d b/addons/medical_treatment/data/suture.p3d new file mode 100644 index 0000000000..b98ee47f95 Binary files /dev/null and b/addons/medical_treatment/data/suture.p3d differ diff --git a/addons/medical_treatment/data/suture.rvmat b/addons/medical_treatment/data/suture.rvmat new file mode 100644 index 0000000000..8664194d32 --- /dev/null +++ b/addons/medical_treatment/data/suture.rvmat @@ -0,0 +1,96 @@ +class StageTI +{ + texture="a3\data_f\default_vehicle_ti_ca.paa"; +}; +ambient[]={0.10196079,0.35686275,0.26274511,1}; +diffuse[]={0.10196079,0.35686275,0.26274511,1}; +forcedDiffuse[]={0,0,0,1}; +emmisive[]={0,0,0,0}; +specular[]={0,0,0,1}; +specularPower=3.5; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\medical_treatment\data\suture_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="#(argb,8,8,3)color(0.5,0.5,0.5,0.5,DT)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,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\medical_treatment\data\suture_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,64,64,1)fresnel(1.5,1)"; + 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/medical_treatment/data/suture_co.paa b/addons/medical_treatment/data/suture_co.paa new file mode 100644 index 0000000000..5555b9dce1 Binary files /dev/null and b/addons/medical_treatment/data/suture_co.paa differ diff --git a/addons/medical_treatment/data/suture_nohq.paa b/addons/medical_treatment/data/suture_nohq.paa new file mode 100644 index 0000000000..94c4f595cf Binary files /dev/null and b/addons/medical_treatment/data/suture_nohq.paa differ diff --git a/addons/medical_treatment/data/suture_smdi.paa b/addons/medical_treatment/data/suture_smdi.paa new file mode 100644 index 0000000000..c41af47eba Binary files /dev/null and b/addons/medical_treatment/data/suture_smdi.paa differ diff --git a/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf b/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf index fe97152c92..921e98d642 100644 --- a/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf +++ b/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Returns children actions to the "Load Patient" action for nearby vehicles. diff --git a/addons/medical_treatment/functions/fnc_addToLog.sqf b/addons/medical_treatment/functions/fnc_addToLog.sqf index b250fec9b1..93d7f8824f 100644 --- a/addons/medical_treatment/functions/fnc_addToLog.sqf +++ b/addons/medical_treatment/functions/fnc_addToLog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Adds an entry to the specified medical log of the unit. diff --git a/addons/medical_treatment/functions/fnc_addToTriageCard.sqf b/addons/medical_treatment/functions/fnc_addToTriageCard.sqf index 75cbc76b26..6e6fe12161 100644 --- a/addons/medical_treatment/functions/fnc_addToTriageCard.sqf +++ b/addons/medical_treatment/functions/fnc_addToTriageCard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Adds an entry to the unit's triage card. diff --git a/addons/medical_treatment/functions/fnc_bandage.sqf b/addons/medical_treatment/functions/fnc_bandage.sqf index 1a7dd4f818..8657936a66 100644 --- a/addons/medical_treatment/functions/fnc_bandage.sqf +++ b/addons/medical_treatment/functions/fnc_bandage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Bandages open wounds on the given body part of the patient. @@ -8,6 +8,10 @@ * 1: Patient * 2: Body Part * 3: Treatment + * 4: Item User + * 5: Used Item + * 6: Create litter + * 7: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -18,8 +22,11 @@ * Public: No */ -params ["_medic", "_patient", "_bodyPart", "_classname"]; +_this set [7, _this param [7, 1]]; // set bandage effectiveness coefficient +[QGVAR(bandaged), _this] call CBA_fnc_localEvent; // Raise event with reference so mods can modify this + +params ["_medic", "_patient", "_bodyPart", "_classname", "", "", "", "_bandageEffectiveness"]; [_patient, "activity", LSTRING(Activity_bandagedPatient), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[QGVAR(bandageLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; +[QGVAR(bandageLocal), [_patient, _bodyPart, _classname, _bandageEffectiveness], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_bandageLocal.sqf b/addons/medical_treatment/functions/fnc_bandageLocal.sqf index f001d2f0c1..2c59540fd1 100644 --- a/addons/medical_treatment/functions/fnc_bandageLocal.sqf +++ b/addons/medical_treatment/functions/fnc_bandageLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Local callback for bandaging a patient's open wounds. @@ -7,6 +7,7 @@ * 0: Patient * 1: Body Part * 2: Treatment + * 3: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -17,41 +18,86 @@ * Public: No */ -params ["_patient", "_bodyPart", "_bandage"]; - -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; -if (_partIndex < 0) exitWith {false}; +params ["_patient", "_bodyPart", "_bandage", ["_bandageEffectiveness", 1, [0]]]; +TRACE_4("bandageLocal",_patient,_bodyPart,_bandage,_bandageEffectiveness); +_bodyPart = toLowerANSI _bodyPart; private _openWounds = GET_OPEN_WOUNDS(_patient); -if (_openWounds isEqualTo []) exitWith {false}; +private _woundsOnPart = _openWounds getOrDefault [_bodyPart, []]; +if (_woundsOnPart isEqualTo []) exitWith {}; -// 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"]; +// Figure out which injuries for this bodypart are the best choice to bandage +private _targetWounds = [_patient, _bandage, _bodyPart, _bandageEffectiveness * GVAR(bandageEffectiveness)] call FUNC(findMostEffectiveWounds); // Everything is patched up on this body part already -if (_effectiveness == -1) exitWith {}; +if (count _targetWounds == 0) 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]; +private _treatedDamage = 0; +private _clearConditionCache = false; + +{ + private _wound = _x; + _wound params ["_classID", "_amountOf", "_bleeding", "_damage"]; + _y params ["_effectiveness", "_woundIndex", "_impact"]; + + // clear condition cache if we stopped all bleeding for this injury + if (!_clearConditionCache) then { + _clearConditionCache = (_effectiveness >= _amountOf); + }; + + // Reduce the amount this injury is present + (_woundsOnPart select _woundIndex) set [1, _amountOf - _impact]; + + // Store treated damage for clearing trauma + _treatedDamage = _treatedDamage + (_impact * _damage); + + // Handle reopening bandaged wounds + if (_impact > 0 && {GVAR(advancedBandages) == 2}) then { + [_patient, _impact, _bodyPart, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening); + }; +} forEach _targetWounds; _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 { +if ( + EGVAR(medical,limping) == 1 + && {_clearConditionCache} + && {_bodyPart in ["leftleg", "rightleg"]} + && {_patient getVariable [QEGVAR(medical,isLimping), false]} +) then { [_patient] call EFUNC(medical_engine,updateDamageEffects); }; -true +if (GVAR(clearTrauma) == 2) then { + TRACE_2("clearTrauma - clearing trauma after bandage",_bodyPart,_openWounds); + private _partIndex = ALL_BODY_PARTS find _bodyPart; + private _bodyPartDamage = _patient getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; + private _newDam = (_bodyPartDamage select _partIndex) - _treatedDamage; + + // Prevent obscenely small damage from lack of floating precision + if (_newDam < 0.05) then { + _bodyPartDamage set [_partIndex, 0]; + } else { + _bodyPartDamage set [_partIndex, _newDam]; + }; + _patient setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; + TRACE_2("clearTrauma - healed damage",_partIndex,_treatedDamage); + + switch (_bodyPart) do { + case "head": { [_patient, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case "body": { [_patient, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case "leftarm"; + case "rightarm": { [_patient, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + default { [_patient, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); }; + }; +}; + +// Reset treatment condition cache for nearby players if we stopped all bleeding +if (_clearConditionCache) then { + private _nearPlayers = (_patient nearEntities ["CAManBase", 6]) select {_x call EFUNC(common,isPlayer)}; + TRACE_1("clearConditionCaches: bandage",_nearPlayers); + [QEGVAR(interact_menu,clearConditionCaches), [], _nearPlayers] call CBA_fnc_targetEvent; +}; diff --git a/addons/medical_treatment/functions/fnc_bodyCleanupLoop.sqf b/addons/medical_treatment/functions/fnc_bodyCleanupLoop.sqf index eed0020ddf..d35dcc452c 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" +#include "..\script_component.hpp" /* * Author: Glowbal, esteldunedain - * Handles cleaning up bodies that were replaced by body bags. + * Handles cleaning up bodies or body bags that were replaced by body bags or put in grave. * * Arguments: * None @@ -29,4 +29,4 @@ if (GVAR(bodiesToDelete) isEqualTo []) exitWith { }; // Schedule cleanup loop to executed again -[FUNC(litterCleanupLoop), [], BODY_CLEANUP_CHECK_DELAY] call CBA_fnc_waitAndExecute; +[FUNC(bodyCleanupLoop), [], BODY_CLEANUP_CHECK_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_treatment/functions/fnc_canBandage.sqf b/addons/medical_treatment/functions/fnc_canBandage.sqf index f60836f38c..808f86b958 100644 --- a/addons/medical_treatment/functions/fnc_canBandage.sqf +++ b/addons/medical_treatment/functions/fnc_canBandage.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Prevents bandage actions from showing if selected body part isn't bleeding. * Toggles between showing all or only basic bandage action for advanced setting. * @@ -20,20 +20,23 @@ */ params ["_medic", "_patient", "_bodyPart", "_bandage"]; +_bodyPart = toLowerANSI _bodyPart; + +// If patient is swimming, don't allow bandage actions. +if (_patient call EFUNC(common,isSwimming)) exitWith {false}; // 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) != 0)) exitWith {false}; -private _index = ALL_BODY_PARTS find toLower _bodyPart; private _canBandage = false; { - _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; + _x params ["", "_amountOf", "_bleeding"]; // If any single wound on the bodypart is bleeding bandaging can go ahead - if (_bodyPartN == _index && {_amountOf * _bleeding > 0}) exitWith { + if (_amountOf * _bleeding > 0) exitWith { _canBandage = true; }; -} forEach GET_OPEN_WOUNDS(_patient); +} forEach ((GET_OPEN_WOUNDS(_patient)) getOrDefault [_bodyPart, []]); _canBandage diff --git a/addons/medical_treatment/functions/fnc_canCPR.sqf b/addons/medical_treatment/functions/fnc_canCPR.sqf index 172cbe5aa9..e5b4d7a317 100644 --- a/addons/medical_treatment/functions/fnc_canCPR.sqf +++ b/addons/medical_treatment/functions/fnc_canCPR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Checks if CPR can be performed on the patient. @@ -19,5 +19,5 @@ 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) +&& {(GVAR(advancedDiagnose) != 0) || {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_canDigGrave.sqf b/addons/medical_treatment/functions/fnc_canDigGrave.sqf new file mode 100644 index 0000000000..444fb5ff3c --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canDigGrave.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Ruthberg, commy2, esteldunedain, drofseh + * Checks if a unit can dig a grave at the position of the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * Can dig + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_canDigGrave + * + * Public: No + */ + +params ["_medic", "_patient"]; + +if !(["ace_trenches"] call EFUNC(common,isModLoaded)) exitWith {false}; + +(GVAR(allowGraveDigging) > 0) +&& {!((_patient isKindOf "CaManBase") && {_patient call EFUNC(common,isAwake)})} +&& {_patient call EFUNC(common,canDig)} +&& {_medic call EFUNC(trenches,hasEntrenchingTool)} diff --git a/addons/medical_treatment/functions/fnc_canPlaceInBodyBag.sqf b/addons/medical_treatment/functions/fnc_canPlaceInBodyBag.sqf new file mode 100644 index 0000000000..cc4ca4d23f --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canPlaceInBodyBag.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Checks if the patient can be placed in a bodybag. + * + * 'vehicle _patient' always returns the body + * '_patient in _patient' always false for body + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * Can Place in Bodybag + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_canPlaceInBodybag + * + * Public: No + */ + +params ["", "_patient"]; + +(isNull objectParent _patient) && {!(_patient call EFUNC(common,isAwake))} diff --git a/addons/medical_treatment/functions/fnc_canSplint.sqf b/addons/medical_treatment/functions/fnc_canSplint.sqf index 56551ace02..bc2b235bf8 100644 --- a/addons/medical_treatment/functions/fnc_canSplint.sqf +++ b/addons/medical_treatment/functions/fnc_canSplint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Checks if a splint can be applied to the patient. @@ -19,6 +19,6 @@ params ["", "_patient", "_bodyPart"]; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; (GET_FRACTURES(_patient) select _partIndex) == 1 diff --git a/addons/medical_treatment/functions/fnc_canStitch.sqf b/addons/medical_treatment/functions/fnc_canStitch.sqf index 6d1ab36465..685c2bd1d7 100644 --- a/addons/medical_treatment/functions/fnc_canStitch.sqf +++ b/addons/medical_treatment/functions/fnc_canStitch.sqf @@ -1,21 +1,31 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Katalam - * Checks if the patient can be stitched. + * Author: Katalam, mharis001, Brett Mayson + * Checks if the patient's body part can be stitched. * * Arguments: - * 0: Medic (not used) + * 0: Medic * 1: Patient + * 2: Body Part * * ReturnValue: * Can Stitch * * Example: - * [player, cursorTarget] call ace_medical_treatment_fnc_canStitch + * [player, cursorTarget, "head"] call ace_medical_treatment_fnc_canStitch * * Public: No */ -params ["", "_patient"]; +params ["_medic", "_patient", "_bodyPart"]; -!(GET_BANDAGED_WOUNDS(_patient) isEqualTo []) +if ((GVAR(consumeSurgicalKit) == 2) && {!([_medic, _patient, ["ACE_suture"]] call FUNC(hasItem))}) exitWith {false}; + +private _isBleeding = false; +{ + _x params ["", "_amountOf", "_bleedingRate"]; + _isBleeding = _amountOf > 0 && {_bleedingRate > 0}; + if (_isBleeding) then {break}; +} forEach (GET_OPEN_WOUNDS(_patient) get _bodyPart); + +(!_isBleeding && {(GET_BANDAGED_WOUNDS(_patient) getOrDefault [_bodyPart, []]) isNotEqualTo []}) // return diff --git a/addons/medical_treatment/functions/fnc_canTreat.sqf b/addons/medical_treatment/functions/fnc_canTreat.sqf index d8905626c9..3b643afa2b 100644 --- a/addons/medical_treatment/functions/fnc_canTreat.sqf +++ b/addons/medical_treatment/functions/fnc_canTreat.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Checks if the given treatment can be performed. @@ -10,7 +10,7 @@ * 3: Treatment * * Return Value: - * Can Treat + * Can treat * * Example: * [player, cursorObject, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreat @@ -22,16 +22,14 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; private _config = configFile >> QGVAR(actions) >> _classname; -isClass _config -&& {_patient isKindOf "CAManBase"} -&& {_medic != _patient || {GET_NUMBER_ENTRY(_config >> "allowSelfTreatment") == 1}} -&& {[_medic, GET_NUMBER_ENTRY(_config >> "medicRequired")] call FUNC(isMedic)} -&& { - private _selections = getArray (_config >> "allowedSelections") apply {toLower _x}; - "all" in _selections || {_bodyPart in _selections} +// Conditions that apply, regardless of curator status +( + isClass _config +) && { + _patient isKindOf "CAManBase" } && { - private _items = getArray (_config >> "items"); - _items isEqualTo [] || {[_medic, _patient, _items] call FUNC(hasItem)} + private _selections = getArray (_config >> "allowedSelections") apply {toLowerANSI _x}; + "all" in _selections || {_bodyPart in _selections} } && { GET_FUNCTION(_condition,_config >> "condition"); @@ -39,23 +37,40 @@ isClass _config if (_condition isEqualTo {}) exitWith { _condition = true; }; - + _condition = call _condition; }; _condition } && { - switch (GET_NUMBER_ENTRY(_config >> "treatmentLocations")) do { - case TREATMENT_LOCATIONS_ALL: {true}; - case TREATMENT_LOCATIONS_VEHICLES: { - IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} - }; - case TREATMENT_LOCATIONS_FACILITIES: { - IN_MED_FACILITY(_medic) || {IN_MED_FACILITY(_patient)} - }; - case TREATMENT_LOCATIONS_VEHICLES_AND_FACILITIES: { - IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} || {IN_MED_FACILITY(_medic)} || {IN_MED_FACILITY(_patient)} - }; - default {false}; - }; + // If in Zeus, the rest of the condition checks can be omitted + (_medic isEqualTo player && {!isNull findDisplay 312}) || { + // Conditions that apply when not in Zeus + ( + _medic != _patient || {GET_NUMBER_ENTRY(_config >> "allowSelfTreatment") == 1} + ) && { + [_medic, GET_NUMBER_ENTRY(_config >> "medicRequired")] call FUNC(isMedic) + } && { + [_medic, _patient, _config] call FUNC(canTreat_holsterCheck) + } && { + private _items = getArray (_config >> "items"); + _items isEqualTo [] || {[_medic, _patient, _items] call FUNC(hasItem)} + } && { + switch (GET_NUMBER_ENTRY(_config >> "treatmentLocations")) do { + case TREATMENT_LOCATIONS_ALL: {true}; + case TREATMENT_LOCATIONS_VEHICLES: { + IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} + }; + case TREATMENT_LOCATIONS_FACILITIES: { + IN_MED_FACILITY(_medic) || {IN_MED_FACILITY(_patient)} + }; + case TREATMENT_LOCATIONS_VEHICLES_AND_FACILITIES: { + IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} || {IN_MED_FACILITY(_medic)} || {IN_MED_FACILITY(_patient)} + }; + default {false}; + }; + } && { + !(_medic call EFUNC(common,isSwimming)) || {getNumber (_config >> "allowedUnderwater") == 1} + } + } } diff --git a/addons/medical_treatment/functions/fnc_canTreatCached.sqf b/addons/medical_treatment/functions/fnc_canTreatCached.sqf index d70f041c17..95ecc228c5 100644 --- a/addons/medical_treatment/functions/fnc_canTreatCached.sqf +++ b/addons/medical_treatment/functions/fnc_canTreatCached.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Cached check to determine if given treatment can be performed. 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..c903fc88d7 --- /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_canUnloadUnit.sqf b/addons/medical_treatment/functions/fnc_canUnloadUnit.sqf new file mode 100644 index 0000000000..f1a15f04f9 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canUnloadUnit.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Checks if unit can be unloaded. + * + * Arguments: + * 0: Unloader + * 1: Target + * + * Return Value: + * Can Unload + * + * Example: + * [player, bob] call ace_medical_treatment_fnc_canUnloadUnit + * + * Public: No + */ + +params ["_unloader", "_target"]; + +!isNull objectParent _target && +{!(lifeState _target in ["HEALTHY", "INJURED"])} diff --git a/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf b/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf index b708b7e50f..78a6fcb015 100644 --- a/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf +++ b/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks the blood pressure of the patient. diff --git a/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf b/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf index 5da7495f74..0c3fe39876 100644 --- a/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf +++ b/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Local callback for checking the blood pressure of a patient. diff --git a/addons/medical_treatment/functions/fnc_checkItems.sqf b/addons/medical_treatment/functions/fnc_checkItems.sqf deleted file mode 100644 index 2f4c20175e..0000000000 --- a/addons/medical_treatment/functions/fnc_checkItems.sqf +++ /dev/null @@ -1,47 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, commy2, mharis001 - * Handles converting vanilla medical items with ACE equivalents. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Example: - * [player] call ace_medical_treatment_fnc_checkItems - * - * Public: No - */ - -if (GVAR(convertItems) == 2) exitWith {}; - -params ["_unit"]; - -private _fnc_loop = if (GVAR(convertItems) == 0) then { - { - _x params ["_itemToRemove", "_replacementItems"]; - - private _count = [_unit, _itemToRemove] call EFUNC(common,getCountOfItem); - - if (_count > 0) then { - _unit removeItems _itemToRemove; - - { - _x params ["_item", "_amount"]; - - for "_i" from 1 to (_amount * _count) do { - _unit addItem _item; - }; - } forEach _replacementItems; - }; - } -} else { - { - _x params ["_itemToRemove"]; - _unit removeItems _itemToRemove; - } -}; - -_fnc_loop forEach GVAR(replacementItems); diff --git a/addons/medical_treatment/functions/fnc_checkPulse.sqf b/addons/medical_treatment/functions/fnc_checkPulse.sqf index 6c5b628fae..3f776ff749 100644 --- a/addons/medical_treatment/functions/fnc_checkPulse.sqf +++ b/addons/medical_treatment/functions/fnc_checkPulse.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks the pulse or heart rate of the patient. diff --git a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf index f386fa2c89..bb3efedc22 100644 --- a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf +++ b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Local callback for checking the pulse or heart rate of a patient. @@ -21,8 +21,16 @@ params ["_medic", "_patient", "_bodyPart"]; private _heartRate = 0; -if (alive _patient && {!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then { - _heartRate = GET_HEART_RATE(_patient); +if !([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) then { + _heartRate = switch (true) do { + case (alive _patient): { + GET_HEART_RATE(_patient) + }; + case (alive (_patient getVariable [QEGVAR(medical,CPR_provider), objNull])): { + random [25, 30, 35] // fake heart rate because patient is dead and off state machine + }; + default { 0 }; + }; }; private _heartRateOutput = LSTRING(Check_Pulse_Output_5); @@ -31,7 +39,7 @@ private _logOutput = LSTRING(Check_Pulse_None); if (_heartRate > 1) then { if (_medic call FUNC(isMedic)) then { _heartRateOutput = LSTRING(Check_Pulse_Output_1); - _logOutput = format ["%1", round _heartRate]; + _logOutput = str round _heartRate; } else { _heartRateOutput = LSTRING(Check_Pulse_Output_2); _logOutput = LSTRING(Check_Pulse_Weak); diff --git a/addons/medical_treatment/functions/fnc_checkResponse.sqf b/addons/medical_treatment/functions/fnc_checkResponse.sqf index 0fe0bbd60e..ca95fcb1d1 100644 --- a/addons/medical_treatment/functions/fnc_checkResponse.sqf +++ b/addons/medical_treatment/functions/fnc_checkResponse.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks the response status of the patient. @@ -18,7 +18,20 @@ params ["_medic", "_patient"]; -private _output = [LSTRING(Check_Response_Unresponsive), LSTRING(Check_Response_Responsive)] select (_patient call EFUNC(common,isAwake)); + +private _output = if (_patient call EFUNC(common,isAwake)) then { + LSTRING(Check_Response_Responsive) +} else { + if (GVAR(advancedDiagnose) == 3) exitWith { + if (IN_CRDC_ARRST(_patient)) exitWith { LSTRING(Check_Response_CardiacArrestDirect) }; + if (!alive _patient) exitWith { LSTRING(Check_Response_DeadDirect) }; + LSTRING(Check_Response_UnresponsiveDirect) + }; + if ((GVAR(advancedDiagnose) == 2) && {IN_CRDC_ARRST(_patient)}) exitWith { LSTRING(Check_Response_CardiacArrest) }; + if ((GVAR(advancedDiagnose) == 2) && {!alive _patient}) exitWith { LSTRING(Check_Response_Dead) }; + LSTRING(Check_Response_Unresponsive) +}; + [[_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 index 513c2e43ee..b060bea9c9 100644 --- a/addons/medical_treatment/functions/fnc_cprFailure.sqf +++ b/addons/medical_treatment/functions/fnc_cprFailure.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Zakant * Handles failure of the CPR treatment. diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf index 3d9dfd1e32..e6b1299027 100644 --- a/addons/medical_treatment/functions/fnc_cprLocal.sqf +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Local callback for finishing performing CPR on the patient. @@ -21,10 +21,17 @@ 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)); +private _bloodVolume = GET_BLOOD_VOLUME(_patient); +private _successChance = linearConversion [BLOOD_VOLUME_CLASS_4_HEMORRHAGE, BLOOD_VOLUME_CLASS_2_HEMORRHAGE, _bloodVolume, GVAR(cprSuccessChanceMin), GVAR(cprSuccessChanceMax), true]; +if ((random 1) < _successChance) then { + // If SpO2 is too low, it will make HR skyrocket to the point where patient goes back into CA + // Allow 3rd party mods to disable this mechanic + if (missionNamespace getVariable [QGVAR(setSpO2UponCPRSuccess), true] && {GET_SPO2(_patient) < DEFAULT_SPO2 / 2}) then { + _patient setVariable [VAR_SPO2, DEFAULT_SPO2 / 2, true]; + }; + + TRACE_2("CPR random success",_bloodVolume,_successChance); [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; } else { - TRACE_1("CPR random fail",GVAR(cprSuccessChance)); + TRACE_2("CPR random fail",_bloodVolume,_successChance); }; - diff --git a/addons/medical_treatment/functions/fnc_cprProgress.sqf b/addons/medical_treatment/functions/fnc_cprProgress.sqf index f41fefe5bf..d8b8dd9e3f 100644 --- a/addons/medical_treatment/functions/fnc_cprProgress.sqf +++ b/addons/medical_treatment/functions/fnc_cprProgress.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Zakant * Handles the progress of the CPR treatment. @@ -23,5 +23,5 @@ _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) +&& {(GVAR(advancedDiagnose) != 0) || {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 index f49ccbb4a3..07a5edf819 100644 --- a/addons/medical_treatment/functions/fnc_cprStart.sqf +++ b/addons/medical_treatment/functions/fnc_cprStart.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Zakant * Handles starting the CPR treatment. diff --git a/addons/medical_treatment/functions/fnc_cprSuccess.sqf b/addons/medical_treatment/functions/fnc_cprSuccess.sqf index bd9d0c3e2b..35f7292ad2 100644 --- a/addons/medical_treatment/functions/fnc_cprSuccess.sqf +++ b/addons/medical_treatment/functions/fnc_cprSuccess.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Handles finishing performing CPR on the patient. diff --git a/addons/medical_treatment/functions/fnc_createLitter.sqf b/addons/medical_treatment/functions/fnc_createLitter.sqf index 5aa2a5bed1..df9c2e7f4d 100644 --- a/addons/medical_treatment/functions/fnc_createLitter.sqf +++ b/addons/medical_treatment/functions/fnc_createLitter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Creates litter around the patient based on the treatment. @@ -13,7 +13,7 @@ * None * * Example: - * [player, cursorObject, "Head", "BasicBandage"] call ace_medical_fnc_createLitter + * [player, cursorObject, "Head", "BasicBandage"] call ace_medical_treatment_fnc_createLitter * * Public: No */ @@ -27,11 +27,10 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; if (vehicle _medic != _medic || {vehicle _patient != _patient}) exitWith {}; // Determine if treated body part is bleeding -private _index = ALL_BODY_PARTS find toLower _bodyPart; -private _isBleeding = GET_OPEN_WOUNDS(_patient) findIf { - _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; - - _bodyPartN == _index && {_amountOf * _bleeding > 0} +private _index = ALL_BODY_PARTS find toLowerANSI _bodyPart; +private _isBleeding = (GET_OPEN_WOUNDS(_patient) get _bodyPart) findIf { + _x params ["", "_amountOf", "_bleeding"]; + _amountOf * _bleeding > 0 } != -1; // Get litter config for the treatment diff --git a/addons/medical_treatment/functions/fnc_createLitterServer.sqf b/addons/medical_treatment/functions/fnc_createLitterServer.sqf index 5b94c5f199..afeba0eb36 100644 --- a/addons/medical_treatment/functions/fnc_createLitterServer.sqf +++ b/addons/medical_treatment/functions/fnc_createLitterServer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Creates a litter object and handles its cleanup. Only execute on server. @@ -12,7 +12,7 @@ * None * * Example: - * ["Litter_1", [100, 100, 0], 90] call ace_medical_fnc_createLitterServer + * ["Litter_1", [100, 100, 0], 90] call ace_medical_treatment_fnc_createLitterServer * * Public: No */ diff --git a/addons/medical_treatment/functions/fnc_diagnose.sqf b/addons/medical_treatment/functions/fnc_diagnose.sqf index 531827302d..5605cd2794 100644 --- a/addons/medical_treatment/functions/fnc_diagnose.sqf +++ b/addons/medical_treatment/functions/fnc_diagnose.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Action for diagnosing in basic medical diff --git a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf deleted file mode 100644 index 7bdff17b4f..0000000000 --- a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf +++ /dev/null @@ -1,72 +0,0 @@ -#include "script_component.hpp" -/* - * Author: SilentSpike - * Finds the wound most effective to bandage on the given bodypart of the patient for the given bandage type. - * - * Arguments: - * 0: Patient - * 1: Treatment classname - * 2: Body part index - * - * Return Value: - * [Wound, Index, Effectiveness] - * - * Public: No - */ - -params ["_patient", "_bandage", "_partIndex"]; - -// Get the default effectiveness for the used bandage -private _config = configFile >> QUOTE(ADDON) >> "Bandaging"; -private _effectiveness = getNumber (_config >> "effectiveness"); - -if (isClass (_config >> _bandage)) then { - _config = (_config >> _bandage); - - if (isNumber (_config >> "effectiveness")) then { - _effectiveness = getNumber (_config >> "effectiveness"); - }; -}; - -// Iterate over open wounds to find the most effective target -private _openWounds = GET_OPEN_WOUNDS(_patient); -if (_openWounds isEqualTo []) exitWith { [EMPTY_WOUND, -1, -1] }; - -private _wound = EMPTY_WOUND; -private _woundIndex = -1; -private _effectivenessFound = -1; - -{ - _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 _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; - - // Get the effectiveness of the bandage on this wound type - if (isClass (_config >> _className)) then { - private _woundTreatmentConfig = _config >> _className; - - if (isNumber (_woundTreatmentConfig >> "effectiveness")) then { - _woundEffectiveness = getNumber (_woundTreatmentConfig >> "effectiveness"); - }; - } else { - // Basic medical bandage just has a base level config (same effectivenes for all wound types) - if (_bandage != "BasicBandage") then { - WARNING_2("No config for wound type [%1] config base [%2]",_className,_config); - }; - }; - - // Track most effective found so far - if (_woundEffectiveness * _amountOf * _bleeding > _effectivenessFound * (_wound select 3) * (_wound select 4)) then { - _effectivenessFound = _woundEffectiveness; - _woundIndex = _forEachIndex; - _wound = _x; - }; - }; -} forEach _openWounds; - -[_wound, _woundIndex, _effectivenessFound] diff --git a/addons/medical_treatment/functions/fnc_findMostEffectiveWounds.sqf b/addons/medical_treatment/functions/fnc_findMostEffectiveWounds.sqf new file mode 100644 index 0000000000..6f11f84f57 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_findMostEffectiveWounds.sqf @@ -0,0 +1,92 @@ +#include "..\script_component.hpp" +/* + * Author: kymckay, LinkIsGrim + * Finds the most effective wounds to bandage on the given bodypart of the patient for the given bandage type and remaining overall bandage effectiveness. + * + * Arguments: + * 0: Patient + * 1: Treatment classname + * 2: Body part + * 3: Amount of bandage remaining (default: 1) + * 4: Wounds found from prior runs of the function (default: Empty Hashmap) + * + * Return Value: + * [Wound, [Effectiveness, Index, Impact]] of : + * + * Example: + * [cursorObject, "FieldDressing", "rightleg"] call ace_medical_treatment_fnc_findMostEffectiveWounds + * + * Public: No + */ + +params ["_patient", "_bandage", "_bodyPart", ["_bandageRemaining", 1], ["_foundWounds", createHashMap]]; +TRACE_1("findMostEffectiveWounds",count _foundWounds); + +// Get the default effectiveness for the used bandage +private _config = configFile >> QUOTE(ADDON) >> "Bandaging"; +private _effectiveness = getNumber (_config >> "effectiveness"); + +if (isClass (_config >> _bandage)) then { + _config = (_config >> _bandage); + + if (isNumber (_config >> "effectiveness")) then { + _effectiveness = getNumber (_config >> "effectiveness"); + }; +}; + +// Iterate over open wounds to find the most effective target +private _openWounds = GET_OPEN_WOUNDS(_patient) getOrDefault [_bodyPart, []]; +if (_openWounds isEqualTo []) exitWith {_foundWounds}; + +private _wound = EMPTY_WOUND; +private _woundIndex = -1; +private _effectivenessFound = -1; +private _impactFound = -1; + +{ + // Ignore iterated wounds + if (_x in _foundWounds) then {continue}; + _x params ["_classID", "_amountOf", "_bleeding", "_damage"]; + + private _woundEffectiveness = _effectiveness; + + // Select the classname from the wound classname storage + private _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; + + // Get the effectiveness of the bandage on this wound type + if (isClass (_config >> _className)) then { + private _woundTreatmentConfig = _config >> _className; + + if (isNumber (_woundTreatmentConfig >> "effectiveness")) then { + _woundEffectiveness = getNumber (_woundTreatmentConfig >> "effectiveness"); + }; + } else { + // Basic medical bandage just has a base level config (same effectiveness for all wound types) + if (_bandage != "BasicBandage") then { + WARNING_2("No config for wound type [%1] config base [%2]",_className,_config); + }; + }; + + // Multiply by bandageRemaining in case this is a rollover + _woundEffectiveness = _woundEffectiveness * _bandageRemaining; + + // Track most effective found so far + if ((_woundEffectiveness * _amountOf * _bleeding) > (_effectivenessFound * (_wound select 1) * (_wound select 2))) then { + _effectivenessFound = _woundEffectiveness; + _impactFound = _amountOf min _effectivenessFound; + _woundIndex = _forEachIndex; + _wound = _x; + }; +} forEach _openWounds; + +if (_woundIndex isEqualTo -1) exitWith {_foundWounds}; + +_bandageRemaining = _bandageRemaining - (_impactFound/_effectivenessFound); +_foundWounds set [_wound, [_effectivenessFound, _woundIndex, _impactFound]]; + +// recursion, run function again to find next most effective wound +if (GVAR(bandageRollover) && {_bandageRemaining > 0}) then { + [_patient, _bandage, _bodyPart, _bandageRemaining, _foundWounds] call FUNC(findMostEffectiveWounds); +}; + +_foundWounds // return diff --git a/addons/medical_treatment/functions/fnc_fullHeal.sqf b/addons/medical_treatment/functions/fnc_fullHeal.sqf index c5027e7dbe..0d8e93d3c7 100644 --- a/addons/medical_treatment/functions/fnc_fullHeal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHeal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Fully heals the patient. diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf index d292394eb6..42c5866a9a 100644 --- a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Local callback for fully healing a patient. @@ -20,6 +20,14 @@ TRACE_1("fullHealLocal",_patient); if (!alive _patient) exitWith {}; +// check if on fire, then put out the fire before healing +if ((["ace_fire"] call EFUNC(common,isModLoaded)) && {[_patient] call EFUNC(fire,isBurning)}) then { + _patient setVariable [QEGVAR(fire,intensity), 0, true]; +}; + +// Allow mods to heal +[QGVAR(fullHealLocalMod), [_patient]] call CBA_fnc_localEvent; + private _state = GET_SM_STATE(_patient); TRACE_1("start",_state); @@ -36,13 +44,18 @@ _patient setVariable [VAR_PAIN, 0, true]; _patient setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true]; // Tourniquets +{ + if (_x != 0) then { + [_patient, "ACE_tourniquet"] call EFUNC(common,addToInventory); + }; +} forEach GET_TOURNIQUETS(_patient); _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 [VAR_OPEN_WOUNDS, createHashMap, true]; +_patient setVariable [VAR_BANDAGED_WOUNDS, createHashMap, true]; +_patient setVariable [VAR_STITCHED_WOUNDS, createHashMap, true]; _patient setVariable [QEGVAR(medical,isLimping), false, true]; _patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; @@ -53,6 +66,8 @@ _patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; _patient setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true]; _patient setVariable [VAR_BLOOD_PRESS, [80, 120], true]; _patient setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true]; +_patient setVariable [VAR_SPO2, DEFAULT_SPO2, true]; +_patient setVariable [VAR_OXYGEN_DEMAND, 0, true]; // IVs _patient setVariable [QEGVAR(medical,ivBags), nil, true]; @@ -62,12 +77,12 @@ _patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; // wakeup needs to be done after achieving stable vitals, but before manually reseting unconc var if IS_UNCONSCIOUS(_patient) then { - if (!([_patient] call EFUNC(medical_status,hasStableVitals))) then { ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state); }; + if !([_patient] call EFUNC(medical_status,hasStableVitals)) then {ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state);}; TRACE_1("Waking up",_patient); [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; _state = GET_SM_STATE(_patient); TRACE_1("after WakeUp",_state); - if IS_UNCONSCIOUS(_patient) then { ERROR_1("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state); }; + if IS_UNCONSCIOUS(_patient) then {ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state);}; }; // Generic medical admin diff --git a/addons/medical_treatment/functions/fnc_getBandageTime.sqf b/addons/medical_treatment/functions/fnc_getBandageTime.sqf index d66a8515ae..eb0a3bc5ae 100644 --- a/addons/medical_treatment/functions/fnc_getBandageTime.sqf +++ b/addons/medical_treatment/functions/fnc_getBandageTime.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Calculates the time to bandage a wound based on it's size, the patient and the medic. * * Arguments: @@ -13,33 +13,45 @@ * Treatment Time * * Example: - * [player, cursorTarget, "Head", "FieldDressing"] call ace_medical_treatment_fnc_getBandageTime + * [player, cursorTarget, "head", "FieldDressing"] call ace_medical_treatment_fnc_getBandageTime * * Public: No */ -params ["_medic", "_patient", "_bodypart", "_bandage"]; +params ["_medic", "_patient", "_bodyPart", "_bandage"]; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; if (_partIndex < 0) exitWith { ERROR_1("invalid partIndex - %1",_this); 0 }; -private _targetWound = [_patient, _bandage, _partIndex] call FUNC(findMostEffectiveWound); -_targetWound params ["_wound", "_woundIndex", "_effectiveness"]; -TRACE_3("findMostEffectiveWound",_wound,_woundIndex,_effectiveness); +private _targetWounds = [_patient, _bandage, _bodyPart] call FUNC(findMostEffectiveWounds); +TRACE_1("findMostEffectiveWounds",_targetWounds); + +private _woundCount = count _targetWounds; // Everything is patched up on this body part already -if (_wound isEqualTo EMPTY_WOUND) exitWith { 0 }; - -_wound params ["_classID", "", "_amountOf", "_bloodloss", "_damage"]; -private _category = (_classID % 10); +if (_woundCount == 0) exitWith {0}; // Base bandage time is based on wound size and remaining percentage -private _bandageTime = [BANDAGE_TIME_S, BANDAGE_TIME_M, BANDAGE_TIME_L] select _category; +private _bandageTimesArray = [BANDAGE_TIME_S, BANDAGE_TIME_M, BANDAGE_TIME_L]; +private _bandageTime = 0; -// 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]); -}; +{ + private _wound = _x; + _wound params ["_classID", "", "_amountOf"]; + _y params ["_effectiveness", "", "_impact"]; + private _category = (_classID % 10); + + // Base bandage time is based on wound size and remaining percentage + private _woundTime = _bandageTimesArray select _category; + + // Scale bandage time based on amount left and effectiveness (less time if only a little wound left) + // Basic bandage treatment will have a very high effectiveness and can be ignored + if (GVAR(advancedBandages != 0)) then { + _woundTime = _woundTime * linearConversion [0, _effectiveness, _impact, 0.666, 1, true]; + }; + + _bandageTime = _bandageTime + _woundTime; +} forEach _targetWounds; // Medics are more practised at applying bandages if ([_medic] call FUNC(isMedic)) then { @@ -51,6 +63,11 @@ if (_medic == _patient) then { _bandageTime = _bandageTime + BANDAGE_TIME_MOD_SELF; }; +// Bandaging multiple injuries doesn't require opening a new bandage each time +if (_woundCount > 1) then { + _bandageTime = _bandageTime - (2 * _woundCount); +}; + TRACE_1("",_bandageTime); // Nobody can bandage instantly _bandageTime max 2.25 diff --git a/addons/medical_treatment/functions/fnc_getHealTime.sqf b/addons/medical_treatment/functions/fnc_getHealTime.sqf index e8e8c302bf..74c2bb26d8 100644 --- a/addons/medical_treatment/functions/fnc_getHealTime.sqf +++ b/addons/medical_treatment/functions/fnc_getHealTime.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the PAK treatment time based on the amount of damage to heal. diff --git a/addons/medical_treatment/functions/fnc_getStitchTime.sqf b/addons/medical_treatment/functions/fnc_getStitchTime.sqf index 81bf948ab2..f170d9db26 100644 --- a/addons/medical_treatment/functions/fnc_getStitchTime.sqf +++ b/addons/medical_treatment/functions/fnc_getStitchTime.sqf @@ -1,23 +1,22 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: mharis001 - * Calculates the Surgical Kit treatment time based on the amount of bandaged wounds. + * Author: kymckay + * Calculates the Surgical Kit treatment time based on the amount of stitchable wounds. * * Arguments: * 0: Medic (not used) * 1: Patient + * 2: Body Part * * Return Value: * Treatment Time * * Example: - * [player, cursorObject] call ace_medical_treatment_fnc_getStitchTime + * [player, cursorObject, "head"] call ace_medical_treatment_fnc_getStitchTime * * Public: No */ -#define TIME_PER_WOUND 5 +params ["", "_patient", "_bodyPart"]; -params ["", "_patient"]; - -count GET_BANDAGED_WOUNDS(_patient) * TIME_PER_WOUND +count (GET_BANDAGED_WOUNDS(_patient) getOrDefault [_bodyPart, []]) * GVAR(woundStitchTime) diff --git a/addons/medical_treatment/functions/fnc_getTriageStatus.sqf b/addons/medical_treatment/functions/fnc_getTriageStatus.sqf index 6db6484b8f..22207a5496 100644 --- a/addons/medical_treatment/functions/fnc_getTriageStatus.sqf +++ b/addons/medical_treatment/functions/fnc_getTriageStatus.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Returns the current triage status of the unit. diff --git a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf index f2966d5f9c..b90198f0eb 100644 --- a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Handles the bandage of a patient. @@ -6,7 +6,7 @@ * Arguments: * 0: The target * 1: The impact - * 2: Selection part number + * 2: Body part * 3: Injury index * 4: Injury * 5: Used Bandage type @@ -20,7 +20,7 @@ params ["_target", "_impact", "_part", "_injuryIndex", "_injury", "_bandage"]; TRACE_6("handleBandageOpening",_target,_impact,_part,_injuryIndex,_injury,_bandage); -_injury params ["_classID", "_bodyPartN"]; +_injury params ["_classID"]; private _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; private _reopeningChance = DEFAULT_BANDAGE_REOPENING_CHANCE; @@ -36,7 +36,7 @@ if (isClass (_config >> _bandage)) then { _reopeningMinDelay = getNumber (_config >> "reopeningMinDelay"); _reopeningMaxDelay = getNumber (_config >> "reopeningMaxDelay") max _reopeningMinDelay; } else { - WARNING_2("No config for bandage [%1] config base [%2]", _bandage, _config); + WARNING_2("No config for bandage [%1] config base [%2]",_bandage,_config); }; if (isClass (_config >> _className)) then { @@ -54,26 +54,26 @@ if (isClass (_config >> _className)) then { _reopeningMaxDelay = getNumber (_woundTreatmentConfig >> "reopeningMaxDelay") max _reopeningMinDelay; }; } else { - WARNING_2("No config for wound type [%1] config base [%2]", _className, _config); + WARNING_2("No config for wound type [%1] config base [%2]",_className,_config); }; TRACE_5("configs",_bandage,_className,_reopeningChance,_reopeningMinDelay,_reopeningMaxDelay); private _bandagedWounds = GET_BANDAGED_WOUNDS(_target); private _exist = false; { - _x params ["_id", "_partN", "_amountOf"]; - if (_id == _classID && {_partN == _bodyPartN}) exitWith { - _x set [2, _amountOf + _impact]; - TRACE_2("adding to existing bandagedWound",_id,_partN); + _x params ["_id", "_amountOf"]; + if (_id == _classID) exitWith { + _x set [1, _amountOf + _impact]; + TRACE_2("adding to existing bandagedWound",_id,_part); _exist = true; }; -} forEach _bandagedWounds; +} forEach (_bandagedWounds getOrDefault [_part, []]); if (!_exist) then { - TRACE_2("adding new bandagedWound",_classID,_bodyPartN); + TRACE_2("adding new bandagedWound",_classID,_part); private _bandagedInjury = +_injury; - _bandagedInjury set [2, _impact]; - _bandagedWounds pushBack _bandagedInjury; + _bandagedInjury set [1, _impact]; + (_bandagedWounds getOrDefault [_part, [], true]) pushBack _bandagedInjury; }; _target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; @@ -84,7 +84,7 @@ _target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; TRACE_1("",_reopeningChance); // Check if we are ever going to reopen this -if (random 1 <= _reopeningChance) then { +if (random 1 <= _reopeningChance * GVAR(woundReopenChance)) then { private _delay = _reopeningMinDelay + random (_reopeningMaxDelay - _reopeningMinDelay); TRACE_1("Will open",_delay); [{ @@ -92,39 +92,60 @@ if (random 1 <= _reopeningChance) then { TRACE_5("reopen delay finished",_target,_impact,_part,_injuryIndex,_injury); private _openWounds = GET_OPEN_WOUNDS(_target); - if (count _openWounds - 1 < _injuryIndex) exitWith { TRACE_2("index bounds",_injuryIndex,count _openWounds); }; + private _woundsOnPart = _openWounds getOrDefault [_part, []]; + if (count _woundsOnPart - 1 < _injuryIndex) exitWith { TRACE_2("index bounds",_injuryIndex,count _woundsOnPart); }; - _injury params ["_classID", "_bodyPartN"]; + _injury params ["_classID"]; - private _selectedInjury = _openWounds select _injuryIndex; - _selectedInjury params ["_selClassID", "_selBodyPart", "_selAmmount"]; - if ((_selClassID == _classID) && {_selBodyPart == _bodyPartN}) then { // matching the IDs + private _selectedInjury = _woundsOnPart select _injuryIndex; + _selectedInjury params ["_selClassID", "_selAmmount"]; + if (_selClassID == _classID) then { // matching the IDs private _bandagedWounds = GET_BANDAGED_WOUNDS(_target); private _exist = false; { - _x params ["_id", "_partN", "_amountOf"]; - if ((_id == _classID) && {_partN == _bodyPartN}) exitWith { + _x params ["_id", "_amountOf"]; + if (_id == _classID) exitWith { TRACE_2("bandagedWound exists",_id,_classID); - _x set [2, 0 max (_amountOf - _impact)]; + _x set [1, 0 max (_amountOf - _impact)]; _exist = true; }; - } forEach _bandagedWounds; + } forEach (_bandagedWounds getOrDefault [_part, []]); if (_exist) then { TRACE_2("Reopening Wound",_bandagedWounds,_openWounds); - _selectedInjury set [2, _selAmmount + _impact]; + _selectedInjury set [1, _selAmmount + _impact]; _target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; _target setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; [_target] call EFUNC(medical_status,updateWoundBloodLoss); + private _partIndex = ALL_BODY_PARTS find _part; + + // Re-add trauma and damage visuals + if (GVAR(clearTrauma) == 2) then { + private _injuryDamage = (_selectedInjury select 4) * _impact; + private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; + private _newDam = (_bodyPartDamage select _partIndex) + _injuryDamage; + _bodyPartDamage set [_partIndex, _newDam]; + + _target setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; + + switch (_partIndex) do { + case 0: { [_target, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case 1: { [_target, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case 2; + case 3: { [_target, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + default { [_target, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); }; + }; + }; + // Check if we gained limping from this wound re-opening - if ((EGVAR(medical,limping) == 1) && {_bodyPartN > 3}) then { + if ((EGVAR(medical,limping) == 1) && {_partIndex > 3}) then { [_target] call EFUNC(medical_engine,updateDamageEffects); }; }; } else { - TRACE_3("no match",_selectedInjury,_classID,_bodyPartN); + TRACE_3("no match",_selectedInjury,_classID,_part); }; }, [_target, _impact, _part, _injuryIndex, +_injury], _delay] call CBA_fnc_waitAndExecute; }; diff --git a/addons/medical_treatment/functions/fnc_hasItem.sqf b/addons/medical_treatment/functions/fnc_hasItem.sqf index 564e7c4be2..e0ef4c8a4f 100644 --- a/addons/medical_treatment/functions/fnc_hasItem.sqf +++ b/addons/medical_treatment/functions/fnc_hasItem.sqf @@ -1,9 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * 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. + * If medic or patient are in a vehicle then vehicle's inventory will also be checked. * * Arguments: * 0: Medic @@ -14,7 +15,7 @@ * Has Item * * Example: - * [player, cursorObject, ["ACE_fieldDressing"]] call ace_medical_treatment_fnc_hasItems + * [player, cursorObject, ["ACE_fieldDressing"]] call ace_medical_treatment_fnc_hasItem * * Public: No */ @@ -24,7 +25,12 @@ params ["_medic", "_patient", "_items"]; private _fnc_checkItems = { params ["_unit"]; - private _unitItems = _unit call EFUNC(common,uniqueItems); + private _unitItems = [_unit, 1] call EFUNC(common,uniqueItems); + private _unitVehicle = objectParent _unit; + if (!isNull _unitVehicle) then { + _unitItems append (itemCargo _unitVehicle); + _unitItems append (magazineCargo _unitVehicle); + }; _items findIf {_x in _unitItems} != -1 }; diff --git a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf index c8d2aa8e7b..56477eafee 100644 --- a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf +++ b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks if the unit has a tourniquet applied on the specified body part. @@ -18,6 +18,6 @@ params ["_unit", "_bodyPart"]; -private _index = ALL_BODY_PARTS find toLower _bodyPart; +private _index = ALL_BODY_PARTS find toLowerANSI _bodyPart; _index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_unit,_index)} diff --git a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf index fe144ea78a..d04c1497bd 100644 --- a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf +++ b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Checks if the unit is in a medical facility. @@ -21,7 +21,7 @@ params ["_unit"]; 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)} + CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position,_position vectorAdd [ARR_3(0,0,10)],_unit)]) || {CHECK_OBJECTS(_unit nearObjects 7.5)} }; [[], _fnc_check, _unit, QGVAR(inMedicalFacilityCache), IN_MEDICAL_FACILITY_CACHE_EXPIRY] call EFUNC(common,cachedCall); diff --git a/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf b/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf index 2f76f04f99..f6ca395f9c 100644 --- a/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf +++ b/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Checks if the unit is in a medical vehicle. diff --git a/addons/medical_treatment/functions/fnc_isMedic.sqf b/addons/medical_treatment/functions/fnc_isMedic.sqf index d109ad2452..7e1360e5ed 100644 --- a/addons/medical_treatment/functions/fnc_isMedic.sqf +++ b/addons/medical_treatment/functions/fnc_isMedic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Checks if the unit is a medic of the given level. diff --git a/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf b/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf index 4b06ffdb55..4747860ae6 100644 --- a/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf +++ b/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks if the vehicle is a medical vehicle. @@ -17,4 +17,4 @@ params ["_vehicle"]; -_vehicle getVariable [QEGVAR(medical,isMedicalVehicle), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "attendant") > 0] +_vehicle getVariable [QEGVAR(medical,isMedicalVehicle), getNumber (configOf _vehicle >> "attendant") > 0] diff --git a/addons/medical_treatment/functions/fnc_ivBag.sqf b/addons/medical_treatment/functions/fnc_ivBag.sqf index bfc149564e..7f56f332b3 100644 --- a/addons/medical_treatment/functions/fnc_ivBag.sqf +++ b/addons/medical_treatment/functions/fnc_ivBag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Administers an IV bag treatment to the patient. diff --git a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf index f2640fb0bf..80f06fc11e 100644 --- a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf +++ b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Local callback for administering an IV bag to a patient. @@ -23,7 +23,7 @@ params ["_patient", "_bodyPart", "_classname"]; private _bloodVolume = GET_BLOOD_VOLUME(_patient); if (_bloodVolume >= DEFAULT_BLOOD_VOLUME) exitWith {}; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; // Get attributes for the used IV private _defaultConfig = configFile >> QUOTE(ADDON) >> "IV"; diff --git a/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf b/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf index 1039edb4c6..f9450ac5e1 100644 --- a/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf +++ b/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, esteldunedain, mharis001 * Handles cleaning up litter objects that have reached the end of their lifetime. diff --git a/addons/medical_treatment/functions/fnc_loadUnit.sqf b/addons/medical_treatment/functions/fnc_loadUnit.sqf index 8c65fd88ce..edb9cbe062 100644 --- a/addons/medical_treatment/functions/fnc_loadUnit.sqf +++ b/addons/medical_treatment/functions/fnc_loadUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Loads an unconscious or dead patient in the given or nearest vehicle. @@ -18,6 +18,7 @@ */ 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); @@ -31,10 +32,26 @@ if (_patient call EFUNC(medical_status,isBeingDragged)) then { [_medic, _patient] call EFUNC(dragging,dropObject); }; -private _vehicle = [_medic, _patient, _vehicle] call EFUNC(common,loadPerson); +private _vehicle = [ + _medic, + _patient, + _vehicle, + getArray (configOf _vehicle >> QGVAR(patientSeats)), + ([configOf _vehicle >> QGVAR(patientReverseFill), "NUMBER", 1] call CBA_fnc_getConfigEntry) > 0 +] call EFUNC(common,loadPerson); -if (!isNull _vehicle) then { - private _patientName = [_patient, false, true] call EFUNC(common,getName); - private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); +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 (configOf _vehicle >> "displayName"); [[LSTRING(LoadedInto), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured); -}; +}, [_patient, _vehicle], 3, { + params ["_unit", "_vehicle"]; + 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 index 6def70b212..dfd08d4de2 100644 --- a/addons/medical_treatment/functions/fnc_medication.sqf +++ b/addons/medical_treatment/functions/fnc_medication.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Administers medication to the patient on the given body bodypart. @@ -23,6 +23,7 @@ params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"]; [_patient, _usedItem] call FUNC(addToTriageCard); -[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _usedItem >> "displayName")]] call FUNC(addToLog); +private _cfg = ["CfgWeapons", "CfgMagazines"] select (isClass (configFile >> "CfgMagazines" >> _usedItem)); +[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> _cfg >> _usedItem >> "displayName")]] call FUNC(addToLog); [QGVAR(medicationLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_medicationLocal.sqf b/addons/medical_treatment/functions/fnc_medicationLocal.sqf index 30b64860e6..0b23b365e8 100644 --- a/addons/medical_treatment/functions/fnc_medicationLocal.sqf +++ b/addons/medical_treatment/functions/fnc_medicationLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Local callback for administering medication to a patient. @@ -19,6 +19,9 @@ // todo: move this macro to script_macros_medical.hpp? #define MORPHINE_PAIN_SUPPRESSION 0.6 +// 0.2625 = 0.6/0.8 * 0.35 +// 0.6 = basic medication morph. pain suppr., 0.8 = adv. medication morph. pain suppr., 0.35 = adv. medication painkillers. pain suppr. +#define PAINKILLERS_PAIN_SUPPRESSION 0.2625 params ["_patient", "_bodyPart", "_classname"]; TRACE_3("medicationLocal",_patient,_bodyPart,_classname); @@ -36,13 +39,17 @@ if (!GVAR(advancedMedication)) exitWith { case "Epinephrine": { [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; }; + case "Painkillers": { + private _painSuppress = GET_PAIN_SUPPRESS(_patient); + _patient setVariable [VAR_PAIN_SUPP, (_painSuppress + PAINKILLERS_PAIN_SUPPRESSION) min 1, true]; + }; }; }; -TRACE_1("Running treatmentMedicationLocal with Advanced configuration for", _target); +TRACE_1("Running treatmentMedicationLocal with Advanced configuration for",_patient); // Handle tourniquet on body part blocking blood flow at injection site -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; if (HAS_TOURNIQUET_APPLIED_ON(_patient,_partIndex)) exitWith { TRACE_1("unit has tourniquets blocking blood flow on injection site",_tourniquets); @@ -59,6 +66,7 @@ private _painReduce = GET_NUMBER(_medicationConfig >> "painReduce",g private _timeInSystem = GET_NUMBER(_medicationConfig >> "timeInSystem",getNumber (_defaultConfig >> "timeInSystem")); private _timeTillMaxEffect = GET_NUMBER(_medicationConfig >> "timeTillMaxEffect",getNumber (_defaultConfig >> "timeTillMaxEffect")); private _maxDose = GET_NUMBER(_medicationConfig >> "maxDose",getNumber (_defaultConfig >> "maxDose")); +private _maxDoseDeviation = GET_NUMBER(_medicationConfig >> "maxDoseDeviation",getNumber (_defaultConfig >> "maxDoseDeviation")); private _viscosityChange = GET_NUMBER(_medicationConfig >> "viscosityChange",getNumber (_defaultConfig >> "viscosityChange")); private _hrIncreaseLow = GET_ARRAY(_medicationConfig >> "hrIncreaseLow",getArray (_defaultConfig >> "hrIncreaseLow")); private _hrIncreaseNormal = GET_ARRAY(_medicationConfig >> "hrIncreaseNormal",getArray (_defaultConfig >> "hrIncreaseNormal")); @@ -75,4 +83,4 @@ TRACE_3("adjustments",_heartRateChange,_painReduce,_viscosityChange); [_patient, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange] call EFUNC(medical_status,addMedicationAdjustment); // Check for medication compatiblity -[_patient, _className, _maxDose, _incompatibleMedication] call FUNC(onMedicationUsage); +[_patient, _className, _maxDose, _maxDoseDeviation, _incompatibleMedication] call FUNC(onMedicationUsage); diff --git a/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf b/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf index 9784acb1ab..cd26d15424 100644 --- a/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf +++ b/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Handles the medication given to a patient. @@ -6,54 +6,48 @@ * Arguments: * 0: The patient * 1: Medication Treatment classname - * 2: Max dosage + * 2: Max dose (0 to ignore) + * 3: Max dose deviation * 3: Incompatable medication > * * Return Value: * None * * Example: - * [player, "morphine", 4, [["x", 1]]] call ace_medical_treatment_fnc_onMedicationUsage + * [player, "morphine", 4, 2, [["x", 1]]] call ace_medical_treatment_fnc_onMedicationUsage * * Public: No */ -params ["_target", "_className", "_maxDosage", "_incompatibleMedication"]; -TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatibleMedication); - -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", "_maxDose", "_maxDoseDeviation", "_incompatibleMedication"]; +TRACE_5("onMedicationUsage",_target,_className,_maxDose,_maxDoseDeviation,_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 (_maxDose > 0) then { + private _currentDose = [_target, _className] call EFUNC(medical_status,getMedicationCount); + // Because both {floor random 0} and {floor random 1} return 0 + if (_maxDoseDeviation > 0) then { + _maxDoseDeviation = _maxDoseDeviation + 1; + }; + + if (_currentDose > _maxDose + (floor random _maxDoseDeviation)) then { + TRACE_1("exceeded max dose",_currentDose); + _overdosedMedications pushBackUnique _className; + }; }; // 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 _incompatibleMedication; -if !(_overdosedMedications isEqualTo []) then { +if (_overdosedMedications isNotEqualTo []) then { private _medicationConfig = (configFile >> "ace_medical_treatment" >> "Medication"); private _onOverDose = getText (_medicationConfig >> "onOverDose"); if (isClass (_medicationConfig >> _className)) then { diff --git a/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf b/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf new file mode 100644 index 0000000000..82cd2bc080 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_placeBodyBagInGrave.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Places a body bag inside a grave. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [cursorObject, player] call ace_medical_treatment_fnc_placeBodyBagInGrave + * + * Public: No + */ + +params ["_bodybag", "_medic"]; +TRACE_2("placeBodyBagInGrave",_bodybag,_medic); + +[ + GVAR(treatmentTimeGrave), + _this, + { + TRACE_1("finished",_this); + (_this#0) params ["_bodybag","_medic"]; + private _graveClassname = ""; + if (GVAR(graveDiggingMarker)) then { + _graveClassname = missionNamespace getVariable [QGVAR(graveClassname), "ACE_Grave"]; + }; + private _graveRotation = missionNameSpace getVariable [QGVAR(graveRotation), 0]; + + [[_medic, _bodybag], _graveClassname, [0,0,0], _graveRotation, true] call FUNC(placeInBodyBagOrGrave); + }, + {TRACE_1("failed",_this);}, + LLSTRING(DiggingGrave) + // ToDo: check FUNC(canDigGrave)? - what if body dragged/burried by someone else +] call EFUNC(common,progressBar); diff --git a/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf b/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf index 02feb52025..c65f83ca6b 100644 --- a/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf +++ b/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf @@ -1,11 +1,15 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, drofseh * Places a dead body inside a body bag. * * Arguments: - * 0: Medic (not used) + * 0: Medic * 1: Patient + * 2: Body Part (unused) + * 3: Treatment (unused) + * 4: Item user (unused) + * 5: Body bag classname * * Return Value: * None @@ -16,33 +20,14 @@ * Public: No */ -params ["", "_patient"]; +params ["_medic", "_patient", "", "", "", "_item"]; 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) && {!GVAR(allowBodyBagUnconscious)}) exitWith { + [_medic, _item] call EFUNC(common,addToInventory); // re-add slighly used bodybag? + [LSTRING(bodybagWhileStillAlive)] call EFUNC(common,displayTextStructured); }; -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; +// Body bag needs to be a little higher to prevent it from flipping +private _bodyBagClass = getText (configFile >> "CfgWeapons" >> _item >> QGVAR(bodyBagObject)); +[_this, _bodyBagClass, [0, 0, 0.2], 0, false] call FUNC(placeInBodyBagOrGrave); diff --git a/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf b/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf new file mode 100644 index 0000000000..b72d0ddda4 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf @@ -0,0 +1,75 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, drofseh + * Places a dead body inside a body bag or grave. + * + * Arguments: + * 0: Arguments + * - 0: Medic + * - 1: Patient + * 1: Resting Place Classname + * 2: Offset (default: [0,0,0]) + * 3: Rotation (default: 0) + * 4: Is Grave (default: false) + * + * Return Value: + * None + * + * Example: + * [[player, cursorObject], "ACE_bodyBagObject_blue"] call ace_medical_treatment_fnc_placeInBodyBagOrGrave + * + * Public: No + */ + +params ["_args", "_restingPlaceClass", ["_offset", [0,0,0]], ["_rotation", 0], ["_isGrave", false]]; +_args params ["_medic", "_patient"]; +TRACE_1("placeInBodyBagOrGrave",_patient); + +private _isHuman = _patient isKindOf "CaManBase"; + +if (_isHuman && {!local _patient}) exitWith { + TRACE_1("Calling where local",local _patient); + [QGVAR(placeInBodyBagOrGrave), _this, _patient] call CBA_fnc_targetEvent; +}; + +if (_isHuman && {alive _patient}) then { + TRACE_1("Manually killing with setDead",_patient); + [_patient, "buried_alive", _medic] call EFUNC(medical_status,setDead); +}; + +private _position = getPosASL _patient; +private _direction = 0; + +if (_isHuman) then { + private _headPos = _patient modelToWorldVisual (_patient selectionPosition "head"); + private _spinePos = _patient modelToWorldVisual (_patient selectionPosition "Spine3"); + _direction = (_headPos vectorFromTo _spinePos) call CBA_fnc_vectDir; +} else { + _direction = getDir _patient; +}; + +// apply adjustments +_position = _position vectorAdd _offset; +_direction = _direction + _rotation; + + +// 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]; + +private _restingPlace = objNull; +if (_restingPlaceClass != "") then { + // Create the body bag object, set its position to prevent it from flipping + _restingPlace = createVehicle [_restingPlaceClass, [0, 0, 0], [], 0, "NONE"]; + _restingPlace setPosASL _position; + _restingPlace setDir _direction; + _restingPlace setVectorUp surfaceNormal _position; +}; + + +// Server will handle hiding and deleting the body +// Keep event name as body bag only to avoid breaking things for others +["ace_placedInBodyBag", [_patient, _restingPlace, _isGrave]] call CBA_fnc_globalEvent; +if (_isGrave) then { + ["ace_placedInGrave", [_patient, _restingPlace]] call CBA_fnc_globalEvent; +}; diff --git a/addons/medical_treatment/functions/fnc_placeInGrave.sqf b/addons/medical_treatment/functions/fnc_placeInGrave.sqf new file mode 100644 index 0000000000..6bea5c6db9 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_placeInGrave.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, drofseh + * Places a dead body inside a grave. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_placeInGrave + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_1("placeInGrave",_patient); + +if ((alive _patient) && {GVAR(allowGraveDigging) < 2}) exitWith { + [LSTRING(bodybagWhileStillAlive)] call EFUNC(common,displayTextStructured); +}; + +private _graveClassname = ""; +if (GVAR(graveDiggingMarker)) then { + _graveClassname = missionNamespace getVariable [QGVAR(graveClassname), "ACE_Grave"]; +}; +private _graveRotation = missionNameSpace getVariable [QGVAR(graveRotation), 0]; + +[_this, _graveClassname, [0,0,0], _graveRotation, true] call FUNC(placeInBodyBagOrGrave) + diff --git a/addons/medical_treatment/functions/fnc_removeBody.sqf b/addons/medical_treatment/functions/fnc_removeBody.sqf index e86d374e8e..7be154e89c 100644 --- a/addons/medical_treatment/functions/fnc_removeBody.sqf +++ b/addons/medical_treatment/functions/fnc_removeBody.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#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 + * 0: Body or Bodybag * * Return Value: * None diff --git a/addons/medical_treatment/functions/fnc_scanMedicalItems.sqf b/addons/medical_treatment/functions/fnc_scanMedicalItems.sqf new file mode 100644 index 0000000000..ef8229afbe --- /dev/null +++ b/addons/medical_treatment/functions/fnc_scanMedicalItems.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Caches all item classnames used in ACE_Medical_Treatment_Actions + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_medical_treatment_fnc_scanMedicalItems + * + * Public: No + */ + +private _list = []; +private _cfgActions = configFile >> QGVAR(actions); + +private _fnc_isMedicalItem = toString { + getNumber (_x >> "ACE_isMedicalItem") isEqualTo 1 +}; + +// Get items in ACE_Medical_Treament_Actions, fallback for items without API config property +{ + _list append (getArray (_x >> "items")); +} forEach ("true" configClasses _cfgActions); + +{ + _list pushBack (configName _x); +} forEach (_fnc_isMedicalItem configClasses (configFile >> "CfgWeapons")); + +{ + _list pushBack (configName _x); +} forEach (_fnc_isMedicalItem configClasses (configFile >> "CfgMagazines")); + +uiNamespace setVariable [QGVAR(treatmentItems), compileFinal (_list createHashMapFromArray [])] diff --git a/addons/medical_treatment/functions/fnc_setTriageStatus.sqf b/addons/medical_treatment/functions/fnc_setTriageStatus.sqf index aee8326056..dffd5f7154 100644 --- a/addons/medical_treatment/functions/fnc_setTriageStatus.sqf +++ b/addons/medical_treatment/functions/fnc_setTriageStatus.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Sets the traige status of the given unit. diff --git a/addons/medical_treatment/functions/fnc_splint.sqf b/addons/medical_treatment/functions/fnc_splint.sqf index f7883da86a..e48fb55d36 100644 --- a/addons/medical_treatment/functions/fnc_splint.sqf +++ b/addons/medical_treatment/functions/fnc_splint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Applies a splint to the patient on the given body part. diff --git a/addons/medical_treatment/functions/fnc_splintLocal.sqf b/addons/medical_treatment/functions/fnc_splintLocal.sqf index 4ee190b5a4..ee15a63bf0 100644 --- a/addons/medical_treatment/functions/fnc_splintLocal.sqf +++ b/addons/medical_treatment/functions/fnc_splintLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Local callback for applying a splint to a patient. @@ -20,7 +20,7 @@ params ["_medic", "_patient", "_bodyPart"]; TRACE_3("splintLocal",_medic,_patient,_bodyPart); -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; private _fractures = GET_FRACTURES(_patient); _fractures set [_partIndex, -1]; @@ -29,4 +29,5 @@ _patient setVariable [VAR_FRACTURES, _fractures, true]; // Check if we fixed limping from this treatment [_patient] call EFUNC(medical_engine,updateDamageEffects); -// todo: add logging +[_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 index e41cdf16b7..477c8101f5 100644 --- a/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf +++ b/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf @@ -1,12 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, mharis001 * Handles the surgical kit treatment by periodically closing bandaged wounds. * * Arguments: * 0: Arguments * 0: Medic (not used) * 1: Patient + * 2: Body Part * 1: Elapsed Time * 2: Total Time * @@ -20,30 +21,71 @@ */ params ["_args", "_elapsedTime", "_totalTime"]; -_args params ["", "_patient"]; +_args params ["_medic", "_patient", "_bodyPart"]; private _bandagedWounds = GET_BANDAGED_WOUNDS(_patient); -private _stitchedWounds = GET_STITCHED_WOUNDS(_patient); +private _bandagedWoundsOnPart = _bandagedWounds get _bodyPart; // Stop treatment if there are no wounds that can be stitched remaining -if (_bandagedWounds isEqualTo []) exitWith { false }; +if (_bandagedWoundsOnPart isEqualTo []) exitWith {false}; -// Check if enough time has elapsed to stitch another wound -if (_totalTime - _elapsedTime <= (count _bandagedWounds - 1) * 5) then { - private _treatedWound = _bandagedWounds deleteAt 0; - _stitchedWounds pushBack _treatedWound; - _patient setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; - _patient setVariable [VAR_STITCHED_WOUNDS, _stitchedWounds, true]; - TRACE_3("stitched",_treatedWound,count _bandagedWounds,count _stitchedWounds); +// Not enough time has elapsed to stitch a wound +if (_totalTime - _elapsedTime > ([_patient, _patient, _bodyPart] call FUNC(getStitchTime)) - GVAR(woundStitchTime)) exitWith {true}; - // Check if we fixed limping from this treatment - if ((EGVAR(medical,limping) == 2) && {_patient getVariable [QEGVAR(medical,isLimping), false]}) then { - _treatedWound params ["", "_partN"]; - if (_partN > 3) then { // only for LEG wounds - TRACE_3("updating damage effects",_patient,_partN,local _patient); - [QEGVAR(medical_engine,updateDamageEffects), [_patient], _patient] call CBA_fnc_patientEvent; - }; +// Remove the first stitchable wound from the bandaged wounds +private _treatedWound = _bandagedWoundsOnPart deleteAt (count _bandagedWoundsOnPart - 1); +_treatedWound params ["_treatedID", "_treatedAmountOf", "", "_treatedDamageOf"]; + +// Check if we need to add a new stitched wound or increase the amount of an existing one +private _stitchedWounds = GET_STITCHED_WOUNDS(_patient); +private _stitchedWoundsOnPart = _stitchedWounds getOrDefault [_bodyPart, [], true]; + +private _woundIndex = _stitchedWoundsOnPart findIf { + _x params ["_classID"]; + _classID == _treatedID +}; + +if (_woundIndex == -1) then { + _stitchedWoundsOnPart pushBack _treatedWound; +} else { + private _wound = _stitchedWoundsOnPart select _woundIndex; + _wound set [1, (_wound select 1) + _treatedAmountOf]; +}; + +if (GVAR(clearTrauma) == 1) then { + private _partIndex = ALL_BODY_PARTS find _bodyPart; + TRACE_2("clearTrauma - clearing trauma after stitching",_bodyPart,_treatedWound); + private _bodyPartDamage = _patient getVariable [QEGVAR(medical,bodyPartDamage), []]; + _bodyPartDamage set [_partIndex, (_bodyPartDamage select _partIndex) - (_treatedDamageOf * _treatedAmountOf)]; + _patient setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; + TRACE_2("clearTrauma - healed damage",_bodyPart,_treatedDamageOf); + + switch (_bodyPart) do { + case "head": { [_patient, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case "body": { [_patient, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case "leftarm"; + case "rightarm": { [_patient, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + default { [_patient, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); }; }; }; -true +_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]} + && {_bodyPart in ["leftleg", "rightleg"]} +) then { + TRACE_3("Updating damage effects",_patient,_bodyPart,local _patient); + [QEGVAR(medical_engine,updateDamageEffects), _patient, _patient] call CBA_fnc_targetEvent; +}; + +// Consume a suture for the next wound if one exists, stop stitching if none are left +if (GVAR(consumeSurgicalKit) == 2 && {_bandagedWoundsOnPart isNotEqualTo []}) then { + ([_medic, _patient, ["ACE_suture"]] call FUNC(useItem)) params ["_user"]; + !isNull _user +} else { + true +} diff --git a/addons/medical_treatment/functions/fnc_surgicalKitStart.sqf b/addons/medical_treatment/functions/fnc_surgicalKitStart.sqf new file mode 100644 index 0000000000..b194f88736 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_surgicalKitStart.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Handles the surgical kit treatment start by consuming a suture when applicable + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_surgicalKitStart + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_2("surgicalKitStart",_medic,_patient); + +if (GVAR(consumeSurgicalKit) == 2) then { + ([_medic, _patient, ["ACE_suture"]] call FUNC(useItem)); +}; diff --git a/addons/medical_treatment/functions/fnc_tourniquet.sqf b/addons/medical_treatment/functions/fnc_tourniquet.sqf index 155a2c502b..8e70529ece 100644 --- a/addons/medical_treatment/functions/fnc_tourniquet.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquet.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Applies a tourniquet to the patient on the given body part. diff --git a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf index 4bc803a8a8..9a0480bcb0 100644 --- a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Local callback for applying a tourniquet to a patient. @@ -19,10 +19,14 @@ params ["_patient", "_bodyPart"]; TRACE_2("tourniquetLocal",_patient,_bodyPart); -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; private _tourniquets = GET_TOURNIQUETS(_patient); _tourniquets set [_partIndex, CBA_missionTime]; _patient setVariable [VAR_TOURNIQUET, _tourniquets, true]; [_patient] call EFUNC(medical_status,updateWoundBloodLoss); + +private _nearPlayers = (_patient nearEntities ["CAManBase", 6]) select {_x call EFUNC(common,isPlayer)}; +TRACE_1("clearConditionCaches: tourniquetLocal",_nearPlayers); +[QEGVAR(interact_menu,clearConditionCaches), [], _nearPlayers] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf index 50f4c084c0..8a6be10bb4 100644 --- a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf @@ -1,7 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Removes the tourniquet from the patient on the given body part. + * Note: Patient may not be local * * Arguments: * 0: Medic @@ -21,7 +22,7 @@ params ["_medic", "_patient", "_bodyPart"]; TRACE_3("tourniquetRemove",_medic,_patient,_bodyPart); // Remove tourniquet from body part, exit if no tourniquet applied -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; private _tourniquets = GET_TOURNIQUETS(_patient); if (_tourniquets select _partIndex == 0) exitWith { @@ -33,9 +34,13 @@ _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); +private _nearPlayers = (_patient nearEntities ["CAManBase", 6]) select {_x call EFUNC(common,isPlayer)}; +TRACE_1("clearConditionCaches: tourniquetRemove",_nearPlayers); +[QEGVAR(interact_menu,clearConditionCaches), [], _nearPlayers] call CBA_fnc_targetEvent; + +// Add tourniquet item to medic or patient +private _receiver = [_patient, _medic, _medic] select GVAR(allowSharedEquipment); +[_receiver, "ACE_tourniquet"] call EFUNC(common,addToInventory); // Handle occluded medications that were blocked due to tourniquet private _occludedMedications = _patient getVariable [QEGVAR(medical,occludedMedications), []]; diff --git a/addons/medical_treatment/functions/fnc_treatment.sqf b/addons/medical_treatment/functions/fnc_treatment.sqf index 93c9877ad7..5f6df40e31 100644 --- a/addons/medical_treatment/functions/fnc_treatment.sqf +++ b/addons/medical_treatment/functions/fnc_treatment.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, KoffeinFlummi, mharis001 * Starts the treatment process. @@ -52,80 +52,100 @@ private _userAndItem = if (GET_NUMBER_ENTRY(_config >> "consumeItem") == 1) then [objNull, ""]; // Treatment does not require items to be consumed }; -_userAndItem params ["_itemUser", "_usedItem"]; +_userAndItem params ["_itemUser", "_usedItem", "_createLitter"]; -// Get treatment animation for the medic -private _medicAnim = if (_medic isEqualTo _patient) then { - getText (_config >> ["animationMedicSelf", "animationMedicSelfProne"] select (stance _medic == "PRONE")); -} else { - getText (_config >> ["animationMedic", "animationMedicProne"] select (stance _medic == "PRONE")); -}; +private _isInZeus = !isNull findDisplay 312; -_medic setVariable [QGVAR(selectedWeaponOnTreatment), weaponState _medic]; +if (_medic isNotEqualTo player || {!_isInZeus}) then { + // Get treatment animation for the medic + private _medicAnim = if (_medic isEqualTo _patient) then { + getText (_config >> ["animationMedicSelf", "animationMedicSelfProne"] select (stance _medic == "PRONE")); + } else { + getText (_config >> ["animationMedic", "animationMedicProne"] select (stance _medic == "PRONE")); + }; -// Adjust animation based on the current weapon of the medic -private _wpn = ["non", "rfl", "lnr", "pst"] param [["", primaryWeapon _medic, secondaryWeapon _medic, handgunWeapon _medic] find currentWeapon _medic, "non"]; -_medicAnim = [_medicAnim, "[wpn]", _wpn] call CBA_fnc_replace; + _medic setVariable [QGVAR(selectedWeaponOnTreatment), weaponState _medic]; -// This animation is missing, use alternative -if (_medicAnim == "AinvPknlMstpSlayWlnrDnon_medic") then { - _medicAnim = "AinvPknlMstpSlayWlnrDnon_medicOther"; -}; + // Adjust animation based on the current weapon of the medic + private _wpn = ["non", "rfl", "lnr", "pst"] param [["", primaryWeapon _medic, secondaryWeapon _medic, handgunWeapon _medic] find currentWeapon _medic, "non"]; + _medicAnim = [_medicAnim, "[wpn]", _wpn] call CBA_fnc_replace; -// Determine the animation length -private _animDuration = GVAR(animDurations) getVariable _medicAnim; -if (isNil "_animDuration") then { - WARNING_2("animation [%1] for [%2] has no duration defined",_medicAnim,_classname); - _animDuration = 10; -}; + // This animation is missing, use alternative + if (_medicAnim == "AinvPknlMstpSlayWlnrDnon_medic") then { + _medicAnim = "AinvPknlMstpSlayWlnrDnon_medicOther"; + }; -// These animations have transitions that take a bit longer... -if (weaponLowered _medic) then { - _animDuration = _animDuration + 0.5; + // Determine the animation length + private _animDuration = GVAR(animDurations) get toLowerANSI _medicAnim; + if (isNil "_animDuration") then { + WARNING_2("animation [%1] for [%2] has no duration defined",_medicAnim,_classname); + _animDuration = 10; + }; - // Fix problems with lowered weapon transitions by raising the weapon first - if (currentWeapon _medic != "" && {_medicAnim != ""}) then { - _medic action ["WeaponInHand", _medic]; + // These animations have transitions that take a bit longer... + if (weaponLowered _medic) then { + _animDuration = _animDuration + 0.5; + + // Fix problems with lowered weapon transitions by raising the weapon first + if (currentWeapon _medic != "" && {_medicAnim != ""}) then { + _medic action ["WeaponInHand", _medic]; + }; + }; + + if (binocular _medic != "" && {binocular _medic == currentWeapon _medic}) then { + _animDuration = _animDuration + 1; + }; + + // Play treatment animation for medic and determine the ending animation + if (vehicle _medic == _medic && {_medicAnim != ""}) then { + // Speed up animation based on treatment time (but cap max to prevent odd animiations/cam shake) + private _animRatio = _animDuration / _treatmentTime; + TRACE_3("setAnimSpeedCoef",_animRatio,_animDuration,_treatmentTime); + + // Don't slow down animation too much to prevent it looking funny. + if (_animRatio < ANIMATION_SPEED_MIN_COEFFICIENT) then { + _animRatio = ANIMATION_SPEED_MIN_COEFFICIENT; + }; + + // Skip animation enitrely if progress bar too quick. + if (_animRatio > ANIMATION_SPEED_MAX_COEFFICIENT) exitWith {}; + + [QEGVAR(common,setAnimSpeedCoef), [_medic, _animRatio]] call CBA_fnc_globalEvent; + + // Play animation + private _endInAnim = "AmovP[pos]MstpS[stn]W[wpn]Dnon"; + + private _pos = ["knl", "pne"] select (stance _medic == "PRONE"); + private _stn = "non"; + + if (_wpn != "non") then { + _stn = ["ras", "low"] select (weaponLowered _medic); + }; + + _endInAnim = [_endInAnim, "[pos]", _pos] call CBA_fnc_replace; + _endInAnim = [_endInAnim, "[stn]", _stn] call CBA_fnc_replace; + _endInAnim = [_endInAnim, "[wpn]", _wpn] call CBA_fnc_replace; + + [_medic, _medicAnim] call EFUNC(common,doAnimation); + [_medic, _endInAnim] call EFUNC(common,doAnimation); + _medic setVariable [QGVAR(endInAnim), _endInAnim]; + + if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { + EGVAR(advanced_fatigue,setAnimExclusions) pushBack QUOTE(ADDON); + }; + }; + + // Play a random treatment sound globally if defined + private _soundsConfig = _config >> "sounds"; + + if (isArray _soundsConfig) then { + (selectRandom (getArray _soundsConfig)) params ["_file", ["_volume", 1], ["_pitch", 1], ["_distance", 10]]; + playSound3D [_file, objNull, false, getPosASL _medic, _volume, _pitch, _distance]; }; }; -if (binocular _medic != "" && {binocular _medic == currentWeapon _medic}) then { - _animDuration = _animDuration + 1; -}; - -// Play treatment animation for medic and determine the ending animation -if (vehicle _medic == _medic && {_medicAnim != ""}) then { - private _endInAnim = "AmovP[pos]MstpS[stn]W[wpn]Dnon"; - - private _pos = ["knl", "pne"] select (stance _medic == "PRONE"); - private _stn = "non"; - - if (_wpn != "non") then { - _stn = ["ras", "low"] select (weaponLowered _medic); - }; - - _endInAnim = [_endInAnim, "[pos]", _pos] call CBA_fnc_replace; - _endInAnim = [_endInAnim, "[stn]", _stn] call CBA_fnc_replace; - _endInAnim = [_endInAnim, "[wpn]", _wpn] call CBA_fnc_replace; - - [_medic, _medicAnim] call EFUNC(common,doAnimation); - [_medic, _endInAnim] call EFUNC(common,doAnimation); - _medic setVariable [QGVAR(endInAnim), _endInAnim]; - - // 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 (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { - EGVAR(advanced_fatigue,setAnimExclusions) pushBack QUOTE(ADDON); - }; -}; - -// Play a random treatment sound globally if defined -if (isArray (_config >> "sounds")) then { - selectRandom getArray (_config >> "sounds") params ["_file", ["_volume", 1], ["_pitch", 1], ["_distance", 10]]; - playSound3D [_file, objNull, false, getPosASL _medic, _volume, _pitch, _distance]; +if (_isInZeus) then { + _treatmentTime = _treatmentTime * GVAR(treatmentTimeCoeffZeus); }; GET_FUNCTION(_callbackStart,_config >> "callbackStart"); @@ -135,16 +155,18 @@ if (_callbackProgress isEqualTo {}) then { _callbackProgress = {true}; }; -[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem] call _callbackStart; +[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter] call _callbackStart; + +["ace_treatmentStarted", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; [ _treatmentTime, - [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem], + [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter], FUNC(treatmentSuccess), FUNC(treatmentFailure), getText (_config >> "displayNameProgress"), _callbackProgress, - ["isNotInside"] + ["isNotInside", "isNotSwimming", "isNotInZeus"] ] call EFUNC(common,progressBar); true diff --git a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf index f59331fc77..7b3278b2a5 100644 --- a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Glowbal, mharis001 * Handles treatment process failure. @@ -11,6 +11,7 @@ * 3: Treatment * 4: Item User * 5: Used Item + * 6: Create Litter * * Return Value: * None @@ -19,11 +20,15 @@ */ params ["_args"]; -_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem", "_createLitter"]; // Return used item to user (if used) if (!isNull _itemUser) then { - [_itemUser, _usedItem] call EFUNC(common,addToInventory); + if (isClass (configFile >> "CfgMagazines" >> _usedItem)) then { + [_itemUser, _usedItem, 1] call EFUNC(common,adjustMagazineAmmo); + } else { + [_itemUser, _usedItem] call EFUNC(common,addToInventory); + }; }; // Switch medic to end animation immediately @@ -48,3 +53,5 @@ if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { GET_FUNCTION(_callbackFailure,configFile >> QGVAR(actions) >> _classname >> "callbackFailure"); _args call _callbackFailure; + +["ace_treatmentFailed", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf index 07dd5261b3..0c39f7646e 100644 --- a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Glowbal, mharis001 * Handles treatment process success. @@ -11,6 +11,7 @@ * 3: Treatment * 4: Item User * 5: Used Item + * 6: Create Litter * * Return Value: * None @@ -19,7 +20,8 @@ */ params ["_args"]; -_args params ["_medic", "_patient", "_bodyPart", "_classname"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem", "_createLitter"]; +TRACE_7("",_medic,_patient,_bodyPart,_classname,_itemUser,_usedItem,_createLitter); // Switch medic to end animation immediately private _endInAnim = _medic getVariable QGVAR(endInAnim); @@ -45,7 +47,7 @@ GET_FUNCTION(_callbackSuccess,configFile >> QGVAR(actions) >> _classname >> "cal _args call _callbackSuccess; // Call litter creation handler -_args call FUNC(createLitter); +if (_createLitter) then { _args call FUNC(createLitter); }; // Emit local event for medical API -["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname]] call CBA_fnc_localEvent; +["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_unloadUnit.sqf b/addons/medical_treatment/functions/fnc_unloadUnit.sqf index ef36e2faa8..0ddc297a32 100644 --- a/addons/medical_treatment/functions/fnc_unloadUnit.sqf +++ b/addons/medical_treatment/functions/fnc_unloadUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Unloads an unconscious or dead patient from their vehicle. @@ -17,13 +17,28 @@ */ params ["_medic", "_patient"]; +TRACE_2("unloadUnit",_medic,_patient); -if (vehicle _patient == _patient) exitWith { - TRACE_1("Unit is not in a vehicle",_patient); +if (isNull objectParent _patient) exitWith { + ERROR_1("Unit %1 is not in a vehicle",_patient); }; if (_patient call EFUNC(common,isAwake)) exitWith { - TRACE_1("Unit is awake",_patient); + ERROR_1("Unit %1 is awake",_patient); }; -["ace_unloadPersonEvent", [_patient, vehicle _patient, _medic], _patient] call CBA_fnc_targetEvent; +["ace_unloadPersonEvent", [_patient, objectParent _patient, _medic], _patient] call CBA_fnc_targetEvent; + +[{ + params ["_unit"]; + isNull objectParent _unit +}, { + params ["_unit", "_vehicle"]; + TRACE_2("success",_unit,_vehicle); + private _patientName = [_unit, false, true] call EFUNC(common,getName); + private _vehicleName = getText (configOf _vehicle >> "displayName"); + [[LSTRING(UnloadedFrom), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured); +}, [_patient, objectParent _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 a7484639da..33ac9f98f4 100644 --- a/addons/medical_treatment/functions/fnc_useItem.sqf +++ b/addons/medical_treatment/functions/fnc_useItem.sqf @@ -1,7 +1,8 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, mharis001 * Uses one of the treatment items. Respects the priority defined by the allowSharedEquipment setting. + * Can use items from vehicle inventory if either unit is in a vehicle. * * Arguments: * 0: Medic @@ -9,30 +10,54 @@ * 2: Items * * Return Value: - * User and Item + * User and Item and Litter Created * * Example: - * [player, cursorObject, ["bandage"]] call ace_medical_treatment_fnc_useItems + * [player, cursorObject, ["bandage"]] call ace_medical_treatment_fnc_useItem * * Public: No */ params ["_medic", "_patient", "_items"]; +if (_medic isEqualTo player && {!isNull findDisplay 312}) exitWith { + [_medic, _items select 0] +}; + scopeName "Main"; private _useOrder = [[_patient, _medic], [_medic, _patient], [_medic]] select GVAR(allowSharedEquipment); { - private _unit = _x; - private _unitItems = _x call EFUNC(common,uniqueItems); + private _unit = _x; + private _unitVehicle = objectParent _unit; + private _unitItems = [_x, 0] call EFUNC(common,uniqueItems); + private _unitMagazines = [_x, 2] call EFUNC(common,uniqueItems); + private _vehicleItems = itemCargo _unitVehicle; // [] for objNull + private _vehicleMagazines = magazineCargo _unitVehicle; // same { - if (_x in _unitItems) then { - _unit removeItem _x; - [_unit, _x] breakOut "Main"; + switch (true) do { + case (_x in _vehicleItems): { + _unitVehicle addItemCargoGlobal [_x, -1]; + [_unit, _x, false] breakOut "Main"; + }; + case (_x in _vehicleMagazines): { + [_unitVehicle, _x] call EFUNC(common,adjustMagazineAmmo); + [_unit, _x, false] breakOut "Main"; + }; + case (_x in _unitItems): { + _unit removeItem _x; + [_unit, _x, true] breakOut "Main"; + }; + case (_x in _unitMagazines): { + private _magsStart = count magazines _unit; + [_unit, _x] call EFUNC(common,adjustMagazineAmmo); + private _magsEnd = count magazines _unit; + [_unit, _x, (_magsEnd < _magsStart)] breakOut "Main"; + }; }; } forEach _items; } forEach _useOrder; -[objNull, ""] +[objNull, "", false] diff --git a/addons/medical_treatment/functions/script_component.hpp b/addons/medical_treatment/functions/script_component.hpp deleted file mode 100644 index 86227531f9..0000000000 --- a/addons/medical_treatment/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_treatment\script_component.hpp" \ No newline at end of file diff --git a/addons/medical_treatment/initSettings.inc.sqf b/addons/medical_treatment/initSettings.inc.sqf new file mode 100644 index 0000000000..d080965eb9 --- /dev/null +++ b/addons/medical_treatment/initSettings.inc.sqf @@ -0,0 +1,377 @@ +[ + QGVAR(advancedDiagnose), + "LIST", + [LSTRING(AdvancedDiagnose_DisplayName), LSTRING(AdvancedDiagnose_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2, 3], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrestDirect)], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(advancedMedication), + "CHECKBOX", + [LSTRING(AdvancedMedication_DisplayName), LSTRING(AdvancedMedication_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(advancedBandages), + "LIST", + [LSTRING(AdvancedBandages_DisplayName), LSTRING(AdvancedBandages_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedBandages_EnabledCanReopen)], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(bandageRollover), + "CHECKBOX", + [LSTRING(bandageRollover_DisplayName), LSTRING(bandageRollover_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + false // server can force if necessary, otherwise client decides +] call CBA_fnc_addSetting; + +[ + QGVAR(bandageEffectiveness), + "SLIDER", + [LSTRING(bandageEffectiveness_DisplayName), LSTRING(bandageEffectiveness_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 5, 1, 2], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(woundReopenChance), + "SLIDER", + [LSTRING(WoundReopenChance_DisplayName), LSTRING(WoundReopenChance_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 5, 1, 2], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(clearTrauma), + "LIST", + [LSTRING(ClearTrauma_DisplayName), LSTRING(ClearTrauma_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [ELSTRING(common,Never), LSTRING(ClearTrauma_AfterStitch), LSTRING(ClearTrauma_AfterBandage)], 1], + true +] call CBA_fnc_addSetting; + +// todo: should this setting differentiate between medical vehicles and facilities? +[ + QGVAR(locationsBoostTraining), + "CHECKBOX", + [ELSTRING(common,LocationsBoostTraining_DisplayName), LSTRING(LocationsBoostTraining_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + false, + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(treatmentTimeAutoinjector), + "SLIDER", + [LSTRING(TreatmentTimeAutoinjector_DisplayName), LSTRING(TreatmentTimeAutoinjector_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 5, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(treatmentTimeTourniquet), + "SLIDER", + [LSTRING(TreatmentTimeTourniquet_DisplayName), LSTRING(TreatmentTimeTourniquet_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 7, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(treatmentTimeSplint), + "SLIDER", + [LSTRING(TreatmentTimeSplint_DisplayName), LSTRING(TreatmentTimeSplint_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 7, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(treatmentTimeBodyBag), + "SLIDER", + [LSTRING(TreatmentTimeBodyBag_DisplayName), LSTRING(TreatmentTimeBodyBag_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 15, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(treatmentTimeGrave), + "SLIDER", + [LSTRING(TreatmentTimeGrave_DisplayName), LSTRING(TreatmentTimeGrave_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 120, 30, 1], + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(allowSelfPAK), + "LIST", + [LSTRING(AllowSelfPAK_DisplayName), LSTRING(AllowSelfPAK_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(timeCoefficientPAK), + "SLIDER", + [LSTRING(TimeCoefficientPAK_DisplayName), LSTRING(TimeCoefficientPAK_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 5, 1, 1], + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(consumeSurgicalKit), + "LIST", + [LSTRING(ConsumeSurgicalKit_DisplayName), LSTRING(ConsumeSurgicalKit_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], ["str_eval_typenothing", LSTRING(SurgicalKit_Display), LSTRING(Suture_Display)], 0], + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(woundStitchTime), + "SLIDER", + [LSTRING(WoundStitchTime_DisplayName), LSTRING(WoundStitchTime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 5, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(medicIV), + "LIST", + [LSTRING(MedicIV_DisplayName), LSTRING(MedicIV_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [LSTRING(Anyone), LSTRING(Medics), LSTRING(Doctors)], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(locationIV), + "LIST", + [LSTRING(LocationIV_DisplayName), LSTRING(LocationIV_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], + 1 +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(treatmentTimeIV), + "SLIDER", + [LSTRING(TreatmentTimeIV_DisplayName), LSTRING(TreatmentTimeIV_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 12, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(cprSuccessChanceMin), + "SLIDER", + [LSTRING(CPRSuccessChanceMin_DisplayName), LSTRING(CPRSuccessChanceMin_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 1, 0.4, 2, true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(cprSuccessChanceMax), + "SLIDER", + [LSTRING(CPRSuccessChanceMax_DisplayName), LSTRING(CPRSuccessChanceMax_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 1, 0.4, 2, true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(treatmentTimeCPR), + "SLIDER", + [LSTRING(TreatmentTimeCPR_DisplayName), LSTRING(TreatmentTimeCPR_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 60, 15, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(treatmentTimeCoeffZeus), + "SLIDER", + [LSTRING(TreatmentTimeCoeffZeus_DisplayName), LSTRING(TreatmentTimeCoeffZeus_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 10, 1, 2] +] call CBA_fnc_addSetting; + +[ + QGVAR(allowBodyBagUnconscious), + "CHECKBOX", + [LSTRING(AllowBodyBagUnconscious_DisplayName), LSTRING(AllowBodyBagUnconscious_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(allowGraveDigging), + "LIST", + [LSTRING(AllowGraveDigging_DisplayName), LSTRING(AllowGraveDigging_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(AllowGraveDigging_graveOnlyDead), ELSTRING(common,Yes)], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(graveDiggingMarker), + "CHECKBOX", + [LSTRING(GraveDiggingMarker_DisplayName), LSTRING(GraveDiggingMarker_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(allowLitterCreation), + "CHECKBOX", + [LSTRING(AllowLitterCreation_DisplayName), LSTRING(AllowLitterCreation_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Litter)], + true, + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(litterCleanupDelay), + "SLIDER", + [LSTRING(LitterCleanupDelay_DisplayName), LSTRING(LitterCleanupDelay_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Litter)], + [-1, 3600, 600, 0], + true +] call CBA_fnc_addSetting; diff --git a/addons/medical_treatment/initSettings.sqf b/addons/medical_treatment/initSettings.sqf deleted file mode 100644 index 3da65f8816..0000000000 --- a/addons/medical_treatment/initSettings.sqf +++ /dev/null @@ -1,202 +0,0 @@ - -// 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(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(advancedMedication), - "CHECKBOX", - [LSTRING(AdvancedMedication_DisplayName), LSTRING(AdvancedMedication_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - true, - true -] call CBA_settings_fnc_init; - -// todo: should this setting differentiate between medical vehicles and facilities? -[ - QGVAR(locationsBoostTraining), - "CHECKBOX", - [LSTRING(LocationsBoostTraining_DisplayName), LSTRING(LocationsBoostTraining_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - false, - true -] call CBA_settings_fnc_init; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; - -[ - 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; diff --git a/addons/medical_treatment/script_component.hpp b/addons/medical_treatment/script_component.hpp index bed5241f85..6a334ed72a 100644 --- a/addons/medical_treatment/script_component.hpp +++ b/addons/medical_treatment/script_component.hpp @@ -48,3 +48,11 @@ #define LITTER_CLEANUP_CHECK_DELAY 30 #define BODY_CLEANUP_CHECK_DELAY 20 + +// Animations that would be played slower than this are instead played exactly as slow as this. (= Progress bar will take longer than the slowed down animation). +#define ANIMATION_SPEED_MIN_COEFFICIENT 0.5 + +// Animations that would be played faster than this are instead skipped. (= Progress bar too quick for animation). +#define ANIMATION_SPEED_MAX_COEFFICIENT 2.5 + +#define MEDICAL_TREATMENT_ITEMS (keys (uiNamespace getVariable QGVAR(treatmentItems))) diff --git a/addons/medical_treatment/sounds/Pills.ogg b/addons/medical_treatment/sounds/Pills.ogg new file mode 100644 index 0000000000..7fbe550554 Binary files /dev/null and b/addons/medical_treatment/sounds/Pills.ogg differ diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index d974d89cbc..930562434f 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -6,270 +6,1127 @@ Behandlung 治療 Лечение + Traitement + Tratamento + 治療 + 治疗 + Trattamento + Léčba + Leczenie + Tedavi + Tratamiento + 치료 Litter 廃棄物 + Détritus + Медицинский мусор + Lixo + 醫療用廢棄物 + 医疗废弃物 + Rifiuti + Odpadky + Śmieci + Abfall + Cöp + Basura + 의료폐기물 Advanced Diagnose Erweiterte Diagnose - アドバンスド診断 + 高度な診断 Расширенная Диагностика + Diagnostic avancé + Diagnóstico Avançado + 進階診斷 + 进阶诊断 + Diagnosi avanzata + Pokročilá diagnóza + Zaawansowana Diagnoza + Gelişmiş Teşhis + Diagnóstico avanzado + 고급 진료 - Enables the Check Pulse, Check Blood Pressure, and Check Response treatment actions instead of the generic Diagnose action. - 有効化すると通常の診断動作に代わり、心拍や血圧測定、反応を確認できます。 + 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. + 全般的な診断の代わりに、脈拍の確認、血圧の確認、反応の確認の治療アクションを有効にします。\n無効にすると、心肺蘇生(CPR)アクションは、心肺蘇生(CPR)の実行が適切で必要な場合のみ表示されます。\nこの設定で有効になるアクションは、人が意識を失っているか心停止しているかを判断するために必要です。 + Active le diagnostic avancé, permettant la vérification du pouls, de la pression sanguine, ainsi que la réponse du patient aux traitements.\nSi l'option est désactivée, l'action de RCP ne sera visible que si elle est effectivement appropriée.\nLe diagnostic avancé est indispensable pour différencier une personne inconsciente d'une personne en arrêt cardiaque. + Включает действия «Проверить пульс», «Проверить давление» и «Проверить реакцию» вместо общего действия «Диагностика». + Ativa as opções de Verificar Pulso, Verificar Pressão Sanguínea e Verificar Resposta, ao invés do diagnóstico geral. + 啟用檢查脈搏、血壓以及病患反應的動作而非一般的診斷動作。\n當停用時,CPR只會在需要時出現。\n當這個選項啟用時必須診斷病患是否無意識或者心搏停止。 + 启用后,可以检查脉搏、血压和反应治疗,而不是通用诊断。\n禁用时,心肺复苏操作将仅在适当时显示。\n此设置操作启用后必须需要先确定一个人是失去知觉还是心脏骤停。 + Abilita le azioni di controllo del polso, controllo della pressione sanguigna e controllo della risposta al trattamento invece dell'azione generica 'Diagnosi'.\ Se disabilitata, l'azione di RCP sarà mostrata solo quando l'esecuzione della RCP è appropriata.\Le azioni abilitate da questa impostazione sono necessarie per determinare se una persona è in stato di incoscienza o in arresto cardiaco. + Povoluje kontrolu srdečního tepu, krevního tlaku a reakce pacienta namísto univerzální diagnózy.\nKdyž je tato možnost vypnuta, CPR akce bude dostupná pouze pokud je vhodné ji provést.\nAkce které tato možnost zapíná jsou nutné k určení zda je pacient v bezvědomí nebo má srdeční zástavu. + Włącza opcje sprawdzania Pulsu, Ciśnienia Tętniczego Krwi i Reakcje Na Ból, zamiast bardziej ogólnej akcji Diagnozuj.\n Po wyłączeniu tej opcji akcja RKO będzie wyświetlana tylko wtedy, gdy jej wykonanie będzie odpowiednie.\n Opcja, która włącza to ustawienie jest potrzebna do ustalenia, czy osoba jest nieprzytomna lub ma zatrzymanie krążenia. + Ermöglicht die 'Überprüfe Puls', 'Überprüfe Blutdruck' und 'Überprüfe Reaktionen' Behandlungsaktionen anstatt der einfachen 'Diagnose' Behandlungsaktion.\nWenn diese Einstellung nicht aktiviert ist, wird die "HLW"-Aktion nur angezeigt, wenn die Anwendung von HLW angemessen ist.\nDie Aktionen, die das Aktivieren dieser Einstellung ermöglicht, werden benötigt um zu bestimmen, ob eine Person bewusstlos ist oder einen Herzstillstand erleidet. + Genel Teşhis eylemi yerine Nabzı Kontrol Et, Kan Basıncını Kontrol Et ve Yanıtı Kontrol Et tedavi eylemlerini etkinleştirir. \ Devre dışı bırakıldığında, CPR eylemi yalnızca CPR gerçekleştirilmesi uygun olduğunda gösterilecektir. + Habilita la comprobación del pulso, presión sanguinea y rsepuesta a las acciones del tratamiento en lugar de la acción de diagnóstico genérico. \n Cuando se deshabilita, la acción RCP solo se mostrará cuando realizar un RCP sea apropiado. \n Las acciones activadas de este ajuste son necesarias para determinar si una persona está inconsciente o en parada cardiaca. + 맥박 확인, 혈압 확인, 반응 확인 등의 일반적인 진료행위를 추가합니다. \n 비활성화시 심폐소생술은 가능 할때만 표시됩니다. \n 해당 옵션은 인원이 기절한건지 아니면 심정지가 왔는지 구분할 때 쓰입니다. + + + Enabled & Can Diagnose Death/Cardiac Arrest + Activé & Diagnostic du décès/de l'arrêt cardiaque + Włączone i pozwala zdiagnozować Śmierć/Zatrzymanie Akcji Serca + 有効 & 死亡/心停止状態を診断可能 + Включено и может диагностировать смерть/остановку сердца + Aktiviert & kann Tod/Herzstillstand diagnostizieren + 已启用 & 可以诊断死亡/心搏骤停 + 활성화 및 사망/심정지 진찰 가능 + Habilitado y poder diagnosticar Muerte/Parada cardíaca + Abilitato e può diagnosticare Morte/Arresto Cardiaco + + + Enabled & Can Diagnose Death/Cardiac Arrest [Directly] + 有効 & 死亡/心停止状態を診断可能 [直接的に] + Включено и может диагностировать смерть/остановку сердца [Напрямую] + 활성화 및 사망/심정지 진찰 가능 [직접] + Aktiviert & kann Tod/Herzstillstand diagnostizieren [Direkt] + Abilitato e può diagnosticare Morte/Arresto Cardiaco [Esplicito] + + + Advanced Medication + Erweiterte Medikation + 高度な医薬品 + Расширенные Лекарства + Médication avancée + Medicação Avançada + 進階醫療用品 + 进阶医疗用品 + Pokročilé léky + Medicazione avanzata + Zaawansowane leki + Gelişmiş Ilaç + Medicación avanzada + 고급 약물 + + + Enables extended, more in-depth medication handling. Also, enables the use of Adenosine. + Устанавливает расширенное использование лекарств + 有効化するともっと多くの多様な機能を持つ医薬品を使えます。また、アデノシンが利用可能になります。 + Permet une manipulation étendue et plus approfondie des médicaments.\nEn outre, permet l'utilisation d'adénosine. + Ativa a manipulação avançada de medicações. Também permite o uso de Adenosina e Atropina. + 是否擴展藥物管控使其更深度化。並且,啟用腺苷以及阿托品的使用次數 + 可以扩展、更深入地使用药物。同时,能够使用腺苷以及阿托品。 + Povoluje hlubší a rozšířené zacházení s léčivy. Také aktivuje Adenosin a Atropin. + Abilita una gestione della medicazione più estesa e approfondita. Permette inoltre l'utilizzo dell'Adenosina. + Ermöglicht erweiterte, mehr tiefgründigere Anwendung von Medikationen. Ebenso ermöglicht es die Benutzung von Adenosin. + Pozwala na zaawansowane uzycie leków. Pozwala na używanie Adenozyny. + Habilita el manejo de la medicación más avanzada y en profundidad. Tambien permite el uso de Adenosina. + 더욱 더 확장된, 깊은 약물 치료를 활성화합니다. 또한 아데노신 기능을 활성화합니다. Advanced Bandages Erweiterte Bandagen - アドバンスド包帯 + 高度な包帯 Расширенная Перевязка + Pansements avancés + Ataduras Avançadas + 進階包紮 + 进阶包扎 + Bendaggi avanzati + Pokročilé obvazy + Zaawansowane Bandaże + Gelişmiş Bandajlar + Vendaje avanzado + 고급 붕대 - Enables treatment actions for different bandage types instead of the generic Bandage action. - 有効化すると通常の包帯動作に代わり、様々な種類がある包帯で治療ができます。 + Enables treatment actions for different bandage types instead of the generic Bandage action.\nAdditionally, the reopening of bandaged wounds can also be enabled. + Ermöglicht Behandlungsaktionen für verschiedene Bandagentypen anstelle der gewöhnlichen Bandageaktionen. + 有効化すると通常の包帯動作に代わり、様々な種類がある包帯で治療ができます。\nまた、創傷の再開放も有効化できます。 + 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. + 啟用不同繃帶的可用行為而非一般包紮動作。 + 启用不同绷带类型的治疗操作,而不是通用的绷带操作。\n此外,也可以启用包扎伤口开裂。 + Permette azioni di trattamento per diversi tipi di bendaggio al posto del bendaggio generico. + Povoluje specifické obvazy s různými vlastnostmi namísto jednoho univerzálního obvazu. + Umożliwia wybranie konkretnego rodzaju bandaża zamiast ogólnej akcji bandażowania. + Genel Bandaj eylemi yerine farklı bandaj türleri için tedavi eylemlerini etkinleştirir. \ Ek olarak, bandajlı yaraların yeniden açılması da etkinleştirilebilir. + Habilita las acciones de ttratamiento para distintos tipos de vendajes en lugar de la acción de vendaje genérico + 붕대마다 조금씩 다른 차이를 둬 상황에 알맞는 붕대를 쓰게 합니다.\n또한 붕대 풀림을 구현합니다. - - Wound Reopening - 創傷再開放 + + Enabled & Can Reopen + Activé & peuvent se rouvrir + 有効 & 再開放 + Zapnuto & Úrazy se mohou znovu otevřít + Включено и может открыться заново + Aktywne & możliwe ponowne otwarcie + Etkinleştirildi ve Yeniden Açılabilir + Habilitada y pueden reabrirse + Aktiviert und können sich wieder öffnen + Attivi e possono riaprirsi + 已启用 & 可以伤口开裂 + 활성화 및 붕대 풀림 구현 - - Enables the reopening of bandaged wounds. Requires Advanced Bandages to be enabled. - 有効化すると治療をした創傷を再開放します。アドバンスド包帯を有効化している必要があります。 + + Wound Reopening Coefficient + Coefficient de réouverture des plaies + Wundwiederöffnungskoeffizient + Coefficiente di riapertura ferite + Koeficient opětovného otevření rány + Коэф. повторного открытия раны + Współczynnik ponownego otwierania ran + 創傷再開放係数 + Yara Yeniden Açılma Katsayısı + Coeficiente de reapertura de heridas + 伤口开裂系数 + 붕대 풀림 계수 - - Advanced Medication - Erweiterte Medikamente - アドバンスド医薬品 - Расширенные Лекарства + + Coefficient for controlling the wound reopening chance. The final reopening chance is determined by multiplying this value with the specific reopening chance for the wound type and bandage used. + Coefficient de contrôle des chances de réouverture de la plaie. La chance de réouverture finale est déterminée en multipliant cette valeur par la chance de réouverture spécifique pour le type de plaie et le bandage utilisés. + Koeffizient zur Kontrolle der Wundöffnungswahrscheinlichkeit. Die endgültige Wiedereröffnungschance wird bestimmt, indem dieser Wert mit der spezifischen Wiedereröffnungschance für den verwendeten Wundtyp und Verband multipliziert wird. + Coefficiente che controlla la probabilità di riapertura delle ferite. La probabilità finale viene determinata moltiplicando questo valore con la probabilità di riapertura specifica del tipo di ferita e benda usata. + Koeficient pro řízení šance na opětovné otevření rány. Konečná šance na opětovné otevření se stanoví vynásobením této hodnoty specifickou šancí na opětovné otevření pro použitý typ rány a obvaz. + Коэффициент контроля вероятности повторного открытия раны. Окончательный шанс повторного открытия определяется путем умножения этого значения на определенный шанс повторного открытия для используемого типа раны и повязки. + Współczynnik kontroluje szanse na ponowne otworzenie rany. Końcowa szansa na otworzenie jest ustalana przez pomnożenie tej wartości z wartością szansy na otworzenie rany dla typu rany oraz typu bandaża. + 創傷が再開放する確率の係数を設定できます。再開放は、この数値と傷の種類、そして使用した包帯に応じて左右されます。 + Yaranın yeniden açılma şansını kontrol etme katsayısı. Son yeniden açılma şansı, bu değerin kullanılan yara tipi ve bandaj için spesifik yeniden açılma şansı ile çarpılmasıyla belirlenir. + Coeficiente que controla la probabilidad de reapertura de heridas. La probabilidad final de reapertura de heridas queda determinada multiplicando este valor por la probabilidad específica del tipo de herida y venda usada. + 用于控制伤口开裂概率的系数。最终的重开放概率=该值x伤口类型x所使用的绷带的具体开裂概率。 + 붕대가 풀리는 확률 계수를 정합니다. 최종 붕대 풀림 계수는 상처의 종류와 쓰인 붕대의 합의 결과에 계수를 곱한 결과입니다. - - Enables extended, more in-depth medication handling. Also, enables the use of Adenosine and Atropine. - Устанавливает расширенное использование лекарств - 有効化するともっと多くの多様な機能を持つ医薬品を使えます。また、アデノシンとアトロピンが利用可能になります。 + + Clear Trauma + 外傷を取り除く + Soigner les blessures + Очистить рану + Traumata entfernen + Rimuovi Trauma + Leczenie ran + 清理创伤 + 상처 제거 + Despejar trauma - - 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é - Места ускоренного обучения - 衛生能力の上昇位置 - 교육 증가 지역 - 受所在位置影响提升医疗能力 - 受所在位置影響提升醫療能力 + + Controls when hitpoint damage from wounds is healed. + 治療後に負傷箇所にある外傷の状態を制御できます。 + Définit à quel moment les blessures sont entièrement soignées. + Определяет, когда исцеляется урон от ран. + Steuert, wann Trefferpunktschaden von Wunden geheilt wird. + Controlla quando vengono guariti i danni ricevuti da ferite. + Kontroluje kiedy punkty obrażeń od odniesionych ran są w pełni wyleczone. + 控制伤口治疗后确定受伤部位的受伤情况。 + 상처가 언제 제거되는 지를 결정합니다. + Controla cuando los puntos de daño de las heridas son curados. + + + After Bandage + 包帯を巻いた後 + Après bandage + После перевязки + Nach dem Bandagieren + Dopo il bendaggio + Po zabandażowaniu + 包扎后 + 붕대 묶은 후 + Después de vendado + + + After Stitch + 縫合した後 + Après suture + После наложения швов + Nach dem Nähen + Dopo la cucitura + Po zszyciu + 缝合后 + 상처 봉합 후 + Después de sutura Boost medical training when in medical vehicles or facilities. Untrained becomes medic, medic becomes doctor. 衛生車両か施設では衛生能力を上昇します。未訓練では衛生兵に、衛生兵では医師になります。 - - - Self IV Transfusion - Eigennutzung von Bluttransfusionen - Внутривенное переливание на себе - 自己 IV 輸血 - - - Enables the use of IV Transfusions on oneself. - Erlaube Bluttransfusionen an sich selbst zu benutzen - Позволяет использовать внутривенные переливания на себе - 自らに対して IV 輸血を可能にします。 + Améliore les compétences médicales des unités en fonction du lieu où elles se trouvent ; notamment dans les véhicules ou les 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. + 在醫療設施或者載具旁時增加醫療能力。未受訓練的將會成為醫療兵,醫療兵將會成為軍醫。 + 在医疗设施或载具旁时提升医疗训练。未受训练者将会成为医疗兵,医疗兵将会晋升为军医。 + Aumenta la formazione medica quando si è in veicoli o strutture mediche. Se non addestrato diventa medico, se medico diventa dottore. + Zvyšuje zdravotnickou úroveň v zdravotnických objektech a vozidlech. Nevycvičení se stávají mediky a medici se stávají doktory. + Zwiększ wyszkolenie medyczne w pojazdach lub obiektach medycznych. Niewytrenowana jednostka zostaje medykiem, medyk zostaje lekarzem. + Verbessere 'Fähigkeiten-Level' in medizinischen Fahrzeugen oder Einrichtungen. Untrainiert wird zu Sanitäter, Sanitäter wird zu Arzt. + Tıbbi araçlar veya tesislerdeyken tıbbi müdaheleyi artırın. Eğitimsizler sıhhiye olur, sıhhiyeler doktor olur. + Aumente la formación médica cuando se encuentre en vehículos o instalaciones médicas. Sin entrenamiento se convierte en médico, médico se convierte en médico. + 의료 차량이나 시설 주위에 있으면 의료 수준을 높입니다. 의무병이 아닌 사람은 의무병이 되고, 의무병은 군의관이 됩니다. Allow Shared Equipment 装備共有を許可 + Matériel médical partagé + Разрешить общие медикаменты + Permitir Compartilhar Itens Médicos + 允許共享設備 + 允许共享装备 + Consenti la condivisione di risorse + Povolit sdílení vybavení + Zezwalaj na współdzielenie sprzętu + Erlaube geteilte Ausrüstung + Paylaşılan Ekipmana İzin Ver + Permite compartir material médico. + 의료물자 공유 Controls whether medical equipment can be shared between the patient and the medic. - 患者と衛生兵との間で医療品の共有をするかどうかを決定します。 + 患者と救護者との間で医療品の共有をするかどうかを制御します。 + Définit si l'équipement médical du médecin et du patient sont mis en commun, et quel matériel est à utiliser en priorité, le cas échéant. + Контролирует, можно ли разделить медикаменты между пациентом и врачом. + Controla se um item médico pode ser compartilhado entre médico e paciente. + 控制是否病患與醫療兵之間能否共享醫療物資 + 控制伤员和医疗兵之间是否可以共享医疗装备。 + Controlla se le risorse mediche possono essere condivise tra il paziente e il medico. + Nastavuje zda jak je zdravotnické vybavení sdíleno mezi medikem a pacientem. + Kontroluje, czy sprzęt medyczny ma być dzielony między pacjentem a medykiem. + Legt fest, ob medizinische Ausrüstung zwischen Patient und Sanitäter geteilt werden kann. + Tıbbi ekipmanın hasta ve sağlık görevlisi arasında paylaşılıp paylaşılamayacağını kontrol eder. + Controla si el equipo médico se puede compartir entre el paciente y el médico. + 환자와 치료자간에 의료물자를 공유할 지를 결정합니다. Patient's Equipment First - 患者の装備を先に使用 + 患者の装備を優先 + Matériel du patient d'abord + Сначала медикаменты пациента + Usar do Paciente Primeiro + 優先使用患者的醫療物資 + 优先消耗伤员装备 + Prima le risorse del paziente + Prvně pacientovo vybavení + Najpierw sprzęt pacjenta + Ausrüstung des Patienten zuerst + Önce Hastanın Ekipmanı + Usar equipo médico del paciente en primer lugar. + 환자의 의료물자 먼저 사용 Medic's Equipment First - 衛生兵の装備を先に使用 + 救護者の装備を優先 + Matériel du médecin d'abord + Сначала медикаменты врача + Usar do Médico Primeiro + 優先使用醫療兵的醫療物資 + 优先消耗医疗兵装备 + Prima le risorse del medico + Prvně medikovo vybavení + Najpierw sprzęt medyka + Ausrüstung des Sanitäters zuerst + İlk Sıhhiyenin Ekipmanı + Usar equipo médico del santiario en primer lugar. + 치료자의 의료물자 먼저 사용 + + + Autoinjector Treatment Time + Durée d'interaction - Auto-injecteurs + 自動注射器の所要時間 + Tiempo de tratamiento de autoinyección + Время ввода автоинъектора + Czas aplikacji autostrzykawki + Behandlungszeit des Autoinjektors + Tempo di utilizzo dell'autoiniettore + 自动注射器治疗时间 + 주사기 사용 시간 + + + Time, in seconds, required to administer medication using an autoinjector. + Définit le temps nécessaire à l'administration d'une substance auto-injectable (en secondes). + 自動注射器の使用に掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para administrar medicación utilizando un autoinyectador. + Время, необходимое для введения медикаментов автоинъектором (в секундах). + Czas w sekundach potrzebny do aplikacji medykamentów za pomocą autostrzykawki. + Zeit in Sekunden, die benötigt wird, um Medikamente mittels Autoinjektor zu verabreichen. + Tempo in secondi richiesto per ricevere medicina da un autoiniettore. + 使用自动注射器给药所需的时间(秒) + 초 단위로 주사기를 사용하는데 걸리는 시간을 정합니다. + + + Tourniquet Treatment Time + Durée d'interaction - Garrots + Tourniquet-Behandlungszeit + Tempo d'uso del Laccio Emostatico + 止血帯の所要時間 + Tiempo de tratamiento de torniquete + Время наложения/снятия жгута + Czas aplikacji stazy + 止血带治疗时间 + 지혈대 사용 시간 + + + Time, in seconds, required to apply/remove a tourniquet. + Définit le temps nécessaire à l'application ou au retrait d'un garrot (en secondes). + Zeit in Sekunden, die benötigt wird, um ein Tourniquet anzuwenden. + Tempo in secondi richiesto per mettere/rimuovere un laccio emostatico. + 止血帯の使用/取り外しに掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para aplicar/quitar un torniquete. + Время, необходимое для наложения/снятия жгута (в секундах). + Czas w sekundach potrzebny do założenia/zdjęcia stazy. + 使用/移除止血带所需的时间(秒) + 초 단위로 지혈대를 사용/제거하는 데 걸리는 시간을 정합니다. + + + IV Bag Treatment Time + Durée d'interaction - IVs + IV Beutelbehandlungszeit + Tempo di inserimento EV + 点滴の所要時間 + Tiempo de tratamiento de bolsa de IV + Время применения пакета внутривенного переливания + Czas aplikacji IV + 静脉输液袋治疗时间 + 수액용기 사용 시간 + + + Time, in seconds, required to administer an IV bag. + Définit le temps nécessaire à la pose d'une perfusion IV (en secondes). + Zeit in Sekunden, die benötigt wird, um einen Infusionsbeutel aufzutragen. + Tempo in secondi richiesto per applicare una Flebo Endovenosa. + 点滴の投与に掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para administrar una bolsa de IV. + Время, необходимое для применения пакета внутривенного переливания (в секундах). + Czas w sekundach potrzebny na aplikację transfuzji IV. + 使用静脉输液所需的时间(秒) + 초 단위로 수액용기를 사용하는 데 걸리는 시간을 정합니다. + + + Splint Treatment Time + Durée d'interaction - Attelles + Schienenbehandlungszeit + Tempo di Gessatura + 添え木の所要時間 + TIempo de tratamiento de férula + Время наложения шины + Czas aplikacji szyny + 夹板治疗时间 + 부목 사용 시간 + + + Time, in seconds, required to apply a splint. + Définit le temps nécessaire à l'application d'une attelle (en secondes). + Zeit in Sekunden, die zum Anbringen einer Schiene benötigt wird. + Tempo in secondi richiesto per applicare una gessatura. + 添え木の使用に掛かる時間。 (秒単位) + TIempo, en segundos, requerido para aplicar una férula. + Время, необходимое для наложения шины (в секундах). + Czas w sekundach potrzebny na aplikację szyny. + 使用夹板所需的时间(秒) + 초 단위로 부목을 사용하는데 걸리는 시간을 정합니다. + + + Body Bag Use Time + Durée d'interaction - Housses mortuaires + Anwendungszeit für Leichensack + Tempo della sacca per corpi + 遺体袋の所要時間 + TIempo de uso de bolsa para cuerpos + Время использования мешка для трупов + Czas użycia worka na ciało + 尸袋使用时间 + 시체 운반용 부대 사용 시간 + + + Time, in seconds, required to put a patient in a body bag. + Définit le temps nécessaire à la mise en housse d'un corps (en secondes). + Zeit in Sekunden, die benötigt wird, um einen Leichensack aufzutragen. + Tempo in secondi richiesto per mettere un deceduto in una sacca per corpi. + 遺体袋の使用に掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para poner a un paciente en una bolsa para cuerpos. + Время, необходимое для того чтобы упаковать труп в мешок (в секундах). + Czas w sekundach potrzebny na spakowanie ciała do worka na ciało. + 装入裹尸袋时间 + 초 단위로 시체 운반용 부대를 사용하는데 걸리는 시간을 정합니다. + + + Grave Digging Time + 무덤 파는 시간 + Czas Kopania Grobu + Durée pour creuser une tombe + Zeit zum Graben von Gräbern + Tempo di scavo tomba + 墓掘りの所要時間 + Время рытья могилы + Tiempo de Cavado de Tumba + + + Time, in seconds, required to dig a grave for a body. + 시신의 무덤을 파는 데 필요한 시간(초 단위). + Czas, w sekundach wymagany do wykopania grobu. + Durée, en secondes, requise pour creuser une tombe pour un corps. + Zeit (in Sekunden), die benötigt wird, um ein Grab für einen Leichnam auszuheben. + Tempo in secondi richiesto per seppellire un morto. + 遺体の墓を掘るのに掛かる時間。 (秒単位) + Время в секундах, необходимое для того, чтобы выкопать могилу для тела. + Tiempo, en segundos, requerido para cavar una tumba para un cuerpo. Allow Epinephrine Erlaube Epiniphrin Permitir Epinefrina - Ograniczenia adrenaliny - Activer l'épinéphrine - Permette epinefrina - Povolit adrenalin + Ograniczenia użycia adrenaliny + Épinéphrine autorisée pour + Permetti Epinefrina + Povolit epinefrin Permitir Epinefrina Разрешить Адреналин アドレナリンの許可 - 에피네프린 활성화 + 에피네프린 사용 허가 允许使用肾上腺素 允許使用腎上腺素 + Epinefrine izin ver - Training level required to use Epinephrine. - アドレナリンの使用に訓練レベルを必要とさせます。 + Training level required to use epinephrine. + アドレナリンの使用に必要な医療スキルのレベルを設定します。 + Définit la qualification médicale requise pour utiliser l'épinéphrine. + Уровень подготовки, необходимый для использования Адреналина. + É necessária uma qualificação médica para usar epinefrina. + 要受過何種程度的醫療訓練才可以使用腎上腺素 + 使用肾上腺素所需的医疗水平。 + Livello di addestramento richiesto per usare l'Epinefrina. + Úroveň výcviku pro použití epinefrinu + Poziom wyszkolenia wymagany do korzystania z epinefryny. + 'Fähigkeiten-Level', das benötigt wird, um Epinephrin zu nutzen. + Epinefrin kullanmak için gerekli eğitim seviyesi. + Nivel de entrenamiento médico requerido para usar Epinefrina. + 에피네프린을 사용하는데 필요한 등급을 정합니다. Locations Epinephrine Orte für Epiniphrin Ubicaciones epinefrina - Ograniczenia adrenaliny - Utilisation de l'épinéphrine - Ubicazione epinefrina - Oblast k použití adrenalinu + Miejsca użycia epinefryny + Lieux épinéphrine + Luoghi Epinefrina + Oblast pro použití epinefrinu Localizações de Epinefrina - Место использования адреналина - アドレナリンの使用可能場所 + Места использования Адреналина + アドレナリンの使用可能な場所 에피네프린 사용 장소 肾上腺素使用地点 腎上腺素使用地點 + Epinefrinin kullanılabileceği yerler - Controls where Epinephrine can be used. - アドレナリンが使える場所を決定します。 + Controls where epinephrine can be used. + アドレナリンが使える場所を制御します。 + Définit les lieux où l'usage d'épinéphrine est autorisé. + Контролирует, где можно использовать Адреналин. + Controla onde Epinefrina pode ser utilizada. + 控制何處能使用腎上腺素 + 控制何地能使用肾上腺素。 + Controlla dove si può usare l'Epinefrina. + Nastavuje kde může být epinefrin použit + Kontroluje, gdzie można stosować epinefrynę. + Legt fest, wo Epinephrin genutzt werden kann. + Epinefrinin nerelerde kullanılabileceğini kontrol eder + Controla donde puede sr usada la Epinefrina. + 에피네프린을 사용할 수 있는 장소를 정합니다. Allow PAK - Использование аптечки - Ustawienie apteczek osobistych + Использование Аптечки + Ograniczenia użycia apteczek osobistych Permitir EPA Erlaube Erste-Hilfe-Set Povolit osobní lékárničky (PAK) - Permitir Kit de Primeiros Socorros - Activer la trousse sanitaire + Permitir Kit de Primeiros Socorros (KPS) + Trousse sanitaire autorisée pour Elsősegélycsomag engedélyezése - Consenti Kit di Pronto Soccorso - 応急処置キットの許可 - 개인응급키트 활성화 + Consenti PAK + PAKの許可 + 개인응급키트 사용 허가 允许使用个人急救包 允許使用個人急救包 + PAK'a izin ver Training level required to use a PAK. - 応急処置キットの使用に訓練レベルを必要とさせます。 + PAKの使用に必要な医療スキルのレベルを設定します。 + Définit la qualification médicale requise pour utiliser la trousse sanitaire. + Уровень подготовки, необходимый для использования Аптечки. + É necessária uma qualificação médica para usar KPS + 要受過何種程度的醫療訓練才可以使用個人急救包 + 使用个人急救包所需的医疗水平。 + Livello di formazione richiesto per l'utilizzo di un Kit di Pronto Soccorso (PAK). + Úroveň výcviku pro použití osobní lékárničky (PAK). + Poziom wyszkolenia wymagany do korzystania z apteczek osobistych. + 'Fähigkeiten-Level', das benötigt wird, um ein Erste-Hilfe-Set zu nutzen. + PAK kullanmak için gerekli eğitim seviyesi. + Nivel de entrenamiento requerido para usar EPA + 개인응급키트을 사용하는 데 필요한 등급을 정합니다. Locations PAK - Место использования аптечки - Ograniczenie apteczek osobistych + Места использования Аптечки + Miejsca użycia 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 + Lieux trousse sanitaire Elsősegélycsomag helyek - Locazioni Kit Pronto Soccorso - 応急処置キットの使用可能場所 + Luoghi PAK + PAKの使用可能な場所 개인응급키트 사용 장소 个人急救包使用地点 個人急救包使用地點 + PAK kullanılabileceği yerler Controls where a PAK can be used. - 応急処置キットが使える場所を決定します。 + PAKが使える場所を制御します。 + Définit les lieux où l'usage de la trousse sanitaire est autorisé. + Контролирует, где можно использовать Аптечку. + Controla onde o KPS pode ser utilizado. + 控制何處能使用個人急救包 + 控制何地能使用个人急救包。 + Controlla dove può essere usato un Kit di Pronto Soccorso (PAK). + Nastavuje kde může být osobní lékárnička (PAK) použita. + Kontroluje, gdzie można korzystać z apteczek osobistych. + Kontrolliert, wo ein Erste-Hilfe-Set benutzt werden kann. + PAK'ın nerelerde kullanılabileceğini kontrol eder + Controla donde puede usarse el EPA + 개인응급키트을 사용할 수 있는 장소를 정합니다. Consume PAK - 応急処置キットの消費 + PAKの消費 + Trousse sanitaire consommable + Израсходовать Аптечку + KPS Descartável + 個人急救包為消耗品 + 个人急救包会被消耗 + Consuma PAK + Spotřebuj osobní lékárničku (PAK) + Zużycie apteczek osobistych + Verbrauche Erste-Hilfe-Set + PAK Tüketimi + Consumir EPA + 개인응급키트 소모 Controls whether a PAK should be consumed after use. - 応急処置キットの使用後に消費するかどうかを決定します。 + PAKの使用後に消費するかどうかを制御します。 + Définit si la trousse sanitaire doit être à usage unique. + Контролирует, следует ли израсходовать Аптечку после использования. + Controla se o KPS deve ser descartado/consumido após o uso. + 設定個人急救包是否為消耗品 + 设置个人急救包是否会被消耗 + Controlla se un PAK viene consumato dopo l'uso. + Nastavuje zda má být osobní lékárnička (PAK) spotřebována po použití. + Kontroluje, czy apteczka osobista powinna być zużyta po użyciu. + Kontrolliert, ob ein Erste-Hilfe-Set nach der Benutzung verbraucht werden soll. + Kullanımdan sonra bir PAK tüketilip tüketilmeyeceğini kontrol eder. + Controla si se debe consumir un EPA después de su uso. + 개인응급키트가 사용 후 소모되는 지를 결정합니다. + + + Self PAK Usage + Utilizzo del PAK su se stessi + Erste-Hilfe-Set Selbstanwendung + 自我使用急救包 + 自我使用急救包 + Utilisation de la trousse sanitaire sur soi-même + Używanie apteczki osobistej na sobie + PAKの自己使用 + Samo-použití osobní lékárničky (PAK) + Использование аптечки на себе + Kendi PAK Kullanımı + Usar EPA sobre uno mismo + 개인응급키트 자가 사용 + + + Enables the use of PAKs to heal oneself. + Abilita l'utilizzo del Kit di Pronto Soccorso (PAK) su se stessi. + Erlaubt die Benutzung des Erste-Hilfe-Sets, um sich selbst zu heilen. + 啟用個人急救包能對自己使用。 + 启用自身能使用个人急救包。 + Définit si le joueur peut utiliser la trousse sanitaire pour se soigner lui-même. + Pozwala na użycie apteczki osobistej na sobie + PAKを使って、自分を治療できるようにします。 + Umožňuje použít osobní lékárničku (PAK) na sama sebe. + Позволяют использовать аптечку на себе в одиночку. + Kendini iyileştirmek için PAK'ların kullanılmasını sağlar. + Habilita el uso de EPA para curarse a uno mismo. + 개인응급키트를 사용자 본인에게 쓸 수 있는 지를 정합니다. Time Coefficient PAK - 応急処置キットの時間係数 + PAKの所要時間係数 + Coefficient de temps pour la trousse sanitaire + Контролирует, следует ли израсходовать Аптечку после использования. + Coeficiente de Tempo do KPS + 個人急救包的時間係數 + 个人急救包时间系数 + Coefficiente temporale PAK + Časový koeficient pro osobní lékárničku (PAK) + Współczynnik czasu apteczek osobistych + Zeit-Koeffizient Erste-Hilfe-Set + PAK Zaman Katsayısı + EPA coheficiente de tiempo + 개인응급키트 사용 시간 Modifies how long a PAK takes to apply.\nThe treatment time is based on the total body part damage multiplied by this coefficient, with a minimum of 10 seconds. - 応急処置キットの使用にかかる時間を変更できます。\n総治療時間は最低でも 10 秒間で、この係数と体全体に負ったダメージによって決まります。 + PAKの使用に掛かる時間を変更できます。\n総治療時間は最低でも 10 秒間で、この係数と体全体に負ったダメージによって決まります。 + Modifie le temps nécessaire à l'application de la trousse sanitaire.\nLa durée est calculée en multipliant ce coefficient par les dommages totaux du patient, avec un minimum de 10 secondes. + Изменяет быстроту применения Аптечки.\nВремя лечения зависит от общего повреждения частей тела, умноженного на данный коэффициент (минимум 10 сек.). + Modifica quanto tempo o KPS leva para ser aplicado.\nO tempo de tratamento é baseado no total de dano do corpo, multiplicado por esse coeficiente, com um mínimo de 10 segundos. + 修改個人急救包要使用多久才能完成。\n醫療時間是依照全身的肢體狀況並乘上該係數而決定的,至少十秒。 + 修改个人急救包应用时间。 \n治疗时间=全身的总伤害x该系数,至少十秒。 + Il tempo di trattamento del PAK si basa sul danno totale della parte del corpo, moltiplicato per questo coefficiente, con un minimo di 10 secondi. + Upravuje jak dlouho trvá léčba pomocí osobní lékárničky (PAK).\nDoba léčby závisí na celkovém poškození částí těla vynásobeném tímto koeficientem, přičemž minimum je 10 vteřin. + Zmienia czas potrzebny na zastosowanie apteczki osobistej.\n Czas leczenia jest oparty na całkowitym uszkodzeniu części ciała pomnożonym przez ten współczynnik, wynosi minimum 10 sekund. + Modifiziert, wie lange ein Erste-Hilfe-Set für die Anwendung benötigt.\nDie Behandlungszeit basiert auf der Anzahl des Gesamtkörperschadens multipliziert mit diesem Koeffizienten, mit einen Minimum von 10 Sekunden. + Bir PAK'ın uygulanmasının ne kadar süreceğini değiştirir. \ Tedavi süresi, toplam vücut parçası hasarının bu katsayı ile en az 10 saniye çarpımına dayanır. + Modifica el tiempo que tarda en aplicarse un EPA. \n El tiempo de tratamiento se basa en el daño total de la parte del cuerpo multiplicado por este coeficiente, con un mínimo de 10 segundos. + 개인응급키트를 사용하는데 걸리는 시간의 계수을 정합니다.\n최소 10초를 기준으로 몸 전체 피해량과 계수를 합산하여 계산합니다. Allow Surgical Kit - 縫合キットを許可 + 手術キットを許可 + Trousse chirurgicale autorisée pour + Разрешить Хирургический набор + Permitir Kit Cirúrgico + 允許使用手術包 + 允许使用手术包 + Permetti il Kit Chirurgico + Povolit sešívací sadu + Ograniczenia Użycia Zestawu Chirurgicznego + Erlaube Operations-Set + Cerrahi Kitine İzin Ver + Permitir kit quirúrjico + 봉합키트 사용 허가 - Training level required to use a Surgical Kit. - 縫合キットの使用に訓練レベルを必要とさせます。 + Training level required to use a surgical kit. + 手術キットの使用に必要な医療スキルのレベルを設定します。 + Définit la qualification médicale requise pour utiliser la trousse chirurgicale. + Уровень медицинской подготовки, необходимый для использования Хирургического набора. + É necessária uma qualificação médica para usar Kit Cirúrgico + 要受過多少程度的醫療訓練才能使用手術包。 + 使用手术包所需的医疗水平。 + Livello di formazione richiesto per l'utilizzo di un Kit Chirurgico. + Úroveň výcviku pro použití sešívací sady. + Poziom wyszkolenia wymagany do korzystania z Zestawu Chirurgicznego. + 'Fähigkeiten-Level', das benötigt wird um ein Operations-Set zu nutzen. + Cerrahi kit kullanmak için gerekli eğitim seviyesi. + Nivel de entrenamiento requerido para usar el kit quirúrgico + 봉합키트를 사용하는데 필요한 등급을 정합니다. Locations Surgical Kit - 縫合キットの使用可能場所 + 手術キットの使用可能な場所 + Lieux trousse chirurgicale + Места использования Хирургического набора + Locais para Kit Cirúrgico + 手術包使用地點 + 手术包使用地点 + Luoghi Kit Chirurgico + Nastavuje kde může být sešívací sada použita + Miejsca użycia Zestawu Chirurgicznego + Orte für Operations-Set + Cerrahi Kitin kullanılabileceği yerler + Localización de los kits quirúrgicos + 봉합키트 사용 장소 - Controls where a Surgical Kit can be used. - 縫合キットが使える場所を決定します。 + Controls where a surgical kit can be used. + 手術キットが使える場所を制御します。 + Définit les lieux où l'usage de la trousse chirurgicale est autorisé. + Контролирует, где можно использовать Хирургический набор + Controle onde o Kit Cirúrgico pode ser utilizado. + 控制何處能使用手術包 + 控制何地能使用手术包 + Controlla dove può essere usato un Kit Chirurgico. + Nastavuje zda má být sešívací sada spotřebována po použití. + Kontroluje, gdzie można użyć Zestawu Chirurgicznego. + Legt fest, wo ein Operations-Set genutzt werden kann. + Cerrahi Kitin nerelerde kullanılabileceğini kontrol eder + Controla donde puede usarse un kit quirúrgico. + 봉합키트를 사용할 수 있는 장소를 정합니다. Consume Surgical Kit - 縫合キットの消費 + 手術キットの消費 + Trousse chirurgicale consommable + Израсходовать Хирургический набор + Kit Cirúrgico Consumível + 手術包為消耗品 + 手术包是否被消耗 + Consuma Kit Chirurgico + Spotřebuj sešívací sadu + Zużycie Zestawów Chirurgicznych + Verbrauche Operations-Set + Consumir kit quirúrgico + 봉합키트 소모 - Controls whether a Surgical Kit should be consumed after use. - 縫合キットの使用後に消費するかどうかを決定します。 + What should be consumed after use. + Legt fest, ob etwas nach der Anwendung verwendet werden soll. + Controlla se un Kit Chirurgico viene consumato dopo l'uso. + Qué debe ser consumido despues de su uso. + 使用後に何を消費するか設定します。 + Co powinno zostać zużyte po zastosowaniu. + 봉합키트를 1회성 소모품으로 설정할 지 여부를 결정합니다. + Ce qui doit être consommé après l'utilisation. + Решите, следует ли использовать набор для наложения швов в качестве одноразового расходного материала. Self Stitching - Suturer soi-même + Réaliser des sutures sur soi-même + Auto-Cirurgia + 自己縫合 + 自我縫合 + 自我缝合 + Auto Cucitura + Samo-zašívání + Zszywanie własnych ran + Selbstnähen + Зашитие своей раны + Auto cosido + 봉합키트 자가 사용 Enables the use of surgical kits to stitch oneself. - Autorise l'utilisation de la trousse chirugical sur soi-même + Autorise l'utilisation de la trousse chirugicale sur soi-même. + Permite o uso de Kit Cirúrgico em si mesmo. + 手術キットを使い自らを縫合できるようにします。 + 啟用是否能自己使用手術包來縫合自己的傷口。 + 启用是否能够使用手术包进行自我缝合。 + Umožňuje použití sešívací sady na sebe sama. + Umożliwia użycie Zestawu Chirurgicznego na sobie. + Permette di ricucire se stesso con un Kit Chirurgico. + Ermöglicht die Benutzung des Operations-Sets, um sich selbst zu nähen. + Включает использование хирургического набора на себе. + Permite el uso de kits quirúrgicos sobre uno mismo + 봉합키트를 사용자 본인에게 쓸 수 있는지를 정합니다. + + + Wound Stitch Time + Durée d'interaction - Sutures + 縫合の所要時間 + Tiempo de sutura de herida + Время зашивания ран + Czas szycia rany + Benötigte Zeit, um Wunden zu nähen + Tempo di suturazione ferita. + 伤口缝合时间 + 상처 봉합 시간 + + + Time, in seconds, required to stitch a single wound. + Définit le temps nécessaire à la suture d'une plaie (en secondes). + 縫合に掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para suturar una única herida. + Время, необходимое для зашивания одной раны (в секундах). + Czas w sekundach potrzebny na zaszycie pojedyńczej rany. + Zeit in Sekunden, um eine einzelne Wunde zu nähen. + Tempo in secondi richiesto per suturare una singola ferita. + 缝合一个伤口所需的时间(秒) + 초 단위로, 한 상처를 봉합하는데 걸리는 시간을 설정합니다. + + + Self IV Transfusion + Eigennutzung von Bluttransfusionen + Внутривенное переливание на себе + 自己 IV 輸液 + Pose d'IV sur soi-même + Autotransfusão de IV + 自我注射點滴 + 自我静脉输液 + Samoaplikace IV transfuze + Samotransfuzja IV + Trasfusione endovena su se stessi + Autotransfusión intravenosa (IV) + 수액용기 자가 사용 + + + Enables the use of IV transfusions on oneself. + Erlaube Bluttransfusionen an sich selbst zu benutzen + Позволяет использовать внутривенные переливания на себе + 自らに対して IV 輸液を可能にします。 + Active la possibilité de s'auto-poser des IVs. + Permite utilizar bolsas de IV para transfusão em si mesmo + 啟用是否能對自己注射點滴 + 启用是否能够自我静脉输液 + Umožňuje aplikovat IV transfuze na sama sebe. + Pozwala przetoczyć płyny IV samemu sobie + Abilita l'applicazione di Fleboclisi Endovenose su se stessi. + Habilita el uso de las transfusiones IV sobre uno mismo + 수액용기를 사용자 본인에게 쓸 수 있는지를 정합니다. + + + Allow Unconscious Body Bag + Housse mortuaire - Autoriser patients inconscients + 無意識者の遺体袋への収容許可 + Permitir bolsa para cuerpos inconsciente + Разрешить упаковывать пациентов без сознания в мешки для трупов + Nieprzytomni w worku na ciało + Erlaube Benutzung des Leichensackes mit bewusstlosen Personen + Permetti di insaccare un paziente svenuto + 允许昏迷者装入尸袋 + 기절 인원 시체 운반용 부대에 옮기기 + + + Enables placing an unconscious patient in a body bag. + Active la possibilité de placer des patients inconscients dans les housses mortuaires.\nAttention : le cas échéant cela provoquera la mort du patient. + 無意識状態のプレイヤーを遺体袋へ入れることが出来る様にします。 + Permitir colocar a un paciente inconsciente en una bolsa para cuerpos. + Разрешает упаковывать пациентов без сознания в мешки для трупов. + Zezwalaj na pakowanie nieprzytomnych osób do worka na ciało. + Aktiviert, Bewusstlose in Leichensack zu legen. + Permette l'uso della sacca per morti anche su pazienti che sono solo svenuti (causa la morte del paziente) + 能够将昏迷的伤员装入尸袋中。 + 기절 상태의 인원을 시체 운반용 부대에 옮겨 담을 수 있는 지를 정합니다. + + + Allow Grave Digging + Zezwalaj na kopanie grobów + 무덤 파기 허용 + Erlaube Graben von Gräbern + Permetti scavo di tombe + Permitir cavar tumbas + Autoriser le creusement de tombes + 墓掘りを許可 + Разрешить рытье могил + + + Enables digging graves to dispose of corpses. + Umożliwia kopanie grobów w celu pozbycia się zwłok. + 시체를 처리하기 위해 무덤을 파는 것을 허용합니다. + Erlaubt das Graben von Gräbern um Leichen zu entsorgen. + Permette lo scavo di tombe per seppellire cadaveri. + Habilita cavar tumbas para deshacerse de los cadáveres. + Active la possibilité de creuser des tombes pour enterrer les cadavres. + 墓を掘って死体を処理できるようになります。 + Позволяет рыть могилы для захоронения трупов. + + + Only if dead + Tylko kiedy martwy + 죽었을 때에만 + Nur wenn tot + Solo se morti + Solo si está muerto + Uniquement s'il est mort + 死体のみ + Только если мертв + + + Create Grave Markers + Erstelle Grabmal + Crea lapide + Crear Tumba + Utwórz Nagrobek + 무덤 마커 생성 + Créer des pierres tombales + 墓標を作成 + Создайте надгробные знаки + + + Enables the creation of grave markers when digging graves. + Erstellt Grabmale beim Graben von Gräbern. + Permette la creazione di una lapide su una tomba scavata. + Habilita la creación de Tumbas al cavar tumbas. + Umożliwia tworzenie nagrobków podczas kopania grobów. + 무덤을 파낼 때 무덤 마커를 표시할 수 있습니다. + Active la création de pierres tombales lors de l'enterrement de cadavres. + 墓を掘った際、墓標を作成できるようにします。 + Позволяет создавать надгробные знаки при рытье могил. + + + Allow IV Transfusion + Erlaube Bluttransfusionen + Permetti Fleboclisi EV + Zezwalaj na przetaczanie płynów IV + Pose de perfusions autorisée pour + 允許操作點滴 + 允许静脉输液 + IV 輸液の制限 + Povolit IV transfuzi + Разрешить внутривенное переливание + Permitir transfusión de IV + 수액용기 사용 허가 + + + Training level required to transfuse IVs. + 'Fähigkeiten-Level', das benötigt wird, um Blut zu transfundieren. + Formazione richiesta per applicare Fleboclisi Endovenose. + Poziom wyszkolenia potrzebny aby móc przetaczać płyny IV. + Définit la qualification médicale requise pour poser des perfusions intraveineuses. + 要有何種醫療水準才可注射點滴。 + 静脉输液所需的医疗水平。 + IV 輸液を行うのに必要な医療スキルのレベルを設定します。 + Úroveň výcviku nutná pro IV transfuzi. + Уровень навыка, требуемый для осуществления внутривенного переливания. + Nivel de capacitación requerido para transfusiones de IV. + 수액용기를 사용하는데 필요한 등급을 정합니다. + + + Locations IV Transfusion + IV輸液の可能な場所 + Ubicación para transfusiones IV + Lieux perfusions IV + Места введения пакетов внутривенного переливания + Miejsca do transfuzji IV + Orte an denen IV-Transfusionen angelegt werden können + Luoghi Fleboclisi EV + 静脉输液地点 + 수액용기 사용 장소 + + + Controls where IV transfusions can be performed. + IV 輸液を行える場所を制御します。 + Controla dónde pueden ser realizadas las transfusiones IV. + Définit les lieux où la pose de perfusions est autorisée. + Определяет к каким частям тела разрешено применять пакеты внутренного переливания. + Kontroluje w jakich miejscach można robić transfuzje IV. + Kontrolliert, wo IV-Transfusionen durchgeführt werden können. + Luoghi in cui è possibile applicare Fleboclisi Endovenose. + 控制何地可以静脉输液 + 수액용기를 사용할 수 있는 장소를 정합니다. Convert Vanilla Items Standard Arma-Equipment in ACE-Items umwandeln - Конвертировать ванильные медикаменты - 標準アイテムの変換 + Преобразовывать ванильные медикаменты + バニラアイテムの変換 + Convertir les objets vanilla + Converter itens vanilla + 轉換原版物品 + 转换原版物品 + Converti oggetti vanilla + Přeměnit zdravotnické předměty ze základní hry + Konwertuj przedmioty z vanili + Convierte los objetos estándars de A3 en objetos ACE + 바닐라 아이템 전환 Controls whether vanilla medical items are converted to ACE Medical items, removed only, or ignored. Legt fest, ob Standard Medic-Equipment in ACE-Equipment umgewandelt oder entfernt wird - ゲーム標準の医療アイテムを ACE 医療アイテムへ変換、削除、そのままにするかを決定します。 + ゲーム標準の医療アイテムをACE医療アイテムへ変換するか、削除するか、そのままにするかを制御します。 + Détermine si les objets médicaux vanilla sont convertis en objets médicaux ACE, s'ils sont simplement retirés, ou s'ils sont ignorés. + Определяет, что делать с ванильными медикаментами: преобразовать в медикаменты ACE, удалить или проигнорировать. + Controla se itens médicos vanilla serão convertidos para itens do ACE, removidos ou ignorados. + 控制是否轉換原版的醫療物資成ACE的醫療物資,或者單純移除或無視。 + 控制是否转换原版的医疗物品成 ACE 的医疗物品,或者单纯移除/无视。 + Controlla se gli oggetti medicali vanilla vengono convertiti in oggetti medicali ACE, rimossi o ignorati. + Nastavuje zda zdravotnické předměty ze základní hry budou přeměněny na ACE předměty, odstraněny nebo ignorovány. + Kontroluje, czy podstawowe przedmioty medyczne z Arma są konwertowane na przedmioty medyczne ACE, tylko usuwane lub ignorowane. + Controla si los artículos médicos básicos se convierten en artículos médicos de ACE, solo se eliminan o se ignoran. + 바닐라 치료 아이템을 ACE 치료 물자로 바꿀지, 제거할지, 무시할지를 정합니다. Remove Only - 削除 + 削除のみ + Retirer uniquement + Удалять + Apenas Remover + 單純移除 + 仅移除 + Rimuovi solo + Pouze odstranit + Tylko Usuwaj + Nur Entfernen + Solo eliminar + 바닐라 제거 Enable Litter - Включить мусор + Вкл. мусор Aktywuj odpadki Activar restos médicos Abfälle aktivieren Povolit odpadky - Ativar lixo médico + Permitir Lixo Médico Activer les détritus Szemét engedélyezése - Abilita Barella + Abilita rifiuti 廃棄物の有効化 + 啟用醫療用廢棄物 + 启用医疗废弃物 + Çöpleri Etkinleştir + 의료폐기물 생성 활성화 Enables the creation of litter upon treatment. 治療後に廃棄物の生成を有効化します。 + Active la généreration de détritus (emballages, pansements usagés...) suite à un traitement. + Разрешает создание медицинского мусора при лечении. + Permite a criação de lixo médico durante o tratamento. + 啟用醫療後剩下的醫療用廢棄物。 + 启用在治疗后能够产生医疗垃圾。 + Abilita la creazione di rifiuti al momento del trattamento. + Umožňuje vytvořit odpadky při léčbě. + Umożliwia tworzenie śmieci po przeprowadzaniu zabiegu. + Ermöglicht das Produzieren von Abfall während einer Behandlung. + Habilita la opción de basura durante el tratamiento + 치료시 의료폐기물을 주위에 생성하는지를 결정합니다. Max Litter Objects - 最大廃棄物数 + 廃棄物最大数 + Nombre maximum de détritus + Макс. кол-во мусора + Máximo de Objetos de Lixo + 最大醫療用廢棄物數量 + 最大医疗垃圾数量 + Numero massimo di rifiuti + Maximum odpadků + Maksymalna Ilość Śmieci + Maximale Anzahl an Abfall-Objekten + Maks. Çöp Objesi + Número máximo de objetos de basura + 최대 의료폐기물 수 Sets the maximum number of litter objects which can be spawned, excessive amounts can cause FPS lag. - 生成される最大廃棄物数を設定できます。極端に増やすと FPS ラグを引き起こします。 + 生成される廃棄物の最大数を設定できます。極端に増やすと 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. + 設定最大可以產生的醫療用廢棄物數量,極端的數量的話可能導致幀數下降。 + 设置可以生成的最大垃圾数量,数量过多会导致 FPS 延迟。 + Imposta il numero massimo di rifiuti che possono essere generati, quantità eccessive possono diminuire gli FPS. + Nastavuje maximum odpadků, které se mohou objevit. Vysoká hodnota m§že negativně ovlivnit FPS. + Definiuje maksymalną liczbę śmieci, które mogą zostać stworzone, nadmierne ilości mogą powodować spadki FPS. + Bestimmt die maximal Anzahl an Abfall-Objekten, die erstellt werden können. Eine zu hohe Anzahl kann Lag verursachen. + Establece el número máximo de objetos de basura que se pueden generar, cantidades excesivas pueden causar saltos de FPS. + 최대 의료폐기물의 스폰 수를 결정합니다. 많은 양은 프레임의 저하로 이어질 수 있습니다. Litter Lifetime 廃棄物寿命 + Durée d'affichage des détritus + Время жизни мусора + Duração de Lixo + 醫療用廢棄物時長 + 医疗垃圾寿命 + Tempo di presenza rifiuti + Životnost odpadků + Czas trwania Śmieci + Abfall Anzeigedauer + Cöp Silinme Süresi + Tiempo de vida de la basura + 의료폐기물 지속시간 Controls the lifetime of litter objects, in seconds. -1 is forever. - 廃棄物の寿命を秒で決定できます。-1 で永遠です。 + 廃棄物の寿命を秒単位で制御します。-1 にすると恒久的になります。 + Définit la durée d'affichage des détritus, en secondes. Durée illimitée : -1. + Управляет временем жизни объектов мусора в секундах. -1 означает Навсегда. + Controla o tempo de vida de objetos de lixo criados em segundos. -1 é para sempre. + 控制醫療用廢棄物的時長,以秒為單位。設定為-1則是永不刪除。 + 控制医疗垃圾物体的生命周期,以秒为单位。-1则是永不删除。 + Controlla la durata di vita dei rifiuti in secondi. -1 è per sempre. + Nastavuje za jak dlouho zdravotnické odpadky zmizí. -1 je navždy. + Kontroluje czas trwania śmieci w sekundach. -1 pozostawia je na zawsze. + Kontrolliert die Anzeigedauer von Abfall-Objekten in Sekunden. -1 ist für immer. + Controla el tiempo de vida de la basura (segundos). -1 es igual a permanentes + 의료폐기물의 지속시간을 초 단위로 결정합니다. -1의 경우 사라지지 않습니다. Anyone @@ -279,29 +1136,234 @@ Jeder Kdokoliv Qualquer um - Tous + Tout le monde Akárki Chiunque だれでも 모두 任何人 任何人 + Hiçbiri Medics 衛生兵 + Infirmiers + Медики + Médicos + 醫療兵 + 医疗兵 + Medici + Medikové + Medycy + Sanitäter + Sıhhiye + Médicos + 의무병 Doctors 医師 + Médecins + Доктора + Doutores + 軍醫 + 军医 + Dottori + Doktoři + Doktorzy + Ärzte + Doktor + Doctores + 군의관 Medical Facilities 医療施設 + Installations sanitaires + Госпитали + Instalações Médicas + 醫療設施 + 医疗设施 + Strutture mediche + Zdravotnické zařízení + Obiekty Medyczne + Medizinische Einrichtungen + Tıbbi tesisler + Instalaciones médicas + 의료 시설 Vehicles & Facilities 車両 & 施設 + Véhicules & installations sanitaires + Техника и госпитали + Veículos e Instalações Médicas + 車輛與設施 + 载具&设施 + Zdravotnická zařízení a vozidla + Veicoli e strutture + Pojazdy i Obiekty + Fahrzeuge und Einrichtungen + Araçlar ve Tesisler + Vehículos e instalaciones médicas + 의료 차량 및 시설 + + + CPR Success Chance Minimum + RCP - Chance minimale de réussite + Мин. шансы успеха СЛР + Szansa na powodzenie CPR - Minimum + 心肺蘇生(CPR)の最低成功確率 + HLW Minimale Erfolgschance + RCP - Prob. Successo Minima + 心肺复苏的最低成功率 + 최소 심폐소생술 성공 가능성 + RCP posibilidad mínima de resultado satisfactorio + + + CPR Success Chance Maximum + RCP - Chance maximale de réussite + Макс. шансы успеха СЛР + Szansa na powodzenie CPR - Maksimum + 心肺蘇生(CPR)の最高成功確率 + HLW Maximale Erfolgschance + RCP - Prob. Successo Massima + 心肺复苏的最高成功率 + 최대 심폐소생술 성공 가능성 + RCP posibilidad máxima de resultado satisfactorio + + + Minimum probability that performing CPR will restore heart rhythm.\nThis minimum value is used when the patient has at least "Lost a fatal amount of blood".\nAn interpolated probability is used when the patient's blood volume is between the minimum and maximum thresholds. + Probabilité minimale de rétablir un rythme cardiaque suite à une RCP.\nCette valeur minimale est définie pour un patient à l'état "A perdu une quantité critique de sang".\nUne interpolation est faite entre la chance minimale et maximale, en fonction du volume sanguin du patient. + Probabilità minima di successo per una RCP nel ristabilire il battito cardiaco.\nQuesto valore minimo è usato quando il paziente ha perso almeno una 'quantità fatale di sangue', una probabilità intermedia è usata per volumi di sangue intermedi. + Минимальная вероятность того, что выполнение искусственного дыхания восстановит сердечный ритм.\nЭто минимальное значение используется, когда пациент, по крайней мере, получил статус "Фатальная кровопотеря".\n Интерполированная вероятность используется, когда объем крови пациента находится между минимальным и максимальным порогами. + Minimalna wartość szansy na to że CPR przywróci bicie serca.\nTa minimalna wartość jest używana gdy pacjent ma status "Stracił krytyczną ilość krwi".\nInterpolowana wartość szansy jest używana gdy pacjent ma poziom krwi będący pomiędzy minimum a maksimum. + 心肺蘇生(CPR)を行うことで脈拍が回復する最低成功確率を設定します。\nこの値は患者が"致命的な程失血している"時に使用されます。\n患者の血液量が最低値と最大値の間だった場合は、補完確率が適用されます。 + Minimale Wahrscheinlichkeit, dass die Durchführung einer HLW den Herzrhythmus wiederherstellt.\nDieser Mindestwert wird verwendet, wenn der Patient mindestens "eine tödliche Menge Blut verloren" hat.\nEine interpolierte Wahrscheinlichkeit wird verwendet, wenn das Blutvolumen des Patienten zwischen dem minimalen und dem maximalen Schwellenwert liegt. + 实施心肺复苏恢复心律的最小可能性。\n当伤员至少有"致命失血量"时,就取该最小值。\n当伤员的血量介于最小和最大阈值之间时,将使用插值概率。 + 심폐소생술 시 제일 낮은 성공 가능성을 결정합니다.\n이 가능성은 환자가 최소 "심각한 양의 혈액을 잃음"일 때 사용됩니다. + Probabilidad mínima de que realizar RCP restaure el ritmo cardíaco.\n Este valor mínimo es utilizado cuando el paciente tiene al menos "Pérdida fatal de sangre".\n Una probabilidad interpolada es usada cuando el volumen de sangre del paciente está entre el umbral mínimo y máximo. + + + Maximum probability that performing CPR will restore heart rhythm.\nThis maximum value is used when the patient has at most "Lost some blood".\nAn interpolated probability is used when the patient's blood volume is between the minimum and maximum thresholds. + Probabilité maximale de rétablir un rythme cardiaque suite à une RCP.\nCette valeur maximale est définie pour un patient à l'état "A perdu une faible quantité de sang".\nUne interpolation est faite entre la chance minimale et maximale, en fonction du volume sanguin du patient. + Probabilità massima di successo per una RCP nel ristabilire il battito cardiaco.\nQuesto valore massimo è usato quando il paziente ha perso meno di 'un po' di sangue', una probabilità intermedia è usata per volumi di sangue intermedi. + Максимальная вероятность того, что выполнение искусственного дыхания восстановит сердечный ритм.\nЭто максимальное значение используется, когда пациент, по крайней мере, получил статус "Фатальная кровопотеря".\n Интерполированная вероятность используется, когда объем крови пациента находится между минимальным и максимальным порогами. + Maksymalna wartość szansy na to że CPR przywróci bicie serca.\nTa maksymalna wartość jest używana gdy pacjent ma status "Stracił trochę krwi".\nInterpolowana wartość szansy jest używana gdy pacjent ma poziom krwi będący pomiędzy minimum a maksimum. + 心肺蘇生(CPR)を行うことで脈拍が回復する最高成功確率を設定します。\nこの値は患者が"いくらか失血している"時以上の場合に使用されます。\n患者の血液量が最低値と最大値の間だった場合は、補完確率が適用されます。 + Maximale Wahrscheinlichkeit, dass die Durchführung einer HLW den Herzrhythmus wiederherstellt.\nDieser Maximalwert wird verwendet, wenn der Patient höchstens "Blut verloren" hat.\nEine interpolierte Wahrscheinlichkeit wird verwendet, wenn das Blutvolumen des Patienten zwischen dem minimalen und dem maximalen Schwellenwert liegt. + 实施心肺复苏恢复心律的最大可能性。\n当伤员最多“失血一些”时,就取该最大值。\n当伤员的血量介于最小和最大阈值之间时,将使用插值概率。 + 심폐소생술 시 제일 높은 성공 가능성을 결정합니다.\n이 가능성은 환자가 최소 "혈액을 조금 잃음"일 때 사용됩니다. + Probabilidad máxima de que realizar RCP restaure el ritmo cardíaco.\n Este valor máximo es utilizado cuando el paciente tiene como mucho "Pérdida de un poco de sangre".\n Una probabilidad interpolada es usada cuando el volumen de sangre del paciente está entre el umbral mínimo y máximo. + + + CPR Treatment Time + RCP - Durée d'interaction + RCP - Durata di interazione + 心肺蘇生(CPR)の所要時間 + Tiempo de tratamiento de RCP + Время проведения СЛР + Czas potrzebny na wykonanie CPR + HLW Behandlungsdauer + 心肺复苏时间 + 심폐소생술 시행 시간 + + + Time, in seconds, required to perform CPR on a patient. + Définit le temps nécessaire à la mise en œuvre d'une RCP (en secondes). + Tempo in secondi richiesto per effettuare RCP su un paziente. + 心肺蘇生(CPR)に掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para realizar RCP en un paciente. + Время, необходимое для проведения сердечно-лёгочной реанимации (СЛР) (в секундах). + Czas w sekundach jaki jest potrzebny do wykonania CPR na pacjencie. + Zeit in Sekunden, die benötigt wird, um eine HLW durzuführen. + 对伤员实施心肺复苏所需的时间(秒) + 초 단위로, 심폐소생술을 진행하는 시간을 결정합니다. + + + Holster Required + 武器の扱い + 需要收起武器 + 需要收起武器 + Rengainer obligatoirement + Fondina richiesta + Vyžadováno schování zbraně + Wymagana broń w kaburze + Holstern benötigt + Необходимость убирать оружие + Requiere enfundar + 무장여부 + + + Controls whether weapons must be holstered / lowered in order to perform medical actions.\nExcept Exam options allow examination actions (checking pulse, blood pressure, response) at all times regardless of this setting. + 何らかの治療をするには武器を下げるか収める必要があるかを設定します。\nなお次の診断行動は設定で例外できます: 脈拍の確認、血圧の確認、反応の確認 + 控制是否要先放下或把武器放入武器套才能做出醫療行為。\n除了診斷 - 允許未放下或未放入的情況下進行一連串的診斷(檢查脈搏,血壓,反應)。 + 控制是否要先放下或把武器放起才能做出医疗行为。\n除了诊断—允许未放下或未收起的情况下进行一连串的诊断(检查脉搏,血压,反应)。 + Définit si les armes doivent être rengainées ou abaissées avant de pouvoir effectuer des actes médicaux.\nLes options "sauf examens" autorisent les examens (vérification du pouls, de la tension artérielle, de l'état de conscience) en toutes circonstances. + Nastavuje zda musí být zbraň schovaná/snížená pro provádění zdravotnických úkonů.\nKromě Diagnózy - Umožňuje diagnostické akce (kontrola srdečního tepu, tlaku krve a reakci pacienta) vždy bez ohledu na nastavení schování zbraně. + Kontroluje, czy broń musi być schowana/opuszczona w celu wykonania leczenia pacjenta.\n Za wyjątkiem diagnozowania - umożliwia wykonywanie czynności kontrolnych (sprawdzanie tętna, ciśnienia krwi, reakcji) przez cały czas, niezależnie od ustawienia Wymagana broń w kaburze. + Controlla se le armi devono essere tenute nella fondina / abbassate per poter eseguire le azioni mediche.\Eccetto l'esame - Permette azioni di esame (controllo del polso, della pressione sanguigna, della risposta) in ogni momento indipendentemente dall'impostazione della fondina richiesta. + Kontrolliert, ob Waffen geholstert/gesenkt werden müssen, um medizinische Aktionen durchzuführen.\nAusgenommen die eingestellten Untersuchungsoptionen erlauben Diagnose-Aktionen (Überprüfung von Puls, Blutdruck, Reaktion) jederzeit. + Нужно ли убирать оружие для проведения медицинских действий.\nОпция «Проверка разрешена» разрешает проверять пульс, кровяное давление или реакцию независимо от этого параметра. + Controla si las armas deben estar enfundadas / bajadas para realizar acciones médicas. \n Excepto Las opciones de examen permiten acciones de examen (control del pulso, presión arterial, respuesta) en todo momento, independientemente de esta configuración. + 치료하기에 앞서 손에서 무기를 집어넣을 지/내릴지를 결정합니다.\n검사제외 옵션의 경우 맥박 확인, 혈압 확인, 반응 확인은 앞선 옵션에 구애받지 않고 사용할 수 있습니다. + + + Lowered or Holstered + 下げるか収める + 放低或者收起 + 放低或者收起 + Abaisser ou rengainer + Abbassato o nella fondina + Snížena nebo Schována + Opuszczona lub w kaburze + Gesenkt oder Geholstert + Опущено или убрано + Bajada o enfundada + 내리거나 집어넣기 + + + Lowered or Holstered (Except Exam) + 下げるか収める (診断行動は除外) + 放低或者收起(除了診斷) + 放低或者收起(除了诊断) + Abaisser ou rengainer (sauf examens) + Abbassato o nella fondina (eccetto l'esame) + Snížena nebo Schována (kromě Diagnózy) + Opuszczona lub w kaburze (oprócz diagnozowania) + Gesenkt oder Geholstert (Ausnahme Untersuchung) + Опущено или убрано (Проверка разрешена) + Bajada o enfundada (excepto examen) + 내리거나 집어넣기(검사 제외) + + + Holstered Only + 収めた時のみ + 只能收起 + 只能收起 + Rengainer seulement + Solo nella fondina + Pouze Schována + Tylko w Kaburze + Nur geholstert + Только убрано + Solo enfundada + 집어넣기 + + + Holstered Only (Except Exam) + 収めた時のみ (診断行動は除外) + 只能收起(除了診斷) + 只能收起(除了诊断) + Rengainer seulement (sauf examens) + Solo nella fondina (eccetto esame) + Pouze Schována (kromě Diagnózy) + Tylko w Kaburze (oprócz diagnozowania) + Nur geholstert (Ausnahme Untersuchung) + Только убрано (Проверка разрешена) + Solo enfundada (excepto examen) + 집어넣기(검사 제외) [ACE] Medical Supply Crate (Basic) @@ -313,11 +1375,12 @@ [ACE] Caixa com suprimentos médicos [ACE] Caisse médicale (basique) [ACE] Orvosi láda (Alap) - [ACE] Cassa Rifornimenti Medici (Basico) + [ACE] Cassa Rifornimenti Medici (Basici) [ACE] 医療物資箱 (ベーシック) [ACE] 의료 물자 (기본) - [ACE] 医疗补给箱(基本) + [ACE] 医疗补给箱(基础) [ACE] 醫療補給箱(基本) + [ACE] Tıbbi Malzeme Kutusu (Temel) [ACE] Medical Supply Crate (Advanced) @@ -329,25 +1392,27 @@ [ACE] Caixa com suprimentos médicos (Avançados) [ACE] Caisse médicale (avancée) [ACE] Orvosi láda (Fejlett) - [ACE] Cassa Rifornimenti Medici (Avanzato) + [ACE] Cassa Rifornimenti Medici (Avanzati) [ACE] 医療物資箱 (アドバンスド) [ACE] 의료 물자 (고급) - [ACE] 医疗补给箱(进阶) + [ACE] 医疗补给箱(高级) [ACE] 醫療補給箱(進階) + [ACE] Tıbbi Malzeme Kutusu (Gelişmiş) Whether or not the object will be a medical vehicle. Czy pojazd ma być pojazdem medycznym? - L'oggetto in questione sarà un veicolo medico o meno. + Se l'oggetto in questione sarà un veicolo medico. Legt fest, ob das Objekt ein Sanitätsfahrzeug ist. Es un vehículo médico? - Détermine si c'est un véhicule sanitaire. + Définit s'il s'agit d'un véhicule sanitaire. Se o objeto será ou não um veículo médico Будет ли объект считаться медицинским транспортом. - どれでも、またはオブジェクトを医療車両として割り当てます。 - 무엇이 되었던간에 이 목록에 있는 물체는 의료 차량이 됩니다. - 是否使该载具为医疗载具? + 車両をを医療車両として割り当てます + 이 물체는 의료 차량이 됩니다. + 是否使该载具为医疗载具? 是否使該載具為醫療載具? + Rozhoduje zda bude objekt zdravotnickým vozidlem. Medical training @@ -355,14 +1420,15 @@ Addestramento Medico Sanitätsausbildung Entrenamiento médico - Entraînement médical + Choix du niveau de compétence médicale de l'unité. Lékařský výcvik Treino médico Медицинская подготовка - 衛生訓練 + ユニットの医療スキルのレベルを定義します。 의료 훈련 医疗训练 醫療訓練 + Tıbbi eğitim Is Medic @@ -372,13 +1438,14 @@ Ist Sanitäter Je zdravotník É médico - Est infirmier + Qualification médicale Orvos-e - E' Medico - 衛生兵に + È Medico + 衛生兵にする 의무병 是医疗兵 是醫療兵 + Sıhhiye This module allows you to assign the medic class to selected units. @@ -386,15 +1453,16 @@ 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 médicale 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. - Questo modulo ti permette di assegnare la classe Medico alle unità selezionate. - 選択されたユニットを衛生兵として指定します。 - 이 모듈은 선택한 보직이 의무병을 할 수 있게 해줍니다. + Questo modulo ti permette di assegnare la classe di Medico alle unità selezionate. + このモジュールは選択されたユニットを衛生兵として指定します。 + 이 모듈로 선택한 유닛을 의무병으로 만들 수 있습니다. 本模块可让被同步的单位成为医疗兵 本模塊可讓被同步的單位成為醫療兵 + Bu modül, Medic sınıfını seçilen birimlere atamanıza izin verir. None @@ -404,13 +1472,14 @@ Keine Žádný Nada - Aucun + Aucune Nincs Nessuno なし - 없음 + 아님 + Hiçbiri Regular Medic @@ -423,10 +1492,11 @@ Infirmier Hagyományos orvos Medico Regolare - 通常の衛生兵 - 일반 의무병 + 一般衛生兵 + 의무병 普通医疗兵 普通醫療兵 + Normal Sıhhıye Is Medical Vehicle @@ -436,13 +1506,14 @@ Ist medizinisches Fahrzeug Zdravotnické vozidlo É um veículo médico - Véhicule médical + Est un véhicule sanitaire Orvosi jármű-e - E' Veicolo Medico - 医療車両に + È Veicolo Medico + 医療車両とする 의료 차량 是医疗载具 是醫療載具 + Tıbbi Araç Is Medical Facility @@ -452,13 +1523,14 @@ Ist eine medizinische Einrichtung Zdravotnické zařízení É uma instalação médica - Est une installation médical + Est une installation sanitaire Orvosi létesítmény-e - E' Struttura Medica - 医療施設に + È Struttura Medica + 医療施設とする 의료시설 是医疗设施 是醫療設施 + Tıbbi Tesis Registers an object as a medical facility @@ -468,12 +1540,12 @@ 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 l'objet comme étant une installation sanitaire. Egy objektum orvosi létesítményként való regisztrálása Registra un oggetto come struttura medica - オブジェクトを医療施設として割り当てる + オブジェクトを医療施設として割り当てます 물체를 의료시설로 등록합니다 - 指定一个物件作为医疗设施 + 指定一个物体作为医疗设施 指定一個物件作為醫療設施 @@ -484,12 +1556,12 @@ 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) - 医師 (アドバンスド医療のみ) - 의사 (오직 고급 의료에서만) - 军医 (只限进阶医疗系统) + 医師 (上級衛生兵のみ) + 군의관 (오직 고급 의료에서만) + 军医(只限进阶医疗系统) 軍醫 (只限進階醫療系統) @@ -504,25 +1576,27 @@ Doktor Dottore 医師 - 의사 + 군의관 军医 軍醫 + Doktor Bandage (Basic) Bandage (Einfach) Повязка (обычная) Vendaje (Básico) - Pansement adhésif + Pansement individuel Bandaż (jałowy) - Obvaz (Standartní) + Obvaz (Standardní) Kötszer (Általános) - Bendaggio (base) + Bendaggio (Base) Bandagem(Básico) - 包帯 (緊急圧迫) + 包帯 (緊急圧迫止血) 붕대 (기본) - 基础绷带 + 绷带(基础型) 基礎繃帶 + Bandaj (Basit) Used to cover a wound @@ -535,10 +1609,11 @@ Usato per coprire una ferita Usado para cobrir um ferimento Slouží k překrytí poranění - 傷口を覆います - 상처를 덮을때 씁니다 + 傷を覆うために使用される + 상처를 덮을 때 씁니다 用于覆盖伤口 用於覆蓋傷口 + Bir yarayı kapatmak için kullanılır A dressing, that is a particular material used to cover a wound, which is applied over the wound once bleeding has been stemmed. @@ -548,109 +1623,116 @@ Pansement utilisé pour couvrir une blessure lorsque le saignement a été stoppé. Opatrunek materiałowy, używany do przykrywania ran, zakładany na ranę po zatamowaniu krwawienia. Egy különleges anyagú kötszer sebek betakarására, amelyet a vérzés elállítása után helyeznek fel. - Una benda apposita, utilizzata per coprire una ferita, la quale viene applicata su di essa una volta fermata l'emorragia. + Un bendaggio fatto apposta per coprire una ferita una volta fermata l'emorragia. Uma curativo, material específico para cobrir um ferimento que é aplicado assim que o sangramento é estancando. Obvaz je vhodným způsobem upravený sterilní materiál, určený k překrytí rány, případně k fixaci poranění. - 傷口を血液凝固剤で塞ぐようにできていて、使うと出血の原因を取りさります。 + 包帯(被覆材)、これは傷口を覆うためもので、傷口の上に貼ると出血を食い止める。 드레싱, 출혈을 막고서 상처를 덮기위해 쓰는 물건입니다. - 用于覆盖伤口以防止出血, 透过敷料的止血剂来让出血慢慢停止 + 用于覆盖伤口以防止出血,透过敷料的止血剂来让出血慢慢停止 用於覆蓋傷口以防止出血, 透過敷料的止血劑來讓出血慢慢停止 + Bir yarayı örtmek için kullanılan ve kanama başladıktan sonra yaranın üzerine uygulanan özel bir malzeme olan bir pansuman. - Packing Bandage - Mullbinde + Bandage (Packing) + Bandage (Mullbinde) Тампонирующая повязка Vendaje compresivo - Bande extensible + Bande compressive Bandaż (uciskowy) Nyomókötszer - Bendaggio compressivo + Bendaggio (Compressivo) Bandagem de Compressão Obvaz (Tlakový) - 弾性包帯 - 거즈 붕대 - 包扎绷带 - 包紮繃帶 + 包帯 (弾性) + 붕대 (거즈) + 绷带(包扎型) + 繃帶(包紮型) + Bandaj (Paket) 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ée pour panser les moyennes et grosses plaies, et freiner le saignement. Używany w celu opatrywania średnich i dużych ran oraz tamowania krwawienia. Dobrze radzi sobie z tamowaniem ran płatowych oraz postrzałowych. Közepestől nagyig terjedő sebek betakarására és vérzés elállítására használt kötszer - Usato su ferite medie o larghe per fermare emorragie. + Usato su ferite medie o grandi per fermare emorragie. Usado para o preenchimento de cavidades geradas por ferimentos médios e grandes e estancar o sangramento. Používá se k zastavení středních až silnějších krvácení - 粘着フィルム状で、普通から大きめなケガに使い止血します。 - 중형 또는 대형 상처를 채우고 출혈을 막기위해 쓰입니다 - 用于包扎中到大型伤口, 并防止出血 + 中程度から大きな傷の手当てと止血に使用される + 중형 또는 대형 상처를 채우고 출혈을 막기 위해 쓰입니다, + 用于包扎中到大型伤口,并防止出血 用於包紮中到大型傷口, 並防止出血 + Orta ila büyük yaraları sarmak ve kanamayı durdurmak için kullanılır 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. + Un bendaggio usato per coprire la ferita, fermare il sanguinamento e facilitarne la guarigione. Comprimere la ferita è una delle opzioni per gestire ferite politraumatiche. Ein Verband, um die Wunde abzudecken und die Wundheilung zu fördern. Wunden abdecken ist eine Option bei größeren Polytraumen Uma bandagem usada para preencher o ferimento para estancar o sangramento e facilitar a cicatrização. Preenchimento de feridas é uma opção em ferimentos de politrauma grandes. Tlakový obvaz se skládá se ze sterilní krycí vrstvy, na kterou je přiložena silná vrstva savého materiálu stlačující cévu v ráně a která je přitlačována k ráně a připevněna obinadlem. Slouží k zastavení silnějších krvácení. - 包帯を使うと出血元を塞ぎ、怪我の治癒を促進させます。また大きめ多発性外傷に対しても使えます。 - 출혈을 막고 상처를 치유하기 위한 붕대. 다발성외상의 경우 상처를 채우는것도 한 가지 방법입니다. - 用于包扎中到大型伤口, 并防止出血, 为在大型多处性伤口的选项之一! + 出血を止め、創傷の治癒を促進するために創傷を包む包帯。大きな多発外傷では、創部を包帯で覆うこともある。 + 출혈을 막고 상처를 치유하기 위한 붕대. 다발성외상의 경우 상처를 싸매는 것도 한 가지 방법입니다. + 用于包扎中到大型伤口,并防止出血, 为在大型多处性伤口的选项之一! 用於包紮中到大型傷口, 並防止出血, 為在大型多處性傷口的選項之一! + Kanamayı durdurmak ve yara iyileşmesini kolaylaştırmak için yarayı sarmak için kullanılan bir bandaj. Bandage (Elastic) Bandage (Elastisch) Повязка (давящая) Vendaje (Elástico) - Bande compressive + Bande extensible Bandaż (elastyczny) Obvaz (Elastický) Rögzító kötszer - Benda (elastica) + Benda (Elastica) Bandagem (Elástica) 包帯 (伸縮) 붕대 (압박) - 弹性绷带 - 彈性繃帶 + 绷带(弹性型) + 繃帶(彈性型) + Bandaj (Elastik) 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 Kit de Bandagem, Elástica Sada obvazů, Elastická - 包帯キット (伸縮) - 붕대, 압박 - 弹性绷带 - 彈性繃帶 + 包帯キット, 伸縮性 + 압박 붕대 키트 + 绷带(弹性型) + 一個彈性繃帶包 + Bandaj kiti, Elastik 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. - Permette di comprimere e aiutare la zone ferita. + Consente compressione uniforme e supporto aggiuntivo della zona ferita. Esta bandagem pode ser utilizada para comprimir o ferimento e diminuir o sangramento e garantir que o ferimento não abra em movimento. Hodí se k fixačním účelům a to i v oblastech kloubů. - 負傷部分へ最大の対応と止血を続けられます。 + 負傷部位を均等に圧迫し、保護する。 부상 부위를 골고루 압박해주면서 동시에 고정시켜 줍니다. 可对伤口持续压迫并固定以防止伤口情况变严重 可對傷口持續壓迫並固定以防止傷口情況變嚴重 + Yaralı bölgeye eşit bir sıkıştırma ve ekstra destek sağlar. Tourniquet (CAT) @@ -658,60 +1740,85 @@ Жгут Torniquete (CAT) Garrot (CAT) - Staza (typ. CAT) + Staza taktyczna (CAT) Škrtidlo (CAT) Érszorító (CAT) - Laccio emostatico (CAT) + Laccio Emostatico (CAT) Torniquete (CAT) 止血帯 (CAT) 지혈대 [CAT] - 军用止血带 + 止血带(军用型) 軍用止血帶 + Turnike (CAT) Slows down blood loss when bleeding Замедляет кровопотерю при кровотечении Reduce la velocidad de pérdida de sangre - Ralentit l'hémorragie + Ralentit l'hémorragie. Zmniejsza ubytek krwi z kończyn w przypadku krwawienia. Nie może być noszony zbyt długo ze względu na narastający ból z kończyny. Verringert den Blutverlust Lelassítja a vérvesztést vérzés esetén - Rallenta la perdita di sangue in caso di sanguinamento + Rallenta la perdita di sangue da un arto Reduz a velocidade da perda de sangue Zpomaluje ztráty krve při krvácení - 出血時に失血量を減らします。 + 出血時の失血を抑える 출혈 시 혈액손실을 늦춰줍니다 - 减缓失血的速度 + 减缓失血速度 減緩失血的速度 + Kanama sırasında kan kaybını yavaşlatır 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. + Un laccio emostatico usato per comprimere le vene e arterie per bloccare o rallentare la circolazione del sangue in un arto e quindi rallentare dissanguamenti. A aparelho que comprime as artérias e veias para diminuir a perda de sangue. Zařízení používané ke stlačení venózního a arteriálního oběhu. V důsledku dochází ke zpomalení toku krve a tedy i snížení ztrát krve. - 止血帯は静脈や動脈へ圧力をかけ、循環を遅らせることで血液の流れを遅し失血を防ぎます。 + 静脈と動脈の循環を圧迫するために使用される収縮装置で、実質的に血流を抑制または減速させ、血液の損失を減少させる。 정맥과 동맥을 압축시키켜 혈액순환을 억제 혹은 늦추게하여 혈액손실을 줄이는 도구입니다. - 用于压迫静脉与动脉的血液流动, 达到减缓失血速度的目的 + 用于压迫静脉与动脉的血液流动,以达到减缓失血速度的目的 用於壓迫靜脈與動脈的血液流動, 達到減緩失血速度的目的 + Kan akışını engelleyen veya yavaşlatan ve dolayısıyla kan kaybını azaltan venöz ve arteriyel dolaşımı sıkıştırmak için kullanılan bir daraltıcı cihaz. Splint Шина 添え木 + Attelle + Tala + 固定板 + Gessatura + Dlaha + Szyna + Schiene + 夹板 + Atel + Férula + 부목 Stabilizes a fractured limb Стабилизирует перелом конечности - 骨折部位を安定させます。 + 骨折した四肢を保持させる + Stabilise un membre fracturé. + Estabiliza um membro fraturado. + 固定骨折的部位 + Stabilizza un arto fratturato + Znehybňuje zlomenou končetinu + Stabilizuje złamaną kończynę + Stabilisiere einen Bruch + 用于固定骨折的肢体 + Kırık bir uzvu stabilize eder + Estabilizar un hueso roto + 아작난 사지를 고정시킵니다. - Morphine autoinjector + Morphine Autoinjector Morphium-Autoinjektor Морфин в пневмошприце Morfina auto-inyectable @@ -719,12 +1826,13 @@ Autostrzykawka z morfiną Auto-morfin Morfium autoinjektor - Autoiniettore di morfina + Autoiniettore di Morfina Auto-injetor de morfina - モルヒネ注射器 - 모르핀 자동주사기 + モルヒネ自動注射器 + 자동주사기 (모르핀) 吗啡自动注射器 嗎啡自動注射器 + Morfin otomatik enjektör Used to combat moderate to severe pain experiences @@ -737,55 +1845,56 @@ 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 + Adenosine Autoinjector Adenosin-Autoinjektor Asenosina auto-inyectable Autostrzykawka z adenozyną Auto-injecteur d'adénosine - Autoiniettore di adenosina + Autoiniettore di Adenosina Auto-adenosine Auto-injetor de Adenosina Аденозин в пневмошприце - アデノシン注射器 - 아데노신 자동주사기 + アデノシン自動注射器 + 자동주사기 (아데노신) 腺苷自动注射器 腺苷自動注射器 + Adenosin otomatik enjektörü Used to counter effects of Epinephrine Wird verwendet um die Symptome von Epiniphrin zu lindern Utilizada para contrarrestar los effectos de la Epinefrina Adenozyna. Stosowana do zwalczania efektów działania adrenaliny. - Utilisé pour contrer les effets de l'épinéphrine - Usato per contrastare l'effetto dell'epinefrina + Utilisé pour contrer les effets de l'épinéphrine. + Usato per contrastare l'effetto dell'Epinefrina Slouží jako protiváha Adrenalinu Usado para combater os efeitos da Epinefrina Используется для купирования эффектов адреналина - アドレナリンの反対の効果として使います。 + アドレナリンの作用に対抗するために使用される 에피네프린 대응책으로 쓰입니다 - 用来对付肾上腺素的影响 + 用于中和肾上腺素的影响 用來對付腎上腺素的影響 @@ -793,18 +1902,18 @@ 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 - Medicamento usato per contrastare l'effetto dell'epinefrina + 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 + Atropine Autoinjector Атропин в пневмошприце Atropina auto-inyectable Auto-injecteur d'atropine @@ -812,26 +1921,27 @@ Atropin-Autoinjektor Auto-atropine Atropin autoinjektor - Autoiniettore di atropina + Autoiniettore di Atropina Auto-injetor de Atropina - アトロピン注射器 - 아트로핀 자동주사기 + アトロピン自動注射器 + 자동주사기 (아트로핀) 阿托品自动注射器 阿托品自動注射器 + Atropin otomatik enjektör 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ů - 核・生物・化学兵器による汚染環境下にて使います。 - 핵,생물,화학 상황에 쓰입니다 + 核・生物・化学兵器(NBC)による汚染環境下で使用される + 화생방 상황에 쓰입니다 使用于核生化污染的情况 使用於核生化汙染的情況 @@ -839,20 +1949,20 @@ 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. - 核・生物・化学兵器による汚染環境下にて使います。 - 핵,생물,화학 상황에 쓰이는 군용 약품 - 军用神经解毒针, 用来应付核生化污染的情况. + 核・生物・化学兵器(NBC)による汚染環境下で軍が使用する薬品。 + 화생방 상황에 쓰이는 군용 약품 + 军用神经解毒针,用来应付核生化污染的情况。 軍用神經解毒針, 用來應付核生化汙染的情況. - Epinephrine autoinjector + Epinephrine Autoinjector Адреналин в пневмошприце Epinefrina auto-inyectable Auto-injecteur d'épinéphrine @@ -860,73 +1970,74 @@ Epiniphrin-Autoinjektor Auto-adrenalin Epinefrin autoinjektor - Autoiniettore di adrenalina + Autoiniettore di Epinefrina Auto-injetor de epinefrina - アドレナリン注射器 - 에피네프린 자동주사기 + アドレナリン自動注射器 + 자동주사기 (에피네프린) 肾上腺素自动注射器 腎上腺素自動注射器 + Epinefrin otomatik enjektör 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 Aumenta il battito cardiaco e combatte gli effetti di reazioni allergiche. Aumenta a frequência cardíaca e combate efeitos causados por reações alérgicas Zvyšuje srdeční frekvenci a chrání před alergickými reakcemi - 心拍数を増加させたり、アレルギー反応を収める効果もあります。 - 심박수를 높이며 알러지반응의 대응책입니다 - 增加心跳速率的一种药物 + 心拍数を増加させ、アレルギー反応に対抗する作用を持つ + 심박수를 높이며 알러지 반응의 대응책입니다 + 用于提升心率的一种药物 增加心跳速率的一種藥物 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) - Plasma IV (1000ml) + Plasma IV (1000 ml) Osocze IV (1000ml) Plasma IV (1000ml) Vérplazma-infúzió (1000ml) Plasma EV (1000ml) Plasma IV (1000ml) Krevní plazma (1000ml) - 血しょう IV (1000ml) - 혈장 IV (250ml) - 血浆 (1000ml) - 血漿 (1000ml) + 血漿 IV (1000ml) + 혈장 IV (1000ml) + 血浆(1000毫升) + 血漿 (1000毫升) 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. Volumenerweiterungsmittel (künstliches Blutvolumen) Suplemento para expandir o volume sanguíneo. Intravenózně podávaný doplněk k zvětšení objemu krve - 血液量を増加させる補助です。 + 血液量の増加を補助します。 혈액량을 늘리기위한 보조수단 입니다. 可快速得到血液补充 可快速得到血液補充 @@ -935,14 +2046,14 @@ 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. Volumenerweiterungsmittel (künstliches Blutvolumen) Suplemento para expandir o volume sanguíneo. Intravenózně podávaný doplněk k zvětšení objemu krve - 血液量を増加させる補助です。 + 血液量の増加を補助します。 혈액량을 늘리기위한 보조수단 입니다. 可快速得到血液补充 可快速得到血液補充 @@ -951,39 +2062,41 @@ 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) Plasma EV (500ml) Plasma IV (500ml) Krevní plazma (500ml) - 血しょう IV (500ml) + 血漿 IV (500ml) 혈장 IV (500ml) - 血浆 (500ml) - 血漿 (500ml) + 血浆(500毫升) + 點滴 (血漿 500毫升) + Plasma IV (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) Plasma EV (250ml) Plasma IV (250ml) Krevní plazma (250ml) - 血しょう IV (250ml) + 血漿 IV (250ml) 혈장 IV (250ml) - 血浆 (250ml) - 血漿 (250ml) + 血浆(250毫升) + 點滴 (血漿 250毫升) + Plasma IV (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) @@ -992,24 +2105,26 @@ Krevní transfúze (1000ml) 血液 IV (1000ml) 혈액 IV (1000ml) - 血液 (1000ml) - 血液 (1000ml) + 血液(1000毫升) + 點滴 (血液 1000毫升) + Kan IV (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. - 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) - Blut IV, Bluthaushalt des Patienten wiederherstellen. (Kühl halten) - Sangue intravenoso, para restaurar o volume sanguinio do paciente.(Manter frio) - Krevní transfuze pro doplnění pacientovi krve (skladujte v chladu) - 血液 IV は、患者へ血液を補給します。(要低温保存) - 혈액 IV, 환자에게 혈액을 공급합니다. (차갑게 할것) - 血液, 用于补充伤者流失的血液 (需冷藏) - 血液, 用於補充傷者流失的血液 (需冷藏) + Blood IV, for restoring a patients blood + Пакет крови для возмещения объёма потерянной крови + Sangre intravenosa, para restarurar el volumen sanguíneo + Culot sanguin pour transfustion IV, restaure le sang d'un patient. + Krew IV, używana do uzupełnienia krwi u pacjenta. + Vér-infúzió, intravénás bejuttatásra egy páciensnek + Sangue usato per ripristinare pazienti in cui si è verificata una perdita di sangue + Blut IV, um den Bluthaushalt des Patienten wiederherzustellen. + Sangue intravenoso, para restaurar o volume sanguinio do paciente. + Krevní transfuze pro doplnění pacientovi krve + 血液 IVは患者の血液量を回復させます。 + 혈액 IV, 환자에게 혈액을 공급합니다. + 血液,用于补充伤者流失的血液 + 血液, 用於補充傷者流失的血液 + Kan IV, bir hastanın kanını geri enjekte etmek için O Negative infusion blood used in strict and rare events to replenish blood supply usually conducted in the transport phase of medical care. @@ -1017,21 +2132,21 @@ 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. 0 Rh negativní krev se používá v vzácných případech k doplnění pacientovy hladiny krve, obvykle při převozu zraněné osoby do nemocnice. - O 型への輸血はまれで厳格であり、通常は治療のための輸送段階で輸血をおこないます。 - O- 형 혈액 투여는 매우 엄격하고 드문 혈액보급의 경우에 쓰이는데 주로 치료의 운송단계에서 사용됩니다. - O型负值注射用血液, 在紧急情况时使用, 用于补充伤者流失的血液 - O型負值注射用血液, 在緊急情況時使用, 用於補充傷者流失的血液 + 血液型O-の輸血は、厳密かつ稀な事象において行われる。通常、医療の搬送段階で血液を補充するために使用される。 + O형 혈액 투여는 매우 엄격하고 드문 혈액 보급의 경우에 쓰이는데 주로 치료의 운송단계에서 사용됩니다. + 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) @@ -1040,14 +2155,15 @@ Krevní transfúze (500ml) 血液 IV (500ml) 혈액 IV (500ml) - 血液 (500ml) - 血液 (500ml) + 血液(500毫升) + 點滴 (血液 500毫升) + Kan IV (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) @@ -1056,62 +2172,64 @@ Krevní transfúze (250ml) 血液 IV (250ml) 혈액 IV (250ml) - 血液 (250ml) - 血液 (250ml) + 血液(250毫升) + 點滴 (血液 250毫升) + Kan IV (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) - Soluzione salina EV (1˙000ml) + Soluzione salina EV (1000ml) Soro IV (1000ml) Fyziologický roztok (1000ml) 生理食塩水 IV (1000ml) 생리식염수 IV (1000ml) - 生理食盐水 (1000ml) - 生理食鹽水 (1000ml) + 生理盐水(1000毫升) + 點滴 (食鹽水 1000毫升) + Serum IV (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. Kochsalzlösung, ein medizinisches Volumenersatzmittel Solução Salina Intravenosa 0.9%, para restaurar o volume de sangue temporariamente. Fyziologický roztok se aplikuje intravenózně a slouží k obnově pacientovi krve - 生理食塩水 IV は、患者の血液量を補助します + 生理食塩水 IVは患者の血液量を回復させます。 생리식염수, 환자의 혈액량을 보충할때 쓰입니다 - 生理食盐水, 用于恢复伤者血液 + 生理盐水,用于恢复伤者血液 生理食鹽水, 用於恢復傷者血液 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.\nÀ administrer par perfusion intraveineuse. Używany w medycynie w formie płynu infuzyjnego jako środek nawadniający i uzupełniający niedobór elektrolitów, podawany dożylnie (IV). Egy orvosi térfogat-helyreállító készítmény, melyet intravénás módon lehet a szervezetbe juttatni. - Una soluzione medica per ripristinare il volume del sangue introdotta tramite trasfusione EV. + Una soluzione medica per ripristinare il volume del sangue, introdotta tramite trasfusione EV. Ein medizinisches Volumenersatzmittel, dass durch einen intravenösen Zugang in den Blutkreislauf verabreicht wird. Uma reposição temporaria para restaurar a pressão arterial perdida por perda de sangue. Fyziologický roztok se využívá nejčastěji jako infuze při dehydrataci organismu. - 生理食塩水 IV を静脈へ投与し、血液量を増加させることができます。 + 点滴で血液系に導入される医療用血液量補充剤。 혈류에 IV로 투여되는 의료 용적 대체 요법 - 利用静脉注射进入人体血液系统, 帮助伤者血液恢复 + 利用静脉注射进入人体血液系统,帮助伤者血液恢复 利用靜脈注射進入人體血液系統, 幫助傷者血液恢復 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) @@ -1120,14 +2238,15 @@ Fyziologický roztok (500ml) 生理食塩水 IV (500ml) 생리식염수 IV (500ml) - 生理食盐水 (500ml) - 生理食鹽水 (500ml) + 生理盐水(500毫升) + 點滴 (食鹽水 500毫升) + Serum IV (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) @@ -1136,45 +2255,47 @@ Fyziologický roztok (250ml) 生理食塩水 IV (250ml) 생리식염수 IV (250ml) - 生理食盐水 (250ml) - 生理食鹽水 (250ml) + 生理盐水(250毫升) + 點滴 (食鹽水 250毫升) + Serum IV (250ml) - Basic Field Dressing (QuikClot) + Bandage (QuikClot) Первичный перевязочный пакет (QuikClot) Vendaje básico (QuickClot) - Bandage basique (Hémostatique) + Pansement hémostatique (Quikclot) Opatrunek QuikClot ACS - Verbandpäckchen (QuikClot) + Bandage (QuikClot) Általános zárókötszer (QuikClot) - Bendaggio emostatico (QuikClot) + Bendaggio Emostatico (QuikClot) Bandagem básica (Coagulante) Hemostatický obvaz (QuikClot) - 緊急圧迫止血包帯 (クイッククロット) - 필드 드레싱 (퀵 클롯) - 基本战地包扎 (止血粉) - 基本戰地包紮 (止血粉) + 包帯 (クイッククロット) + 붕대 (퀵 클롯) + 绷带(止血型) + 繃帶 (止血粉) 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 - Bendaggio emostatico (QuikClot) + Bendaggio Emostatico (QuikClot) Bandagem com agente coagulante Hemostatický obvaz (QuikClot) - クイッククロット + クイッククロット包帯 퀵 클롯 붕대 - 止血粉绷带 + 绷带(止血型) 止血粉繃帶 + QuikClot bandaj 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. @@ -1182,9 +2303,9 @@ 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í - 血液凝固剤を含む包帯により、止血できます。 - 지혈시 사용하는 붕대로 혈액 응고제를 포함하고있습니다. - 包含止血粉成分的止血绷带, 可用于止血 + 出血を止める凝固剤入りの止血包帯。 + 지혈 시 사용하는 붕대로 혈액 응고제를 포함하고 있습니다. + 包含止血粉成分的止血绷带,可用于止血 包含止血粉成分的止血繃帶, 可用於止血 @@ -1195,45 +2316,48 @@ Apteczka osobista Persönliches Erste-Hilfe-Set Elsősegélycsomag - Pronto soccorso personale + Kit di Pronto Soccorso (PAK) Kit De Primeiros Socorros Pessoal Osobní lékárnička (PAK) - 応急処置キット + 個人用治療キット (PAK) 개인응급키트 个人急救包 個人急救包 + Kişisel Yardım Seti 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 - 縫合や高度な処置に必要とされる、様々な治療器具が含まれています。 - 봉합및 고급 조치에 필요한 다양한 치료 도구가 있습니다. - 包含各种医疗套件, 以及进阶伤口系统需要的缝合用品 + 縫合や高度な処置に必要とされる様々な治療器具が含まれている + 봉합 및 고급 조치에 필요한 다양한 치료 도구가 있습니다. + 包含各种医疗套件,以及进阶伤口系统需要的缝合用品 包含各種醫療套件, 以及進階傷口系統需要的縫合用品 + Dikiş veya gelişmiş tedavi için gerekli çeşitli tedavi malzemelerini içerir 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. - 戦場で縫合や高度な処置に必要とされる、様々な治療器具が含まれています。 - 야전에서 봉합및 고급 조치를 위한 개인응급키트 + 個人用治療キット (PAK) は戦場での縫合や高度な処置に必要です + 야전에서 봉합 및 고급 조치를 위한 개인응급키트 个人急救包可用于战地缝合手术或进阶伤口系统使用 - 個人急救包可用於戰地縫合手術或進階傷口系統使用 + 個人急救包可用於戰地縫合手術或進階醫療用 + Alan dikişi veya gelişmiş tedavi için Kişisel Yardım Kiti Use Personal Aid Kit @@ -1245,11 +2369,12 @@ Elsősegélycsomag használata Usar o kit de primeiros socorros Použít osobní lékárničku (PAK) - Usa il pronto soccorso personale - 応急処置キットを使う - 개인 응급 키트사용하기 + Usa il Kit di Pronto Soccorso (PAK) + 個人用治療キットを使う + 개인응급키트 사용 使用个人急救包 使用個人急救包 + Kişisel Yardım Kitini Kullan Surgical Kit @@ -1262,14 +2387,15 @@ Kit chirurgico Kit Cirurgico Chirurgická sada - 縫合キット + 手術キット 봉합 키트 手术包 手術包 + Cerrahi Kit 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 @@ -1278,10 +2404,11 @@ 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 - 縫合キットは戦場で高度な処置をする為に使われます。 + 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 - 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) - 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) + 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) + 用於在戰場上為傷口進行縫合 + Sahada gelişmiş tıbbi tedavi için Cerrahi Kit Surgical Kit for in field advanced medical treatment @@ -1289,15 +2416,16 @@ 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 avancé 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 - 縫合キットは戦場で高度な処置をする為に使われます。 + 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 - 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) - 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) + 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) + 用於在戰場上為傷口進行縫合 + Sahada gelişmiş tıbbi tedavi için Cerrahi Kit Use Surgical Kit @@ -1309,11 +2437,45 @@ Usar equipo quirúrgico Sebészeti készlet használata Použít chirurgickou sadu - Usar kit cirúrgico - 縫合キットを使う + Usar Kit Cirúrgico + 手術キットを使う 봉합키트 사용하기 使用手术包 使用手術包 + Cerrahi Kit Kullan + + + Suture + Naht + Sutura + Sutura + 糸付縫合針 + Szew + 봉합술 + Suture + Нить + + + Surgical Suture for stitching injuries. + Chirurgisches Nahtmaterial zum Nähen von Wunden. + Sutura chirurgica per cucire ferite. + Sutura quirúrjica para heridas de puntos. + 傷害縫合用の外科糸付縫合針。 + Szew chirurgiczny do zszywania ran. + 상처를 꿰메는 수술용 봉합술. + Suture chirurgicale pour suturer les blessures. + Хирургическая нить для зашивания травм. + + + Surgical Suture for stitching injuries. + Chirurgisches Nahtmaterial zum Nähen von Wunden. + Sutura chirurgica per cucire ferite. + Sutura quirúrjica para heridas de puntos. + 傷害縫合用の外科糸付縫合針。 + Szew chirurgiczny do zszywania ran. + 상처를 꿰메는 수술용 봉합술. + Suture chirurgicale pour suturer les blessures. + Хирургическая нить для зашивания травм. Bodybag @@ -1326,10 +2488,11 @@ Sacca per corpi Saco para cadáver Pytel na mrtvoly - 死体袋 - 시체 가방 + 遺体袋 + 시체 운반용 부대 尸袋 屍袋 + Ceset torbası A bodybag for dead bodies @@ -1339,13 +2502,14 @@ Worek do pakowania zwłok Ein Leichensack für Tote Egy hullazsák a holttestek számára - Una sacca nera per trasportare cadaveri. + Una sacca per trasportare cadaveri. Um saco para corpos mortos Pytel na mrtvoly - 死体袋は死体を入れる為に使います。 - 시체를 운반할때 쓰는 가방입니다 - 用来装尸体用 + 死体のための遺体袋 + 시체를 운반할 때 쓰는 가방입니다 + 用于装尸体 用來裝屍體用 + Ölü bedenler için bir ceset torbası A bodybag for dead bodies @@ -1355,29 +2519,31 @@ Worek do pakowania zwłok Ein Leichensack für Tote Egy hullazsák a holttestek számára - Una sacca nera per trasportare cadaveri. + Una sacca per trasportare cadaveri. Um saco para corpos mortos. Pytel na mrtvoly - 死体袋は死体を入れる為に使います。 - 시체를 운반할때 쓰는 가방입니다 - 用来装尸体用 + 死体のための遺体袋 + 시체를 운반할 때 쓰는 가방입니다 + 用于装尸体 用來裝屍體用 + Ölü bedenler için bir ceset torbası 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... - この部分には怪我をしていません・・・ + この部分に怪我をしていません・・・ 이 부위에는 부상이 없습니다... - 此身体部位没有受伤 + 该部位没有受伤 此身體部位沒有受傷 + Bu vücut parçasında yaralanma yok ... Inject Adenosine @@ -1385,14 +2551,15 @@ Inyectar Adenosina Wstrzyknij adenozynę Adénosine - Inietta andenosina + Inietta Adenosina Aplikovat adenosine Injetar Adenosina Ввести аденозин - アデノシンを投与 - 아데노신 주사 + アデノシンを注射 + 아데노신 주사하기 注射腺苷 注射腺苷 + Adenosin Enjekte Et Inject Atropine @@ -1403,12 +2570,13 @@ Atropine Ввести атропин Atropin beadása - Inietta atropina + Inietta Atropina Injetar Atropina - アトロピンを投与 - 아트로핀 주사 + アトロピンを注射 + 아트로핀 주사하기 注射阿托品 注射阿托品 + Atropin Enjekte Et Inject Epinephrine @@ -1420,11 +2588,12 @@ Ввести адреналин Epinefrin beadása Injetar Epinefrina - Inietta adrenalina - アドレナリンを投与 - 에피네프린 주사 + Inietta Epinefrina + アドレナリンを注射 + 에피네프린 주사하기 注射肾上腺素 注射腎上腺素 + Epinefrin Enjekte Et Inject Morphine @@ -1436,11 +2605,12 @@ Morphine Morfium beadása Injetar Morfina - Inietta morfina - モルヒネを投与 - 모르핀 주사 + Inietta Morfina + モルヒネを注射 + 모르핀 주사하기 注射吗啡 注射嗎啡 + Morfin Enjekte Et Transfuse Blood @@ -1453,10 +2623,11 @@ Infúzió (vér) Transfundir Sangue Trasfusione di sangue - 輸血する + 血液を投与 혈액 수혈 - 输血液 + 输入血液 輸血液 + Kan Ver Transfuse Plasma @@ -1469,10 +2640,11 @@ Infúzió (vérplazma) Trasfusione di plasma Transfundir Plasma - 血しょうを投与 + 血漿を投与 혈장 수혈 - 输血浆 + 输入血浆 輸血漿 + Plasma Ver Transfuse Saline @@ -1487,8 +2659,9 @@ Transfundir Soro 生理食塩水を投与 생리식염수 수혈 - 注射生理食盐水 + 输入生理盐水 注射生理食鹽水 + Serum Ver Apply Tourniquet @@ -1496,15 +2669,16 @@ Aplicar torniquete Aplikovat škrtidlo Załóż stazę - Poser garrot + Poser un garrot Наложить жгут Applica laccio emostatico Aplicar Torniquete Érszorító alkalmazása 止血帯を巻く 지혈대 적용 - 使用军用止血带 + 使用止血带 使用軍用止血帶 + Turnike Uygula Bandage @@ -1517,10 +2691,11 @@ Kötözés Atadura Перевязать - 包帯 + 包帯を巻く 붕대 - 绷带 + 包扎 繃帶 + Bandaj Bandage Head @@ -1533,10 +2708,11 @@ Fej kötözése Atar Cabeça Benda la testa - 包帯を頭へ - 머리에 붕대감기 - 绷带包扎 头部 + 包帯を頭部へ巻く + 머리에 붕대 감기 + 包扎头部 繃帶包紮 頭部 + Kafayı Bandajla Bandage Torso @@ -1549,10 +2725,11 @@ Testtörzs kötözése Atar Tronco Benda il torso - 包帯を胴体へ - 몸통에 붕대감기 - 绷带包扎 身体 + 包帯を胴体へ巻く + 몸통에 붕대 감기 + 包扎躯干 繃帶包紮 身體 + Gövdeyi Bandajla Bandage Left Arm @@ -1565,10 +2742,11 @@ Bal kar kötözése Atar Braço Esquerdo Benda il braccio sinistro - 包帯を左腕に - 왼팔에 붕대감기 - 绷带包扎 左手 + 包帯を左腕へ巻く + 왼팔에 붕대 감기 + 包扎左臂 繃帶包紮 左手 + Sol Kolu Bandajla Bandage Right Arm @@ -1581,10 +2759,11 @@ Jobb kar kötözése Atar Braço Direito Benda il braccio destro - 包帯を右腕に - 오른팔에 붕대감기 - 绷带包扎 右手 + 包帯を右腕へ巻く + 오른팔에 붕대 감기 + 包扎右臂 繃帶包紮 右手 + Sağ Kolu Bandajla Bandage Left Leg @@ -1597,10 +2776,11 @@ Bal láb kötözése Atar Perna Esquerda Benda la gamba sinistra - 包帯を左足へ - 왼쪽 다리에 붕대감기 - 绷带包扎 左脚 + 包帯を左足へ巻く + 왼쪽 다리에 붕대 감기 + 包扎左腿 繃帶包紮 左腳 + Sol Bacağı Bandajla Bandage Right Leg @@ -1613,10 +2793,11 @@ Jobb láb kötözése Atar Perna Direita Benda la gamba destra - 包帯を右足へ - 오른쪽 다리에 붕대감기 - 绷带包扎 右脚 + 包帯を右足へ巻く + 오른쪽 다리에 붕대 감기 + 包扎右腿 繃帶包紮 右腳 + Sağ Bacağı Bandajla Injecting Morphine... @@ -1628,11 +2809,12 @@ Injection (morphine)... Morfium beadása... Injetando Morfina... - Inietto la morfina... + Iniettando Morfina... モルヒネを投与しています・・・ - 모르핀 주사중... - 吗啡注射中... + 모르핀 주사 중... + 正在注射吗啡... 嗎啡注射中... + Morfin Enjekte Ediliyor ... Injecting Epinephrine... @@ -1644,11 +2826,12 @@ Injection (épinéphrine)... Epinefrin beadása... Injetando Epinefrina... - Inietto l'adrenalina... + Iniettando Epinefrina... アドレナリンを投与しています・・・ - 에피네프린 주사중... - 肾上腺素注射中... + 에피네프린 주사 중... + 正在注射肾上腺素... 腎上腺素注射中... + Epinefrin Enjekte Ediliyor... Injecting Adenosine... @@ -1656,14 +2839,15 @@ Inyectando Adenosina... Wstrzykiwanie adenozyny... Injection (adénosine)... - Inietto l'andenosina + Iniettando Adenosina... Aplikuji adenosine... Injetando Adenosina... Введение аденозина... アドネシンを投与しています・・・ - 아데노신 주사중... - 腺苷注射中... + 아데노신 주사 중... + 正在注射腺苷... 腺苷注射中... + Adenosin Enjekte Ediliyor... Injecting Atropine... @@ -1674,12 +2858,13 @@ Injection (atropine)... Введение атропина... Atropin beadása... - Inietto l'atropina... + Iniettando Atropina... Injetando Atropina アトロピンを投与しています・・・ - 아트리핀 주사중... - 阿托品注射中 ... + 아트로핀 주사 중... + 正在注射阿托品... 阿托品注射中 ... + Atropin Enjekte Ediliyor... Transfusing Blood... @@ -1692,10 +2877,11 @@ Infúzió vérrel... Transfundindo Sangue... Effettuo la trasfusione di sangue... - 輸血しています・・・ - 혈액 수혈중... - 输血液中 ... + 血液を投与しています・・・ + 혈액 수혈 중... + 正在输入血液... 輸血液中 ... + Kan Veriliyor... Transfusing Saline... @@ -1706,12 +2892,13 @@ Transfusion (solution saline)... Переливание физраствора... Infúzió sós vizzel... - Effettuo la rasfusione di soluzione salina + Effettuo la trasfusione di soluzione salina Transfundindo Soro... 生理食塩水を投与しています・・・ - 생리식염수 수혈중... - 施打生理食盐水中 ... + 생리식염수 수혈 중... + 正在输入生理盐水... 施打生理食鹽水中 ... + Serum Veriliyor... Transfusing Plasma... @@ -1722,12 +2909,13 @@ Transfusion (plasma)... Переливание плазмы... Infúzió vérplazmával... - Effettu la trasfusione di plasma... + Effettuo la trasfusione di plasma... Transfundindo Plasma... - 血しょうを投与しています・・・ - 혈장 수혈중... - 输血浆中 ... + 血漿を投与しています・・・ + 혈장 수혈 중... + 正在输入血浆... 輸血漿中 ... + Plasma Veriliyor... Bandaging... @@ -1736,14 +2924,15 @@ Bandażowanie... Obvazuji... Pansement... - Sto bendando... + Bendando... Bekötözés... Atando... Перевязывание... 包帯を巻いています・・・ - 붕대감는중... - 绷带包扎中 ... + 붕대 감는 중... + 正在包扎... 繃帶包紮中 ... + Bandajlanıyor... Applying Tourniquet... @@ -1754,12 +2943,13 @@ Pose du garrot... Наложение жгута... Érszorító felhelyezése... - Sto applicando il laccio emostatico... - Applicando Torniquete + Applicando il laccio emostatico... + Aplicando Torniquete... 止血帯を巻いています・・・ - 지혈대 적용중... - 使用军用止血带中 ... + 지혈대 적용 중... + 正在使用止血带... 使用軍用止血帶中 ... + Turnike Uygulanıyor... Field Dressing @@ -1770,11 +2960,11 @@ Bandaż jałowy Pansement individuel Zárókötszer - Bendaggio rapido + Bendaggio Rapido Curativo de Campo - 緊急圧迫包帯 - 필드 드레싱 - 基础绷带 + 緊急圧迫止血包帯 + 붕대 (기본) + 绷带(基础型) 基礎繃帶 @@ -1784,14 +2974,15 @@ Компресионный пакет Bandaż uciskowy Nyomókötszer - Bendaggio compressivo - Bande extensible + Bendaggio Compressivo + Bandage compressif Bandagem de Compressão Obvaz Tlakový 弾性包帯 - 거즈 붕대 - 包扎绷带 + 붕대 (거즈) + 绷带(包扎型) 包紮繃帶 + Paket Bandaj Elastic Bandage @@ -1800,14 +2991,15 @@ Давящая повязка Obavaz Elastický Bandaż elastyczny - Bande compressive + Bandage extensible Rögzitő kötszer - Bendaggio elastico + Bendaggio Elastico Bandagem Elástica 伸縮包帯 - 압박 붕대 - 弹性绷带 + 붕대 (압박) + 绷带(弹性型) 彈性繃帶 + Elastik Bandaj QuikClot @@ -1818,11 +3010,11 @@ QuikClot Bandage hémostatique QuikClot - QuikClot (polvere emostatica) + Bendaggio Emostatico (QuikClot) QuikClot クイッククロット - 퀵 클롯 - 止血粉 + 붕대 (퀵 클롯) + 绷带(止血型) 止血粉 @@ -1836,10 +3028,11 @@ Pulzus ellenőrzése Controlla il polso Checar Pulso - 心拍数を計る + 脈拍を確認 맥박 확인 检查脉搏 檢查脈搏 + Nabzı Kontrol Et Check Blood Pressure @@ -1850,12 +3043,13 @@ Sprawdź ciśnienie krwi Prendre la tension Vérnyomás megmérése - Controlla pressionsa sanguigna - Chegar Pressão Sanguínea - 血圧を計る + Controlla pressione sanguigna + Checar Pressão Arterial + 血圧を確認 혈압 확인 检查血压 檢查血壓 + Kan Basıncını Kontrol Et No entries on this triage card. @@ -1868,10 +3062,11 @@ Ez az orvosi lap nem tartalmaz bejegyzést. Žádné záznamy na tomto štítku Nenhuma entrada neste cartão de triagem - トリアージ カードには何も無い。 - 부상자 분류 카드에 쓰여있는것이 없습니다. - 此检伤分类卡上没有任何资料 + トリアージ カードには何も書かれていない。 + 부상자 분류 카드에 쓰여있는 것이 없습니다. + 此分诊卡上没有信息。 此檢傷分類卡上沒有任何資料 + Bu triyaj kartında kayıt yok. Tourniquet @@ -1882,12 +3077,13 @@ Staza Garrot Érszorító - Laccio emostatico + Laccio Emostatico Torniquete 止血帯 지혈대 - 军用止血带 + 止血带 軍用止血帶 + Turnike Remove Tourniquet @@ -1896,24 +3092,47 @@ Снять жгут Sundat škrtidlo Zdejmij stazę - Enlever garrot + Enlever le garrot Érszorító leszedése Rimuovi laccio emostatico Remover Torniquete 止血帯を外す 지혈대 제거 - 移除军用止血带 + 移除止血带 移除軍用止血帶 + Turnikeyi Çıkar Apply Splint Наложить Шину 添え木を当てる + Poser une attelle + Aplicar Tala + 套上固定板 + Applica gessatura + Aplikovat dlahu + Załóż szynę + Aplicar férula + Schiene anlegen + 安装夹板 + Atel Uygula + 부목 대기 Applying Splint... Накладывается Шина... 添え木を当てています・・・ + Application de l'attelle... + Aplicando Tala... + 套用固定板中... + Applicazione gessatura + Aplikuji dlahu... + Zakładanie szyny + Aplicando férula... + Lege Schiene an ... + 正在安装夹板... + Atel Uygulanıyor... + 부목 대는 중... Diagnose @@ -1930,22 +3149,24 @@ 진단 诊断 診斷 + Teşhis et Diagnosing... Diagnostizieren... Diagnosi in corso... Диагностика... - Diagnostic en cours + Diagnostic en cours... Diagnozowanie... Diagnosticando... Diagnózis folyamatban... Diagnostika... Diagnosticando... 診断しています・・・ - 진단중... - 诊断中... + 진단 중... + 正在诊断... 診斷中... + Teşhis ediliyor... CPR @@ -1957,35 +3178,29 @@ RCP Újraélesztés CPR - SBV - 心肺蘇生 + RCP + 心肺蘇生(CPR) 심폐소생술 - 心肺复苏术 + 心肺复苏(CPR) 心肺復甦術 + CPR Performing CPR... HLW durchführen... Eseguendo RCP... Сердечно-лёгочная реанимация... - RCP en cours + RCP en cours... Przeprowadzanie RKO... Realizando RCP... Újraélesztés folyamatban... Provádím CPR... - Realizando o SBV... - 心肺蘇生をしています・・・ - 심폐소생중... - 进行心肺复苏术中... + Realizando o RCP... + 心肺蘇生(CPR)しています・・・ + 심폐소생 중... + 正在进行心肺复苏... 進行心肺復甦術中... - - - CPR Success Chance - 心肺蘇生の成功率 - - - Probability that cpr will be successful in restoring heart rhythm. - 心肺蘇生によって心拍を戻せる確率を決定できます。 + CPR Yapılıyor... Give Blood IV (1000ml) @@ -1993,15 +3208,16 @@ 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) + Effettua trasfusione Sangue EV (1000ml) Administrar Sangue IV (1000ml) 血液 IV (1000ml) を投与 IV 혈액 수혈 (1000ml) - 输血液 (1000ml) - 輸血液 (1000ml) + 静脉输血(1000毫升) + 輸血液 (1000毫升) + Kan IV (1000ml) Ver Give Blood IV (500ml) @@ -2009,15 +3225,16 @@ 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) + Effettua trasfusione Sangue EV (500ml) Administrar Sangue IV (500ml) 血液 IV (500ml) を投与 IV 혈액 수혈 (500ml) - 输血液 (500ml) - 輸血液 (500ml) + 静脉输血(500毫升) + 輸血液 (500毫升) + Kan IV (500ml) Ver Give Blood IV (250ml) @@ -2025,15 +3242,16 @@ 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) + Effettua trasfusione Sangue EV (250ml) Administrar Sangue IV (250ml) 血液 IV (250ml) を投与 IV 혈액 수혈 (250ml) - 输血液 (250ml) - 輸血液 (250ml) + 静脉输血(250毫升) + 輸血液 (250毫升) + Kan IV (250ml) Ver Give Plasma IV (1000ml) @@ -2041,15 +3259,16 @@ 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) + Effettua trasfusione Plasma EV (1˙000ml) Administrar Plasma IV (1000ml) - 血しょう IV (1000ml) を投与 + 血漿 IV (1000ml) を投与 IV 혈장 수혈 (1000ml) - 输血浆 (1000ml) - 輸血漿 (1000ml) + 静脉注射血浆(1000毫升) + 輸血漿 (1000毫升) + Plasma IV (1000ml) Ver Give Plasma IV (500ml) @@ -2057,15 +3276,16 @@ 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) + Effettua trasfusione Plasma EV (500ml) Administrar Plasma IV (500ml) - 血しょう IV (500ml) を投与 + 血漿 IV (500ml) を投与 IV 혈장 수혈 (500ml) - 输血浆 (500ml) - 輸血漿 (500ml) + 静脉注射血浆(500毫升) + 輸血漿 (500毫升) + Plasma IV (500ml) Ver Give Plasma IV (250ml) @@ -2073,15 +3293,16 @@ 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) + Effettua trasfusione Plasma EV (250ml) Administrar Plasma IV (250ml) - 血しょう IV (250ml) を投与 + 血漿 IV (250ml) を投与 IV 혈장 수혈 (250ml) - 输血浆 (250ml) - 輸血漿 (250ml) + 静脉注射血浆(250毫升) + 輸血漿 (250毫升) + Plasma IV (250ml) Ver Give Saline IV (1000ml) @@ -2089,15 +3310,16 @@ 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) + Effettua trasfusione Salina EV (1000ml) Administrar Soro IV (1000ml) 生理食塩水 IV (1000ml) を投与 IV 생리식염수 수혈 (1000ml) - 注射生理食盐水 (1000ml) - 注射生理食鹽水 (1000ml) + 静脉注射生理盐水(1000毫升) + 注射生理食鹽水 (1000毫升) + Serum IV (1000ml) Ver Give Saline IV (500ml) @@ -2105,15 +3327,16 @@ 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) + Effettua trasfusione Salina EV (500ml) Administrar Soro IV (500ml) 生理食塩水 IV (500ml) を投与 IV 생리식염수 수혈 (500ml) - 注射生理食盐水 (500ml) - 注射生理食鹽水 (500ml) + 静脉注射生理盐水(500毫升) + 注射生理食鹽水 (500毫升) + Serum IV (500ml) Ver Give Saline IV (250ml) @@ -2121,44 +3344,56 @@ 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) + Effettua trasfusione Salina EV (250ml) Administrar Soro IV (250ml) 生理食塩水 IV (250ml) を投与 IV 생리식염수 수혈 (250ml) - 注射生理食盐水 (250ml) - 注射生理食鹽水 (250ml) + 静脉注射生理盐水(250毫升) + 注射生理食鹽水 (250毫升) + Serum IV (250ml) Ver Minimal Minimal 軽処置群 Минимально + Aucune urgence + Mínimo + 輕微 + Minimo + Minimální + Minimalny + Mínimo + 轻微 + Düşük + 비응급 Delayed Retrasado Срочная помощь - Opóźniony - Traitement urgent + Pomoc Odroczona + Peut attendre Verzögert Odložitelný Késleltetett Differito Atrasado 待機的治療群 - 늦어짐 + 응급 延后 延後 + Ertelenmiş Immediate Inmediato Неотложная помощь - Natychmiastowy - Traitement immédiat + Pomoc Natychmiastowa + Urgent Sofort Okamžitý Azonnali @@ -2168,12 +3403,13 @@ 긴급 紧急 緊急 + Acil Deceased Fallecido Труп - Nie żyje + Denat Décédé Verstorben Mrtvý @@ -2184,12 +3420,13 @@ 사망 死亡 死亡 + Ölü None Ninguno Отсутствует - Brak + Brak klasyfikacji Pas de fiche Keine Nic @@ -2200,6 +3437,7 @@ 없음 未分类 未分類 + Yok Normal breathing @@ -2212,10 +3450,11 @@ Normális légzés Respiro normale Respiração normal - 通常の呼吸 + 呼吸は正常 정상 호흡 呼吸正常 呼吸正常 + Normal nefes alıyor No breathing @@ -2226,18 +3465,19 @@ Brak oddechu Nedýchá Nincs légzés - Mancanza di respiro + Assenza di respiro Não respira - 息をしていない + 呼吸をしていない 호흡 불가 没有呼吸 沒有呼吸 + Nefes alamıyor Difficult breathing Дыхание затруднено Dificultad para respirar - Difficulté respiratoire + Respiratoire difficile Trudności z oddychaniem Schwere Atmung Dýchá s obtížemi @@ -2248,28 +3488,50 @@ 호흡 곤란 呼吸困难 呼吸困難 + Nefes almakta zorlanıyor 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 - Respira a fatica + Quasi nessuna respirazione Quase não respira ほとんど呼吸をしていない 호흡이 없음 - 快要没呼吸 - 快要沒呼吸 + 呼吸微弱 + 呼吸極弱 + Neredeyse nefes almıyor + + + No pain + Nie odczuwa bólu + 고통 없음 + Pas de douleur + Nessun dolore + Kein Schmerz + 痛みはない + Нет боли + Sin dolor In mild pain Hat leichte Schmerzen - 中くらいの痛みがある + 軽い痛みがある Небольшая боль + Légère douleur + Com dor leve + 中度疼痛中 + Con dolore leggero + V mírných bolestech + W łagodnym bólu + Con dolor leve + 轻度疼痛 + 조금 고통스러움 In pain @@ -2283,15 +3545,24 @@ Con dolore Com dor 痛みがある - 고통 - 疼痛中 + 꽤 고통스러움 + 疼痛 疼痛中 In severe pain Hat starke Schmerzen - ひどい痛みがある + 酷い痛みがある Сильная боль + Douleur intense + Com dor intensa + 嚴重疼痛中 + Con forte dolore + Ve velkých bolestech + W silnym bólu + Con dolor severo + 重度疼痛 + 매우 고통스러움 Tourniquet [CAT] @@ -2299,31 +3570,75 @@ Жгут Torniquete [CAT] Garrot [CAT] - Staza [typ. CAT] + Staza [CAT] Škrtidlo [CAT] Érszorító [CAT] - Laccio emostatico [CAT] + Laccio Emostatico [CAT] Torniquete [CAT] 止血帯 [CAT] 지혈대 [CAT] - 军用止血带 + 止血带(军用型) 軍用止血帶 + Turnike [CAT] - - Receiving IV [%1ml] - Erhalte IV [%1ml] - Recibiendo IV [%1ml] - Принимается переливание [%1 мл] - Otrzymywanie IV [pozostało %1ml] - Transfusion : [%1ml] - Přijímání transfúze [%1ml] - Infúzióra kötve [%1ml] - Ricevendo EV [%1ml] - Recebendo IV [%1ml] - IV [%1ml] を投与されている - IV로 [%1ml] 수혈중 - 接收静脉注射液中 [%1ml] - 接收靜脈注射液中 [%1ml] + + Receiving Saline IV [%1ml] + Erhalte Saline IV [%1ml] + Recibiendo Salina IV [%1ml] + Принимается физраствор [%1 мл] + Otrzymywanie soli IV [%1ml] + Transfusion de sérum salé : [%1 ml] + Přijímání soli IV [%1ml] + Saline Infúzióra kötve [%1ml] + Ricevendo Salina EV [%1ml] + Recebendo Salina IV [%1ml] + 生理食塩水 IV [%1ml] を投与中 + 생리식염수 IV로 [%1ml] 수혈중 + 正在接受生理盐水静脉注射 [%1毫升] + 接收生理鹽水靜脈注射液中 [%1毫升] + + + Receiving Blood IV [%1ml] + Erhalte Blut IV [%1ml] + Recibiendo Sangre IV [%1ml] + Принимается кровь [%1 мл] + Otrzymywanie krwi IV [%1ml] + Transfusion de sang : [%1 ml] + Přijímání krve IV [%1ml] + Vér Infúzióra kötve [%1ml] + Ricevendo Sangue EV [%1ml] + Recebendo Sangue IV [%1ml] + 血液 IV [%1ml] を投与中 + 혈액 IV로 [%1ml] 수혈중 + 正在接受血液静脉注射 [%1毫升] + 接收血液靜脈注射液中 [%1毫升] + + + Receiving Plasma IV [%1ml] + Erhalte Plasma IV [%1ml] + Recibiendo Plasma IV [%1ml] + Принимается плазма [%1 мл] + Otrzymywanie plazmy IV [%1ml] + Transfusion de plasma : [%1 ml] + Přijímání plazmy IV [%1ml] + Plazma Infúzióra kötve [%1ml] + Ricevendo Plasma EV [%1ml] + Recebendo Plasma IV [%1ml] + プラズマ IV [%1ml] を投与中 + 혈장 IV로 [%1ml] 수혈중 + 正在接受血浆静脉注射 [%1毫升] + 接收血漿靜脈注射液中 [%1毫升] + + + No IV + Brak podpiętego IV + 수혈 없음 + Pas de transfusion + Nessuna Flebo EV + Kein IV + IV なし + Нет капельницы + Sin IV Blood Pressure @@ -2336,14 +3651,15 @@ Pressione sanguigna Pressão Arterial Krevní tlak - 血圧を測る + 血圧 혈압 血压 血壓 + Kan Basıncı Checking Blood Pressure.. - Prise de la tension... + Prise de tension... Проверка артериального давления... Comprobando presión arterial... Sprawdzanie ciśnienia krwi... @@ -2352,30 +3668,31 @@ Controllando la pressione sanguigna.. Aferindo Pressão Arterial... Měřím krevní tlak... - 血圧を測定しています・・・ - 혈압 측정증... - 检查血压中... + 血圧を確認しています・・・ + 혈압 측정 중... + 正在测量血压... 檢查血壓中... + Kan basıncı kontrol ediliyor... %1 checked Blood Pressure: %2 %1 kontrollierte Blutdruck: %2 - %1 controllata pressione sanguigna: %2 + %1 ha controllato pressione sanguigna: %2 %1 проверил артериальное давление: %2 - %1 a mesuré la tension: %2 + %1 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 %1 zkontroloval krevní tlak: %2 %1 verificou pressão arterial: %2 - %1 が測った血圧は: %2 - %1 (이)가 혈압을 측정했습니다: %2 - 已由%1确认血压: %2 + %1 が血圧を確認: %2 + %1(이)가 혈압을 측정했습니다: %2 + %1 测得血压为 %2 已由%1確認血壓: %2 You checked %1 - Vous examinez %1 + Vous avez examiné %1. Вы осмотрели раненого %1 Examinando a %1 Zbadałeś %1 @@ -2384,14 +3701,15 @@ Hai diagnosticato %1 Você verificou o paciente %1 Zkontroloval jsi %1 - 自分の血圧は %1 - 나의 혈압은 %1 이다 - 你已经检查 %1 + %1 を確認した + 혈압은 %1 입니다 + 你已检查 %1 你已經檢查 %1 + Kontrol ettin %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 @@ -2400,14 +3718,15 @@ Der Blutdruck liegt bei %2/%3 A Pressão Arterial é de %2/%3 Naměřil si krevní tlak u %2/%3 - 血圧は %2/%3 - 혈압이 %2/%3 이다 - 血压为%2/%3 + 計測した血圧数は %2/%3 でした + 혈압이 %2/%3 입니다 + 血压为 %2/%3 血壓為%2/%3 + Kan basıncı buldun %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 @@ -2416,14 +3735,15 @@ La pressione sanguigna è bassa Pressão Arterial baixa Naměřil si nízký krevní tlak - 血圧はかなり低い - 혈압이 매우 낮다 - 发现到低血压 + 血圧が 低い ことを確認した + 혈압이 매우 낮습니다 + 血压低 發現到低血壓 + Düşük kan basıncı buldun You find a normal blood pressure - Tension normale + La tension est normale. Давление нормальное La presión arterial es normal Wyczuwasz normalne ciśnienie krwi @@ -2432,14 +3752,15 @@ La pressione sanguigna è normale Pressão Arterial normal Naměřil si normální krevní tlak - 血圧は通常 - 혈압이 정상이다 - 发现到正常血压 + 血圧が 正常 なことを確認した + 혈압이 정상입니다 + 血压正常 發現到正常血壓 + Normal kan basıncı buldun 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 @@ -2448,14 +3769,15 @@ La pressione sanguigna è alta Pressão Arterial Alta Naměřil si vysoký krevní tlak - 血圧はかなり高い - 혈압이 매우 높다 - 发现到高血压 + 血圧が 高い ことを確認した + 혈압이 매우 높습니다 + 血压高 發現到高血壓 + Yüksek kan basıncı buldun 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 @@ -2464,26 +3786,28 @@ La pressione sanguigna è assente Sem Pressão Arterial Nenaměřil si žádný krevní tlak - 血圧は測れなかった - 혈압이 잡히지 않는다 - 量不到血压 + 血圧が ない ことを確認した + 혈압이 잡히지 않습니다 + 血压为零 量不到血壓 + Kan basıncı yok You fail to find a blood pressure - Vous n'avez pas pu mesurer de tension + Vous n'avez pu mesurer aucune pression sanguine. Артериальное давление не определяется No puedes encontrar presión arterial Nie udało Ci się sprawdzić ciśnienia krwi Du konntest keinen Blutdruck feststellen Nem sikerült a vérnyomás megmérése - Manca strumento per misurare pressione sanguigna + Non puoi misurare la pressione sanguigna Você falhou em aferir a Pressão Arterial Nedokázal si změřit krevní tlak - 血圧を測るのに失敗 - 혈압을 잡을 수 없었다 - 检查血压的动作失败 + 血圧の計測に失敗した + 혈압을 측정하는데 실패했습니다 + 无法测得血压 檢查血壓的動作失敗 + Kan basıncını bulamıyorsun Low @@ -2500,6 +3824,7 @@ 낮음 + Düşük Normal @@ -2512,10 +3837,11 @@ Normális Normální Normal - 通常 + 正常 보통 正常 正常 + Normal High @@ -2532,13 +3858,14 @@ 높음 + Yüksek 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 @@ -2546,8 +3873,9 @@ Sem pressão arterial 血圧なし 혈압 없음 - 无血压 + 血压为零 無血壓 + Kan Basıncı Yok Pulse @@ -2560,31 +3888,33 @@ Polso Pulso Puls - 心拍数 + 脈拍 맥박 脉搏 脈搏 + Nabız - Checking Heart Rate... + Checking Pulse... Vérification du pouls... Проверка пульса... - Comprobando ritmo cardíaco... + Comprobando pulso... Sprawdzanie tętna... - Kontrolliere Herzfrequenz... + Kontrolliere Puls... Szívverés-szám mérése... - Controllando il battito cardiaco... - Aferindo Pulso... - Kontroluji srdeční tep... - 心拍数を測定しています・・・ - 맥박 확인중... - 检查心跳中... + Controllando il polso... + Checando Pulso... + Kontroluji puls... + 脈拍を確認しています・・・ + 맥박 확인 중... + 正在测量脉搏... 檢查心跳中... + Nabız Kontrol Ediliyor ... You checked %1 Вы осмотрели раненого %1 - Vous examinez %1 + Vous avez examiné %1. Examinando a %1 Zbadałeś %1 Kontrolliert %1 @@ -2592,25 +3922,25 @@ Hai diagnosticato %1 Você aferiu o paciente %1 Zkontroloval si %1 - 心拍数は %1 - 나의 맥박은 %1 이다 - 你已经检查 %1 + %1 を確認した + 맥박은 %1 입니다 + 你已检查 %1 你已經檢查 %1 %1 checked Heart Rate: %2 %1 kontrollierte Herzfrequenz: %2 - %1 Controllata Frequenza Cardiaca: %2 + %1 ha controllato il polso: %2 %1 проверил пульс: %2 - %1 a vérifié le pouls 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 %1 zkontroloval srdeční tep: %2 %1 verificou a frequência cardíaca: %2 - %1 が測った心拍数は: %2 - %1 (이)가 맥박을 측정했습니다: %2 - 已由%1确认心跳: %2 + %1 が心拍を確認: %2 + %1(이)가 맥박을 측정했습니다: %2 + %1 测得心率为 %2 已由%1確認心跳: %2 @@ -2621,20 +3951,21 @@ Keine Žádný Nada - aucun + Aucun pouls Nincs Niente なし 없음 + Yok Weak Schwach Lento Слабый - lent + Lent Słabe Débil Gyenge @@ -2644,29 +3975,31 @@ 약함 微弱 微弱 + Zayıf Normal Normal Normale Нормальный - normal + Normal Normalne Normal Normális Normální Normal - 通常 + 正常 보통 正常 正常 + Normal Strong Stark Veloce Сильный - rapide + Rapide Silne Fuerte Erős @@ -2676,86 +4009,91 @@ 강함 过快 過快 + Güçlü 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 Herzfrequenz ist %2 A szívverés-szám %2 Il battito cardiaco è %2 - A Freqüência Cardíaca é de %2 + A Frequência Cardíaca é de %2 Nahmatal jsi srdeční tep u %2 - 心拍数は %2 - 맥박이 %2 이다 - 心跳为%2 + 計測した心拍数は %2 でした + 맥박은 %2 입니다 + 心率为 %2 心跳為%2 You find a weak Heart Rate - Poulslent + Rythme cardiaque lent. Пульс слабый El ritmo cardíaco es débil Wyczuwasz słabe tętno Schwacher Puls A szívverés-szám alacsony Hai riscontrato un debole battito cardiaco - Freqüência Cardíaca baixa - Nahmatal si slabý srdeční puls - 自分の心拍数は低い - 약한 맥박이다 - 心跳微弱 + Frequência Cardíaca baixa + Nahmatal jsi slabý srdeční puls + 心拍が 弱い ことを確認した + 약한 맥박입니다 + 心率微弱 心跳微弱 + Düşük nabız ölçtün You find a strong Heart Rate - pouls rapide + Rythme cardiaque rapide. Пульс учащенный El ritmo cardíaco está acelerado Wyczuwasz silne tętno Starker Puls A szívverés-szám magas Hai riscontrato un forte battito cardiaco - Freqüência Cardíaca normal - Nahmatal si silný srdeční puls - 自分の心拍数は強い - 강한 맥박이다 - 心跳过快 + Frequência Cardíaca normal + Nahmatal jsi silný srdeční puls + 心拍が 強い ことを確認した + 강한 맥박입니다 + 心率过快 心跳過快 + Yüksek nabız ölçtün You find a normal Heart Rate - pouls normal + Rythme cardiaque normal. Пульс в норме El ritmo cardíaco es bueno Wyczuwasz normalne tętno Normaler Puls A szívverés-szám normális Hai riscontrato un normale battito cardiaco - Freqüência Cardíaca alta - Nahmatal si normální srdeční puls - 自分の心拍数は通常 - 보통 맥박이다 - 心跳正常 + Frequência Cardíaca alta + Nahmatal jsi normální srdeční puls + 心拍が 正常 なことを確認した + 보통 맥박입니다 + 心率正常 心跳正常 + Normal nabız ölçtün You find no Heart Rate - pas de pouls + Aucun pouls. Пульс не прощупывается No tiene ritmo cardíaco Wyczuwasz brak tętna Kein Puls gefunden Nem észlelhető szívverés Hai riscontrato una assenza di battito cardiaco - Sem Freqüência Cardíaca + Sem Frequência Cardíaca Žádný puls - 心拍数を測れなかった - 맥박을 찾을 수가 없다 - 量不到心跳 + 心拍が ない ことを確認した + 맥박을 찾을 수가 없습니다 + 无法测得心率 量不到心跳 + Nabız bulamadın Response @@ -2768,14 +4106,14 @@ Risposta Reação Odezva - 反応を見る + 反応を確認 반응 反应 反應 You check response of patient - Vous évaluez l'état de conscience + Évaluation de l'état de conscience du patient... Вы проверяете реакцию раненого Compruebas si el paciente reacciona Sprawdzasz przytomność pacjenta @@ -2784,47 +4122,97 @@ Controlli la risposta del paziente Aferindo se o paciente tem reação Zkontroloval jsi reakci pacienta - 患者からの反応をみる - 대상의 반응 확인중 - 检查伤者的反应 + 患者の反応を確かめています + 대상의 반응 확인 중 + 检查伤员的反应 檢查傷者的反應 %1 is responsive %1 реагирует на раздражители - %1 est conscient + %1 est conscient. %1 ha reaccionado %1 jest przytomny %1 ist anprechbar %1 reakcióképes - %1 e' cosciente + %1 è cosciente %1 está respondendo %1 odpovídá - %1 は反応あり - %1 은 반응이있다 + %1 は反応している + %1은(는) 반응이 있습니다 %1 有反应 %1 有反應 + %1 tepki veriyor %1 is not responsive %1 не реагирует на раздражители - %1 est inconscient + %1 est inconscient. %1 no reacciona %1 jest nieprzytomny %1 ist nicht ansprechbar %1 nem reagál - %1 e' incosciente + %1 non risponde %1 não está respondendo %1 neodpovídá - %1 の反応なし - %1 은 반응이없다 + %1 は反応していない + %1은(는) 반응이 없습니다 %1 没有反应 %1 沒有反應 + %1 tepki vermiyor + + + %1 is unconscious + %1 は意識がない + %1 находится без сознания + %1은(는) 의식불명입니다 + %1 ist bewusstlos + %1 è privo di sensi + + + %1 is not responsive, taking shallow gasps and convulsing + %1 est inconscient, respire par intermittence et convulse. + %1 jest nieresponsywny, ma płytki oddech oraz jest w konwulsjach + %1 は反応していない、 浅く呻きながら痙攣している + %1 reagiert nicht, schnappt nach Luft und verkrampft + %1 non risponde, ha convulsioni e prende respiri deboli + %1没有反应,微软的喘着气和抽搐 + %1 은 반응이 없고, 얕은 헐떡임과 경련증세를 보입니다 + %1 не реагирует на раздражители, поверхностно дышит, в конвульсиях + %1 no responde, dando pequeñas bocanadas y convulsionando + + + %1 is in cardiac arrest + %1 は心停止している + У %1 произошла остановка сердца + %1은(는) 심정지 상태입니다 + %1 ist im Herzstillstand + %1 è in arresto cardiaco + + + %1 is not responsive, motionless and cold + %1 est inconscient, inanimé et froid. + %1 jest nieresponsywny, nieruchomy oraz zimny + %1 は反応していない、 動かず冷たくなっている + %1 reagiert nicht, ist regungslos und kalt + %1 non risponde, è immobile e freddo + %1没有反应,一动不动,身体冰凉 + %1 은 반응이 없고, 움직임이 없으며 차갑습니다 + %1 не реагирует на раздражители, не шевелится и холодный + %1 no responde, sin movimiento y frío + + + %1 is dead + %1 は死亡している + %1 мертв + %1은(는) 사망했습니다 + %1 ist tod + %1 è morto You checked %1 Вы осмотрели раненого %1 - Vous avez examiné %1 + Vous avez examiné %1. Examinas a %1 Zbadałeś %1 Du hast versucht, %1 anzusprechen @@ -2832,25 +4220,26 @@ Hai controllato %1 Você aferiu o paciente %1 Zkontroloval jsi %1 - %1 を見た + %1 を確認した %1 을 확인함 - 你已经检查 %1 + 你已检查 %1 你已經檢查 %1 + %1 i kontrol ettiniz 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 Patient %1<br/>ist %2.<br/>%3.<br/>%4 - Patient %1<br/>est %2.<br/>%3.<br/> + Le patient %1<br/>est %2.<br/>%3.<br/>%4 Pacjent %1<br/>jest %2.<br/>%3.<br/>%4 Paciente %1<br/>is %2.<br/>%3.<br/>%4 A páciens, %1,<br/>%2.<br/>%3.<br/>%4 Pacient %1<br/>je %2.<br/>%3.<br/>%4 Paciente %1<br/>é %2.<br/>%3.<br/>%4 - 患者 %1<br/>は %2.<br/>%3.<br/>%4 + 患者 %1 は<br/>%2している。<br/>%3。<br/>%4。 환자 %1<br/>는 %2.<br/>%3.<br/>%4 - 伤者 %1<br/>is %2.<br/>%3.<br/>%4 + 伤员 %1 <br/> %2 <br/> %3 <br/> %4 傷者 %1<br/>is %2.<br/>%3.<br/>%4 @@ -2866,8 +4255,9 @@ vivo 生存 생존 - 活着 + 存活 活著 + Hayatta dead @@ -2884,6 +4274,7 @@ 사망 死亡 死亡 + Olü He's lost some blood @@ -2891,15 +4282,16 @@ 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 Ele perdeu um pouco de sangue 彼は出血している 적은 양의 피를 잃었다 - 他流失一些血液 + 他轻微失血 他流失一些血液 + O biraz kan kaybetmiş He's lost a lot of blood @@ -2914,8 +4306,9 @@ Ha perso molto sangue 彼は大量失血している 많은 양의 피를 잃었다 - 他流失大量血液 + 他大量失血 他流失大量血液 + O çok kan kaybetmiş He hasn't lost blood @@ -2930,12 +4323,13 @@ Ele não perdeu sangue 彼は失血していない 피를 잃지 않았다 - 他并没有失血 + 他没有失血 他並沒有失血 + O hiç kan kaybetmemiş He is in pain - Sente dolori + Sente dolore Испытывает боль Er hat Schmerzen Il souffre @@ -2944,14 +4338,15 @@ Fájdalmai vannak Je v bolestech Ele está com dor - 彼には痛みがあるようだ + 彼は痛みを感じている 통증이 있다 他感到疼痛 - 他感到疼痛 + 他感到疼痛中 + Onun ağrısı var He is not in pain - Non sente dolori + Non sente dolore Не испытывает боли Er hat keine Schmerzen Il ne souffre pas @@ -2960,10 +4355,11 @@ Nincsenek fájdalmai Nemá žádné bolesti Ele não está com dor - 彼には痛みがないようだ + 彼は痛みを感じていない 통증이 없다 - 他不会疼痛 - 他不會疼痛 + 他没有感到疼痛 + 他沒感到疼痛中 + Onun ağrısı yok Bandaged @@ -2976,14 +4372,15 @@ verbunden Enfaixado Obvázaný - 包帯 + 包帯を巻いた 붕대 감음 - 绷带 + 包扎 繃帶 + Bandajlı You bandage %1 (%2) - Vous pansez %1 (%2) + Vous pansez %1 (%2). Вы перевязали раненого %1 (%2) Aplicas vendaje a %1 en %2 Bandażujesz %1 (%2) @@ -2992,14 +4389,14 @@ Du verbindest %1 (%2) Você aplica bandagem no paciente %1 (%2) Obvazuješ %1 (%2) - %1 (%2) 包帯を使った + あなたは %1 (%2) に包帯を使用した %1 (%2) 붕대를 감았다 - 你正在对 %1 (%2) 包扎绷带中 + 你正在使用 %2 包扎 %1 你正在對 %1 (%2) 包紮繃帶中 %1 is bandaging you - %1 vous panse + %1 vous panse. %1 перевязывает вас %1 te está vendando %1 bandażuje Ciebie @@ -3009,15 +4406,16 @@ %1 está aplicando uma bandagem em você %1 tě obvazuje %1 はあなたに包帯を巻いている - %1 (이)가 나에게 붕대를 감고있다 - %1 正在对你包扎绷带中 + %1 (이)가 나에게 붕대를 감고 있다 + 你正在被 %1 包扎 %1 正在對你包紮繃帶中 + %1 seni bandajlıyor You start stitching injuries from %1 (%2) Вы зашиваете ранения от %1 (%2) Du nähst die Wunden von %1 (%2) - Vous suturez %1 (%2) + Vous suturez %1 (%2). Estás suturando heridas de %1 en %2 Zszywasz rany %1 (%2) Elkezded összevarni %1 sérüléseit (%2) @@ -3025,41 +4423,43 @@ Você começa a suturar os ferimentos do %1 (%2) Zašíváš rány %1 (%2) あなたは %1 (%2) の外傷へ縫合を始めた - 나는 %1(%2) 상처로부터 봉합을 시작했다 - 你正开始对 %1 (%2) 缝合伤口中 + 당신은 %1(%2) 상처로부터 봉합을 시작했다 + 你正在使用 %2 缝合 %1 的伤口 你正開始對 %1 (%2) 縫合傷口中 - Stitching - Наложение швов - Suturando - Nähen - Sutures - Szycie - Összevarrás - Suturando - Suturando - Šití - 縫合中 - 붕합중 - 缝合中 - 縫合中 + Stitching... + Наложение швов... + Suturando... + Nähen... + Suture en cours... + Szycie... + Összevarrás... + Suturando... + Suturando... + Šití... + 縫合中・・・ + 봉합 중... + 正在缝合... + 縫合中... + Dikiş... You treat the airway of %1 Вы интубируете раненого %1 Estás intubando a %1 Du behandelst die Atemwege von %1 - Vous traitez les voies respiratoires de %1 + Vous traitez les voies respiratoires de %1. Udrażniasz drogi oddechowe %1 Kezeled %1 légútját Controlli le vie respiratorie di %1 Você entuba o %1 Ošetřuješ dýchací cesty %1 - %1 の気道を診断する + あなたは %1 の気道を処置した %1의 기도를 확보했다 - 你治疗 %1 的呼吸道 + 你正在治疗 %1 的呼吸道 你治療 %1 的呼吸道 + % 1 hava yolunu tedavi ediyorsunuz Airway @@ -3076,11 +4476,12 @@ 기도 呼吸道 呼吸道 + Hava yolu %1 is treating your airway %1 проводит вам интубацию - %1 traite vos voies respiratoires + %1 traite vos voies respiratoires. %1 te está intubando %1 udrażnia Twoje drogi oddechowe %1 behandelt deine Atemwege @@ -3088,10 +4489,11 @@ %1 ti sta trattando le vie respiratorie %1 está te entubando %1 ošetřuje tvoje dýchací cesty - %1 はあなたの気道を見ている - %1 (이)가 나의 기도를 확보중이다 + %1 があなたの気道を治療中 + %1 (이)가 나의 기도를 확보 중이다 %1 正在治疗你的呼吸道 %1 正在治療你的呼吸道 + % 1 hava yolu tedavi ediyor Drag @@ -3105,9 +4507,10 @@ Arrastar Trascina 引きずる - 끌다 - 拖拉 + 끌기 + 拖拽 拖拉 + Sürükle Carry @@ -3121,9 +4524,10 @@ Carregar Trasporta 担ぐ - 업다 + 업기 背起 背起 + Taşı Release @@ -3135,11 +4539,12 @@ Déposer Elengedés Soltar - Rrilascia + Rilascia 離す 내려놓기 放下 放下 + Bırak Load Patient Into @@ -3154,8 +4559,9 @@ Carica paziente nel 患者を載せる 환자 싣기 - 将伤者放入 + 将伤者装入 將傷者放入 + Hastayı Bindir Unload Patient @@ -3172,6 +4578,7 @@ 환자 내리기 将伤者背出 將傷者背出 + Hastayı İndir This person (%1) is awake and cannot be loaded @@ -3185,13 +4592,14 @@ %1 est conscient et ne peut être embarqué. 患者 (%1) は意識があり、積み込めない 이 사람 (%1) 은(는) 의식이 있어 태우지 못합니다 - 此人(%1)是清醒且不能被装载 + 此人(%1)处于清醒状态,因此无法被装载 此人(%1)是清醒且不能被裝載 + Bu kişi (% 1) uyanık ve yüklenemiyor %1<br/>loaded into<br/>%2 %1<br/>cargado en<br/>%2 - %1<br/>chargé dans<br/>%2 + %1<br/>a embarqué dans<br/>%2. %1<br/>in<br/>%2 verladen %1<br/>załadowano do<br/>%2 %1<br/>naloženo do<br/>%2 @@ -3199,26 +4607,65 @@ %1<br/>caricato su<br/>%2 %1<br/>berakodva ide:<br/>%2 %1<br/>загружен в<br/>%2 - %1<br/>は<br/>%2へ積み込まれました - %1<br/>는<br/>%2 에 실림 + %1 は<br/>%2 へ<br/>積み込まれました + %1<br/>(은)는<br/>%2 에 실림 %1<br/>裝載至<br/>%2 %1<br/>装载至<br/>%2 - - Place body in bodybag - Colocar cuerpo en bolsa para cadáveres - Поместить тело в мешок для трупов - Körper in Leichesack verstauen - Zapakuj ciało do worka na zwłoki - Mettre le corps dans la housse mortuaire - Test hullazsákba helyezése - Metti il corpo nella sacca per cadaveri - Colocar corpo dentro do saco para cadáver - Umístni tělo do pytle na mrtvoly - 死体袋に入れる - 시체 가방에 담기 - 将尸体放入尸袋 - 將屍體放入屍袋 + + Unloaded<br/>%1 from<br/>%2 + %1<br/>von<br/>%2 abgeladen + Descargado/a<br/>%1 de<br/>%2 + %1<br/> a débarqué du<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 + %1 が<br/>%2 から<br/>降ろされました + %1<br/>(은)는<br/>%2 에서 내려짐 + 從<br/>%2卸載<br/>%1 + 从<br/>%2卸载<br/>%1 + + + Place body in black bodybag + Colocar cuerpo en bolsa para cadáveres negra + Körper in schwarzen Leichensack verstauen + Mettre le corps dans la housse mortuaire noir + Metti il corpo nella sacca per cadaveri nera + Colocar corpo dentro do saco para cadáver preto + Umístit tělo do černého pytle na mrtvoly + Vücudu siyah ceset torbasına yerleştir + 遺体袋 (黒) に入れる + 시체를 검은 시체가방에 놓기 + Положить тело в черный мешок для тела + + + Place body in blue bodybag + Colocar cuerpo en bolsa para cadáveres azule + Körper in Blau Leichensack verstauen + Mettre le corps dans la housse mortuaire bleu + Metti il corpo nella sacca per cadaveri blu + Colocar corpo dentro do saco para cadáver azul + Umístit tělo do modrého pytle na mrtvoly + Vücudu mavi ceset torbasına yerleştir + 遺体袋 (青) に入れる + 시체를 파란 시체가방에 놓기 + Положить тело в синий мешок для тела + + + Place body in white bodybag + Colocar cuerpo en bolsa para cadáveres blanca + Körper in weißen Leichensack verstauen + Mettre le corps dans la housse mortuaire blanc + Metti il corpo nella sacca per cadaveri bianca + Colocar corpo dentro do saco para cadáver branco + Umístit tělo do bílého pytle na mrtvoly + Vücudu beyaz ceset torbasına yerleştir + 遺体袋 (白) に入れる + 시체를 흰 시체가방에 놓기 + Положить тело в белый мешок для тела Placing body in bodybag... @@ -3230,11 +4677,34 @@ Test hullazsákba helyezése... Stai mettendo il corpo nella sacca... Colocando corpo dentro do saco para cadáver... - Umístňuji tělo do pytle na mrtvoly... - 死体袋へ入れています・・・ - 시체 가방에 담는중... - 将尸体放入尸袋中... + Umisťuji tělo do pytle na mrtvoly... + 遺体袋へ入れています・・・ + 시체 운반용 부대에 담는 중... + 正在将尸体装入尸袋... 將屍體放入屍袋中... + Vücut, ceset torbasına yerleştiriliyor... + + + Dig grave for body + 시체를 위해 무덤 파기 + Wykop grób na ciało + Enterrer le corps + Grabe ein Grab für den Leichnam + Scava tomba per cadavere + 墓を掘る + Выкопать могилу для тела + Cavar tumba para cuerpo + + + Digging grave for body... + 시체를 위한 무덤 파는 중... + Kopanie grobu... + Enterrement du corps... + Grab für Leichnam ausheben ... + Scavando tomba per cadavere... + 墓を掘っています + Рытьё могилы для тела... + Cavando tumba para cuerpo... %1 has bandaged patient @@ -3242,14 +4712,14 @@ %1 перевязал пациента %1 hat den Patienten verbunden %1 założył bandaż - %1 a pansé le patient + %1 a pansé le patient. %1 bekötözte a pácienst %1 ha bendato il paziente %1 aplicou bandagem no paciente %1 již obvázal pacienta - %1 は包帯を巻いた + %1 が包帯を巻いた %1 (이)가 붕대를 감아줬다 - %1 已包扎伤者 + %1 已包扎伤员 %1 已包紮傷者 @@ -3261,10 +4731,10 @@ %1 realizou RCP %1 провел сердечно-легочную реанимацию %1 realicó RCP - %1 à fait une RCP - %1 は心肺蘇生をした + %1 a fait une RCP. + %1 が心肺蘇生(CPR)を実施 %1 (이)가 심폐소생술을 실시했다 - %1 已执行心肺复苏术 + %1 已进行心肺复苏 %1 已執行心肺復甦術 @@ -3273,15 +4743,16 @@ %1 benutzt %2 %1 использовал %2 %1 użył %2 - %1 utilise %2 + %1 a utilisé un %2. %1 használta a %2-t %1 ha usato %2 %1 usou %2 %1 použil %2 - %1 は %2 を使った + %1 が%2を使用した %1 (이)가 %2 을 썼다 %1 已使用 %2 %1 已使用 %2 + %1 kullanıldı %2 %1 has given an IV @@ -3289,15 +4760,16 @@ %1 ha puesto una IV %1 hat eine Infusion verabreicht %1 podał IV - %1 a plaçé une IV + %1 a posé une IV. %1 infúziót adott %1 ha somministrato una EV %1 aplicou um intravenoso %1 již aplikoval IV - %1 は IV を与えた + %1 がIVを投与した %1 (이)가 IV를 실시했다 - %1 已经给予静脉注射液 + %1 已进行静脉注射 %1 已經給予靜脈注射液 + % 1 IV verildi %1 applied a tourniquet @@ -3305,15 +4777,32 @@ %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 %1 použil škrtidlo - %1 は止血帯を巻いた + %1 が止血帯を巻いた %1 (이)가 지혈대를 적용했다 - %1 已经绑上止血带 + %1 已使用止血带 %1 已經綁上止血帶 + % 1 turnike uyguladı + + + %1 applied a splint + %1 наложил Шина + %1 a posé une attelle. + %1 aplicou uma Tala + %1 已套用固定板 + %1 ha applicato una gessatura + %1 použil dlahu + %1 が添え木を当てた + %1 założył szynę + %1 aplicada una férula + %1 hat eine Schiene angelegt + %1 已安装夹板 + % 1 splint uyguladı + %1 (이)가 부목을 적용했다 %1 used Personal Aid Kit @@ -3322,13 +4811,14 @@ %1 utilizou KPS %1 používá PAK %1 использовал аптечку - %1 ha usato Kit Pronto Soccorso Personale + %1 ha usato Kit di Pronto Soccorso (PAK) %1 usó Kit de Primeros Auxilios - %1 a utilisé une trousse - %1 は応急処置キットを使った + %1 a utilisé une trousse sanitaire. + %1 が個人用治療キットを使用した %1 (이)가 개인응급키트를 사용했다 - %1 已使用了个人急救包 + %1 已使用个人急救包 %1 已使用了個人急救包 + % 1 Kişisel Yardım Seti kullanıldı Heavily wounded @@ -3345,6 +4835,7 @@ 중상 重伤 重傷 + Ağır yaralı Lightly wounded @@ -3361,35 +4852,37 @@ 경상 轻伤 輕傷 + Hafif yaralı Very lightly wounded Sehr leicht verwundet: B. lekko ranny Царапины - Ferito lievemente + Lievemente Ferito Muy levemente herido Très légèrement blessé Nagyon enyhén sérült Velmi lehce raněn Muito levemente ferido - かなり浅い傷 - 매우 가벼운 부상 + ごく軽傷 + 미미한 부상 小伤 小傷 + Çok hafif yaralı Heal fully bandaged hitpoints Lecz w pełni zabandażowane hitpointy Curar miembros totalmente vendados - Исцелять полностью перебинтованные части тела - Curar hitpoints totalmente enfaixados + Исцелить полностью перебинтованные части тела + Curar membros 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 - 包帯は体力を完全に回復する - 붕대를 감은후 체력을 회복함 + 包帯は体力を完全に回復させます + 붕대를 감은 후 체력을 회복함 完全医疗包扎的部位至痊愈 完全醫療包紮的部位至痊癒 @@ -3405,104 +4898,200 @@ Ošetřuji... Curando... 治療しています・・・ - 치료중... - 治疗中... + 치료 중... + 正在治疗... 治療中... + Tedavi ediliyor ... 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... Снятие жгута... Togliendo il laccio emostatico... 止血帯を外しています・・・ - 지혈대 제거중... - 移除军用止血带中... + 지혈대 제거 중... + 正在移除止血带... 移除軍用止血帶中... + Turnike Çıkarılıyor ... 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! + Na tej kończynie nie ma stazy! No hay torniquete en esta parte del cuerpo! Нет жгута на этой части тела! Não existe nenhum torniquete nesta parte do corpo! Žádné škrtidlo na této části těla! - Non c'è nessun laccio emostatico su questa parte del corpo! + Nessun laccio emostatico su questa parte del corpo! Il n'y a pas de garrot sur ce membre ! - 身体には止血帯が無い! + この部位に止血帯はありません! 이 부위에는 지혈대가 없습니다! - 这部位没有止血带! + 该部位没有使用止血带! 這部位沒有止血帶! + Bu vücut kısmında turnike yok! - - 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? - 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? - どこでも応急処置キットを使えるようにしますか? - 언제 개인응급키트를 사용할 수 있습니까? - 何时可以使用个人急救包? - 何時可以使用個人急救包? + + The body twitched and may not be dead! + Тело дернулось и, возможно, пациент жив! + L'unité a bougé et n'est peut-être pas morte ! + Il cadavere si è mosso e potrebbe essere ancora vivo! + 身体が痙攣している、まだ死んでないようだ! + ¡El cuerpo se retorció y puede que no esté muerto! + Ciało drgnęło i może nie być martwe! + Der Körper zuckte und kann nicht tot sein! + 身体抽搐了一下,可能还没死! + 꿈틀대는걸 보니 죽은 것 같지는 않습니다! - - 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.) - Warunek zestawu chirurgicznego - Sebészkészlet állapot - Condição do Kit Cirúrgico (Avançado) - Условие использования хирургического набора (усл.) - Condizioni Kit Chirurgico (Avanzato) - 縫合キットの状態 (アド) - 봉합키트 상태 (고급) - 使用手术包的条件 (进阶伤口) - 使用手術包的條件 (進階傷口) + + Check name on headstone + Sprawdź imię na grobie + 묘비 이름 확인 + Vérifier le nom sur la pierre tombale + Überprüfe Name auf dem Grabstein + Controlla nome sulla lapide + 墓石の名前を確認 + Проверьте имя на надгробии + Comprobar nombre en la lápida - - 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 - 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? - いつでも縫合キットを使えるようにしますか? - 언제 봉합키트를 사용할 수 있습니까? - 何时可以使用手术工具包? - 何時可以使用手術工具包? + + Bandage Rollover + Bandażowanie Wielu Ran + Verbandüberschlag + 붕대 모두 감기 + Pansement de plaies multiples + Srotolamento Bendaggi + 包帯の繰り越し + Перевязка множественных ран + Vendaje múltiple - - 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 - Warunek apteczek - Elsősegélycsomag állapot - Condição do KPS - Условие использования аптечки - Condizioni Kit Pronto Soccorso - 応急処置キットの状態 - 개인응급키트 상태 - 个人急救包使用条件 - 個人急救包使用條件 + + If enabled, bandages can close different types of wounds on the same body part.\nBandaging multiple injuries will scale bandaging time accordingly. + Jeśli opcja jest włączona, bandaże mogą zamykać różne rodzaje ran na tej samej części ciała. \nOpatrywanie wielu ran będzie adekwatnie skalować czas bandażowania. + Wenn diese Option aktiviert ist, können Verbände verschiedene Arten von Wunden am selben Körperteil schließen.\nBeim Verbinden mehrerer Verletzungen wird die Verbandszeit entsprechend skaliert. + 활성화된 경우 붕대로 동일한 신체 부위에 있는 다른 유형의 상처를 막을 수 있습니다.\n여러 부상을 붕대로 감으면 붕대 감는 시간이 그만큼 늘어납니다. + Si activé, les bandages peuvent fermer plusieurs types de blessures sur la même partie du corps.\nPanser de multiples blessures modifiera la durée d'application en conséquence. + Se attivo, un singolo bendaggio potrà chiudere più ferite sulla stessa parte del corpo.\nBendare più ferite di conseguenza richiederà più tempo. + 有効にすると、体の同じ部分にある別の種類の傷を一つの包帯で閉じることができます。\n複数の傷に包帯を巻くと、それに応じて包帯時間が変動します。 + Если эта функция включена, бинты могут закрывать различные типы ран на одной и той же части тела.\nПри перевязке нескольких повреждений время перевязки будет увеличено соответствующим образом. + Si se habilita, las vendas pueden cerrar diferentes tipos de heridas en la misma parte del cuerpo.n\Vendar múltiples heridas escala el tiempo de vendado acorde. + + + Bandage Effectiveness Coefficient + Współczynnik Efektywności Bandażowania + Verbandswirksamkeitskoeffizient + 붕대 효과 계수 + Coefficient d'efficacité des bandages + Coefficiente di efficacia bendaggi + 包帯有効性係数 + Коэффициент эффективности повязки + Coeficiente de Efectividad de Vendado + + + Determines how effective bandages are at closing wounds. + Określa skuteczność bandaży w zamykaniu ran. + Bestimmt, wie wirksam Bandagen beim Verschließen von Wunden sind. + 붕대가 상처를 치료하는 데 얼마나 효과적으로 지속되는지 결정합니다. + Défini l'efficacité des bandages à refermer des plaies. + Determina quanto i bendaggi sono efficaci nel chiudere le ferite. + 包帯が傷をふさぐのにどれだけ効果的かを定義します。 + Определяет, насколько эффективны бинты при закрытии ран. + Determina como de efectivos son los vendajes cerrando heridas. + + + Medical Items + Przedmioty Medyczne + Matériel médical + Oggetti Medici + 의료 물품 + Orvosi felszerelés + Медицинские предметы + Zdravotnický materiál + Tıbbi Ürünler + Medizinisches Material + 医療品 + Objetos médicos + + + Zeus Treatment Time Coefficient + Coeff. di tempo per trattamenti Zeus + Zeit-Koeffizient für Zeus Behandlungen + Zeus治療時間係数 + 제우스 치료 시간 계수 + Коэффициент времени обработки Zeus + Coeff. de temps + Coeficiente de Tiempo del Tratamiento de Zeus + + + Multiply all treatment times with this coefficient when in Zeus. + Moltiplica il tempo di ogni trattamento per questo coefficiente quando si è Zeus. + Dauer von Behandlungen als Zeus wird mit diesem Koeffizienten multipliziert. + Zeus操作中は、すべての治療時間にこの係数を掛けます。 + 제우스일 때 모든 치료 시간에 이 계수를 곱합니다. + Умножьте все время лечения на этот коэффициент, когда вы находитесь в Zeus. + Coefficient de temps de traitement Zeus + Multiplica los tiempos de tratamientos por este coeficiente cuando se está en Zeus + + + Painkillers + Léky proti bolesti + Schmerztabellen + Болеутоляющее + Środki przeciwbólowe + Antidolorifici + Analgésicos + Analgésiques + 止痛藥 + 鎮痛剤 + 진통제 + Analgésicos + 止痛药 + Ağrı kesici + + + Administer Painkillers + Somministra Antidolorifici + Испол-ть обезболивающие + 鎮痛剤を投与 + 진통제 투여 + Administrer des analgésiques + Verabreiche Schmerztabletten + Administrar Analgésicos + + + Administering Painkillers... + Somministrando Antidolorifici... + Использование обезболивающего... + 鎮痛剤を投与しています・・・ + 진통제 투여 중... + Administration d'analgésiques... + Verabreiche Schmerztablette... + Administrando Analgésicos... + + + Over-the-counter analgesic used to combat light to moderate pain experiences. + Antidolorifici senza prescrizione, usati per alleviare dolore leggero o moderato. + Безрецептурный анальгетик, используемый для борьбы с легкими и умеренными болевыми ощущениями. + 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 + 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. + Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. + + + Over-the-counter analgesic used to combat light to moderate pain experiences. + Antidolorifici senza prescrizione, usati per alleviare dolore leggero o moderato. + Безрецептурный анальгетик, используемый для борьбы с легкими и умеренными болевыми ощущениями. + 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 + 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. + Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. diff --git a/addons/medical_treatment/ui/bodybag_blue_ca.paa b/addons/medical_treatment/ui/bodybag_blue_ca.paa new file mode 100644 index 0000000000..2948b4639b Binary files /dev/null and b/addons/medical_treatment/ui/bodybag_blue_ca.paa differ diff --git a/addons/medical_treatment/ui/bodybag_white_ca.paa b/addons/medical_treatment/ui/bodybag_white_ca.paa new file mode 100644 index 0000000000..a4d789d45c Binary files /dev/null and b/addons/medical_treatment/ui/bodybag_white_ca.paa differ diff --git a/addons/medical_treatment/ui/painkillers_ca.paa b/addons/medical_treatment/ui/painkillers_ca.paa new file mode 100644 index 0000000000..15036c85cb Binary files /dev/null and b/addons/medical_treatment/ui/painkillers_ca.paa differ diff --git a/addons/medical_treatment/ui/suture_ca.paa b/addons/medical_treatment/ui/suture_ca.paa new file mode 100644 index 0000000000..4b27ca8509 Binary files /dev/null and b/addons/medical_treatment/ui/suture_ca.paa differ diff --git a/addons/medical_vitals/CfgEventHandlers.hpp b/addons/medical_vitals/CfgEventHandlers.hpp index 0d3301d6e0..865276cfba 100644 --- a/addons/medical_vitals/CfgEventHandlers.hpp +++ b/addons/medical_vitals/CfgEventHandlers.hpp @@ -1,17 +1,11 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(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)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/medical_vitals/CfgWeapons.hpp b/addons/medical_vitals/CfgWeapons.hpp new file mode 100644 index 0000000000..5c6e4c9fd8 --- /dev/null +++ b/addons/medical_vitals/CfgWeapons.hpp @@ -0,0 +1,10 @@ +class CfgWeapons { + class H_HelmetB; + class H_PilotHelmetFighter_B: H_HelmetB { + GVAR(oxygenSupply) = QUOTE(vehicle _this isKindOf 'Plane' || vehicle _this isKindOf 'Helicopter'); + }; + class Vest_Camo_Base; + class V_RebreatherB: Vest_Camo_Base { + GVAR(oxygenSupply) = QUOTE(eyePos _this select 2 < 0); // will only work for sea-level water + }; +}; diff --git a/addons/medical_vitals/XEH_PREP.hpp b/addons/medical_vitals/XEH_PREP.hpp index 8f8c427751..02f1cc5f89 100644 --- a/addons/medical_vitals/XEH_PREP.hpp +++ b/addons/medical_vitals/XEH_PREP.hpp @@ -1,4 +1,6 @@ PREP(handleUnitVitals); +PREP(scanConfig); PREP(updateHeartRate); +PREP(updateOxygen); PREP(updatePainSuppress); PREP(updatePeripheralResistance); diff --git a/addons/medical_vitals/XEH_postInit.sqf b/addons/medical_vitals/XEH_postInit.sqf deleted file mode 100644 index 6eccf9d1dd..0000000000 --- a/addons/medical_vitals/XEH_postInit.sqf +++ /dev/null @@ -1,2 +0,0 @@ -#include "script_component.hpp" - diff --git a/addons/medical_vitals/XEH_preInit.sqf b/addons/medical_vitals/XEH_preInit.sqf index b47cf6628d..8cc49805e9 100644 --- a/addons/medical_vitals/XEH_preInit.sqf +++ b/addons/medical_vitals/XEH_preInit.sqf @@ -6,4 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +GVAR(oxygenSupplyConditionCache) = uiNamespace getVariable QGVAR(oxygenSupplyConditionCache); + ADDON = true; diff --git a/addons/medical_vitals/XEH_preStart.sqf b/addons/medical_vitals/XEH_preStart.sqf index 022888575e..78dd8ad0e3 100644 --- a/addons/medical_vitals/XEH_preStart.sqf +++ b/addons/medical_vitals/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +GVAR(oxygenSupplyConditionCache) = createHashMap; + +call FUNC(scanConfig); + +GVAR(oxygenSupplyConditionCache) = compileFinal GVAR(oxygenSupplyConditionCache); diff --git a/addons/medical_vitals/addon.toml b/addons/medical_vitals/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/medical_vitals/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/medical_vitals/config.cpp b/addons/medical_vitals/config.cpp index 91995242c9..290c25bc9b 100644 --- a/addons/medical_vitals/config.cpp +++ b/addons/medical_vitals/config.cpp @@ -1,5 +1,13 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\nomedical\script_component.hpp") +#define PATCH_SKIP "No Medical" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -15,3 +23,6 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgWeapons.hpp" + +#endif diff --git a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf index 5fe474ad38..c284b00701 100644 --- a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf +++ b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Updates the vitals. Called from the statemachine's onState functions. @@ -7,20 +7,19 @@ * 0: The Unit * * Return Value: - * None + * Update Ran (at least 1 second between runs) * * Example: * [player] call ace_medical_vitals_fnc_handleUnitVitals * * Public: No */ -// #define DEBUG_MODE_FULL params ["_unit"]; private _lastTimeUpdated = _unit getVariable [QGVAR(lastTimeUpdated), 0]; private _deltaT = (CBA_missionTime - _lastTimeUpdated) min 10; -if (_deltaT < 1) exitWith {}; // state machines could be calling this very rapidly depending on number of local units +if (_deltaT < 1) exitWith { false }; // state machines could be calling this very rapidly depending on number of local units BEGIN_COUNTER(Vitals); @@ -32,6 +31,9 @@ if (_syncValues) then { _unit setVariable [QGVAR(lastMomentValuesSynced), CBA_missionTime]; }; +// Update SPO2 intake and usage since last update +[_unit, _deltaT, _syncValues] call FUNC(updateOxygen); + private _bloodVolume = GET_BLOOD_VOLUME(_unit) + ([_unit, _deltaT, _syncValues] call EFUNC(medical_status,getBloodVolumeChange)); _bloodVolume = 0 max _bloodVolume min DEFAULT_BLOOD_VOLUME; @@ -54,7 +56,7 @@ if (_hemorrhage != GET_HEMORRHAGE(_unit)) then { private _woundBloodLoss = GET_WOUND_BLEEDING(_unit); private _inPain = GET_PAIN_PERCEIVED(_unit) > 0; -if !(_inPain isEqualTo IS_IN_PAIN(_unit)) then { +if (_inPain isNotEqualTo IS_IN_PAIN(_unit)) then { _unit setVariable [VAR_IN_PAIN, _inPain, true]; }; @@ -76,7 +78,7 @@ private _painSupressAdjustment = 0; private _peripheralResistanceAdjustment = 0; private _adjustments = _unit getVariable [VAR_MEDICATIONS,[]]; -if !(_adjustments isEqualTo []) then { +if (_adjustments isNotEqualTo []) then { private _deleted = false; { _x params ["_medication", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust"]; @@ -88,7 +90,7 @@ if !(_adjustments isEqualTo []) then { private _effectRatio = (((_timeInSystem / _timeTillMaxEffect) ^ 2) min 1) * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem; if (_hrAdjust != 0) then { _hrTargetAdjustment = _hrTargetAdjustment + _hrAdjust * _effectRatio; }; if (_painAdjust != 0) then { _painSupressAdjustment = _painSupressAdjustment + _painAdjust * _effectRatio; }; - if (_hrAdjust != 0) then { _peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _flowAdjust * _effectRatio; }; + if (_flowAdjust != 0) then { _peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _flowAdjust * _effectRatio; }; }; } forEach _adjustments; @@ -165,3 +167,8 @@ if (!isPlayer _unit) then { #endif END_COUNTER(Vitals); + +//placed outside the counter as 3rd-party code may be called from this event +[QEGVAR(medical,handleUnitVitals), [_unit, _deltaT]] call CBA_fnc_localEvent; + +true diff --git a/addons/medical_vitals/functions/fnc_scanConfig.sqf b/addons/medical_vitals/functions/fnc_scanConfig.sqf new file mode 100644 index 0000000000..377b235315 --- /dev/null +++ b/addons/medical_vitals/functions/fnc_scanConfig.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Cache a hashmap of all oxygen-providing items for SpO2 simulation + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +private _filter = toString {getText (_x >> QGVAR(oxygenSupply)) != ""}; + +{ + private _cfgRoot = configFile >> _x; + { + private _condition = compile getText (_x >> QGVAR(oxygenSupply)); + GVAR(oxygenSupplyConditionCache) set [configName _x, _condition]; + } forEach (_filter configClasses _cfgRoot); +} forEach ["CfgWeapons", "CfgGoggles"]; diff --git a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf index 4da8519077..0390a9ad07 100644 --- a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf +++ b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Update the heart rate @@ -37,22 +37,22 @@ if IN_CRDC_ARRST(_unit) then { if (_bloodVolume > BLOOD_VOLUME_CLASS_4_HEMORRHAGE) then { GET_BLOOD_PRESSURE(_unit) params ["_bloodPressureL", "_bloodPressureH"]; private _meanBP = (2/3) * _bloodPressureH + (1/3) * _bloodPressureL; + private _spo2 = GET_SPO2(_unit); private _painLevel = GET_PAIN_PERCEIVED(_unit); - private _targetBP = 107; - if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then { - _targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME); - }; - _targetHR = DEFAULT_HEART_RATE; if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then { + private _targetBP = 107 * (_bloodVolume / DEFAULT_BLOOD_VOLUME); _targetHR = _heartRate * (_targetBP / (45 max _meanBP)); }; if (_painLevel > 0.2) then { _targetHR = _targetHR max (80 + 50 * _painLevel); }; + // Increase HR to compensate for low blood oxygen + // Increase HR to compensate for higher oxygen demand (e.g. running, recovering from sprint) + private _oxygenDemand = _unit getVariable [VAR_OXYGEN_DEMAND, 0]; + _targetHR = _targetHR + ((97 - _spo2) * 2) + (_oxygenDemand * -1000); _targetHR = (_targetHR + _hrTargetAdjustment) max 0; - _hrChange = round(_targetHR - _heartRate) / 2; } else { _hrChange = -round(_heartRate / 10); diff --git a/addons/medical_vitals/functions/fnc_updateOxygen.sqf b/addons/medical_vitals/functions/fnc_updateOxygen.sqf new file mode 100644 index 0000000000..f2c0f68f71 --- /dev/null +++ b/addons/medical_vitals/functions/fnc_updateOxygen.sqf @@ -0,0 +1,75 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Update the oxygen levels + * + * Arguments: + * 0: The Unit + * 1: Time since last update + * 2: Sync value? + * + * ReturnValue: + * Current SPO2 + * + * Example: + * [player, 1, false] call ace_medical_vitals_fnc_updateOxygen + * + * Public: No + */ + +params ["_unit", "_deltaT", "_syncValue"]; + +if (!GVAR(simulateSpO2)) exitWith {}; // changing back to default is handled in initSettings.inc.sqf + +#define IDEAL_PPO2 0.255 + +private _current = GET_SPO2(_unit); +private _heartRate = GET_HEART_RATE(_unit); + +private _altitude = EGVAR(common,mapAltitude) + ((getPosASL _unit) select 2); +private _po2 = if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then { + private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); + private _pressure = _altitude call EFUNC(weather,calculateBarometricPressure); + [_temperature, _pressure, EGVAR(weather,currentHumidity)] call EFUNC(weather,calculateOxygenDensity) +} else { + // Rough approximation of the partial pressure of oxygen in the air + 0.25725 * (_altitude / 1000 + 1) +}; + +private _oxygenSaturation = (IDEAL_PPO2 min _po2) / IDEAL_PPO2; + +// Check gear for oxygen supply +[goggles _unit, headgear _unit, vest _unit] findIf { + _x in GVAR(oxygenSupplyConditionCache) && + {ACE_player call (GVAR(oxygenSupplyConditionCache) get _x)} && + { // Will only run this if other conditions are met due to lazy eval + _oxygenSaturation = 1; + _po2 = IDEAL_PPO2; + true + } +}; + +// Base oxygen consumption rate +private _negativeChange = BASE_OXYGEN_USE; + +// Fatigue & exercise will demand more oxygen +// Assuming a trained male in midst of peak exercise will have a peak heart rate of ~180 BPM +// Ref: https://academic.oup.com/bjaed/article-pdf/4/6/185/894114/mkh050.pdf table 2, though we don't take stroke volume change into account +if (_unit == ACE_player && {missionNamespace getVariable [QEGVAR(advanced_fatigue,enabled), false]}) then { + _negativeChange = _negativeChange - ((1 - EGVAR(advanced_fatigue,aeReservePercentage)) * 0.1) - ((1 - EGVAR(advanced_fatigue,anReservePercentage)) * 0.05); +}; + +// Effectiveness of capturing oxygen +// increases slightly as po2 starts lowering +// but falls off quickly as po2 drops further +private _capture = 1 max ((_po2 / IDEAL_PPO2) ^ (-_po2 * 3)); +private _positiveChange = _heartRate * 0.00368 * _oxygenSaturation * _capture; + +private _breathingEffectiveness = 1; + +private _rateOfChange = _negativeChange + (_positiveChange * _breathingEffectiveness); + +private _spo2 = (_current + (_rateOfChange * _deltaT)) max 0 min 100; + +_unit setVariable [VAR_OXYGEN_DEMAND, _negativeChange - BASE_OXYGEN_USE]; +_unit setVariable [VAR_SPO2, _spo2, _syncValue]; diff --git a/addons/medical_vitals/functions/fnc_updatePainSuppress.sqf b/addons/medical_vitals/functions/fnc_updatePainSuppress.sqf index 1015549d62..36e8708be0 100644 --- a/addons/medical_vitals/functions/fnc_updatePainSuppress.sqf +++ b/addons/medical_vitals/functions/fnc_updatePainSuppress.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Update the pain suppression @@ -20,15 +20,16 @@ params ["_unit", "_painSupressAdjustment", "_deltaT", "_syncValue"]; -_unit setVariable [VAR_PAIN_SUPP, 0 max _painSupressAdjustment, _syncValue]; - // Handle continuous pain reduction private _pain = GET_PAIN(_unit); _unit setVariable [VAR_PAIN, 0 max (_pain - _deltaT / PAIN_FADE_TIME), _syncValue]; -// Handles simple medication if (isNil QEGVAR(medical_treatment,advancedMedication) || {!EGVAR(medical_treatment,advancedMedication)}) then { + // Handles simple medication private _painSupress = _unit getVariable [VAR_PAIN_SUPP, 0]; _painSupress = _painSupress - _deltaT / PAIN_SUPPRESSION_FADE_TIME; _unit setVariable [VAR_PAIN_SUPP, 0 max _painSupress, _syncValue]; +} else { + // Handle advanced medication + _unit setVariable [VAR_PAIN_SUPP, 0 max _painSupressAdjustment, _syncValue]; }; diff --git a/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf b/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf index c5552143c7..30f8038d80 100644 --- a/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf +++ b/addons/medical_vitals/functions/fnc_updatePeripheralResistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Update the peripheral resistance diff --git a/addons/medical_vitals/functions/script_component.hpp b/addons/medical_vitals/functions/script_component.hpp deleted file mode 100644 index 4fe94957b5..0000000000 --- a/addons/medical_vitals/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\medical_vitals\script_component.hpp" diff --git a/addons/medical_vitals/initSettings.inc.sqf b/addons/medical_vitals/initSettings.inc.sqf new file mode 100644 index 0000000000..db762d2c52 --- /dev/null +++ b/addons/medical_vitals/initSettings.inc.sqf @@ -0,0 +1,15 @@ +[ + QGVAR(simulateSpO2), + "CHECKBOX", + [LSTRING(simulateSpO2_DisplayName), LSTRING(simulateSpO2_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + 1, + { + if (_this) exitWith {}; // skip if true + { + _x setVariable [VAR_OXYGEN_DEMAND, 0, true]; + _x setVariable [VAR_SPO2, DEFAULT_SPO2, true]; + } forEach (allUnits select {local _x}) + } // reset oxygen demand on setting change +] call CBA_fnc_addSetting; diff --git a/addons/medical_vitals/script_component.hpp b/addons/medical_vitals/script_component.hpp index 3bfb4bcc26..1064ebc52c 100644 --- a/addons/medical_vitals/script_component.hpp +++ b/addons/medical_vitals/script_component.hpp @@ -16,3 +16,5 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" + +#define BASE_OXYGEN_USE -0.25 diff --git a/addons/medical_vitals/stringtable.xml b/addons/medical_vitals/stringtable.xml new file mode 100644 index 0000000000..2fe7336dc0 --- /dev/null +++ b/addons/medical_vitals/stringtable.xml @@ -0,0 +1,36 @@ + + + + + Vitals + Vitais + Parametri Vitali + Жизненно-важные органы + バイタル + 생명 + Paramètres vitaux + Vitalwerte + Vitales + + + Enable SpO2 Simulation + Abilita simulazione SpO2 + Включить имитацию SpO2 + SpO2シミュレーションを有効化 + 산소포화도 시뮬레이션 활성화 + Activer la simulation de la SpO2 + SpO2-Simulation aktivieren + Habilitar Simulación SpO2 + + + Enables oxygen saturation simulation, providing variable heart rate and oxygen demand based on physical activity and altitude. Required for Airway Management. + Abilita la simulazione della saturazione di ossigeno, alterando la frequenza cardiaca e consumo di ossigeno in funzione dell'attività fisica e l'altitudine. Richiesto per la gestione delle vie aeree. + Позволяет имитировать насыщение кислородом, обеспечивая переменную частоту сердечных сокращений и потребность в кислороде в зависимости от физической активности и высоты над уровнем моря. Требуется для управления дыхательными путями. + 酸素飽和度シミュレーションを有効にし、身体活動や標高に基づいて変動する心拍数と酸素要求量の機能を提供します。 気道管理に必要です。 + 산소포화도 시뮬레이션을 활성화하여 신체 활동과 고도에 따라 다양한 심박수와 산소 요구량을 제공합니다. 기도 관리에 필요합니다. + Permet de simuler la saturation en oxygène, de modifier la fréquence cardiaque et la consommation d'oxygène en fonction de l'activité physique et de l'altitude. Nécessaire pour la gestion des voies respiratoires. + Aktiviert die Simulation der Sauerstoffsättigung und bietet variable Herzfrequenz und Sauerstoffbedarf basierend auf körperlicher Aktivität und Geländehöhe. Erforderlich für das Atemwegsmanagement. + Habilita la saturación de oxígeno, utilizando la demanda de oxígeno y ritmo cardíaco basado en la actividad física y la altitud. Requerido para el Manejo de las Vías Aéreas. + + + diff --git a/addons/metis/$PBOPREFIX$ b/addons/metis/$PBOPREFIX$ new file mode 100644 index 0000000000..d37f3f7328 --- /dev/null +++ b/addons/metis/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\metis \ No newline at end of file diff --git a/addons/metis/CfgAmmo.hpp b/addons/metis/CfgAmmo.hpp new file mode 100644 index 0000000000..1f613a36b1 --- /dev/null +++ b/addons/metis/CfgAmmo.hpp @@ -0,0 +1,81 @@ +class CfgAmmo { + class M_Vorona_HEAT; + class GVAR(HEAT): M_Vorona_HEAT { + manualControl = 0; + irLock = 0; + laserLock = 0; + airLock = 0; + lockType = 0; + + class ace_missileguidance { + enabled = 1; + + minDeflection = 0; // Minium flap deflection for guidance + maxDeflection = 0.0027; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 15; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 80; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + correctionDistance = 3; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; + }; + }; + + class M_Vorona_HE; + class GVAR(HE): M_Vorona_HE { + manualControl = 0; + irLock = 0; + laserLock = 0; + airLock = 0; + lockType = 0; + + class ace_missileguidance { + enabled = 1; + + minDeflection = 0; // Minium flap deflection for guidance + maxDeflection = 0.0027; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 15; // Angle from the shooter's view that can track the missile + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 80; + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + + correctionDistance = 3; // distance from center of crosshair where missile slows down + offsetFromCrosshair[] = { 0, 0, 0 }; // where the missile wants to stay in relation to the center of the crosshair. + + // Attack profile type selection + defaultAttackProfile = "WIRE"; + attackProfiles[] = {"WIRE"}; + }; + }; +}; diff --git a/addons/metis/CfgMagazines.hpp b/addons/metis/CfgMagazines.hpp new file mode 100644 index 0000000000..2d20d942dc --- /dev/null +++ b/addons/metis/CfgMagazines.hpp @@ -0,0 +1,10 @@ +class CfgMagazines { + class CA_LauncherMagazine; + class Vorona_HEAT: CA_LauncherMagazine { + ammo = QGVAR(HEAT); + }; + class Vorona_HE: Vorona_HEAT { + ammo = QGVAR(HE); + }; +}; + diff --git a/addons/metis/README.md b/addons/metis/README.md new file mode 100644 index 0000000000..4f735d21a8 --- /dev/null +++ b/addons/metis/README.md @@ -0,0 +1,4 @@ +ace_metis +=================== + +Converts vanilla "Vorona" Missile Guidance into ACE SACLOS Guidance diff --git a/addons/metis/config.cpp b/addons/metis/config.cpp new file mode 100644 index 0000000000..f16d3c7892 --- /dev/null +++ b/addons/metis/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"tcvm"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" + diff --git a/addons/metis/script_component.hpp b/addons/metis/script_component.hpp new file mode 100644 index 0000000000..d812eba2a2 --- /dev/null +++ b/addons/metis/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT metis +#define COMPONENT_BEAUTIFIED Metis +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_METIS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_METIS + #define DEBUG_SETTINGS DEBUG_SETTINGS_METIS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + diff --git a/addons/microdagr/CfgEventHandlers.hpp b/addons/microdagr/CfgEventHandlers.hpp index 789cfeb05c..e325095c32 100644 --- a/addons/microdagr/CfgEventHandlers.hpp +++ b/addons/microdagr/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); }; }; diff --git a/addons/microdagr/CfgVehicles.hpp b/addons/microdagr/CfgVehicles.hpp index cc06db69f9..7b7a1ff61b 100644 --- a/addons/microdagr/CfgVehicles.hpp +++ b/addons/microdagr/CfgVehicles.hpp @@ -71,8 +71,9 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(itemName); author = ECSTRING(common,ACETeam); - vehicleClass = "Items"; icon = QPATHTOF(UI\icon_microDAGR.paa); + vehicleClass = "Items"; + model = "\A3\Weapons_f\DummyWeapon.p3d"; class TransportItems { MACRO_ADDITEM(ACE_microDAGR,1); }; diff --git a/addons/microdagr/CfgWeapons.hpp b/addons/microdagr/CfgWeapons.hpp index 6c7c920427..aebe427c90 100644 --- a/addons/microdagr/CfgWeapons.hpp +++ b/addons/microdagr/CfgWeapons.hpp @@ -9,6 +9,7 @@ class CfgWeapons { descriptionShort = CSTRING(itemDescription); model = QPATHTOF(data\MicroDAGR.p3d); picture = QPATHTOF(images\microDAGR_item.paa); + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; diff --git a/addons/microdagr/XEH_clientInit.sqf b/addons/microdagr/XEH_clientInit.sqf index 7a8d775a05..c17914ad4b 100644 --- a/addons/microdagr/XEH_clientInit.sqf +++ b/addons/microdagr/XEH_clientInit.sqf @@ -17,9 +17,25 @@ private _closeCode = { }; [(localize LSTRING(itemName)), QPATHTOF(images\microDAGR_item.paa), _conditonCode, _toggleCode, _closeCode] call EFUNC(common,deviceKeyRegisterNew); +// Mode keybinds: +["ACE3 Equipment", QGVAR(previousMode), LLSTRING(previousMode), { + private _newMode = GVAR(currentApplicationPage) - 1; + if (_newMode < APP_MODE_INFODISPLAY) then { + _newMode = APP_MODE_SETUP; + }; + [_newMode] call FUNC(saveCurrentAndSetNewMode); +}, ""] call CBA_fnc_addKeybind; + +["ACE3 Equipment", QGVAR(nextMode), LLSTRING(nextMode), { + private _newMode = GVAR(currentApplicationPage) + 1; + if (_newMode > APP_MODE_SETUP) then { + _newMode = APP_MODE_INFODISPLAY; + }; + [_newMode] call FUNC(saveCurrentAndSetNewMode); +}, ""] call CBA_fnc_addKeybind; //Add Eventhandler: -[QEGVAR(vector,rangefinderData), {_this call FUNC(recieveRangefinderData)}] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(recieveRangefinderData)] call CBA_fnc_addEventHandler; //Global Variables to default: GVAR(gpsPositionASL) = [0,0,0]; diff --git a/addons/microdagr/XEH_preInit.sqf b/addons/microdagr/XEH_preInit.sqf index b46948b0bb..610dc0ed81 100644 --- a/addons/microdagr/XEH_preInit.sqf +++ b/addons/microdagr/XEH_preInit.sqf @@ -9,6 +9,6 @@ PREP_RECOMPILE_END; //Functions that are called for each draw of the map: GVAR(miniMapDrawHandlers) = []; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/microdagr/data/MicroDAGR.p3d b/addons/microdagr/data/MicroDAGR.p3d deleted file mode 100644 index bd4ea59090..0000000000 Binary files a/addons/microdagr/data/MicroDAGR.p3d and /dev/null differ diff --git a/addons/microdagr/data/MicroDAGR_nohq.paa b/addons/microdagr/data/MicroDAGR_nohq.paa deleted file mode 100644 index 1b9c8a337c..0000000000 Binary files a/addons/microdagr/data/MicroDAGR_nohq.paa and /dev/null differ diff --git a/addons/microdagr/data/MicroDAGR_smdi.paa b/addons/microdagr/data/MicroDAGR_smdi.paa deleted file mode 100644 index 66c69a63b3..0000000000 Binary files a/addons/microdagr/data/MicroDAGR_smdi.paa and /dev/null differ diff --git a/addons/microdagr/data/microdagr.p3d b/addons/microdagr/data/microdagr.p3d new file mode 100644 index 0000000000..5726b7b4ca Binary files /dev/null and b/addons/microdagr/data/microdagr.p3d differ diff --git a/addons/microdagr/data/microdagr.rvmat b/addons/microdagr/data/microdagr.rvmat index 6f3522304c..e6d9148ed7 100644 --- a/addons/microdagr/data/microdagr.rvmat +++ b/addons/microdagr/data/microdagr.rvmat @@ -1,92 +1,80 @@ -ambient[] = {0.6,0.6,0.6,0.6}; -diffuse[] = {0.6,0.6,0.6,0.6}; -forcedDiffuse[] = {0.0,0.0,0.0,0.0}; -emmisive[] = {0.0,0.0,0.0,0.6}; -specular[] = {0.1,0.1,0.1,0.2}; -specularPower = 90.0; +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.4,0.4,0.4,1}; //amount of glossiness - the higher the number, the higher the glossiness +specularPower = 500; //area of glossiness - the higher the number, the smaller the area PixelShaderID = "Super"; VertexShaderID = "Super"; -class Stage1 -{ - texture="z\ace\addons\microdagr\data\MicroDAGR_nohq.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage1 { + texture = "z\ace\addons\microdagr\data\microdagr_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="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; - uvSource="tex"; - class uvTransform - { - aside[]={0,9,0}; - up[]={4.5,0,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,1}; + pos[] = {0,0,0}; + }; }; -class Stage3 -{ - texture="#(argb,8,8,3)color(0.5,0.5,0.5,0,MC)"; - 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,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,0}; - pos[]={0,0,0}; - }; + +class Stage4 { + texture = "z\ace\addons\microdagr\data\microdagr_as.paa"; + uvSource = "tex"; + + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,1}; + }; }; -class Stage5 -{ - texture="z\ace\addons\microdagr\data\MicroDAGR_smdi.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\microdagr\data\microdagr_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,16,2,2)fresnel(10.4,8.3)"; - 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,0}; - pos[]={0,0,0}; - }; + +class Stage6 { + texture = "#(ai,64,64,1)fresnel(4.7,1.2)"; + uvSource = "tex"; + + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; }; diff --git a/addons/microdagr/data/microdagr_as.paa b/addons/microdagr/data/microdagr_as.paa new file mode 100644 index 0000000000..74c3af7df9 Binary files /dev/null and b/addons/microdagr/data/microdagr_as.paa differ diff --git a/addons/microdagr/data/microdagr_co.paa b/addons/microdagr/data/microdagr_co.paa index 6efd68bff5..0b1d5a3093 100644 Binary files a/addons/microdagr/data/microdagr_co.paa and b/addons/microdagr/data/microdagr_co.paa differ diff --git a/addons/microdagr/data/microdagr_nohq.paa b/addons/microdagr/data/microdagr_nohq.paa new file mode 100644 index 0000000000..5880af2401 Binary files /dev/null and b/addons/microdagr/data/microdagr_nohq.paa differ diff --git a/addons/microdagr/data/microdagr_smdi.paa b/addons/microdagr/data/microdagr_smdi.paa new file mode 100644 index 0000000000..b8b5b6b4aa Binary files /dev/null and b/addons/microdagr/data/microdagr_smdi.paa differ diff --git a/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf b/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf index ece62c22e9..8d77fb6605 100644 --- a/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf +++ b/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the keypad entries from the "Mark" Application diff --git a/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf b/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf index 4aa01155ca..da22251453 100644 --- a/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf +++ b/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the "Connect To" button from the menu application diff --git a/addons/microdagr/functions/fnc_appSettingsLBClick.sqf b/addons/microdagr/functions/fnc_appSettingsLBClick.sqf index 5c5c511ca6..4f084b5932 100644 --- a/addons/microdagr/functions/fnc_appSettingsLBClick.sqf +++ b/addons/microdagr/functions/fnc_appSettingsLBClick.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles double clicking on the setting listbox diff --git a/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf b/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf index 61508a1553..8649d8d962 100644 --- a/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf +++ b/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles clicking the delete button from the waypoint application diff --git a/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf b/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf index 80d5cfaef6..d888eb4bbf 100644 --- a/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf +++ b/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles clicking the setWP button from the waypoint application diff --git a/addons/microdagr/functions/fnc_canShow.sqf b/addons/microdagr/functions/fnc_canShow.sqf index 0c80896661..141fad9ed0 100644 --- a/addons/microdagr/functions/fnc_canShow.sqf +++ b/addons/microdagr/functions/fnc_canShow.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Tests if the dagr can be shown in a mode diff --git a/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf b/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf index 443ab193e4..080ff73deb 100644 --- a/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf +++ b/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Adds a waypoint to the "device" diff --git a/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf b/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf index 895b64bb38..14bfcbf1de 100644 --- a/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf +++ b/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Deletes a waypoint from the "device" diff --git a/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf b/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf index c231b583b4..d392024b0b 100644 --- a/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf +++ b/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Gets all waypoints from the "device" @@ -11,7 +11,7 @@ * Waypoints * * Example: - * [["Hill 55", [41,324, 12]]] = [] call ace_microdagr_fnc_deviceGetWaypoint + * [["Hill 55", [41,324, 12]]] = [] call ace_microdagr_fnc_deviceGetWaypoints * * Public: No */ diff --git a/addons/microdagr/functions/fnc_dialogClosedEH.sqf b/addons/microdagr/functions/fnc_dialogClosedEH.sqf index fc94b101f5..942167462b 100644 --- a/addons/microdagr/functions/fnc_dialogClosedEH.sqf +++ b/addons/microdagr/functions/fnc_dialogClosedEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the dialog closeing, switches back to display mode diff --git a/addons/microdagr/functions/fnc_mapButtonDownEH.sqf b/addons/microdagr/functions/fnc_mapButtonDownEH.sqf index 9ca55bc5ab..6a92ebc601 100644 --- a/addons/microdagr/functions/fnc_mapButtonDownEH.sqf +++ b/addons/microdagr/functions/fnc_mapButtonDownEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles right clicking on the map ('dragging' the map) diff --git a/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf b/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf index aeb73414f5..00d53418b1 100644 --- a/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf +++ b/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the double tapping either of the 2 mini-maps diff --git a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf index 15c1b0a59c..86415a1914 100644 --- a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf +++ b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the draw event from all 3 maps (compass + 2 minimaps) @@ -60,7 +60,7 @@ if (GVAR(currentApplicationPage) == 1) then { _size = 32 * _mapSize; { _x params ["_wpName", "_wpPos"]; - private _alpha = if (_forEachIndex == GVAR(currentWaypoint)) then {1} else {0.5}; + private _alpha = [0.5, 1] select (_forEachIndex == GVAR(currentWaypoint)); _theMap drawIcon [QUOTE(PATHTO_R(images\icon_mapWaypoints.paa)), [1,1,1,_alpha], _wpPos, _size, _size, 0, '', 0 ]; } forEach _waypoints; }; diff --git a/addons/microdagr/functions/fnc_modeMapButtons.sqf b/addons/microdagr/functions/fnc_modeMapButtons.sqf index 8ed8171535..e1a0509ee4 100644 --- a/addons/microdagr/functions/fnc_modeMapButtons.sqf +++ b/addons/microdagr/functions/fnc_modeMapButtons.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Takes some arguments and returns something or other. diff --git a/addons/microdagr/functions/fnc_moduleMapFill.sqf b/addons/microdagr/functions/fnc_moduleMapFill.sqf index 01e6af799f..aa227830da 100644 --- a/addons/microdagr/functions/fnc_moduleMapFill.sqf +++ b/addons/microdagr/functions/fnc_moduleMapFill.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Function for the module (handles the map fill level) diff --git a/addons/microdagr/functions/fnc_openDisplay.sqf b/addons/microdagr/functions/fnc_openDisplay.sqf index 775378a533..56d404bf6f 100644 --- a/addons/microdagr/functions/fnc_openDisplay.sqf +++ b/addons/microdagr/functions/fnc_openDisplay.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Changes the display mode of the MicroDAGR. diff --git a/addons/microdagr/functions/fnc_recieveRangefinderData.sqf b/addons/microdagr/functions/fnc_recieveRangefinderData.sqf index 640c42cfe4..8fd16d68f7 100644 --- a/addons/microdagr/functions/fnc_recieveRangefinderData.sqf +++ b/addons/microdagr/functions/fnc_recieveRangefinderData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Recieves the data packet from the vector rangefinder diff --git a/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf b/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf index 973e0ac7fb..c756b63141 100644 --- a/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf +++ b/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Saves the current mode and sets a new mode @@ -20,7 +20,7 @@ params ["_newMode"]; disableSerialization; private _display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; -if (isNull _display) exitWith {ERROR("No Display");}; +if (isNull _display) exitWith {LOG("No Display");}; if (GVAR(currentApplicationPage) == 2) then { private _theMap = [_display displayCtrl IDC_MAPDETAILS, _display displayCtrl IDC_MAPPLAIN] select (!GVAR(mapShowTexture)); diff --git a/addons/microdagr/functions/fnc_showApplicationPage.sqf b/addons/microdagr/functions/fnc_showApplicationPage.sqf index 1ba8a36d45..75f817ad3f 100644 --- a/addons/microdagr/functions/fnc_showApplicationPage.sqf +++ b/addons/microdagr/functions/fnc_showApplicationPage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Changes the "application page" shown on the microDAGR diff --git a/addons/microdagr/functions/fnc_updateDisplay.sqf b/addons/microdagr/functions/fnc_updateDisplay.sqf index 877bbb2bcc..3e5775b86d 100644 --- a/addons/microdagr/functions/fnc_updateDisplay.sqf +++ b/addons/microdagr/functions/fnc_updateDisplay.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Updates the display (several times a second) called from the pfeh @@ -44,7 +44,7 @@ case (APP_MODE_INFODISPLAY): { (_display displayCtrl IDC_MODEDISPLAY_ELEVATIONNUM) ctrlSetText _aboveSeaLevelText; //Heading: - _compassAngleText = if (GVAR(settingUseMils)) then { + private _compassAngleText = if (GVAR(settingUseMils)) then { [(floor ((6400 / 360) * (([ACE_player] call CBA_fnc_headDir) select 0))), 4, 0] call CBA_fnc_formatNumber; } else { ([([ACE_player] call CBA_fnc_headDir) select 0, 3, 1] call CBA_fnc_formatNumber) + "°" //degree symbol is in UTF-8 @@ -65,12 +65,12 @@ case (APP_MODE_INFODISPLAY): { } else { private _targetPosName = ""; private _targetPosLocationASL = []; - _bearingText = "----"; - _rangeText = "----"; + private _bearingText = "----"; + private _rangeText = "----"; _aboveSeaLevelText = "----"; if (GVAR(currentWaypoint) == -2) then { - if (!(GVAR(rangeFinderPositionASL) isEqualTo [])) then { + if (GVAR(rangeFinderPositionASL) isNotEqualTo []) then { private _targetPos = [GVAR(rangeFinderPositionASL)] call EFUNC(common,getMapGridFromPos); _targetPosName = format ["[%1 %2 %3]", EGVAR(common,MGRS_data) select 1, _targetPos select 0, _targetPos select 1]; _targetPosLocationASL = GVAR(rangeFinderPositionASL); @@ -81,7 +81,7 @@ case (APP_MODE_INFODISPLAY): { _targetPosLocationASL = (_waypoints select GVAR(currentWaypoint)) select 1; }; - if (!(_targetPosLocationASL isEqualTo [])) then { + if (_targetPosLocationASL isNotEqualTo []) then { private _bearing = [(getPosASL ACE_player), _targetPosLocationASL] call BIS_fnc_dirTo; _bearingText = if (GVAR(settingUseMils)) then { [(floor ((6400 / 360) * (_bearing))), 4, 0] call CBA_fnc_formatNumber; @@ -123,7 +123,7 @@ case (APP_MODE_COMPASS): { private _targetPosLocationASL = []; if (GVAR(currentWaypoint) == -2) then { - if (!(GVAR(rangeFinderPositionASL) isEqualTo [])) then { + if (GVAR(rangeFinderPositionASL) isNotEqualTo []) then { private _targetPos = [GVAR(rangeFinderPositionASL)] call EFUNC(common,getMapGridFromPos); _targetPosName = format ["[%1 %2 %3]", EGVAR(common,MGRS_data) select 1, _targetPos select 0, _targetPos select 1]; _targetPosLocationASL = GVAR(rangeFinderPositionASL); @@ -134,10 +134,10 @@ case (APP_MODE_COMPASS): { _targetPosLocationASL = (_waypoints select GVAR(currentWaypoint)) select 1; }; - _bearingText = "---"; - _rangeText = "---"; + private _bearingText = "---"; + private _rangeText = "---"; - if (!(_targetPosLocationASL isEqualTo [])) then { + if (_targetPosLocationASL isNotEqualTo []) then { private _bearing = [(getPosASL ACE_player), _targetPosLocationASL] call BIS_fnc_dirTo; _bearingText = if (GVAR(settingUseMils)) then { [(floor ((6400 / 360) * (_bearing))), 4, 0] call CBA_fnc_formatNumber; diff --git a/addons/microdagr/functions/script_component.hpp b/addons/microdagr/functions/script_component.hpp deleted file mode 100644 index 13fbbcf5fe..0000000000 --- a/addons/microdagr/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\microdagr\script_component.hpp" \ No newline at end of file diff --git a/addons/microdagr/gui_controls.hpp b/addons/microdagr/gui_controls.hpp index 4fd194e1ab..5ab0b27b25 100644 --- a/addons/microdagr/gui_controls.hpp +++ b/addons/microdagr/gui_controls.hpp @@ -116,12 +116,12 @@ class controlsBackground { colorRocks[] = {0.50, 0.50, 0.50, 0.50}; - class hospital: Hospital {color[] = {0,0,0,0.25};}; - class church: Church {color[] = {0,0,0,0.25};}; - class lighthouse: Lighthouse {color[] = {0,0,0,0.25};}; + class Hospital: Hospital {color[] = {0,0,0,0.25};}; + class church: church {color[] = {0,0,0,0.25};}; + class Lighthouse: Lighthouse {color[] = {0,0,0,0.25};}; class power: power {color[] = {0,0,0,0.25};}; - class fuelstation: Fuelstation {color[] = {0,0,0,0.25};}; - class transmitter: Transmitter {color[] = {0,0,0,0.25};}; + class Fuelstation: Fuelstation {color[] = {0,0,0,0.25};}; + class Transmitter: Transmitter {color[] = {0,0,0,0.25};}; }; class MapCompass: RscMapControlEmpty { @@ -132,9 +132,12 @@ class controlsBackground { h = H_PART(19); onDraw = QUOTE(_this call FUNC(mapOnDrawEH)); + showMarkers = 0; colorBackground[] = {0,0,0,1}; colorOutside[] = {0,0,0,1}; moveOnEdges = 0; + + showCountourInterval = 0; }; }; diff --git a/addons/microdagr/initSettings.inc.sqf b/addons/microdagr/initSettings.inc.sqf new file mode 100644 index 0000000000..aacc5fd24b --- /dev/null +++ b/addons/microdagr/initSettings.inc.sqf @@ -0,0 +1,19 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(itemName)]; + +[ + QGVAR(mapDataAvailable), "LIST", + [LSTRING(MapDataAvailable_DisplayName), LSTRING(MapDataAvailable_Description)], + _category, + [[0,1,2],[LSTRING(MapFill_None), LSTRING(MapFill_OnlyRoads), LSTRING(MapFill_Full)],2], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(mapDataAvailable), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // require mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(waypointPrecision), "LIST", + [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], + _category, + [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/microdagr/initSettings.sqf b/addons/microdagr/initSettings.sqf deleted file mode 100644 index 5138637645..0000000000 --- a/addons/microdagr/initSettings.sqf +++ /dev/null @@ -1,21 +0,0 @@ -// CBA Settings [ADDON: ace_microdagr]: - -[ - QGVAR(mapDataAvailable), "LIST", - [LSTRING(MapDataAvailable_DisplayName), LSTRING(MapDataAvailable_Description)], - ["ACE Uncategorized", "MicroDAGR"], - [[0,1,2],[LSTRING(MapFill_None), LSTRING(MapFill_OnlyRoads), LSTRING(MapFill_Full)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(mapDataAvailable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // require mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(waypointPrecision), "LIST", - [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], - ["ACE Uncategorized", "MicroDAGR"], - [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // require mission restart -] call cba_settings_fnc_init; diff --git a/addons/microdagr/readme.md b/addons/microdagr/readme.md index d7bcf01b40..e85159f23d 100644 --- a/addons/microdagr/readme.md +++ b/addons/microdagr/readme.md @@ -1,7 +1,7 @@ ace_microdagr =============== -Adds a MicroDAGR infantry GPS device. +Adds a MicroDAGR infantry GPS device. Press home to open. Then home again to toggle an interactive version. Press CTRL+Home to close. Info/Compass/Minimap modes are selectable by the bottom buttons. Tap the top bar to open the menu and access Mark/Waypoints/Connect To/Settings modes. Tap the minimap button again to toggle map modes (if available). @@ -11,15 +11,7 @@ Can interface with the `ace_vector`. Hold Azimuth+Range and release (see page 14 #### Items Added: `ACE_microDAGR` - ## For Mission Makers: #### Modules: - MicroDAGR Map Fill - Controls the amount of map data available for the minimap. Can limit to just roads/topographical or disable entirely. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/microdagr/stringtable.xml b/addons/microdagr/stringtable.xml index e5fc0347db..c9bd546afc 100644 --- a/addons/microdagr/stringtable.xml +++ b/addons/microdagr/stringtable.xml @@ -8,14 +8,15 @@ MicroDAGR GPS MicroDAGR GPS MicroDAGR GPS - MicroDAGR GPS + MicroDAGR MicroDAGR GPS GPS MicroDAGR GPS MicroDAGR MicroDAGR GPS - MicroDAGR GPS - 微型军用GPS接收器 + 마이크로DAGR GPS + 微型军用 GPS 接收器 微型軍用GPS接收器 + MicroDAGR GPS MicroDAGR advanced GPS receiver @@ -23,14 +24,14 @@ Receptor avanzado GPS MicroDAGR Многофункциональный GPS-приёмник. Zaawansowany odbiornik GPS MicroDAGR - Récepteur GPS MicroDAGR + MicroDAGR - Récepteur GPS avancé MicroDAGR pokročílá GPS příjímač MicroDAGR fejlett GPS vevőegység Ricevitore GPS avanzato MicroDAGR - Recepitor GPS avançado MicroDAGR - MicroDAGR は改良された GPS 受信機です - MicroDAGR 고급 위성항법 수신기 - 微型军用高级防御GPS接收器 + Receptor GPS avançado MicroDAGR + MicroDAGRは改良された高度なGPS受信機です + 마이크로DAGR 고급 위성항법 수신기 + 微型军用高级防御 GPS 接收器 微型軍用高級防禦GPS接收器 @@ -38,24 +39,40 @@ Unidad angular: Угловые единицы: Jednostka kątowa: - Unité angulaire + Unité angulaire : Winkeleinheit: Úhlová jednotka: Szögmértékegység: Unità angolare: Unidade Angular: - 角度の種類: + 角度の単位: 각도의 단위: - 角密位: + 角密位: 角密位: + + Degrees + Grad + Grados + Градусы + Stopnie + Degré + Stupně + Fok + Gradi + Graus + + 각도 + + + Mils Mil Mils Тысячные Tysiączne - Mils + Mil Mils Mil Mils @@ -71,36 +88,20 @@ Mostrar puntos de ruta en el mapa: Показывать маршрутные точки на карте: Pokaż PT na mapie: - Montrer points de passage sur la carte + Montrer les WP sur la carte : Ukázat waypointy na mapě: Útvonalpontok mutatása a térképen: Mostra waypoint sulla mappa: Mostrar Waypoints no mapa: - 地図へウェイポイントを表示: + 地図にウェイポイントを表示: 웨이포인트를 지도에 보이기: - 显示路径点在地图上: + 显示路径点在地图上: 顯示路徑點在地圖上: - - Degrees - Grad - Grados - Градусы - Stopnie - Degrés - Stupně - Fok - Gradi - Graus - 角度 - 각도 - - - On Zapnuto - Allumé + Actif Ein Acceso Wł. @@ -108,15 +109,16 @@ Вкл. Encendido Be - 有効 + オン 켜기 开启 開啟 + Açık Off Vypnuto - Eteint + Inactif Aus Spento Wył. @@ -124,10 +126,11 @@ Выкл. Apagado Ki - 無効 + オフ 끄기 关闭 關閉 + Kapalı Enter Grid Cords: @@ -138,10 +141,10 @@ Koordinaten eingeben: Napiš souřadnice: Add meg a rácskoordinátákat: - Introduci griglia coordinate: - Digite as Ccords. do Grid + Inserisci coordinata-griglia: + Digite as Coords. do Grid 座標を入力: - 输入网格座标: + 输入网格座标: 輸入網格座標: 좌표 입력: @@ -151,12 +154,12 @@ Nombre de [%1] Название [%1] Nazwa [%1] - Nom de %1 + Nom de [%1] Název [%1] [%1] neve Nome di [%1] Nome do [%1] - [%1] の名前 + [%1] の名称 [%1] 의 이름 名称 [%1] 名稱 [%1] @@ -167,15 +170,15 @@ Nuevo-MGRS MGRS-Новая MGRS-Nowy - Info-MGRS + MGRS-Nouveau MGRS-Nový MGRS-új Nuovo MGRS MGRS-Novo MGRS-New - 军事网格座标系统-新型 - 軍事網格座標系統-新型 - MGRS-New + 军事网格座标系统—新型 + 軍事網格座標系統—新型 + 군용 좌표 시스템-신형 WGD @@ -189,7 +192,7 @@ WGD WGD WGD - WGD + 세계좌표 世界座标 世界座標 @@ -199,14 +202,14 @@ Distanz: Дистанция: Dystans: - Distance: + Distance : Vzdálenost: Távolság: Distanza: Distância: 距離: 거리: - 范围: + 范围: 範圍: @@ -219,10 +222,10 @@ Azimut: Irányszög Azimut - Direção na bússula - 方位磁石での方位 + Direção na bússola + 方位磁石 방위 - 指北针方位 + 指南针方位 指北針方位 @@ -231,7 +234,7 @@ Marca Отметка Oznacz - Marque + Marquer Označit Jelölés Marca @@ -248,9 +251,9 @@ Машрутные точки Waypointy Punkty trasy - Point de passage + Points de passage Útvonalpontok - waypoints + Waypoints Waypoints ウェイポイント 웨이포인트 @@ -266,9 +269,9 @@ Podłącz do Connecter Csatlakozás - Collega a + Collega a Conectar à - 次に接続 + 接続 연결 连接到 連接到 @@ -282,7 +285,7 @@ Nastavení Ustawienia Beállítások - Impostaizoni + Impostazioni Opções 設定 설정 @@ -296,11 +299,11 @@ Установить МТ Nastavit WP UstawPT - Définir point de passage + ChoixWP UP Beállítása - Definisci WayPoints + Definisci WayPoint Definir WP - WP設定 + WPセット 웨이포인트 설정 设置路径点 設置路徑點 @@ -312,7 +315,7 @@ Добавить Přidat Dodaj - Ajouter + Ajout Hozzáadás Aggiungi Adicionar @@ -324,7 +327,7 @@ Delete Smazat - Supprimer + Suppr. Löschen Elimina Usuń @@ -348,13 +351,13 @@ MicroDAGR kijelzési mód váltása Alterna modalità display MicroDAGR Alternar Modo de Display do MicroDAGR - MicroDAGR の表示モード - MicroDAGR 화면 모드 토글 - 切换微型军用GPS接收器显示模式 + MicroDAGR の表示モード切り替え + 마이크로DAGR 화면 모드 토글 + 切换微型军用 GPS 接收器显示模式 切換微型軍用GPS接收器顯示模式 - Show MicoDAGR + Show MicroDAGR Zeige MicroDAGR Mostrar MicroDAGR Показать MicroDAGR @@ -365,8 +368,8 @@ Mostra MicroDAGR Mostrar MicroDAGR MicoDAGR を表示 - MicroDAGR 꺼내기 - 显示微型军用GPS接收器 + 마이크로DAGR 꺼내기 + 显示微型军用 GPS 接收器 顯示微型軍用GPS接收器 @@ -378,11 +381,11 @@ Otwórz MicroDAGR Configurer MicroDAGR MicroDAGR konfigurálása - ConfiguraMicroDAGR + Configura MicroDAGR Configurar MicroDAGR MicroDAGR を設定 - MicroDAGR 설정하기 - 设定微型军用GPS接收器 + 마이크로DAGR 설정하기 + 设定微型军用 GPS 接收器 設定微型軍用GPS接收器 @@ -397,8 +400,8 @@ Chiudi MicroDAGR Fechar MicroDAGR MicroDAGR を閉じる - MicroDAGR 집어넣기 - 关闭微型军用GPS接收器 + 마이크로DAGR 집어넣기 + 关闭微型军用 GPS 接收器 關閉微型軍用GPS接收器 @@ -413,8 +416,8 @@ Заполнение карты MicroDAGR Riempimento Mappa MicroDAGR MicroDAGR での地図情報 - MicroDAGR - 지도채우기 - 微型军用GPS接收器地图资料 + 마이크로DAGR - 지도채우기 + 微型军用 GPS 接收器地图资料 微型軍用GPS接收器地圖資料 @@ -424,13 +427,13 @@ MicroDAGR - Vyplnění mapy MicroDAGR-Kartenfüllung Preenchimento de mapa do MicroDAGR - MicroDAGR - Remplissage de la carte + Contenu de la carte MicroDAGR térképkitöltés Заполнение карты MicroDAGR Riempimento Mappa MicroDAGR MicroDAGR での地図情報 - MicroDAGR - 지도채우기 - 微型军用GPS接收器地图资料 + 마이크로DAGR - 지도채우기 + 微型军用 GPS 接收器地图资料 微型軍用GPS接收器地圖資料 @@ -440,13 +443,13 @@ Wie viel Daten auf einem MicroDAGR zu sehen sind Kolik informací je načteno do MicroDAGR? Quanta informação é preenchida no mapa do MicroDAGR - Combien d'informations apparaissent sur la carte du MicroDAGR + Définit le type d'information à afficher sur la carte du MicroDAGR. Mennyi térképadatot tartalmaz a MicroDAGR Сколько данных должно отображаться на карте MicroDAGR - Quanti dati sono trasferiti nella mappa del MicroDAGR - MicroDAGR で表示する地図情報を決定します - 얼마나 많은 데이터가 MicroDAGR에 있는지에 대한 정보 - 有多少地图数据会显示在微型军用GPS接收器 + Quanti dati cartografici sono mostrati sulla mappa del MicroDAGR + MicroDAGR で表示される地図の情報量 + 얼마나 많은 데이터를 마이크로DAGR가 보여주는지를 결정합니다 + 有多少地图数据会显示在微型军用 GPS 接收器 有多少地圖數據會顯示在微型軍用GPS接收器 @@ -456,10 +459,10 @@ Satellitenbild + Gebäude Satelit + Budovy Satélite completo + Edifícios - Satellite + Batiments + Image satellite + Bâtiments Teljes műholdas + épületek Спутник + Здания - Satellite Completo + Edifici + Satellitare Completo + Edifici 完全な衛星画像と建物 위성 사진 + 건물 完整卫星画面 + 建筑物位置 @@ -488,13 +491,13 @@ Keine (kann keine Kartenansicht verwenden) Žádný (Nelze použít zobrazení mapy) Nada (Não pode usar a tela de mapa) - Rien (La vue carte n'est pas possible) + Néant (carte désactivée) Semmi (nem használható a térképnézet) Не показывать (запрещает использовать режим карты) - Nessuno (Non puoi usare la vista mappa) - なし(地図表示を使えません) + Nessuno (Non puoi usare la visuale mappa) + なし (地図表示を使えません) 없음 (지도를 볼 수 없음) - 无 (无法检视地图) + 无(无法检视地图) 無 (無法檢視地圖) @@ -504,14 +507,28 @@ MicroDAGR - ウェイポイントの精度 MicroDAGR - Precyzja PT MicroDAGR - Точность маршрутных точек + MicroDAGR - Precisão de Waypoint + Précision des points de passage + 微型軍用GPS接收器 - 導航精確度 + 微型军用 GPS 接收器—航点精度 + MicroDAGR - přesnost Waypointů + Micro DAGR - precisión del waypoint + 마이크로DAGR - 경유지 정확도 Controls how precise the waypointdistance can be displayed Legt die Genauigkeit der Entfernung von Wegpunkten fest - Controlla quanto precisamente può essere visualizzato il waypoint a distanza - 表示されるウェイポイントの精度を設定します + Controlla quanto è precisa la distanza indicata dal waypoint + ウェイポイント距離の表示精度を制御します。 Kontroluje jak precyzyjnie może być wyświetlany dystans PT Управляет точностью отображения расстояний маршрутных точек + Controla o quão preciso pode exibir o waypoint de distância + Définit la précision d'affichage des points de passage. + 控制顯示的導航點精確度為多少 + 控制显示航点距离的精确程度。 + Nastavuje jak přesně je vzdálenost waypointů zobrazena. + Controla cómo de precisa se mostrará la distancia al waypoint + 경유지 거리가 얼마나 정확하게 표시되는지를 결정합니다 100m @@ -520,6 +537,14 @@ 100m 100m 100 м + 100m + 100 m + 一百公尺 + 100米 + 100 m + 100m + 100m + 100m 10m @@ -528,6 +553,14 @@ 10m 10m 10 м + 10m + 10 m + 十公尺 + 10米 + 10 m + 10m + 10m + 10m 1m @@ -536,6 +569,14 @@ 1m 1m 1 м + 1m + 1 m + 一公尺 + 1米 + 1 m + 1m + 1m + 1m Controls how much data is filled on the microDAGR items. Less data restricts the map view to show less on the minimap. @@ -544,14 +585,38 @@ Steuert wie viel Daten auf dem microDAGR zu sehen ist. Weniger Daten schränken die Kartenansicht ein, um mehr auf der Minimap zu sehen. Tento modul umožňuje kontrolovat, kolik informací je obsaženo v MicroDAGR. Menší množství dat omezené zobrazením mapy ukazují méně věcí na minimapě. Controla quantos dados são preenchidos nos itens microDAGR. Menos dados restringe a visualização de mapa para mostrar menos informações no minimapa. - Contrôle le nombre d'informations disponibles sur la carte du MicroDAGR. + Définit la quantité de données présentes dans le MicroDAGR.\nMoins de données force la carte à afficher moins d'informations sur la minimap. Meghatárroza a MicroDAGR objektumok térképének tartalmát. A kevesebb adat korlátozza a térképnézeti módot az eszközön. Контролирует, сколько данных должно отображаться на карте устройств MicroDAGR. Ограничивает объем отображаемых данных на миникарте. - Controlla quanti dati sono presenti negli oggetti MicroDAGR. Meno dati costringono la vista mappa a mostrare meno informazioni nella minimappa. - アイテム上で表示されるデータ量を決定します。設定を減らすと地図上での情報が少なくなります。 - MicroDAGR에 얼마나 많은 데이터가 들어있는지 정합니다. 적을 수록 지도상에도 비춰지는게 적어집니다. - 设定有多少数据会显示在微型军用GPS接收器上。这些资料的多寡会反映在迷你地图的显示上。 + Controlla quanti dati cartografici vengono caricati sui MicroDAGR. Meno dati permetteranno la visualizzazione di meno informazioni sulla minimappa. + microDAGRの項目に入力されるデータの量を制御します。データを少なくすると、マップビューが制限され、ミニマップの表示量が少なくなります。 + 마이크로DAGR에 얼마나 많은 데이터가 들어있는지 정합니다. 적을 수록 지도상에도 비춰지는게 적어집니다. + 设定有多少数据会显示在微型军用 GPS 接收器上。这些资料的多寡会反映在迷你地图的显示上。 設定有多少數據會顯示在微型軍用GPS接收器上。這些資料的多寡會反映在迷你地圖的顯示上。 + + MicroDAGR - Previous Mode + MicroDAGR - Предыдущий режим + MicroDAGR - Modo anterior + MicroDAGR - Mode précédent + MicroDAGR - 前のモードに + MicroDAGR - vorheriger Modus + MicroDAGR - Modalità Precedente + MicroDAGR - Poprzedni Tryb + 微型 GPS 接收器—上一个模式 + 마이크로DAGR - 이전 모드 + + + MicroDAGR - Next Mode + MicroDAGR - Следующий режим + MicroDAGR - Modo siguiente + MicroDAGR - Mode suivant + MicroDAGR - 次のモードに + MicroDAGR - nächster Modus + MicroDAGR - Modalità Successiva + MicroDAGR - Kolejny Tryb + 微型 GPS 接收器—下一个模式 + 마이크로DAGR - 다음 모드 + diff --git a/addons/minedetector/CfgEventHandlers.hpp b/addons/minedetector/CfgEventHandlers.hpp index e90bed419e..2a3f71f852 100644 --- a/addons/minedetector/CfgEventHandlers.hpp +++ b/addons/minedetector/CfgEventHandlers.hpp @@ -1,15 +1,15 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/minedetector/CfgVehicles.hpp b/addons/minedetector/CfgVehicles.hpp index ab6c06b4cb..874fc597f5 100644 --- a/addons/minedetector/CfgVehicles.hpp +++ b/addons/minedetector/CfgVehicles.hpp @@ -34,14 +34,14 @@ class CfgVehicles { class GVAR(connectHeadphones) { displayName = CSTRING(ConnectHeadphones); condition = QUOTE(call FUNC(canConnectHeadphones)); - statement = QUOTE([ARR_2(ACE_player, true)] call FUNC(connectHeadphones)); + statement = QUOTE([ARR_2(ACE_player,true)] call FUNC(connectHeadphones)); icon = ""; //TODO exceptions[] = {}; }; class GVAR(disconnectHeadphones) { displayName = CSTRING(DisconnectHeadphones); condition = QUOTE(call FUNC(canDisconnectHeadphones)); - statement = QUOTE([ARR_2(ACE_player, false)] call FUNC(connectHeadphones)); + statement = QUOTE([ARR_2(ACE_player,false)] call FUNC(connectHeadphones)); icon = ""; //TODO exceptions[] = {}; }; diff --git a/addons/minedetector/README.md b/addons/minedetector/README.md index 5de7970013..e4607a92c8 100644 --- a/addons/minedetector/README.md +++ b/addons/minedetector/README.md @@ -3,9 +3,3 @@ ace_minedetector Add mine detectors -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Glowbal](https://github.com/Glowbal) -- [Grey](https://github.com/Grey-Soldierman) diff --git a/addons/minedetector/XEH_postInit.sqf b/addons/minedetector/XEH_postInit.sqf index 1c448794cc..f5f5de0ca8 100644 --- a/addons/minedetector/XEH_postInit.sqf +++ b/addons/minedetector/XEH_postInit.sqf @@ -1,19 +1,10 @@ #include "script_component.hpp" // Create a dictionary to store detector configs -GVAR(detectorConfigs) = call CBA_fnc_createNamespace; +GVAR(detectorConfigs) = createHashMap; -// Create a dictionary of detectable classnames -GVAR(detectableClasses) = call CBA_fnc_createNamespace; - -private _detectableClasses = call (uiNamespace getVariable [QGVAR(detectableClasses), {[]}]); //See XEH_preStart.sqf -{ - GVAR(detectableClasses) setVariable [_x, true]; -} forEach _detectableClasses; -TRACE_1("built cache",count allVariables GVAR(detectableClasses)); - -[QGVAR(enableDetector), FUNC(enableDetector)] call CBA_fnc_addEventHandler; -[QGVAR(disableDetector), FUNC(disableDetector)] call CBA_fnc_addEventHandler; +[QGVAR(enableDetector), LINKFUNC(enableDetector)] call CBA_fnc_addEventHandler; +[QGVAR(disableDetector), LINKFUNC(disableDetector)] call CBA_fnc_addEventHandler; // Shows detector and mine posistions in 3d when debug is on #ifdef DEBUG_MODE_FULL @@ -24,7 +15,7 @@ addMissionEventHandler ["Draw3D", { drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [0,0,1,1], _detectorPointAGL, 1, 1, 0, "detector", 1, 0.02, "PuristaMedium"]; { private _name = format ["%1@%2", typeOf _x, (floor ((_x distance _detectorPointAGL) * 10)) / 10]; - if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _x) >> QGVAR(detectable))) == 1) then { + if ((getNumber (configOf _x >> QGVAR(detectable))) == 1) then { drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [1,0,0,1], (ASLtoAGL (getPosASL _x)), 1, 1, 0, _name, 1, 0.02, "PuristaMedium"]; } else { drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [1,1,0,1], (ASLtoAGL (getPosASL _x)), 1, 1, 0, _name, 1, 0.02, "PuristaMedium"]; diff --git a/addons/minedetector/XEH_preStart.sqf b/addons/minedetector/XEH_preStart.sqf index 48f003d08e..046c037364 100644 --- a/addons/minedetector/XEH_preStart.sqf +++ b/addons/minedetector/XEH_preStart.sqf @@ -15,5 +15,5 @@ private _detectableClasses = []; }; } forEach (configProperties [configFile >> "CfgAmmo", "isClass _x", true]); -TRACE_1("compiled",count _detectableClasses); -uiNamespace setVariable [QGVAR(detectableClasses), compileFinal str _detectableClasses]; +TRACE_1("built cache",count _detectableClasses); +uiNamespace setVariable [QGVAR(detectableClasses), compileFinal (_detectableClasses createHashMapFromArray [])]; diff --git a/addons/minedetector/functions/fnc_activateDetector.sqf b/addons/minedetector/functions/fnc_activateDetector.sqf index 5ce236250b..7899899d4b 100644 --- a/addons/minedetector/functions/fnc_activateDetector.sqf +++ b/addons/minedetector/functions/fnc_activateDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Activate the mine detector diff --git a/addons/minedetector/functions/fnc_canActivateDetector.sqf b/addons/minedetector/functions/fnc_canActivateDetector.sqf index 8a5d795b49..7b1de093e9 100644 --- a/addons/minedetector/functions/fnc_canActivateDetector.sqf +++ b/addons/minedetector/functions/fnc_canActivateDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if the mine detector can be activated diff --git a/addons/minedetector/functions/fnc_canConnectHeadphones.sqf b/addons/minedetector/functions/fnc_canConnectHeadphones.sqf index 4266f6e065..cc83271d03 100644 --- a/addons/minedetector/functions/fnc_canConnectHeadphones.sqf +++ b/addons/minedetector/functions/fnc_canConnectHeadphones.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Check if headphones can be connected to the mine detector diff --git a/addons/minedetector/functions/fnc_canDeactivateDetector.sqf b/addons/minedetector/functions/fnc_canDeactivateDetector.sqf index 8c38363288..06eeab62e1 100644 --- a/addons/minedetector/functions/fnc_canDeactivateDetector.sqf +++ b/addons/minedetector/functions/fnc_canDeactivateDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if the mine detector can be deactivated diff --git a/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf b/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf index b55338b641..733d1a9ff2 100644 --- a/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf +++ b/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Check if headphones can be disconnected from the mine detector diff --git a/addons/minedetector/functions/fnc_connectHeadphones.sqf b/addons/minedetector/functions/fnc_connectHeadphones.sqf index 3bf76a4d23..88b6b29846 100644 --- a/addons/minedetector/functions/fnc_connectHeadphones.sqf +++ b/addons/minedetector/functions/fnc_connectHeadphones.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Connect/disconnect headphones to the mine detector diff --git a/addons/minedetector/functions/fnc_deactivateDetector.sqf b/addons/minedetector/functions/fnc_deactivateDetector.sqf index 7ed0713846..7403250ad6 100644 --- a/addons/minedetector/functions/fnc_deactivateDetector.sqf +++ b/addons/minedetector/functions/fnc_deactivateDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Deactivate the mine detector diff --git a/addons/minedetector/functions/fnc_detectorLoop.sqf b/addons/minedetector/functions/fnc_detectorLoop.sqf index 3895ab8193..1ede6c7422 100644 --- a/addons/minedetector/functions/fnc_detectorLoop.sqf +++ b/addons/minedetector/functions/fnc_detectorLoop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Handle mine detection in a PFH loop diff --git a/addons/minedetector/functions/fnc_disableDetector.sqf b/addons/minedetector/functions/fnc_disableDetector.sqf index be0c57117d..33106b4c45 100644 --- a/addons/minedetector/functions/fnc_disableDetector.sqf +++ b/addons/minedetector/functions/fnc_disableDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Disables the mine detector diff --git a/addons/minedetector/functions/fnc_enableDetector.sqf b/addons/minedetector/functions/fnc_enableDetector.sqf index 2bb663d977..55b58dcf3a 100644 --- a/addons/minedetector/functions/fnc_enableDetector.sqf +++ b/addons/minedetector/functions/fnc_enableDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Enables the mine detector @@ -31,4 +31,4 @@ if (_unit == ACE_player) then { [QGVAR(detectorEnabled), [_unit, _detectorType]] call CBA_fnc_localEvent; private _config = [_detectorType] call FUNC(getDetectorConfig); -[FUNC(detectorLoop), 0.05, [_unit, _detectorType, _config, CBA_missionTime - 0.25]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(detectorLoop), 0.05, [_unit, _detectorType, _config, CBA_missionTime - 0.25]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 9bcfcf2cc7..7811b3eaaa 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Get the distance to the nearest detectable object @@ -38,18 +38,16 @@ private _mine = objNull; private _distance = -1; { - private _objectType = typeOf _x; - - _isDetectable = GVAR(detectableClasses) getVariable _objectType; - if (isNil "_isDetectable" || {(getModelInfo _x) select 0 == "empty.p3d"}) then { - _isDetectable = false; + if ((getModelInfo _x) select 0 == "empty.p3d") then { + continue; }; - // If a nun-null object was detected exit the search - if (_isDetectable && {!isNull _x}) exitWith { + // If an object was detected, exit the search + if ((typeOf _x) in (uiNamespace getVariable QGVAR(detectableClasses))) exitWith { + _isDetectable = true; _distance = _detectorPointAGL distance _x; _mine = _x; - TRACE_3("return", _isDetectable, _mine, _distance); + TRACE_3("return",_isDetectable,_mine,_distance); }; } forEach _nearestObjects; diff --git a/addons/minedetector/functions/fnc_getDetectorConfig.sqf b/addons/minedetector/functions/fnc_getDetectorConfig.sqf index 313cc30142..a5566cbfbf 100644 --- a/addons/minedetector/functions/fnc_getDetectorConfig.sqf +++ b/addons/minedetector/functions/fnc_getDetectorConfig.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Get the mine detector configuration from the cache or config file @@ -19,18 +19,15 @@ params ["_detectorType"]; if (_detectorType isEqualTo "") exitWith {[]}; -private _detectorConfig = GVAR(detectorConfigs) getVariable _detectorType; -if (isNil "_detectorConfig") then { +GVAR(detectorConfigs) getOrDefaultCall [_detectorType, { private _cfgEntry = (configFile >> "ACE_detector" >> "detectors" >> _detectorType); if (isClass _cfgEntry) then { - _detectorConfig = [ + [ _detectorType, getNumber (_cfgEntry >> "radius"), getArray (_cfgEntry >> "sounds") ]; } else { - _detectorConfig = []; + [] }; - GVAR(detectorConfigs) setVariable [_detectorType, _detectorConfig]; -}; -_detectorConfig +}, true] diff --git a/addons/minedetector/functions/fnc_hasDetector.sqf b/addons/minedetector/functions/fnc_hasDetector.sqf index 4752284196..05ac7e412e 100644 --- a/addons/minedetector/functions/fnc_hasDetector.sqf +++ b/addons/minedetector/functions/fnc_hasDetector.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if unit has a mine detector in hands @@ -17,4 +17,4 @@ params ["_unit"]; -!(([currentWeapon _unit] call FUNC(getDetectorConfig)) isEqualTo []); +([currentWeapon _unit] call FUNC(getDetectorConfig)) isNotEqualTo []; diff --git a/addons/minedetector/functions/fnc_isDetectorEnabled.sqf b/addons/minedetector/functions/fnc_isDetectorEnabled.sqf index 95ff89fa65..6b94e4bc11 100644 --- a/addons/minedetector/functions/fnc_isDetectorEnabled.sqf +++ b/addons/minedetector/functions/fnc_isDetectorEnabled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if the mine detector is enabled @@ -10,7 +10,7 @@ * None * * Example: - * ["example"] call ace_minedetector_fnc_[functionName] + * ["example"] call ace_minedetector_fnc_isDetectorEnabled * * Public: No */ diff --git a/addons/minedetector/functions/fnc_playDetectorSound.sqf b/addons/minedetector/functions/fnc_playDetectorSound.sqf index 8e47508209..cfd5dc3822 100644 --- a/addons/minedetector/functions/fnc_playDetectorSound.sqf +++ b/addons/minedetector/functions/fnc_playDetectorSound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Play the detector sound @@ -28,6 +28,6 @@ if (!alive _unit) exitWith { if (_unit getVariable [QGVAR(isUsingHeadphones), false] && {_unit == ACE_player}) then { playSound _soundClass; } else { - private _posASL = AGLtoASL (_unit modelToWorld (_unit selectionPosition "granat")); + private _posASL = _unit modelToWorldWorld (_unit selectionPosition "granat"); [_soundClass, _posASL, 3, 15] call EFUNC(common,playConfigSound3D); }; diff --git a/addons/minedetector/functions/script_component.hpp b/addons/minedetector/functions/script_component.hpp deleted file mode 100644 index 03333c8bae..0000000000 --- a/addons/minedetector/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\minedetector\script_component.hpp" diff --git a/addons/minedetector/sounds/metal_detector.wav b/addons/minedetector/sounds/metal_detector.wav index 59f3b43ebe..f07e128061 100644 Binary files a/addons/minedetector/sounds/metal_detector.wav and b/addons/minedetector/sounds/metal_detector.wav differ diff --git a/addons/minedetector/sounds/metal_detector.wss b/addons/minedetector/sounds/metal_detector.wss index 3ba5d3b7e3..4fe2135cb1 100644 Binary files a/addons/minedetector/sounds/metal_detector.wss and b/addons/minedetector/sounds/metal_detector.wss differ diff --git a/addons/minedetector/stringtable.xml b/addons/minedetector/stringtable.xml index 72f389813f..95fab779dd 100644 --- a/addons/minedetector/stringtable.xml +++ b/addons/minedetector/stringtable.xml @@ -6,26 +6,32 @@ Détecteur de métaux Детектор металла Detektor kovů - 地雷探知機 + 金属探知機 Wykrywacz metali Metalldetektor 지뢰탐지기 Metal detector 金属探测器 金屬探測器 + Detector de Metais + Detector de metales + Metal Dedektör Metal detector Détecteur de métaux Детектор металла Detektor kovů - 地雷探知機 + 金属探知機 Wykrywacz metali Metalldetektor 지뢰탐지기 Metal detector 金属探测器 金屬探測器 + Detector de Metais + Detector de metales + Metal Dedektör Activate @@ -39,6 +45,9 @@ Attiva 启用探测器 啟用探測器 + Ativar + Activar + Aktif Deactivate @@ -52,12 +61,15 @@ Disattiva 停用探测器 停用探測器 + Desativar + Desactivar + Aktif Değil Connect Headphones Подключить наушники Připojit sluchátka - ヘッドホンへつなぐ + ヘッドホンに接続 Podłącz słuchawki Kopfhörer verbinden 헤드폰에 연결 @@ -65,19 +77,25 @@ Connetti Auricolari 连接耳机 連接耳機 + Conectar fones de ouvido + Conectar auriculares + Kulaklığını Bağla Disconnect Headphones Отключить наушники Odpojit sluchátka - ヘッドホンからはずす + ヘッドホンを切断 Odłącz słuchawki Kopfhörer trennen - 헤드폰 연결끊기 + 헤드폰 연결 끊기 Déconnecter les écouteurs Disconnetti Auricolari 断开耳机 斷開耳機 + Desconectar fones de ouvido + Desconectar auriculares + Kulaklığının Bağlantısını Kes Headphones Connected @@ -91,19 +109,25 @@ Auricolari Connessi 已连接耳机 已連接耳機 + Fones de ouvido conectados + Auriculares conectados + Kulaklık Bağlandı Headphones Disconnected Наушники отключены Sluchátka odpojena - ヘッドホンから外しました + ヘッドホンを切断しました Słuchawki odpięte Kopfhörer getrennt - 헤드폰 연결끊김 + 헤드폰 연결 끊김 Écouteurs déconnectés Auricolari Disconnessi 已断开耳机 已斷開耳機 + Fones de ouvido conectados + Auriculares desconectados + Kulaklık Çıkartıldı diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index f202e7d161..3628c9eec0 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -41,6 +41,22 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_JAV_TOP); }; + class WIRE { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(attackProfile_WIRE); + onFired = QFUNC(wire_onFired); + }; + class BEAM { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(attackProfile_BEAM); + onFired = QFUNC(wire_onFired); // since Beam guidance is pretty much the same as Wire guidance, we can reuse this + }; }; class GVAR(SeekerTypes) { @@ -58,4 +74,20 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_Optic); }; + class SACLOS { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(seekerType_SACLOS); + onFired = QFUNC(SACLOS_onFired); + }; + class ARH { + name = ""; + visualName = ""; + description = ""; + + functionName = QFUNC(seekerType_ARH); + onFired = QFUNC(ahr_onFired); + }; }; diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index d2d5c1ecf0..a2b07b7fff 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -63,7 +63,7 @@ class CfgAmmo { //trackOversteer = 1; //trackLead = 0; - initTime = 2; + initTime = 0.5; // Begin ACE guidance Configs class ADDON { diff --git a/addons/missileguidance/CfgEventhandlers.hpp b/addons/missileguidance/CfgEventhandlers.hpp index 7fba1f43c4..a288a93399 100644 --- a/addons/missileguidance/CfgEventhandlers.hpp +++ b/addons/missileguidance/CfgEventhandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_pre_init)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_post_init)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/missileguidance/CfgMagazines.hpp b/addons/missileguidance/CfgMagazines.hpp index 7cc33b17a3..74d75e8d4a 100644 --- a/addons/missileguidance/CfgMagazines.hpp +++ b/addons/missileguidance/CfgMagazines.hpp @@ -1,7 +1,7 @@ class CfgMagazines { class 12Rnd_PG_missiles; - class 6Rnd_ACE_Hydra70_DAGR : 12Rnd_PG_missiles { + class 6Rnd_ACE_Hydra70_DAGR: 12Rnd_PG_missiles { ammo = "ACE_Hydra70_DAGR"; count = 12; displayName = "6 Round DAGR"; @@ -10,14 +10,14 @@ class CfgMagazines { weight = 36; }; - class 12Rnd_ACE_Hydra70_DAGR : 6Rnd_ACE_Hydra70_DAGR { + class 12Rnd_ACE_Hydra70_DAGR: 6Rnd_ACE_Hydra70_DAGR { count = 12; displayName = "16 Round DAGR"; displayNameShort = "16 Round DAGR"; descriptionShort = "16 Round DAGR"; weight = 72; }; - class 24Rnd_ACE_Hydra70_DAGR : 6Rnd_ACE_Hydra70_DAGR { + class 24Rnd_ACE_Hydra70_DAGR: 6Rnd_ACE_Hydra70_DAGR { count = 24; displayName = "24 Round DAGR"; displayNameShort = "24 Round DAGR"; diff --git a/addons/missileguidance/README.md b/addons/missileguidance/README.md index bb8047bdf2..b21a5c2408 100644 --- a/addons/missileguidance/README.md +++ b/addons/missileguidance/README.md @@ -2,11 +2,3 @@ ace_missileguidance =================== Various new modes for different missiles. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [walterpearce](https://github.com/walterpearce) -- [NouberNou](https://github.com/NouberNou) diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index ee2b7328cb..075f2f03c5 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -10,7 +10,7 @@ PREP(onFired); PREP(onIncomingMissile); PREP(guidancePFH); -PREP(doAttackProfile); +PREP(doAttackProfile); PREP(doSeekerSearch); PREP(doHandoff); @@ -22,6 +22,8 @@ PREP(attackProfile_DIR); PREP(attackProfile_HI); PREP(attackProfile_LIN); PREP(attackProfile_MID); +PREP(attackProfile_WIRE); +PREP(attackProfile_BEAM); // Javelin profiles PREP(attackProfile_JAV_DIR); @@ -30,3 +32,12 @@ PREP(attackProfile_JAV_TOP); // Seeker search functions PREP(seekerType_SALH); PREP(seekerType_Optic); +PREP(seekerType_SACLOS); +PREP(seekerType_ARH); + +// Attack Profiles OnFired +PREP(wire_onFired); + +// Seeker OnFired +PREP(SACLOS_onFired); +PREP(ahr_onFired); diff --git a/addons/missileguidance/XEH_postInit.sqf b/addons/missileguidance/XEH_postInit.sqf new file mode 100644 index 0000000000..eb0fb60abf --- /dev/null +++ b/addons/missileguidance/XEH_postInit.sqf @@ -0,0 +1,13 @@ +#include "script_component.hpp" + +[QGVAR(handoff), LINKFUNC(handleHandoff)] call CBA_fnc_addEventHandler; + +["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), +{ + [] call FUNC(cycleAttackProfileKeyDown); + false +}, +{ + false +}, +[15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key diff --git a/addons/missileguidance/XEH_post_init.sqf b/addons/missileguidance/XEH_post_init.sqf deleted file mode 100644 index cc09b1f0ac..0000000000 --- a/addons/missileguidance/XEH_post_init.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -[QGVAR(handoff), {_this call FUNC(handleHandoff)}] call CBA_fnc_addEventHandler; - -["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), -{ - [] call FUNC(cycleAttackProfileKeyDown); - false -}, -{ - false -}, -[15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key diff --git a/addons/missileguidance/XEH_preInit.sqf b/addons/missileguidance/XEH_preInit.sqf new file mode 100644 index 0000000000..0798fed2e4 --- /dev/null +++ b/addons/missileguidance/XEH_preInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +// Formally a ace_setting, users can still disable by `setting ace_missileguidance_enabled = x;` +// [0 - Off , 1 - PlayerOnly, 2 - PlayerAndAi] +// As weapons take config changes, there is little point in being able to disable guidance +if (isNil QGVAR(enabled)) then { GVAR(enabled) = 2; }; + +ADDON = true; diff --git a/addons/missileguidance/XEH_pre_init.sqf b/addons/missileguidance/XEH_pre_init.sqf deleted file mode 100644 index f377efddb6..0000000000 --- a/addons/missileguidance/XEH_pre_init.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -PREP_RECOMPILE_START; -#include "XEH_PREP.hpp" -PREP_RECOMPILE_END; - -// Formally a ace_setting, users can still disable by `setting ace_missileguidance_enabled = x;` -// [0 - Off , 1 - PlayerOnly, 2 - PlayerAndAi] -// As weapons take config changes, there is little point in being able to disable guidance -if (isNil QGVAR(enabled)) then { GVAR(enabled) = 2; }; - -ADDON = true; diff --git a/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf new file mode 100644 index 0000000000..299ec6f236 --- /dev/null +++ b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up SACLOS state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_SACLOS_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile"]; +_stateParams params ["", "_seekerStateParams"]; + +private _usePilotCamera = getNumber (configOf _shooter >> "pilotCamera" >> QGVAR(usePilotCameraForTargeting)) == 1; + +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, _usePilotCamera || { (_shooter isKindOf "Plane") && hasPilotCamera _shooter }]; + +if ((_shooter isKindOf "Plane") && !hasPilotCamera _shooter) then { WARNING("SACLOS fired from planes without pilot camera unsupported!"); }; + diff --git a/addons/missileguidance/functions/fnc_ahr_onFired.sqf b/addons/missileguidance/functions/fnc_ahr_onFired.sqf new file mode 100644 index 0000000000..0618c046ad --- /dev/null +++ b/addons/missileguidance/functions/fnc_ahr_onFired.sqf @@ -0,0 +1,73 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up Active Radar state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_ahr_onFired + * + * Public: No + */ +params ["_firedEH", "_launchParams", "", "", "_stateParams"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_stateParams params ["", "_seekerStateParams"]; +_launchParams params ["","_targetLaunchParams"]; +_targetLaunchParams params ["_target"]; + +_target = missileTarget _projectile; +if (isNull _target && isVehicleRadarOn vehicle _shooter) then { + _target = cursorTarget; +}; +if !(_target isKindOf "AllVehicles") then { + _target = nil; +}; +_launchParams set [0, _target]; +_projectile setMissileTarget objNull; // to emulate a no launch warning + +private _projectileConfig = configOf _projectile; +private _config = _projectileConfig >> "ace_missileguidance"; + +private _isActive = false; +private _activeRadarDistance = [_config >> "activeRadarEngageDistance", "NUMBER", 500] call CBA_fnc_getConfigEntry; +private _projectileThrust = [_projectileConfig >> "thrust", "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _projectileThrustTime = [_projectileConfig >> "thrustTime", "NUMBER", 0] call CBA_fnc_getConfigEntry; + +private _velocityAtImpact = _projectileThrust * _projectileThrustTime; +private _timeToActive = 0; +if (!isNil "_target" && _velocityAtImpact > 0) then { + private _distanceUntilActive = (((getPosASL _shooter) vectorDistance (getPosASL _target)) - _activeRadarDistance); + _timeToActive = 0 max (_distanceUntilActive / _velocityAtImpact); +}; + +if (isNil "_target") then { + _timeToActive = 0; + _isActive = true; + _target = objNull; +}; + +private _shooterHasActiveRadar = { + if ("ActiveRadarSensorComponent" in _x) exitWith { true }; + false +} forEach listVehicleSensors vehicle _shooter; + +if !(isVehicleRadarOn vehicle _shooter) then { + _isActive = true; +}; + +_seekerStateParams set [0, _isActive]; +_seekerStateParams set [1, _activeRadarDistance]; +_seekerStateParams set [2, CBA_missionTime + _timeToActive]; +_seekerStateParams set [3, getPosASL _target]; +_seekerStateParams set [4, CBA_missionTime]; +_seekerStateParams set [5, _shooterHasActiveRadar]; +_seekerStateParams set [6, false]; +_seekerStateParams set [7, [0, 0, 0]]; +_seekerStateParams set [8, CBA_missionTime]; +_seekerStateParams set [9, isNull _target]; + diff --git a/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf index 823e85efaa..e1675bc1bb 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: AIR diff --git a/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf new file mode 100644 index 0000000000..5aaff9d7f8 --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Attack profile: Beam guided. Exact same as wire-guided, except no wire cutting + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_BEAM; + * + * Public: No + */ +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; + +private _projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; + +private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos); +private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos; + +if (_distanceToProjectile > _seekerMaxRangeSqr || { _seekerTargetPos isEqualTo [0, 0, 0] } || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith { + // return position 50m infront of projectile + _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) +}; + +private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); +_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; + +private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; +private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair + +// Adjust the impulse due to near-zero values creating wobbly missiles? +private _correction = _fovImpulse; + + +_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; +private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); +_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) diff --git a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf index cddd70807e..80499a85da 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: DIR diff --git a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf b/addons/missileguidance/functions/fnc_attackProfile_HI.sqf index 6f1fbe67d3..92413f59d0 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_HI.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: HI diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf index f277c1bc68..b690ab2075 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: Javelin Dir @@ -39,7 +39,7 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; @@ -69,5 +69,5 @@ switch (_attackProfileStateParams select 0) do { }; }; -TRACE_1("Adjusted target position", _returnTargetPos); +TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf index 08219ea24a..f1f360e403 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: Javelin Top @@ -39,7 +39,7 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; @@ -58,7 +58,7 @@ switch( (_attackProfileStateParams select 0) ) do { private _cruisAlt = 140; if (_distanceShooterToTarget < 1250) then { _cruisAlt = 140 * (_distanceShooterToTarget/1250); - TRACE_1("_cruisAlt", _cruisAlt); + TRACE_1("_cruisAlt",_cruisAlt); }; if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { if (_cruisAlt < 140) then { @@ -72,7 +72,7 @@ switch( (_attackProfileStateParams select 0) ) do { }; case STAGE_COAST: { TRACE_1("STAGE_COAST",""); - TRACE_1("", ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ); + TRACE_1("",((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2)); if (_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 2) then { _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { @@ -86,5 +86,5 @@ switch( (_attackProfileStateParams select 0) ) do { }; }; -TRACE_1("Adjusted target position", _returnTargetPos); +TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index 464ee9e36b..e346b16eb6 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: Linear (used by DAGR) @@ -30,7 +30,7 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _addHeight = [0,0,0]; diff --git a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf b/addons/missileguidance/functions/fnc_attackProfile_MID.sqf index f66088844c..2ca9eef77f 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_MID.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Attack profile: MID diff --git a/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf new file mode 100644 index 0000000000..443fe1bb97 --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf @@ -0,0 +1,63 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Attack profile: Wire guided + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_WIRE; + * + * Public: No + */ +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; + +private _projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; + +private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos); +private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos; + +if ((_distanceToProjectile > _seekerMaxRangeSqr) || { _wireCut }) exitWith { + // wire snap, random direction + if (_randomVector isEqualTo [0, 0, 0]) then { + _randomVector = RANDOM_VECTOR_3D vectorMultiply 300; + _attackProfileStateParams set [1, true]; + _attackProfileStateParams set [2, _randomVector]; + + playSound3D ["a3\sounds_f\air\sfx\SL_rope_break.wss", objNull, false, AGLtoASL (_shooter modelToWorld _wireCutSource), 5, 1, 150]; + }; + _projectilePos vectorAdd _randomVector +}; + +if (_seekerTargetPos isEqualTo [0, 0, 0] || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith { + // cut wire if its caught on terrain + /*if (lineIntersectsSurfaces [getPosASL _shooter, _projectilePos, _shooter] isNotEqualTo []) then { + _attackProfileStateParams set [1, true]; + };*/ + // return position 50m infront of projectile + _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) +}; + +private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); +_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; + +private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; +private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair + +// Adjust the impulse due to near-zero values creating wobbly missiles? +private _correction = _fovImpulse; + + +_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; +private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); +_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) diff --git a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf index d560f05e2a..21884c1693 100644 --- a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf +++ b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Change a projectile's direction, maintaing speed diff --git a/addons/missileguidance/functions/fnc_checkLos.sqf b/addons/missileguidance/functions/fnc_checkLos.sqf index edc8b5ab19..1fadc5510e 100644 --- a/addons/missileguidance/functions/fnc_checkLos.sqf +++ b/addons/missileguidance/functions/fnc_checkLos.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Returns whether the seeker object can see the target position with checkVisibility @@ -6,17 +6,41 @@ * Arguments: * 0: Seeker * 1: Target + * 2: Whether or not to use checkVisibility to test for LOS * * Return Value: * Has LOS * * Example: - * [player, cursorTarget] call ace_missileguidance_fnc_checkLOS; + * [player, cursorTarget] call ace_missileguidance_fnc_checkLos; * * Public: No */ -params ["_seeker", "_target"]; +params ["_seeker", "_target", ["_checkVisibilityTest", true]]; + +// Boolean checkVisibilityTest so that if the seeker type is one that ignores smoke we revert back to raw LOS checking. +if (_checkVisibilityTest) exitWith { + private _visibility = [_seeker, "VIEW", _target] checkVisibility [getPosASL _seeker, aimPos _target]; + _visibility > 0.001 +}; +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_checkSeekerAngle.sqf b/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf index d8b3b858b3..c69f6d20f0 100644 --- a/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf +++ b/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus * Returns whether the target position is within the maximum angle FOV of the provided seeker diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index adfd1b5e01..2263716724 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Cycles fire mode for any missileGuidance enabled ammo that has multiple attack profiles @@ -18,7 +18,7 @@ TRACE_1("cycle fire mode",_this); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; private _currentShooter = objNull; @@ -78,14 +78,13 @@ TRACE_4("",_currentFireMode,_nextFireMode,_index,_attackProfiles); private _currentFireMode = if (_useModeForAttackProfile) then { TRACE_2("setting fire mode",_weaponStateToken,_nextFireMode); - for "_weaponIndex" from 0 to 299 do { - ACE_player action ["SwitchWeapon", _currentShooter, ACE_player, _weaponIndex]; - (weaponState _weaponStateToken) params ["_xWeapon", "", "_xMode"]; + { + _x params ["_xIndex", "", "_xWeapon", "", "_xMode"]; if ((_xWeapon == _weapon) && {(getText (configFile >> "CfgWeapons" >> _weapon >> _xMode >> QGVAR(attackProfile))) == _nextFireMode}) exitWith { - TRACE_2("Restoring",_weaponIndex,weaponState _currentShooter); + ACE_player action ["SwitchWeapon", _currentShooter, ACE_player, _xIndex]; + TRACE_2("Restoring",weaponState _currentShooter,_x); }; - if ((weaponState _weaponStateToken) isEqualTo ["","","","",0]) exitWith {ERROR_2("weaponState not found",_weapon,_nextFireMode);}; - }; + } forEach (ACE_player weaponsInfo [_weapon, false]); } else { TRACE_2("setVariable attackProfile",_currentShooter,_nextFireMode); _currentShooter setVariable [QGVAR(attackProfile), _nextFireMode, false]; diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index 53d43883d3..cafbadf69c 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou, PabstMirror * Do attack profile with a valid seeker target location diff --git a/addons/missileguidance/functions/fnc_doHandoff.sqf b/addons/missileguidance/functions/fnc_doHandoff.sqf index 569a827173..153f38a3c4 100644 --- a/addons/missileguidance/functions/fnc_doHandoff.sqf +++ b/addons/missileguidance/functions/fnc_doHandoff.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE * Not currently used diff --git a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf index feb13481a5..6008725b4c 100644 --- a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf +++ b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou, PabstMirror * Do seeker search @@ -12,7 +12,7 @@ * Missile Aim PosASL * * Example: - * [[], [], []] call ace_missileguidance_fnc_seekerType_Optic; + * [[], [], []] call ace_missileguidance_fnc_doSeekerSearch; * * Public: No */ @@ -27,7 +27,7 @@ private _seekerFunction = getText (configFile >> QGVAR(SeekerTypes) >> _seekerTy private _seekerTargetPos = _this call (missionNamespace getVariable _seekerFunction); if ((isNil "_seekerTargetPos") || {_seekerTargetPos isEqualTo [0,0,0]}) then { // A return of nil or [0,0,0] indicates the seeker has no target - if (_seekLastTargetPos && {!(_lastKnownPos isEqualTo [0,0,0])}) then { // if enabled for the ammo, use last known position if we have one stored + if (_seekLastTargetPos && {_lastKnownPos isNotEqualTo [0,0,0]}) then { // if enabled for the ammo, use last known position if we have one stored TRACE_2("seeker returned bad pos - using last known",_seekLastTargetPos,_lastKnownPos); _seekerTargetPos = _lastKnownPos; #ifdef DRAW_GUIDANCE_INFO diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index e218e27e54..0620e9e3c0 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Guidance Per Frame Handler @@ -37,7 +37,7 @@ private _adjustTime = 1; if (accTime > 0) then { _adjustTime = 1/accTime; _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); - TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); + TRACE_4("Adjust timing",1/accTime,_adjustTime,_runtimeDelta,(_runtimeDelta / TIMESTEP_FACTOR)); } else { _adjustTime = 0; }; @@ -56,7 +56,7 @@ private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStat // If we have no seeker target, then do not change anything // 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 { +if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); @@ -89,8 +89,8 @@ if ((_minDeflection != 0 || {_maxDeflection != 0}) && {!(_profileAdjustedTargetP }; private _finalAdjustVector = [_yaw, _roll, _pitch]; - TRACE_3("", _pitch, _yaw, _roll); - TRACE_3("", _targetVector, _adjustVector, _finalAdjustVector); + TRACE_3("",_pitch,_yaw,_roll); + TRACE_3("",_targetVector,_adjustVector,_finalAdjustVector); if (accTime > 0) then { private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; diff --git a/addons/missileguidance/functions/fnc_handleHandoff.sqf b/addons/missileguidance/functions/fnc_handleHandoff.sqf index b4bb0052ae..785071da01 100644 --- a/addons/missileguidance/functions/fnc_handleHandoff.sqf +++ b/addons/missileguidance/functions/fnc_handleHandoff.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Not currently used @@ -19,4 +19,4 @@ params ["_target", "_args"]; if (isNil "_target" || {isNull _target} || {!local _target} ) exitWith { false }; -[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index b77911e979..1d63d120a9 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Fired event handler, starts guidance if enabled for ammo @@ -20,7 +20,7 @@ params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; // Bail on not missile -if (!(_ammo isKindOf "MissileBase")) exitWith {}; +if !(_ammo isKindOf "MissileBase") exitWith {}; // Bail if guidance is disabled for this ammo if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; @@ -71,14 +71,14 @@ if (isNil "_target") then { if (!isPlayer _shooter) then { // This was an AI shot, lets still guide it on the AI target _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!", _target); + TRACE_1("Detected AI Shooter!",_target); } else { private _canUseLock = getNumber (_config >> "canVanillaLock"); // @TODO: Get vanilla target if (_canUseLock > 0 || difficulty < 1) then { private _vanillaTarget = cursorTarget; - TRACE_1("Using Vanilla Locking", _vanillaTarget); + TRACE_1("Using Vanilla Locking",_vanillaTarget); if (!isNil "_vanillaTarget") then { _target = _vanillaTarget; }; @@ -123,29 +123,29 @@ 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"]; // _firedEH params ["_shooter","","","","_ammo","","_projectile"]; // _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; // _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; // _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; -// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; -[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; /* Clears locking settings diff --git a/addons/missileguidance/functions/fnc_onIncomingMissile.sqf b/addons/missileguidance/functions/fnc_onIncomingMissile.sqf index 04ad0c79b7..d49ade0022 100644 --- a/addons/missileguidance/functions/fnc_onIncomingMissile.sqf +++ b/addons/missileguidance/functions/fnc_onIncomingMissile.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Handles AI shooting a locking missile @@ -12,7 +12,7 @@ * None * * Example: - * [cursorTarget, "x", player] call ace_missileguidance_fnc_changeMissileDirection; + * [cursorTarget, "x", player] call ace_missileguidance_fnc_onIncomingMissile; * * Public: No */ diff --git a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf b/addons/missileguidance/functions/fnc_seekerType_ARH.sqf new file mode 100644 index 0000000000..54e487a9a0 --- /dev/null +++ b/addons/missileguidance/functions/fnc_seekerType_ARH.sqf @@ -0,0 +1,119 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Active Radar Homing seeker + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Seeker Pos + * + * Example: + * [] call call ace_missileguidance_fnc_seekerType_ARH; + * + * Public: No + */ +params ["", "_args", "_seekerStateParams"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_launchParams params ["_target","","","",""]; +_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; +_seekerStateParams params ["_isActive", "_activeRadarEngageDistance", "_timeWhenActive", "_expectedTargetPos", "_lastTargetPollTime", "_shooterHasRadar", "_wasActive", "_lastKnownVelocity", "_lastTimeSeen", "_doesntHaveTarget"]; + +if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { + if !(_isActive) then { + _seekerStateParams set [0, true]; + }; + if !(_wasActive) then { + _seekerStateParams set [6, true]; + TRACE_1("Missile Pitbull",_seekerStateParams); + }; + + // Internal radar homing + // For performance reasons only poll for target every so often instead of each frame + if ((_lastTargetPollTime + ACTIVE_RADAR_POLL_FREQUENCY) - CBA_missionTime < 0) then { + private _searchPos = _expectedTargetPos; + if (_searchPos isEqualTo [0, 0, 0] || { _doesntHaveTarget }) then { + _seekerStateParams set [9, true]; + // no target pos - shot without lock. Have the missile's radar search infront of it on the ground + _searchPos = (getPosASL _projectile) vectorAdd (_projectile vectorModelToWorld [0, _seekerMaxRange, -((getPos _projectile)#2)]); + }; + + _target = objNull; + _lastTargetPollTime = CBA_missionTime; + _seekerStateParams set [4, _lastTargetPollTime]; + private _distanceToExpectedTarget = _seekerMaxRange min ((getPosASL _projectile) vectorDistance _searchPos); + + // Simulate how much the seeker can see at the ground + private _projDir = vectorDir _projectile; + private _projYaw = getDir _projectile; + private _rotatedYaw = (+(_projDir select 0) * sin _projYaw) + (+(_projDir select 1) * cos _projYaw); + if (_rotatedYaw isEqualTo 0) then { _rotatedYaw = 0.001 }; + private _projPitch = atan ((_projDir select 2) / _rotatedYaw); + private _a1 = abs _projPitch; + private _a2 = 180 - ((_seekerAngle / 2) + _a1); + private _seekerBaseRadiusAtGround = ACTIVE_RADAR_MINIMUM_SCAN_AREA max (_distanceToExpectedTarget / sin(_a2) * sin(_seekerAngle / 2)); + private _seekerBaseRadiusAdjusted = linearConversion [0, _seekerBaseRadiusAtGround, (CBA_missionTime - _lastTimeSeen) * vectorMagnitude _lastKnownVelocity, ACTIVE_RADAR_MINIMUM_SCAN_AREA, _seekerBaseRadiusAtGround, false]; + if (_doesntHaveTarget) then { + _seekerBaseRadiusAdjusted = _seekerBaseRadiusAtGround; + }; + // Look in front of seeker for any targets + private _nearestObjects = nearestObjects [ASLtoAGL _searchPos, ["Air", "LandVehicle", "Ship"], _seekerBaseRadiusAdjusted, false]; + + _nearestObjects = _nearestObjects apply { + // I check both Line of Sight versions to make sure that a single bush doesnt make the target lock dissapear but at the same time ensure that this can see through smoke. Should work 80% of the time + if ([_projectile, getPosASL _x, _seekerAngle] call FUNC(checkSeekerAngle) && { ([_projectile, _x, true] call FUNC(checkLOS)) || { ([_projectile, _x, false] call FUNC(checkLOS)) } }) then { + _x + } else { + objNull + }; + }; + _nearestObjects = _nearestObjects select { !isNull _x }; + // Select closest object to the expected position to be the current radar target + if (_nearestObjects isEqualTo []) exitWith { + _projectile setMissileTarget objNull; + _searchPos + }; + private _closestDistance = _seekerBaseRadiusAtGround; + { + if ((_x distance2d _searchPos) < _closestDistance) then { + _closestDistance = _x distance2d _searchPos; + _target = _x; + }; + } forEach _nearestObjects; + + _expectedTargetPos = _searchPos; + }; + + _projectile setMissileTarget _target; +} else { + #ifdef DRAW_GUIDANCE_INFO + _seekerTypeName = "AHR - EXT"; + #endif + // External radar homing + // if the target is in the remote targets for the side, whoever the donor is will "datalink" the target for the hellfire. + private _remoteTargets = listRemoteTargets side _shooter; + if ((_remoteTargets findIf { (_target in _x) && (_x#1 > 0) }) < 0) then { + // I check both Line of Sight versions to make sure that a single bush doesnt make the target lock dissapear but at the same time ensure that this can see through smoke. Should work 80% of the time + if (!_shooterHasRadar || { !isVehicleRadarOn vehicle _shooter } || { !alive vehicle _shooter } || { !([vehicle _shooter, _target, true] call FUNC(checkLOS)) && { !([vehicle _shooter, _target, false] call FUNC(checkLOS)) } }) then { + _seekerStateParams set [0, true]; + _target = objNull; // set up state for active guidance + }; + }; +}; + +if !(isNull _target) then { + private _centerOfObject = getCenterOfMass _target; + private _targetAdjustedPos = _target modelToWorldWorld _centerOfObject; + _expectedTargetPos = _targetAdjustedPos; + + _seekerStateParams set [3, _expectedTargetPos]; + _seekerStateParams set [7, velocity _target]; + _seekerStateParams set [8, CBA_missionTime]; + _seekerStateParams set [9, false]; +}; + +_launchParams set [0, _target]; +_expectedTargetPos diff --git a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf index 356ad5c2f1..bac01d05b4 100644 --- a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Seeker Type: Optic @@ -34,12 +34,12 @@ private _losOkay = false; if (_angleOkay) then { _losOkay = [_projectile, _target] call FUNC(checkLos); }; -TRACE_2("", _angleOkay, _losOkay); +TRACE_2("",_angleOkay,_losOkay); // Can't see target, return [0,0,0] and let doSeekerSearch handle it if (!_angleOkay || !_losOkay) exitWith {[0,0,0]}; -TRACE_2("", _target, _foundTargetPos); +TRACE_2("",_target,_foundTargetPos); // @TODO: Configurable lead for seekers private _projectileSpeed = (vectorMagnitude velocity _projectile); private _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; diff --git a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf new file mode 100644 index 0000000000..da9549c3ae --- /dev/null +++ b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf @@ -0,0 +1,62 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * SACLOS seeker + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Position of wanted missile pos relative to the camera direction + * + * Example: + * [] call ace_missileguidance_fnc_seekerType_SACLOS + * + * Public: No + */ +params ["", "_args"]; +_args params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile"]; +_seekerParams params ["_seekerAngle"]; +_stateParams params ["", "_seekerStateParams"]; +_seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", "_animationSourceGun", "_usePilotCamera"]; + +private _shooterPos = AGLToASL (_shooter modelToWorld(_shooter selectionPosition _memoryPointGunnerOptics)); +private _projPos = getPosASL _projectile; + +private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { + private _finalLookDirection = if (_usePilotCamera) then { + _shooterPos = _shooter modelToWorldVisualWorld getPilotCameraPosition _shooter; + private _trackingTarget = getPilotCameraTarget _shooter; + _trackingTarget params ["_isTracking", "_trackingPos"]; + // Because ARMA doesnt update the camera rotation if you are locked on immediatly, we have to calculate the look direction manually or else the SACLOS target will be wrong, especially if shooter is moving + if (_isTracking) then { + vectorNormalized (_trackingPos vectorDiff _shooterPos); + } else { + _shooter vectorModelToWorldVisual getPilotCameraDirection _shooter; + }; + } else { + private _gBody = -deg(_shooter animationPhase _animationSourceBody); + private _gGun = deg(_shooter animationPhase _animationSourceGun); + _shooter vectorModelToWorldVisual ([1, _gBody, _gGun] call CBA_fnc_polar2vect); + }; + _finalLookDirection +} else { + _shooterPos = eyePos _shooter; + _shooter weaponDirection _weapon +}; + +private _distanceToProj = _shooterPos vectorDistance _projPos; +private _testPointVector = vectorNormalized (_projPos vectorDiff _shooterPos); +private _testDotProduct = (_lookDirection vectorDotProduct _testPointVector); + +private _testIntersections = lineIntersectsSurfaces [_shooterPos, _projPos, _shooter]; + +if ((_testDotProduct < (cos _seekerAngle)) || {_testIntersections isNotEqualTo []}) exitWith { + // out of LOS of seeker + [0, 0, 0] +}; + +_shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj); + diff --git a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf index 09e20e7887..a16c58ce5f 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: jaynus / nou * Seeker Type: SALH (Laser) @@ -27,6 +27,6 @@ _laserParams params ["_code", "_wavelengthMin", "_wavelengthMax"]; private _laserResult = [(getPosASL _projectile), (velocity _projectile), _seekerAngle, _seekerMaxRange, [_wavelengthMin, _wavelengthMax], _code, _projectile] call EFUNC(laser,seekerFindLaserSpot); private _foundTargetPos = _laserResult select 0; -TRACE_1("Search", _laserResult); +TRACE_1("Search",_laserResult); _foundTargetPos; diff --git a/addons/missileguidance/functions/fnc_wire_onFired.sqf b/addons/missileguidance/functions/fnc_wire_onFired.sqf new file mode 100644 index 0000000000..0cfa90ff99 --- /dev/null +++ b/addons/missileguidance/functions/fnc_wire_onFired.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up wireGuided state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_wire_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile", "_gunner"]; +_stateParams params ["", "", "_attackProfileStateParams"]; +_seekerParams params ["", "", "_seekerMaxRange", "_seekerMinRange"]; + +private _config = configOf _projectile >> "ace_missileguidance"; +private _maxCorrectableDistance = [_config >> "correctionDistance", "NUMBER", DEFAULT_CORRECTION_DISTANCE] call CBA_fnc_getConfigEntry; +private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry; +private _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange; +private _minDistanceSqr = _seekerMinRange * _seekerMinRange; + +// AI don't know how to use the crosshair offset becauze they dum dum +private _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 +}; + +private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon; +private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret; + +private _wireCutSource = _shooter selectionPosition getText(_turretConfig >> "missileEnd"); + +_attackProfileStateParams set [0, _maxCorrectableDistance]; +_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, _minDistanceSqr]; +_attackProfileStateParams set [6, _wireCutSource]; +_attackProfileStateParams set [7, _distanceAheadOfMissile]; + diff --git a/addons/missileguidance/functions/script_component.hpp b/addons/missileguidance/functions/script_component.hpp deleted file mode 100644 index 7046e9271d..0000000000 --- a/addons/missileguidance/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\missileguidance\script_component.hpp" \ No newline at end of file diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index 298de3a051..2b43be42f3 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -16,3 +16,16 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define RANDOM_VECTOR_3D (call {\ + private _z = random 2 - 1;\ + private _r = sqrt (1 - _z^2);\ + private _theta = random 360;\ + [_r * cos _theta, _r * sin _theta, _z]\ +}) + +#define DEFAULT_CORRECTION_DISTANCE 2 +#define DEFAULT_LEAD_DISTANCE 5 +#define ACTIVE_RADAR_POLL_FREQUENCY (1 / 7) +#define ACTIVE_RADAR_MINIMUM_SCAN_AREA 30 + diff --git a/addons/missileguidance/stringtable.xml b/addons/missileguidance/stringtable.xml index 1758dea3e3..aacdd472d6 100644 --- a/addons/missileguidance/stringtable.xml +++ b/addons/missileguidance/stringtable.xml @@ -9,34 +9,36 @@ 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ó Продвинутое наведение ракет - 高度なミサイルの誘導 + アドバンスドミサイル誘導 고급 미사일 유도 - 进阶飞弹制导 + 进阶导弹制导 進階飛彈制導 + Gelişmiş Füze Güdüm Sistemi Advanced missile guidance, or AMG, provides multiple enhancements to missile locking and firing. It is also a framework required for missile weapon types. Zaawansowane namierzanie rakiet, lub ZNR, dostarcza wiele poprawek do systemu namierzania rakiet oraz dodaje nowe tryby strzału. Jest to wymagana opcja dla broni rakietowych. - Guida dei missili avanzata, o AMG, offre diversi miglioramenti alla teleguida di missili. E' anche un sistema necessario per i tipi di armi missile. + Guida dei missili avanzata, o GMA, offre diversi miglioramenti alla teleguida di missili. È anche un sistema necessario per la categoria d'arma dei missili. Продвинутое наведение ракет, или ПНР, обеспечивает множество усовершествований для наведения и стрельбы ракет. Также, это система, необходимая для всех ракетных типов оружия. El guiado avanzado de misiles, o AMG en sus siglas en inglés, ofrece múltiples mejoras en el fijado y disparo de misiles. Es también un sistema requerido para armas de tipo misil. Das Erweiterte Raketenlenksystem, auch ERls genannt, bietet viele Verbesserungen zum Aufschalten und Feuern mittels gelenkter Raketen. - Le guidage avancé de missile, ou AMG en anglais, apporte de multiples améliorations au verouillage et au tir de missiles. C'est aussi un framework requis pour tout arme de type missile. + Le guidage avancé de missile, ou AMG en anglais, apporte de multiples améliorations au verrouillage et au tir de missiles. C'est aussi un framework requis pour toute arme de type missile. A fejlett rakétairányító (vagy AMG) többféle módosítást tartalmaz a rakéták célkövetéséhez és tüzeléséhez. Ez egy szükséges keresztrendszer a rakéta-alapú fegyverekhez. Orientação avançada de mísseis ou OAM, fornece vários aprimoramentos para travamento de mísseis e disparos. Também é um sistema requerido para disparar armas que utilizem mísseis. Pokočilé navádění raket (AMG) poskytuje několik vylepšení pro lepší zaměření a následnou střelbu. Je to prvek vyžadovaný u typu zbraní jako jsou rakety. - 高度なミサイルの誘導、または AMG はミサイルの捕捉と発射に複数の強化をあたえます。これはミサイルの種類によって、枠組みを必要とします。 - 고급 미사일 유도 혹은 AMG 는 표적 획득 및 발사를 위한 여러 기능을 제공합니다. 미사일 종류에따라 체계가 필요합니다. - 进阶飞弹制导增强了多种导弹锁定和射击的能力。此系统适用于所有飞弹类型的武器。 + アドバンスドミサイル誘導 (AMG) は、ミサイルの捕捉と発射に複数の機能強化を提供します。 これは、ミサイル兵器の種類に必要なフレームワークでもあります。 + 고급 미사일 유도 혹은 AMG는 표적 획득 및 발사를 위한 여러 기능을 제공합니다. 미사일 종류에 따라 체계가 필요합니다. + 进阶导弹制导增强了多种导弹锁定和射击的能力。此系统适用于所有导弹类型的武器。 進階飛彈制導增強了多種導彈鎖定和射擊的能力。此系統適用於所有飛彈類型的武器 + Gelişmiş füze rehberliği veya AMG, füze kilitleme ve ateşleme için çoklu geliştirmeler sağlar. Hydra-70 DAGR Missile Misil Hydra-70 DAGR - Hydra-70 DAGR + Missile Hydra-70 DAGR Hydra-70 DAGR Hydra-70 DAGR Rakete Hydra-70 DAGR @@ -45,9 +47,10 @@ Hydra-70 DAGR rakéta Hydra-70 DAGR ハイドラ-70 DAGR ミサイル - Hydra-70 DAGR 미사일 - 九头蛇-70 直接攻击导引飞弹 + 히드라-70 DAGR 미사일 + Hydra-70 DAGR 制导火箭 九頭蛇-70 直接攻擊導引飛彈 + Hydra-70 DAGR Füze DAGR @@ -62,40 +65,43 @@ DAGR DAGR DAGR - 直接攻击制导火箭弹 + DAGR 直接攻擊導引飛彈 + DAGR Hydra-70 DAGR Laser Guided Missile Misil guiado por láser Hydra-70 DAGR - Missile à guidage laser Hydra-70 DAGR + Missile Hydra-70 DAGR, à guidage laser Laserowo naprowadzana rakieta Hydra-70 DAGR Hydra-70 DAGR lasergelenkte Rakete Hydra-70 DAGR laserem naváděná střela - Hydra-70 DAGR Missile a Guida Laser + Hydra-70 DAGR Missile Laserguidato Míssil guiado a laser Hydra-70 DAGR Hydra-70 DAGR lézer-irányított rakéta Управляемая ракета лазерного наведения Hydra-70 DAGR - ハイドラ-70 DAGR レーザ誘導ミサイル - Hydra-70 DAGR 레이저 유도 미사일 - 九头蛇-70mm 制导航空火箭弹 + ハイドラ-70 DAGR レーザー誘導ミサイル + 히드라-70 DAGR 레이저 유도 미사일 + Hydra-70 激光制导直接攻击火箭(DAGR) 九頭蛇-70 直接攻擊雷射導引飛彈 + Hydra-70 DAGR Lazer Güdümlü Füze Hellfire II AGM-114K Missile Misil Hellfire II AGM-114K - Hellfire II AGM-114K + Missile Hellfire II AGM-114K Hellfire II AGM-114K Hellfire II AGM-114K Hellfire II AGM-114K - Missile Hellfire II AGM-114K + Missile AGM-114K Hellfire II Míssil Hellfire II AGM-114K Hellfire II AGM-114K rakéta Hellfire II AGM-114K ヘルファイア II AGM-114K ミサイル - Hellfire II AGM-114K 미사일 - 地狱火II型AGM-114K空地制导破甲弹 + 헬파이어 II AGM-114K 미사일 + AGM-114K 地狱火二型导弹 地獄火II型 AGM-114K 導彈 + Hellfire II AGM-114K Füze AGM-114K @@ -110,24 +116,26 @@ AGM-114K AGM-114K AGM-114K - AGM-114K制导破甲弹 + AGM-114K AGM-114K + AGM-114K Hellfire II AGM-114K Laser Guided Missile Misil guiado por láser Hellfire II AGM-114K - Missile à guidage laser Hellfire II AGM-114K + Missile Hellfire II AGM-114K, à guidage laser Laserowo naprowadzana rakieta Hellfire II AGM-114K Hellfire II AGM-114K Lasergelenkte Rakete Hellfire II AGM-114K laserem naváděná střela - Missile a Guida Laser Hellfire II AGM-114K + Missile Laserguidato AGM-114K Hellfire II Míssil guiado a laser Hellfire II AGM-114K Hellfire II AGM-114K lézer-irányított rakéta Управляемая ракета лазерного наведения Hellfire II AGM-114K - ヘルファイア II AGM-114K レーザ誘導ミサイル - Hellfire II AGM-114K 레이저 유도 미사일 - 地狱火II型AGM-114K空地制导破甲弹 + ヘルファイア II AGM-114K レーザー誘導ミサイル + 헬파이어 II AGM-114K 레이저 유도 미사일 + AGM-114K 地狱火二型激光制导导弹 地獄火II型 AGM-114K 雷射導引飛彈 + Hellfire II AGM-114K Lazer Güdümlü Füze Off @@ -136,7 +144,7 @@ Aus Vypnout Desligado - Eteint + Éteint Ki Выкл. Spento @@ -144,6 +152,7 @@ 끄기 关闭 關閉 + Kapalı Player Only @@ -160,6 +169,7 @@ 오직 플레이어만 只有玩家 只有玩家 + Sadece Oyuncular Player and AI @@ -172,10 +182,11 @@ Játékosok és AI Игрок и боты Giocatore ed IA - プレイヤーと AI - 玩家和AI + プレイヤーとAI + 玩家和 AI 玩家和AI 플레이어와 AI + Oyuncular ve AI Cycle Fire Mode @@ -183,15 +194,16 @@ Переключение режимов огня Přepínání režimů palby Przełącz tryb ognia - Cycle mode de tir + Guidage missiles - Changer le mode de tir Tüzelési mód váltása - Alterna le modalità di fuoco + Cambia modalità di fuoco Cambiar modo de disparo Alterar Modo de Disparo - 発射モード切り替え + 発射モードサイクル 발사 방식 순환 循环切换开火模式 循環切換開火模式 + Ateşleme Modunu Değiştir diff --git a/addons/missionmodules/CfgEventHandlers.hpp b/addons/missionmodules/CfgEventHandlers.hpp index be284a9d70..8e27a9f14f 100644 --- a/addons/missionmodules/CfgEventHandlers.hpp +++ b/addons/missionmodules/CfgEventHandlers.hpp @@ -1,12 +1,12 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/missionmodules/CfgFactionClasses.hpp b/addons/missionmodules/CfgFactionClasses.hpp index fc4abc3606..bf0aea3a10 100644 --- a/addons/missionmodules/CfgFactionClasses.hpp +++ b/addons/missionmodules/CfgFactionClasses.hpp @@ -3,4 +3,4 @@ class CfgFactionClasses { class ACE_missionModules: NO_CATEGORY { displayName = CSTRING(Category_DisplayName); }; -}; \ No newline at end of file +}; diff --git a/addons/missionmodules/CfgVehicles.hpp b/addons/missionmodules/CfgVehicles.hpp index 6a2f74b934..880623d488 100644 --- a/addons/missionmodules/CfgVehicles.hpp +++ b/addons/missionmodules/CfgVehicles.hpp @@ -65,4 +65,4 @@ class CfgVehicles { sync[] = {}; }; }; -}; \ No newline at end of file +}; diff --git a/addons/missionmodules/README.md b/addons/missionmodules/README.md index 0b8950d3fe..3389702453 100644 --- a/addons/missionmodules/README.md +++ b/addons/missionmodules/README.md @@ -2,10 +2,3 @@ ace_missionmodules =========== Adds mission modules. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Glowbal](https://github.com/Glowbal) diff --git a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf index ba20ac0b8d..88e2ba02d5 100644 --- a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf +++ b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Plays synchronized ambiance sounds while the module is alive. @@ -55,11 +55,9 @@ private _missionRoot = str missionConfigFile select [0, count str missionConfigF ERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x); }; }; +} forEach _splittedList; - false -} count _splittedList; - -if (count _ambianceSounds == 0) exitWith {}; +if (_ambianceSounds isEqualTo []) exitWith {}; { if ((_x find ".") == -1) then { _ambianceSounds set [_forEachIndex, _x + ".wss"]; @@ -82,7 +80,7 @@ TRACE_1("",_ambianceSounds); private _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]}; // Check if there are enough players to even start playing this sound. - if (count _allUnits > 0) then { + if (_allUnits isNotEqualTo []) then { // find the position from which we are going to play this sound from. private _newPosASL = if (_followPlayers) then { // Select a target unit at random. diff --git a/addons/missionmodules/functions/script_component.hpp b/addons/missionmodules/functions/script_component.hpp deleted file mode 100644 index 42d34d4801..0000000000 --- a/addons/missionmodules/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\missionmodules\script_component.hpp" \ No newline at end of file diff --git a/addons/missionmodules/stringtable.xml b/addons/missionmodules/stringtable.xml index cb28cb3d7e..dfdcef97f3 100644 --- a/addons/missionmodules/stringtable.xml +++ b/addons/missionmodules/stringtable.xml @@ -7,15 +7,16 @@ Módulo de misiones ACE ACE-Missionsmodule ACE Moduly mise - Módulo de missões ACE - ACE module de mission + ACE Módulo de missões + ACE modules de mission ACE küldetési modulok - Модули миссий ACE - Moduli Missione ACE + ACE Модули миссий + ACE Moduli Missione ACE ミッション モジュール ACE 미션 모듈 ACE 任务模块 ACE 任務模塊 + ACE Görev Modülleri Ambiance Sounds @@ -26,12 +27,13 @@ Sons ambientes Sons d'ambiance Ambiens hangok - Звук окружения + Звуки окружения Souni Ambientali 環境音 환경 효과음 环境声音 環境聲音 + Ortam Sesleri Sounds @@ -48,6 +50,7 @@ 효과음 声音 聲音 + Sesler Class names of the ambiance sounds to be played. Seperated by ',' @@ -57,12 +60,13 @@ Class names zvuků prostředí, které budou přehrány. Oddělené ',' Nomes de classe dos sons de ambiente para serem reproduzidos. Separados por "," Имена классов звуков окружения, которые должны проигрываться. Разделенные ',' - ClassNames des sons d'ambiances. Séparation par "," + ClassNames des sons d'ambiance, séparées par une virgule. Nomi classi dei suoni ambientali da eseguire. Separati da ',' 再生する環境音のクラスネームを記載。','で複数指定できます。 재생되는 환경 효과음의 단위와 이름입니다. ','로 구분됩니다. - 输入想使用的环境声音classname。每个classname用','做区隔 + 输入想使用的环境声音 classname。每个 classname 用','做区隔 輸入想使用的環境聲音classname。每個classname用','做區隔 + Çalınacak ambiyans seslerinin sınıf isimleri. Minimal Distance @@ -73,12 +77,13 @@ Distância mínima Distance minimale Minimális távolság - Минимальная дистанция - Distanza Minimale + Мин. дистанция + Distanza Minima 最低距離 최소 거리 最小距离 最小距離 + Minimum Mesafe Used for calculating a random position and sets the minimal distance between the players and the played sound file(s) @@ -87,13 +92,13 @@ Wird verwendet, um eine zufällige Position zu bestimmen und setzt den Mindestabstand zwischen Spielern und der/den abzuspielenden Sounddatei(en) fest Používá se pro výpočet náhodné pozice a určuje minimální vzdálenost mezi hráči a přehrávaným zvukem. Usada para calcular uma posição aleatória e definir a distância mínima entre os jogadores e os arquivos de sons que estão sendo reproduzidos. - Utilisé pour calculer une position aléatoire et pour définir la distance minimale entre le joueur les sons lus. + Valeur utilisée pour calculer une position aléatoire et définir la distance minimale entre les joueurs et les sons joués. Egy véletlenszerű pozíció számításához használt érték, amihez megadja a minimum távolságot a játékosok és a lejátszott hangfájl(ok) között Используется для расчета случайной позиции и указывает минимальное расстояние между игроками и источниками звука - Usati per calcolare una posizione casuale ed impostare la distanza minima tra i giocatori ed il file suono eseguito + Usati per calcolare una posizione casuale ed impostare la distanza minima tra i giocatori ed il file audio riprodotto 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最低距離を設定します - 무작위 위치 계산에 사용되며 플레이어와 재생 된 사운드 파일 간의 최소 거리를 설정합니다. - 声音将随机产生在玩家附近,此选项定义该声音最近会距离玩家多少公尺 + 무작위 위치 계산에 사용되며 플레이어와 재생된 사운드 파일 간의 최소 거리를 설정합니다. + 声音将随机产生在玩家附近,此选项定义该声音最近会距离玩家多少米 聲音將隨機產生在玩家附近,此選項定義該聲音最近會距離玩家多少公尺 @@ -105,12 +110,13 @@ Distância máxima Distance maximale Maximális távolság - Максимальная дистанция + Макс. дистанция Distanza Massima 最大距離 최대 거리 最大距离 最大距離 + Maksimum Mesafe Used for calculating a random position and sets the maximum distance between the players and the played sound file(s) @@ -119,13 +125,13 @@ Wird verwendet, um eine zufällige Position zu bestimmen und setzt den Maximalabstand zwischen Spielern und der/den abzuspielenden Sounddatei(en) fest Používá se pro výpočet náhodné pozice a určuje maximální vzdálenost mezi hráči a přehrávaným zvukem. Usado para calcular uma posição aleatória e definir uma distância máxima entre os jogadores e os arquivos de sons que estão sendo reproduzidos. - Utilisé pour calculer une position aléatoire et pour définir la distance maximale entre le joueur les sons lus. + Valeur utilisée pour calculer une position aléatoire et définir la distance maximale entre les joueurs et les sons joués. Egy véletlenszerű pozíció számításához használt érték, amihez megadja a maximum távolságot a játékosok és a lejátszott hangfájl(ok) között Используется для расчета случайной позиции и указывает максимальное расстояние между игроками и источниками звука - Usato per calcolare una posizione casuale ed impostare la distanza massima tra giocatori e il file suono eseguito + Usato per calcolare una posizione casuale ed impostare la distanza massima tra giocatori e il file audio riprodotto 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最大距離を設定します - 무작위 위치 계산에 사용되며 플레이어와 재생 된 사운드 파일 간의 최대 거리를 설정합니다. - 声音将随机产生在玩家附近,此选项定义该声音最远会距离玩家多少公尺 + 무작위 위치 계산에 사용되며 플레이어와 재생된 사운드 파일 간의 최대 거리를 설정합니다. + 声音将随机产生在玩家附近,此选项定义该声音最远会距离玩家多少米 聲音將隨機產生在玩家附近,此選項定義該聲音最遠會距離玩家多少公尺 @@ -135,14 +141,15 @@ Minimale Verzögerung Minimální prodleva Atraso mínimo - Délais minimal + Délai minimal Minimum késleltetés - Минимальная задержка + Мин. задержка Pausa Minima 最低遅延 최소 지연 最小延迟 最小延遲 + Minimum Gecikme Minimal delay between sounds played @@ -151,14 +158,15 @@ Minimale Verzögerung zwischen abzuspielenden Sounds Minimální prodleva mezi přehrávanými zvuky Atraso mínimo entre os sons reproduzidos - Délais minimal entre les sons lus. + Délai minimal entre deux sons consécutifs. Minimum késleltetés a lejátszott hangok között Минимальная задержка между воспроизведением звуков - Pausa Minima tra suoni eseguiti + Pausa Minima tra suoni riprodotti 再生されるまでの最低遅延 - 재생된 소리간 최소 지연시간 + 재생된 소리간 최소 지연 시간 设定每个声音档案中间最少间隔多久再进行播放 設定每個聲音檔案中間最少間隔多久再進行播放 + Çalınan sesler arasında minimum gecikme Maximum Delay @@ -167,7 +175,7 @@ Maximale Verzögerung Maximální prodleva Atraso máximo - Délais maximal + Délai maximal Maximum késleltetés Максимальная задержка Pausa Massima @@ -175,6 +183,7 @@ 최대 지연 最大延迟 最大延遲 + Maksimum Gecikme Maximum delay between sounds played @@ -183,14 +192,15 @@ Maximale Verzögerung zwischen abzuspielenden Sounds Maximální prodleva mezi přehrávanými zvuky Atraso máximo entre os sons reproduzidos - Délais maximal entre les sons lus. + Délai maximal entre deux sons consécutifs. Maximum késleltetés a lejátszott hangok között Максимальная задержка между воспроизведением звуков - Pausa Massima tra suoni eseguiti + Pausa Massima tra suoni riprodotti 再生されるまでの最大遅延 - 재생된 소리간 최대 지연시간 + 재생된 소리간 최대 지연 시간 设定每个声音档案中间最多间隔多久再进行播放 設定每個聲音檔案中間最多間隔多久再進行播放 + Çalınan sesler arasında maksimum gecikme Follow Players @@ -207,6 +217,7 @@ 플레이어 따라가기 跟随玩家 跟隨玩家 + Oyuncuları Takip Et Follow players. If set to false, loop will play sounds only nearby logic position. @@ -215,14 +226,15 @@ Spielern folgen. Wenn auf falsch gesetzt, werden Sounds nur in der Nähe des Logikmoduls abgespielt. Následuj hráče. Pokud je FALSE, smyčka zvuku bude přehrávána na nejbližší pozici logiki. Segue os jogadores. Se esta desabilitado (falso), o loop reproduzirá os sons somente perto de sua posição lógica. - Suivre le joueur. Si défini sur false, les sons seront joués en boucle autour la position logique + Suivre les joueurs. Si défini sur false, les sons ne seront joués qu'autour de la position du module. Játékosok követése. Ha le van tiltva, az ismétlés csak a legközelebbi logikai ponton játszik le hangokat. Следовать за игроками. Если установить в Ложь, звуки будут циклически проигрываться только около позиции Логики. - Segui Giocatori. Se impostato su falso, il ciclo eseguirà i suoni solo vicino ad una posizione logica. + Segui Giocatori. Se impostato su falso, il ciclo riprodurrà i suoni solo in prossimità del modulo. プレイヤーを追随します。False に設定するとロジックの近くで延々と再生します。 - 플레이어를 따라갑니다. 거짓으로 설정될경우 오직 한 자리에서만 반복해서 소리를 재생합니다. + 플레이어를 따라갑니다. False로 설정될 경우 오직 한 자리에서만 반복해서 소리를 재생합니다. 设定声音是否会在玩家的附近产生。假如关闭此功能,声音只会在模块的位置产生。 設定聲音是否會在玩家的附近產生。假如關閉此功能,聲音只會在模塊的位置產生。 + Eğer devde dışı bırakılırsa sesler oyuncuyu takip etmez Volume @@ -239,6 +251,7 @@ 볼륨 音量 音量 + Ses The volume of the sounds played @@ -247,14 +260,15 @@ Lautstärke der abzuspielenden Sounds Hlasitost přehrávaného zvuku O volume em que os sons serão reproduzidos - Volume des sons lus + Définit le volume des sons. A lejátszott hangok hangereje Громкость воспроизводимых звуков - Il volume dei suoni eseguiti + Il volume dei suoni riprodotti 再生される音の大きさ 재생되는 소리의 볼륨 调整声音的音量 調整聲音的音量 + Çalınan seslerin seviyesi Ambiance sounds loop (synced across MP) @@ -263,14 +277,15 @@ Umgebungsgeräusch-Schleife (im MP synchronisiert) Smyčka okkolního zvuku (synchronizováno v MP) Loop de sons ambientes (sincronizados através do MP) - Sons d'ambiance lus en boucle (Synchronisation MP) + Boucle de sons d'ambiance. (Synchronisée en MP) Ambiens hangok folyamatossága (MP alatt szinkronizálva) Циклически воспроизводимые звуки окружения (синх. между игроками) Ciclo Suoni Ambientali (sincronizzato in MP) 環境音の繰り返し (MP 間で同期させます) 환경 효과음 반복 (멀티플레이 전반적으로 동기화됨) - 循环的环境声音 (在多人游戏中会同步所有玩家的播放状态) + 循环的环境声音(在多人游戏中会同步所有玩家的播放状态) 循環的環境聲音 (在多人遊戲中會同步所有玩家的播放狀態) + Ambiyans sesleri döngüsü (MP üzerinden senkronize edilir) diff --git a/addons/mk6mortar/ACE_Settings.hpp b/addons/mk6mortar/ACE_Settings.hpp index 5fb88aa23b..9c3a1a33e8 100644 --- a/addons/mk6mortar/ACE_Settings.hpp +++ b/addons/mk6mortar/ACE_Settings.hpp @@ -1,35 +1,14 @@ class ACE_Settings { - //These settings effect gameplay difficutly: defaults will leave the mortar the same as vanilla class GVAR(airResistanceEnabled) { - category = CSTRING(DisplayName); - displayName = CSTRING(airResistanceEnabled_DisplayName); - description = CSTRING(airResistanceEnabled_Description); - value = 0; - typeName = "BOOL"; - isClientSetable = 0; + movedToSQF = 1; }; class GVAR(allowComputerRangefinder) { - category = CSTRING(DisplayName); - displayName = CSTRING(allowComputerRangefinder_DisplayName); - description = CSTRING(allowComputerRangefinder_Description); - value = 1; - typeName = "BOOL"; - isClientSetable = 0; + movedToSQF = 1; }; class GVAR(allowCompass) { - category = CSTRING(DisplayName); - displayName = CSTRING(allowCompass_DisplayName); - description = CSTRING(allowCompass_Description); - value = 1; - typeName = "BOOL"; - isClientSetable = 0; + movedToSQF = 1; }; class GVAR(useAmmoHandling) { - category = CSTRING(DisplayName); - displayName = CSTRING(useAmmoHandling_DisplayName); - description = CSTRING(useAmmoHandling_Description); - value = 0; - typeName = "BOOL"; - isClientSetable = 0; + movedToSQF = 1; }; }; diff --git a/addons/mk6mortar/CfgEventHandlers.hpp b/addons/mk6mortar/CfgEventHandlers.hpp index 957fefb736..6c29240403 100644 --- a/addons/mk6mortar/CfgEventHandlers.hpp +++ b/addons/mk6mortar/CfgEventHandlers.hpp @@ -1,26 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - }; -}; - -class Extended_FiredBIS_EventHandlers { - class Mortar_01_base_F { - class ADDON { - firedBIS = QUOTE(_this call FUNC(handleFired)); - }; + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/mk6mortar/CfgMagazines.hpp b/addons/mk6mortar/CfgMagazines.hpp index 0d5c1d5703..e0626479c4 100644 --- a/addons/mk6mortar/CfgMagazines.hpp +++ b/addons/mk6mortar/CfgMagazines.hpp @@ -1,10 +1,11 @@ -class cfgMagazines { +class CfgMagazines { class 8Rnd_82mm_Mo_shells; class ACE_1Rnd_82mm_Mo_HE: 8Rnd_82mm_Mo_shells { count = 1; scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_displayName); displayNameShort = ""; @@ -19,6 +20,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_Smoke_displayName); displayNameShort = ""; @@ -33,6 +35,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_Illum_displayName); displayNameShort = ""; @@ -47,6 +50,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_Guided_displayName); displayNameShort = ""; @@ -61,6 +65,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_LaserGuided_displayName); displayNameShort = ""; diff --git a/addons/mk6mortar/CfgWeapons.hpp b/addons/mk6mortar/CfgWeapons.hpp index 3e247910fb..b32cce1e41 100644 --- a/addons/mk6mortar/CfgWeapons.hpp +++ b/addons/mk6mortar/CfgWeapons.hpp @@ -8,24 +8,28 @@ class CfgWeapons { displayName = CSTRING(rangetable_name); descriptionShort = CSTRING(rangetable_description); picture = QPATHTOF(UI\icon_rangeTable.paa); + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 0.5; + mass = 0.1; }; }; class CannonCore; class mortar_82mm: CannonCore { class Single1; + class Burst1; }; class ACE_mortar_82mm: mortar_82mm { author = ECSTRING(common,ACETeam); magazines[] = {"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"}; - modes[] = {"Single1","Single2","Single3"}; reloadTime = 0.5; magazineReloadTime = 0.5; class Single1: Single1 { reloadTime = 0.5; }; + class Burst1: Burst1 { + reloadTime = 0.5; + }; }; }; diff --git a/addons/mk6mortar/README.md b/addons/mk6mortar/README.md index 3e5109f38f..2c3be4cd97 100644 --- a/addons/mk6mortar/README.md +++ b/addons/mk6mortar/README.md @@ -1,11 +1,4 @@ ace_mk6mortar ========== -Tweaks the Nk6 Mortar system. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) +Tweaks the Mk6 Mortar system. diff --git a/addons/mk6mortar/RscInGameUI.hpp b/addons/mk6mortar/RscInGameUI.hpp index 3c2a1da534..60e5c5f324 100644 --- a/addons/mk6mortar/RscInGameUI.hpp +++ b/addons/mk6mortar/RscInGameUI.hpp @@ -3,17 +3,9 @@ class RscInGameUI { class CA_IGUI_elements_group: RscControlsGroup {}; }; class ACE_Mk6_RscWeaponRangeArtillery: RscWeaponRangeArtillery { - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_Mk6_RscWeaponRangeArtillery', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Mk6Mortar')])] call CBA_fnc_localEvent;); - controls[] = {"ACE_ChargeDisplay", "ACE_MILS_GROUP", "CA_IGUI_elements_group","CA_RangeElements_group"}; - class ACE_ChargeDisplay: RscStructuredText { - idc = 80085; - colorText[] = {1, 1, 1, 1}; - colorBackground[] = {0, 0, 0, 0.1}; - x = "3.8 * (((safezoneW / safezoneH) min 1.2) / 40) + (profilenamespace getvariable [""IGUI_GRID_WEAPON_X"",((safezoneX + safezoneW) - (10 * (((safezoneW / safezoneH) min 1.2) / 40)) - 4.3 * (((safezoneW / safezoneH) min 1.2) / 40))])"; - y = "2.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (profilenamespace getVariable ['IGUI_GRID_WEAPON_Y', (safezoneY + 0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))])"; - w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; - h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - }; + onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_Mk6_RscWeaponRangeArtillery',_this select 0)]; [ARR_2('ace_infoDisplayChanged',[ARR_2(_this select 0,'Mk6Mortar')])] call CBA_fnc_localEvent;); + controls[] = {"ACE_MILS_GROUP", "CA_IGUI_elements_group","CA_RangeElements_group"}; + class ACE_MILS_GROUP: CA_IGUI_elements_group { idc = 80170; class controls { diff --git a/addons/mk6mortar/RscRangeTable.hpp b/addons/mk6mortar/RscRangeTable.hpp deleted file mode 100644 index c719dd7ee4..0000000000 --- a/addons/mk6mortar/RscRangeTable.hpp +++ /dev/null @@ -1,87 +0,0 @@ -class ACE_82mm_RangeTable_Dialog { - idd = -1; - movingEnable = 1; - onLoad = "uiNamespace setVariable ['ACE_82mm_RangeTable_Dialog', _this select 0];"; - objects[] = {}; - - class ControlsBackground { - class TableBackground: RscPicture { - idc = -1; - text = QPATHTOF(UI\RangeTable_background.paa); - x = "18 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)"; - y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)"; - w = "16.2634559672906 * (safeZoneH / 40)"; - h = "23 * ((safeZoneH / 1.2) / 25)"; - colorBackground[] = {1,1,1,1}; - }; - class ChargeBackground: RscText { - idc = -1; - x = "14 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)"; - y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)"; - w = "4 * (safeZoneH / 40)"; - h = "5 * ((safeZoneH / 1.2) / 25)"; - colorBackground[] = {0,0,0,1}; - }; - }; - class controls { - class TheTable: RscListNBox { - idc = 20001; - // style = ST_CENTER + ST_MULTI + LB_TEXTURES; - // style = ST_LEFT + ST_MULTI + LB_TEXTURES; - // style = LB_MULTI + ST_LEFT; // Style - x = "18 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)"; - y = "3.76 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)"; - w = "16.2634559672906 * (safeZoneH / 40)"; - h = "20.24 * ((safeZoneH / 1.2) / 25)"; - columns[] = {(10/867),(86/867),(171/867),(238/867),(320/867),(405/867), - (485/867),(546/867),(607/867),(668/867),(729/867),(790/867)}; - rowHeight = 0.015 * safeZoneH; - sizeEx = "0.014 * safeZoneH"; - font = "EtelkaMonospacePro"; - drawSideArrows = 1; - idcLeft = 14124; - idcRight = 412343243; - colorText[] = {0, 0, 0, 1}; - shadow = "0"; - // colorBorder[] = {1,0,0,1}; - // colorBackground[] = {1, 0, 0, 1}; - colorSelectBackground[] = {0, 0, 0, 0.025}; - colorSelectBackground2[] = {0, 0, 0, 0.025}; - colorScrollbar[] = {0.95,0,0.95,1}; - class ListScrollBar: ScrollBar{ - color[] = {0,0,0,0.6}; - }; - }; - class ChargeListBox: RscListbox { - idc = 1501; - style = ST_RIGHT; - x = "14 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)"; - y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)"; - w = "4 * (safeZoneH / 40)"; - h = "5 * ((safeZoneH / 1.2) / 25)"; - onLBSelChanged = QUOTE(_this call FUNC(rangeTablePageChange)); - }; - class CloseBackground: RscText { - idc = -1; - x = "33.7634559672906 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)"; - y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)"; - w = "0.5 * (safeZoneH / 40)"; - h = "0.5 * ((safeZoneH / 1.2) / 25)"; - colorBackground[] = {0,0,0,0.5}; - }; - class CloseActiveText: RscActiveText { - idc = -1; - style = 48; - color[] = {1,1,1,0.7}; - text = "A3\Ui_f\data\GUI\Rsc\RscDisplayArcadeMap\icon_exit_cross_ca.paa"; - x = "33.7634559672906 *(safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)"; - y = "1 * ((safeZoneH / 1.2) / 25) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)"; - w = "0.5 * (safeZoneH / 40)"; - h = "0.5 * ((safeZoneH / 1.2) / 25)"; - colorText[] = {1,1,1,0.7}; - colorActive[] = {1,1,1,1}; - tooltip = "Close"; - onButtonClick = "closeDialog 0"; - }; - }; -}; diff --git a/addons/mk6mortar/XEH_PREP.hpp b/addons/mk6mortar/XEH_PREP.hpp index 03d6bd6051..dd052a993e 100644 --- a/addons/mk6mortar/XEH_PREP.hpp +++ b/addons/mk6mortar/XEH_PREP.hpp @@ -1,18 +1,9 @@ -PREP(dev_buildTable); -PREP(dev_formatNumber); -PREP(dev_simulateCalcRangeTableLine); -PREP(dev_simulateFindSolution); -PREP(dev_simulateShot); - PREP(csw_getProxyWeapon); - PREP(handleFired); PREP(handlePlayerVehicleChanged); PREP(moduleInit); PREP(rangeTableCanUse); PREP(rangeTableOpen); -PREP(rangeTablePageChange); -PREP(rangeTablePreCalculatedValues); PREP(toggleMils); PREP(turretDisplayLoaded); diff --git a/addons/mk6mortar/XEH_postInit.sqf b/addons/mk6mortar/XEH_postInit.sqf index 338f859767..280e16cf79 100644 --- a/addons/mk6mortar/XEH_postInit.sqf +++ b/addons/mk6mortar/XEH_postInit.sqf @@ -1,11 +1,17 @@ #include "script_component.hpp" if (hasInterface) then { - ["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; + #include "initKeybinds.inc.sqf" + ["ace_infoDisplayChanged", LINKFUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; }; -["ace_settingsInitialized", { - TRACE_1("ace_settingsInitialized",GVAR(useAmmoHandling)); +["CBA_settingsInitialized", { + TRACE_4("CBA_settingsInitialized",GVAR(airResistanceEnabled),GVAR(allowComputerRangefinder),GVAR(allowCompass),GVAR(useAmmoHandling)); - ["vehicle", FUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; + ["vehicle", LINKFUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; + + if (!GVAR(airResistanceEnabled)) exitWith {}; + if (EGVAR(artillerytables,advancedCorrections)) exitWith { TRACE_1("defer firedEH to artillerytables",_this); }; + + ["Mortar_01_base_F", "fired", LINKFUNC(handleFired)] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/mk6mortar/XEH_preInit.sqf b/addons/mk6mortar/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/mk6mortar/XEH_preInit.sqf +++ b/addons/mk6mortar/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/mk6mortar/config.cpp b/addons/mk6mortar/config.cpp index 79fd043619..4e4ad2cb5f 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_csw"}; + requiredAddons[] = {"ace_csw", "ace_artillerytables"}; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror","Grey","VKing"}; url = ECSTRING(main,URL); @@ -24,7 +24,7 @@ class CfgPatches { //UI Stuff: class RscText; -class RscListbox; +class RscListBox; class RscListNBox; class RscPicture; class RscControlsGroup; @@ -33,4 +33,3 @@ class RscActiveText; class RscStructuredText; #include "RscInGameUI.hpp" -#include "RscRangeTable.hpp" diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf index 04ed2a0014..663afa2cc7 100644 --- a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Compatibility With ACE_CSW (will be called by ace_csw, no dependency) @@ -55,13 +55,13 @@ if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { }; }; } else { - WARNING("unknown mag %1", _xMag); + WARNING_1("unknown mag %1",_xMag); }; }; } forEach (magazinesAllTurrets _mortar); // remove orignal mags and add 1rnd versions: - { _staticWeapon removeMagazinesTurret _x; } forEach _magsToRemove; + { _mortar removeMagazinesTurret _x; } forEach _magsToRemove; { _mortar addMagazineTurret _x; } forEach _convertedMags; }; diff --git a/addons/mk6mortar/functions/fnc_dev_buildTable.sqf b/addons/mk6mortar/functions/fnc_dev_buildTable.sqf deleted file mode 100644 index 6141314eea..0000000000 --- a/addons/mk6mortar/functions/fnc_dev_buildTable.sqf +++ /dev/null @@ -1,84 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * DEV function to build mortar tables, very cpu intensive (never used durring normal gameplay) - * - * Arguments: - * 0: Muzzle Velocity - * 1: Air Friction - * - * Return Value: - * None - * - * Example: - * [100, -0.0001] spawn ace_mk6mortar_fnc_dev_buildTable; //spawn (scheduled) is slower - * [100, -0.0001] call ace_mk6mortar_fnc_dev_buildTable; //faster, but will lock while processing - * - * Public: No - */ - -private _muzzleVelocity = _this select 0; -private _airFriction = _this select 1; -private _stillInRange = true; -private _currentRange = 100; -private _increasePerRow = 50; -private _outputArray = []; - - -//[_rangeToHit, _lineElevation, _lineHeightElevation, _lineHeightTimeDelta, _lineTimeOfFlight, _lineCrosswindDeg, _lineHeadwindMeters, _lineTailWindMeters, _lineTempDec, _lineTempInc, _lineAirDensDec, _lineAirDensInc] - -while {_stillInRange} do { - private _result = [_muzzleVelocity, _currentRange, _airFriction] call FUNC(dev_simulateCalcRangeTableLine); - if (_result isEqualTo []) then { - _stillInRange = false; - } else { - if (_airFriction == 0) then { - _result set [5, 0]; - _result set [6, 0]; - _result set [7, 0]; - _result set [8, 0]; - _result set [9, 0]; - _result set [10, 0]; - _result set [11, 0]; - }; - if ((_result select 1) < 88) then { - _outputArray pushBack [ - ([(_result select 0), "meters", false] call FUNC(dev_formatNumber)), - ([(_result select 1), "mil", true] call FUNC(dev_formatNumber)), - ([(_result select 2), "mil", true] call FUNC(dev_formatNumber)), - ([(_result select 3), "sec", false] call FUNC(dev_formatNumber)), - ([(_result select 4), "sec", false] call FUNC(dev_formatNumber)), - ([(_result select 5), "milPrecise", true] call FUNC(dev_formatNumber)), - ([(_result select 6), "metersprecise", false] call FUNC(dev_formatNumber)), - ([(_result select 7), "metersprecise", false] call FUNC(dev_formatNumber)), - ([(_result select 8), "metersprecise", false] call FUNC(dev_formatNumber)), - ([(_result select 9), "metersprecise", false] call FUNC(dev_formatNumber)), - ([(_result select 10), "metersprecise", false] call FUNC(dev_formatNumber)), - ([(_result select 11), "metersprecise", false] call FUNC(dev_formatNumber)) - ]; - }; - _currentRange = _currentRange + _increasePerRow; - }; - hintSilent str _currentRange; -}; - -//handle floating point rounding errors -private _outputString = format ["case ((abs(_muzzleVelocity - %1) < 0.00001) && {(abs(_airFriction - %2) < 0.00001)}): { -[ -", _muzzleVelocity, _airFriction]; - -{ - if (_forEachIndex < ((count _outputArray) - 1)) then { - _outputString = _outputString + format ["%1, - ", _x]; - } else { - _outputString = _outputString + format ["%1 - ] - };", _x]; - }; -} forEach _outputArray; - -copyToClipboard _outputString; -rangeTableOutput = _outputString; - -hint "done"; diff --git a/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf b/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf deleted file mode 100644 index a24f456037..0000000000 --- a/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf +++ /dev/null @@ -1,76 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Pabst Mirror - * Converts numbers into nicely formated strings. - * - * Arguments: - * 0: Input number - * 1: Output type (see case statement) - * 2: If output type is mil, convert input type from deg->mil - * - * Return Value: - * Formatted number - * - * Example: - * [45, "mil4", true] call ace_mk6mortar_fnc_dev_formatNumber = "0800" - * - * Public: No - */ - -params ["_theNumber", "_inputType", "_convertToMils"]; - -private _decimalPlaces = -1; -private _integerPlaces = -1; - -switch (toLower _inputType) do { -case ("meters"): { - _decimalPlaces = 0; - _integerPlaces = 1; - }; -case ("metersprecise"): { - _decimalPlaces = 1; - _integerPlaces = 1; - }; -case ("meters4"): { - _decimalPlaces = 0; - _integerPlaces = 4; - }; -case ("deg3precise"): { - _decimalPlaces = 2; - _integerPlaces = 3; - }; -case ("mil"): { - _decimalPlaces = 0; - _integerPlaces = 1; - if (_convertToMils) then { - _theNumber = _theNumber * (6400 / 360); - }; - }; -case ("mil4"): { - _decimalPlaces = 0; - _integerPlaces = 4; - if (_convertToMils) then { - _theNumber = _theNumber * (6400 / 360); - }; - }; -case ("milprecise"): { - _decimalPlaces = 1; - _integerPlaces = 1; - if (_convertToMils) then { - _theNumber = _theNumber * (6400 / 360); - }; - }; -case ("sec"): { - _decimalPlaces = 1; - _integerPlaces = 1; - }; - default {systemChat format ["badtype %1", _inputType];}; -}; - -//CBA_fnc_formatNumber is silly: [-9.58545, 1, 1, false] call CBA_fnc_formatNumber == "-9.-6" - -private _prefix = if (_theNumber < 0) then {"-"} else {""}; - -private _return = [abs (_theNumber), _integerPlaces, _decimalPlaces, false] call CBA_fnc_formatNumber; - -(_prefix + _return) diff --git a/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf b/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf deleted file mode 100644 index 2bdfe56c22..0000000000 --- a/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf +++ /dev/null @@ -1,77 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Pabst Mirror - * Builds a rangeTable line for a certian range, given muzzle velocity and air friction, returns [] if out of range. - * - * Arguments: - * 0: Muzzle Velocity - * 1: Air Friction - * 2: Range To Hit - * - * Return Value: - * Range Table Line Data (see return line) - * - * Example: - * [300, -0.0001, 3000] call ace_mk6mortar_fnc_simulateCalcRangeTableLine - * - * Public: No - */ - -#define TIME_STEP (1/50) - -params ["_muzzleVelocity", "_rangeToHit", "_airFriction"]; - -private _startTime = diag_tickTime; - - - -//Run Binary search for correct elevation -private _solution = [_rangeToHit, 0, _muzzleVelocity, _airFriction, TIME_STEP] call FUNC(dev_simulateFindSolution); -if (_solution isEqualTo []) exitWith {[]}; - -//Real Elevation -private _lineElevation = _solution select 0; - -//Time Of Flight: -private _lineTimeOfFlight = _solution select 1; - -//Height Adjustment for -100m (another binary search) -private _solution = [_rangeToHit, -100, _muzzleVelocity, _airFriction, TIME_STEP] call FUNC(dev_simulateFindSolution); -if (_solution isEqualTo []) exitWith {[]};//should never be triggered (lower elevation easier to hit) - -private _lineHeightElevation = ((_solution select 0) - _lineElevation); -private _lineHeightTimeDelta = (_solution select 1) - _lineTimeOfFlight; - -//Compute for 10x and divide to minimize rounding errors - -//Crosswind -private _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 0, 10, 0, TIME_STEP] call FUNC(dev_simulateShot); -private _lineCrosswindDeg = (_lastTestResult select 2) / 10; - -//Headwind: -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, -10, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -private _lineHeadwindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; - -//TailWind: -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 10, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -private _lineTailWindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; - -//Air Temp Dec -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, (15 - 10), 1, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineTempDec = (_rangeToHit - (_lastTestResult select 0)) / 10; - -//Air Temp Inc -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, (15 + 10), 1, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineTempInc = (_rangeToHit - (_lastTestResult select 0)) / 10; - -//Air Density Dec -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 0.9, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -private _lineAirDensDec = (_rangeToHit - (_lastTestResult select 0)) / 10; - -//Air Density Inc -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1.1, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -private _lineAirDensInc = (_rangeToHit - (_lastTestResult select 0)) / 10; - -// systemChat format ["debug: Range %1 - in %2 sec", _rangeToHit, (diag_tickTime - _startTime)]; - -[_rangeToHit, _lineElevation, _lineHeightElevation, _lineHeightTimeDelta, _lineTimeOfFlight, _lineCrosswindDeg, _lineHeadwindMeters, _lineTailWindMeters, _lineTempDec, _lineTempInc, _lineAirDensDec, _lineAirDensInc] diff --git a/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf b/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf deleted file mode 100644 index 3c509d5a19..0000000000 --- a/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf +++ /dev/null @@ -1,48 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * DEV to find a firing solution for a given range - * - * Arguments: - * 0: Range to Hit (Meters) - * 1: Height To Hit (Meters) - * 2: Muzzle Velocity (M/S) - * 3: Air Friction - * 4: Time Step (seconds) (eg 1/50 will simulate 50 cycles per second) - * - * Return Value: - * [NUMBER - Elevation In Degrees, NUMBER - Shot Durration] - * - * Example: - * [_rangeToHit, _heightToHit, _muzzleVelocity, _airFriction, TIME_STEP] call ace_mk6mortar_fnc_dev_simulateFindSolution; - * - * Public: No - */ - -#define MAX_ATTEMPTS 22 -params ["_rangeToHit", "_heightToHit", "_muzzleVelocity", "_airFriction","_timeStep"]; - -private _maxElev = 90; -private _minElev = 45; //todo - Low Angle Howitzers??? - -private _error = 10000; -private _solutionElevation = -1; -private _lastTestResult = []; -private _numberOfAttempts = 0; - -//(binary search) -while {(_numberOfAttempts < MAX_ATTEMPTS) && {(abs _error) > 0.2}} do { - _numberOfAttempts = _numberOfAttempts + 1; - _solutionElevation = (_maxElev + _minElev) / 2; - _lastTestResult = [_solutionElevation, _muzzleVelocity, _airFriction, 15, 1, 0, 0, _heightToHit, _timeStep] call FUNC(dev_simulateShot); - _error = _rangeToHit - (_lastTestResult select 0); - if (_error > 0) then { - _maxElev = _solutionElevation; //test range was short - } else { - _minElev = _solutionElevation; //test range was long - }; -}; -if (_numberOfAttempts >= MAX_ATTEMPTS) exitWith {[]}; - -//return the elevation and time required -[_solutionElevation, (_lastTestResult select 1)] diff --git a/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf b/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf deleted file mode 100644 index 7974526ff6..0000000000 --- a/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf +++ /dev/null @@ -1,63 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * DEV function to build mortar tables, very cpu intensive (never used durring normal gameplay) - * - * Arguments: - * 0: Shot Angle (degrees) - * 1: Muzzle Velocity (m/s) - * 2: Air Friction - * 3: Tempeture (degres celcius) - * 4: Relative Air Denisty - * 5: Tail Wind (m/s) - * 6: Cross Wind (m/s) - * 7: Height Of Target (M) - * 8: Time Step (fraction of a second) - * - * Return Value: - * [Distance Traveled, Shot Time, Offset (degrees)] - * - * Example: - * [45, 180, -0.0001, 15, 1, 10, 0, 0, 1/50] call ace_mk6mortar_fnc_dev_simulateShot; - * - * Public: No - */ - -params ["_angleDeg", "_muzzleVelocity", "_airFriction", "_temp", "_relDensity", "_tailWind", "_crosswind", "_heightOfTarget", "_timeStep"]; - -private _wind = [_crosswind, _tailWind, 0]; -private _gravity = [0,0,-9.8]; - -private _currentPos = [0,0,0]; -private _muzzleVelocity = _muzzleVelocity * (((_temp + 273.13) / 288.13 - 1) / 40 + 1); -private _currentVelocity = [0, (_muzzleVelocity * cos _angleDeg), (_muzzleVelocity * sin _angleDeg)]; - -private _currentTime = 0; -private _lastPos = _currentPos; - -private _kCoefficent = -1 * _relDensity * _airFriction; //save time in the loop and compute once - -while {((_currentVelocity select 2) > 0) || ((_currentPos select 2) >= _heightOfTarget)} do { - _lastPos = _currentPos; - - private _aparentWind = _wind vectorDiff _currentVelocity; - private _changeInVelocity = _gravity vectorAdd (_aparentWind vectorMultiply ((vectorMagnitude _aparentWind) * _kCoefficent)); - - _currentVelocity = _currentVelocity vectorAdd (_changeInVelocity vectorMultiply _timeStep); - - _currentPos = _currentPos vectorAdd (_currentVelocity vectorMultiply _timeStep); - _currentTime = _currentTime + _timeStep; -}; - -//Uses linearConversion to get a weighted average betwen points before and after dropping below target height -private _linConversion = linearConversion [(_lastPos select 2), (_currentPos select 2), _heightOfTarget, 0, 1, true]; -private _middlePos = (_lastPos vectorMultiply (1 - _linConversion)) vectorAdd (_currentPos vectorMultiply (_linConversion)); -// private _middlePosOld = (_lastPos vectorAdd _currentPos) vectorMultiply 0.5; - -//Same to find travel time -private _middleTotalTravelTime = _currentTime - (_timeStep * (1-_linConversion)); - -//Find shot offset (from crosswind), in degrees -private _offsetDeg = (_middlePos select 0) aTan2 (_middlePos select 1); - -[(_middlePos select 1), _middleTotalTravelTime, _offsetDeg] diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index 550ae05f8a..8ea2984b79 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Called when the mortar is fired. @@ -21,16 +21,14 @@ * Public: No */ -params ["_vehicle", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; - -if (!GVAR(airResistanceEnabled)) exitWith {}; +params ["_vehicle", "", "", "", "", "", "_projectile"]; // Large enough distance to not simulate any wind deflection -if (_vehicle distance ACE_player > 8000) exitWith {false}; +if (_vehicle distance ACE_player > 8000) exitWith {}; //AI will have no clue how to use: -_shooterMan = gunner _vehicle; -if (!([_shooterMan] call EFUNC(common,isPlayer))) exitWith {false}; +private _shooterMan = gunner _vehicle; +if !([_shooterMan] call EFUNC(common,isPlayer)) exitWith {}; //Calculate air density: private _altitude = (getPosASL _vehicle) select 2; @@ -45,8 +43,8 @@ TRACE_5("FiredWeather",_temperature,_pressure,_relativeHumidity,_airDensity,_rel //powder effects: private _newMuzzleVelocityCoefficent = (((_temperature + 273.13) / 288.13 - 1) / 40 + 1); if (_newMuzzleVelocityCoefficent != 1) then { - _bulletVelocity = velocity _projectile; - _bulletSpeed = vectorMagnitude _bulletVelocity; + private _bulletVelocity = velocity _projectile; + private _bulletSpeed = vectorMagnitude _bulletVelocity; _bulletVelocity = (vectorNormalized _bulletVelocity) vectorMultiply (_bulletSpeed * _newMuzzleVelocityCoefficent); _projectile setVelocity _bulletVelocity; }; @@ -64,7 +62,6 @@ if (_newMuzzleVelocityCoefficent != 1) then { _args set[2, CBA_missionTime]; private _bulletVelocity = velocity _shell; - private _bulletSpeed = vectorMagnitude _bulletVelocity; private _trueVelocity = _bulletVelocity vectorDiff wind; private _trueSpeed = vectorMagnitude _trueVelocity; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index 6e0b9b1794..d721b0e4ae 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. @@ -19,7 +19,7 @@ params ["_player", "_newVehicle"]; if (isNull _newVehicle) exitWith {}; -if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {}; +if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {}; private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); @@ -56,40 +56,13 @@ if (_lastFireMode != -1) then { private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; if (isNull _display) exitWith {}; //It may be null for the first frame - private _chargeText = format ["%1: %2 ", (localize LSTRING(rangetable_charge)), _currentChargeMode, QPATHTOF(UI\ui_charges.paa)]; - //Hud should hidden in 3rd person private _notGunnerView = cameraView != "GUNNER"; - //Calc real azimuth/elevation - //(looking at the sky VS looking at ground will radicaly change fire direction because BIS) - private _realAzimuth = -1; - private _realElevation = -1; - - private _useRealWeaponDir = (ctrlText (_display displayCtrl 173)) == "--"; - if (_useRealWeaponDir && {(_mortarVeh ammo (currentWeapon _mortarVeh)) == 0}) then { - // With no ammo, distance display will be empty, but gun will still fire at wonky angle if aimed at ground - private _testSeekerPosASL = AGLtoASL (positionCameraToWorld [0,0,0]); - private _testSeekerDir = _testSeekerPosASL vectorFromTo (AGLtoASL (positionCameraToWorld [0,0,1])); - private _testPoint = _testSeekerPosASL vectorAdd (_testSeekerDir vectorMultiply viewDistance); - if ((terrainIntersectASL [_testSeekerPosASL, _testPoint]) || {lineIntersects [_testSeekerPosASL, _testPoint]}) then { - _useRealWeaponDir = false; // If we are not looking at infinity (based on viewDistance) - }; - }; - - if (_useRealWeaponDir) then { - //No range (looking at sky), it will follow weaponDir: - private _weaponDir = _mortarVeh weaponDirection (currentWeapon _mortarVeh); - _realAzimuth = (_weaponDir select 0) atan2 (_weaponDir select 1); - _realElevation = asin (_weaponDir select 2); - } else { - //Valid range, will fire at camera dir - private _lookVector = ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL)) vectorFromTo ((positionCameraToWorld [0,0,10]) call EFUNC(common,positionToASL)); - _realAzimuth = ((_lookVector select 0) atan2 (_lookVector select 1)); - private _upVectorDir = (((vectorUp _mortarVeh) select 0) atan2 ((vectorUp _mortarVeh) select 1)); - private _elevationDiff = (cos (_realAzimuth - _upVectorDir)) * acos ((vectorUp _mortarVeh) select 2); - _realElevation = ((180 / PI) * (_mortarVeh animationPhase "mainGun")) + 75 - _elevationDiff; - }; + // Get aiming values from ace_artillerytables + // Note: it also handles displaying the "charge" level + private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; + private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; //Update Heading Display: if (_notGunnerView || (!GVAR(allowCompass))) then { @@ -102,13 +75,10 @@ if (_lastFireMode != -1) then { }; }; - //Update CurrentElevation Display and "charge" text + //Update CurrentElevation Display if (_notGunnerView) then { - (_display displayCtrl 80085) ctrlSetStructuredText parseText ""; (_display displayCtrl 80175) ctrlSetText ""; } else { - (_display displayCtrl 80085) ctrlSetStructuredText parseText _chargeText; - if (_useMils) then { (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); } else { diff --git a/addons/mk6mortar/functions/fnc_moduleInit.sqf b/addons/mk6mortar/functions/fnc_moduleInit.sqf index 3158236859..ab4b4e8965 100644 --- a/addons/mk6mortar/functions/fnc_moduleInit.sqf +++ b/addons/mk6mortar/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Loads settings from the module. @@ -17,7 +17,7 @@ * Public: No */ -params ["_logic", "_syncedUnits", "_activated"]; +params ["_logic", "", "_activated"]; if (!_activated) exitWith {WARNING("Module - placed but not active");}; diff --git a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf index 1a5d5bf9a6..24bd4f9ad3 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Can player open 82mm rangetable. diff --git a/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf b/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf index f55e2bcd99..7b350804f1 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Opens the rangetable and fills the charge listbox. @@ -15,32 +15,6 @@ * Public: No */ -#define LIST_CHARGE ((uiNamespace getVariable "ACE_82mm_RangeTable_Dialog") displayCtrl 1501) +TRACE_1("rangeTableOpen - defer to artillerytables",_this); -private _weaponName = "mortar_82mm"; //todo: work on other weapons - -createDialog "ACE_82mm_RangeTable_Dialog"; -if (isNull (uiNamespace getVariable ["ACE_82mm_RangeTable_Dialog", displayNull])) exitWith {ERROR("Dialog failed to open");}; - -//Get Magazine Types -private _magazines = getArray (configFile >> "CfgWeapons" >> _weaponName >> "magazines"); - -//For now just get settings from first mag, all rounds have same flight characteristics: -if ((count _magazines) < 1) exitWith {ERROR("No Magazines for weapon");}; -private _initSpeed = getNumber (configFile >> "CfgMagazines" >> (_magazines select 0) >> "initSpeed"); - -//Get Charge Modes -private _fireModes = getArray (configFile >> "CfgWeapons" >> _weaponName >> "modes"); - -private _muzzleVelocities = []; -{ - private _showToPlayer = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "showToPlayer"); - if (_showToPlayer == 1) then { - private _artilleryCharge = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "artilleryCharge"); - LIST_CHARGE lbAdd format ["%1: %2", (localize LSTRING(rangetable_charge)), (count _muzzleVelocities)]; - LIST_CHARGE lbSetData [(count _muzzleVelocities), str (_artilleryCharge * _initSpeed)]; - _muzzleVelocities pushBack _artilleryCharge; - }; -} forEach _fireModes; - -LIST_CHARGE lbSetCurSel 0; +["mortar_82mm", 45, 88, GVAR(airResistanceEnabled) || EGVAR(artillerytables,advancedCorrections)] call EFUNC(artillerytables,rangeTableOpen); diff --git a/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf b/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf deleted file mode 100644 index 84bb2fba05..0000000000 --- a/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf +++ /dev/null @@ -1,35 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * Called when listbox selection changes. Updates the rangetable with new values. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_mk6mortar_fnc_rangeTablePageChange - * - * Public: No - */ - -#define RANGE_TABLE ((uiNamespace getVariable "ACE_82mm_RangeTable_Dialog") displayCtrl 20001) -#define LIST_CHARGE ((uiNamespace getVariable "ACE_82mm_RangeTable_Dialog") displayCtrl 1501) - -private _listBoxData = LIST_CHARGE lbData (lbCurSel LIST_CHARGE); -if (isNil "_listBoxData" || {_listBoxData == ""}) exitWith {ERROR("lbCurSel out of bounds or no data");}; -private _muzzleVelocity = parseNumber _listBoxData; - -private _airFriction = if (GVAR(airResistanceEnabled)) then {MK6_82mm_AIR_FRICTION} else {0}; - -private _precalcArray = [_muzzleVelocity, _airFriction] call FUNC(rangeTablePreCalculatedValues); - -lnbClear RANGE_TABLE; -{ - RANGE_TABLE lnbAddRow _x; -} forEach _precalcArray; - -//put dummy line at end because scrolling is fucked and can't see last line -RANGE_TABLE lnbAddRow ["", "", "", "", "", "", "", "", "", "", ""]; diff --git a/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf b/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf deleted file mode 100644 index 7a219e5535..0000000000 --- a/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf +++ /dev/null @@ -1,271 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * Simple Lookup Table for various muzzle velocities and air frictions. - * Use ace_mk6mortar_fnc_dev_buildTable to build - * - * Arguments: - * 0: Muzzle Velocity - * 1: Air Friction - * - * Return Value: - * Array - * - * Example: - * [200, 0] call ace_mk6mortar_fnc_rangeTablePreCalculatedValues - * - * Public: No - */ - -params ["_muzzleVelocity", "_airFriction"]; - -switch (true) do { - -case ((abs(_muzzleVelocity - 70) < 0.00001) && {(abs(_airFriction - -0.0001) < 0.00001)}): { - [ - ["100","1493","9","1.4","14.0","3.7","0.4","-0.3","0.0","0.0","0.0","0.0"], - ["150","1438","14","1.4","13.9","2.5","0.4","-0.4","0.0","0.0","-0.1","0.0"], - ["200","1381","20","1.4","13.8","1.9","0.5","-0.4","0.0","0.0","-0.1","0.1"], - ["250","1321","27","1.5","13.6","1.5","0.5","-0.4","0.0","0.0","-0.1","0.1"], - ["300","1256","36","1.6","13.3","1.3","0.6","-0.5","0.0","-0.1","-0.1","0.1"], - ["350","1183","49","1.7","12.9","1.1","0.6","-0.5","0.1","-0.1","-0.1","0.1"], - ["400","1097","70","1.9","12.4","0.9","0.6","-0.5","0.1","-0.1","-0.2","0.1"], - ["450","979","113","2.3","11.6","0.8","0.6","-0.5","0.1","-0.1","-0.2","0.2"] - ] - }; -case ((abs(_muzzleVelocity - 140) < 0.00001) && {(abs(_airFriction - -0.0001) < 0.00001)}): { - [ - ["150","1556","1","0.8","27.2","16.3","2.5","-2.4","0.0","0.0","-0.2","0.2"], - ["200","1541","1","0.8","27.2","12.3","2.5","-2.4","0.0","0.0","-0.3","0.2"], - ["250","1527","2","0.8","27.2","9.9","2.6","-2.4","0.0","0.0","-0.3","0.3"], - ["300","1512","2","0.8","27.2","8.3","2.7","-2.4","0.1","0.0","-0.4","0.4"], - ["350","1497","3","0.8","27.1","7.1","2.7","-2.5","0.0","-0.1","-0.5","0.4"], - ["400","1482","3","0.8","27.1","6.2","2.7","-2.5","0.1","-0.1","-0.5","0.5"], - ["450","1467","3","0.8","27.0","5.6","2.8","-2.5","0.1","-0.1","-0.6","0.6"], - ["500","1451","4","0.8","27.0","5.0","2.9","-2.6","0.1","-0.1","-0.6","0.6"], - ["550","1436","4","0.8","26.9","4.6","2.9","-2.6","0.1","-0.1","-0.7","0.7"], - ["600","1420","5","0.8","26.8","4.2","3.0","-2.7","0.1","-0.1","-0.8","0.8"], - ["650","1404","5","0.8","26.8","3.9","3.0","-2.7","0.1","-0.1","-0.9","0.8"], - ["700","1388","6","0.8","26.7","3.6","3.1","-2.8","0.1","-0.1","-0.9","0.9"], - ["750","1372","6","0.8","26.6","3.4","3.2","-2.8","0.1","-0.1","-1.0","1.0"], - ["800","1355","7","0.8","26.5","3.2","3.2","-2.9","0.1","-0.1","-1.1","1.1"], - ["850","1338","8","0.8","26.4","3.0","3.3","-2.9","0.1","-0.1","-1.1","1.1"], - ["900","1321","8","0.8","26.2","2.8","3.4","-3.0","0.1","-0.1","-1.2","1.2"], - ["950","1303","9","0.9","26.1","2.7","3.4","-3.1","0.1","-0.2","-1.3","1.2"], - ["1000","1285","10","0.9","26.0","2.6","3.5","-3.1","0.2","-0.1","-1.4","1.3"], - ["1050","1266","11","0.9","25.8","2.4","3.5","-3.2","0.1","-0.2","-1.4","1.4"], - ["1100","1247","12","0.9","25.7","2.3","3.6","-3.3","0.1","-0.2","-1.5","1.4"], - ["1150","1228","13","0.9","25.5","2.2","3.7","-3.3","0.2","-0.2","-1.6","1.5"], - ["1200","1207","14","1.0","25.3","2.1","3.7","-3.4","0.2","-0.2","-1.7","1.6"], - ["1250","1186","15","1.0","25.1","2.0","3.8","-3.4","0.2","-0.2","-1.7","1.7"], - ["1300","1163","17","1.0","24.8","1.9","3.8","-3.5","0.2","-0.2","-1.8","1.7"], - ["1350","1140","19","1.0","24.6","1.9","3.9","-3.5","0.2","-0.2","-1.9","1.8"], - ["1400","1115","21","1.1","24.3","1.8","3.9","-3.6","0.2","-0.2","-1.9","1.9"], - ["1450","1088","24","1.1","23.9","1.7","4.0","-3.6","0.2","-0.2","-2.0","1.9"], - ["1500","1060","27","1.2","23.6","1.6","4.0","-3.7","0.2","-0.2","-2.1","2.0"], - ["1550","1028","32","1.3","23.1","1.5","4.0","-3.7","0.2","-0.2","-2.1","2.1"], - ["1600","991","38","1.4","22.6","1.5","4.0","-3.7","0.2","-0.2","-2.2","2.1"], - ["1650","947","49","1.7","21.9","1.4","4.0","-3.7","0.2","-0.3","-2.3","2.2"], - ["1700","888","71","2.1","21.0","1.3","3.9","-3.6","0.3","-0.3","-2.3","2.2"] - ] - }; -case ((abs(_muzzleVelocity - 200) < 0.00001) && {(abs(_airFriction - -0.0001) < 0.00001)}): { - [ - ["250","1559","1","0.6","37.3","23.8","6.1","-5.9","0.0","0.0","-0.6","0.5"], - ["300","1551","1","0.6","37.3","20.0","6.1","-5.9","0.1","0.0","-0.7","0.7"], - ["350","1543","1","0.6","37.3","17.2","6.2","-5.9","0.0","-0.1","-0.8","0.7"], - ["400","1535","1","0.6","37.3","15.1","6.2","-5.9","0.1","0.0","-0.9","0.9"], - ["450","1527","1","0.6","37.3","13.4","6.3","-6.0","0.1","-0.1","-1.0","1.0"], - ["500","1519","1","0.6","37.2","12.1","6.3","-6.0","0.1","-0.1","-1.1","1.1"], - ["550","1510","1","0.6","37.2","11.0","6.4","-6.0","0.1","-0.1","-1.3","1.2"], - ["600","1502","1","0.6","37.2","10.1","6.4","-6.1","0.1","-0.1","-1.4","1.3"], - ["650","1494","1","0.6","37.2","9.4","6.5","-6.1","0.1","-0.1","-1.5","1.4"], - ["700","1485","2","0.6","37.1","8.7","6.5","-6.2","0.1","-0.1","-1.6","1.5"], - ["750","1477","2","0.6","37.1","8.2","6.6","-6.2","0.1","-0.1","-1.7","1.6"], - ["800","1468","2","0.6","37.0","7.7","6.7","-6.3","0.1","-0.1","-1.8","1.8"], - ["850","1460","2","0.6","37.0","7.2","6.7","-6.3","0.1","-0.1","-2.0","1.9"], - ["900","1451","2","0.6","37.0","6.8","6.8","-6.4","0.1","-0.1","-2.1","2.0"], - ["950","1443","2","0.6","36.9","6.5","6.9","-6.4","0.1","-0.1","-2.2","2.1"], - ["1000","1434","2","0.6","36.9","6.2","6.9","-6.5","0.1","-0.1","-2.3","2.2"], - ["1050","1425","2","0.6","36.8","5.9","7.0","-6.6","0.1","-0.2","-2.5","2.3"], - ["1100","1417","3","0.6","36.8","5.6","7.1","-6.6","0.1","-0.2","-2.6","2.4"], - ["1150","1408","3","0.6","36.7","5.4","7.1","-6.7","0.2","-0.2","-2.7","2.5"], - ["1200","1399","3","0.6","36.6","5.2","7.2","-6.7","0.2","-0.2","-2.8","2.7"], - ["1250","1390","3","0.6","36.6","5.0","7.3","-6.8","0.2","-0.2","-2.9","2.8"], - ["1300","1381","3","0.6","36.5","4.8","7.4","-6.9","0.2","-0.2","-3.0","2.9"], - ["1350","1372","3","0.6","36.4","4.6","7.4","-6.9","0.2","-0.2","-3.2","3.0"], - ["1400","1362","4","0.6","36.4","4.4","7.5","-7.0","0.2","-0.2","-3.3","3.1"], - ["1450","1353","4","0.6","36.3","4.3","7.6","-7.1","0.2","-0.2","-3.4","3.2"], - ["1500","1344","4","0.6","36.2","4.2","7.7","-7.1","0.2","-0.2","-3.5","3.4"], - ["1550","1334","4","0.6","36.1","4.0","7.7","-7.2","0.2","-0.2","-3.7","3.5"], - ["1600","1324","4","0.6","36.0","3.9","7.8","-7.3","0.2","-0.2","-3.8","3.6"], - ["1650","1314","4","0.7","35.9","3.8","7.9","-7.3","0.2","-0.2","-3.9","3.7"], - ["1700","1304","5","0.7","35.8","3.7","7.9","-7.4","0.2","-0.2","-4.0","3.8"], - ["1750","1294","5","0.7","35.7","3.6","8.0","-7.5","0.2","-0.2","-4.2","3.9"], - ["1800","1284","5","0.7","35.6","3.5","8.1","-7.6","0.2","-0.3","-4.3","4.0"], - ["1850","1274","5","0.7","35.5","3.4","8.2","-7.6","0.2","-0.3","-4.4","4.2"], - ["1900","1263","6","0.7","35.4","3.3","8.2","-7.7","0.2","-0.3","-4.5","4.3"], - ["1950","1253","6","0.7","35.2","3.2","8.3","-7.8","0.2","-0.3","-4.7","4.4"], - ["2000","1242","6","0.7","35.1","3.1","8.4","-7.8","0.3","-0.3","-4.8","4.5"], - ["2050","1231","7","0.7","35.0","3.0","8.4","-7.9","0.3","-0.3","-4.9","4.7"], - ["2100","1219","7","0.7","34.8","2.9","8.5","-8.0","0.3","-0.3","-5.0","4.8"], - ["2150","1208","7","0.7","34.7","2.9","8.5","-8.0","0.3","-0.3","-5.2","4.9"], - ["2200","1196","8","0.7","34.5","2.8","8.6","-8.1","0.3","-0.3","-5.3","5.0"], - ["2250","1184","8","0.7","34.3","2.7","8.7","-8.2","0.3","-0.3","-5.4","5.1"], - ["2300","1171","9","0.8","34.2","2.7","8.7","-8.2","0.3","-0.3","-5.5","5.2"], - ["2350","1158","9","0.8","34.0","2.6","8.8","-8.3","0.3","-0.3","-5.7","5.4"], - ["2400","1145","10","0.8","33.8","2.5","8.8","-8.3","0.3","-0.3","-5.8","5.5"], - ["2450","1132","10","0.8","33.6","2.5","8.9","-8.4","0.3","-0.3","-5.9","5.6"], - ["2500","1118","11","0.8","33.3","2.4","8.9","-8.4","0.3","-0.3","-6.0","5.7"], - ["2550","1103","12","0.8","33.1","2.4","9.0","-8.5","0.3","-0.3","-6.1","5.8"], - ["2600","1088","13","0.9","32.8","2.3","9.0","-8.5","0.4","-0.3","-6.2","5.9"], - ["2650","1072","14","0.9","32.6","2.2","9.0","-8.6","0.4","-0.4","-6.4","6.0"], - ["2700","1056","15","0.9","32.3","2.2","9.0","-8.6","0.3","-0.4","-6.5","6.1"], - ["2750","1038","16","1.0","31.9","2.1","9.1","-8.6","0.4","-0.4","-6.6","6.3"], - ["2800","1020","18","1.0","31.6","2.1","9.1","-8.6","0.4","-0.4","-6.7","6.4"], - ["2850","1000","20","1.1","31.2","2.0","9.1","-8.6","0.4","-0.4","-6.8","6.5"], - ["2900","978","22","1.1","30.8","1.9","9.0","-8.6","0.4","-0.4","-6.9","6.5"], - ["2950","954","26","1.2","30.3","1.9","9.0","-8.6","0.4","-0.4","-7.0","6.6"], - ["3000","927","31","1.4","29.7","1.8","8.9","-8.5","0.4","-0.4","-7.1","6.7"], - ["3050","894","38","1.6","29.0","1.7","8.8","-8.4","0.4","-0.4","-7.2","6.8"], - ["3100","849","54","2.0","27.9","1.6","8.5","-8.3","0.4","-0.4","-7.2","6.8"] - ] - }; -case ((abs(_muzzleVelocity - 70) < 0.00001) && {(abs(_airFriction - 0) < 0.00001)}): { - [ - ["100","1497","9","1.3","14.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["150","1445","14","1.3","14.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["200","1390","19","1.4","14.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["250","1333","26","1.4","13.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["300","1272","34","1.5","13.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["350","1204","45","1.6","13.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["400","1127","61","1.8","12.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["450","1028","91","2.1","12.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"] - ] - }; -case ((abs(_muzzleVelocity - 140) < 0.00001) && {(abs(_airFriction - 0) < 0.00001)}): { - [ - ["150","1562","1","0.7","28.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["200","1549","1","0.7","28.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["250","1536","2","0.7","28.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["300","1523","2","0.7","28.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["350","1510","2","0.7","28.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["400","1497","3","0.7","28.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["450","1484","3","0.7","28.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["500","1471","3","0.7","28.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["550","1458","4","0.7","28.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["600","1445","4","0.7","28.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["650","1431","4","0.7","28.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["700","1418","5","0.7","28.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["750","1404","5","0.7","28.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["800","1390","6","0.7","27.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["850","1376","6","0.7","27.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["900","1362","6","0.8","27.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["950","1348","7","0.8","27.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1000","1333","7","0.8","27.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1050","1318","8","0.8","27.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1100","1303","9","0.8","27.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1150","1288","9","0.8","27.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1200","1272","10","0.8","27.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1250","1256","11","0.8","26.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1300","1239","12","0.8","26.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1350","1222","13","0.9","26.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1400","1205","13","0.9","26.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1450","1187","15","0.9","26.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1500","1168","16","0.9","26.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1550","1148","18","1.0","25.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1600","1127","19","1.0","25.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1650","1105","21","1.1","25.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1700","1082","24","1.1","24.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1750","1057","27","1.2","24.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1800","1029","31","1.3","24.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1850","997","37","1.4","23.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1900","960","46","1.6","23.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1950","912","63","1.9","22.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"] - ] - }; -case ((abs(_muzzleVelocity - 200) < 0.00001) && {(abs(_airFriction - 0) < 0.00001)}): { - [ - ["300","1563","0","0.5","40.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["350","1556","1","0.5","40.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["400","1550","1","0.5","40.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["450","1544","1","0.5","40.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["500","1537","1","0.5","40.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["550","1531","1","0.5","40.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["600","1525","1","0.5","40.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["650","1519","1","0.5","40.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["700","1512","1","0.5","40.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["750","1506","1","0.5","40.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["800","1499","1","0.5","40.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["850","1493","1","0.5","40.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["900","1487","1","0.5","40.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["950","1480","1","0.5","40.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1000","1474","2","0.5","40.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1050","1467","2","0.5","40.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1100","1461","2","0.5","40.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1150","1454","2","0.5","40.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1200","1448","2","0.5","40.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1250","1441","2","0.5","40.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1300","1435","2","0.5","40.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1350","1428","2","0.5","40.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1400","1422","2","0.5","40.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1450","1415","2","0.5","40.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1500","1408","2","0.5","40.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1550","1402","3","0.5","40.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1600","1395","3","0.5","40.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1650","1388","3","0.5","39.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1700","1381","3","0.5","39.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1750","1374","3","0.5","39.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1800","1367","3","0.5","39.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1850","1360","3","0.5","39.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1900","1353","3","0.5","39.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["1950","1346","4","0.5","39.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2000","1339","4","0.5","39.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2050","1332","4","0.5","39.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2100","1325","4","0.6","39.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2150","1317","4","0.6","39.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2200","1310","4","0.6","39.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2250","1302","4","0.6","39.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2300","1295","5","0.6","39.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2350","1287","5","0.6","38.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2400","1280","5","0.6","38.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2450","1272","5","0.6","38.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2500","1264","5","0.6","38.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2550","1256","5","0.6","38.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2600","1248","6","0.6","38.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2650","1240","6","0.6","38.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2700","1232","6","0.6","38.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2750","1223","6","0.6","38.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2800","1215","7","0.6","37.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2850","1206","7","0.6","37.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2900","1197","7","0.6","37.6","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["2950","1188","7","0.7","37.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3000","1179","8","0.7","37.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3050","1170","8","0.7","37.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3100","1160","8","0.7","37.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3150","1151","9","0.7","36.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3200","1141","9","0.7","36.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3250","1131","10","0.7","36.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3300","1120","10","0.7","36.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3350","1109","11","0.8","36.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3400","1098","11","0.8","35.9","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3450","1087","12","0.8","35.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3500","1075","13","0.8","35.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3550","1062","14","0.8","35.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3600","1049","15","0.9","35.0","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3650","1036","16","0.9","34.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3700","1021","17","0.9","34.4","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3750","1006","19","1.0","34.1","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3800","990","21","1.1","33.7","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3850","971","24","1.1","33.3","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3900","952","27","1.2","32.8","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["3950","929","32","1.4","32.2","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["4000","900","40","1.6","31.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"], - ["4050","861","56","2.1","30.5","0.0","0.0","0.0","0.0","0.0","0.0","0.0"] - ] - }; - default { - ERROR("MuzzleVelocity not found in LUT"); - [] - }; -}; diff --git a/addons/mk6mortar/functions/fnc_toggleMils.sqf b/addons/mk6mortar/functions/fnc_toggleMils.sqf index a2c2a29789..0207054451 100644 --- a/addons/mk6mortar/functions/fnc_toggleMils.sqf +++ b/addons/mk6mortar/functions/fnc_toggleMils.sqf @@ -1,11 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Toggles the mortart to show mils or degrees * * Arguments: * 0: Vehicle - * 1: Player * * Return Value: * None @@ -16,7 +15,8 @@ * Public: No */ -params ["_mortarVeh", "_unit"]; +params ["_mortarVeh"]; +TRACE_1("toggleMils",_mortarVeh); private _currentSetting = _mortarVeh getVariable [QGVAR(useMils), true]; _mortarVeh setVariable [QGVAR(useMils), (!_currentSetting)]; diff --git a/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf b/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf index aa2e9f2823..a800755357 100644 --- a/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf +++ b/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Called when the mk6's in game UI is loaded. Hides rangefinder data if it is disabled. @@ -19,7 +19,7 @@ disableSerialization; params ["_display", "_rscType"]; -TRACE_2("params",_display,_rscType); +TRACE_2("turretDisplayLoaded",_display,_rscType); if (_rscType != "Mk6Mortar") exitWith {}; if (isNull _display) exitWith {}; diff --git a/addons/mk6mortar/functions/script_component.hpp b/addons/mk6mortar/functions/script_component.hpp deleted file mode 100644 index 9980d4fc88..0000000000 --- a/addons/mk6mortar/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\mk6mortar\script_component.hpp" \ No newline at end of file diff --git a/addons/mk6mortar/initKeybinds.inc.sqf b/addons/mk6mortar/initKeybinds.inc.sqf new file mode 100644 index 0000000000..0e3a53c1d9 --- /dev/null +++ b/addons/mk6mortar/initKeybinds.inc.sqf @@ -0,0 +1,15 @@ +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +["ACE3 Equipment", QGVAR(rangetable_action), LLSTRING(rangetable_action), { + if ( + !([ACE_player, "ACE_RangeTable_82mm"] call EFUNC(common,hasItem)) || + !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) + ) exitWith {false}; + + // Close previously opened dialogs + closeDialog 0; + + // Statement + [] call FUNC(rangeTableOpen); + true +}] call CBA_fnc_addKeybind; // Unbound diff --git a/addons/mk6mortar/initSettings.inc.sqf b/addons/mk6mortar/initSettings.inc.sqf new file mode 100644 index 0000000000..fc90029562 --- /dev/null +++ b/addons/mk6mortar/initSettings.inc.sqf @@ -0,0 +1,43 @@ +// These settings effect gameplay difficutly: defaults will leave the mortar the same as vanilla + +private _category = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art"], localize LSTRING(DisplayName)]; + +[ + QGVAR(airResistanceEnabled), "CHECKBOX", + [LSTRING(airResistanceEnabled_DisplayName), LSTRING(airResistanceEnabled_Description)], + _category, + false, // default value + true, // isGlobal + {[QGVAR(airResistanceEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(allowComputerRangefinder), "CHECKBOX", + [LSTRING(allowComputerRangefinder_DisplayName), LSTRING(allowComputerRangefinder_Description)], + _category, + true, // default value + true, // isGlobal + {[QGVAR(allowComputerRangefinder), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(allowCompass), "CHECKBOX", + [LSTRING(allowCompass_DisplayName), LSTRING(allowCompass_Description)], + _category, + true, // default value + true, // isGlobal + {[QGVAR(allowCompass), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(useAmmoHandling), "CHECKBOX", + [LSTRING(useAmmoHandling_DisplayName), LSTRING(useAmmoHandling_Description)], + _category, + false, // default value + true, // isGlobal + {[QGVAR(useAmmoHandling), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index 24f846eaea..4195579998 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -5,49 +5,52 @@ 82mm Rangetable 82mm Distanztabelle Tabela strzelnicza 82mm - Table de tir 82mm + Table de tir 82 mm 82 мм Таблица дальностей и прицелов Tabla de distancias de 82mm 82mm hatótáv-tábla Tabela de distâncias de para 82mm 82mm Rangetable Tavola di tiro 82mm - 82mm 射表 + 82mm用 射表 82mm 사거리표 - 82mm迫击炮射表 - 82mm迫擊炮射表 + 82 mm 迫击炮射表 + 82毫米迫擊炮射表 + 82mm Menzil Tablosu Range Table for the Mk6 82mm Mortar Distanztabelle für den Mk6 82mm Mortar Tabela strzelnicza dla moździerza 82mm Mk6 - Table de tir pour le mortier Mk6 82mm + Table de tir pour le mortier Mk6 82 mm. Таблица дальностей и прицелов для Mk6 82 мм мортиры Tabla de distancias para el mortero Mk6 de 82mm Hatótáv-tábla a Mk6 82mm-es mozsárhoz Tabela de distâncias para morteiro Mk6 82mm Rangetable pro Mk6 82mm minomet - Tavola di tiro per il mortaio calibro 82mm Mk6 - Mk6 82mm 迫撃砲の射表 + Tavola di tiro per il mortaio Mk6 di calibro 82mm + Mk6 82mm迫撃砲専用の射撃表 Mk6 82mm 박격포 사격을 위한 사거리표 - MK6 82mm迫击炮射表 - MK6 82mm迫擊炮射表 + MK6 82 mm 迫击炮射表 + MK6 82毫米迫擊炮射表 + Mk6 82mm için Menzil Tablosu Open 82mm Rangetable Öffne 82mm Distanztabelle Otwórz tabelę strzelniczą 82mm - Ouvrir la table de tir 82mm + Ouvrir la table de tir 82 mm Открыть 82 мм Таблицу дальностей и прицелов Abrir tabla de distancias de 82mm 82mm hatótáv-tábla megnyitása Abrir tabela de distâncias para 82mm Otevřít 82mm Rangetable Apri la tavola di tiro 82mm - 82mm 射表を開く + 82mm用射表を開く 82mm 사거리표 열기 - 开启82mm迫击炮射表 - 開啟82mm迫擊炮射表 + 开启82 mm 迫击炮射表 + 開啟82毫米迫擊炮射表 + 82mm Menzil Tablosunu Aç Charge @@ -64,17 +67,23 @@ 장약 装药 裝藥 + Yükle Mk6 Mortar Mk6 Mörser Mortaio Mk6 MK6迫擊炮 - MK6迫击炮 + MK6 迫击炮 Mk6 迫撃砲 Mortier Mk6 Moździerz Mk6 Миномет Mk6 + Morteiro Mk6 + Minomet Mk6 + Mk6 Havan + Mortero MK6 + Mk6 박격포 Mk6 Settings @@ -83,14 +92,15 @@ Mk6-Einstellungen Mk6 - Nastavení Ajustes do Mk6 - Option du Mk6 + Paramètres du Mk6 Mk6 beállítások Настройки Mk6 Impostazioni Mk6 Mk6 設定 Mk6 설정 - MK6设定 + MK6 设定 MK6設定 + Mk6 Ayarları Air Resistance @@ -107,6 +117,7 @@ 공기저항 空气阻力 空氣阻力 + Hava Direnci For Player Shots, Model Air Resistance and Wind Effects @@ -115,12 +126,12 @@ Für Spielerschüsse, Luftwiderstand und Windeffekte Pro hráčovu střelbu, Model odporu vzduchu a povětrných podmínek Para disparos do jogador, modelo de resistência de ar e efeitos de vento - Pour les tirs de joueurs, modèle de résistance à l'air et d'effet du vent + Pour les tirs des joueurs, simule la résistance de l'air et les effets du vent. Játékos általi lövésekhez, legyen-e számított légellenállás és szélhatás Для выстрелов игрока. Моделирует сопротивление воздуха и эффект ветра Per Proiettili dei Giocatori, simula la Resistenza dell'Aria e gli Effetti del Vento - プレイヤが射撃すると、空気抵抗モデルと風による影響をあたえます。 - 플레이어 사격시 공기저항과 바람에 영향을 받습니다 + プレイヤーが射撃すると、空気抵抗モデルと風による影響をあたえます。 + 플레이어가 사격 시 공기저항과 바람에 영향을 받습니다 设定由玩家射击的迫击炮,将会受到空气阻力与风力的影响 設定由玩家射擊的迫擊砲,將會受到空氣阻力與風力的影響 @@ -131,14 +142,15 @@ Erlaube Mk6-Computer Mk6 - Povolit počítač Permitir computador do Mk6 - Autoriser l'ordinateur de tir pour Mk6 + Activer l'ordinateur de tir du Mk6 Mk6 számítógép engedélyezése Разрешить компьютер Mk6 Consenti Computer Mk6 - Mk6 コンピュータを許可 + Mk6の砲撃コンピュータを許可 Mk6 탄도계산컴퓨터 허가 - 允许使用MK6射控电脑 + 允许使用 MK6 弹道计算机 允許使用MK6射控電腦 + Mk6 bilgisayarına izin ver Show the Computer and Rangefinder (these NEED to be removed if you enable air resistance) @@ -147,13 +159,13 @@ Zeige den Computer und den Entfernungsmesser an (diese MÜSSEN entfernt werden, wenn der Luftwiderstand aktiviert ist) Zobrazit počítač a dálkoměr (toto MUSÍ být odstraněno pokud je zapnut odpor vzduchu) Mostra o computador e o medidor de distância (estes DEVEM ser removidos se você habilitar resistência do ar) - Affiche l'ordinateur de tir (cette option doit être DESACTIVEE si la résisance à l'air est activée) + Affiche l'ordinateur de tir et le télémètre. Cette option doit être DÉSACTIVÉE si la résistance de l'air est activée. A távmérő és számítógép megjelenítése (ezeket el KELL távolítani ha a légellenállás engedélyezve van) Показывает компьютер и дальномер (это НУЖНО отключить, если вы включаете сопротивление воздуха) - Mostra il Computer e Distaziometro (questi DEVONO essere rimossi se vuoi abilitare la resistenza dell'aria) - コンピュータと距離を表示します (空気抵抗を有効化している場合は必ず削除してください) - 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을경우 이 항목은 비활성화 되어야만 합니다) - 显示射控电脑和测距仪 (如果有启用空气阻力功能时,须停用此项功能) + Consenti l'utilizzo del Computer Balistico e del Telemetro (questi DEVONO essere disabilitati se vuoi abilitare la resistenza dell'aria) + 砲撃コンピュータと距離計を表示します (空気抵抗を有効化する場合はこれらを取り除く必要があります) + 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을 경우 이 항목은 비활성화 되어야 합니다) + 显示弹道计算机和测距仪(如果有启用空气阻力功能时,须停用此项功能) 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) @@ -162,15 +174,16 @@ Habilitar brujula del Mk6 Erlaube Mk6-Kompass Mk6 - Povolit kompas - Permitir bússula do Mk6 - Autoriser la boussole pour Mk6 + Permitir bússola do Mk6 + Activer la boussole du Mk6 Mk6 iránytű engedélyezése Разрешить компас Mk6 Consenti Bussola Mk6 - Mk6 への方位磁石を有効化 + Mk6の方位磁石を許可 Mk6 나침반 허용 - 允许使用MK6指北针 + 允许使用 MK6 指南针 允許使用MK6指北針 + Mk6 pusulasına izin ver Show the Mk6 Digital Compass @@ -178,15 +191,16 @@ Muestra la brujula digital en el Mk6 Zeige Mk6-Digitaler-Kompass Mk6 - Zobrazit digitální kompas - Mostra a bússula digital do Mk6 - Affiche la boussole digitale pour le Mk6 + Mostra a bússola digital do Mk6 + Affiche la boussole numérique du Mk6. Az Mk6 digitális iránytű megjelenítése Показывает цифровой компас Mk6 - Mostra la Bussola Digitale Mk6 - Mk6 のデジタル方位磁石を表示 + Mostra la Bussola Digitale del Mk6 + Mk6迫撃砲のデジタル方位磁石を表示します Mk6 에서 전자 나침반을 보여줍니다 - 显示MK6的数位指北针 + 显示 MK6 的电子指南针 顯示MK6的數位指北針 + Mk6 Dijital Pusulasını göster This module allows you to setup Mk6 mortar settings. @@ -195,12 +209,12 @@ Tento modul umožňuje nastavení minometu Mk6. Este módulo permite que você ajuste o morteiro Mk6. Модуль настройки миномета Mk6. - Ce module permet de régler les options du mortier Mk6 - Questo modulo ti consente di impostare i parametri del mortaio Mk6. + Ce module permet de régler les options du mortier Mk6. + Questo modulo ti consente di impostare le impostazioni del mortaio Mk6. Este módulo permite configurar los parámetros del mortero Mk6. - Mk6 迫撃砲への設定をできます。 + このモジュールでは、Mk6 迫撃砲の設定をセットアップできます。 이 모듈은 Mk6 설치 설정을 가능케 합니다. - 这个模块允许你设定MK6迫击炮的相关功能 + 这个模块允许你设定 MK6 迫击炮的相关功能 這個模塊允許你設定MK6迫擊砲的相關功能 @@ -211,40 +225,43 @@ Utiliser la gestion des munitions Utilizza la gestione delle munizioni Usar manejo de munição - Использовать манипуляции с боеприпасами + Манипуляции с боеприпасами 弾薬の取り扱い 탄약 관리 활성화 使用手动弹药装卸 使用手動彈藥裝卸 + Používat ruční manipulaci s municí Removes mortar magazines, requiring individual rounds to be loaded by the gunner or loader. Does not affect AI mortars. Enfernt das Magzin des Mörsers. Es ist nun erforderlich, die einzelnen Patronen manuell zu laden. Dies beeinflusst nicht die KI-Truppen. Elimina los cargadores del mortero, requiriendo al artillero o cargador la carga manual de cada rondas. No afecta morteros controlados por IA. Usuwa magazynki moździerza, wymagając ładowania pojedynczych pocisków przez strzelca lub ładowniczego. Nie dotyczy moździerzy AI. - Enlever les chargeurs de mortier, requiert des obus individuels qui doivent être chargés par le tireur ou le servant. N'affect pas les mortiers IA. - Toglie i proiettili dal mortaio. I colpi singoli devono essere caricati dall'operatore. Non cambia quado l'IA spara. + Enlève les chargeurs de mortier, ce qui oblige le tireur ou le servant à charger les obus manuellement. N'affecte pas les mortiers IA. + Rimuove i caricatori di colpi dal mortaio. Un operatore dovrà caricare proiettili singoli prima di poter fare fuoco. Non viene applicato su operatori IA. Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. - Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжащим. Не влияет на артиллерию ИИ. - 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI 迫撃砲へ影響を与えません。 - 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야만 합니다. 인공지능은 영향을 받지 않습니다. - 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由AI射击的迫击炮 + Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. Не влияет на артиллерию ИИ. + 迫撃砲から弾倉を除去します。一発ずつ射手か装填手によって装填される必要があります。AIの迫撃砲には影響を与えません。 + 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. 인공지능은 영향을 받지 않습니다. + 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由 AI 射击的迫击炮 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 + Odstraní z minometu zásobník a vynucuje nabíjení po každém výstřelu buď mířičem nebo nabíječem. Tato možnost neovlivňuje AI posádky. Remove Round Entferne Patrone Extraer ronda Wyładuj pocisk - Enlever l'obus + Retirer l'obus Togli proiettile Odstranit náboj Remover munição Извлечь снаряд - 弾薬を除去 + 砲弾を取り除く 탄약 제거 卸除弹头 卸除彈頭 + Mermiyi Boşalt Load Mortar @@ -256,10 +273,11 @@ Nabít minomet Carregar morteiro Зарядить миномет - 弾薬を装填 + 砲弾を装填 탄약 장전 装载弹头 裝載彈頭 + Havanı Yükle Unloading Round @@ -267,13 +285,15 @@ Descargando ronda Rozładowywanie moździerza Déchargement de l'obus - Scarica proiettile + Togliendo Proiettile Descarregar munição Извлечение снаряда - 弾薬を除去しています - 탄약 제거중 - 卸除弹头中 + 砲弾を取り除いています + 탄약 제거 중 + 正在卸除弹头 卸除彈頭中 + Vybít minomet + Mermi Boşaltılıyor Preparing Round @@ -281,14 +301,15 @@ Preparando ronda Przygotowywanie pocisku Praparation de l'obus - Prepara il proiettile + Caricando Proiettile Připavuji náboj Preparar munição Подготовка снаряда - 砲弾を事前装填 - 탄약 준비중 - 准备弹头中 + 砲弾を準備 + 탄약 준비 중 + 正在准备弹头 準備彈頭中 + Mermi Hazırlanıyor Load HE @@ -296,14 +317,15 @@ Cargar HE Załaduj pocisk wybuchowy Charger HE - Carica proiettile esplosivo ad alto potenziale (HE) + Carica Proiettile Esplosivo (HE) Nabít HE Carregar HE Зарядить фугасный - りゅう弾を装填 + 榴弾を装填 고폭탄 장전 装载高爆弹 裝載高爆彈 + HE Yükle Load Smoke @@ -311,7 +333,7 @@ Cargar Humo Załaduj pocisk dymny Charger Fumigène - Carica fumogeno + Carica Proiettile Fumogeno Nabít Dýmovnici Carregar Fumaça Зарядить дымовой @@ -319,14 +341,15 @@ 연막탄 장전 装载烟雾弹 裝載煙霧彈 + Sis Yükle Load Illumination Lade Leuchtpatrone Cargar Iluminación Załaduj pocisk oświetlający - Charger Eclairante - Carica illuminante + Charger Éclairant + Carica Proiettile Illuminante Nabít Světlici Carregar Iluminação Зарядить осветительный @@ -334,6 +357,7 @@ 조명탄 장전 装载照明弹 裝載照明彈 + Aydınlatma Yükle Load Guided HE @@ -341,14 +365,15 @@ Cagar HE Guiada Załaduj kierowany pocisk wybuchowy Charger HE guidé - Carica HE guidata + Carica Proiettile Esplosivo (HE) Guidato Nabít HE (Naváděné) Carregar HE Guiada Зарядить фугасный управляемый - 誘導りゅう弾を装填 + 誘導榴弾を装填 유도 고폭탄 장전 - 装载导引高爆弹 + 装载制导高爆弹 裝載導引高爆彈 + Güdümlü HE Yükle Load Laser Guided HE @@ -356,103 +381,109 @@ Cargar HE Guiada por Laser Załaduj laserowo napr. pocisk wybuchowy Charger HE guidé au laser - Carica HE a guida laser + Carica Proiettile Esplosivo (HE) Laserguidato Nabít HE (Naváděné laserem) Carregar HE Guiada por Laser Зарядить фугасный управляемый по ЛЦУ - レーザ誘導りゅう弾を装填 + レーザー誘導榴弾を装填 레이저 유도 고폭탄 장전 - 装载雷射导引高爆弹 + 装填激光制导高爆弹 裝載雷射導引高爆彈 + Lazer Güdümlü HE Yükle - 82mm HE Round - 82mm Sprengpatrone - Ronda 82mm HE - Pocisk wybuchowy kal. 82mm - Obus de 82mm HE - Proiettile da 82mm HE - 82mm HE náboj - Munição 82mm HE - Фугасный снаряд 82мм - 82mm りゅう弾 - 82mm 고폭탄 - 82mm高爆弹 - 82mm高爆彈 + [CSW] 82mm HE Round + [CSW] 82mm Sprengpatrone + [CSW] Ronda 82mm HE + [CSW] Pocisk wybuchowy kal. 82mm + [CSW] Obus de 82 mm HE + [CSW] Proiettile da 82mm HE + [CSW] 82mm HE náboj + [CSW] Munição 82mm HE + [CSW] Фугасный снаряд 82мм + [CSW] 82mm 榴弾 + [CSW] 82mm 고폭탄 + [班组] 82 mm 高爆弹 + [CSW] 82毫米高爆彈 + [CSW] 82mm HE Mermisi - 82mm Smoke Round - 82mm Nebelpatrone - Ronda 82mm Humo - Pocisk dymny kal. 82mm - Obus de 82mm fumigène - Proiettile Fumogeno da 82mm - 82mm Kouřový náboj - Munição 82mm Fumaça - Дымовой снаряд 82мм - 82mm 発煙弾 - 82mm 연막탄 - 82mm烟雾弹 - 82mm煙霧彈 + [CSW] 82mm Smoke Round + [CSW] 82mm Nebelpatrone + [CSW] Ronda 82mm Humo + [CSW] Pocisk dymny kal. 82mm + [CSW] Obus de 82 mm fumigène + [CSW] Proiettile da 82mm Fumogeno + [CSW] 82mm Kouřový náboj + [CSW] Munição 82mm Fumaça + [CSW] Дымовой снаряд 82мм + [CSW] 82mm 発煙弾 + [CSW] 82mm 연막탄 + [班组] 82 mm 烟雾弹 + [CSW] 82毫米煙霧彈 + [CSW] 82mm Sis Mermisi - 82mm Illumination Round - 82mm Leuchtpatrone - Ronda 82mm Iluminación - Pocisk oświetlający kal. 82mm - Obus de 82mm éclairant - Proiettile illuminante da 82mm - 82mm Osvětlovací náboj - Munição 82mm Iluminação - Осветительный снаряд 82мм - 82mm 照明弾 - 82mm 조명탄 - 82mm照明弹 - 82mm照明彈 + [CSW] 82mm Illumination Round + [CSW] 82mm Leuchtpatrone + [CSW] Ronda 82mm Iluminación + [CSW] Pocisk oświetlający kal. 82mm + [CSW] Obus de 82 mm éclairant + [CSW] Proiettile da 82mm Illuminante + [CSW] 82mm Osvětlovací náboj + [CSW] Munição 82mm Iluminação + [CSW] Осветительный снаряд 82мм + [CSW] 82mm 照明弾 + [CSW] 82mm 조명탄 + [班组] 82 mm 照明弹 + [CSW] 82毫米照明彈 + [CSW] 82mm Işık Mermisi - 82mm Guided HE Round - 82mm gelenkte Sprengpatrone - Ronda 82mm Guiada - Kierowany pocisk wybuchowy kal. 82mm - Obus de 82mm HE guidé - Proiettile HE guidato - 82mm HE náboj (naváděný) - Munição 82mm HE Guiada - Фугасный снаряд управляемый 82мм - 82mm 誘導りゅう弾 - 82mm 유도 고폭탄 - 82mm导引高爆弹 - 82mm導引高爆彈 + [CSW] 82mm Guided HE Round + [CSW] 82mm gelenkte Sprengpatrone + [CSW] Ronda 82mm Guiada + [CSW] Kierowany pocisk wybuchowy kal. 82mm + [CSW] Obus de 82 mm HE guidé + [CSW] Proiettile da 82mm HE Guidato + [CSW] 82mm HE náboj (naváděný) + [CSW] Munição 82mm HE Guiada + [CSW] Фугасный снаряд управляемый 82мм + [CSW] 82mm 誘導榴弾 + [CSW] 82mm 유도 고폭탄 + [班组] 82 mm 制导高爆弹 + [CSW] 82毫米導引高爆彈 + [CSW] 82mm Güdümlü HE Mermisi - 82mm Laser Guided HE Round - 82mm lasergelenkte Sprengpatrone - Ronda 82mm Guiada por Laser - Laserowo napr. pocisk wybuchowy kal. 82mm - Obus de 82mm HE guidé au laser - Proiettile HE a guida laser - 82mm HE náboj (naváděný laserem) - Munição 82mm HE Guiada por Laser - Фугасный снаряд управляемый по ЛЦУ 82мм - 82mm レーザ誘導りゅう弾 - 82mm 레이저 유도 고폭탄 - 82mm雷射导引高爆弹 - 82mm雷射導引高爆彈 + [CSW] 82mm Laser Guided HE Round + [CSW] 82mm lasergelenkte Sprengpatrone + [CSW] Ronda 82mm Guiada por Laser + [CSW] Laserowo napr. pocisk wybuchowy kal. 82mm + [CSW] Obus de 82 mm HE guidé au laser + [CSW] Proiettile da 82mm HE Laserguidato + [CSW] 82mm HE náboj (naváděný laserem) + [CSW] Munição 82mm HE Guiada por Laser + [CSW] Фугасный снаряд управляемый по ЛЦУ 82мм + [CSW] 82mm レーザー誘導榴弾 + [CSW] 82mm 레이저 유도 고폭탄 + [班组] 82 mm 激光制导高爆弹 + [CSW] 82毫米雷射導引高爆彈 + [CSW] 82mm Lazer Güdümlü HE Mermisi - Used in Mk6 mortar - Wird im Mk6 Mörser verwendet + Used in Mk6 Mortar + Wird im Mk6-Mörser verwendet Usada en el mortero Mk6 Używany w moździerzu Mk6 - Utilisé dans le mortier Mk6 + Utilisé dans le mortier Mk6. Usato nel mortaio Mk6 Používá se u minometu Mk6 Usada no Morteiro MK6 Использовался в миномете Mk6 - Mk6 mortar で使います + Mk6 迫撃砲 で使用 Mk6 박격포에 사용됨 - 用于Mk6迫击炮 + 用于 Mk6 迫击炮 用於Mk6迫擊砲 @@ -460,60 +491,64 @@ [ACE] 82mm Sprengpatronenkiste [ACE] Caja de municiones 82mm HE [ACE] Skrzynka amunicji wybuchowej 82mm - [ACE] Obus de 82mm HE - [ACE] Scatola proiettili espolisvi ad alto potenziale (HE) da 82mm + [ACE] Obus de 82 mm HE + [ACE] Scatola Proiettili Esplosivi (HE) da 82mm [ACE] Bedna s municí (82mm HE) [ACE] Caixa de Munição 82mm HE [ACE] Ящик фугасных снарядов 82мм - [ACE] 82mm りゅう弾入り弾薬箱 + [ACE] 82mm 榴弾入り弾薬箱 [ACE] 82mm 고폭탄 상자 - [ACE] 82mm高爆弹药箱 - [ACE] 82mm高爆彈藥箱 + [ACE] 82 mm 高爆弹药箱 + [ACE] 82毫米高爆彈藥箱 + [ACE] 82mm HE Mermisi Kutusu [ACE] 82mm Smoke Rounds Box [ACE] 82mm Nebelpatronenkiste [ACE] Caja de municiones 82mm Humo [ACE] Skrzynka amunicji dymnej 82mm - [ACE] Obus de 82mm fumigène - [ACE] Scatola fumogeni da 82mm + [ACE] Obus de 82 mm fumigène + [ACE] Scatola Proiettili Fumogeni da 82mm [ACE] Bedna s municí (82mm Dýmovnice) [ACE] Caixa de Munição 82mm Fumaça [ACE] Ящик дымовых снарядов 82мм [ACE] 82mm 発煙弾入り弾薬箱 [ACE] 82mm 연막탄 상자 - [ACE] 82mm烟雾弹药箱 - [ACE] 82mm煙霧彈藥箱 + [ACE] 82 mm 烟雾弹药箱 + [ACE] 82毫米煙霧彈藥箱 + [ACE] 82mm Sis Mermisi Kutusu [ACE] 82mm Illumination Rounds Box [ACE] 82mm Leuchtpatronenkiste [ACE] Caja de municiones 82mm Iluminacion [ACE] Skrzynka amunicji oświetlającej 82mm - [ACE] Obus de 82mm éclairants - [ACE] Scatola illuminanti da 82mm + [ACE] Obus de 82 mm éclairants + [ACE] Scatola Proiettili Illuminanti da 82mm [ACE] Bedna s municí (82mm Světlice) [ACE] Caixa de Munição 82mm Iluminação [ACE] Ящик осветительных снарядов 82мм [ACE] 82mm 照明弾入り弾薬箱 [ACE] 82mm 조명탄 상자 - [ACE] 82mm照明弹药箱 - [ACE] 82mm照明彈藥箱 + [ACE] 82 mm 照明弹药箱 + [ACE] 82毫米照明彈藥箱 + [ACE] 82mm Işık Mermisi Kutusu [ACE] 82mm Default Loadout Box [ACE] 82mm Standardkiste [ACE] Caja de municiones 82mm por defecto [ACE] Skrzynka amunicji standardowej 82mm - [ACE] Obus de 82mm par défaut - [ACE] Scatola proiettili 82mm standard + [ACE] Obus de 82 mm par défaut + [ACE] Scatola Proiettili 82mm Misti [ACE] Bedna se standardní 82mm municí [ACE] Caixa de Munição 82mm Padrão [ACE] Ящик снарядов 82мм (стандартный) - [ACE] 82mm 保管箱 + [ACE] 82mm 標準砲弾セット入り弾薬箱 [ACE] 82mm 기본 장비 상자 - [ACE] 82mm预设弹药箱 - [ACE] 82mm預設彈藥箱 + [ACE] 82 mm 预设弹药箱 + [ACE] 82毫米預設彈藥箱 + [ACE] 82mm Varsayılan Teçhizat Kutusu diff --git a/addons/modules/CfgEventHandlers.hpp b/addons/modules/CfgEventHandlers.hpp index dc1da95f37..9675998bd4 100644 --- a/addons/modules/CfgEventHandlers.hpp +++ b/addons/modules/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class _ACE_modules { // using a _ so it is the first postInit to be executed - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/modules/README.md b/addons/modules/README.md index b13743b981..e490449dc3 100644 --- a/addons/modules/README.md +++ b/addons/modules/README.md @@ -2,10 +2,3 @@ ace_modules =========== Provides framework for module handling. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Glowbal](https://github.com/Glowbal) diff --git a/addons/modules/XEH_postInit.sqf b/addons/modules/XEH_postInit.sqf index c6892046fe..c391916f19 100644 --- a/addons/modules/XEH_postInit.sqf +++ b/addons/modules/XEH_postInit.sqf @@ -12,7 +12,7 @@ _logic hideObject true; if (_logic getVariable [QGVAR(initalized), false]) exitWith {}; - private _config = (configFile >> "CfgVehicles" >> _logicType); + private _config = configOf _logic; if !(isClass _config) exitWith {}; private _isGlobal = getNumber (_config >> "isGlobal") > 0; @@ -26,7 +26,7 @@ _function = missionNamespace getVariable _function; }; if (_isSingular && {_logicType in _uniqueModulesHandled}) then { //ToDo: should this be an exit? - WARNING_1("Module [%1] - More than 1 singular module placed", _logicType); + WARNING_1("Module [%1] - More than 1 singular module placed",_logicType); }; if (_isSingular) then {_uniqueModulesHandled pushBack _logicType;}; diff --git a/addons/modules/functions/fnc_moduleInit.sqf b/addons/modules/functions/fnc_moduleInit.sqf index 5e03aad13c..d722f9a69b 100644 --- a/addons/modules/functions/fnc_moduleInit.sqf +++ b/addons/modules/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * IV Treatment local callback diff --git a/addons/modules/functions/script_component.hpp b/addons/modules/functions/script_component.hpp deleted file mode 100644 index ffd50bc09b..0000000000 --- a/addons/modules/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\modules\script_component.hpp" diff --git a/addons/movement/CfgEventHandlers.hpp b/addons/movement/CfgEventHandlers.hpp index 6aee79933c..f6503c2479 100644 --- a/addons/movement/CfgEventHandlers.hpp +++ b/addons/movement/CfgEventHandlers.hpp @@ -1,23 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - }; -}; - -class Extended_DisplayLoad_EventHandlers { - class RscDisplayInventory { - ADDON = QUOTE(_this call FUNC(inventoryDisplayLoad)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/movement/README.md b/addons/movement/README.md index 658e4a357a..abf381552a 100644 --- a/addons/movement/README.md +++ b/addons/movement/README.md @@ -2,11 +2,3 @@ ace_movement ============ Various tweaks to movement animations. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/movement/XEH_PREP.hpp b/addons/movement/XEH_PREP.hpp index ceafa7f5dc..36fe97880d 100644 --- a/addons/movement/XEH_PREP.hpp +++ b/addons/movement/XEH_PREP.hpp @@ -3,4 +3,3 @@ PREP(canClimb); PREP(climb); PREP(handleClimb); PREP(handleVirtualMass); -PREP(inventoryDisplayLoad); diff --git a/addons/movement/XEH_postInit.sqf b/addons/movement/XEH_postInit.sqf index f64b92603b..4d7cc5ba12 100644 --- a/addons/movement/XEH_postInit.sqf +++ b/addons/movement/XEH_postInit.sqf @@ -3,8 +3,8 @@ if (!hasInterface) exitWith {}; -["unit", FUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; -["loadout", FUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; ["ACE3 Movement", QGVAR(climb), localize LSTRING(Climb), { // Conditions: canInteract diff --git a/addons/movement/functions/fnc_addLoadToUnitContainer.sqf b/addons/movement/functions/fnc_addLoadToUnitContainer.sqf index 5910f6c186..11dc6718a5 100644 --- a/addons/movement/functions/fnc_addLoadToUnitContainer.sqf +++ b/addons/movement/functions/fnc_addLoadToUnitContainer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Add (negative numbers to subtract) a virtual mass to a units container. diff --git a/addons/movement/functions/fnc_canClimb.sqf b/addons/movement/functions/fnc_canClimb.sqf index 808a81d582..d197afe4ed 100644 --- a/addons/movement/functions/fnc_canClimb.sqf +++ b/addons/movement/functions/fnc_canClimb.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Tests the the player can climb. diff --git a/addons/movement/functions/fnc_climb.sqf b/addons/movement/functions/fnc_climb.sqf index 2d5eb88786..04cbe7faac 100644 --- a/addons/movement/functions/fnc_climb.sqf +++ b/addons/movement/functions/fnc_climb.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Make the player climb over short walls. diff --git a/addons/movement/functions/fnc_handleClimb.sqf b/addons/movement/functions/fnc_handleClimb.sqf index 6f6c7b536b..1325f2f021 100644 --- a/addons/movement/functions/fnc_handleClimb.sqf +++ b/addons/movement/functions/fnc_handleClimb.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles the climb animation finishing. Called from "AnimDone" event handler. diff --git a/addons/movement/functions/fnc_handleVirtualMass.sqf b/addons/movement/functions/fnc_handleVirtualMass.sqf index 8f035cc5ad..6e50cebf00 100644 --- a/addons/movement/functions/fnc_handleVirtualMass.sqf +++ b/addons/movement/functions/fnc_handleVirtualMass.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Recalculate the units loadCoef to emulate a mass added to uniform, vest or backpack. diff --git a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf deleted file mode 100644 index d107bd70b1..0000000000 --- a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf +++ /dev/null @@ -1,35 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Executed every time an inventory display is opened. - * - * Arguments: - * 0: Inventory display - * - * Return Value: - * None - * - * Example: - * [DISPLAY] call ACE_movement_fnc_inventoryDisplayLoad - * - * Public: No - */ - -params ["_display"]; - -private _fnc_update = { - params ["_display"]; - private _control = _display displayCtrl 111; - - _control ctrlSetText format ["%1 - %2 %3 (%4)", - [ACE_player, false, true] call EFUNC(common,getName), - localize ELSTRING(common,Weight), - [ACE_player] call EFUNC(common,getWeight), - [ACE_player, true] call EFUNC(common,getWeight) - ]; -}; - -_display displayAddEventHandler ["MouseMoving", _fnc_update]; -_display displayAddEventHandler ["MouseHolding", _fnc_update]; - -_display call _fnc_update; diff --git a/addons/movement/functions/script_component.hpp b/addons/movement/functions/script_component.hpp deleted file mode 100644 index d33fa99b30..0000000000 --- a/addons/movement/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\movement\script_component.hpp" \ No newline at end of file diff --git a/addons/movement/stringtable.xml b/addons/movement/stringtable.xml index 45a3bf65c3..560d407f68 100644 --- a/addons/movement/stringtable.xml +++ b/addons/movement/stringtable.xml @@ -12,10 +12,11 @@ Mostrar peso em libras Súly megjelenítése fontban. Показывать вес в фунтах - ポンドで重量を表示する + ポンドで重量を表示 무게를 파운드(lb)로 보여줍니다 使用磅来显示重量 使用磅來顯示重量 + Ağırlığı lb olarak göster Climb @@ -28,10 +29,11 @@ Mászás Arrampicati Subir - 登る + よじ登る 오르기 攀爬 攀爬 + Tırman Can't climb here @@ -43,11 +45,12 @@ Здесь невозможно взобраться Itt nem tudsz mászni Non puoi arrampicarti qui - Não se pode subir aqui + Não pode subir aqui ここは登れません 这里无法攀爬 這裡無法攀爬 여기는 올라갈 수 없다 + Buraya tırmanamazsın diff --git a/addons/mx2a/CfgWeapons.hpp b/addons/mx2a/CfgWeapons.hpp index 7ff5943a88..66f775c2d8 100644 --- a/addons/mx2a/CfgWeapons.hpp +++ b/addons/mx2a/CfgWeapons.hpp @@ -15,7 +15,7 @@ class CfgWeapons { opticsZoomInit = 0.1; visionMode[] = {"Ti"}; thermalMode[] = {0,1}; - discretefov[] = {0.33333/1, 0.33333/2}; // 1x/2x -- http://www.drs.com/Products/RSTA/PDF/MX2A.pdf + discretefov[] = {"0.33333/1", "0.33333/2"}; // 1x/2x -- http://www.drs.com/Products/RSTA/PDF/MX2A.pdf discreteInitIndex = 0; discreteDistance[] = {120,400}; discreteDistanceInitIndex = 1; diff --git a/addons/mx2a/README.md b/addons/mx2a/README.md index f03edf1849..d3eb882348 100644 --- a/addons/mx2a/README.md +++ b/addons/mx2a/README.md @@ -2,10 +2,3 @@ ace_mx2a ========== Adds the MX-2A thermal imaging device. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/mx2a/stringtable.xml b/addons/mx2a/stringtable.xml index 099a8e7703..fd7a76d6fa 100644 --- a/addons/mx2a/stringtable.xml +++ b/addons/mx2a/stringtable.xml @@ -14,8 +14,9 @@ MX-2A MX-2A MX-2A - MX-2A(热成像) + MX-2A(热成像) MX-2A + MX-2A Thermal imaging device @@ -28,10 +29,11 @@ Hőleképező készülék Тепловизионный прибор Dispositivo di visione termica - サーマル画像表示双眼鏡 - 열영상 장치 + 熱画像表示装置 + 열화상 장치 热成像装置 熱成像裝置 + Termal Görüntüleme Aracı diff --git a/addons/nametags/ACE_Settings.hpp b/addons/nametags/ACE_Settings.hpp index 5b5d7b79cc..452005ae3d 100644 --- a/addons/nametags/ACE_Settings.hpp +++ b/addons/nametags/ACE_Settings.hpp @@ -3,74 +3,30 @@ class ACE_Settings { movedToSQF = 1; }; class GVAR(showPlayerNames) { - value = 1; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(ShowPlayerNames); - description = CSTRING(ShowPlayerNames_Desc); - values[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled), CSTRING(OnlyCursor), CSTRING(OnlyKeypress), CSTRING(OnlyCursorAndKeypress), CSTRING(FadeOnBorder)}; - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; class GVAR(showPlayerRanks) { - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(ShowPlayerRanks); - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; class GVAR(showVehicleCrewInfo) { - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(ShowVehicleCrewInfo); - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; class GVAR(showNamesForAI) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(ShowNamesForAI); - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; class GVAR(showCursorTagForVehicles) { - displayName = CSTRING(showCursorTagForVehicles_DisplayName); - value = 0; - typeName = "BOOL"; - isClientSettable = 0; - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; class GVAR(showSoundWaves) { - value = 1; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(ShowSoundWaves); - description = CSTRING(ShowSoundWaves_Desc); - values[] = {ECSTRING(common,Disabled), CSTRING(NameTagSettings), CSTRING(AlwaysShowAll)}; - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; class GVAR(playerNamesViewDistance) { - displayName = CSTRING(playerNamesViewDistance_DisplayName); - value = 5; - typeName = "SCALAR"; - isClientSettable = 0; - category = CSTRING(Module_DisplayName); - sliderSettings[] = {0, 50, 5, 1}; + movedToSQF = 1; }; class GVAR(playerNamesMaxAlpha) { - displayName = CSTRING(playerNamesMaxAlpha); - value = 0.8; - typeName = "SCALAR"; - isClientSettable = 0; - category = CSTRING(Module_DisplayName); - sliderSettings[] = {0, 1, 0.8, 2}; + movedToSQF = 1; }; class GVAR(tagSize) { - value = 2; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(TagSize_Name); - description = CSTRING(TagSize_Description); - values[] = {"$str_very_small", "$str_small", "$str_medium", "$str_large", "$str_very_large"}; - category = CSTRING(Module_DisplayName); + movedToSQF = 1; }; }; diff --git a/addons/nametags/CfgEventHandlers.hpp b/addons/nametags/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/nametags/CfgEventHandlers.hpp +++ b/addons/nametags/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; 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/CfgVehicles.hpp b/addons/nametags/CfgVehicles.hpp index e712459f68..a014e1c099 100644 --- a/addons/nametags/CfgVehicles.hpp +++ b/addons/nametags/CfgVehicles.hpp @@ -47,14 +47,14 @@ class CfgVehicles { }; }; class playerNamesViewDistance { - displayName = CSTRING(PlayerNamesViewDistance_DisplayName); - description = CSTRING(PlayerNamesViewDistance_Description); + displayName = CSTRING(playerNamesViewDistance_DisplayName); + description = CSTRING(playerNamesViewDistance_Description); typeName = "NUMBER"; defaultValue = 5; }; class showNamesForAI { - displayName = CSTRING(showNamesForAI_DisplayName); - description = CSTRING(showNamesForAI_Description); + displayName = CSTRING(ShowNamesForAI); + description = CSTRING(ShowNamesForAI_Desc); typeName = "NUMBER"; class values { class DoNotForce { @@ -73,8 +73,8 @@ class CfgVehicles { }; }; class showVehicleCrewInfo { - displayName = CSTRING(showVehicleCrewInfo_DisplayName); - description = CSTRING(showVehicleCrewInfo_Description); + displayName = CSTRING(ShowVehicleCrewInfo); + description = CSTRING(ShowVehicleCrewInfo_Desc); typeName = "NUMBER"; class values { class DoNotForce { diff --git a/addons/nametags/README.md b/addons/nametags/README.md index b3ee538ce1..f659b1d5ed 100644 --- a/addons/nametags/README.md +++ b/addons/nametags/README.md @@ -2,11 +2,3 @@ ace_nametags ============ Adds nametags above other players to simulate the familiarity with the faces with others one would have in real life. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/nametags/RscTitles.hpp b/addons/nametags/RscTitles.hpp index f0d5678603..0fad69070d 100644 --- a/addons/nametags/RscTitles.hpp +++ b/addons/nametags/RscTitles.hpp @@ -20,8 +20,8 @@ class RscTitles { idc = ACE_CrewInfo_TextIDC; type = CT_STRUCTURED_TEXT; style = ST_LEFT; - x = SafeZonex + SafezoneW - 0.31; - y = SafeZoneY + SafeZoneH * 0.4; + x = "SafeZonex + SafezoneW - 0.31"; + y = "SafeZoneY + SafeZoneH * 0.4"; w = 0.3; h = 0.6; size = 0.018; @@ -34,7 +34,7 @@ class RscTitles { }; text = ""; class Attributes { - align = right; + align = "right"; }; }; }; 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_PREP.hpp b/addons/nametags/XEH_PREP.hpp index a27102a4e5..33b21f04ec 100644 --- a/addons/nametags/XEH_PREP.hpp +++ b/addons/nametags/XEH_PREP.hpp @@ -1,9 +1,5 @@ - -PREP(canShow); -PREP(doShow); PREP(drawNameTagIcon); PREP(getCachedFlags); -PREP(getVehicleData); PREP(initIsSpeaking); PREP(moduleNameTags); PREP(onDraw3d); diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index 2df7565cd6..a3fb7307f2 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -15,7 +15,6 @@ GVAR(showNamesTime) = -10; // Statement GVAR(showNamesTime) = CBA_missionTime; - // if (call FUNC(canShow)) then{ call FUNC(doShow); }; // This code doesn't work (canShow has a nil / has never worked??) // Return false so it doesn't block other actions false }, @@ -23,13 +22,13 @@ GVAR(showNamesTime) = -10; [29, [false, false, false]], false] call CBA_fnc_addKeybind; //LeftControl Key // Wait until the colors are defined before starting to draw the nametags -["ace_settingsInitialized", { +["CBA_settingsInitialized", { // Draw handle call FUNC(updateSettings); }] call CBA_fnc_addEventHandler; // Change settings accordingly when they are changed -["ace_settingChanged", { +["CBA_SettingChanged", { params ["_name"]; if (_name == QGVAR(showPlayerNames)) then { call FUNC(updateSettings); @@ -45,3 +44,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 (_faction in GVAR(factionRanks)) 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/XEH_preInit.sqf b/addons/nametags/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/nametags/XEH_preInit.sqf +++ b/addons/nametags/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/nametags/config.cpp b/addons/nametags/config.cpp index 0f491efce1..30b8415787 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 +#include "RscTitles.hpp" diff --git a/addons/nametags/functions/common.hpp b/addons/nametags/functions/common.hpp deleted file mode 100644 index ef3706cd32..0000000000 --- a/addons/nametags/functions/common.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Author: aeroson - * Images, index in images and order of roles. - * Defined number also implies order, lower number shows more on top of the list. - */ - -#define PILOT 0 -#define DRIVER 1 -#define COPILOT PILOT -#define COMMANDER 2 -#define GUNNER 3 -#define FFV 4 -#define CARGO 5 - -#define ROLE_IMAGES [ \ - "a3\ui_f\data\IGUI\Cfg\Actions\getinpilot_ca.paa", \ - "a3\ui_f\data\IGUI\Cfg\Actions\getindriver_ca.paa", \ - "a3\ui_f\data\IGUI\Cfg\Actions\getincommander_ca.paa", \ - "a3\ui_f\data\IGUI\Cfg\Actions\getingunner_ca.paa", \ - QPATHTOF(UI\icon_position_ffv.paa), \ - "a3\ui_f\data\IGUI\Cfg\Actions\getincargo_ca.paa" \ -] diff --git a/addons/nametags/functions/fnc_canShow.sqf b/addons/nametags/functions/fnc_canShow.sqf deleted file mode 100644 index 9cc83cfd91..0000000000 --- a/addons/nametags/functions/fnc_canShow.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: aeroson - * Checks if crew info can be shown. - * Might be called several times a second. - * - * Arguments: - * None - * - * Return Value: - * Can show Crew Info - * - * Example: - * call ace_nametags_fnc_canShow - * - * Public: No - */ - -((vehicle ACE_player) != ACE_player) && -{GVAR(ShowCrewInfo)} && -{!(vehicle ACE_player isKindOf "ParachuteBase")}; diff --git a/addons/nametags/functions/fnc_doShow.sqf b/addons/nametags/functions/fnc_doShow.sqf deleted file mode 100644 index 12ac1a04cb..0000000000 --- a/addons/nametags/functions/fnc_doShow.sqf +++ /dev/null @@ -1,86 +0,0 @@ -#include "script_component.hpp" -#include "common.hpp" -/* - * Author: aeroson - * Shows the actual text and sets text the crew info. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_nametags_fnc_doShow - * - * Public: No - */ - -private _player = ACE_player; -private _vehicle = vehicle _player; -private _type = typeOf _vehicle; -private _config = configFile >> "CfgVehicles" >> _type; -private _text = format[" %2
", getText(_config>>"picture"), getText (_config >> "DisplayName")]; - -private _data = [_type] call FUNC(getVehicleData); - -private _isAir = _data select 0; -private _data = _data select 1; - -private _turretUnits = _data apply {_vehicle turretUnit (_x select 0)}; -private _turretRoles = _data apply {_x select 1}; - -private _roleType = CARGO; -private _toShow = []; -{ - switch (_x) do { - case commander _vehicle: { - _roleType = COMMANDER; - }; - case gunner _vehicle: { - _roleType = GUNNER; - }; - case driver _vehicle: { - _roleType = if(_isAir) then { PILOT } else { DRIVER }; - }; - default { - _index = _turretUnits find _x; - if(_index !=-1 ) then { - _roleType = _turretRoles select _index; - } else { - _roleType = CARGO; - }; - }; - }; - _toShow pushBack [_x, _roleType]; -} forEach crew _vehicle; - -_toShow = [ - _toShow, - [], - { - _x select 1 - }, - "ASCEND", - { - _unit = _x select 0; - alive _unit - } -] call BIS_fnc_sortBy; - -private _roleImages = ROLE_IMAGES; -{ - private _unit = _x select 0; - private _roleType = _x select 1; - _text = _text + format["%1
", [_unit] call EFUNC(common,getName), _roleImages select _roleType]; -} forEach _toShow; - -("ACE_CrewInfo_CrewInfo" call BIS_fnc_rscLayer) cutRsc ["ACE_CrewInfo_dialog", "PLAIN", 1, false]; - -terminate (missionNamespace getVariable [QGVAR(hideCrewInfoHandle), scriptNull]); -GVAR(hideCrewInfoHandle) = 0 spawn { - sleep 2; - ("ACE_CrewInfo_CrewInfo" call BIS_fnc_rscLayer) cutFadeOut 2; -}; - -[_text] call FUNC(setText); diff --git a/addons/nametags/functions/fnc_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index 61a8a1b930..efe0c6bf15 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, esteldunedain + * Author: commy2, esteldunedain, Drift_91 * Draw the nametag and rank icon. * * Arguments: @@ -21,7 +21,7 @@ * Public: No */ -TRACE_1("drawName:", _this); +TRACE_1("drawName:",_this); params ["", "_target", "", "_heightOffset"]; @@ -29,20 +29,27 @@ _fnc_parameters = { params ["_player", "_target", "_alpha", "_heightOffset", "_drawName", "_drawRank", "_drawSoundwave"]; //Set Icon: - private _icon = ""; - private _size = 0; - if (_drawSoundwave) then { - _icon = format [QPATHTOF(UI\soundwave%1.paa), floor random 10]; - _size = 1; - } else { - if (_drawRank && {rank _target != ""}) then { - _icon = GVAR(factionRanks) getVariable (_target getVariable [QGVAR(faction), faction _target]); - if (!isNil "_icon") then { - _icon = _icon param [ALL_RANKS find rank _target, ""]; + private _targetIcon = _target getVariable QGVAR(rankIcon); + + private _icon = switch true do { + case _drawSoundwave: { + format [QPATHTOF(UI\soundwave%1.paa), floor random 10] + }; + + case !_drawRank: {""}; + case !isNil "_targetIcon": {_targetIcon}; + case (rank _target == ""): {""}; + + default { + private _targetFaction = _target getVariable [QGVAR(faction), faction _target]; + private _customRankIcons = GVAR(factionRanks) get _targetFaction; + + if (!isNil "_customRankIcons") then { + _customRankIcons param [ALL_RANKS find rank _target, ""] // return } else { - _icon = format ["\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa", rank _target]; + // default rank icons + format ["\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa", rank _target] // return }; - _size = 1; }; }; @@ -76,8 +83,8 @@ _fnc_parameters = { _icon, _color, [], - (_size * _scale), - (_size * _scale), + _scale, + _scale, 0, _name, 2, diff --git a/addons/nametags/functions/fnc_getCachedFlags.sqf b/addons/nametags/functions/fnc_getCachedFlags.sqf index 3fc13256e0..806f443e3d 100644 --- a/addons/nametags/functions/fnc_getCachedFlags.sqf +++ b/addons/nametags/functions/fnc_getCachedFlags.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: * Get's flags used for onDraw3D that can be cached @@ -50,7 +50,13 @@ switch (GVAR(showPlayerNames)) do { }; }; -private _ambientBrightness = ((([] call EFUNC(common,ambientBrightness)) + ([0, 0.4] select ((currentVisionMode ace_player) != 0))) min 1) max 0; -private _maxDistance = _ambientBrightness * GVAR(PlayerNamesViewDistance); +private _maxDistance = GVAR(playerNamesViewDistance); +if (GVAR(ambientBrightnessAffectViewDist) != 0) then { + private _ambientBrightness = [] call EFUNC(common,ambientBrightness); + if (currentVisionMode ace_player != 0) then { + _ambientBrightness = _ambientBrightness + 0.4; + }; + _maxDistance = _maxDistance * linearConversion [0, 1, _ambientBrightness, 1 - GVAR(ambientBrightnessAffectViewDist), 1, true]; +}; [_drawName, GVAR(showPlayerRanks),_enabledTagsNearby,_enabledTagsCursor,_maxDistance] diff --git a/addons/nametags/functions/fnc_getVehicleData.sqf b/addons/nametags/functions/fnc_getVehicleData.sqf deleted file mode 100644 index 55dc758081..0000000000 --- a/addons/nametags/functions/fnc_getVehicleData.sqf +++ /dev/null @@ -1,103 +0,0 @@ -#include "script_component.hpp" -#include "common.hpp" -/* - * Author: aeroson - * Gathers and caches data needed by ace_nametags_fnc_doShow. - * What really does make difference for the engine is simulation of CfgAmmo. - * Priority of roles is: driver/pilot, gunner, copilot, commander, FFV, cargo. - * - * Arguments: - * None - * - * Return Value: - * Data - * 0: Vehicle inherits from Air - * 1: Categorized vehicle's turrets - * - * Example: - * call ace_nametags_fnc_updateSettings - * - * Public: No - */ - -params ["_type"]; - -private _varName = format ["ACE_CrewInfo_Cache_%1", _type]; -private _data = + (uiNamespace getVariable _varName); - -if (!isNil "_data") exitWith {_data}; - -_data = []; -private _isAir = _type isKindOf "Air"; - -private _fnc_addTurretUnit = { - params ["_config", "_path"]; - private _role = CARGO; - - private _simulationEmpty = 0; - private _simulationLaserDesignate = 0; - private _simulationOther = 0; - { - { - private _magazine = configFile >> "CfgMagazines" >> _x; - private _ammo = configFile >> "CfgAmmo" >> getText (_magazine >> "ammo"); - private _simulation = getText (_ammo >> "simulation"); - - if(_simulation=="") then { - _simulationEmpty = _simulationEmpty + 1; - } else { - if(_simulation=="laserDesignate") then { - _simulationLaserDesignate = _simulationLaserDesignate + 1; - } else { - _simulationOther = _simulationOther + 1; - }; - }; - - } forEach getArray (configFile >> "CfgWeapons" >> _x >> "magazines"); - } forEach getArray (_config >> "weapons"); - - if(_simulationOther>0) then { - _role = GUNNER; - }; - if (_role == CARGO && {getNumber (_config >> "isCopilot") == 1}) then { - _role = COPILOT; - }; - if (_role == CARGO && {_simulationLaserDesignate>0 || getNumber (_config >> "primaryObserver") == 1}) then { - _role = COMMANDER; - }; - if (_role == CARGO && {getNumber (_config >> "isPersonTurret") == 1}) then { - _role = FFV; - }; - - _data pushBack [_path, _role]; -}; - - -private _fnc_addTurret = { - params ["_config", "_path"]; - - _config = _config >> "Turrets"; - private _count = count _config; - - private _offset = 0; - - for "_index" from 0 to (_count - 1) do { - private _turretPath = _path + [_index - _offset]; - private _turretConfig = _config select _index; - if (isClass _turretConfig) then { - [_turretConfig, _turretPath] call _fnc_addTurretUnit; - [_turretConfig, _turretPath] call _fnc_addTurret; - } else { - _offset = _offset + 1; - }; - }; -}; - - -_config = configFile >> "CfgVehicles" >> _type; -[_config, []] call _fnc_addTurret; - -_data = [_isAir, _data]; -uiNamespace setVariable [_varName, _data]; - -_data diff --git a/addons/nametags/functions/fnc_initIsSpeaking.sqf b/addons/nametags/functions/fnc_initIsSpeaking.sqf index b400e2d6fa..5bae931e60 100644 --- a/addons/nametags/functions/fnc_initIsSpeaking.sqf +++ b/addons/nametags/functions/fnc_initIsSpeaking.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, PabstMirror * Starts up a PFEH to monitor the when players are talking. @@ -36,27 +36,29 @@ if (!hasInterface) exitWith {}; }; }] call CBA_fnc_addPlayerEventHandler; -if (isClass (configFile >> "CfgPatches" >> "acre_api")) then { - INFO("ACRE Detected."); - DFUNC(isSpeaking) = { - params ["_unit"]; - ([_unit] call acre_api_fnc_isSpeaking) && {!(_unit getVariable ["ACE_isUnconscious", false])} +switch (true) do { + case (["acre_api"] call EFUNC(common,isModLoaded)): { + INFO("ACRE Detected."); + DFUNC(isSpeaking) = { + params ["_unit"]; + ([_unit] call acre_api_fnc_isSpeaking) && {!(_unit getVariable ["ACE_isUnconscious", false])} + }; }; -} else { - if (isClass (configFile >> "CfgPatches" >> "task_force_radio")) then { + case (["task_force_radio"] call EFUNC(common,isModLoaded)): { INFO("TFAR Detected."); DFUNC(isSpeaking) = { params ["_unit"]; (_unit getVariable ["tf_isSpeaking", false]) && {!(_unit getVariable ["ACE_isUnconscious", false])} }; - } else { + }; + default { //No Radio Mod - Start a PFEH to watch the internal VON icon //Note: class RscDisplayVoiceChat {idd = 55} - only present when talking [{ private _oldSetting = ACE_player getVariable [QGVAR(isSpeakingInGame), false]; private _newSetting = (!(isNull findDisplay 55)); - if (!(_oldSetting isEqualTo _newSetting)) then { + if (_oldSetting isNotEqualTo _newSetting) then { ACE_player setVariable [QGVAR(isSpeakingInGame), _newSetting, true]; }; } , 0.1, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/nametags/functions/fnc_moduleNameTags.sqf b/addons/nametags/functions/fnc_moduleNameTags.sqf index 03ced478be..4b269033f9 100644 --- a/addons/nametags/functions/fnc_moduleNameTags.sqf +++ b/addons/nametags/functions/fnc_moduleNameTags.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Initializes the name tags module. diff --git a/addons/nametags/functions/fnc_onDraw3d.sqf b/addons/nametags/functions/fnc_onDraw3d.sqf index fb5d29807a..f831a3209f 100644 --- a/addons/nametags/functions/fnc_onDraw3d.sqf +++ b/addons/nametags/functions/fnc_onDraw3d.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: * Draws names and icons. @@ -113,7 +113,7 @@ if (_enabledTagsNearby) then { private _centerOffsetFactor = 1; if (GVAR(showPlayerNames) == 5) then { private _screenPos = worldToScreen (_target modelToWorld (_target selectionPosition "head")); - if !(_screenPos isEqualTo []) then { + if (_screenPos isNotEqualTo []) then { // Distance from center / half of screen width _centerOffsetFactor = 1 - ((_screenPos distance2D [0.5, 0.5]) / (safezoneW / 3)); } else { @@ -138,8 +138,7 @@ if (_enabledTagsNearby) then { [ACE_player, _target, _alpha, _distance * 0.026, _drawName, _drawRank, _drawSoundwave] call FUNC(drawNameTagIcon); }; }; - nil - } count _targets; + } forEach _targets; }; END_COUNTER(GVAR(onDraw3d)); diff --git a/addons/nametags/functions/fnc_setFactionRankIcons.sqf b/addons/nametags/functions/fnc_setFactionRankIcons.sqf index fa7975d5e5..42d3ed40cb 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Sets a custom set of icons for a specified faction. @@ -25,13 +25,19 @@ */ if (isNil QGVAR(factionRanks)) then { - GVAR(factionRanks) = [] call CBA_fnc_createNamespace; + GVAR(factionRanks) = createHashMap; }; params [["_faction", "", [""]], ["_icons", [], [[]], [7]]]; +TRACE_2("setFactionRankIcons",_faction,_icons); if !(_faction != "" && {_icons isEqualTypeAll ""}) exitWith {false}; -GVAR(factionRanks) setVariable [_faction, _icons]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {false}; + +GVAR(factionRanks) set [_faction, _icons]; true diff --git a/addons/nametags/functions/fnc_setText.sqf b/addons/nametags/functions/fnc_setText.sqf index 543b4fc913..836df0a1b6 100644 --- a/addons/nametags/functions/fnc_setText.sqf +++ b/addons/nametags/functions/fnc_setText.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: aeroson * Sets the text on the dialog. diff --git a/addons/nametags/functions/fnc_updateSettings.sqf b/addons/nametags/functions/fnc_updateSettings.sqf index 56ba016064..9fe0dd9908 100644 --- a/addons/nametags/functions/fnc_updateSettings.sqf +++ b/addons/nametags/functions/fnc_updateSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Dynamically adds and removes Draw3D based on settings on run-time. diff --git a/addons/nametags/functions/script_component.hpp b/addons/nametags/functions/script_component.hpp deleted file mode 100644 index b8135e8ecd..0000000000 --- a/addons/nametags/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\nametags\script_component.hpp" diff --git a/addons/nametags/initSettings.inc.sqf b/addons/nametags/initSettings.inc.sqf new file mode 100644 index 0000000000..5655be3496 --- /dev/null +++ b/addons/nametags/initSettings.inc.sqf @@ -0,0 +1,129 @@ +[ + QGVAR(showPlayerNames), "LIST", + [LSTRING(ShowPlayerNames), LSTRING(ShowPlayerNames_Desc)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + [[0, 1, 2, 3, 4, 5], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(OnlyCursor), LSTRING(OnlyKeypress), LSTRING(OnlyCursorAndKeypress), LSTRING(FadeOnBorder)], 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showPlayerRanks), "CHECKBOX", + LSTRING(ShowPlayerRanks), + format ["ACE %1", localize LSTRING(Module_DisplayName)], + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showVehicleCrewInfo), "CHECKBOX", + [LSTRING(ShowVehicleCrewInfo), LSTRING(ShowVehicleCrewInfo_Desc)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showNamesForAI), "CHECKBOX", + [LSTRING(ShowNamesForAI), LSTRING(ShowNamesForAI_Desc)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + false, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showCursorTagForVehicles), "CHECKBOX", + [LSTRING(showCursorTagForVehicles_DisplayName), LSTRING(showCursorTagForVehicles_Description)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(showSoundWaves), "LIST", + [LSTRING(ShowSoundWaves), LSTRING(ShowSoundWaves_Desc)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(NameTagSettings), LSTRING(AlwaysShowAll)], 1], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(playerNamesViewDistance), "SLIDER", + [LSTRING(PlayerNamesViewDistance_DisplayName), LSTRING(PlayerNamesViewDistance_Description)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + [0, 50, 5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(playerNamesMaxAlpha), "SLIDER", + LSTRING(playerNamesMaxAlpha), + format ["ACE %1", localize LSTRING(Module_DisplayName)], + [0, 1, 0.8, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(tagSize), "LIST", + [LSTRING(TagSize_Name), LSTRING(TagSize_Description)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(defaultNametagColor), "COLOR", + [LSTRING(DefaultNametagColor)], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], + [0.77, 0.51, 0.08, 1], + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(nametagColorMain), "COLOR", + ["str_team_main"], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], + [1.00, 1.00, 1.00, 1], + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(nametagColorRed), "COLOR", + ["str_team_red"], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], + [1.00, 0.67, 0.67, 1], + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(nametagColorGreen), "COLOR", + ["str_team_green"], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], + [0.67, 1.00, 0.67, 1], + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(nametagColorBlue), "COLOR", + ["str_team_blue"], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], + [0.67, 0.67, 1.00, 1], + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(nametagColorYellow), + "COLOR", + ["str_team_yellow"], + [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], + [1.00, 1.00, 0.67, 1], + false // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(ambientBrightnessAffectViewDist), + "SLIDER", + [LSTRING(AmbientBrightnessAffectsViewDist_DisplayName), LSTRING(AmbientBrightnessAffectsViewDist_Description)], + format ["ACE %1", localize LSTRING(Module_DisplayName)], + [0, 1, 1, 0, true], + true +] call CBA_fnc_addSetting; diff --git a/addons/nametags/initSettings.sqf b/addons/nametags/initSettings.sqf deleted file mode 100644 index b2cf482ce1..0000000000 --- a/addons/nametags/initSettings.sqf +++ /dev/null @@ -1,56 +0,0 @@ -// CBA Settings [ADDON: ace_nametags]: - -[ - QGVAR(defaultNametagColor), "COLOR", - [LSTRING(DefaultNametagColor)], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], - [0.77, 0.51, 0.08, 1], - false, // isGlobal - {[QGVAR(defaultNametagColor), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(nametagColorMain), "COLOR", - ["str_team_main"], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], - [1.00, 1.00, 1.00, 1], - false, // isGlobal - {[QGVAR(nametagColorMain), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(nametagColorRed), "COLOR", - ["str_team_red"], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], - [1.00, 0.67, 0.67, 1], - false, // isGlobal - {[QGVAR(nametagColorRed), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(nametagColorGreen), "COLOR", - ["str_team_green"], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], - [0.67, 1.00, 0.67, 1], - false, // isGlobal - {[QGVAR(nametagColorGreen), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(nametagColorBlue), "COLOR", - ["str_team_blue"], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], - [0.67, 0.67, 1.00, 1], - false, // isGlobal - {[QGVAR(nametagColorBlue), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(nametagColorYellow), - "COLOR", - ["str_team_yellow"], - [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize "str_a3_rscdisplaygameoptions_buttongui"], - [1.00, 1.00, 0.67, 1], - false, // isGlobal - {[QGVAR(nametagColorYellow), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index 02993e83e9..9f410c6a75 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -1,11 +1,45 @@ + + Name Tags + Ustawienia imion + Etiquetas de nombre + Zeige Spielernamen + Jmenovky + Etiquetas de nome + Noms des joueurs + Névcímkék + Имена игроков + Etichette Nomi + ネーム タグ + 이름표 + 玩家名称 + 玩家名稱 + Isım Etiketleri + + + This module allows you to customize settings and range of Name Tags. + Moduł ten pozwala dostosować ustawienia i zasięg wyświetlania imion. + Dieses Modul erlaubt die Einstellungen der Anzeigenamen zu verändern. + Este módulo permite personalizar la configuración y la distancia de las Etiquetas de nombre. + Tento modul umožňuje si přizpůsobit nastavení a vzdálenost jmenovky. + Este módulo permite que você personalize as configurações e distâncias de etiquetas de nome. + Ce module permet de configurer les options et la distance d'affichage du nom des unités. + Ez a modul lehetővé teszi a névcímkék beállításainak testreszabását. + Этот модуль позволяет настроить опции и дистанцию отображения имен игроков. + Questo modulo ti consente di personalizzare le impostazioni ed la distanza visibile delle Etichette Nomi + このモジュールを使用すると、ネーム タグの設定と範囲を調整できます。 + 이 모듈은 당신이 이름표의 범위를 임의로 수정할 수 있게 해줍니다. + 这个模块允许您设定名字和显示范围等设定 + 這個模塊允許您設定名稱和顯示範圍等設定 + Bu modül, Isim Etiketleri ayarlarını ve aralığını özelleştirmenizi sağlar. + Show Names Namen anzeigen Mostrar nombres - Afficher noms + Afficher les noms Zobrazit jména Pokaż imiona Nevek mutatása @@ -16,70 +50,125 @@ 이름 표시 显示名字 顯示名稱 + Isimleri Göster Show player names Spielernamen anzeigen Mostrar nombres de jugadores Pokaż imiona graczy - Afficher les nom des joueurs + Afficher le nom des joueurs Játékosnevek mutatása Zobrazit jména hráčů Mostrar nomes de jogadores Mostra i nomi dei giocatori Показывать имена игроков (включить имена) - プレイヤ名を表示 + プレイヤー名を表示 플레이어 이름 표시 - 显示玩家名字 + 显示玩家名称 顯示玩家名稱 + Oyuncu isimlerini göster - - Show player name only on cursor (requires player names) - Pokaż imiona graczy tylko pod kursorem (wymagana opcja Pokaż imiona graczy) - Mostrar nombres de jugadores solo al apuntarles (requiere Mostrar nombres de jugadores) - Zeige Spielernamen nur an, wenn die Maus auf sie gerrichtet ist (benötigt Spielernamen) - Noms uniquement sous le curseur (si noms affichés) - Zobrazit jméno hráče jenom na kurzor (vyžaduje jména hráčů) - Mostra i nomi solo se puntati (insieme ai nomi) - Mostrar nome de jogador somente no cursor (requer nome de jogadores) - Játékosok nevének mutatása csak a kurzoron (a nevek mutatása szükséges) - Показать имена игроков только под курсором (при включенных именах) - カーソルを合わせた時だけプレイヤ名を表示 (プレイヤ名が必要) - 커서로 지시할때만 플레이어 이름 표시(플레이어 이름 필요) - 仅在准心指到后显示玩家名字 (玩家必须有设定名字) - 僅在準心指到後顯示玩家名稱 (玩家必須有設定名稱) + + Show player names and set their activation. Default: Enabled + Opcja ta pozwala dostosować sposób wyświetlania imion nad głowami graczy. Opcja "Tylko po wciśnięciu klawisza" wyświetla imiona tylko przytrzymania klawisza "Modyfikator" dostępnego w menu ustawień addonów -> ACE3. + Mostrar nombres de los jugadores y establecer su activación. Predeterminado: Habilitado + Zobrazit jména hráčů a nastavit jejich aktivaci. Výchozí: Povoleno + Erlaubt das Anzeigen von Spielernamen und stellt ein, ob sie standardmäßig aktiviert oder deaktiviert sind. Standard: aktiviert + Mostrar os nomes dos jogadores e definir sua ativação. Padrão: Ativado + Affiche le nom des joueurs et définit leur activation. Valeur par défaut : activé. + Mutassa a játékosok nevét és kezelje az aktivációjukat. Alapértelmezett: Engedélyezve + Показывать имена игроков и установить их активацию. По умолчанию: Включено + Mostra nomi giocatori ed imposta la loro attivazione. Default: Abilitato + プレイヤー名の表示とそれを有効にする方法を設定します。 デフォルト: 有効 + 플레이어 이름의 표시와 설정을 활성화합니다. 기본설정: 활성화 + 显示玩家的名字并设置其启动方式。预设:启用 + 顯示玩家的名稱並設置其啟動方式。預設: 啟用 + Oyuncu adlarını gösterin ve etkinleştirmelerini ayarlayın. Varsayılan: Etkin - - Show player name only on keypress (requires player names) - Spielernamen nur auf Tastendruck anzeigen (benötigt Spielernamen) - Mostrar nombres solo al pulsar la tecla(requiere Mostrar nombres de jugadores) - Noms uniquement sur pression de la touche (si noms affichés) - Zobrazit jména hráčů jen na klávesu (vyžaduje jména hráčů) - Pokaż imiona graczy tylko po przytrzymaniu klawisza (wymagana opcja Pokaż imiona graczy) - Játékosnevek mutatása csak gombnyomásra (a nevek mutatása szükséges) - Показать имена игроков только по нажатию клавиши (при включенных именах) - Mostra i nomi solo se si preme il tasto (insieme ai nomi) - Mostrar nomes somente ao pressionar teclar (requer nome de jogadores) - キーを押した時だけプレイヤ名を表示 (プレイヤ名が必要) - 키를 누를때만 플레이어 이름 표시(플레이어 이름 필요) - 仅在按按键后显示玩家名字 (玩家必须有设定名字) - 僅在按按鍵後顯示玩家名稱 (玩家必須有設定名稱) + + Only on Cursor + Tylko pod kursorem + Solo cursor + Nur bei Maus + Pouze na kurzor + Somente no cursor + Seulement sous le curseur + Csak kurzorra + Только под курсором + Solo su Cursore + カーソルを合わせた時 + 커서만 해당 + 只有准心指到时 + 只有準心指到時 + Yalnızca İmleçte + + + Only on Keypress + Tylko po wciśnięciu klawisza + Solo al pulsar tecla + Nur bei Tastendruck + Pouze na klávesu + Somente em tecla ativada + Seulement par appui de touche + Csak gombnyomásra + Только по нажатию клавиши + Solo quando Premi Tasto + キーを押した時のみ + 키를 누를 경우만 + 只有按按键时 + 只有按按鍵時 + Yalnızca Tuşa Basmada + + + Only on Cursor and Keypress + Tylko pod kursorem i po wciśnięciu klawisza + En cursor y al pulsar tecla + Nur Maus und Tastendruck + Pouze na kurzor a klávesu + Somente em cursor ou tecla ativada + Seulement sous le curseur et par appui de touche + Csak kurzorra és gombnyomásra + Под курсором или по нажатию клавиши + Solo su Cursore e quando Premi Tasto + カーソルを合わせてキーを押した時のみ + 커서와 키를 누를 경우만 + 只有在准心指到和按按键时 + 只有在準心指到和按按鍵時 + Yalnızca İmleç ve Tuşa Basıldığında + + + Fade on screen border + Am Bildschirmrand ausblenden + 画面端でフェードアウト + Ukryj na brzegach ekranu + 화면 가장자리에서 사라짐 + Estomper sur les bords de l'écran + Sfoca ai bordi dello schermo + 在屏幕边框旁淡出 + 在螢幕邊框旁淡出 + Затухание на границе экрана + Ocultar na borda da tela + Zeslábnout poblíž okrajů obrazovky + Difuminar en el borde de pantalla + Ekran kenarında karart Show player ranks (requires player names) Spielerränge anzeigen (benötigt Spielernamen) Pokaż rangi graczy (wymagana opcja Pokaż imiona graczy) Mostrar rango de los jugadores (requiere Mostrar nombres de jugadores) - Grade des joueurs (si noms affichés) + Afficher le grade des joueurs (si noms affichés) Zobrazit hodnosti hráčů (vyžaduje jména hráčů) Mostra i gradi (insieme ai nomi) Mostrar patente de jogadores (requer nome de jogadores) Játékosok rendfokozatának mutatása (a nevek mutatása szükséges) Показывать звания игроков (при вкл. именах) - プレイヤの階級を表示 (プレイヤ名が必要) + プレイヤーの階級を表示 (プレイヤー名を表示が必要) 플레이어 계급 표시 (플레이어 이름 필요) - 显示玩家军阶 (玩家必须有设定名字) + 显示玩家军阶(玩家必须有设定名字) 顯示玩家軍階 (玩家必須有設定名稱) + Oyuncu rütbelerini göster (oyuncu isimleri açılması gerektirir) Show vehicle crew info @@ -96,6 +185,24 @@ 차량 승무원 정보 표시 显示载具成员信息 顯示載具成員信息 + Araç mürettebatı bilgilerini göster + + + Show vehicle crew info, or by default allows players to choose it on their own. Default: Do Not Force + Pokaż informacje o obsadzie pojazdu, lub pozwól graczom ustawić tą opcje według własnego uznania. Domyślnie: Nie wymuszaj + Muestra información de la tripulación, o por defecto permite a los jugadores elegirlo. Por defecto: No forzar + Zeige Status der Fahrzeugbesatzung oder erlaube Spielern ihn auszuwählen. Standard: nicht erzwingen. + Zobrazit informace o posádce, nebo nechat aby si hráč vybral sám. Výchozí: Nevynucovat + Mostrar informações de tripulação ou por padrão permitir a escolha dos jogadores. Padrão: Não forçar. + Affiche les informations sur l'équipage des véhicules. + A legénységi adatok mutatása, alapértelmezett esetben a játékos által kiválasztható. Alapértelmezett: Nincs felülbírálás + Показывать информацию об экипаже техники, или по умолчанию, позволяет игрокам выбрать свою настройку. По умолчанию: Не обязывать + Mostra informazioni sull'equipaggio del veicolo, oppure consenti di default di lasciare che siano i giocatori a scegliere. Default: Non Forzare + 車両の乗組員情報を表示するか、デフォルトでのようにプレイヤーが自分で情報を選択できるようにします。 デフォルト: 強制しない + 승무원 정보를 표시하거나 플레이어가 직접 고르게 놔둡니다. 기본설정: 강제하지 않음 + 显示载具成员信息。在预设的情况下,系统允许玩家自己决定开关此信息。预设:不显示 + 顯示載具成員訊息。在預設的情況下,系統允許玩家自己決定開關此訊息。預設: 不顯示 + Araç mürettebat bilgilerini gösterin veya varsayılan olarak oyuncuların kendi başlarına seçmelerine izin verir. Varsayılan: Zorlama Show name tags for AI units @@ -104,190 +211,32 @@ Показывать имена ботов Zobrazit jména AI Wyświetl imiona jednostek AI - Afficher les noms des IA + Afficher le nom des unités IA Névcímkék mutatása MI-egységeknél Mostra i nomi delle le unità AI Mostrar nomes para unidades de IA - AI ユニットの名札を表示 + AIユニットのネーム タグを表示 인공지능 인원 이름 표시 - 显示AI单位名字 + 显示 AI 单位名字 顯示AI單位名稱 + AI birimleri için ad etiketlerini göster - - Show SoundWaves (requires player names) - Sprechsymbol anzeigen (benötigt Spielernamen) - Mostrar onda sonora (requiere Mostrar nombres de jugadores) - Индикатор разговора (при вкл. именах) - Zobrazit SoundWaves (vyžaduje jména hráčů) - Pokaż fale dźwiękowe (wymagana opcja Pokaż imiona graczy) - Afficher "qui parle" (si noms affichés) - "Hanghullámok" mutatása (a nevek mutatása szükséges) - Mostra movimento audio (insieme ai nomi) - Mostrar onda sonora (requer nome de jogadores) - 音波形を表示 (プレイヤ名が必要) - 음파 표시 (플레이어 이름 필요) - 当玩家讲话时,显示声波图案 (玩家必须有设定名字) - 當玩家講話時,顯示聲波圖案 (玩家必須有設定名稱) - - - Default Nametag Color (Non Group Members) - Voreingestellte Namenfarbe (Spieler außerhalb der Gruppe) - Цвет меток игроков (не членов групп) - Color de etiquetas de nombre por defecto (No miembros de grupo) - Domyślny kolor imion (członkowie spoza grupy) - Couleur d'affichage par défaut (si dans aucun groupe) - Standardní barva jmenovek (pro nečleny jednotky) - Alap névcímke-szín (csoporton kívüli személyek) - Colore dei nomi non appartenenti al gruppo - Cor padrão do nome (unidades fora do grupo) - 標準の名札の色(グループ メンバ以外) - 기본 이름표 색상 (비-그룹 멤버) - 预设名字颜色 (非同小队队友) - 預設名稱顏色 (非同小隊隊友) - - - Name Tags - Ustawienia imion - Etiquetas de nombre - Zeige Spielernamen - Jmenovky - Etiquetas de nome - NameTags - Névcímkék - Имена игроков - Etichette Nomi - 名札 - 이름표 - 玩家名字 - 玩家名稱 - - - Player Names View Dist. - Zasięg imion graczy - Distancia de vision para nombres de jugadores - Sichtweite der Spielernamen - Vzdálenost zobrazení jména hráčů - Distância de visão dos nomes dos jogadores - Distance de vue des noms de joueurs - Játékosok nevének látótávja - Дистанция отображения имен - Distanza Visiva Etichette Nomi - プレイヤ名が見える範囲 - 플레이어 이름 표시 거리 - 玩家名字显示距离 - 玩家名稱顯示距離 - - - Distance in meters at which player names are shown. Default: 5 - Dystans w metrach, na którym wyświetlane są imiona graczy. Domyślnie: 5 - Distancia en metros a la que se muestran los nombres de los jugadores. Por defecto: 5 - Entfernung in Metern, bei der Spielernamen angezeigt werden. Standard: 5 - Vzdálenost v metrech pro zobrazení jména. Výchozí: 5 - Distância em metros que os nomes dos jogadores são mostrados. Padrão: 5 - Distance en mètres au delà de laquelle les noms de joueurs ne sont plus affichés. Défaut: 5 - Méterben megadott érték a játékosok nevének mutatására. Alapértelmezett: 5 - Дистанция в метрах, на которой отображаются имена игроков. По-умолчанию: 5 - Distanza in metri a cui sono visibili i nomi giocatori. Default: 5 - プレイヤの周り何メートルまで名札を表示できます。標準: 5 - 플레이어 이름이 표시되는 미터. 기본설정: 5 - 设定名字在多少距离以内显示。预设:5公尺 - 設定名稱在多少距離以內顯示。預設:5公尺 - - - Show name tags for AI? - Imiona AI - ¿Mostrar nombres para la IA? - Zeige KI-Namen? - Zobrazit jmenovky pro AI? - Mostrar nomes para IA? - Afficher les noms pour les IA? - Névcímkék megjelenítése AI-nál? - Показывать имена ботов? - Mostra etichette nomi per IA? - AI の名札も表示しますか? - 인공지능의 이름도 표시합니까? - 显示AI名字? - 顯示AI名稱? - - + Show the name and rank tags for friendly AI units? Default: Do not force Pokaż imiona i rangi przyjaznych jednostek AI? Domyślnie: Nie wymuszaj Muestra etiquetas de nombre y rango para las unidades IA amigas? Por defecto: No forzar Zeige den Namen und Rang für freundliche KI-Einheiten? Standard: nicht erzwingen Zobrazit jména a hodnosti pro spřátelené AI jednotky? Výchozí: Nevynucovat Mostra o nome e patente para unidades IA aliadas? Padrão: Não forçar - Affiche le nom et le rang pour les IA alliées? Défaut : ne pas forcer + Affiche le nom et le grade des IA alliées. Mutassa-e a szövetséges AI egységek nevét és rangját? Alapértelmezett: Nincs felülbírálás - Показывать имена и звания дружественных ботов? По-умолчанию: Не обязывать + Показывать имена и звания дружественных ботов? По умолчанию: Не обязывать Mostra etichette nomi ed etichette gradi per unità IA alleate? Default: Non forzare - 友軍の AI にも名前と階級を表示しますか? 標準: 強制しない + 友軍のAIにも名前と階級を表示しますか? デフォルト: 強制しない 아군 인공지능의 계급을 표시합니까? 기본설정: 강제하지 않음 - 显示友军AI的名字和军阶? 预设: 不显示 + 显示友军 AI 的名字和军阶? 预设:不显示 顯示友軍AI的名稱和軍階? 預設: 不顯示 - - - Force Hide - Wymuś ukrycie - Ocultar forzado - Verstecken erzwingen - Vynuceno skrýt - Ocultar forçado - Forcer la désactivation - Erőltetett rejtett - Обязательно: Скрывать - Forza Nascosto - 強制で非表示 - 강제로 숨기기 - 强制隐藏 - 強迫隱藏 - - - Force Show - Wymuś wyświetlanie - Mostrar forzado - Anzeige erzwingen - Vynuceno zobrazit - Mostrar forçado - Forcer l'affichage - Erőltetett látható - Обязательно: Показывать - Forza Mostra - 強制で表示 - 강제로 표시 - 强制显示 - 強迫顯示 - - - Show crew info? - Pokaż załogę - ¿Mostrar información de la tripulación? - Zeige Besatzungsstatus? - Zobrazit informace o posádce? - Mostrar informação de tripulação? - Afficher les informations de l'équipage? - Legénységi adatok megjelenítése? - Показывать экипаж? - Mostra informazioni equipaggio? - 乗員の情報を表示 - 승무원 정보 표시? - 显示载具成员讯息? - 顯示載具成員訊息? - - - Show vehicle crew info, or by default allows players to choose it on their own. Default: Do Not Force - Pokaż informacje o obsadzie pojazdu, lub pozwól graczom ustawić tą opcje według własnego uznania. Domyślnie: Nie wymuszaj - Muestra información de la tripulación, o por defecto permite a los jugadores elegirlo. Por defecto: No forzar - Zeige Status der Fahrzeugbesatzung oder erlaube Spielern ihn auszuwählen. Standard: nicht erzwingen. - Zobrazit informace o posádce, nebo nechat aby si hráč vybral sám. Výchozí: Nevynucovat - Mostrar informações de tripulação ou por padrão permitir a escolha dos jogadores. Padrão: Não forçar. - Afficher les informations sur l'équipage d'un véhicule. Défaut: ne pas forcer - A legénységi adatok mutatása, alapértelmezett esetben a játékos által kiválasztható. Alapértelmezett: Nincs felülbírálás - Показывать информацию об экипаже техники, или по-умолчанию, позволяет игрокам выбрать свою настройку. По-умолчанию: Не обязывать - Mostra informazioni sull'equipaggio del veicolo, oppure consenti di default di lasciare che siano i giocatori a scegliere. Default: Non Forzare - 車両の乗員を表示します。標準ではプレイヤ各々が選べられます。標準: 強制しない - 승무원 정보를 표시하거나 플레이어가 직접 고르게 냅둡니다. 기본설정: 강제하지 않음 - 显示载具成员讯息。在预设的情况下,系统允许玩家自己决定开关此讯息。预设: 不显示 - 顯示載具成員訊息。在預設的情況下,系統允許玩家自己決定開關此訊息。預設: 不顯示 + Dost AI birimleri için ad ve rütbe etiketleri gösterilsin mi? Varsayılan: Zorlama Show for Vehicles @@ -304,6 +253,7 @@ 차량 표시 显示给载具指挥官 顯示給載具指揮官 + Araçlar için Göster Show cursor NameTag for vehicle commander (only if client has name tags enabled) Default: No @@ -312,125 +262,48 @@ Zeige Maus-Spielernamen für Fahrzeugkommandanten (nur wenn der Client Namensanzeigen aktiviert hat). Standard: Nein Zobrazit jmenovky pro velitele vozidla (pouze pokud má klient jmenovky povolené). Výchozí: Ne Mostrar o nome no cursor para o comandante do veículo (somente se o cliente tiver etiquetas de nomes ativada). Padrão: Não - Показывать имя командира техники (только, если клиент включил отображение имен). По-умолчанию: Нет - Afficher les étiquettes de nom pour les commandants de véhicule (uniquement si l'affichage est activé pour le client). Défaut: non + Показывать имя командира техники (только если клиент включил отображение имен). По умолчанию: Нет + Affiche les noms pour les commandants de véhicule (uniquement si le client a activé l'affichage des noms). Mostra il nome sul cursore per il comandante del veicolo (solo se il client ha le Etichette Nomi attive) Default: No - 車長の名札をカーソルを当てて表示します (クライアント側で名札を有効化する必要があります) 標準: 無効 - 차량의 사령관의 이름표를 표시합니다 (오직 클라이언트가 이름표를 활성화 할시에만 보입니다) 기본설정: 아니요 - 使载具指挥官能透过准心指到别的单位来显示其名字 (仅当客户端的名字功能已启用)。预设: 关闭 + カーソルを当てた時、車長のネーム タグを表示します (クライアント側でネーム タグを有効化する必要があります) デフォルト: 無効 + 차장의 이름표를 표시합니다 (오직 클라이언트가 이름표를 활성화할 시에만 보입니다) 기본설정: 아니요 + 使载具指挥官能透过准心指到别的单位来显示其名字(仅当客户端的名字功能已启用)。预设:关闭 使載具指揮官能透過準心指到別的單位來顯示其名稱 (僅當客戶端的名稱功能已啟用)。預設: 關閉 + Araç komutanı için Gösterge İsim Etiketini göster (yalnızca istemcide ad etiketleri etkinse) Varsayılan: Hayır - - This module allows you to customize settings and range of Name Tags. - Moduł ten pozwala dostosować ustawienia i zasięg wyświetlania imion. - Dieses Modul erlaubt die Einstellungen der Anzeigenamen zu verändern. - Este módulo permite personalizar la configuración y la distancia de las Etiquetas de nombre. - Tento modul umožňuje si přizpůsobit nastavení a vzdálenost jmenovky. - Este módulo permite que você personalize as configurações e distâncias de etiquetas de nome. - Ce module permet le paramétrage de l'affichage des étiquettes des noms - Ez a modul lehetővé teszi a névcímkék beállításainak testreszabását. - Этот модуль позволяет настроить опции и дистанцию отображения имен игроков. - Questo modulo ti consente di personalizzare le impostazioni ed il raggio delle Etichette Nomi - これは名札の表示範囲と設定を変更できます。 - 이 모듈은 당신이 이름표의 범위를 임의로 수정할 수 있게 해줍니다. - 这个模块允许您设定名字和显示范围等设定 - 這個模塊允許您設定名稱和顯示範圍等設定 + + Show SoundWaves (requires player names) + Sprechsymbol anzeigen (benötigt Spielernamen) + Mostrar onda sonora (requiere Mostrar nombres de jugadores) + Индикатор разговора (при вкл. именах) + Zobrazit SoundWaves (vyžaduje jména hráčů) + Pokaż fale dźwiękowe (wymagana opcja Pokaż imiona graczy) + Afficher "qui parle" (si noms affichés) + "Hanghullámok" mutatása (a nevek mutatása szükséges) + Mostra movimento audio (insieme ai nomi) + Mostrar onda sonora (requer nome de jogadores) + 音波形を表示 (プレイヤー名の表示が必要) + 음파 표시 (플레이어 이름 필요) + 当玩家讲话时,显示声波图案(玩家必须有设定名字) + 當玩家講話時,顯示聲波圖案 (玩家必須有設定名稱) + Ses Dalgalarını Göster (oyuncu isimleri gerektirir) - - Only on Cursor - Tylko pod kursorem - Solo cursor - Nur bei Maus - Pouze na kurzor - Somente no cursor - Seulement sous le curseur - Csak kurzorra - Только под курсором - Solo su Cursore - カーソルでのみ - 커서만 해당 - 只有准心指到时 - 只有準心指到時 - - - Only on Keypress - Tylko po wciśnięciu klawisza - Solo al pulsar tecla - Nur bei Tastendruck - Pouze na klávesu - Somente em tecla ativada - Seulement par appui de touche - Csak gombnyomásra - Только по нажатию клавиши - Solo quando Premi Tasto - キー押下のみ - 키를 누를경우만 - 只有按按键时 - 只有按按鍵時 - - - Only on Cursor and Keypress - Tylko pod kursorem i po wciśnięciu klawisza - En cursor y al pulsar tecla - Nur Maus und Tastendruck - Pouze na kurzor a klávesu - Somente em cursor ou tecla ativada - Seulement sous le curseur et par appui de touche - Csak kurzorra és gombnyomásra - Под курсором или по нажатию клавиши - Solo su Cursore e quando Premi Tasto - カーソルとキー押下のみ - 커서와 키를 누를경우만 - 只有在准心指到和按按键时 - 只有在準心指到和按按鍵時 - - - Force Show Only on Cursor - Wymuś pod kursorem - Forzar mostrar solo en el cursor - Vynuceno zobrazit pouze na kurzor - Erzwinge nur mit Mauszeiger anzuzeigen - Forçar mostrar somente no cursor - Forcer l'affichage sous le curseur uniquement - Erőltetett látható, csak kurzorra - Обязательно: Только под курсором - Forza Mostra solo su Cursore - カーソルでのみに強制する - 커서만 강제로 해당 - 强制仅显示在准心指到时 - 強制僅顯示在準心指到時 - - - Force Show Only on Keypress - Wymuś po wciśnięciu klawisza - Forzar mostrar solo al pulsar tecla - Vynuceno zobrazit pouze na klávesu - Erzwinge nur mit Tastendruck anzuzeigen - Forçar somente mostrar em tecla ativada - Forcer l'affichage par appui de touche uniquement - Erőltetett látható, csak gombnyomásra - Обязательно: Только по нажатию клавиши - Forza Mostra solo quando Premi Tasto - キー押下のみに強制する - 키를 누를경우만 강제로 해당 - 强制仅显示在按按键时 - 強制僅顯示在按按鍵時 - - - Force Show Only on Cursor and Keypress - Wymuś pod kursorem i po wciśnięciu klawisza - Forzar mostrar en el cursor y al pulsar tecla - Vynuceno zobrazit pouze na kurzor a klávesu - Erzwinge nur mit Mauszeiger und Tastendruck anzuzeigen - Forçar mostrar somente em cursor e tecla ativada - Forcer l'affichage sous le curseur et par appui de touche uniquement - Erőltetett látható, csak kurzorra és gombnyomásra - Обязательно: Под курсором или по нажатию клавиши - Forza Mostra solo su Cursore e quando Premi Tasto - カーソルとキー押下のみに強制する - 커서와 키를 누를경우만 강제로 해당 - 强制显示在准心指到和按按键时 - 強制顯示在準心指到和按按鍵時 + + Effect of sound waves above the heads of speaking players after holding the PTT key. This option works with TFAR and ACRE2. + Opcja ta pozwala dostosować sposób wyświetlania efektu fal dźwiękowych nad głowami mówiących graczy, wyświetlanych po przytrzymaniu klawisza PTT. Opcja ta współpracuje z TFAR oraz ACRE2. + Efecto de ondas sonoras encima de las cabezas de los jugadores que hablan después de mantener la tecla PTT. Esta opción funciona con TFAR y ACRE2. + Efekt zvukových vln nad hlavami hráčů když mluví skrz PTT klávesu. Tato volba funguje s TFAR a ACRE2. + Es wird ein Schallwellensymbol über den Köpfen von sprechenden Spielern angezeigt, die ihre Push-to-Talk-Taste drücken. Diese Option funktioniert mit "TFAR" und "ACRE2". + Efeito de ondas sonoras acima das cabeças dos jogadores que falam depois mantendo pressionada a tecla PTT. Esta opção funciona com TFAR e ACRE2. + Effet d'onde sonore, qui s'anime au-dessus de la tête des joueurs lorsqu'ils parlent en maintenant la touche PTT enfoncée. Cette option fonctionne avec TFAR et ACRE2. + Hanghullám-effekt a beszélő játékosok feje felett a PTT-gomb lenyomásakor. Ez a beállítás TFAR és ACRE2 alatt működik. + Эффект звуковой волны над головами говорящих игроков при удерживании кнопки push-to-talk. Эта опция работает также с рациями TFAR и ACRE2. + Effetto delle onde sonore sopra la testa dei giocatori parlanti quando premono il tasto PTT. Questa opzione funziona con TFAR ed ACRE2 + プレイヤーが PTT キーを押している間は、音波形を表示します。 このオプションは TFAR と ACRE2 で動作します。 + 플레이어가 눌러서 말할 시 머리위에 음파효과를 적용합니다. 이 옵션은 TFAR과 ACRE2가 있을 때만 적용됩니다. + 当玩家使用按键发话时,其头上的角色名字旁会显示声波的图案。此功能可搭配 TFAR、ACRE2 等模组使用。 + 當玩家使用按鍵發話時,其頭上的角色名稱旁會顯示聲波的圖案。此功能可搭配TFAR、ACRE2等模組使用。 + Bas Konuş tuşunu basılı tuttuktan sonra ses dalgalarının konuşan oyuncuların başlarının üzerindeki etkisi. Bu seçenek TFAR ve ACRE2 ile çalışır. Use Nametag settings @@ -439,14 +312,15 @@ Verwende Spielernamen Použít nastavení jmenovky Usar ajustes de etiquetas de nome - Utiliser les paramètre des NamesTags + Utiliser les paramètre des noms Névcímkék beállításának használata Так же, как имена Usa impostazioni Etichette Nomi - 名札の設定 + ネーム タグの設定 이름표 설정 사용 - 玩家名字设定 + 玩家名称设定 玩家名稱設定 + İsim etiketi ayarlarını kullan Always Show All @@ -459,42 +333,61 @@ Mindig minden mutatása Всегда показывать Mostra Sempre Tutto - 常に表示する + 常に全て表示する 항상 모두 표시 永远显示全部 永遠顯示全部 + Her Zaman Tümünü Göster - - Show player names and set their activation. Default: Enabled - Opcja ta pozwala dostosować sposób wyświetlania imion nad głowami graczy. Opcja "Tylko po wciśnięciu klawisza" wyświetla imiona tylko przytrzymania klawisza "Modyfikator" dostępnego w menu ustawień addonów -> ACE3. - Mostrar nombres de los jugadores y establecer su activación. Predeterminado: Habilitado - Zobrazit jména hráčů a nastavit jejich aktivaci. Výchozí: Povoleno - Erlaubt das Anzeigen von Spielernamen und stellt ein, ob sie standardmäßig aktiviert oder deaktiviert sind. Standard: aktiviert - Mostrar os nomes dos jogadores e definir sua ativação. Padrão: Ativado - Afficher les noms des joueurs et paramètre son activation. Défaut: activé - Mutassa a játékosok nevét és kezelje az aktivációjukat. Alapértelmezett: Engedélyezve - Показывать имена игроков и установить их активацию. По-умолчанию: Включено - Mostra nomi giocatori ed imposta la loro attivazione. Default: Abilitato - プレイヤ名の表示と設定を有効化します。標準: 有効 - 플레이어 이름의 표시와 설정을 활성화합니다. 기본설정: 활성화 - 显示玩家的名字并设置其启动方式。预设: 启用 - 顯示玩家的名稱並設置其啟動方式。預設: 啟用 + + Player Names View Dist. + Zasięg imion graczy + Distancia de vision para nombres de jugadores + Sichtweite der Spielernamen + Vzdálenost zobrazení jména hráčů + Distância de visão dos nomes dos jogadores + Distance de visibilité du nom des joueurs + Játékosok nevének látótávja + Дистанция отображения имен + Distanza Visiva Etichette Nomi + プレイヤー名の表示距離 + 플레이어 이름 표시 거리 + 玩家名称显示距离 + 玩家名稱顯示距離 + Oyuncu Adlarını Görüntüleme Mes. - - Effect of sound waves above the heads of speaking players after holding the PTT key. This option works with TFAR and ACRE2. - Opcja ta pozwala dostosować sposób wyświetlania efektu fal dźwiękowych nad głowami mówiących graczy, wyświetlanych po przytrzymaniu klawisza PTT. Opcja ta współpracuje z TFAR oraz ACRE2. - Efecto de ondas sonoras encima de las cabezas de los jugadores que hablan después de mantener la tecla PTT. Esta opción funciona con TFAR y ACRE2. - Efekt zvukových vln nad hlavami hráčů když mluví skrz PTT klávesu. Tato volba funguje s TFAR a ACRE2. - Es wird ein Schallwellensymbol über den Köpfen von sprechenden Spielern angezeigt, die ihre Push-to-Talk-Taste drücken. Diese Option funktioniert mit "TFAR" und "ACRE2". - Efeito de ondas sonoras acima das cabeças dos jogadores que falam depois mantendo pressionada a tecla PTT. Esta opção funciona com TFAR e ACRE2. - Icone au dessus de la tête du joueur qui parle après avoir utilisé la touche de PTT. Option compatible avec ACRE2 et TFAR - Hanghullám-effekt a beszélő játékosok feje felett a PTT-gomb lenyomásakor. Ez a beállítás TFAR és ACRE2 alatt működik. - Эффект звуковой волны над головами говорящих игроков при удерживании кнопки push-to-talk. Эта опация работает также с рациями TFAR и ACRE2. - Effetto delle onde sonore sopra la testa dei giocatori parlanti quando premono il tasto PTT. Questa opzione funziona con TFAR ed ACRE2 - プレイヤーが PTT キーを押している間は、音波形を表示します。このオプションは TFAR と ACRE2 で動作します。 - 플레이어가 PTT로 말할시 머리위에 음파효과를 적용합니다. 이 옵션은 TFAR과 ACRE2가 있을때만 적용됩니다. - 当玩家使用按键发话时,其头上的角色名字旁会显示声波的图案。此功能可搭配TFAR、ACRE2等模组使用。 - 當玩家使用按鍵發話時,其頭上的角色名稱旁會顯示聲波的圖案。此功能可搭配TFAR、ACRE2等模組使用。 + + Distance in meters at which player names are shown. Default: 5 + Dystans w metrach, na którym wyświetlane są imiona graczy. Domyślnie: 5 + Distancia en metros a la que se muestran los nombres de los jugadores. Por defecto: 5 + Entfernung in Metern, bei der Spielernamen angezeigt werden. Standard: 5 + Vzdálenost v metrech pro zobrazení jména. Výchozí: 5 + Distância em metros que os nomes dos jogadores são mostrados. Padrão: 5 + Distance au delà de laquelle les noms des joueurs ne sont plus affichés. Valeur par défaut : 5 mètres. + Méterben megadott érték a játékosok nevének mutatására. Alapértelmezett: 5 + Дистанция в метрах, на которой отображаются имена игроков. По умолчанию: 5 + Distanza in metri entro la quale sono visibili i nomi dei giocatori. Predefinito: 5 + プレイヤー名が表示される距離 (メートル)。 デフォルト: 5 + 플레이어 이름이 표시되는 미터. 기본설정: 5 + 设定名字在多少距离以内显示。预设:5米 + 設定名稱在多少距離以內顯示。預設:5公尺 + Oyuncu adlarının gösterildiği metre cinsinden mesafe. Varsayılan: 5 + + + Player tags transparency + Spielernamen Transparenz + プレイヤーのネーム タグの透明度 + 玩家名称标签透明度 + 玩家名稱透明度 + Trasparenza Etichette Nome + Przezroczystość etykiet gracza + Прозрачность меток игроков + Transparência da etiqueta de nome + Transparence des noms + Průhlednost jmenovek + Transparencia de etiquetas de jugadores + Oyuncu etiketlerinde şeffaflık + 플레이어 이름 투명도 Nametags Size @@ -507,10 +400,11 @@ Névcímkék mérete Размер имен игроков Dimensione Etichette Nome - 名札の大きさ + ネーム タグの大きさ 이름표 크기 - 玩家名字标记大小 + 玩家名称标记大小 玩家名稱標記大小 + Isim Etiketi Büyüklüğü Text and Icon Size Scaling @@ -519,36 +413,141 @@ Velikost textu a ikon Text- und Symbolgrößen Escala de tamanho dos ícones e textos - Taille du texte et des icones + Taille du texte et des icônes. Szöveg és ikon méretének skálázása Масштабирование размера текста и иконок - Proporzione Dimensioni Testo ed Icone + Proporzione e Dimensioni di Testo ed Icone 文字とアイコンの大きさ - 글자와 아이콘 크기 비례 + 글자와 아이콘 크기 비례합니다 文字和图示大小设定 文字和圖示大小設定 + Metin ve Simge Boyutu Ölçeklendirme - - Fade on screen border - Am Bildschirmrand ausblenden - 画面端では非表示 - Ukryj na brzegach ekranu - 화면 가장자리에서 사라짐 - Estomper sur les bords de l'écran - Sfocatura nei bordi dello schermo - 在荧幕边框旁淡出 - 在螢幕邊框旁淡出 - Затухание на границе экрана + + Default Nametag Color (Non Group Members) + Voreingestellte Namenfarbe (Spieler außerhalb der Gruppe) + Цвет меток игроков (не членов групп) + Color de etiquetas de nombre por defecto (No miembros de grupo) + Domyślny kolor imion (członkowie spoza grupy) + Couleur d'affichage par défaut (si dans aucun groupe) + Standardní barva jmenovek (pro nečleny jednotky) + Alap névcímke-szín (csoporton kívüli személyek) + Colore dei nomi non appartenenti al gruppo + Cor padrão do nome (unidades fora do grupo) + ネーム タグの標準色 (グループメンバー以外) + 기본 이름표 색상 (비그룹 멤버) + 预设名字颜色(非同小队队友) + 預設名稱顏色 (非同小隊隊友) + Varsayılan İsim Etiketi Rengi (Grup Üyeleri Olmayanlar) - - Player tags transparency - Spielernamen Transparenz - プレイヤー名札の透明度 - 玩家名字标签透明度 - 玩家名稱透明度 - Trasparenza Etichette Nome - Przezroczystość etykiet gracza - Прозрачность меток игроков + + Force Hide + Wymuś ukrycie + Ocultar forzado + Verstecken erzwingen + Vynuceno skrýt + Ocultar forçado + /!\ Module obsolète /!\ - Forcer le masquage + Erőltetett rejtett + Обязательно: Скрывать + Forza Nascosto + 非表示を強制 + 강제로 숨기기 + 强制隐藏 + 強迫隱藏 + Gizlemeye Zorla + + + Force Show + Wymuś wyświetlanie + Mostrar forzado + Anzeige erzwingen + Vynuceno zobrazit + Mostrar forçado + /!\ Module obsolète /!\ - Forcer l'affichage + Erőltetett látható + Обязательно: Показывать + Forza Visibili + 表示を強制 + 강제로 표시 + 强制显示 + 強迫顯示 + Göstermeye Zorla + + + Force Show Only on Cursor + Wymuś pod kursorem + Forzar mostrar solo en el cursor + Vynuceno zobrazit pouze na kurzor + Erzwinge nur mit Mauszeiger anzuzeigen + Forçar mostrar somente no cursor + /!\ Module obsolète /!\ - Forcer l'affichage sous le curseur uniquement + Erőltetett látható, csak kurzorra + Обязательно: Только под курсором + Forza Visibili solo su Cursore + カーソルを合わせた時のみ に強制する + 커서만 강제로 해당 + 强制仅显示在准心指到时 + 強制僅顯示在準心指到時 + Göstermeyi Yalnızca İmleç Üzerinde Zorla + + + Force Show Only on Keypress + Wymuś po wciśnięciu klawisza + Forzar mostrar solo al pulsar tecla + Vynuceno zobrazit pouze na klávesu + Erzwinge nur mit Tastendruck anzuzeigen + Forçar somente mostrar em tecla ativada + /!\ Module obsolète /!\ - Forcer l'affichage par appui de touche uniquement + Erőltetett látható, csak gombnyomásra + Обязательно: Только по нажатию клавиши + Forza Visibili solo quando Premi Tasto + キーを押した時のみ に強制 + 키를 누를 경우만 강제로 해당 + 强制仅显示在按按键时 + 強制僅顯示在按按鍵時 + Gösteriyi Yalnızca Tuşa Basıldığında Zorla + + + Force Show Only on Cursor and Keypress + Wymuś pod kursorem i po wciśnięciu klawisza + Forzar mostrar en el cursor y al pulsar tecla + Vynuceno zobrazit pouze na kurzor a klávesu + Erzwinge nur mit Mauszeiger und Tastendruck anzuzeigen + Forçar mostrar somente em cursor e tecla ativada + /!\ Module obsolète /!\ - Forcer l'affichage sous le curseur et par appui de touche uniquement + Erőltetett látható, csak kurzorra és gombnyomásra + Обязательно: Под курсором или по нажатию клавиши + Forza Mostra solo su Cursore e quando Premi Tasto + カーソルを合わせてキーを押した時のみ に強制 + 커서와 키를 누를 경우만 강제로 해당 + 强制显示在准心指到和按按键时 + 強制顯示在準心指到和按按鍵時 + Göstermeyi Yalnızca İmleç ve Tuşa Basmaya Zorla + + + Nametag Ambient Brightness Coefficient + Коэф. освещения для меток игроков + Coeff. di Luminosità Ambiente + ネーム タグ 環境明るさ係数 + Coefficient de luminosité ambiante + Spielernamen Umgebungshelligkeitskoeffizient + Współczynnik jasności otoczenia + 铭牌的环境亮度系数 + 이름표 배경 밝기 계수 + Coeficiente de brillo ambiental de Etiquetas de nombre + + + Adjusts how strongly ambient brightness affects nametag view distance. + Определяет как сильно окружающее освещение влияет на дальность отображения меток игроков. + Definisce quanto fortemente la luminosità dell'ambiente influenza la visibilità delle etichette nomi. + 周囲の明るさがネーム タグの表示距離にどの程度強く影響するかを調整します。 + Définit à quel point le manque de lumière ambiante abaisse la distance de visibilité du nom des joueurs. + Stellt ein, wie stark sich die Umgebungshelligkeit auf die Sichtweite der Spielernamen auswirkt. + Definiuje jak bardzo jasność otoczenia wpływa na zasięg wyświetlania imion postaci. + 调整环境亮度对铭牌查看距离的影响程度。 + 배경 밝기가 이름표를 보는 거리에 얼마나 영향을 끼치는 지를 조절합니다. + Ajusta cómo de fuerte afecta el brillo ambiental a la distancia de visión de las Etiquetas de nombre diff --git a/addons/nightvision/ACE_Arsenal_Stats.hpp b/addons/nightvision/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..e6d2a87c89 --- /dev/null +++ b/addons/nightvision/ACE_Arsenal_Stats.hpp @@ -0,0 +1,12 @@ +class EGVAR(arsenal,stats) { + class statBase; + class GVAR(generation): statBase { + scope = 2; + priority = 1.6; + condition = QUOTE('nvg' in (getArray ((_this select 1) >> 'visionMode') apply {toLowerANSI _x})); + displayName = CSTRING(NVGeneration); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_NVGeneration)); + tabs[] = {{8}, {}}; + }; +}; diff --git a/addons/nightvision/CfgEventHandlers.hpp b/addons/nightvision/CfgEventHandlers.hpp index 5f8c191f66..27d0d9ed28 100644 --- a/addons/nightvision/CfgEventHandlers.hpp +++ b/addons/nightvision/CfgEventHandlers.hpp @@ -1,16 +1,16 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/nightvision/CfgIRLaserSettings.hpp b/addons/nightvision/CfgIRLaserSettings.hpp new file mode 100644 index 0000000000..c42bc3a3cd --- /dev/null +++ b/addons/nightvision/CfgIRLaserSettings.hpp @@ -0,0 +1,3 @@ +class CfgIRLaserSettings { + maxNumberOfRays = 64; // Default is 24. +}; diff --git a/addons/nightvision/CfgWeapons.hpp b/addons/nightvision/CfgWeapons.hpp index a81835996f..3c9a98ad53 100644 --- a/addons/nightvision/CfgWeapons.hpp +++ b/addons/nightvision/CfgWeapons.hpp @@ -5,45 +5,140 @@ class CfgWeapons { modelOptics = ""; GVAR(border) = QPATHTOF(data\nvg_mask_binos_4096.paa); GVAR(bluRadius) = 0.15; + NVG_GREEN_PRESET; + }; + class ACE_NVGoggles_WP: NVGoggles { + displayName = CSTRING(NVG_Gen3_brown_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; }; class O_NVGoggles_hex_F: NVGoggles { // APEX NVG with multiple lenses (spider eyes) modelOptics = ""; GVAR(border) = QPATHTOF(data\nvg_mask_quad_4096.paa); // Use quad tube mask GVAR(bluRadius) = 0.26; + GVAR(generation) = 4; }; class NVGogglesB_grn_F: NVGoggles { // APEX NVG/Thermal modelOptics = "\A3\weapons_f_exp\reticle\ENVG.p3d"; // use vanilla modelOptics so it will show in IR mode + GVAR(generation) = 4; + }; + class NVGogglesB_blk_F: NVGoggles { + GVAR(generation) = 4; }; class NVGogglesB_gry_F: NVGoggles { modelOptics = "\A3\weapons_f_exp\reticle\ENVG.p3d"; + GVAR(generation) = 4; }; class NVGoggles_OPFOR: NVGoggles { modelOptics = ""; displayName = CSTRING(NVG_Gen3_black); }; + class ACE_NVGoggles_OPFOR_WP: NVGoggles_OPFOR { + displayName = CSTRING(NVG_Gen3_black_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; class NVGoggles_INDEP: NVGoggles { modelOptics = ""; displayName = CSTRING(NVG_Gen3_green); }; + class ACE_NVGoggles_INDEP_WP: NVGoggles_INDEP { + displayName = CSTRING(NVG_Gen3_green_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; class ACE_NVG_Gen1: NVGoggles_OPFOR { author = ECSTRING(common,ACETeam); - displayName = CSTRING(NVG_Gen1); + displayName = CSTRING(NVG_Gen1_black); GVAR(generation) = 1; }; + class ACE_NVG_Gen1_Brown: NVGoggles { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(NVG_Gen1_brown); + GVAR(generation) = 1; + }; + class ACE_NVG_Gen1_Green: NVGoggles_INDEP { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(NVG_Gen1_green); + GVAR(generation) = 1; + }; + class ACE_NVG_Gen2_Black: NVGoggles_OPFOR { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(NVG_Gen2_black); + GVAR(generation) = 2; + }; + class ACE_NVG_Gen2_Brown: NVGoggles { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(NVG_Gen2_brown); + GVAR(generation) = 2; + }; class ACE_NVG_Gen2: NVGoggles_INDEP { author = ECSTRING(common,ACETeam); - displayName = CSTRING(NVG_Gen2); + displayName = CSTRING(NVG_Gen2_green); GVAR(generation) = 2; }; + class ACE_NVG_Gen4_Black: NVGoggles_OPFOR { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(NVG_Gen4_black); + GVAR(generation) = 4; + }; + class ACE_NVG_Gen4_Black_WP: ACE_NVG_Gen4_Black { + displayName = CSTRING(NVG_Gen4_black_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; class ACE_NVG_Gen4: NVGoggles { author = ECSTRING(common,ACETeam); - displayName = CSTRING(NVG_Gen4); + displayName = CSTRING(NVG_Gen4_brown); GVAR(generation) = 4; }; + class ACE_NVG_Gen4_WP: ACE_NVG_Gen4 { + displayName = CSTRING(NVG_Gen4_brown_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; + class ACE_NVG_Gen4_Green: NVGoggles_INDEP { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(NVG_Gen4_green); + GVAR(generation) = 4; + }; + class ACE_NVG_Gen4_Green_WP: ACE_NVG_Gen4_Green { + displayName = CSTRING(NVG_Gen4_green_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; + class ACE_NVG_Wide_Black: NVGoggles_OPFOR { + author = ECSTRING(common,ACETeam); + modelOptics = QPATHTOF(models\ACE_nvg_wide_optics); + displayName = CSTRING(NVG_Wide_black); + GVAR(generation) = 4; + }; + class ACE_NVG_Wide_Black_WP: ACE_NVG_Wide_Black { + displayName = CSTRING(NVG_Wide_black_wP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; class ACE_NVG_Wide: NVGoggles { author = ECSTRING(common,ACETeam); modelOptics = QPATHTOF(models\ACE_nvg_wide_optics); - displayName = CSTRING(NVG_FullScreen); + displayName = CSTRING(NVG_Wide_brown); + GVAR(generation) = 4; + }; + class ACE_NVG_Wide_WP: ACE_NVG_Wide { + displayName = CSTRING(NVG_Wide_brown_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; + }; + class ACE_NVG_Wide_Green: NVGoggles_INDEP { + author = ECSTRING(common,ACETeam); + modelOptics = QPATHTOF(models\ACE_nvg_wide_optics); + displayName = CSTRING(NVG_Wide_green); + GVAR(generation) = 4; + }; + class ACE_NVG_Wide_Green_WP: ACE_NVG_Wide_Green { + displayName = CSTRING(NVG_Wide_green_WP); + descriptionShort = CSTRING(NVG_WP_desc); + NVG_WHITE_PRESET; }; diff --git a/addons/nightvision/README.md b/addons/nightvision/README.md index 469d83d942..85e5c530f0 100644 --- a/addons/nightvision/README.md +++ b/addons/nightvision/README.md @@ -2,11 +2,3 @@ ace_nightvision =============== Adds different types of NVGs with different levels of quality. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/nightvision/RscTitles.hpp b/addons/nightvision/RscTitles.hpp index 98c2b11cb3..1a4d030e01 100644 --- a/addons/nightvision/RscTitles.hpp +++ b/addons/nightvision/RscTitles.hpp @@ -22,7 +22,7 @@ class RscTitles { class Mask: RscPicture { idc = 1001; }; - + // Add blinders for side monitors for tripple monitors (mask won't cover them) class trippleHeadLeft: RscPicture { idc = 1002; diff --git a/addons/nightvision/XEH_PREP.hpp b/addons/nightvision/XEH_PREP.hpp index c212d22b18..988cfaa623 100644 --- a/addons/nightvision/XEH_PREP.hpp +++ b/addons/nightvision/XEH_PREP.hpp @@ -10,3 +10,4 @@ PREP(pfeh); PREP(refreshGoggleType); PREP(scaleCtrl); PREP(setupDisplayEffects); +PREP(statTextStatement_NVGeneration); diff --git a/addons/nightvision/XEH_postInit.sqf b/addons/nightvision/XEH_postInit.sqf index 44926ae7ac..5a1aa19b82 100644 --- a/addons/nightvision/XEH_postInit.sqf +++ b/addons/nightvision/XEH_postInit.sqf @@ -21,28 +21,24 @@ GVAR(ppeffectRadialBlur) = -1; GVAR(ppeffectColorCorrect) = -1; GVAR(ppeffectBlur) = -1; +GVAR(isUsingMagnification) = false; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { TRACE_4("settingsInitialized",GVAR(disableNVGsWithSights),GVAR(fogScaling),GVAR(noiseScaling),GVAR(effectScaling)); ["visionMode", LINKFUNC(onVisionModeChanged), false] call CBA_fnc_addPlayerEventHandler; - - // handle only brightness if effects are disabled - if (GVAR(effectScaling) == 0) exitWith { - GVAR(ppEffectNVGBrightness) = ppEffectCreate ["ColorCorrections", 1236]; - GVAR(ppEffectNVGBrightness) ppEffectForceInNVG true; - GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, (-3+3)/5 + 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; - GVAR(ppEffectNVGBrightness) ppEffectCommit 0; - }; - ["loadout", LINKFUNC(onLoadoutChanged), true] call CBA_fnc_addPlayerEventHandler; ["cameraView", LINKFUNC(onCameraViewChanged), true] call CBA_fnc_addPlayerEventHandler; ["vehicle", LINKFUNC(refreshGoggleType), false] call CBA_fnc_addPlayerEventHandler; ["turret", LINKFUNC(refreshGoggleType), true] call CBA_fnc_addPlayerEventHandler; + ["ACE_controlledUAV", LINKFUNC(refreshGoggleType)] call CBA_fnc_addEventHandler; - ["ace_firedPlayer", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler; - + // handle only brightness if effects are disabled + GVAR(ppEffectNVGBrightness) = ppEffectCreate ["ColorCorrections", 1236]; + GVAR(ppEffectNVGBrightness) ppEffectForceInNVG true; + GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, (-3+3)/5 + 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; + GVAR(ppEffectNVGBrightness) ppEffectCommit 0; + GVAR(ppEffectNVGBrightness) ppEffectEnable (GVAR(effectScaling) == 0); addMissionEventHandler ["Loaded", { // Restart UI vars on mission load if (GVAR(running)) then { @@ -65,7 +61,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, 1] call FUNC(changeNVGBrightness); @@ -77,7 +73,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, -1] call FUNC(changeNVGBrightness); diff --git a/addons/nightvision/XEH_preInit.sqf b/addons/nightvision/XEH_preInit.sqf index 9361d05015..8251bf8baf 100644 --- a/addons/nightvision/XEH_preInit.sqf +++ b/addons/nightvision/XEH_preInit.sqf @@ -6,6 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +// #9781 - register effects layer ASAP +QGVAR(display) cutText ["", "PLAIN"]; ADDON = true; diff --git a/addons/nightvision/config.cpp b/addons/nightvision/config.cpp index 8e33002c31..9028e6951e 100644 --- a/addons/nightvision/config.cpp +++ b/addons/nightvision/config.cpp @@ -4,7 +4,24 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; - weapons[] = {"ACE_NVG_Gen1", "ACE_NVG_Gen2", /*"ACE_NVG_Gen3",*/ "ACE_NVG_Gen4", "ACE_NVG_Wide"}; + weapons[] = { + "ACE_NVG_Gen1", + "ACE_NVG_Gen1_Brown", + "ACE_NVG_Gen1_Green", + "ACE_NVG_Gen2_Black", + "ACE_NVG_Gen2_Brown", + "ACE_NVG_Gen2", + /*"ACE_NVG_Gen3",*/ + "ACE_NVG_Gen4_Black", + "ACE_NVG_Gen4_Black_WP", + "ACE_NVG_Gen4", + "ACE_NVG_Gen4_WP", + "ACE_NVG_Gen4_Green", + "ACE_NVG_Gen4_Green_WP", + "ACE_NVG_Wide_Black", + "ACE_NVG_Wide", + "ACE_NVG_Wide_Green" + }; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); @@ -15,7 +32,9 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgIRLaserSettings.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "ACE_Settings.hpp" #include "RscTitles.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/nightvision/functions/fnc_changeNVGBrightness.sqf b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf index ffbdc45dea..1697fa907e 100644 --- a/addons/nightvision/functions/fnc_changeNVGBrightness.sqf +++ b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Change the brightness of the unit's NVG. diff --git a/addons/nightvision/functions/fnc_initModule.sqf b/addons/nightvision/functions/fnc_initModule.sqf index 4118360ccc..5c5ad01943 100644 --- a/addons/nightvision/functions/fnc_initModule.sqf +++ b/addons/nightvision/functions/fnc_initModule.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Initializes the settings for the disable NVGs in sight module. diff --git a/addons/nightvision/functions/fnc_nonDedicatedFix.sqf b/addons/nightvision/functions/fnc_nonDedicatedFix.sqf index 578099846d..63f8919eaf 100644 --- a/addons/nightvision/functions/fnc_nonDedicatedFix.sqf +++ b/addons/nightvision/functions/fnc_nonDedicatedFix.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the client who is the non-dedicated server turning on the fog effects. diff --git a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf index 09eb8e247f..6f03c2a3af 100644 --- a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf +++ b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut * Disables/re-enables NVGs when the player starts/stops aiming down his sight. @@ -20,10 +20,10 @@ params ["_unit", "_cameraView"]; TRACE_2("onCameraViewChanged",_unit,_cameraView); // Refresh goggle effect (e.g. switching to vehicle's NVG) -[] call FUNC(refreshGoggleType); +call FUNC(refreshGoggleType); if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { - if ((vehicle _unit == _unit) + if ((isNull objectParent _unit) || {isTurnedOut _unit} || {!([_unit] call EFUNC(common,hasHatch)) && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} diff --git a/addons/nightvision/functions/fnc_onFiredPlayer.sqf b/addons/nightvision/functions/fnc_onFiredPlayer.sqf index 19750891c9..5bc7ff621e 100644 --- a/addons/nightvision/functions/fnc_onFiredPlayer.sqf +++ b/addons/nightvision/functions/fnc_onFiredPlayer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2, Dslyecxi, PabstMirror * Change the blending when the player fires. Called from the unified fired EH only for the local player and his vehicle. @@ -16,9 +16,14 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; -TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); +TRACE_7("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -if ((!GVAR(running)) || {!GVAR(shutterEffects)} || {_weapon == "throw"} || {_weapon == "put"}) exitWith {}; +if ((!GVAR(running)) + || {!GVAR(shutterEffects)} + || {EGVAR(common,epilepsyFriendlyMode)} + || {_weapon == "throw"} + || {_weapon == "put"} +) exitWith {}; private _visibleFireCoef = 1; if (_unit == ace_player) then { @@ -50,7 +55,7 @@ _visibleFire = _visibleFireCoef * _visibleFire; if (_ammo isKindOf "BulletBase") then { _visibleFire = _visibleFire min 5; // Prevent every shot from triggering with HMG }; -TRACE_1("final", _visibleFire); +TRACE_1("final",_visibleFire); if (_visibleFire <= 1.5) exitWith {}; if ((random (linearConversion [1, 4, GVAR(nvgGeneration), 10, 20])) > _visibleFire) exitWith {}; diff --git a/addons/nightvision/functions/fnc_onLoadoutChanged.sqf b/addons/nightvision/functions/fnc_onLoadoutChanged.sqf index 59be659f53..ff4baadd4b 100644 --- a/addons/nightvision/functions/fnc_onLoadoutChanged.sqf +++ b/addons/nightvision/functions/fnc_onLoadoutChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, PabstMirror * Refreshes nvg effect if switching NVG goggles. @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ace_nightvision_fnc_onLoadoutChange + * [player] call ace_nightvision_fnc_onLoadoutChanged * * Public: No */ diff --git a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf index b4bdc7f4f9..8086b2d1a0 100644 --- a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf +++ b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, Dslyecxi, PabstMirror * Disables turning on NVGs while the player aims down his sight. @@ -19,7 +19,20 @@ params ["_unit", "_visionMode"]; TRACE_2("onVisionModeChanged",_unit,_visionMode); -// handle only brightness if effects are disabled +// Handle disableNVGsWithSights setting: +if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { + if ((isNull objectParent _unit) + || {isTurnedOut _unit} + || {!([_unit] call EFUNC(common,hasHatch)) + && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} + }) then { + if ((cameraView == "GUNNER") && {_visionMode > 0}) then { + _unit action ["NVGogglesOff", _unit]; + }; + }; +}; + +// Handle only brightness if effects are disabled if (GVAR(effectScaling) == 0) exitWith { GVAR(ppEffectNVGBrightness) ppEffectEnable (_visionMode == 1); }; @@ -31,21 +44,13 @@ if (_visionMode == 1) then { [true] call FUNC(setupDisplayEffects); [] call FUNC(refreshGoggleType); GVAR(PFID) = [LINKFUNC(pfeh), 0, []] call CBA_fnc_addPerFrameHandler; + GVAR(firedEHs) = [ + ["ace_firedPlayer", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler, + ["ace_firedPlayerVehicle", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler + ]; + TRACE_1("Added fired EHs",GVAR(firedEHs)); // Fade in from black when turning nvg on QGVAR(turnOnEffect) cutText ["", "BLACK IN", 2.5]; }; }; - -// Handle disableNVGsWithSights setting: -if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { - if ((vehicle _unit == _unit) - || {isTurnedOut _unit} - || {!([_unit] call EFUNC(common,hasHatch)) - && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} - }) then { - if ((cameraView == "GUNNER") && {_visionMode > 0}) then { - _unit action ["NVGogglesOff", _unit]; - }; - }; -}; diff --git a/addons/nightvision/functions/fnc_pfeh.sqf b/addons/nightvision/functions/fnc_pfeh.sqf index c889b59a47..dbd101631c 100644 --- a/addons/nightvision/functions/fnc_pfeh.sqf +++ b/addons/nightvision/functions/fnc_pfeh.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, PabstMirror * PFEH to handle refreshing effects. @@ -16,21 +16,27 @@ * Public: No */ -if ((currentVisionMode ACE_player) != 1) exitWith { +private _unit = ACE_player; + +if (currentVisionMode _unit != 1) exitWith { GVAR(running) = false; [false] call FUNC(setupDisplayEffects); [GVAR(PFID)] call CBA_fnc_removePerFrameHandler; GVAR(PFID) = -1; + (missionNamespace getVariable [QGVAR(firedEHs), []]) params [["_firedPlayerID", -1], ["_firedPlayerVehicleID", -1]]; + TRACE_2("removing fired EHs",_firedPlayerID,_firedPlayerVehicleID); + ["ace_firedPlayer", _firedPlayerID] call CBA_fnc_removeEventHandler; + ["ace_firedPlayerVehicle", _firedPlayerVehicleID] call CBA_fnc_removeEventHandler; }; if (EGVAR(common,OldIsCamera)) exitWith { if (GVAR(running)) then { - TRACE_2("pausing NVG for scripted camera",alive ACE_player,EGVAR(common,OldIsCamera)); + TRACE_2("pausing NVG for scripted camera",alive _unit,EGVAR(common,OldIsCamera)); GVAR(running) = false; [false] call FUNC(setupDisplayEffects); }; }; if (!GVAR(running)) then { - TRACE_1("Un-Pausing", GVAR(paused)); + TRACE_1("Un-Pausing",GVAR(paused)); GVAR(running) = true; [true] call FUNC(setupDisplayEffects); [] call FUNC(refreshGoggleType); @@ -39,9 +45,9 @@ if (!GVAR(running)) then { // Scale Border / Hex BEGIN_COUNTER(borderScaling); private _scale = (call EFUNC(common,getZoom)) * 1.12513; -if (!(GVAR(defaultPositionBorder) isEqualTo [])) then { +if (GVAR(defaultPositionBorder) isNotEqualTo []) then { // Prevents issues when "zooming out" on ultra wide monitors - The square mask would be narrower than the screen - if (((GVAR(defaultPositionBorder) select 2) * _scale) < safeZoneW) then { + if ((GVAR(defaultPositionBorder) select 2) * _scale < safeZoneW) then { _scale = safeZoneW / (GVAR(defaultPositionBorder) select 2); }; [(uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1000, GVAR(defaultPositionHex), _scale] call FUNC(scaleCtrl); @@ -51,6 +57,11 @@ if (!(GVAR(defaultPositionBorder) isEqualTo [])) then { }; END_COUNTER(borderScaling); +if (IS_MAGNIFIED isNotEqualTo GVAR(isUsingMagnification)) then { + GVAR(isUsingMagnification) = IS_MAGNIFIED; + GVAR(nextEffectsUpdate) = -1; +}; + if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { // Update radial blur as it depends on zoom level, so should be changed each frame like the border/hex if (GVAR(ppeffectRadialBlur) != -1) then { @@ -83,10 +94,11 @@ if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { private _fogApply = linearConversion [0, 1, _effectiveLight, ST_NVG_MAXFOG, ST_NVG_MINFOG, true]; // Modify blur if looking down scope - if ((cameraView == "GUNNER") && {[ACE_player] call CBA_fnc_canUseWeapon}) then { - if (currentWeapon ACE_player == "") exitWith {}; - if (currentWeapon ACE_player == primaryWeapon ACE_player) exitWith {_blurFinal = _blurFinal * linearConversion [0, 1, GVAR(aimDownSightsBlur), 1, ST_NVG_CAMERA_BLUR_SIGHTS_RIFLE]}; // Rifles are bad - if (currentWeapon ACE_player == handgunWeapon ACE_player) exitWith {_blurFinal = _blurFinal * linearConversion [0, 1, GVAR(aimDownSightsBlur), 1, ST_NVG_CAMERA_BLUR_SIGHTS_PISTOL]}; // Pistols aren't so bad + if (cameraView == "GUNNER" && {[_unit] call CBA_fnc_canUseWeapon && {!GVAR(isUsingMagnification)}}) then { + private _weapon = currentWeapon _unit; + if (_weapon == "") exitWith {}; + if (_weapon == primaryWeapon _unit) exitWith {_blurFinal = _blurFinal * linearConversion [0, 1, GVAR(aimDownSightsBlur), 1, ST_NVG_CAMERA_BLUR_SIGHTS_RIFLE]}; // Rifles are bad + if (_weapon == handgunWeapon _unit) exitWith {_blurFinal = _blurFinal * linearConversion [0, 1, GVAR(aimDownSightsBlur), 1, ST_NVG_CAMERA_BLUR_SIGHTS_PISTOL]}; // Pistols aren't so bad }; // Scale general effects based on ace_nightvision_effectScaling setting @@ -95,7 +107,7 @@ if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { _contrastFinal = linearConversion [0, 1, GVAR(effectScaling), 1, _contrastFinal]; // Add adjusted NVG brightness - private _playerBrightSetting = ACE_player getVariable [QGVAR(NVGBrightness), 0]; + private _playerBrightSetting = _unit getVariable [QGVAR(NVGBrightness), 0]; _brightFinal = _brightFinal + (_playerBrightSetting / 20); // Scale grain effects based on ace_nightvision_noiseScaling setting @@ -128,7 +140,7 @@ if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { // ColorCorrections - Changes brightness, contrast and "green" color of nvg // Params: [brightness(0..2), contrast(0..inf), offset(-x..+x), blendArray, colorizeArray, weightArray] GVAR(ppeffectColorCorrect) = ppEffectCreate ["ColorCorrections", 2003]; - GVAR(ppeffectColorCorrect) ppEffectAdjust [_brightFinal, _contrastFinal, 0, [0.0, 0.0, 0.0, 0.0], [1.3, 1.2, 0.0, 0.9], [6, 1, 1, 0.0]]; + GVAR(ppeffectColorCorrect) ppEffectAdjust [_brightFinal, _contrastFinal, GVAR(nvgOffset), GVAR(nvgBlend), GVAR(nvgColorize), GVAR(nvgWeight)]; GVAR(ppeffectColorCorrect) ppEffectCommit 0; GVAR(ppeffectColorCorrect) ppEffectForceInNVG true; GVAR(ppeffectColorCorrect) ppEffectEnable true; @@ -144,9 +156,12 @@ if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { // Modify local fog: if (GVAR(fogScaling) > 0) then { - if (((vehicle ACE_player) != ACE_player) && {(vehicle ACE_player) isKindOf "Air"}) then { // For flying in particular, can refine nicer later. + private _vehicle = vehicle _unit; + + if (_vehicle != _unit && {_vehicle isKindOf "Air"}) then { // For flying in particular, can refine nicer later. _fogApply = _fogApply * ST_NVG_AIR_FOG_MULTIPLIER; }; + _fogApply = linearConversion [0, 1, GVAR(priorFog) select 0, (GVAR(fogScaling) * _fogApply), 1]; // mix in old fog if present GVAR(nvgFog) = [_fogApply, 0, 0]; 0 setFog GVAR(nvgFog) diff --git a/addons/nightvision/functions/fnc_refreshGoggleType.sqf b/addons/nightvision/functions/fnc_refreshGoggleType.sqf index 8943784646..ccfbd017b6 100644 --- a/addons/nightvision/functions/fnc_refreshGoggleType.sqf +++ b/addons/nightvision/functions/fnc_refreshGoggleType.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, PabstMirror * Determines night vision source (player/vehicle) - Updates UI based on type. @@ -17,7 +17,7 @@ TRACE_1("refreshGoggleType",_this); -if (!GVAR(running)) exitWith {}; +if (!GVAR(running) || {GVAR(effectScaling) == 0}) exitWith {}; // Defaults (good for most vehicles/binoculars) private _borderImage = ""; @@ -26,43 +26,32 @@ private _hideHex = true; private _nvgGen = 3; private _blurRadius = -1; -if (alive ACE_player) then { +// Adds Array of Params / Original ACE3's (ST's) by default. (NVG_GREEN_PRESET) +private _preset = getArray (configFile >> "CfgWeapons" >> "NVGoggles" >> QGVAR(colorPreset)); + +if ((alive ACE_player) && {isNull (ACE_controlledUAV select 0)}) then { if (((vehicle ACE_player) == ACE_player) || { // Test if we are using player's nvg or if sourced from vehicle: private _currentVehicle = vehicle ACE_player; - private _vehConfig = configFile >> "CfgVehicles" >> (typeOf _currentVehicle); + private _vehConfig = configOf _currentVehicle; if (cameraView != "GUNNER") exitWith {true}; // asume hmd usage outside of gunner view + if ([ACE_player] call CBA_fnc_canUseWeapon) exitWith {true}; // FFV - if (ACE_player == (driver _currentVehicle)) exitWith { - !("NVG" in getArray (_vehConfig >> "ViewOptics" >> "visionMode")); - }; - private _result = true; - private _turret = ACE_player call CBA_fnc_turretPath; - private _turretConfig = [_currentVehicle, _turret] call CBA_fnc_getTurret; - - // Seems to cover things like the offroad technical - if ((isNumber (_turretConfig >> "optics")) && {(getNumber (_turretConfig >> "optics")) == 0}) exitWith {true}; - - private _turretConfigOpticsIn = _turretConfig >> "OpticsIn"; - if (isClass _turretConfigOpticsIn) then { - for "_index" from 0 to (count _turretConfigOpticsIn - 1) do { - if ("NVG" in getArray (_turretConfigOpticsIn select _index >> "visionMode")) exitWith {_result = false}; - }; - } else { - // No OpticsIn usualy means RCWS, still need to test on more vehicles - _result = false; - }; - _result + private _turret = _currentVehicle unitTurret ACE_player; // driver is [-1] + if (_turret isEqualTo []) exitWith { true }; + (_currentVehicle currentVisionMode _turret) params ["_turretVisionMode"]; + _turretVisionMode != 1 // if turret isn't giving nvg, then it must be unit's googles }) then { if ((cameraView == "GUNNER") && {currentWeapon ACE_player != ""} && {binocular ACE_player == currentWeapon ACE_player}) exitWith { TRACE_1("souce: binocular",binocular ACE_player); // Source is from player's binocular (Rangefinder/Vector21bNite) private _config = configFile >> "CfgWeapons" >> (binocular ACE_player); if (isNumber (_config >> QGVAR(generation))) then {_nvgGen = getNumber (_config >> QGVAR(generation));}; + if (isArray (_config >> QGVAR(colorPreset))) then {_preset = getArray (_config >> QGVAR(colorPreset));}; }; - TRACE_1("source: hmd",GVAR(playerHMD)); // Source is player's HMD (or possibly a NVG scope, but no good way to detect that) + TRACE_1("source: hmd",GVAR(playerHMD)); // Source is player's HMD (or possibly a NVG scope,but no good way to detect that) private _config = configFile >> "CfgWeapons" >> GVAR(playerHMD); if (!isClass _config) exitWith {}; @@ -74,7 +63,7 @@ if (alive ACE_player) then { if (isNumber (_config >> QGVAR(bluRadius))) then {_blurRadius = getNumber (_config >> QGVAR(bluRadius));}; }; if (isNumber (_config >> QGVAR(generation))) then {_nvgGen = getNumber (_config >> QGVAR(generation));}; - + if (isArray (_config >> QGVAR(colorPreset))) then {_preset = getArray (_config >> QGVAR(colorPreset));}; } else { TRACE_1("source: vehicle - defaults",typeOf vehicle ACE_player); }; @@ -85,9 +74,18 @@ systemChat format ["NVG Refresh - Border: %1", _borderImage]; systemChat format ["EyeCups: %1, HideHex %2, NVGen: %3, BluRadius: %4", _eyeCups, _hideHex, _nvgGen, _blurRadius]; #endif +// Selection cancelled, params added +_preset params ["_offset", "_blend", "_colorize", "_weight"]; + GVAR(nvgBlurRadius) = _blurRadius; GVAR(nvgGeneration) = _nvgGen; +// Additional Global variables for Params transfer & supporting +GVAR(nvgOffset) = _offset; +GVAR(nvgBlend) = _blend; +GVAR(nvgColorize) = _colorize; +GVAR(nvgWeight) = _weight; + // Setup border and hex image based on NVG config: private _scale = (call EFUNC(common,getZoom)) * 1.12513; diff --git a/addons/nightvision/functions/fnc_scaleCtrl.sqf b/addons/nightvision/functions/fnc_scaleCtrl.sqf index e01a798580..97ea69dde5 100644 --- a/addons/nightvision/functions/fnc_scaleCtrl.sqf +++ b/addons/nightvision/functions/fnc_scaleCtrl.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, PabstMirror * Determines night vision source (player/vehicle) - Updates UI based on type. diff --git a/addons/nightvision/functions/fnc_setupDisplayEffects.sqf b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf index 9137419202..6e480c1ca6 100644 --- a/addons/nightvision/functions/fnc_setupDisplayEffects.sqf +++ b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dslyecxi, PabstMirror * Handles setting up the effects: fog, ppEffects and the RscTittle. @@ -48,10 +48,9 @@ if (GVAR(fogScaling) > 0) then { }; }; -// Note: Using BIS_fnc_rscLayer because of bug with string syntax - https://feedback.bistudio.com/T120768 -(QGVAR(display) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; // Cleanup Old Display +QGVAR(display) cutText ["", "PLAIN"]; // Cleanup Old Display if (_activated) then { // Create New Display - (QGVAR(display) call BIS_fnc_rscLayer) cutRsc [QGVAR(title), "PLAIN", 0, false]; + QGVAR(display) cutRsc [QGVAR(title), "PLAIN", 0, false, false]; // draw under HUD }; // Cleanup Old PP Effects diff --git a/addons/nightvision/functions/fnc_statTextStatement_NVGeneration.sqf b/addons/nightvision/functions/fnc_statTextStatement_NVGeneration.sqf new file mode 100644 index 0000000000..08baf28998 --- /dev/null +++ b/addons/nightvision/functions/fnc_statTextStatement_NVGeneration.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Text statement for the NV Generation stat. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_nvGeneration",_config); + +private _gen = 3; // Default +if (isNumber (_config >> QGVAR(generation))) then { + _gen = getNumber (_config >> QGVAR(generation)); +}; + +format [localize LSTRING(statGen), _gen]; diff --git a/addons/nightvision/functions/script_component.hpp b/addons/nightvision/functions/script_component.hpp deleted file mode 100644 index d79af487d7..0000000000 --- a/addons/nightvision/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\nightvision\script_component.hpp" \ No newline at end of file diff --git a/addons/nightvision/initSettings.inc.sqf b/addons/nightvision/initSettings.inc.sqf new file mode 100644 index 0000000000..9d11956a12 --- /dev/null +++ b/addons/nightvision/initSettings.inc.sqf @@ -0,0 +1,84 @@ +[ + QGVAR(effectScaling), "SLIDER", + [LSTRING(effectScaling_DisplayName), LSTRING(effectScaling_Description)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + { + TRACE_1("effectScaling setting changed",_this); + GVAR(ppEffectNVGBrightness) ppEffectEnable ( + (GVAR(effectScaling) == 0) && {currentVisionMode ACE_player == 1} + ); + + if (GVAR(effectScaling) == 0) then { + // Destroy PFH & PP effects + GVAR(running) = false; + [false] call FUNC(setupDisplayEffects); + [GVAR(PFID)] call CBA_fnc_removePerFrameHandler; + GVAR(PFID) = -1; + GVAR(nextEffectsUpdate) = -1; + (missionNamespace getVariable [QGVAR(firedEHs), []]) params [["_firedPlayerID", -1], ["_firedPlayerVehicleID", -1]]; + TRACE_2("removing fired EHs",_firedPlayerID,_firedPlayerVehicleID); + ["ace_firedPlayer", _firedPlayerID] call CBA_fnc_removeEventHandler; + ["ace_firedPlayerVehicle", _firedPlayerVehicleID] call CBA_fnc_removeEventHandler; + } else { + // Start PFH if scaling was previously set to 0 + if ((currentVisionMode ACE_player == 1) && {!GVAR(running)}) then { + GVAR(running) = true; + [true] call FUNC(setupDisplayEffects); + [] call FUNC(refreshGoggleType); + + if (!isMultiplayer && {!isNull findDisplay 49}) then { + // Prevent duplicate effects when paused + GVAR(nextEffectsUpdate) = CBA_missionTime + 0.1; + }; + + GVAR(PFID) = [LINKFUNC(pfeh), 0, []] call CBA_fnc_addPerFrameHandler; + GVAR(firedEHs) = [ + ["ace_firedPlayer", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler, + ["ace_firedPlayerVehicle", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler + ]; + TRACE_1("Added fired EHs",GVAR(firedEHs)); + }; + }; + } +] call CBA_fnc_addSetting; +[ + QGVAR(fogScaling), "SLIDER", + [LSTRING(fogScaling_DisplayName), LSTRING(fogScaling_Description)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(noiseScaling), "SLIDER", + [LSTRING(noiseScaling_DisplayName), LSTRING(noiseScaling_Description)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(aimDownSightsBlur), "SLIDER", + [LSTRING(aimDownSightsBlur_DisplayName)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(disableNVGsWithSights), "CHECKBOX", + [LSTRING(DisableNVGsWithSights_DisplayName), LSTRING(DisableNVGsWithSights_description)], + localize LSTRING(Category), + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(shutterEffects), "CHECKBOX", + [LSTRING(shutterEffects_DisplayName), LSTRING(shutterEffects_description)], + localize LSTRING(Category), + true, // default value + false // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/nightvision/initSettings.sqf b/addons/nightvision/initSettings.sqf deleted file mode 100644 index 5b6492a2cb..0000000000 --- a/addons/nightvision/initSettings.sqf +++ /dev/null @@ -1,56 +0,0 @@ -// CBA Settings [ADDON: ace_nightVision]: - -[ - QGVAR(effectScaling), "SLIDER", - [LSTRING(effectScaling_DisplayName), LSTRING(effectScaling_Description)], - localize LSTRING(Category), - [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(effectScaling), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; -[ - QGVAR(fogScaling), "SLIDER", - [LSTRING(fogScaling_DisplayName), LSTRING(fogScaling_Description)], - localize LSTRING(Category), - [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(fogScaling), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(noiseScaling), "SLIDER", - [LSTRING(noiseScaling_DisplayName), LSTRING(noiseScaling_Description)], - localize LSTRING(Category), - [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(noiseScaling), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(aimDownSightsBlur), "SLIDER", - [LSTRING(aimDownSightsBlur_DisplayName)], - localize LSTRING(Category), - [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(aimDownSightsBlur), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(disableNVGsWithSights), "CHECKBOX", - [LSTRING(DisableNVGsWithSights_DisplayName), LSTRING(DisableNVGsWithSights_description)], - localize LSTRING(Category), - false, // default value - true, // isGlobal - {[QGVAR(disableNVGsWithSights), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(shutterEffects), "CHECKBOX", - [LSTRING(shutterEffects_DisplayName), LSTRING(shutterEffects_description)], - localize LSTRING(Category), - true, // default value - false, // isGlobal - {[QGVAR(shutterEffects), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; diff --git a/addons/nightvision/script_component.hpp b/addons/nightvision/script_component.hpp index 2f431c5407..68548ed39f 100644 --- a/addons/nightvision/script_component.hpp +++ b/addons/nightvision/script_component.hpp @@ -19,6 +19,9 @@ // Effect Settings / Magic values to tweak: +#define NVG_GREEN_PRESET GVAR(colorPreset)[] = {0, {0.0, 0.0, 0.0, 0.0}, {1.3, 1.2, 0.0, 0.9}, {6, 1, 1, 0.0}} +#define NVG_WHITE_PRESET GVAR(colorPreset)[] = {0.0, {0.0, 0.0, 0.0, 0.0}, {1.1, 0.8, 1.9, 0.9}, {1, 1, 6, 0.0}} + // Decreases fog when in air vehicles #define ST_NVG_AIR_FOG_MULTIPLIER 0.5 @@ -46,3 +49,5 @@ #define ST_NVG_NOISESHARPNESS_MIN 1.2 #define ST_NVG_NOISESHARPNESS_MAX 1 + +#define IS_MAGNIFIED (0.75 call CBA_fnc_getFOV select 1 > 3.01) diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index 827f318e20..1c1cd61ba7 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -4,141 +4,340 @@ ACE Nightvision ACE 暗視装置 - ACE Visione notturna + ACE Visione Notturna ACE-Nachtsicht ACE夜視鏡 - ACE夜视镜 + ACE 夜视仪 ACE Vision Nocturne ACE Noktowizja ACE ПНВ + ACE Visão Noturna + ACE Noční vidění + ACE Gece Görüşü + ACE visión nocturna + ACE 야간투시 - - NV Goggles (Gen1) - Noktovizor (Gen1) - JVN (Gen1) - NS-Brille (1. Gen.) - Occhiali notturni (Gen1) - Gogle noktowizyjne (Gen1) - Óculos de visão noturna (Gen1) - ПНВ (Gen1) - Gafas de visión nocturna (Gen1) - Éjjellátó szemüveg (1. Gen.) - 暗視装置 (第1世代) - 야투경 (1세대) - 夜视镜 (初代) - 夜視鏡 (初代) + + NV Goggles (Gen1, Brown) + JVN (Gen1, marron) + ПНВ (Gen1, Коричневый) + Visore Notturno (Gen1, Marrone) + NVゴーグル (第1世代、ブラウン) + Gogle noktowizyjne (Gen 1, Brązowe) + NS-Brille (1. Gen., braun) + 夜视仪(一代,棕色) + 아투경 (1세대, 갈색) + Gafas de visión nocturna (Gen1, Marrón) - - NV Goggles (Gen2) - Noktovizor (Gen2) - JVN (Gen2) - NS-Brille (2. Gen.) - Occhiali notturni (Gen2) - Gogle noktowizyjne (Gen2) - Óculos de visão noturna (Gen2) - ПНВ (Gen2) - Gafas de visión nocturna (Gen2) - Éjjellátó szemüveg (2. Gen.) - 暗視装置 (第2世代) - 야투경 (2세대) - 夜视镜 (二代) - 夜視鏡 (二代) + + NV Goggles (Gen1, Black) + JVN (Gen1, noires) + ПНВ (Gen1, Чёрный) + Visore Notturno (Gen1, Nero) + NVゴーグル (第1世代、ブラック) + Gogle noktowizyjne (Gen 1, Czarne) + NS-Brille (1. Gen., schwarz) + 夜视仪(一代,黑色) + 아투경 (1세대, 검정) + Gafas de visión nocturna (Gen1, Negro) + + + NV Goggles (Gen1, Green) + JVN (Gen1, vertes) + ПНВ (Gen1, Зелёный) + Visore Notturno (Gen1, Verde) + NVゴーグル (第1世代、グリーン) + Gogle noktowizyjne (Gen 1, Zielone) + NS-Brille (1. Gen., grün) + 夜视仪(一代,绿色) + 아투경 (1세대, 녹색) + Gafas de visión nocturna (Gen1, Verde) + + + NV Goggles (Gen2, Brown) + JVN (Gen2, marron) + ПНВ (Gen2, Коричневый) + Visore Notturno (Gen2, Marrone) + NVゴーグル (第2世代、ブラウン) + Gogle noktowizyjne (Gen 2, Brązowe) + NS-Brille (2. Gen., braun) + 夜视仪(二代,棕色) + 아투경 (2세대, 갈색) + Gafas de visión nocturna (Gen2, Marrón) + + + NV Goggles (Gen2, Black) + JVN (Gen2, noires) + ПНВ (Gen2, Чёрный) + Visore Notturno (Gen2, Nero) + NVゴーグル (第2世代、ブラック) + Gogle noktowizyjne (Gen 2, Czarne) + NS-Brille (2. Gen., schwarz) + 夜视仪(二代,黑色) + 아투경 (2세대, 검정) + Gafas de visión nocturna (Gen2, Negro) + + + NV Goggles (Gen2, Green) + NV Goggles (Gen2, vertes) + ПНВ (Gen2, Зелёный) + Visore Notturno (Gen2, Verde) + NVゴーグル (第2世代、グリーン) + Gogle noktowizyjne (Gen 2, Zielone) + NS-Brille (2. Gen., grün) + 夜视仪(二代,绿色) + 아투경 (2세대, 녹색) + Gafas de visión nocturna (Gen2, Verde) NV Goggles (Gen3) Noktovizor (Gen3) JVN (Gen3) NS-Brille (3. Gen.) - Occhiali notturni (Gen3) + Visore Notturno (Gen3) Gogle noktowizyjne (Gen3) Óculos de visão noturna (Gen3) ПНВ (Gen3) Gafas de visión nocturna (Gen3) Éjjellátó szemüveg (3. Gen.) - 暗視装置 (第3世代) + NVゴーグル (第3世代) 야투경 (3세대) - 夜视镜 (三代) + 夜视仪(三代) 夜視鏡 (三代) + GG Gözlüğü (3. Jen) NV Goggles (Gen3, Brown) Noktovizor (Gen3, hnědý) JVN (Gen3, marron) NS-Brille (3. Gen., braun) - Occhiali notturni (Gen3, Marroni) - Gogle noktowizyjne (Gen3, brązowe) + Visore Notturno (Gen3, Marrone) + Gogle noktowizyjne (Gen3, Brązowe) Óculos de visão noturna (Gen3, marrons) ПНВ (Gen3, Коричневый) - Gafas de visión nocturna (Gen3, marrón) + Gafas de visión nocturna (Gen3, Marrón) Éjjellátó szemüveg (3. Gen., barna) - 暗視装置 (第3世代、ブラウン) + NVゴーグル (第3世代、ブラウン) 야투경 (3세대, 갈색) - 夜视镜 (三代, 棕色) + 夜视仪(三代,棕色) 夜視鏡 (三代, 棕色) + GG Gözlüğü (3. Jen Kahverengi) + + + NV Goggles (Gen3, Brown, WP) + NVゴーグル (第3世代、ブラウン、白色蛍光) + Visore Notturno (Gen3, Marrone, FB) + Gogle noktowizyjne (Gen3, Brązowe, WP) + NS-Brille (3. Generation, Braun, WP) + 야투경 (3세대, 갈색, 백색광) + JVN (Gen3, marron, WP) + ПНВ (Gen3, Коричневый, БФ) + Gafas de visión nocturna (Gen3, Marrón, FB) + + + Night Vision Goggles, White Phosphor + ナイトビジョン・ゴーグル、白色蛍光 + Visore Notturno, Fosforo Bianco + Gogle noktowizyjne, Biały Fosfor + Nachtsichtbrille, weißer Phosphor + 백색광 야투경 + Jumelles Vision Nocturne, Phosphore blanc + Очки ночного видения, белый фосфор + Gafas de Visión Nocturna, Fósforo Blanco NV Goggles (Gen3, Green) Noktovizor (Gen3, zelený) JVN (Gen3, vertes) NS-Brille (3. Gen., grün) - Occhiali notturni (Gen3, Verdi) - Gogle noktowizyjne (Gen3, zielone) + Visore Notturno (Gen3, Verde) + Gogle noktowizyjne (Gen3, Zielone) Óculos de visão noturna (Gen3, verdes) ПНВ (Gen3, Зелёный) - Gafas de visión nocturna (Gen3, verde) + Gafas de visión nocturna (Gen3, Verde) Éjjellátó szemüveg (3. Gen., zöld) - 暗視装置 (第3世代、グリーン) + NVゴーグル (第3世代、グリーン) 야투경 (3세대, 녹색) - 夜视镜 (三代, 绿色) + 夜视仪(三代,绿色) 夜視鏡 (三代, 綠色) + GG Gözlüğü (3. Jen Yeşil) + + + NV Goggles (Gen3, Green, WP) + Visore Notturno (Gen3, Verde, FB) + NVゴーグル (第3世代、グリーン、白色蛍光) + Gogle noktowizyjne (Gen3, Zielone, WP) + NS-Brille (3. Generation, Grün, WP) + 야투경 (3세대, 녹색, 백색광) + JVN (Gen3, vertes, WP) + ПНВ (Gen3, Зелёный, БФ) + Gafas de visión nocturna (Gen3, Verde, FB) NV Goggles (Gen3, Black) Noktovizor (Gen3, černý) JVN (Gen3, noires) NS-Brille (3. Gen., schwarz) - Occhiali notturni (Gen3, Neri) - Gogle noktowizyjne (Gen3, czarne) + Visore Notturno (Gen3, Nero) + Gogle noktowizyjne (Gen3, Czarne) Óculos de visão noturna (Gen3, pretos) ПНВ (Gen3, Чёрный) - Gafas de visión nocturna (Gen3, negro) + Gafas de visión nocturna (Gen3, Negro) Éjjellátó szemüveg (3. Gen., fekete) - 暗視装置 (第3世代、ブラック) + NVゴーグル (第3世代、ブラック) 야투경 (3세대, 검정색) - 夜视镜 (三代, 黑色) + 夜视仪(三代,黑色) 夜視鏡 (三代, 黑色) + GG Gözlüğü (3. Jen Siyah) - - NV Goggles (Gen4) - Noktovizor (Gen4) - JVN (Gen4) - NS-Brille (4. Gen.) - Occhiali notturni (Gen4) - Gogle noktowizyjne (Gen4) - Óculos de visão noturna (Gen4) - ПНВ (Gen4) - Gafas de visión nocturna (Gen4) - Éjjellátó szemüveg (4. Gen.) - 暗視装置 (第4世代) - 야투경 (4세대) - 夜视镜 (四代) - 夜視鏡 (四代) + + NV Goggles (Gen3, Black, WP) + NVゴーグル (第3世代、ブラック、白色蛍光) + Visore Notturno (Gen3, Nero, FB) + Gogle noktowizyjne (Gen3, Czarne, WP) + NS-Brille (3. Generation, Schwarz, WP) + 야투경 (3세대, 검정, 백색광) + JVN (Gen3, noires, WP) + ПНВ (Gen3, Чёрный, БФ) + Gafas de visión nocturna (Gen3, Negro, FB) - - NV Goggles (Wide) - NS-Brille (Weitwinkel) - Gafas de visión nocturna (Panorámicas) - Gogle noktowizyjne (panoramiczne) - Noktovizor (Širokoúhlý) - ПНВ (Широкоугольный) - JVN (Large) - Éjjellátó szemüveg (széles látószögű) - Óculos de visão noturna (Panorâmico) - Occhiali notturni (Larghi) - 暗視装置 (ワイド) - 야투경 (넓음) - 夜视镜 (宽版) - 夜視鏡 (寬版) + + NV Goggles (Gen4, Brown) + JVN (Gen4, marron) + ПНВ (Gen4, Коричневый) + Visore Notturno (Gen4, Marrone) + NVゴーグル (第4世代、ブラウン) + Gogle noktowizyjne (Gen 4, Brązowe) + NS-Brille (4. Gen., braun) + 夜视仪(四代,棕色) + 야투경 (4세대, 갈색) + Gafas de visión nocturna (Gen4, Marrón) + + + NV Goggles (Gen4, Brown, WP) + NVゴーグル (第4世代、ブラウン、白色蛍光) + Visore Notturno (Gen4, Marrone, FB) + Gogle noktowizyjne (Gen 4, Brązowe, WP) + NS-Brille (4. Generation, Braun, WP) + 야투경 (4세대, 갈색, 백색광) + JVN (Gen4, marron, WP) + ПНВ (Gen4, Коричневый, БФ) + Gafas de visión nocturna (Gen4, Marrón, FB) + + + NV Goggles (Gen4, Black) + JVN (Gen4, noires) + ПНВ (Gen4, Чёрный) + Visore Notturno (Gen4, Nero) + NVゴーグル (第4世代、ブラック) + Gogle noktowizyjne (Gen 4, Czarne) + NS-Brille (4. Gen., schwarz) + 夜视仪(四代,黑色) + 야투경 (4세대, 검정) + Gafas de visión nocturna (Gen4, Negro) + + + NV Goggles (Gen4, Black, WP) + NVゴーグル (第4世代、ブラック、白色蛍光) + Visore Notturno (Gen4, Nero, FB) + Gogle noktowizyjne (Gen 4, Czarne, WP) + NS-Brille (4. Generation, Schwarz, WP) + 야투경 (4세대, 검정, 백색광) + JVN (Gen4, noires, WP) + ПНВ (Gen4, Чёрный, БФ) + Gafas de visión nocturna (Gen4, Negro, FB) + + + NV Goggles (Gen4, Green) + JVN (Gen4, vertes) + ПНВ (Gen4, Зелёный) + Visore Notturno (Gen4, Verde) + NVゴーグル (第4世代、グリーン) + Gogle noktowizyjne (Gen 4, Zielone) + NS-Brille (4. Gen., grün) + 夜视仪(四代,绿色) + 야투경 (4세대, 녹색) + Gafas de visión nocturna (Gen4, Verde) + + + NV Goggles (Gen4, Green, WP) + NVゴーグル (第4世代、グリーン、白色蛍光) + Visore Notturno (Gen4, Verde, FB) + Gogle noktowizyjne (Gen 4, Zielone, WP) + NS-Brille (4. Generation, Grün, WP) + 야투경 (4세대, 녹색, 백색광) + JVN (Gen4, vertes, WP) + ПНВ (Gen4, Зелёный, БФ) + Gafas de visión nocturna (Gen4, Verde, FB) + + + NV Goggles (Wide, Brown) + JVN (Large, marron) + ПНВ (Широкий, Коричневый) + Visore Notturno (Grandangolo, Marrone) + NVゴーグル (ワイド、ブラウン) + Gogle noktowizyjne (Szerokie, Brązowe) + NS-Brille (Weit, braun) + 夜视仪(宽,棕色) + 야투경 (넓음, 갈색) + Gafas de visión nocturna (Panorámicas, Marrón) + + + NV Goggles (Wide, Brown, WP) + NVゴーグル (ワイド、ブラウン、白色蛍光) + Visore Notturno (Grandangolo, Marrone, FB) + Gogle noktowizyjne (Szerokie, Brązowe, WP) + NS-Brille (Weit, Braun, WP) + 야투경 (넓음, 갈색, 백색광) + JVN (Large, marron, WP) + ПНВ (Широкий, Коричневый, БФ) + Gafas de visión nocturna (Panorámicas, Marrón, FB) + + + NV Goggles (Wide, Black) + JVN (Large, noires) + ПНВ (Широкий, Чёрный) + Visore Notturno (Grandangolo, Nero) + NVゴーグル (ワイド、ブラック) + Gogle noktowizyjne (Szerokie, Czarne) + NS-Brille (Weit, schwarz) + 夜视仪(宽,黑色) + 야투경 (넓음, 검정) + Gafas de visión nocturna (Panorámicas, Negro) + + + NV Goggles (Wide, Black, WP) + NVゴーグル (ワイド、ブラック、白色蛍光) + Visore Notturno (Grandangolo, Nero, FB) + Gogle noktowizyjne (Szerokie, Czarne, WP) + NS-Brille (Weit, Schwarz, WP) + 야투경 (넓음, 검정, 백색광) + JVN (Large, noires, WP) + ПНВ (Широкий, Чёрный, БФ) + Gafas de visión nocturna (Panorámicas, Negro, FB) + + + NV Goggles (Wide, Green) + JVN (Large, vertes) + ПНВ (Широкий, Зелёный) + Visore Notturno (Grandangolo, Verde) + NVゴーグル (ワイド、グリーン) + Gogle noktowizyjne (Szerokie, Zielone) + NS-Brille (Weit, grün) + 夜视仪(宽,绿色) + 야투경 (넓음, 녹색) + Gafas de visión nocturna (Panorámicas, Verde) + + + NV Goggles (Wide, Green, WP) + NVゴーグル (ワイド、グリーン、白色蛍光) + Visore Notturno (Grandangolo, Verde, FB) + Gogle noktowizyjne (Szerokie, Zielone, WP) + NS-Brille (Weit, Grün, WP) + 야투경 (넓음, 녹색, 백색광) + JVN (Large, vertes, WP) + ПНВ (Широкий, Зелёный, БФ) + Gafas de visión nocturna (Panorámicas, Verde, FB) Brightness: %1 @@ -153,8 +352,9 @@ Luminosità: %1 明度: %1 밝기: %1 - 亮度: %1 + 亮度:%1 亮度: %1 + Parlaklık: %1 Increase NVG Brightness @@ -169,8 +369,9 @@ Aumenta la luminosità dell'NVG 暗視装置の明度を上げる 야투경 밝기 높이기 - 增加夜视镜亮度 + 增加夜视仪亮度 增加夜視鏡亮度 + Gece Görüşü Parlaklığını Arttır Decrease NVG Brightness @@ -178,15 +379,16 @@ Disminuir el brillo de las NVG Zmniejsz czułość noktowizji Snížení jasu noktovizoru - Baisser la luminosité des JVN + Abaisser la luminosité des JVN Уменьшить яркость ПНВ Éjjellátó fényerejének csökkentése Diminuir Luminosidade do EVN Riduci la luminosità dell'NVG 暗視装置の明度を下げる 야투경 밝기 줄이기 - 减少夜视镜亮度 + 减少夜视仪亮度 減少夜視鏡亮度 + Gece Görüşü Parlaklığını Düşür Nightvision @@ -200,8 +402,9 @@ Vision nocturne 暗視装置 야간투시경 - 夜视 + 夜视仪 夜視 + Gece Görüşü Settings for night vision. @@ -212,118 +415,148 @@ Ustawienia noktowizorów Impostazioni per visione notturna. Parámetros para visión nocturna - Réglage pour la vision nocturne + Réglages pour la vision nocturne. 暗視装置の設定をします。 야간투시경 설정 - 设定夜视选项. + 设置夜视仪选项。 設定夜視選項 + Gece görüşü ayarı. Disable NVGs in scope Deakt. NS mit Visier Убирать ПНВ при прицеливании Desabilitar visão noturna nas lunetas - Zakázat NVG v zaměřovači + Zakázat noktovizor u puškohledů Wył. NVG przy celowaniu Disabilita NVG nei mirini Desactivar NVG en miras - Desactiver les JVN dans les viseurs. + Désactiver les JVN dans les viseurs スコープでは暗視装置を無効化 - 조준경 사용시 야투경 비활성화 - 使用瞄准镜时关闭夜视镜 + 조준경 사용 시 야투경 비활성화 + 使用瞄准镜时关闭夜视仪 使用瞄準鏡時關閉夜視鏡 + Gece görüşünü dürbünde kapat. 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. + Zabraňuje používání noktovizoru při použití mířidel. Uniemożliwia korzystanie z gogli noktowizyjnych przy celowaniu. Blocca l'uso di visori notturni mentre miri con ottiche. Desactiva el uso de gafas visión nocturna cuando se utilizan miras normales. Bloque l'usage des JVN pendant la visée. スコープで狙いを付けると、暗視装置を無効化します。 - 조준시 야투경의 사용을 제한합니다. - 此功能开启后,当要使用瞄准镜时,为避免夜视镜镜头碰撞到瞄准镜,会先拿开夜视镜后再进行瞄准镜瞄准。 + 조준 시 야투경의 사용을 제한합니다. + 此功能开启后,当要使用瞄准镜时,为避免夜视仪镜头碰撞到瞄准镜,会先拿开夜视仪后再进行瞄准镜瞄准。 此功能開啟後,當要使用瞄準鏡時,為避免夜視鏡鏡頭碰撞到瞄準鏡,會先拿開夜視鏡後再進行瞄準鏡瞄準 NVG Fog Scale - 暗視装置の霧の規模 + 暗視装置フォグ強度 Livello Nebbia NVG Nebel in Nachtsicht 夜視鏡霧氣程度 - 夜视镜雾气程度 + 夜视仪雾气程度 Épaisseur du brouillard (JVN) Skala Mgły NVG Степень размытия ПНВ + Escala de Névoa na NVG + Míra mlhy pro noktovizor + Escala de niebla NVG + 야투경 안개 규모 Fog is used to limit visibility. - 霧は視界制限のために使われます。 + 霧で視程を制限します。 La nebbia viene utilizzata per limitare la visibilità. Nebel wird genutzt, um die Sichtbarkeit einzuschränken. 透過霧氣來縮減夜視鏡的可視距離 - 透过雾气来缩减夜视镜的可视距离。 - Le brouillard est utilisé pour limiter la visibilité + 透过雾气来缩减夜视仪的可视距离。 + Le brouillard est utilisé pour limiter la visibilité. Mgła jest wykorzystywana do ograniczenia widoczności. Туман используется для ограничения видимости + Névoa é usada para limitar visibilidade. + Mlha je použita pro omezení dohledu. + Niebla es usada para limitar la visibilidad + 안개로 시야를 제한합니다 NVG Effect Scale - 暗視装置の効果規模 - Effetto livello NVG + 暗視装置エフェクト強度 + Livello dell'Effetto ACE NVG Nachtsichteffekte 夜視鏡效果程度 - 夜视镜效果程度 + 夜视仪效果程度 Intensité des effets Skala Efektów NVG Степень эффектов ПНВ + Intensidade de efeito da Visão Noturna + Míra efektu pro noktovizor + Escala del efecto NVG + 야투경 효과 스케일 Blur and brightness effects [Setting to 0 will disable ALL nightvision effects] ぼかしと粒子、明度効果 [0 に設定で全効果を無効化します] - Effetti di sfocatura e luminosità [Importare a 0 disabiliterà TUTTI gli effetti della visione notturna] + Effetti di sfocatura e luminosità [Importare a 0 disabiliterà TUTTI gli effetti ACE della visione notturna] Unschärfe und Helligkeitseffekte [Dies auf 0 zu setzen deaktiviert SÄMTLICHE Nachtsichteffekte] 調整模糊與亮度的效果。[設值為0會關閉所有夜視鏡的特殊效果] - 调整模糊与亮度的效果。[设值为0会关闭所有夜视镜的特殊效果] - Effets de flou et de luminosité [Règler cette option sur 0 désactivera TOUS les effets de vision nocturne] + 调整模糊与亮度的效果。[设值为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] + Rozostření a jas [Nastavení na 0 vypne VŠECHNY efekty nočního vidění] + Efectos de emborronado y brillo [Configuración a 0 deshabilita todos los efectos de visión nocturna] + 흐림과 밝기 효과 [0으로 설정하면 효과를 제거합니다] Aim Down Sights Blur - 照準器を覗く時にぼかし + 照準時のぼかし効果 Visierunschärfe 瞄準具模糊程度 瞄准具模糊程度 Flou de visée - Blur durante la mira + Sfoca la mira attraverso ottiche Rozmazanie podczas celowania z narządów celowniczych Размытие при опущеном прицеле + Borrão ao mirar + Rozostření při použití mířidel + Emborronado al mirar + 조준 시 조준경 흐림 NVG Noise Scale Intensität des Bildrauschens 夜視鏡雜訊程度 - 夜视镜杂讯程度 - 暗視装置のノイズ度 + 夜视仪噪声强度 + 暗視装置ノイズ強度 Intensité du bruit (JVN) - Fattore di Disturbo del NVG + Quantità di Disturbo del NVG Skala Szumu NVG Степень шума ПНВ + Intensidade de Ruído/Efeito Granulado + Míra šumu pro noktovizor + Escala de ruido/granulado NVG + 야투경 노이즈 규모 Image noise intensity when wearing NVGs Intensität des Bildrauschens im Nachtsichtgerät 調整配戴夜視鏡時畫面雜訊的多寡。 - 调整配戴夜视镜时画面杂讯的多寡。 - 暗視装置を使用時に起きる画像ノイズの強度です - Intensité du bruit de l'image lorsque vous portez des JVN - Intensità del disturbo dell'immagine quando i NVG sono equipaggiati + 调整配戴夜视仪时画面噪声的强度。 + 暗視装置使用時の画像ノイズの強度 + Intensité du bruit de l'image lorsque vous portez des JVN. + Intensità del disturbo nell'immagine degli NVG Intensywność efektu szumu podczas noszenia gogli noktowizyjnych Интенсивность шума при использовании ПНВ + Intensidade de Ruído de Imagem ao utilizar Visão Noturna + Intezita šumu při používání noktovizoru + Intensidad de ruido de la imagen cuando se usa NVG + 야투경 착용 시 보여지는 노이즈의 정도를 조절합니다 Shutter Effects @@ -332,20 +565,50 @@ 快门效果 快門效果 Effets d'obturateur - Effetti lampeggianti + Effetti "Shutter" Efekt Shutter Эффекты затвора + Efeito de Obturador + Efekt závěrky + Efecto 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 + Effet d'obturateur à rideau dû aux flashs du canon. + Effetto "Shutter" dato dall'abbagliamento del visore in risposta al lampo dello sparo Efekt rolling shutter z błysków wylotowych Эффект затвора при вспышках выстрелов + Efeito de rolamento de Obturador de flashes de focinho + Efekt závěrky z důsledku výšlehu při střelbě + Efecto obturador por los fogonazos de la boca del cañón + 총구화염에 의한 셔터효과를 구현합니다 + + + Night Vision Generation + 暗視装置の世代 + Generazione del NVG + Generacja gogli noktowizyjnych + Nachtsicht-Generation + 야투경 세대 + Génération de jumelles de vision nocturne + Генерация ночного видения + Generación de Visión Nocturna + + + Gen %1 + 第%1世代 + Gen %1 + Gen %1 + Gen %1 + %1세대 + Gen %1 + Генерация %1 + Gen %1 diff --git a/addons/nlaw/CfgEventhandlers.hpp b/addons/nlaw/CfgEventhandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/nlaw/CfgEventhandlers.hpp +++ b/addons/nlaw/CfgEventhandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/nlaw/README.md b/addons/nlaw/README.md index dd62b36014..2123e79be5 100644 --- a/addons/nlaw/README.md +++ b/addons/nlaw/README.md @@ -3,8 +3,3 @@ ace_nlaw Adds Predicted Line Of Sight guidance to the NLAW. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/nlaw/functions/fnc_attackProfile.sqf b/addons/nlaw/functions/fnc_attackProfile.sqf index acc4330083..9628974800 100644 --- a/addons/nlaw/functions/fnc_attackProfile.sqf +++ b/addons/nlaw/functions/fnc_attackProfile.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * NLAW missile guidance attack profile. @@ -24,7 +24,7 @@ _targetLaunchParams params ["", "", "_launchPos"]; _firedEH params ["","","","","","","_projectile"]; // Use seeker (if terminal) -if (!(_seekerTargetPos isEqualTo [0,0,0])) exitWith {_seekerTargetPos}; +if (_seekerTargetPos isNotEqualTo [0,0,0]) exitWith {_seekerTargetPos}; _attackProfileStateParams params ["_startTime", "_startLOS", "_yawChange", "_pitchChange"]; (_startLOS call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; @@ -56,5 +56,5 @@ if ((count _test) > 0) then { }; #endif -// TRACE_1("Adjusted target position", _returnTargetPos); +// TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/nlaw/functions/fnc_keyDown.sqf b/addons/nlaw/functions/fnc_keyDown.sqf index fcc320360c..5b75c72140 100644 --- a/addons/nlaw/functions/fnc_keyDown.sqf +++ b/addons/nlaw/functions/fnc_keyDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the track key being held down. @@ -19,8 +19,8 @@ TRACE_1("lock key down",GVAR(isLockKeyDown)); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; if ((getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0) exitWith {}; if (GVAR(isLockKeyDown)) exitWith {ERROR("already running?");}; @@ -65,7 +65,7 @@ playSound "ACE_Sound_Click"; _args set [3, false]; } else { // smoothing factor alpha - higher values will be more responsive to change, but also spike higher on jerky mouse movmeent - private _alpha = _deltaT / 3; + private _alpha = _deltaT / 3; GVAR(yawChange) = (_yawChange * _alpha) + GVAR(yawChange) * (1 - _alpha); GVAR(pitchChange) = (_pitchChange * _alpha) + GVAR(pitchChange) * (1 - _alpha); }; diff --git a/addons/nlaw/functions/fnc_onFired.sqf b/addons/nlaw/functions/fnc_onFired.sqf index 0552afcd86..11b38a1da0 100644 --- a/addons/nlaw/functions/fnc_onFired.sqf +++ b/addons/nlaw/functions/fnc_onFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Sets up missile guidance state arrays (called from missileGuidance's onFired). diff --git a/addons/nlaw/functions/fnc_seeker.sqf b/addons/nlaw/functions/fnc_seeker.sqf index eeb2e0794c..e5de6d320c 100644 --- a/addons/nlaw/functions/fnc_seeker.sqf +++ b/addons/nlaw/functions/fnc_seeker.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the top down attack seeker for missile guidance. @@ -54,7 +54,7 @@ if ((_projPos distance _launchPos) >= 20) then { // Limit scan to 5 meters directly down (shaped charge jet has a very limited range) private _res = lineIntersectsSurfaces [_virtualPos, (_virtualPos vectorAdd [0,0,-5]), _projectile]; - if (!(_res isEqualTo [])) then { + if (_res isNotEqualTo []) then { (_res select 0) params ["_targetPos", "", "_target"]; if ((_target isKindOf "Tank") || {_target isKindOf "Car"} || {_target isKindOf "Air"}) exitWith { TRACE_3("Firing shaped charge down",_target,_targetPos distance _virtualPos,_frameDistance); @@ -74,7 +74,7 @@ if ((_projPos distance _launchPos) >= 20) then { _shapedCharage setVelocity [0,0,-300]; _seekerStateParams set [1, true]; - + END_COUNTER(targetScan); breakOut "targetScan"; }; diff --git a/addons/nlaw/functions/script_component.hpp b/addons/nlaw/functions/script_component.hpp deleted file mode 100644 index 50d8cac4c1..0000000000 --- a/addons/nlaw/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\nlaw\script_component.hpp" diff --git a/addons/nlaw/stringtable.xml b/addons/nlaw/stringtable.xml index bd642d49e5..0d2eaca93a 100644 --- a/addons/nlaw/stringtable.xml +++ b/addons/nlaw/stringtable.xml @@ -4,13 +4,18 @@ NLAW Track Target (Hold) NLAW Zielverfolgung - NLAW Traccia Bersaglio (Mantieni) - NALW 目標の追跡 (押しっぱ) - 次世代轻型反坦克导弹发射器追踪目标 (按住) + NLAW Traccia Bersaglio (Tieni Premuto) + NLAW 目標追跡 (ホールド) + NLAW 追踪目标(按住) 次世代輕型反坦克導彈發射器追蹤目標 (按住) Śledzenie Celu NLAW (Przytrzymaj) NLAW 목표 추적 (누름유지) - NLAW наведение на цель (Удерживать) + NLAW наведение на цель (удерживать) + NLAW Rastrear Alvo (Segurar) + NLAW suivre la cible (maintenir) + NLAW sledování cíle (držet) + NLAW Track Target (Basılı Tut) + NLAW Seguir objetivo (Mantener) Direct Attack @@ -20,19 +25,29 @@ 直射模式 直射模式 Bezpośredni atak - 직접 사격 + 직사 타격 Прямая атака + Ataque Direto + Attaque directe + Přímý útok + Doğrudan Saldırı + Ataque directo Overfly Top Attack Überflugangriff Attacco dall'alto オーバーフライ トップ アタック - 攻顶模式 + 飞越攻顶模式 攻頂模式 Atak z góry - 탑어택 + 상부 타격 Атака сверху + Ataque por cima + Attaque par le haut + Útok zvrchu při přeletu + Yüksek Uçuş Saldırı + Ataque desde arriba diff --git a/addons/noidle/README.md b/addons/noidle/README.md index 4ea313bd57..3d6a40ec37 100644 --- a/addons/noidle/README.md +++ b/addons/noidle/README.md @@ -2,10 +2,3 @@ ace_noidle =========== Removes idle animations. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/noradio/CfgEventhandlers.hpp b/addons/noradio/CfgEventhandlers.hpp index b928bc2de6..9b160c1600 100644 --- a/addons/noradio/CfgEventhandlers.hpp +++ b/addons/noradio/CfgEventhandlers.hpp @@ -1,5 +1,5 @@ class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/noradio/README.md b/addons/noradio/README.md index 95abf72b6f..98a2fb5c66 100644 --- a/addons/noradio/README.md +++ b/addons/noradio/README.md @@ -2,11 +2,3 @@ ace_noradio =========== Disables the automatic callouts for player units. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [bux578](https://github.com/bux578) diff --git a/addons/noradio/XEH_preInit.sqf b/addons/noradio/XEH_preInit.sqf index 61492aa36d..75f7afa62e 100644 --- a/addons/noradio/XEH_preInit.sqf +++ b/addons/noradio/XEH_preInit.sqf @@ -27,13 +27,4 @@ if (hasInterface) then { }, true] call CBA_fnc_addPlayerEventHandler; }; -[QGVAR(enabled), "CHECKBOX", [LSTRING(setting), LSTRING(setting_tooltip)], format ["ACE %1", localize ELSTRING(common,DisplayName)], true, true, { - params ["_enabled"]; - - if (_enabled) then { - [ACE_player, "isPlayer"] call EFUNC(common,muteUnit); - } else { - [ACE_player, "isPlayer"] call EFUNC(common,unmuteUnit); - }; -}, true // Needs mission restart -] call CBA_settings_fnc_init; +#include "initSettings.inc.sqf" diff --git a/addons/noradio/initSettings.inc.sqf b/addons/noradio/initSettings.inc.sqf new file mode 100644 index 0000000000..5c558064da --- /dev/null +++ b/addons/noradio/initSettings.inc.sqf @@ -0,0 +1,15 @@ +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(setting), LSTRING(setting_tooltip)], + [LELSTRING(Common,CategoryUncategorized), LLSTRING(DisplayName)], + true, + true, { + params ["_enabled"]; + + if (_enabled) then { + [ACE_player, "isPlayer"] call EFUNC(common,muteUnit); + } else { + [ACE_player, "isPlayer"] call EFUNC(common,unmuteUnit); + }; +}, true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/noradio/stringtable.xml b/addons/noradio/stringtable.xml index 99124dbca5..d1cf51f0e6 100644 --- a/addons/noradio/stringtable.xml +++ b/addons/noradio/stringtable.xml @@ -1,7 +1,19 @@ - - + + + No Radio + 去无线电 + Kein Funkgerät + Nessuna Radio + 음소거 + Brak Radia + 無線無効化 + Нет рации + No Radio + Pas de radio + + Mute Player Spieler stummschalten Muta Giocatore @@ -10,16 +22,28 @@ プレイヤーをミュート Wycisz Gracza Заглушить игрока + Silenciar Jogador + Joueur en sourdine + Ztlumit hráče + Oyuncuyu Sustur + Ensordecer jugador + 플레이어 음소거 - + Mutes the controlled player avatar. Schaltet eigenen Spieleravatar stumm. Muta l'avatar del giocatore controllato. 靜音玩家所控制的角色 静音玩家所控制的角色。 - プレイヤーに操作されているこのキャラをミュートします。 + プレイヤーに操作されているキャラをミュートします。 Wycisza awatar kontrolowany przez gracza Заглушить контролируемого игрока + Silencia o avatar do Jogador controlado + Met en sourdine l'avatar du joueur. + Vypne hlas charakteru hráče. + Oyuncuları Susturur + Ensordecer el avatar del jugador controlado + 플레이어 아바타를 음소거합니다 diff --git a/addons/norearm/README.md b/addons/norearm/README.md index f0035e5749..f83eea021b 100644 --- a/addons/norearm/README.md +++ b/addons/norearm/README.md @@ -2,10 +2,3 @@ ace_norearm =========== Removes rearm action. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/novehicleclanlogo/$PBOPREFIX$ b/addons/novehicleclanlogo/$PBOPREFIX$ new file mode 100644 index 0000000000..8232a79524 --- /dev/null +++ b/addons/novehicleclanlogo/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\novehicleclanlogo diff --git a/addons/novehicleclanlogo/CfgEventHandlers.hpp b/addons/novehicleclanlogo/CfgEventHandlers.hpp new file mode 100644 index 0000000000..6c29240403 --- /dev/null +++ b/addons/novehicleclanlogo/CfgEventHandlers.hpp @@ -0,0 +1,18 @@ + +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/novehicleclanlogo/README.md b/addons/novehicleclanlogo/README.md new file mode 100644 index 0000000000..4a058d99ba --- /dev/null +++ b/addons/novehicleclanlogo/README.md @@ -0,0 +1,4 @@ +novehicleclanlogo +============= + +Prevents clan logo from being displayed on vehicles controlled by players. diff --git a/addons/novehicleclanlogo/XEH_PREP.hpp b/addons/novehicleclanlogo/XEH_PREP.hpp new file mode 100644 index 0000000000..a835a8884f --- /dev/null +++ b/addons/novehicleclanlogo/XEH_PREP.hpp @@ -0,0 +1 @@ +PREP(removeClanLogo); diff --git a/addons/novehicleclanlogo/XEH_postInit.sqf b/addons/novehicleclanlogo/XEH_postInit.sqf new file mode 100644 index 0000000000..ec2049c4a1 --- /dev/null +++ b/addons/novehicleclanlogo/XEH_postInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +// clan logos are not used in singleplayer +if (!isMultiplayer) exitWith {}; + +["CBA_settingsInitialized", { + TRACE_1("settingsInit eh",GVAR(enabled)); + + if (isServer && {GVAR(enabled)}) then { + ["LandVehicle", "initPost", LINKFUNC(removeClanLogo), true, [], true] call CBA_fnc_addClassEventHandler; + ["Air", "initPost", LINKFUNC(removeClanLogo), true, [], true] call CBA_fnc_addClassEventHandler; + ["Ship", "initPost", LINKFUNC(removeClanLogo), true, [], true] call CBA_fnc_addClassEventHandler; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/novehicleclanlogo/XEH_preInit.sqf b/addons/novehicleclanlogo/XEH_preInit.sqf new file mode 100644 index 0000000000..894773534a --- /dev/null +++ b/addons/novehicleclanlogo/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/novehicleclanlogo/XEH_preStart.sqf b/addons/novehicleclanlogo/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/novehicleclanlogo/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/novehicleclanlogo/config.cpp b/addons/novehicleclanlogo/config.cpp new file mode 100644 index 0000000000..77c7dce638 --- /dev/null +++ b/addons/novehicleclanlogo/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"veteran29"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" diff --git a/addons/novehicleclanlogo/functions/fnc_removeClanLogo.sqf b/addons/novehicleclanlogo/functions/fnc_removeClanLogo.sqf new file mode 100644 index 0000000000..9274172140 --- /dev/null +++ b/addons/novehicleclanlogo/functions/fnc_removeClanLogo.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Replaces the vehicle clan logo with an empty texture. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [vehicle player] call ace_novehicleclanlogo_fnc_removeClanLogo + * + * Public: Yes + */ + +params ["_vehicle"]; + +private _selectionClan = getText (configOf _vehicle >> "selectionClan"); +if !(_selectionClan in selectionNames _vehicle) exitWith { + TRACE_2("vehicle does not have 'selectionClan' selection",_vehicle,_selectionClan); +}; + +if (_vehicle getVariable [QEGVAR(tagging,hasTag), false]) exitWith { + TRACE_1("vehicle has tag applied",_vehicle); +}; + +TRACE_1("replacing clan logo with empty texture",_vehicle); +_vehicle setObjectTextureGlobal [_selectionClan, "#(argb,1,1,1)color(0,0,0,0)"] // return diff --git a/addons/novehicleclanlogo/initSettings.inc.sqf b/addons/novehicleclanlogo/initSettings.inc.sqf new file mode 100644 index 0000000000..ddec0e1314 --- /dev/null +++ b/addons/novehicleclanlogo/initSettings.inc.sqf @@ -0,0 +1,11 @@ +private _category = [ELSTRING(common,ACEKeybindCategoryVehicles), LSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LELSTRING(common,Enabled), LSTRING(Enabled_Tooltip)], + _category, + false, + true, + {}, + true +] call CBA_fnc_addSetting; diff --git a/addons/novehicleclanlogo/script_component.hpp b/addons/novehicleclanlogo/script_component.hpp new file mode 100644 index 0000000000..eef91354bd --- /dev/null +++ b/addons/novehicleclanlogo/script_component.hpp @@ -0,0 +1,16 @@ +#define COMPONENT novehicleclanlogo +#define COMPONENT_BEAUTIFIED No Vehicle Clan Logo +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE + +#ifdef DEBUG_ENABLED_NOVEHICLECLANLOGO + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_ENABLED_NOVEHICLECLANLOGO + #define DEBUG_SETTINGS DEBUG_ENABLED_NOVEHICLECLANLOGO +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/novehicleclanlogo/stringtable.xml b/addons/novehicleclanlogo/stringtable.xml new file mode 100644 index 0000000000..96d463f582 --- /dev/null +++ b/addons/novehicleclanlogo/stringtable.xml @@ -0,0 +1,27 @@ + + + + + Remove clan logo from vehicles + Usuń logo klanu z pojazdów + 차량에서 클랜 로고 제거 + Убрать логотип отрядов с техники + Suprimir logo del clan de los vehículos + 乗り物から部隊ロゴを削除 + Clan-Logo von Fahrzeugen entfernen + Rimuovi Icone Clan dai veicoli + Retirer les logos de clan des véhicules + + + Prevents clan logo from being displayed on vehicles controlled by players. + Zapobiega wyświetlaniu logo klanu na pojazdach kontrolowanych przez graczy. + 플레이어가 조종하는 차량에 클랜 로고가 표시되지 않도록 합니다. + Не отображать логотипы отрядов на технике контроллируемой игроками. + Previene que se muestre el logo del clan en los vehículos controlados por jugadores. + プレイヤーが操作する乗り物に部隊ロゴが表示されないようにする。 + Verhindert, dass das Clan-Logo auf von Spielern kontrollierten Fahrzeugen angezeigt wird. + Impedisce la visualizzazione di icone clan sui veicoli controllati da giocatori. + Empêche les logos de clan d'être affichés sur les véhicules contrôlés par des joueurs. + + + diff --git a/addons/optics/CfgEventHandlers.hpp b/addons/optics/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/optics/CfgEventHandlers.hpp +++ b/addons/optics/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/optics/CfgJointRails.hpp b/addons/optics/CfgJointRails.hpp index 86c962afe5..5489b1c4fe 100644 --- a/addons/optics/CfgJointRails.hpp +++ b/addons/optics/CfgJointRails.hpp @@ -13,3 +13,35 @@ class asdg_OpticRail1913: asdg_OpticRail { ACE_optic_LRPS_PIP = 1; }; }; + +// Vanilla rails +class SlotInfo; +class CowsSlot: SlotInfo { + compatibleItems[] += { + "ACE_optic_Hamr_2D", + "ACE_optic_Hamr_PIP", + "ACE_optic_Arco_2D", + "ACE_optic_Arco_PIP", + "ACE_optic_MRCO_2D", + "ACE_optic_MRCO_PIP", + "ACE_optic_SOS_2D", + "ACE_optic_SOS_PIP", + "ACE_optic_LRPS_2D", + "ACE_optic_LRPS_PIP" + }; +}; + +class CowsSlot_Rail: CowsSlot { + class compatibleItems { + ACE_optic_Hamr_2D = 1; + ACE_optic_Hamr_PIP = 1; + ACE_optic_Arco_2D = 1; + ACE_optic_Arco_PIP = 1; + ACE_optic_MRCO_2D = 1; + ACE_optic_MRCO_PIP = 1; + ACE_optic_SOS_2D = 1; + ACE_optic_SOS_PIP = 1; + ACE_optic_LRPS_2D = 1; + ACE_optic_LRPS_PIP = 1; + }; +}; diff --git a/addons/optics/CfgRscTitles.hpp b/addons/optics/CfgRscTitles.hpp index 3df4632e16..bb01281a22 100644 --- a/addons/optics/CfgRscTitles.hpp +++ b/addons/optics/CfgRscTitles.hpp @@ -68,10 +68,10 @@ class RscInGameUI { text = ""; colorText[] = {1, 1, 1, 0}; colorBackground[] = {0, 0, 0, 0}; - x = safezoneX + 0.5 * safezoneW - 0.5 * SIZEX; - y = safezoneY + 0.5 * safezoneH - 0.5 * SIZEX * (4 / 3); - w = SIZEX; - h = SIZEX * (4 / 3); + x = QUOTE(safezoneX + 0.5 * safezoneW - 0.5 * SIZEX); + y = QUOTE(safezoneY + 0.5 * safezoneH - 0.5 * SIZEX * (4 / 3)); + w = QUOTE(SIZEX); + h = QUOTE(SIZEX * (4 / 3)); }; class ReticleNight: ReticleDay { @@ -84,10 +84,10 @@ class RscInGameUI { class BodyDay: ReticleDay { idc = 1713005; text = ""; - x = safezoneX + 0.5 * safezoneW - 0.5 * SIZEX; - y = safezoneY + 0.5 * safezoneH - 0.5 * SIZEX * (4 / 3); - w = SIZEX; - h = SIZEX * (4 / 3); + x = QUOTE(safezoneX + 0.5 * safezoneW - 0.5 * SIZEX); + y = QUOTE(safezoneY + 0.5 * safezoneH - 0.5 * SIZEX * (4 / 3)); + w = QUOTE(SIZEX); + h = QUOTE(SIZEX * (4 / 3)); }; class BodyNight: BodyDay { @@ -109,7 +109,7 @@ class RscInGameUI { class trippleHeadRight: trippleHeadLeft { idc = 1713011; x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4) / (16 / 3))"; - colorBackground[] = {0, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 1}; }; }; diff --git a/addons/optics/CfgWeapons.hpp b/addons/optics/CfgWeapons.hpp index c9dfbb8d7b..8088a5fcd3 100644 --- a/addons/optics/CfgWeapons.hpp +++ b/addons/optics/CfgWeapons.hpp @@ -307,20 +307,3 @@ class CfgWeapons { }; }; }; - -class SlotInfo; -class CowsSlot: SlotInfo { - compatibleItems[] += { - "ACE_optic_Hamr_2D", - "ACE_optic_Hamr_PIP", - "ACE_optic_Arco_2D", - "ACE_optic_Arco_PIP", - "ACE_optic_MRCO_2D", - "ACE_optic_MRCO_PIP", - "ACE_optic_SOS_2D", - "ACE_optic_SOS_PIP", - "ACE_optic_LRPS_2D", - "ACE_optic_LRPS_PIP" - //"ACE_optic_DMS" - }; -}; diff --git a/addons/optics/README.md b/addons/optics/README.md index a5224267b7..da4acac567 100644 --- a/addons/optics/README.md +++ b/addons/optics/README.md @@ -2,10 +2,3 @@ ace_optics =============== Adds animated 2D and PiP (picture-in-picture) optics. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/optics/XEH_postInit.sqf b/addons/optics/XEH_postInit.sqf index abb97e5b5d..1641ee2174 100644 --- a/addons/optics/XEH_postInit.sqf +++ b/addons/optics/XEH_postInit.sqf @@ -28,4 +28,4 @@ GVAR(camera) = objNull; }] call CBA_fnc_addPlayerEventHandler; // Register fire event handler -["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; diff --git a/addons/optics/functions/fnc_handleFired.sqf b/addons/optics/functions/fnc_handleFired.sqf index fbcb177f2e..f36f04d881 100644 --- a/addons/optics/functions/fnc_handleFired.sqf +++ b/addons/optics/functions/fnc_handleFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Taosenai * Adapted By: KoffeinFlummi, commy2 @@ -18,7 +18,7 @@ */ // IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); disableSerialization; diff --git a/addons/optics/functions/fnc_onDrawScope.sqf b/addons/optics/functions/fnc_onDrawScope.sqf index 22b9ddc2b2..4b1b9e321d 100644 --- a/addons/optics/functions/fnc_onDrawScope.sqf +++ b/addons/optics/functions/fnc_onDrawScope.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/optics/functions/fnc_onDrawScope2D.sqf b/addons/optics/functions/fnc_onDrawScope2D.sqf index 9031ca8ba7..c7fb19c9c1 100644 --- a/addons/optics/functions/fnc_onDrawScope2D.sqf +++ b/addons/optics/functions/fnc_onDrawScope2D.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Helper function for updating the 2d and 3d scope controls @@ -80,11 +80,11 @@ if (_isPIP) then { // Calculate lighting private _dayOpacity = call EFUNC(common,ambientBrightness); -private _nightOpacity = [1, 0] select (_dayOpacity == 1); +private _nightOpacity = parseNumber (_dayOpacity == 1); // Apply lighting and make layers visible (_display displayCtrl 1713001) ctrlSetTextColor [1, 1, 1, 1]; -(_display displayCtrl 1713002) ctrlSetTextColor [1, 1, 1, [0, 1] select (_dayOpacity < 0.5)]; +(_display displayCtrl 1713002) ctrlSetTextColor [1, 1, 1, parseNumber (_dayOpacity < 0.5)]; (_display displayCtrl 1713005) ctrlSetTextColor [1, 1, 1, _dayOpacity]; (_display displayCtrl 1713006) ctrlSetTextColor [1, 1, 1, _nightOpacity]; diff --git a/addons/optics/functions/script_component.hpp b/addons/optics/functions/script_component.hpp deleted file mode 100644 index 5613c1aec3..0000000000 --- a/addons/optics/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\optics\script_component.hpp" \ No newline at end of file diff --git a/addons/optics/stringtable.xml b/addons/optics/stringtable.xml index 377cca28bc..85620ac37c 100644 --- a/addons/optics/stringtable.xml +++ b/addons/optics/stringtable.xml @@ -13,9 +13,10 @@ RCO (2D) RCO (2D) RCO (2D) - RCO (2D) - 步枪战斗光学瞄准镜(2D) + 류폴드 마크 4 HAMR (2D) + RCO(2D) 步槍戰鬥光學瞄準鏡(2D) + RCO (2D) RCO (PIP) @@ -29,9 +30,10 @@ RCO (PIP) RCO (PIP) RCO (PIP) - RCO (PIP) - 步枪战斗光学瞄准镜(拟真版) + 류폴드 마크 4 HAMR (PIP) + RCO(画中画) 步槍戰鬥光學瞄準鏡(擬真版) + RCO (PIP) ARCO (2D) @@ -45,9 +47,10 @@ ARCO (2D) ARCO (2D) ARCO (2D) - ARCO (2D) - 先进步枪战斗光学瞄准镜(2D) + 엘칸 스펙터OS (2D) + ARCO(2D) 先進步槍戰鬥光學瞄準鏡(2D) + ARCO (2D) ARCO (PIP) @@ -61,9 +64,10 @@ ARCO (PIP) ARCO (PIP) ARCO (PIP) - ARCO (PIP) - 先进步枪战斗光学瞄准镜(拟真版) + 엘칸 스펙터OS (PIP) + ARCO(画中画) 先進步槍戰鬥光學瞄準鏡(擬真版) + ARCO (PIP) MRCO (2D) @@ -77,9 +81,10 @@ MRCO (2D) MRCO (2D) MRCO (2D) - MRCO (2D) - 多距离战斗瞄准镜(2D) + IOR-Valdada 핏불 2 (2D) + MRCO(2D) 多距離戰鬥瞄準鏡(2D) + MRCO (2D) MRCO (PIP) @@ -93,9 +98,10 @@ MRCO (PIP) MRCO (PIP) MRCO (PIP) - MRCO (PIP) - 多距离战斗瞄准镜(拟真版) + IOR-Valdada 핏불 2 (PIP) + MRCO(画中画) 多距離戰鬥瞄準鏡(擬真版) + MRCO (PIP) MOS (2D) @@ -110,8 +116,9 @@ MOS (2D) MOS (2D) MOS (2D) - 精准光学瞄准镜(2D) + MOS(2D) 精準光學瞄準鏡(2D) + MOS (2D) MOS (PIP) @@ -126,8 +133,9 @@ MOS (PIP) MOS (PIP) MOS (PIP) - 精准光学瞄准镜(拟真版) + MOS(画中画) 精準光學瞄準鏡(擬真版) + MOS (PIP) LRPS (2D) @@ -141,9 +149,10 @@ MPLD (2D) LRPS (2D) LRPS (2D) - LRPS (2D) - 长距离精确瞄准镜(2D) + 나이트포스 NXS (2D) + LRPS(2D) 長距離精確瞄準鏡(2D) + LRPS (2D) LRPS (PIP) @@ -157,9 +166,10 @@ MPLD (PIP) LRPS (PIP) LRPS (PIP) - LRPS (PIP) - 长距离精确瞄准镜(拟真版) + 나이트포스 NXS (PIP) + LRPS(画中画) 長距離精確瞄準鏡(擬真版) + LRPS (PIP) diff --git a/addons/optionsmenu/ACE_Settings.hpp b/addons/optionsmenu/ACE_Settings.hpp index bab67cd37f..cd5bed07ee 100644 --- a/addons/optionsmenu/ACE_Settings.hpp +++ b/addons/optionsmenu/ACE_Settings.hpp @@ -1,8 +1,5 @@ class ACE_Settings { class GVAR(showNewsOnMainMenu) { - value = 1; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(showNewsOnMainMenu_name); + movedToSQF = 1; }; }; diff --git a/addons/optionsmenu/CfgEventHandlers.hpp b/addons/optionsmenu/CfgEventHandlers.hpp index 4f50c9613f..e656fd8a0d 100644 --- a/addons/optionsmenu/CfgEventHandlers.hpp +++ b/addons/optionsmenu/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_DisplayLoad_EventHandlers { class RscDisplayMain { - GVAR(loadMainMenuBox) = QUOTE(_this call COMPILE_FILE(init_loadMainMenuBox)); + GVAR(loadMainMenuBox) = QUOTE(_this call COMPILE_SCRIPT(init_loadMainMenuBox)); }; }; diff --git a/addons/optionsmenu/README.md b/addons/optionsmenu/README.md index e274229053..02977228c8 100644 --- a/addons/optionsmenu/README.md +++ b/addons/optionsmenu/README.md @@ -3,11 +3,3 @@ ace_optionsmenu Previously held the options menu. Now just handles version display on main menu and debug/headbug on options menu. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) -- [NouberNou](https://github.com/NouberNou) diff --git a/addons/optionsmenu/XEH_preInit.sqf b/addons/optionsmenu/XEH_preInit.sqf index 46d58b5a8a..aaa0b64a03 100644 --- a/addons/optionsmenu/XEH_preInit.sqf +++ b/addons/optionsmenu/XEH_preInit.sqf @@ -11,4 +11,6 @@ if (hasInterface) then { [[format ["ACE %1", localize LSTRING(headBugFix)], localize LSTRING(headBugFixTooltip)], QGVAR(MainMenuHelperHeadBugFix)] call CBA_fnc_addPauseMenuOption; }; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/optionsmenu/config.cpp b/addons/optionsmenu/config.cpp index b17fe12cc3..811b1eecec 100644 --- a/addons/optionsmenu/config.cpp +++ b/addons/optionsmenu/config.cpp @@ -30,11 +30,14 @@ class CfgAddons { #include "gui\pauseMenu.hpp" class ACE_Extensions { - extensions[] += {"ace_clipboard"}; + class ace_clipboard { + windows = 1; + client = 1; + }; }; class CfgCommands { allowedHTMLLoadURIs[] += { - "https://ace3mod.com/version.html" + "https://ace3.acemod.org/version.html" }; }; diff --git a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf index 3b662eb121..07205dc195 100644 --- a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf +++ b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Dumps debug info to clipboard. @@ -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/optionsmenu/functions/script_component.hpp b/addons/optionsmenu/functions/script_component.hpp deleted file mode 100644 index dd11862f9d..0000000000 --- a/addons/optionsmenu/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\optionsmenu\script_component.hpp" \ No newline at end of file diff --git a/addons/optionsmenu/gui/pauseMenu.hpp b/addons/optionsmenu/gui/pauseMenu.hpp index f48cecfd0f..6defe4534c 100644 --- a/addons/optionsmenu/gui/pauseMenu.hpp +++ b/addons/optionsmenu/gui/pauseMenu.hpp @@ -1,3 +1,5 @@ +#pragma hemtt suppress pw3_padded_arg file + class RscDisplayEmpty; class GVAR(MainMenuHelperDumpDebug): RscDisplayEmpty { onLoad = QUOTE(\ diff --git a/addons/optionsmenu/initSettings.inc.sqf b/addons/optionsmenu/initSettings.inc.sqf new file mode 100644 index 0000000000..e5bb44e512 --- /dev/null +++ b/addons/optionsmenu/initSettings.inc.sqf @@ -0,0 +1,13 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(aceNews)]; + +[ + QGVAR(showNewsOnMainMenu), "CHECKBOX", + LSTRING(showNewsOnMainMenu_name), + _category, + true, + 0, + { + if (!hasInterface) exitWith {}; + profileNamespace setVariable [QGVAR(showNewsOnMainMenu), _this]; + } +] call CBA_fnc_addSetting; diff --git a/addons/optionsmenu/init_loadMainMenuBox.sqf b/addons/optionsmenu/init_loadMainMenuBox.sqf index 5b21d7aabb..78ba6e839d 100644 --- a/addons/optionsmenu/init_loadMainMenuBox.sqf +++ b/addons/optionsmenu/init_loadMainMenuBox.sqf @@ -51,7 +51,7 @@ if (profileNamespace getVariable [QGVAR(showNewsOnMainMenu), true]) then { _versionStr = _versionStr joinString "."; (_display displayCtrl IDC_MAIN_INFO_CURRENT_VERSION_INFO) ctrlSetText format ["Version: %1", _versionStr]; - (_display displayCtrl IDC_MAIN_INFO_NEWEST_VERSION_INFO) htmlLoad "https://ace3mod.com/version.html"; + (_display displayCtrl IDC_MAIN_INFO_NEWEST_VERSION_INFO) htmlLoad "https://ace3.acemod.org/version.html"; } else { _controlsGroup ctrlShow false; }; diff --git a/addons/optionsmenu/stringtable.xml b/addons/optionsmenu/stringtable.xml index 4ef6afd120..4cd7f7d2f7 100644 --- a/addons/optionsmenu/stringtable.xml +++ b/addons/optionsmenu/stringtable.xml @@ -11,11 +11,12 @@ Debug vers le presse-papier Debug a vágólapra Отладка в буфер обмена - Debug su Blocco Note + Debug negli Appunti クリップボードにデバッグ - 디버그를 클립보드로 - 复制除错讯息至剪贴簿 + 클립보드를 디버그하기 + 复制调试信息至剪贴板 複製除錯訊息至剪貼簿 + Panoya Hata Ayıkla Sends debug information to RPT and clipboard. @@ -24,14 +25,15 @@ Pošle debug informace do RPT a schránky. Protokolliert Debug-Informationen im RPT und speichert sie in der Zwischenablage. Envia informação de depuração para RPT e área de transferência. - Copie le Debug dans le RPT et le presse-papier + Envoie les informations de debug vers le RPT et le presse-papier. Debug információt küld az RPT-be és a vágólapra. Отправляет отладочную информацию в RPT и буфер обмена. - Invia informazioni di debug all'RPT e al Blocco Note + Invia informazioni di debug all'RPT e gli appunti di Windows. デバッグ情報を RPT とクリップボードに送ります。 디버그 정보를 보고하기 및 클립보드에 복사하기 위해 보냅니다. - 复制除错讯息至剪贴簿与RPT报告档中。 + 复制调试信息至剪贴板与 RPT 报告档中。 複製除錯訊息至剪貼簿與RPT報告檔中 + Hata ayıklama bilgilerini RPT ve panoya gönderir. Headbug Fix @@ -46,14 +48,15 @@ Sistema Bug della Testa ヘッドバグ修正 헤드버그 수정 - 修复动作BUG + 修复动作 BUG 修復動作BUG + Animasyon Düzeltme Resets your animation state. Setzt die derzeitige Animation zurück. Resetuje aktualną animację. - Réinitialise l'état de l'animation + Réinitialise l'état de votre animation. Visszaállítja az animációs állapotodat. Redefine seu estado de animação. Исправляет баг с зациклившейся анимацией. @@ -62,8 +65,9 @@ Resetta il tuo stato animazione 現在のアニメーション状態を初期化します。 자신의 동작 상태 초기화 - 当ACE发生动作BUG时,点此修复。 + 当 ACE 发生动作 BUG 时,点此修复。 當ACE發生動作BUG時,點此修復 + Animasyon durumunuzu sıfırlar. ACE News @@ -75,11 +79,12 @@ Nouveautés ACE ACE hírek Новости ACE - Novità ACE + ACE Novità ACE ニュース - ACE 새소식 - ACE新闻 + ACE 새 소식 + ACE 新闻 ACE新聞 + ACE Haberler Show News on Main Menu @@ -87,142 +92,16 @@ Zeige Neuigkeiten im Hauptmenü Mostrar notícias no menu principal Pokazuj wiadomości ACE w menu głównym - Affiche les nouveautés sur l'écran principal + Afficher les nouveautés dans le menu principal Hírek mutatása a főmenüben - Показывать новости в Главном Меню + Показывать новости в главном меню Zobrazit zprávy v hlavním menu - Mostra News nel Menù Princinpale + Mostra novità nel Menù Principale メイン画面にニュースを表示します - 메인메뉴에 새소식을 표시합니다 - 显示新闻消息于主选单 + 메인메뉴에 새 소식을 표시합니다 + 显示新闻消息于主菜单 顯示新聞消息於主選單 - - - ACE Logistics - ACE Logistik - ACE Logistyka - ACE Logística - ACE Логистика - ACE Logistika - ACE Logística - ACE Logistica - ACE Logistique - ACE ロジスティクス - ACE 보급 - ACE 后勤设定 - ACE 後勤設定 - - - Hide - Ukryj - Ocultar - Verstecken - Skrýt - Ocultar - Cacher - Elrejtés - Скрыть - Nascondi - 非表示 - 숨기기 - 隐藏 - 隱藏 - - - Top right, downwards - Po prawej u góry, w dół - Arriba a la derecha, hacia abajo - Oben rechts, nach unten - Vpravo nahoře, dolů - Superior direito, para baixo - Haut droit, vers le bas - Jobb felül, lefele - Справа — сверху вниз - In Alto a Destra, verso il Basso - 右上、下側 - 오른쪽 위에서 아래로 - 右上角,向下 - 右上角,向下 - - - Top right, to the left - Po prawej u góry, do lewej - Arriba a la derecha, hacia la izquierda - Von rechts nach links - Vpravo nahoře, do leva - Superior direito, à esquerda - Haut droit, vers la gauche - Jobb felül, balra - Сверху — справа налево - In Alto a Destra, verso Sinistra - 右上、左詰 - 오른쪽 위에서 왼쪽으로 - 右上角,向左 - 右上角,向左 - - - Top left, downwards - Po lewej u góry, w dół - Arriba a la izquierda, hacia abajo - Von links, nach unten - Vlevo nahoře, dolů - Superior esquerdo, para baixo - Haut gauche, vers le bas - Bal felül, lefele - Слева - сверху вниз - In Alto a Sinistra, verso il Basso - 左上、下側 - 왼쪽 위에서 아래로 - 左上角,向下 - 左上角,向下 - - - Top left, to the right - Po lewej u góry, do prawej - Arriba a la izquierda, hacia la derecha - Oben links nach rechts - Vlevo nahoře, do prava - Superior esquerdo, para a direita - Haut gauche, vers la droite - Bal felül, jobbra - Сверху — слева направо - In Alto a Sinistra, verso Destra - 右上、右詰 - 왼쪽 위에서 오른쪽으로 - 左上角,向右 - 左上角,向右 - - - Top - Góra - Arriba - Oben - Nahoře - Acima - Haut - Fent - Сверху - Alto - 上側 - 상단 - 上方 - 上方 - - - Bottom - Dół - Abajo - Unten - Dole - Abaixo - Bas - Alul - Снизу - Basso - 下側 - 하단 - 下方 - 下方 + Ana Menü de Haberleri Göster diff --git a/addons/overheating/ACE_Arsenal_Stats.hpp b/addons/overheating/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..ef1e497c55 --- /dev/null +++ b/addons/overheating/ACE_Arsenal_Stats.hpp @@ -0,0 +1,21 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_allowSwapBarrel: statBase { + scope = 2; + priority = -1; + stats[] = {QGVAR(allowSwapBarrel)}; + displayName = CSTRING(statBarrelType); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_allowSwapBarrel)); + tabs[] = {{0,1}, {}}; + }; + class ACE_boltType: statBase { + scope = 2; + priority = -1.1; + stats[] = {QGVAR(closedBolt)}; + displayName = CSTRING(statBoltType); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_boltType)); + tabs[] = {{0,1}, {}}; + }; +}; diff --git a/addons/overheating/ACE_Settings.hpp b/addons/overheating/ACE_Settings.hpp index 5a4b8941e9..5febcd6f7f 100644 --- a/addons/overheating/ACE_Settings.hpp +++ b/addons/overheating/ACE_Settings.hpp @@ -1,55 +1,41 @@ class ACE_Settings { - class GVAR(displayTextOnJam) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - isClientSettable = 1; - value = 1; - displayName = CSTRING(DisplayTextOnJam_displayName); - description = CSTRING(DisplayTextOnJam_description); + class GVAR(enabled) { + movedToSQF = 1; + }; + class GVAR(heatCoef) { + movedToSQF = 1; }; class GVAR(showParticleEffects) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - isClientSettable = 1; - value = 1; - displayName = CSTRING(showParticleEffects_displayName); - description = CSTRING(showParticleEffects_description); + movedToSQF = 1; }; class GVAR(showParticleEffectsForEveryone) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - isClientSettable = 1; - value = 0; - displayName = CSTRING(showParticleEffectsForEveryone_displayName); - description = CSTRING(showParticleEffectsForEveryone_description); + movedToSQF = 1; }; class GVAR(overheatingDispersion) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 1; - displayName = CSTRING(overheatingDispersion_displayName); - description = CSTRING(overheatingDispersion_description); + movedToSQF = 1; }; - class GVAR(unJamOnreload) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - displayName = CSTRING(unJamOnreload_displayName); - description = CSTRING(unJamOnreload_description); + class GVAR(particleEffectsAndDispersionDistance) { + movedToSQF = 1; + }; + class GVAR(overheatingRateOfFire) { + movedToSQF = 1; + }; + class GVAR(displayTextOnJam) { + movedToSQF = 1; + }; + class GVAR(jamChanceCoef) { + movedToSQF = 1; + }; + class GVAR(unJamOnReload) { + movedToSQF = 1; + }; + class GVAR(unJamOnSwapBarrel) { + movedToSQF = 1; }; class GVAR(unJamFailChance) { - category = CSTRING(DisplayName); - typeName = "SCALAR"; - value = 0.1; - displayName = CSTRING(unJamFailChance_displayName); - description = CSTRING(unJamFailChance_description); - sliderSettings[] = {0, 1, 0.1, 2}; + movedToSQF = 1; }; - class GVAR(enabled) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 1; - displayName = CSTRING(enabled_displayName); - description = CSTRING(enabled_description); + class GVAR(cookoffCoef) { + movedToSQF = 1; }; }; diff --git a/addons/overheating/CfgEventHandlers.hpp b/addons/overheating/CfgEventHandlers.hpp index becf395052..8143e2ce0d 100644 --- a/addons/overheating/CfgEventHandlers.hpp +++ b/addons/overheating/CfgEventHandlers.hpp @@ -1,18 +1,26 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + +class Extended_Respawn_EventHandlers { + class CAManBase { + class ADDON { + respawn = QUOTE(_this call FUNC(handleRespawn)); + }; }; }; diff --git a/addons/overheating/CfgMagazines.hpp b/addons/overheating/CfgMagazines.hpp index 6819a26b53..2553428c91 100644 --- a/addons/overheating/CfgMagazines.hpp +++ b/addons/overheating/CfgMagazines.hpp @@ -7,7 +7,7 @@ class CfgMagazines { descriptionshort = CSTRING(SpareBarrelDescription); picture = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); count = 1; - mass = 60; + mass = 25; ACE_isUnique = 1; }; }; diff --git a/addons/overheating/CfgSounds.hpp b/addons/overheating/CfgSounds.hpp index bd2831eeb6..2b333c3381 100644 --- a/addons/overheating/CfgSounds.hpp +++ b/addons/overheating/CfgSounds.hpp @@ -23,4 +23,26 @@ class CfgSounds { sound[]={QPATHTOF(sounds\fixing_pistol.wav),1,1}; titles[]={}; }; + /* // to be added when licence compatible audio can be found or recorded + class GVAR(pouring_long) { + name= QGVAR(pouring_long); + sound[]={QPATHTOF(sounds\pouring_long.ogg),5,1}; + titles[]={}; + }; + class GVAR(pouring_short) { + name= QGVAR(pouring_short); + sound[]={QPATHTOF(sounds\pouring_short.ogg),5,1}; + titles[]={}; + }; + class GVAR(sizzling_long) { + name= QGVAR(sizzling_long); + sound[]={QPATHTOF(sounds\sizzling_long.ogg),5,1}; + titles[]={}; + }; + class GVAR(sizzling_short) { + name= QGVAR(sizzling_short); + sound[]={QPATHTOF(sounds\sizzling_short.ogg),5,1}; + titles[]={}; + }; + */ }; diff --git a/addons/overheating/CfgVehicles.hpp b/addons/overheating/CfgVehicles.hpp index e142b71a89..cd22400893 100644 --- a/addons/overheating/CfgVehicles.hpp +++ b/addons/overheating/CfgVehicles.hpp @@ -6,36 +6,45 @@ class CfgVehicles { class ACE_Equipment { class GVAR(UnJam) { displayName = CSTRING(UnjamWeapon); - condition = QUOTE( GVAR(enabled) && {[_player] call FUNC(canUnjam)} ); + condition = QUOTE(GVAR(enabled) && {[_player] call FUNC(canUnjam)}); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; - statement = QUOTE( [ARR_2(_player, currentMuzzle _player)] call FUNC(clearJam); ); + statement = QUOTE([ARR_2(_player,currentMuzzle _player)] call FUNC(clearJam)); showDisabled = 0; icon = QPATHTOEF(common,UI\repack_ca.paa); }; class GVAR(SwapBarrel) { displayName = CSTRING(SwapBarrel); - condition = QUOTE( [ARR_2(_player, currentWeapon _player)] call FUNC(canSwapBarrel) ); + condition = QUOTE([ARR_2(_player,currentWeapon _player)] call FUNC(canSwapBarrel)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; - statement = QUOTE( [ARR_3(_player, _player, currentWeapon _player)] call FUNC(swapBarrel); ); + statement = QUOTE([ARR_3(_player,_player,currentWeapon _player)] call FUNC(swapBarrel)); showDisabled = 0; icon = QPATHTOF(UI\spare_barrel_ca.paa); }; class GVAR(CheckTemperature) { displayName = CSTRING(CheckTemperatureShort); - condition = QUOTE( GVAR(enabled) && {switch (currentWeapon _player) do {case (''): {false}; case (primaryWeapon _player); case (handgunWeapon _player): {true}; default {false}}} ); + condition = QUOTE(GVAR(enabled) && {switch (currentWeapon _player) do {case (''): {false}; case (primaryWeapon _player); case (handgunWeapon _player): {true}; default {false}}}); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; - statement = QUOTE( [ARR_3(_player, _player, currentWeapon _player)] call FUNC(checkTemperature); ); + statement = QUOTE([ARR_3(_player,_player,currentWeapon _player)] call FUNC(checkTemperature)); showDisabled = 0; icon = QPATHTOF(UI\temp_ca.paa); }; class GVAR(CheckTemperatureSpareBarrels) { displayName = CSTRING(CheckTemperatureSpareBarrelsShort); - condition = QUOTE((_player) call FUNC(canCheckSpareBarrelsTemperatures) ); + condition = QUOTE((_player) call FUNC(canCheckSpareBarrelsTemperatures)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; - statement = QUOTE( [_player] call FUNC(checkSpareBarrelsTemperatures); ); + statement = QUOTE([_player] call FUNC(checkSpareBarrelsTemperatures)); showDisabled = 0; icon = QUOTE(PATHTOF(UI\temp_ca.paa)); }; + class GVAR(CoolWeaponWithItem) { + displayName = CSTRING(CoolWeaponWithItem); + condition = QUOTE(call FUNC(canCoolWeaponWithItem)); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; + statement = "true"; + showDisabled = 0; + insertChildren = QUOTE(_player call FUNC(getConsumableChildren)); + icon = QPATHTOF(UI\pour_water_ca.paa); + }; }; }; @@ -43,18 +52,27 @@ class CfgVehicles { class ACE_Weapon { class GVAR(SwapBarrel) { displayName = CSTRING(SwapBarrel); - condition = QUOTE( [ARR_2(_player, currentWeapon _target)] call FUNC(canSwapBarrel) ); - statement = QUOTE([ARR_3(_player, _target, currentWeapon _target)] call FUNC(swapBarrelAssistant);); + condition = QUOTE([ARR_2(_player,currentWeapon _target)] call FUNC(canSwapBarrel)); + statement = QUOTE([ARR_3(_player,_target,currentWeapon _target)] call FUNC(swapBarrelAssistant)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; icon = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); }; class GVAR(CheckTemperature) { displayName = CSTRING(CheckTemperatureShort); - condition = QUOTE( GVAR(enabled) && {switch (currentWeapon _target) do {case ('ACE_FakePrimaryWeapon'); case (''): {false}; case (primaryWeapon _target); case (handgunWeapon _target): {true}; default {false}}} ); + condition = QUOTE(GVAR(enabled) && {switch (currentWeapon _target) do {case ('ACE_FakePrimaryWeapon'); case (''): {false}; case (primaryWeapon _target); case (handgunWeapon _target): {true}; default {false}}}); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; - statement = QUOTE( [ARR_3(_player, _target, currentWeapon _target)] call FUNC(checkTemperature); ); + statement = QUOTE([ARR_3(_player,_target,currentWeapon _target)] call FUNC(checkTemperature)); icon = QUOTE(PATHTOF(UI\temp_ca.paa)); }; + class GVAR(CoolWeaponWithItem) { + displayName = CSTRING(CoolWeaponWithItem); + condition = QUOTE(call FUNC(canCoolWeaponWithItem)); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; + statement = "true"; + showDisabled = 0; + insertChildren = QUOTE(_player call FUNC(getConsumableChildren)); + icon = QPATHTOF(UI\pour_water_ca.paa); + }; }; }; }; diff --git a/addons/overheating/CfgWeapons.hpp b/addons/overheating/CfgWeapons.hpp index f094ec7b27..9232fa3249 100644 --- a/addons/overheating/CfgWeapons.hpp +++ b/addons/overheating/CfgWeapons.hpp @@ -1,4 +1,19 @@ class CfgWeapons { + class PistolCore; + class Pistol: PistolCore { + //Closed Bolt (Closed Bolt will cook off if too hot) + //Pistols are nearly universally closed bolt. + GVAR(closedBolt) = 1; + }; + + class Pistol_Base_F: Pistol {}; + class hgun_Pistol_heavy_02_F: Pistol_Base_F { + GVAR(jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + class hgun_Pistol_Signal_F: Pistol_Base_F { + GVAR(jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + class RifleCore; class Rifle: RifleCore { //Mean Rounds Between Stoppages (this will be scaled based on the barrel temp) @@ -9,33 +24,92 @@ class CfgWeapons { //Slowdown Factor (this will be scaled based on the barrel temp) GVAR(slowdownFactor) = 1; + + //Closed Bolt, most weapons are closed bolt + GVAR(closedBolt) = 1; }; - class Rifle_Base_F : Rifle {}; - class Rifle_Long_Base_F : Rifle_Base_F { + class Rifle_Base_F; + class Rifle_Long_Base_F: Rifle_Base_F { GVAR(dispersion) = 0.75; + + // Open Bolt, most machine guns are open bolt, which cannot normally cook off, and use this as a parent class + // A lot of sniper rifles also use this as a parent class, they will need to be indivisually set to closed bolt, but it's probably not an issue as they are unlikely to overheat + GVAR(closedBolt) = 0; }; - class arifle_MX_Base_F : Rifle_Base_F { + class arifle_MX_Base_F: Rifle_Base_F { // Custom jam clearing action. Default uses reload animation. ACE_clearJamAction = "GestureReloadMX"; }; - class arifle_MX_SW_F : arifle_MX_Base_F { + class arifle_MX_SW_F: arifle_MX_Base_F { // Custom jam clearing action. Use empty string to undefine. ACE_clearJamAction = ""; // 1 to enable barrel swap. 0 to disable. Meant for machine guns where you can easily swap the barrel without dismantling the whole weapon. GVAR(allowSwapBarrel) = 1; GVAR(dispersion) = 0.75; }; + class DMR_01_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class DMR_02_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class DMR_03_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class DMR_04_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class DMR_05_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class DMR_06_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class DMR_07_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class EBR_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class GM6_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; + class LRR_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + }; class MMG_01_base_F: Rifle_Long_Base_F { GVAR(allowSwapBarrel) = 1; }; class MMG_02_base_F: Rifle_Long_Base_F { GVAR(allowSwapBarrel) = 1; }; - class LMG_Zafir_F : Rifle_Long_Base_F { + class LMG_Zafir_F: Rifle_Long_Base_F { GVAR(allowSwapBarrel) = 1; }; - class LMG_Mk200_F : Rifle_Long_Base_F { + class LMG_Mk200_F: Rifle_Long_Base_F { GVAR(allowSwapBarrel) = 1; }; + class LMG_03_Base_F: Rifle_Long_Base_F { + GVAR(allowSwapBarrel) = 1; + }; + class sgun_HunterShotgun_01_base_F: Rifle_Long_Base_F { + GVAR(closedBolt) = 1; + GVAR(jamTypesAllowed)[] = {"Fire", "Dud"}; + }; + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + // Deprecated, 3.16.0 Arsenal supports showing magazines as misc items + class ACE_SpareBarrel_Item: ACE_ItemCore { + displayName = CSTRING(SpareBarrelName); + author = ECSTRING(common,ACETeam); + scope = 1; + scopeArsenal = 0; + descriptionshort = CSTRING(SpareBarrelDescription); + picture = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 25; + }; + }; }; diff --git a/addons/overheating/README.md b/addons/overheating/README.md index fa18f9dc20..181f6bcc08 100644 --- a/addons/overheating/README.md +++ b/addons/overheating/README.md @@ -2,11 +2,3 @@ ace_overheating =============== Introduces weapon overheating and jamming, as well as the ability to swap the barrel on some weapons. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/overheating/UI/pour_water_ca.paa b/addons/overheating/UI/pour_water_ca.paa new file mode 100644 index 0000000000..060a4572d1 Binary files /dev/null and b/addons/overheating/UI/pour_water_ca.paa differ diff --git a/addons/overheating/XEH_PREP.hpp b/addons/overheating/XEH_PREP.hpp index 2436e390db..91d345914d 100644 --- a/addons/overheating/XEH_PREP.hpp +++ b/addons/overheating/XEH_PREP.hpp @@ -3,20 +3,35 @@ PREP(calculateCooling); PREP(canUnjam); PREP(canSwapBarrel); PREP(canCheckSpareBarrelsTemperatures); +PREP(canCoolWeaponWithItem); PREP(checkSpareBarrelsTemperatures); PREP(checkTemperature); PREP(clearJam); +PREP(cookoffWeapon); +PREP(coolWeaponWithItem); +PREP(coolWeaponWithWaterSource); PREP(displayTemperature); PREP(firedEH); +PREP(getAmmoTemperature); +PREP(getBarrelMass); +PREP(getConsumableChildren); PREP(getWeaponData); +PREP(getWeaponTemperature); PREP(handleTakeEH); +PREP(handleRespawn); PREP(jamWeapon); PREP(loadCoolestSpareBarrel); PREP(overheat); PREP(sendSpareBarrelsTemperaturesHint); +PREP(setAmmoTemperature); +PREP(setWeaponTemperature); +PREP(statTextStatement_boltType); +PREP(statTextStatement_allowSwapBarrel); PREP(swapBarrel); PREP(swapBarrelAssistant); PREP(swapBarrelCallback); +PREP(updateAmmoTemperature); +PREP(updateAmmoTemperatureThread); PREP(updateSpareBarrelsTemperaturesThread); PREP(updateTemperature); PREP(updateTemperatureThread); diff --git a/addons/overheating/XEH_postInit.sqf b/addons/overheating/XEH_postInit.sqf index 34390cbe20..a49030b1ad 100644 --- a/addons/overheating/XEH_postInit.sqf +++ b/addons/overheating/XEH_postInit.sqf @@ -1,6 +1,9 @@ // by esteldunedain #include "script_component.hpp" +// Spare barrel item to magazine +["ACE_SpareBarrel_Item", "ACE_SpareBarrel"] call EFUNC(common,registerItemReplacement); + if (hasInterface) then { // Add keybinds ["ACE3 Weapons", QGVAR(unjamWeapon), localize LSTRING(UnjamWeapon), { @@ -16,8 +19,8 @@ if (hasInterface) then { }, {false}, [19, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + R Key }; -["ace_settingsInitialized", { - TRACE_1("SettingsInitialized eh", GVAR(enabled)); +["CBA_settingsInitialized", { + TRACE_1("SettingsInitialized eh",GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; if (isServer) then { @@ -29,11 +32,11 @@ if (hasInterface) then { publicVariable QGVAR(pseudoRandomList); // Keep track of the temperature of stored spare barrels - GVAR(storedSpareBarrels) = [] call CBA_fnc_hashCreate; + GVAR(storedSpareBarrels) = createHashMap; // Install event handlers for spare barrels - [QGVAR(sendSpareBarrelTemperatureHint), FUNC(sendSpareBarrelsTemperaturesHint)] call CBA_fnc_addEventHandler; - [QGVAR(loadCoolestSpareBarrel), FUNC(loadCoolestSpareBarrel)] call CBA_fnc_addEventHandler; + [QGVAR(sendSpareBarrelTemperatureHint), LINKFUNC(sendSpareBarrelsTemperaturesHint)] call CBA_fnc_addEventHandler; + [QGVAR(loadCoolestSpareBarrel), LINKFUNC(loadCoolestSpareBarrel)] call CBA_fnc_addEventHandler; // Schedule cool down calculation of stored spare barrels [] call FUNC(updateSpareBarrelsTemperaturesThread); @@ -41,26 +44,77 @@ if (hasInterface) then { if !(hasInterface) exitWith {}; - GVAR(cacheWeaponData) = call CBA_fnc_createNamespace; - GVAR(cacheAmmoData) = call CBA_fnc_createNamespace; - GVAR(cacheSilencerData) = call CBA_fnc_createNamespace; + GVAR(cacheWeaponData) = createHashMap; + GVAR(cacheAmmoData) = createHashMap; + GVAR(cacheSilencerData) = createHashMap; - //Add Take EH (for reload) - ["CAManBase", "Take", {_this call FUNC(handleTakeEH);}] call CBA_fnc_addClassEventHandler; + //Add Take EH if required + if (GVAR(unJamOnReload) || {GVAR(cookoffCoef) > 0}) then { + ["CAManBase", "Take", LINKFUNC(handleTakeEH)] call CBA_fnc_addClassEventHandler; + }; // Register fire event handler - ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; // Only add eh to non local players if dispersion is enabled - if (GVAR(overheatingDispersion)) then { - ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + if (GVAR(overheatingDispersion) || {GVAR(showParticleEffectsForEveryone)}) then { + ["ace_firedPlayerNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; }; // Schedule cool down calculation of player weapons at (infrequent) regular intervals [] call FUNC(updateTemperatureThread); - // Install event handler to display temp when a barrel was swapped - [QGVAR(showWeaponTemperature), DFUNC(displayTemperature)] call CBA_fnc_addEventHandler; - // Install event handler to initiate an assisted barrel swap - [QGVAR(initiateSwapBarrelAssisted), DFUNC(swapBarrel)] call CBA_fnc_addEventHandler; + //Add event handlers and start ammo heating loop for cookoff + if (GVAR(cookoffCoef) > 0) then { + [] call FUNC(updateAmmoTemperatureThread); + // Reset ammo temperature on reload, unless the reload is a second muzzle. + ["CAManBase", "Reloaded", { + params ["_unit", "_weapon", "_muzzle"]; + if (_muzzle == _weapon) then { + _unit setVariable [format [QGVAR(%1_ammoTemp), _weapon], 0]; + }; + }] call CBA_fnc_addClassEventHandler; + }; + + // Reset all weapon heat to ambient on death to prevent cookoffs when a unit respawns. + ["CAManBase", "Killed", { + params ["_unit"]; + { + _unit setVariable [_x, ambientTemperature select 0]; + } forEach (_unit getVariable [QGVAR(trackedWeapons), []]); + _unit setVariable [QGVAR(trackedWeapons), []]; + }] call CBA_fnc_addClassEventHandler; + + // Install event handler to display temp when a barrel was swapped + [QGVAR(showWeaponTemperature), LINKFUNC(displayTemperature)] call CBA_fnc_addEventHandler; + + // Install event handler to initiate an assisted barrel swap + [QGVAR(initiateSwapBarrelAssisted), LINKFUNC(swapBarrel)] call CBA_fnc_addEventHandler; + + // Add an action to allow hot weapons to be cooled off in AceX Field Rations water sources + if (["acex_field_rations"] call EFUNC(common,isModLoaded)) then { + [ + {EXGVAR(field_rations,enabled) || CBA_missionTime > 1}, + { + if (!EXGVAR(field_rations,enabled)) exitWith {}; + + private _coolWeaponWithWaterSourceAction = [ + QGVAR(CoolWeaponWithWaterSource), + LLSTRING(CoolWeaponWithWaterSource), + QPATHTOEF(field_rations,ui\icon_water_tap.paa), + { + private _waterSource = _target getVariable [QEGVAR(field_rations,waterSource), objNull]; + [_player, _waterSource] call FUNC(coolWeaponWithWaterSource); + }, + { + private _waterSource = _target getVariable [QEGVAR(field_rations,waterSource), objNull]; + [_player, _waterSource] call EFUNC(field_rations,canDrinkFromSource); + } + ] call EFUNC(interact_menu,createAction); + + [QEGVAR(field_rations,helper), 0, [QEGVAR(field_rations,waterSource)], _coolWeaponWithWaterSourceAction] call EFUNC(interact_menu,addActionToClass); + }, + [] + ] call CBA_fnc_waitUntilAndExecute; + }; }] call CBA_fnc_addEventHandler; diff --git a/addons/overheating/XEH_preInit.sqf b/addons/overheating/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/overheating/XEH_preInit.sqf +++ b/addons/overheating/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/overheating/config.cpp b/addons/overheating/config.cpp index bedd96fa30..4d8fb34cc3 100644 --- a/addons/overheating/config.cpp +++ b/addons/overheating/config.cpp @@ -4,7 +4,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; - weapons[] = {}; + weapons[] = {"ACE_SpareBarrel_Item"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); @@ -26,6 +26,8 @@ class CfgPatches { #include "ACE_Settings.hpp" +#include "ACE_Arsenal_Stats.hpp" + class CfgMovesBasic { class ManActions { GVAR(GestureMountMuzzle) = QGVAR(GestureMountMuzzle); diff --git a/addons/overheating/functions/fnc_calculateCooling.sqf b/addons/overheating/functions/fnc_calculateCooling.sqf index 01983814f5..e7ac83f236 100644 --- a/addons/overheating/functions/fnc_calculateCooling.sqf +++ b/addons/overheating/functions/fnc_calculateCooling.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Calculate the cooling down of a weapon over a time interval. @@ -7,6 +7,7 @@ * 0: Initial temperature * 1: Barrel mass * 2: Time interval + * 3: Bolt type * * Return Value: * Final temperature @@ -17,11 +18,14 @@ * Public: No */ -params ["_temperature", "_barrelMass", "_totalTime"]; +params ["_temperature", "_barrelMass", "_totalTime", "_boltType"]; + +// The lowest temperature a weapon can reach is the ambient air temperature. +private _ambientTemperature = ambientTemperature select 0; -if (_temperature < 1) exitWith {0}; // If a long time passed since the last shot, there's no need to calculate anything; the weapon should be cool -if (_totalTime > 1800) exitWith {0}; +if (_totalTime > 1800) exitWith {_ambientTemperature}; +if (_temperature <= _ambientTemperature) exitWith {_ambientTemperature}; //AR-15 (0.00570m bullet diameter) (barrel diameter usually 0.75" or 0.008255m radius) //Steel Denisty = 7850 m^3 / kg @@ -30,6 +34,18 @@ if (_totalTime > 1800) exitWith {0}; //So Area = 210 * 1.1 * (mass / 7850) = mass * 0.029427 (for steel near that diameter) private _barrelSurface = _barrelMass * 0.029427; +private _convectionRate = 25; + +//provide additional cooling if swimming or raining or windy +if (ACE_player call EFUNC(common,isSwimming)) then { + _convectionRate = 500; +} else { + // this will give a convection rate between 25 (no wind or rain) and 125 (max rain and >=50 m/s wind) + _convectionRate = _convectionRate * ((linearConversion [0,1,rain,1,5,true] + (5 min (vectorMagnitude wind / 10))) / 2); +}; + +//Increase convection cooling for open bolt type guns +if (_boltType == 0) then {_convectionRate = _convectionRate * OPEN_BOLT_ADDITIONAL_CONVECTION}; TRACE_4("cooling",_temperature,_totalTime,_barrelMass,_barrelSurface); @@ -38,16 +54,13 @@ while {true} do { private _deltaTime = (_totalTime - _time) min 20; _temperature = _temperature - ( - // Convective cooling - 25 * _barrelSurface * _temperature - // Radiative cooling - + 0.4 * 5.67e-8 * _barrelSurface * - ( (_temperature + 273.15)*(_temperature + 273.15) - * (_temperature + 273.15)*(_temperature + 273.15) - - 273.15 * 273.15 * 273.15 *273.15 ) - ) * _deltaTime / (_barrelMass * 466); + // Convective cooling + _convectionRate * _barrelSurface * _temperature + // Radiative cooling + + 0.4 * 5.67e-8 * _barrelSurface * ((_temperature + 273.15) ^ 4 - 273.15 ^ 4) + ) * GVAR(coolingCoef) * _deltaTime / (_barrelMass * 466); - if (_temperature < 1) exitWith {0}; + if (_temperature <= _ambientTemperature) exitWith {_ambientTemperature}; if (isNil "_temperature") exitWith { diag_log text format ["[ACE] ERROR: _totalTime = %1; _time = %2; _deltaTime = %3;", _totalTime, _time, _deltaTime]; @@ -55,5 +68,5 @@ while {true} do { }; _time = _time + _deltaTime; - if (_time >= _totalTime) exitWith { _temperature max 0 }; + if (_time >= _totalTime) exitWith {_temperature max _ambientTemperature}; }; diff --git a/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf b/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf index ca4d76e77b..c84de1ae6f 100644 --- a/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf +++ b/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Grey-Soldierman * Return true if player can check temperatures of spare barrels @@ -20,7 +20,7 @@ params ["_player"]; //Get the classname of the spare barrel for the weapon private _weaponBarrelClass = getText (configFile >> 'CfgWeapons' >> currentWeapon _player >> QGVAR(barrelClassname)); //If the weapon has no defined classname then use the ACE one -if(_weaponBarrelClass == "") then { +if (_weaponBarrelClass == "") then { _weaponBarrelClass = "ACE_SpareBarrel"; }; //Check if the player has the barrel and the weapon can have its barrel swapped diff --git a/addons/overheating/functions/fnc_canCoolWeaponWithItem.sqf b/addons/overheating/functions/fnc_canCoolWeaponWithItem.sqf new file mode 100644 index 0000000000..2040502283 --- /dev/null +++ b/addons/overheating/functions/fnc_canCoolWeaponWithItem.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Return true if the target's weapon can be cooled with an item in the player's inventory + * + * Arguments: + * 0: Target + * 1: Player + * + * Return Value: + * Bool + * + * Example: + * [cursorObject, player] call ace_overheating_fnc_canCoolWeaponWithItem + * + * Public: No + */ + +params ["_unit", "_player"]; +TRACE_2("canCoolWeaponWithItem",_unit,_player); + +GVAR(enabled) +&& {["acex_field_rations"] call EFUNC(common,isModLoaded)} +&& {!(_unit getVariable [QEGVAR(captives,isSurrendering), false])} // interaction point will overlap with ace_captives +&& {!(_unit getVariable [QEGVAR(captives,isHandcuffed), false])} +&& {[_unit, currentWeapon _unit] call FUNC(getWeaponTemperature) > (ambientTemperature select 0)} +&& {((_player call EFUNC(common,uniqueItems)) findIf {getNumber (configFile >> "CfgWeapons" >> _x >> QEXGVAR(field_rations,thirstQuenched)) > 0}) != -1} diff --git a/addons/overheating/functions/fnc_canSwapBarrel.sqf b/addons/overheating/functions/fnc_canSwapBarrel.sqf index 53104e19d5..cddd45aa5b 100644 --- a/addons/overheating/functions/fnc_canSwapBarrel.sqf +++ b/addons/overheating/functions/fnc_canSwapBarrel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Grey-Soldierman * Return true if player can swap barrel @@ -18,12 +18,12 @@ params ["_unit","_weapon"]; //Check if weapon can have its barrel swapped. If not exit out of function -if( !GVAR(enabled) || {getNumber (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(allowSwapBarrel)) != 1}) exitWith{false}; +if ( !GVAR(enabled) || {getNumber (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(allowSwapBarrel)) != 1}) exitWith{false}; //Get the classname of the spare barrel for the weapon private _weaponBarrelClass = getText (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(barrelClassname)); //If the weapon has no defined classname then use the ACE one -if(_weaponBarrelClass == "") then { +if (_weaponBarrelClass == "") then { _weaponBarrelClass = "ACE_SpareBarrel"; }; //If the player has the spare barrel then it can be swapped diff --git a/addons/overheating/functions/fnc_canUnjam.sqf b/addons/overheating/functions/fnc_canUnjam.sqf index 06511f79cd..f220ce41cd 100644 --- a/addons/overheating/functions/fnc_canUnjam.sqf +++ b/addons/overheating/functions/fnc_canUnjam.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 and esteldunedain * Return true if the unit can unjam it's current weapon diff --git a/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf b/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf index 4c7eba2919..18879292f9 100644 --- a/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf +++ b/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Make the player check the temperature of his spare barrels @@ -10,7 +10,7 @@ * None * * Example: - * [bob] call ace_overheating_fnc_checkSpareBarrelsTemperature + * [bob] call ace_overheating_fnc_checkSpareBarrelsTemperatures * * * Public: No diff --git a/addons/overheating/functions/fnc_checkTemperature.sqf b/addons/overheating/functions/fnc_checkTemperature.sqf index b7be4f4c13..59ed85853a 100644 --- a/addons/overheating/functions/fnc_checkTemperature.sqf +++ b/addons/overheating/functions/fnc_checkTemperature.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 and esteldunedain * Make the player check the temperature of his weapon @@ -12,7 +12,7 @@ * None * * Example: - * [player, currentWeapon player] call ace_overheating_fnc_checkTemperature + * [player, player, currentWeapon player] call ace_overheating_fnc_checkTemperature * * Public: No */ diff --git a/addons/overheating/functions/fnc_clearJam.sqf b/addons/overheating/functions/fnc_clearJam.sqf index 44b219fda2..c8e0a93d68 100644 --- a/addons/overheating/functions/fnc_clearJam.sqf +++ b/addons/overheating/functions/fnc_clearJam.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 * Make the unit clear the jam from a weapon @@ -33,30 +33,43 @@ if (_weapon in _jammedWeapons) then { }; [_unit, _clearJamAction, 1] call EFUNC(common,doGesture); + if (_weapon == primaryWeapon _unit) then { playSound QGVAR(fixing_rifle); } else { - if (_weapon == secondaryWeapon _unit) then { + if (_weapon == handgunWeapon _unit) then { playSound QGVAR(fixing_pistol); }; }; }; - // Check if the jam will be successfull + // Check if the jam clearing will be successfull if (random 1 > GVAR(unJamFailChance)) then { // Success - _jammedWeapons = _jammedWeapons - [_weapon]; - _unit setVariable [QGVAR(jammedWeapons), _jammedWeapons]; - if (_jammedWeapons isEqualTo []) then { - private _id = _unit getVariable [QGVAR(JammingActionID), -1]; - [_unit, "DefaultAction", _id] call EFUNC(common,removeActionEventHandler); - _unit setVariable [QGVAR(JammingActionID), -1]; - }; - if (GVAR(DisplayTextOnJam)) then { - [{ + + [{ + params ["_unit", "_weapon", "_jammedWeapons"]; + _jammedWeapons = _jammedWeapons - [_weapon]; + _unit setVariable [QGVAR(jammedWeapons), _jammedWeapons]; + + // If the round is a dud eject the round + if (_unit getVariable [format [QGVAR(%1_jamType), _weapon], "None"] isEqualTo "Dud") then { + private _ammo = _unit ammo _weapon; + _unit setAmmo [_weapon, _ammo - 1]; + }; + + _unit setVariable [format [QGVAR(%1_jamType), _weapon], "None"]; + + if (_jammedWeapons isEqualTo []) then { + private _id = _unit getVariable [QGVAR(JammingActionID), -1]; + [_unit, "DefaultAction", _id] call EFUNC(common,removeActionEventHandler); + _unit setVariable [QGVAR(JammingActionID), -1]; + }; + + if (GVAR(DisplayTextOnJam)) then { [localize LSTRING(WeaponUnjammed)] call EFUNC(common,displayTextStructured); - }, [], _delay] call CBA_fnc_waitAndExecute; - }; + }; + }, [_unit, _weapon, _jammedWeapons], _delay] call CBA_fnc_waitAndExecute; } else { // Failure if (GVAR(DisplayTextOnJam)) then { diff --git a/addons/overheating/functions/fnc_cookoffWeapon.sqf b/addons/overheating/functions/fnc_cookoffWeapon.sqf new file mode 100644 index 0000000000..61f74cdf85 --- /dev/null +++ b/addons/overheating/functions/fnc_cookoffWeapon.sqf @@ -0,0 +1,66 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Cookoff loaded round. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: Is Weapon Jammed + * 3: Type of Jam + * + * Return Value: + * None + * + * Example: + * [player, currentWeapon player, true, "Fire"] call ace_overheating_fnc_cookoffWeapon + * + * Public: No + */ + +params ["_unit", "_weapon", "_canUnjam", "_jamType"]; +TRACE_4("params",_unit,_weapon,_canUnjam,_jamType); + +// a weapon with a failure to fire or dud type jam will be unjammed from cooking off +// this is first so that the fired event from the cookoff can also cause a jam +if (_canUnjam && {_jamType in ["Fire","Dud"]}) then { + [_unit, currentMuzzle _unit, true] call FUNC(clearJam); + + // clearJam will remove a dud round, but so will the forced fire, so give back the lost round and shoot it + if (_jamType isEqualTo "Dud") then { + _unit setAmmo [_weapon, (_unit ammo _weapon) + 1]; + }; +}; + +// get valid mode and muzzle for the main weapon, we don't want the cookoff to come from an underbarrel launcher +([_weapon] call FUNC(getWeaponData)) params ["", "", "", "_modes", "_muzzle", "_reloadTime"]; + +// get an appropriate firemode and muzzle, cache the current muzzle +// trying to match firemodes and switching back to the cached muzzle will hide the change from the player and prevent unexpected mode/muzzle changes (going from full auto to semi auto, or from underbarrel GL to rifle for example) +private _muzzleCache = currentMuzzle _unit; +private _mode = currentWeaponMode _unit; +if !(_mode in _modes) then { + _mode = _modes select 0; +}; + +// delay cookoff to ensure any previous animation from a fired event is finished +[ + { + params ["_unit", "_mode", "_muzzle", "_muzzleCache"]; + + // fire the cookoff + _unit forceWeaponFire [_muzzle, _mode]; + + // switch back to the cached muzzle if required + if (_muzzle != _muzzleCache) then { + _unit selectWeapon _muzzleCache; + }; + + [ + [localize LSTRING(WeaponCookedOff)], + true // allows the hint to be overwritten by another hint, such as a jam or another cookoff + ] call CBA_fnc_notify; + }, + [_unit, _mode, _muzzle, _muzzleCache], + _reloadTime +] call CBA_fnc_waitAndExecute; diff --git a/addons/overheating/functions/fnc_coolWeaponWithItem.sqf b/addons/overheating/functions/fnc_coolWeaponWithItem.sqf new file mode 100644 index 0000000000..e5e79aaf62 --- /dev/null +++ b/addons/overheating/functions/fnc_coolWeaponWithItem.sqf @@ -0,0 +1,98 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror, drofseh + * Cool a weapon with an item and consume the item being used to cool it. + * + * Arguments: + * 0: Target + * 1: Player + * 2: Item + * + * Return Value: + * None + * + * Example: + * [ACE_player, ACE_player, "ACE_WaterBottle"] call ace_overheating_fnc_coolWeaponWithItem + * + * Public: No + */ + +params ["_target", "_unit", "_item"]; + +private _config = configFile >> "CfgWeapons" >> _item; + +// Get values +private _weapon = currentWeapon _target; +private _tempVarName = format [QGVAR(%1_temp), _weapon]; +private _temperature = _target getVariable [_tempVarName, 0]; +private _replacementItem = getText (_config >> QEXGVAR(field_rations,replacementItem)); +private _liquidAmount = getNumber (_config >> QEXGVAR(field_rations,thirstQuenched)); +private _consumeText = format [LLSTRING(CoolingWeaponWithItem), getText (configFile >> "CfgWeapons" >> _weapon >> "displayName"), getText (_config >> "displayName")]; + +/* // to be added when licence compatible audio can be found or recorded +private _pouringSound = QPATHTO_R(sounds\sizzling_short.ogg); + +if (_temperature < 100) then { + if (_liquidAmount > 5) then { + _pouringSound = QPATHTO_R(sounds\pouring_long.ogg); + } else { + _pouringSound = QPATHTO_R(sounds\pouring_short.ogg); + }; +} else { + if (_liquidAmount > 5) then { + _pouringSound = QPATHTO_R(sounds\sizzling_long.ogg); + }; +}; + +playSound3D [_pouringSound, _target, false, AGLToASL (_target modelToWorld (_target selectionPosition "RightHand")), 5, 1, 10]; +*/ + +private _fnc_onSuccess = { + params ["_args"]; + _args params ["_target", "_unit", "_item", "_weapon", "_tempVarName", "_temperature", "_replacementItem", "_liquidAmount"]; + TRACE_1("Cool weapon with item successful",_args); + + // remove the item + _unit removeItem _item; + + // Add replacement item if needed + if (_replacementItem != "") then { + [_unit, _replacementItem] call EFUNC(common,addToInventory); + }; + + // cool the weapon + private _weaponData = [_weapon] call FUNC(getWeaponData); + _temperature = [_temperature, _weaponData select 7, _liquidAmount * 10, _weaponData select 6] call FUNC(calculateCooling); + [_target, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); +}; + +/* +private _fnc_onFailure = { + params ["_args","_elapsedTime"]; + _args params ["_target", "_unit"]; +}; +*/ + +private _fnc_condition = { + params ["_args"]; + _args params ["", "_unit", "_item"]; + _item in (_unit call EFUNC(common,uniqueItems)) +}; + +[ + _liquidAmount, + [ + _target, + _unit, + _item, + _weapon, + _tempVarName, + _temperature, + _replacementItem, + _liquidAmount + ], + _fnc_onSuccess, + {}, //_fnc_onFailure, + _consumeText, + _fnc_condition +] call EFUNC(common,progressBar); diff --git a/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf b/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf new file mode 100644 index 0000000000..67f22a3cc0 --- /dev/null +++ b/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf @@ -0,0 +1,117 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror, drofseh + * Cool a weapon with an AceX water source. + * + * Arguments: + * 0: Target + * 1: Player + * + * Return Value: + * None + * + * Example: + * [ACE_player, WaterTank] call ace_overheating_fnc_coolWeaponWithWaterSource + * + * Public: No +*/ + +params ["_player", "_target"]; + +private _weapon = currentWeapon _player; +private _tempVarName = format [QGVAR(%1_temp), _weapon]; +private _temperature = _player getVariable [_tempVarName, 0]; +private _consumeText = LLSTRING(CoolingWeaponWithWaterSource); +GVAR(coolingWeaponWithWaterSource) = false; + +private _fnc_onFinish = { + params ["_args"]; + _args params ["_player", "_target", "_weapon", "_tempVarName"]; + + private _water = _target call EFUNC(field_rations,getRemainingWater); + + if (_water <= 0 && {_water != -10}) exitWith { + [ + [LLSTRING(CoolWeaponNotEnoughWater)], + true + ] call CBA_fnc_notify; + }; + + [_player, _player, currentWeapon _player] call ace_overheating_fnc_checkTemperature; + GVAR(coolingWeaponWithWaterSource) = false; +}; + +private _fnc_condition = { + params ["_args"]; + _args params ["_player", "_target", "_weapon", "_tempVarName"]; + + private _temperature = _player getVariable [_tempVarName, 0]; + private _water = _target call EFUNC(field_rations,getRemainingWater); + + if (_water <= 0 && {_water != -10}) exitWith {false}; + + if !(GVAR(coolingWeaponWithWaterSource)) then { + GVAR(coolingWeaponWithWaterSource) = true; + + //Remove water from the source, unless it's unlimited + if (_water != -10) then { + [_target, _water - 1] call EFUNC(field_rations,setRemainingWater); + }; + + //Cool the weapon down + private _weaponData = [_weapon] call FUNC(getWeaponData); + _temperature = [_temperature, _weaponData select 7, 20, _weaponData select 6] call FUNC(calculateCooling); + [_player, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); + +/* // to be added when licence compatible audio can be found or recorded + // water sound, either boiling or not + if (_temperature < 100) then { + [ + [LLSTRING(CoolWeaponIsCool)], + true // allows the hint to be overwritten by another hint, such as a jam or another cookoff + ] call CBA_fnc_notify; + + playSound3D [ + QPATHTO_R(sounds\pouring_short.ogg), + _player, + false, + AGLToASL (_player modelToWorld (_player selectionPosition "RightHand")), + 5, 1, 10 + ]; + } else { + playSound3D [ + QPATHTO_R(sounds\sizzling_short.ogg), + _player, + false, + AGLToASL (_player modelToWorld (_player selectionPosition "RightHand")), + 5, 1, 10 + ]; + }; +*/ + + // wait 1 second before allowing cooling to happen again + [ + { + GVAR(coolingWeaponWithWaterSource) = false; + }, + [], + 1 + ] call CBA_fnc_waitAndExecute; + }; + + true +}; + +[ + 1 max (_temperature / 10), + [ + _player, + _target, + _weapon, + _tempVarName + ], + _fnc_onFinish, + _fnc_onFinish, + _consumeText, + _fnc_condition +] call EFUNC(common,progressBar); diff --git a/addons/overheating/functions/fnc_displayTemperature.sqf b/addons/overheating/functions/fnc_displayTemperature.sqf index 006d81f8f5..f45d7d40d9 100644 --- a/addons/overheating/functions/fnc_displayTemperature.sqf +++ b/addons/overheating/functions/fnc_displayTemperature.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 and esteldunedain * Displays the weapon temperature diff --git a/addons/overheating/functions/fnc_firedEH.sqf b/addons/overheating/functions/fnc_firedEH.sqf index dd6b408a21..bdb7f864c9 100644 --- a/addons/overheating/functions/fnc_firedEH.sqf +++ b/addons/overheating/functions/fnc_firedEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 and esteldunedain * Handle weapon fire. Called from the unified fired EH 1- always for the local player 2- and for non local players if dispersion is simulated. @@ -16,11 +16,11 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); BEGIN_COUNTER(firedEH); -if ((_unit distance ACE_player) > 3000 +if ((_unit distance ACE_player) > GVAR(particleEffectsAndDispersionDistance) || {(_muzzle != (primaryWeapon _unit)) && {_muzzle != (handgunWeapon _unit)}}) exitWith { // Only rifle or pistol muzzles (ignore grenades / GLs) END_COUNTER(firedEH); }; @@ -54,12 +54,12 @@ if (_scaledTemperature > 0.1) then { [_projectile, _dispersionX * _dispersion, _dispersionY * _dispersion, _slowdownFactor * vectorMagnitude (velocity _projectile)] call EFUNC(common,changeProjectileDirection); TRACE_PROJECTILE_INFO(_projectile); }; - + // Particle Effects if (GVAR(showParticleEffects) && {GVAR(showParticleEffectsForEveryone) || {_unit == ACE_player} || {_unit distance ACE_player <= 20}} && {CBA_missionTime > (_unit getVariable [QGVAR(lastDrop), -1000]) + 0.40}) then { - + _unit setVariable [QGVAR(lastDrop), CBA_missionTime]; private _direction = (_unit weaponDirection _weapon) vectorMultiply 0.25; @@ -89,14 +89,32 @@ if (_scaledTemperature > 0.1) then { // Only compute jamming for the local player if (_unit != ACE_player) exitWith {END_COUNTER(firedEH);}; +private _ammoCount = _unit ammo _weapon; + // Compute new temperature once every 3 bullets -if ((_unit ammo _weapon) % 3 == 0) then { +if (_ammoCount % 3 == 0) then { _this call FUNC(overheat); }; +// reset cookoff heat +if (GVAR(cookoffCoef) > 0) then { + _unit setVariable [format [QGVAR(%1_ammoTemp), _weapon], 0]; + [_unit, _weapon, _temperature] call FUNC(updateAmmoTemperature); +}; + +// decrease time to next shot as heat increases, value is a coef where 1 is unchanged and 0 is instant, 0.8 is a 25% faster ROF. +// this could be filtered by weapon type, but I think the heat gain and rate of fire on non-automatic weapons is low enough not to bother +// do not set when empty to prevent animation glitches +if (GVAR(overheatingRateOfFire) && {_ammoCount > 0}) then { + _unit setWeaponReloadingTime [_unit, _muzzle, linearConversion [0, 0.5, _scaledTemperature, 1, 0.909, true]]; +}; + +// Don't bother with jamming if coef makes the chance 0. +if (GVAR(jamChanceCoef) == 0) exitWith {END_COUNTER(firedEH);}; + private _value = 5 * _scaledTemperature; private _array = [0.5, 1, 2, 8, 20, 150]; -_jamChance = _jamChance * linearConversion [0, 1, _value % 1, _array select floor _value, _array select ceil _value]; +_jamChance = _jamChance * GVAR(jamChanceCoef) * linearConversion [0, 1, _value % 1, _array select floor _value, _array select ceil _value]; TRACE_3("check for random jam",_unit,_weapon,_jamChance); diff --git a/addons/overheating/functions/fnc_getAmmoTemperature.sqf b/addons/overheating/functions/fnc_getAmmoTemperature.sqf new file mode 100644 index 0000000000..c1d99e86bc --- /dev/null +++ b/addons/overheating/functions/fnc_getAmmoTemperature.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Get current temperature of weapon's ammo. + * + * Arguments: + * 0: Unit + * 1: Weapon + * + * Return Value: + * Current ammunition temperature + * + * Example: + * [player, currentWeapon player] call ace_overheating_fnc_getAmmoTemperature + * + * Public: Yes + */ + +params ["_unit", "_weapon"]; + +private _ammoTempVarName = format [QGVAR(%1_ammoTemp), _weapon]; + +_unit getVariable [_ammoTempVarName, ambientTemperature select 0] diff --git a/addons/overheating/functions/fnc_getBarrelMass.sqf b/addons/overheating/functions/fnc_getBarrelMass.sqf new file mode 100644 index 0000000000..43150b4fee --- /dev/null +++ b/addons/overheating/functions/fnc_getBarrelMass.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror, drofseh + * Get the mass of the weapons barrel. + * + * Arguments: + * 0: Weapon + * + * Return Value: + * Barrel Mass + * + * Example: + * [currentWeapon ACE_player] call ace_overheating_fnc_getBarrelMass + * + * Public: No + */ + +params ["_weapon"]; + +private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; + +_barrelMass diff --git a/addons/overheating/functions/fnc_getConsumableChildren.sqf b/addons/overheating/functions/fnc_getConsumableChildren.sqf new file mode 100644 index 0000000000..025e9a6939 --- /dev/null +++ b/addons/overheating/functions/fnc_getConsumableChildren.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001, Glowbal, PabstMirror + * Returns children actions for consumable items in player's inventory. + * + * Arguments: + * 0: Player + * + * Return Value: + * Actions + * + * Example: + * [_unit] call ace_overheating_fnc_getConsumableChildren + * + * Public: No + */ + +params ["_unit"]; + +private _fnc_getActions = { + TRACE_1("Creating overheating consumable item actions",_unit); + + private _actions = []; + private _cfgWeapons = configFile >> "CfgWeapons"; + + { + private _config = _cfgWeapons >> _x; + if (getNumber (_config >> QEXGVAR(field_rations,thirstQuenched)) > 0) then { + private _displayName = getText (_config >> "displayName"); + private _picture = getText (_config >> "picture"); + + // Exec next frame so closing interaction menu doesn't block progressBar + private _action = [_x, _displayName, _picture, {[FUNC(coolWeaponWithItem), _this] call CBA_fnc_execNextFrame}, {true}, {}, _x] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _unit]; + }; + } forEach (_unit call EFUNC(common,uniqueItems)); + + _actions +}; + +[[], _fnc_getActions, _unit, QGVAR(overheatingConsumableActionsCache), 9999, "cba_events_loadoutEvent"] call EFUNC(common,cachedCall); diff --git a/addons/overheating/functions/fnc_getWeaponData.sqf b/addons/overheating/functions/fnc_getWeaponData.sqf index a055f65b1e..8edd86bb1a 100644 --- a/addons/overheating/functions/fnc_getWeaponData.sqf +++ b/addons/overheating/functions/fnc_getWeaponData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror and esteldunedain * Get weapon data with caching @@ -7,9 +7,14 @@ * 0: weapon type * * Return Value: - * 0: dispresion + * 0: dispersion * 1: slowdownFactor * 2: jamChance + * 3: modes + * 4: muzzle + * 5: reloadTime + * 6: closedBolt + * 7: barrelMass * * Example: * ["gun"] call ace_overheating_fnc_getWeaponData @@ -20,7 +25,7 @@ params ["_weapon"]; // Look in the cache first -private _weaponData = GVAR(cacheWeaponData) getVariable _weapon; +private _weaponData = GVAR(cacheWeaponData) get _weapon; if (!isNil "_weaponData") exitWith {_weaponData}; // Search the config @@ -65,9 +70,25 @@ if (isArray _property) then { }; }; +// for cookoff +private _modes = getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); +private _muzzle = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles") select 0; +if (_muzzle == "this") then { + _muzzle = _weapon; +}; + +private _reloadTime = getNumber (configfile >> "CfgWeapons" >> _weapon >> (_modes select 0) >> "reloadTime"); + +private _closedBolt = getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(closedBolt)); + +private _barrelMass = getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(barrelMass)); +if (_barrelMass <= 0) then { + _barrelMass = METAL_MASS_RATIO * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; +}; + // Cache the values -_weaponData = [_dispersion, _slowdownFactor, _jamChance]; +_weaponData = [_dispersion, _slowdownFactor, _jamChance, _modes, _muzzle, _reloadTime, _closedBolt, _barrelMass]; TRACE_2("building cache",_weapon,_weaponData); -GVAR(cacheWeaponData) setVariable [_weapon, _weaponData]; +GVAR(cacheWeaponData) set [_weapon, _weaponData]; _weaponData diff --git a/addons/overheating/functions/fnc_getWeaponTemperature.sqf b/addons/overheating/functions/fnc_getWeaponTemperature.sqf new file mode 100644 index 0000000000..e0d13a75d5 --- /dev/null +++ b/addons/overheating/functions/fnc_getWeaponTemperature.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Get current temperature of weapon. + * + * Arguments: + * 0: Unit + * 1: Weapon + * + * Return Value: + * Current ammunition temperature + * + * Example: + * [player, currentWeapon player] call ace_overheating_fnc_getWeaponTemperature + * + * Public: Yes + */ + +params ["_unit", "_weapon"]; + +private _weaponTempVarName = format [QGVAR(%1_temp), _weapon]; + +_unit getVariable [_weaponTempVarName, ambientTemperature select 0]; diff --git a/addons/overheating/functions/fnc_handleRespawn.sqf b/addons/overheating/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..e55ab7cc9e --- /dev/null +++ b/addons/overheating/functions/fnc_handleRespawn.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: 10Dozen + * Handle respawn events and clears list of jammed weapons. + * DefaultAction that blocks firing is removed by the game (remains on corpse?), + * but variables need to be cleared manually. + * + * Arguments: + * 0: Unit + * 1: Corpse + * + * Return Value: + * None + * + * Example: + * [alive, body] call ace_overheating_fnc_handleRespawn + * + * Public: No + */ + +params ["_unit","_dead"]; +if !(local _unit) exitWith {}; + +// --- Reset variables related to jamming +_unit setVariable [QGVAR(jammedWeapons), nil]; +_unit setVariable [QGVAR(JammingActionID), nil]; diff --git a/addons/overheating/functions/fnc_handleTakeEH.sqf b/addons/overheating/functions/fnc_handleTakeEH.sqf index d347e5f071..f6bd4d4323 100644 --- a/addons/overheating/functions/fnc_handleTakeEH.sqf +++ b/addons/overheating/functions/fnc_handleTakeEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 * Handle "take" event @@ -18,16 +18,20 @@ * Public: No */ -if !(GVAR(unJamOnreload)) exitWith {}; - params ["_unit", "_container", "_item"]; TRACE_3("params",_unit,_container,_item); if ((_unit == ACE_player) - && {_container in [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]} - && {_item == currentMagazine _unit}) then { //Todo: should this be any valid magazine for any jammed gun? + && {_container in [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]} + && {_item == currentMagazine _unit} +) then { //Todo: should this be any valid magazine for any jammed gun? - TRACE_1("clearing jam",currentWeapon _unit); - [_unit, currentWeapon _unit, true] call FUNC(clearJam) + if (GVAR(unJamOnReload)) then { + TRACE_1("clearing jam",currentWeapon _unit); + [_unit, currentWeapon _unit, true] call FUNC(clearJam); + }; + if (GVAR(cookoffCoef) > 0) then { + _unit setVariable [format [QGVAR(%1_ammoTemp), currentWeapon _unit], 0]; + }; }; diff --git a/addons/overheating/functions/fnc_jamWeapon.sqf b/addons/overheating/functions/fnc_jamWeapon.sqf index f8518add8e..9a5b8b1049 100644 --- a/addons/overheating/functions/fnc_jamWeapon.sqf +++ b/addons/overheating/functions/fnc_jamWeapon.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2, based on KK_fnc_playerWeaponMulfunction from KillzoneKid * Jam the weapon @@ -21,44 +21,87 @@ TRACE_2("params",_unit,_weapon); // don't jam a weapon with no rounds left private _ammo = _unit ammo _weapon; -if (_ammo == 0) exitWith {}; +if (_ammo < 1) exitWith {}; private _jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []]; _jammedWeapons pushBack _weapon; _unit setVariable [QGVAR(jammedWeapons), _jammedWeapons]; +// Get jam types, select one from available types +// Cookoffs only happen on Fire and Dud, dud rounds are lost on jam clear. +// Reduce chance of duds as temp increases (functionally increasing the chance of the others but with fewer commands) +private _temp = 1 max (_unit getVariable [format [QGVAR(%1_temp), _weapon], 0]); +private _jamTypesAllowed = getArray (configFile >> 'CfgWeapons' >> currentWeapon _unit >> QGVAR(jamTypesAllowed)); + +if (_jamTypesAllowed isEqualTo []) then { + _jamTypesAllowed = ["Eject", 1, "Extract", 1, "Feed", 1, "Fire", 1, "Dud", (5 / (_temp / 5))]; +} else { + for "_i" from count _jamTypesAllowed to 1 step -1 do { + private _jamCurretType = _jamTypesAllowed select _i; + if !(_jamCurretType in ["Eject", "Extract", "Feed", "Fire", "Dud"]) exitWith { // check config values and switch to default values if unusual value found + ERROR_2("Weapon '%1' has unexpected value %2 in QQGVAR(jamTypesAllowed). Expected values are 'Eject', 'Extract', 'Feed', 'Fire', 'Dud'.",_weapon,_jamCurretType); + _jamTypesAllowed = ["Eject", 1, "Extract", 1, "Feed", 1, "Fire", 1, "Dud", (5 / (_temp / 5))]; + }; + if (_jamCurretType == "Dud") then { + _jamTypesAllowed insert [_i, [5 / (_temp / 5)]]; + } else { + _jamTypesAllowed insert [_i, [1]]; + }; + }; +}; + +private _jamType = selectRandomWeighted _jamTypesAllowed; +_unit setVariable [format [QGVAR(%1_jamType), _weapon], _jamType]; // Stop current burst -if (_ammo > 0) then { - _unit setAmmo [_weapon, 0]; - // this is to re-activate the 'DefaultAction', so you can jam a weapon while full auto shootin - [{ - params ["_unit", "_weapon", "_ammo"]; - _unit setAmmo [_weapon, _ammo]; - }, [_unit, _weapon, _ammo]] call CBA_fnc_execNextFrame; +_unit setAmmo [_weapon, 0]; +// this is to re-activate the 'DefaultAction', so you can jam a weapon while full auto shooting +[{ + params ["_unit", "_weapon", "_ammo"]; + _unit setAmmo [_weapon, _ammo]; +}, [_unit, _weapon, _ammo]] call CBA_fnc_execNextFrame; + +if (_weapon == primaryWeapon _unit) then { + playSound QGVAR(jamming_rifle); +} else { + if (_weapon == handgunWeapon _unit) then { + playSound QGVAR(jamming_pistol); + }; }; // only display the hint once, after you try to shoot an already jammed weapon GVAR(knowAboutJam) = false; -["ace_weaponJammed", [_unit,_weapon]] call CBA_fnc_localEvent; - +["ace_weaponJammed", [_unit, _weapon, _jamType]] call CBA_fnc_localEvent; if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then { private _condition = { - [_this select 1] call CBA_fnc_canUseWeapon - && {currentMuzzle (_this select 1) in ((_this select 1) getVariable [QGVAR(jammedWeapons), []])} - && {!(currentMuzzle (_this select 1) in ((_this select 1) getVariable [QEGVAR(safemode,safedWeapons), []]))} + private _unit = _this select 1; + [_unit] call CBA_fnc_canUseWeapon + && {currentMuzzle _unit in (_unit getVariable [QGVAR(jammedWeapons), []])} + && {!(currentMuzzle _unit in (_unit getVariable [QEGVAR(safemode,safedWeapons), []]))} }; private _statement = { - playSound3D ["a3\sounds_f\weapons\Other\dry9.wss", _this select 0]; + params ["_zero","_one"]; - if (!(missionNamespace getVariable [QGVAR(knowAboutJam), false]) && {(_this select 1) ammo currentWeapon (_this select 1) > 0} && {GVAR(DisplayTextOnJam)}) then { - [localize LSTRING(WeaponJammed)] call EFUNC(common,displayTextStructured); + playSound3D ["a3\sounds_f\weapons\Other\dry9.wss", _zero, false, eyePos _zero, 1, 1, 15]; + + if (!(missionNamespace getVariable [QGVAR(knowAboutJam), false]) && {_one ammo currentWeapon _one > 0} && {GVAR(DisplayTextOnJam)}) then { + private _jamType = _one getVariable [format [QGVAR(%1_jamType), currentWeapon _one], "None"]; + private _jamMessage = localize LSTRING(FailureToFire); + switch true do { + case (_jamType isEqualTo "Eject"): {_jamMessage = localize LSTRING(FailureToEject)}; + case (_jamType isEqualTo "Extract"): {_jamMessage = localize LSTRING(FailureToExtract)}; + case (_jamType isEqualTo "Feed"): {_jamMessage = localize LSTRING(FailureToFeed)}; + }; + [ + [localize LSTRING(WeaponJammed)], + [_jamMessage] + ] call CBA_fnc_notify; GVAR(knowAboutJam) = true; }; }; diff --git a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf index 5b7ce31571..a5fb95cf31 100644 --- a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf +++ b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Collect the temperature of all the spare barrels a unit has and load the @@ -25,22 +25,19 @@ params ["_assistant", "_gunner", "_weapon", "_weaponTemp", "_barrelMass"]; TRACE_5("loadCoolestSpareBarrel1",_assistant,_gunner,_weapon,_weaponTemp,_barrelMass); private _weaponBarrelClass = getText (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(barrelClassname)); //If the weapon has no defined classname then use the ACE one -if(_weaponBarrelClass == "") then { +if (_weaponBarrelClass == "") then { _weaponBarrelClass = "ACE_SpareBarrel"; }; // Find all spare barrel the player has private _allBarrels = [_assistant, _weaponBarrelClass] call CBA_fnc_getMagazineIndex; TRACE_1("_allBarrels",_allBarrels); -if ((count _allBarrels) < 1) exitWith {}; +if (_allBarrels isEqualTo []) exitWith {}; // Determine which on is coolest private _coolestTemp = 10000; private _coolestMag = _allBarrels select 0; { - private _temp = 0; - if ([GVAR(storedSpareBarrels), _x] call CBA_fnc_hashHasKey) then { - _temp = ([GVAR(storedSpareBarrels), _x] call CBA_fnc_hashGet) select 0; - }; + private _temp = GVAR(storedSpareBarrels) getOrDefault [_x, [0]] select 0; TRACE_2("loadCoolestSpareBarrel4",_x,_temp); if (_temp < _coolestTemp) then { _coolestTemp = _temp; @@ -54,7 +51,7 @@ TRACE_3("loadCoolestSpareBarrel5",_coolestTemp,_coolestMag,_weaponTemp); _gunner setVariable [format [QGVAR(%1_temp), _weapon], _coolestTemp, true]; // Heat up the coolest barrel to the former weapon temperature -[GVAR(storedSpareBarrels), _coolestMag, [_weaponTemp, CBA_missionTime, _barrelMass]] call CBA_fnc_hashSet; +GVAR(storedSpareBarrels) set [_coolestMag, [_weaponTemp, CBA_missionTime, _barrelMass]]; // Send an event so the machines of the assistant and gunner can show the hint [QGVAR(showWeaponTemperature), [_gunner, _weapon], [_assistant, _gunner]] call CBA_fnc_targetEvent; diff --git a/addons/overheating/functions/fnc_overheat.sqf b/addons/overheating/functions/fnc_overheat.sqf index f1eb7b16c0..b06fcaf668 100644 --- a/addons/overheating/functions/fnc_overheat.sqf +++ b/addons/overheating/functions/fnc_overheat.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 and esteldunedain * Handle weapon fire, heat up the weapon @@ -26,9 +26,9 @@ TRACE_4("params",_unit,_weapon,_ammo,_projectile); BEGIN_COUNTER(overheat); // Get bullet parameters -private _energyIncrement = GVAR(cacheAmmoData) getVariable _ammo; +private _energyIncrement = GVAR(cacheAmmoData) get _ammo; if (isNil "_energyIncrement") then { - _bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass"); + private _bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass"); if (_bulletMass == 0) then { // If the bullet mass is not configured, estimate it _bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber")); @@ -38,28 +38,27 @@ if (isNil "_energyIncrement") then { // Ref: https://en.wikipedia.org/wiki/Physics_of_firearms // Muzzle Engergy = 1/2 * m * v^2 = (1/2 * 0.001 g/kg * bulletMass (grams) * v^2) // Multiple by 3 becase we only calc every 3rd bullet: (3 * 1/2 * 0.001) = 0.0015 - _energyIncrement = 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile); + _energyIncrement = GVAR(heatCoef) * 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile); - GVAR(cacheAmmoData) setVariable [_ammo, _energyIncrement]; + GVAR(cacheAmmoData) set [_ammo, _energyIncrement]; }; // Increase overheating depending on how obstrusive is the current supressor, // if any. Typical arma supressors have visibleFire=0.5 and audibleFire=0.3, // so they produce x2.1 overheating -private _silencer = switch (_weapon) do { +private _suppressor = switch (_weapon) do { case (primaryWeapon _unit) : {(primaryWeaponItems _unit) select 0}; case (handgunWeapon _unit) : {(handgunItems _unit) select 0}; default {""}; }; -if (_silencer != "") then { - private _silencerCoef = GVAR(cacheSilencerData) getVariable _silencer; - if (isNil "_silencerCoef") then { - _silencerCoef = 1 + - (1 - getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire")) + - (1 - getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "visibleFire")); - GVAR(cacheSilencerData) setVariable [_silencer, _silencerCoef]; +if (_suppressor != "" && {GVAR(suppressorCoef) > 0}) then { + private _suppressorCoef = GVAR(cacheSilencerData) get _suppressor; + if (isNil "_suppressorCoef") then { + private _config = configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef"; + _suppressorCoef = GVAR(suppressorCoef) * (1 + (1 - getNumber (_config >> "audibleFire")) + (1 - getNumber (_config >> "visibleFire"))); + GVAR(cacheSilencerData) set [_suppressor, _suppressorCoef]; }; - _energyIncrement = _energyIncrement * _silencerCoef; + _energyIncrement = _energyIncrement * _suppressorCoef; }; TRACE_1("heat",_energyIncrement); diff --git a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf index ff71814ea8..5f75423f2e 100644 --- a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf +++ b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Collect the temperature of all the spare barrels a unit has and send a hint @@ -12,7 +12,7 @@ * None * * Example: - * [bob, "bob"] call ace_overheating_fnc_sendSpareBarrelsIsTemperaturesHint + * [bob, "bob"] call ace_overheating_fnc_sendSpareBarrelsTemperaturesHint * * * Public: No @@ -27,20 +27,17 @@ private _weapon = currentWeapon _player; //Get the classname of the spare barrel of that weapon private _weaponBarrelClass = getText (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(barrelClassname)); //If the weapon has no defined classname then use the ACE one -if(_weaponBarrelClass == "") then { +if (_weaponBarrelClass == "") then { _weaponBarrelClass = "ACE_SpareBarrel"; }; private _allBarrels = [_unit, _weaponBarrelClass] call CBA_fnc_getMagazineIndex; TRACE_1("_allBarrels",_allBarrels); -if ((count _allBarrels) < 1) exitWith {}; +if (_allBarrels isEqualTo []) exitWith {}; // Determine the temp of each barrel private _temps = []; { - private _temp = 0; - if ([GVAR(storedSpareBarrels), _x] call CBA_fnc_hashHasKey) then { - _temp = ([GVAR(storedSpareBarrels), _x] call CBA_fnc_hashGet) select 0; - }; + private _temp = GVAR(storedSpareBarrels) getOrDefault [_x, [0]] select 0; _temps pushBack _temp; } forEach _allBarrels; TRACE_1("_temps",_temps); diff --git a/addons/overheating/functions/fnc_setAmmoTemperature.sqf b/addons/overheating/functions/fnc_setAmmoTemperature.sqf new file mode 100644 index 0000000000..99e96bd41c --- /dev/null +++ b/addons/overheating/functions/fnc_setAmmoTemperature.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Set weapon's ammo to specific temperature. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: Temperature + * + * Return Value: + * None + * + * Example: + * [player, currentWeapon player, 123] call ace_overheating_fnc_setAmmoTemperature + * + * Public: Yes + */ + +params ["_unit", "_weapon", "_temp"]; + +private _ammoTempVarName = format [QGVAR(%1_ammoTemp), _weapon]; + +_unit setVariable [_ammoTempVarName, _temp]; diff --git a/addons/overheating/functions/fnc_setWeaponTemperature.sqf b/addons/overheating/functions/fnc_setWeaponTemperature.sqf new file mode 100644 index 0000000000..56a7c4e84b --- /dev/null +++ b/addons/overheating/functions/fnc_setWeaponTemperature.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Set weapon to specific temperature. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: Temperature + * + * Return Value: + * None + * + * Example: + * [player, currentWeapon player, 123] call ace_overheating_fnc_setWeaponTemperature + * + * Public: Yes + */ + +params ["_unit", "_weapon", "_temp"]; + +private _weaponTempVarName = format [QGVAR(%1_temp), _weapon]; + +_unit setVariable [_weaponTempVarName, _temp]; diff --git a/addons/overheating/functions/fnc_statTextStatement_allowSwapBarrel.sqf b/addons/overheating/functions/fnc_statTextStatement_allowSwapBarrel.sqf new file mode 100644 index 0000000000..9713023c17 --- /dev/null +++ b/addons/overheating/functions/fnc_statTextStatement_allowSwapBarrel.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Barrel Type statement. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["", "_config"]; +TRACE_1("statTextStatement_allowSwapBarrel",_config); + +if ((getNumber (_config >> QGVAR(allowSwapBarrel))) == 1) exitWith {LLSTRING(statBarrelType_removeable)}; + +LLSTRING(statBarrelType_nonRemoveable) diff --git a/addons/overheating/functions/fnc_statTextStatement_boltType.sqf b/addons/overheating/functions/fnc_statTextStatement_boltType.sqf new file mode 100644 index 0000000000..67967496c7 --- /dev/null +++ b/addons/overheating/functions/fnc_statTextStatement_boltType.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Bolt Type statement. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["", "_config"]; +TRACE_1("statTextStatement_boltType",_config); + +if ((getNumber (_config >> QGVAR(closedBolt))) == 1) exitWith {LLSTRING(statBoltType_closedBolt)}; + +LLSTRING(statBoltType_openBolt) diff --git a/addons/overheating/functions/fnc_swapBarrel.sqf b/addons/overheating/functions/fnc_swapBarrel.sqf index b24ac39f3c..8c43032a41 100644 --- a/addons/overheating/functions/fnc_swapBarrel.sqf +++ b/addons/overheating/functions/fnc_swapBarrel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2 * Make a unit start swapping it's barrel diff --git a/addons/overheating/functions/fnc_swapBarrelAssistant.sqf b/addons/overheating/functions/fnc_swapBarrelAssistant.sqf index c8fbba6e3c..5141cc1f5a 100644 --- a/addons/overheating/functions/fnc_swapBarrelAssistant.sqf +++ b/addons/overheating/functions/fnc_swapBarrelAssistant.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain, Commy2 * Make a unit start swapping the barrel of another unit diff --git a/addons/overheating/functions/fnc_swapBarrelCallback.sqf b/addons/overheating/functions/fnc_swapBarrelCallback.sqf index 0b0dec4916..e09f8d0dbc 100644 --- a/addons/overheating/functions/fnc_swapBarrelCallback.sqf +++ b/addons/overheating/functions/fnc_swapBarrelCallback.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Commy2, esteldunedain * Swap barrel callback @@ -26,11 +26,15 @@ if (_assistant isEqualTo _gunner) then { playSound "ACE_BarrelSwap"; }; +if (GVAR(unJamOnSwapBarrel) && {[_gunner] call FUNC(canUnjam)}) then { + [_gunner, currentMuzzle _gunner, true] call FUNC(clearJam); +}; + // don't consume the barrel, but rotate through them. [localize LSTRING(SwappedBarrel), QPATHTOF(UI\spare_barrel_ca.paa)] call EFUNC(common,displayTextPicture); private _temp = _gunner getVariable [format [QGVAR(%1_temp), _weapon], 0]; -private _barrelMass = METAL_MASS_RATIO * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; +private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; // Instruct the server to load the coolest spare barrel into the weapon and // store the removed barrel with the former weapon temperature. The server diff --git a/addons/overheating/functions/fnc_updateAmmoTemperature.sqf b/addons/overheating/functions/fnc_updateAmmoTemperature.sqf new file mode 100644 index 0000000000..870ebbc331 --- /dev/null +++ b/addons/overheating/functions/fnc_updateAmmoTemperature.sqf @@ -0,0 +1,62 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Update temperature of the round in the chamber and determine if a cookoff should occur. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: Barrel Temperature + * + * Return Value: + * New temperature + * + * Example: + * [player, currentWeapon player, 600] call ace_overheating_fnc_updateAmmoTemperature + * + * Public: No + */ + +params ["_unit", "_weapon", "_barrelTemperature"]; +TRACE_3("params",_unit,_weapon,_barrelTemperature); + +private _closedBolt = ([_weapon] call FUNC(getWeaponData)) select 6; +private _canUnjam = [_unit] call FUNC(canUnjam); +private _jamType = _unit getVariable [format [QGVAR(%1_jamType), _weapon], "None"]; + +// Skip if no ammo in chamber +if ( + _unit ammo _weapon < 1 + // closed bolt, and jammed and type not failure to fire + || {_closedBolt == 1 && {_canUnjam} && {!(_jamType in ["Fire","Dud"])}} + // open bolt, and not jammed, or jammed and type not failure to fire + || {_closedBolt == 0 && {!_canUnjam || {_canUnjam && {!(_jamType in ["Fire","Dud"])}}}} +) exitWith { + private _ambientTemperature = ambientTemperature select 0; + _unit setVariable [format [QGVAR(%1_ammoTemp), _weapon], _ambientTemperature]; + _ambientTemperature +}; + +private _ammoTempVarName = format [QGVAR(%1_ammoTemp), _weapon]; +private _ammoTemperature = _unit getVariable [_ammoTempVarName, ambientTemperature select 0]; + +// heat or cool the ammo +if (_ammoTemperature < _barrelTemperature) then { + // this is functional and feels ok, but someone please do better heat transfer math here, my head hurts. + private _temperatureDifference = _barrelTemperature - _ammoTemperature; + _ammoTemperature = _ammoTemperature + (1 max ((_temperatureDifference / 2.75) - 100)); +} else { + _ammoTemperature = _barrelTemperature; +}; + +// cookoff if too hot +if (_ammoTemperature > (GUNPOWDER_IGNITION_TEMP * GVAR(cookoffCoef))) then { + [_unit, _weapon, _canUnjam, _jamType] call FUNC(cookoffWeapon); + + // since a cookoff happened then the next round should start at the ambient temperature. + _ammoTemperature = ambientTemperature select 0; +}; + +_unit setVariable [_ammoTempVarName, _ammoTemperature]; + +_ammoTemperature diff --git a/addons/overheating/functions/fnc_updateAmmoTemperatureThread.sqf b/addons/overheating/functions/fnc_updateAmmoTemperatureThread.sqf new file mode 100644 index 0000000000..622fc3de6c --- /dev/null +++ b/addons/overheating/functions/fnc_updateAmmoTemperatureThread.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: esteldunedain & drofseh + * Update . + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_overheating_fnc_updateAmmoTemperatureThread + * + * Public: No + */ + +// If the ace_overheating_cookoffCoef setting is set to 0 mid mission we want to exit right away or it will immediate cause all player weapons to cook off. +if (GVAR(cookoffCoef) isEqualTo 0) exitWith { + WARNING_1("'%1' has been set to 0 mid mission. Changing this setting requires mission restart.",GVAR(cookoffCoef)); +}; + +private _currentWeapon = currentWeapon ACE_player; +if ((_currentWeapon != "") && {_currentWeapon == primaryWeapon ACE_player || {_currentWeapon == handgunWeapon ACE_player}}) then { + private _temperature = ACE_player getVariable [format [QGVAR(%1_temp), _currentWeapon], 0]; + [ACE_player, _currentWeapon, _temperature] call FUNC(updateAmmoTemperature); +}; + +// Schedule for execution again after 1 seconds. A quick loop is needed for ammo temperature in order to have faster cookoffs at higher barrel temps +[DFUNC(updateAmmoTemperatureThread), [], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf index d2a499fb94..da87c5fdba 100644 --- a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf +++ b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Calculate cooldown of all the stored spare barrels. @@ -15,28 +15,21 @@ * Public: No */ -private _pairs = []; TRACE_1("updateSpareBarrelsTemperaturesThread1",GVAR(storedSpareBarrels)); -[GVAR(storedSpareBarrels), { - //IGNORE_PRIVATE_WARNING ["_key", "_value"]; - _pairs pushBack [_key, _value]; -}] call CBA_fnc_hashEachPair; -TRACE_1("updateSpareBarrelsTemperaturesThread2",_pairs); { - _x params ["_barrelMagazineID","_value"]; - _value params ["_initialTemp","_initialTime", "_barrelMass"]; + _y params ["_initialTemp","_initialTime", "_barrelMass"]; // Calculate cooling - private _finalTemp = [_initialTemp, _barrelMass, CBA_missionTime - _initialTime] call FUNC(calculateCooling); - TRACE_4("updateSpareBarrelsTemperaturesThread3",_barrelMagazineID,_initialTemp,_finalTemp,_barrelMass); - if (_finalTemp < 5) then { - // The barrel is cool enough to keep calculating. Remove it from the hash - [GVAR(storedSpareBarrels), _barrelMagazineID] call CBA_fnc_hashRem; + private _finalTemp = [_initialTemp, _barrelMass, CBA_missionTime - _initialTime, 0] call FUNC(calculateCooling); //the zero is to indicate an open bolt gun. Barrel is outside of a gun here, so always open. + TRACE_4("updateSpareBarrelsTemperaturesThread2",_barrelMagazineID,_initialTemp,_finalTemp,_barrelMass); + if (_finalTemp <= (ambientTemperature select 0)) then { + // The barrel is cool enough to finish calculating. Remove it from the hash + GVAR(storedSpareBarrels) deleteAt _x; } else { // Store the new temp - [GVAR(storedSpareBarrels), _barrelMagazineID, [_finalTemp, CBA_missionTime, _barrelMass]] call CBA_fnc_hashSet; + GVAR(storedSpareBarrels) set [_x, [_finalTemp, CBA_missionTime, _barrelMass]]; }; -} forEach _pairs; +} forEach GVAR(storedSpareBarrels); // Schedule for execution again after 10 seconds [DFUNC(updateSpareBarrelsTemperaturesThread), [], 10] call CBA_fnc_waitAndExecute; diff --git a/addons/overheating/functions/fnc_updateTemperature.sqf b/addons/overheating/functions/fnc_updateTemperature.sqf index 475f0454f9..db7f48be83 100644 --- a/addons/overheating/functions/fnc_updateTemperature.sqf +++ b/addons/overheating/functions/fnc_updateTemperature.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Update temperature of a weapon. @@ -9,7 +9,7 @@ * 2: Heat increment (J) * * Return Value: - * Current temperature + * New temperature * * Example: * [player, currentWeapon player, 2000] call ace_overheating_fnc_updateTemperature @@ -27,10 +27,15 @@ private _timeVarName = format [QGVAR(%1_time), _weapon]; private _temperature = _unit getVariable [_tempVarName, 0]; private _lastTime = _unit getVariable [_timeVarName, 0]; -private _barrelMass = METAL_MASS_RATIO * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; +// keep track of weapons that have heat, so they can be set to ambient temperaure on killed/respawn +private _trackedWeapons = _unit getVariable [QGVAR(trackedWeapons), []]; +_trackedWeapons pushBackUnique _tempVarName; +_unit setVariable [QGVAR(trackedWeapons), _trackedWeapons]; // Calculate cooling -_temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime] call FUNC(calculateCooling); +private _weaponData = [_weapon] call FUNC(getWeaponData); +private _barrelMass = _weaponData select 7; +_temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime, _weaponData select 6] call FUNC(calculateCooling); TRACE_1("cooledTo",_temperature); // Calculate heating @@ -39,6 +44,7 @@ _temperature = _temperature + _heatIncrement / (_barrelMass * 466); // Publish the temperature variable [_unit, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); + // Store the update time locally _unit setVariable [_timeVarName, CBA_missionTime]; diff --git a/addons/overheating/functions/fnc_updateTemperatureThread.sqf b/addons/overheating/functions/fnc_updateTemperatureThread.sqf index 03f2bee53f..1fd3ddd258 100644 --- a/addons/overheating/functions/fnc_updateTemperatureThread.sqf +++ b/addons/overheating/functions/fnc_updateTemperatureThread.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Update cooldown calculation of all player weapons at regular intervals. @@ -15,9 +15,20 @@ * Public: No */ -private _currentWeapon = currentWeapon ACE_player; -if ((_currentWeapon != "") && {_currentWeapon == primaryWeapon ACE_player || {_currentWeapon == handgunWeapon ACE_player}}) then { - [ACE_player, _currentWeapon, 0] call FUNC(updateTemperature); +if (ACE_player call EFUNC(common,isSwimming)) then { // cool off both weapons while swimming because currentWeapon == "" + private _primaryWeapon = primaryWeapon ACE_player; + private _handgunWeapon = handgunWeapon ACE_player; + if (_primaryWeapon != "") then { + [ACE_player, _primaryWeapon, 0] call FUNC(updateTemperature); + }; + if (_handgunWeapon != "") then { + [ACE_player, _handgunWeapon, 0] call FUNC(updateTemperature); + }; +} else { + private _currentWeapon = currentWeapon ACE_player; + if ((_currentWeapon != "") && {_currentWeapon == primaryWeapon ACE_player || {_currentWeapon == handgunWeapon ACE_player}}) then { + [ACE_player, _currentWeapon, 0] call FUNC(updateTemperature); + }; }; // Schedule for execution again after 5 seconds diff --git a/addons/overheating/functions/script_component.hpp b/addons/overheating/functions/script_component.hpp deleted file mode 100644 index a8668e5b4f..0000000000 --- a/addons/overheating/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\overheating\script_component.hpp" \ No newline at end of file diff --git a/addons/overheating/initSettings.inc.sqf b/addons/overheating/initSettings.inc.sqf new file mode 100644 index 0000000000..b3eaf24029 --- /dev/null +++ b/addons/overheating/initSettings.inc.sqf @@ -0,0 +1,145 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_displayName), LSTRING(enabled_description)], + _category, + true, + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(heatCoef), "SLIDER", + [LSTRING(heatCoef_displayName), LSTRING(heatCoef_description)], + _category, + [0, 5, 1, 2], + 1, + { + if (!GVAR(enabled)) exitWith {}; + TRACE_2("reseting cache",GVAR(heatCoef),count GVAR(cacheAmmoData)); + GVAR(cacheAmmoData) = createHashMap; + }, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(coolingCoef), "SLIDER", + [LSTRING(coolingCoef_displayName), LSTRING(coolingCoef_description)], + _category, + [0, 5, 1, 2], + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(suppressorCoef), "SLIDER", + [LSTRING(suppressorCoef_displayName), LSTRING(suppressorCoef_description)], + _category, + [0, 5, 1, 2], + 1, + { + if (!GVAR(enabled)) exitWith {}; + TRACE_2("reseting cache",GVAR(suppressorCoef),count GVAR(cacheSilencerData)); + GVAR(cacheSilencerData) = createHashMap; + }, + false +] call CBA_fnc_addSetting; + +[ + QGVAR(showParticleEffects), "CHECKBOX", + [LSTRING(showParticleEffects_displayName), LSTRING(showParticleEffects_description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(showParticleEffectsForEveryone), "CHECKBOX", + [LSTRING(showParticleEffectsForEveryone_displayName), LSTRING(showParticleEffectsForEveryone_description)], + _category, + false, + 0, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(overheatingDispersion), "CHECKBOX", + [LSTRING(overheatingDispersion_displayName), LSTRING(overheatingDispersion_description)], + _category, + true, + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(particleEffectsAndDispersionDistance), "SLIDER", + [LSTRING(particleEffectsAndDispersionDistance_displayName), LSTRING(particleEffectsAndDispersionDistance_description)], + _category, + [1, 5000, 3000, 0], + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(overheatingRateOfFire), "CHECKBOX", + [LSTRING(overheatingRateOfFire_displayName), LSTRING(overheatingRateOfFire_description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(displayTextOnJam), "CHECKBOX", + [LSTRING(DisplayTextOnJam_displayName), LSTRING(displayTextOnJam_description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(jamChanceCoef), "SLIDER", + [LSTRING(jamChanceCoef_displayName), LSTRING(jamChanceCoef_description)], + _category, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(unJamOnreload), "CHECKBOX", + [LSTRING(unJamOnreload_displayName), LSTRING(unJamOnreload_description)], + _category, + false, + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(unJamOnSwapBarrel), "CHECKBOX", + [LSTRING(unJamOnSwapBarrel_displayName), LSTRING(unJamOnSwapBarrel_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(unJamFailChance), "SLIDER", + [LSTRING(unJamFailChance_displayName), LSTRING(unJamFailChance_description)], + _category, + [0, 1, 0.1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(cookoffCoef), "SLIDER", + [LSTRING(cookoffCoef_displayName), LSTRING(cookoffCoef_description)], + _category, + [0, 5, 1, 2], + 1, + {}, + true +] call CBA_fnc_addSetting; diff --git a/addons/overheating/script_component.hpp b/addons/overheating/script_component.hpp index d7dde59da2..dd1b18806f 100644 --- a/addons/overheating/script_component.hpp +++ b/addons/overheating/script_component.hpp @@ -18,6 +18,8 @@ #define TEMP_TOLERANCE 50 #define METAL_MASS_RATIO 0.55 +#define GUNPOWDER_IGNITION_TEMP 180 +#define OPEN_BOLT_ADDITIONAL_CONVECTION 1.1 #ifdef DEBUG_MODE_FULL #define TRACE_PROJECTILE_INFO(BULLET) _vdir = vectorNormalized velocity BULLET; _dir = (_vdir select 0) atan2 (_vdir select 1); _up = asin (_vdir select 2); _mv = vectorMagnitude velocity BULLET; TRACE_3("adjusted projectile",_dir,_up,_mv); diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index e508793c8b..ef20ae9e81 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -4,27 +4,135 @@ Overheating Heißlaufen + Sobrecalentamiento Surriscaldamento 過熱 过热 過熱 Przegrzewanie Перегрев + Super Aquecimento + Túlmelegedés + Surchauffe + Přehřívání + 과열 + + + Overheating Enabled + Überhitzung aktiviert + Activado Sobrecalentamiento + Superaquecimento ativado + Surchauffe activée + Перегрев включен + Přehřívání povoleno + 過熱を有効化 + Przegrzewanie włączone + 과열 활성화 + Surriscaldamento Abilitato + 启用过热 + 啟用過熱 + + + Master enable for the overheating/jamming module + Activación maestra para Sobrecalentamiento + Chave mestra para o módulo de superaquecimento/emperramento + Active le module de surchauffe/d'enrayement. + Главный включатель для модуля перегрева/заклинивания + 過熱と弾詰まりモジュールを全て有効化します + Główny włącznik modułu przegrzewania/zacinania się broni + Hauptschalter, um die Überhitzung-/Ladehemmung-Module zu aktivieren + 과열/탄걸림 마스터 활성화 + Abilitazione master per il modulo di surriscaldamento / inceppamento + 启用枪管过热/干扰模块 + 啟用槍管過熱/干擾模塊 + Hlavní přepínač pro modul přehřívání/zasekávání + + + Heating Coefficient + 過熱係数 + Coefficient de surchauffe + Coefficiente di riscaldamento + Коэф. нагрева + Erhitzungs-Koeffizient + Współczynnik nagrzewania + 过热系数 + 과열 계수 + Coeficiente de calentamiento + + + Coefficient for the amount of heat a weapon generates per shot.\nHigher value increases heat. + 射撃毎に武器が生み出す熱量の係数を設定します。\n高い値であるほど熱量が増加します。 + Coefficient impactant la quantité de chaleur générée par l'arme à chaque tir. + Coefficiente che determina la quantità di calore generato da un'arma con ogni colpo sparato.\nValori alti accelerano il riscaldamento. + Коэффициент количества тепла, выделяемого оружием за выстрел. \nБольшие значения увеличивают нагрев. + Koeffizient für die Menge an Hitze, die eine Waffe pro Schuss erzeugt.\nHöhere Werte beschleunigen die Erhitzung. + Współczynnik wpływający na ilość ciepła generowanego przez broń przy każdym strzale. + 武器每次射击产生的热量系数。\n数值越高,热量越高。 + 매 발사마다 만들어지는 열에 계수를 적용합니다.\n높은 계수는 더 많은 열을 발생시킵니다. + Coeficiente para la cantidad de calor que genera un arma por disparo.\nValores más altos incrementan el calor + + + Cooling Coefficient + 冷却系数 + 냉각 계수 + Abkühlungskoeffizienten + Coefficiente di raffreddamento + Współczynnik chłodzenia + 冷却係数 + Коэф. остывания + Coeficiente de enfriado + Coefficient de refroidissement + + + Coefficient for how quickly a weapon cools down.\nHigher value increases cooling speed. + 武器冷却速度系数。\n数值越高,冷却速度越快。 + 무기가 차가워지는 정도를 정합니다.\n높은 계수는 무기가 빨리 차가워지는데 관여합니다. + Koeffizient, der angibt, wie schnell eine Waffe abkühlt.\nEin höherer Wert erhöht die Abkühlgeschwindigkeit. + Coefficiente che determina la velocità di raffreddamento di un'arma.\nValori alti aumentano la velocità di raffreddamento. + Współczynnik szybkości chłodzenia broni.\nWiększa wartość zwiększa szybkość chłodzenia. + 武器の冷却速度の係数。\n値を大きくすると冷却速度が速くなります。 + Коэффициент скорости остывания орудия.\nЧем больше значение, тем быстрее остывает. + Coeficiente para cómo de rápido se enfría un arma.\nValores más altos incrementan la velocidad de enfriamiento. + Coefficient de rapidité de refroidissement de l'arme.\nUne valeur élevée augmente la vitesse de refroidissement. + + + Suppressor Coefficient + 消音器系数 + 소음기 계수 + Schalldämpfer-Koeffizient + Coefficiente di Silenziatore + Współczynnik tłumika + サプレッサー係数 + Коэф. глушителя + Coeficiente del silenciador + Coefficient de suppresion + + + Coefficient for how much additional heat is added from having a suppressor attached.\nHigher value increases heat, 0 means no additional heat from the suppressor. + 附加了消音器后,产生的额外热量系数。\n数值越高,热量越高,0意味着消音器不产生额外热量。 + 소음기 장착 시 만들어 지는 열에 대한 계수를 적용합니다.\n높을 수록 온도가 높아집니다, 0으로 설정 시 추가적인 열을 얻지 않습니다. + Koeffizient, der angibt, wie viel zusätzliche Wärme durch das Anbringen eines Schalldämpfers hinzugefügt wird. Ein höherer Wert erhöht die Menge an Wärme, 0 bedeutet, dass keine zusätzliche Wärme durch den Schalldämpfer hinzukommt. + Coefficiente che determina quanto calore viene aggiunto dalla presenza di un silenziatore.\nValori alti aumentano il calore, 0 significa che un silenziatore non fa differenza. + Współczynnik określający, ile dodatkowego ciepła jest dodawane z założonego tłumika.\nWyższa wartość zwiększa ciepło, 0 oznacza brak dodatkowego ciepła z tłumika. + サプレッサーを取り付けることで追加される熱量の係数。\n値が大きいほど熱が増加し、0はサプレッサーからの追加の熱がないことを意味します。 + Коэффициент указывающий как много дополнительного тепла будет выделяться прикреплённым глушителем.\nБольшее значение увеличивает выделение тепла, 0 - отсутствие дополнительного тепла. + Coeficiente para cuanto calor adicional es añadido por tener un silenciador montado.\nValores más altos incrementan el calor. 0 significa que el silenciador no añade calor adicional. + Coefficient d'ajout de chaleur lorsqu'un suppresseur est installé.\nUne valeur élevée augmente la chaleur, 0 signifique qu'aucune chaleur ne sera ajouté par le suppresseur. - Display text on jam + Display Text on Jam Zeige Text bei Ladehemmung Mostrar texto al encasquillarse Показывать текст, когда клинит оружие Zobrazit upozornění při zaseknutí Wyświetl tekst przy zacięciu broni - Affiche texte si enrayé + Afficher du texte si enrayé Szöveges értesítés kijelzése a fegyver elakadásakor Mostrar texto quando trava acontecer Visualizza testo in caso di inceppamento - 弾詰りを文章で表示 + 弾詰まりを文章で表示 탄걸림의 경우 화면에 표시 - 在卡弹时显示提示讯息 + 在卡弹时显示提示信息 在卡彈時顯示提示訊息 @@ -34,13 +142,13 @@ Показывать уведомление каждый раз, когда клинит Ваше оружие. Zobrazí upozornění při zaseknutí zbraně Wyświetl powiadomienie za każdym razem, kiedy Twoja broń ulegnie zacięciu - Affiche une notification lors d'un enrayement + Affiche une notification lorsque votre arme est enrayée. Egy szöveges értesítés jelenik meg, amikor a fegyver megakad Mostra uma notificação quando sua arma sofre um travamento. - Visualizza una notifica in caso la tua arma si inceppasse - 持っている武器が弾詰りをすると、通知を表示します - 총알이 무기에 걸릴경우 화면에 알림을 띄웁니다 - 当武器卡弹时显示提示讯息 + Visualizza una notifica quando tua arma si inceppa + 持っている武器が弾詰まりをすると、通知を表示します + 총알이 무기에 걸릴 경우 화면에 알림을 띄웁니다 + 当武器卡弹时显示提示信息 當武器卡彈時顯示提示訊息 @@ -49,14 +157,15 @@ Efekty cząsteczkowe przegrzania Effetti Particelle Surriscaldamento Efectos de partículas - Effet de surchauffe + Effets de particules Částicové efekty přehřívání - Efeito de parícula de superaquecimento + Efeito de partícula de superaquecimento Эффект частиц при перегреве 過熱の視覚効果 과열 입자 효과 枪管过热特效 槍管過熱特效 + Részecskék túlmelegedése Show particle effects when weapon overheats @@ -64,29 +173,31 @@ Pokaż efekty cząsteczkowe kiedy broń się przegrzeje Mostra effetti particellari quando l'arma si surriscalda Muestra efectos de partículas cuando el arma del jugador se sobreacalienta - Montrer les effets lorsque l'arme surchauffe. - Mostra efeitos de párticula quando a arma superaquece + Affiche des effets de particules lorsqu'une arme surchauffe. + Mostra efeitos de partícula quando a arma superaquece Показывать эффект частиц, когда оружие перегревается Zobrazit částicové efekty když se zbraň přehřije 武器を過熱すると視覚表現を表示します 무기가 과열되면 입자 효과를 보여줍니다 显示枪管过热特效 顯示槍管過熱特效 + Fegyvertúlmelegedést okozó részecskehatások mutatása - Overheating Particle Effects for everyone + Overheating Particle Effects for Everyone Zeige Partikeleffekt bei Überhitzung für jeden Pokaż efekty cząsteczkowe dla wszystkich Effetti Particellari Surriscaldamento per tutti Efectos de partículas para todos - Effets de surchauffe pour tout le monde. + Effets de particules pour tout le monde Částicové efekty přehřívání pro všechny Efeito de partícula de superaquecimento para todos Эффект частиц при перегреве для всех - 過熱の視覚表現を全員に与えます + 過熱の視覚表現を全員に 모두에게 과열 입자 효과 적용 显示其他玩家的枪管过热特效 顯示其他玩家的槍管過熱特效 + A részecskék túlmelegedésének hatása mindenki számára Show particle effects when other players weapon overheats @@ -94,104 +205,231 @@ Pokazuje efekty cząsteczkowe kiedy broń innego gracza się przegrzeje Mostra effetti particellari quando l'arma di altri giocatori si surriscalda Muestra efectos de partículas cuando el arma de jugadores cercanos se sobreacalienta - Montrer les effets de surchauffe des autres joueurs. + Affiche les effets de particules lorsque les armes des autres joueurs surchauffent. Mostra efeito de partículas quando a arma de outros jogadores superaquece Показывать эффект частиц, когда оружие других игроков перегревается Zobrazit částicové efekty když se zbraň přehřije jinému hráči - 他のプレイヤの過熱の視覚表現を表示します - 모든 인원이 무기가 과열될시 입자 효과가 나타납니다. + 他のプレイヤーの過熱の視覚表現を表示します + 모든 인원이 무기가 과열될 시 입자 효과가 나타납니다. 当其他玩家的武器过热时显示特效 當其他玩家的武器過熱時顯示特效 + Mutassa a részecskehatásokat, amikor más játékosok fegyvere melegedik túl Overheating Dispersion Streuung bei Überhitzung Wpływ na rozrzut - Dispersione Surriscaldamento + Dispersione da Surriscaldamento Dispersión - Disperssion dûe à la surchauffe - Disperção de superaquecimento + Dispersion + Dispersão de superaquecimento Разброс при перегреве Důsledky přehřátí zbraně 過熱による精度の低下 과열 명중률 저하 过热散射 過熱散射 + Túlmelegedés diszperzió (szórás) Overheated weapons will be less accurate and have decreased muzzle velocity. Applys for all players. Überhitzte Waffen sind weniger genau und verfügen über eine geringere Mündungsgeschwindigkeit. Wird bei allen Spielern angewendet. Przegrzane bronie będą mniej celne oraz będą miały zmniejszoną prędkość pocisku. Wpływa na wszystkich graczy. - Armi surriscaldate saranno meno precise ed avranno una ridotta velocità alla volata. Applica per tutti i giocatori. + Armi surriscaldate saranno meno precise ed avranno una ridotta velocità alla volata. Applicato a tutti i giocatori. Las armas sobrecalentadas pierden precisión y tienen una velocidad de disparo reducida. Se aplica a todos los jugadores. - Les armes en surchauffe seront moins précises et auront une vitesse en sortie de bouche plus faible. S'applique pour tous les joueurs. + Les armes surchauffées seront moins précises et auront une vitesse initiale moins élevée. S'applique à tous les joueurs. Armas superaquecidas irão ser menos precisas e ter velocidade de disparo reduzidas. Aplica a todos os jogadores. Перегретое оружие будет менее точным, а дульная скорость будет снижена. Применяется ко всем игрокам. Přehřátá zbraň bude méně přesná a bude mít menší úsťovou rychlost. Platí pro všechny hráče. - 過熱は精度を減少させたり、初速を低下させます。これは全プレイヤに適用します。 - 무기 과열시 무기의 명중률이 저하되고 총구속도가 감소합니다. 이는 모든 플레이어에게 적용됩니다. + 過熱は精度を減少させたり、初速を低下させます。これは全プレイヤーに適用します。 + 무기 과열 시 무기의 명중률이 저하되고 총구속도가 감소합니다. 이는 모든 플레이어에게 적용됩니다. 过热的武器将会有打不准和减少射击初速的情况。适用于所有玩家 過熱的武器將會有打不準和減少射擊初速的情況。適用於所有玩家 + A túlmelegedett fegyverek kevésbé lesznek pontosak és csökkent a lövés sebessége. Minden játékosra vonatkozik. - - Unjam weapon on reload + + Distance for Effects and Dispersion + エフェクトと分散の距離 + Distance des effets et de la dispersion + Distanza per effetti e dispersione + Дистанция для эффектов и разброса + Abstand für Effekte und Dispersion + Odległość efektów i rozproszenia + 效果和扩散距离 + 효과와 분산 거리 + Distancia para Efectos y Dispersión + + + The distance, in meters, from the player within which overheating particle effects and dispersion are visible. + プレイヤーが過熱パーティクルのエフェクトと分散を見えるようになる距離 (m) を設定します。 + Définit la distance en mètres, jusqu'à laquelle les effets de particules et la dispersion sont visibles. + La distanza in metri da cui sono visibili gli effetti particellari e la dispersione. + Дистанция в метрах, с которой видны эффекты частиц и разброса при перегреве. + Der Abstand in Metern vom Spieler, in dem Überhitzungspartikeleffekte und Dispersion sichtbar sind. + Określa odległość w metrach, do której widoczne są efekty cząsteczkowe i rozproszenie. + 距离玩家的距离(米),在这个距离内可以看到过热的粒子效应和扩散。 + 미터 단위로, 과열 시 입자효과와 분산 정도가 플레이어로부터 얼마나 떨어진 곳까지 보여지는지를 결정합니다. + La distancia, en metros, desde la cual los efectos de sobrecalentamiento de particulas y dispersión son visibles. + + + Heat Increases Fire Rate + 熱による連射速度上昇 + La chaleur augmente la cadence de tir + Calore aumenta la cadenza di tiro + Нагрев увеличивает темп стрельбы + Hitze erhöht die Feuerrate + Ciepło zwiększa szybkostrzelność + 过热增加射速 + 과열 시 발사속도 증가 + Calentamiento incrementa la cadencia de tiro. + + + As weapons heat up, their rate of fire increases by up to 10%. + 武器が熱を帯び始めると、連射速度が 10% 上昇します。 + Lorsqu'une arme chauffe, sa cadence de tir peut augmenter jusqu'à 10%. + При нареве орудия, его темп стрельбы увеличивается до 10%. + Wenn sich Waffen erhitzen, erhöht sich ihre Feuerrate um bis zu 10%. + Quando le armi si surriscaldano, la loro cadenza di tiro può aumentare anche del 10%. + Gdy broń się nagrzewa, jej szybkostrzelność może wzrosnąć nawet o 10%. + 随着武器的过热,其射速最多增加10%。 + 과열될수록 발사속도가 최대 10%까지 올라갑니다. + Según se calienta el arma, su cadencia de tiro aumenta hasta un 10%. + + + Jam Chance Coefficient + 弾詰まり係数 + Coefficient du risque d'enrayement + Coefficiente di inceppamento + Шанс заклинивания оружия + Koeffizient für Ladehemmung + Szansa na zacięcie + 卡弹概率系数 + 기능고장 확률 계수 + Coeficiente de posibilidad de encasquillamiento + + + Coefficient for the chance that a weapon will jam from overheating.\nHigher value make jams more likely.\nSet to 0 to disable jamming. + 武器が過熱によって弾詰まりする確率係数を設定します。\n高い値では弾詰まりが起こりやすくなり、0 で弾詰まりが無効化されます。 + Coefficient modifiant les chances qu'une arme s'enraye à cause de la surchauffe.\nPlus la valeur est élevée, plus grand est le risque que l'arme s'enraye.\nDéfinir à 0 pour désactiver l'enrayement des armes. + Coefficiente della probabilità di inceppamento da surriscaldamento.\nValori alti aumentano la probabilità, 0 la disabilità. + Шанс заклинивания оружия от перегрева.\nБольшие значения повышают шанс заклинивания.\nУстановите 0 для отключения заклинивания. + Koeffizient für die Wahrscheinlichkeit, dass eine Waffe eine Ladehemmung hat.\Höhere Werte erhöhen die Wahrscheinlichkeit.\Auf 0 setzen, um Ladehemmungen zu deaktivieren. + Współczynnik zmieniający szansę na zacięcie się broni z powodu przegrzania.\nIm wyższa wartość, tym większe ryzyko zacięcia się broni.\nUstaw na 0, aby wyłączyć zacinanie się broni. + 武器因过热而卡弹的概率系数。\n数值越高,卡住的可能性越大。\n设置为0以禁用卡弹。 + 과열로 인해 얼마나 고장나는지에 대한 계수를 정합니다.\n높을 수록 더 고장이 잘납니다.\n0으로 설정하면 고장이 일어나지 않습니다. + Coeficiente de posibilidad de que un arma se encasquille debido al sobrecalentamiento.\nValores más altos hacen más posible que se encasquille.\n Establecer a 0 para deshabilitar el encasquillamiento. + + + Unjam Weapon on Reload Behebt Ladehemmung beim Nachladen Desencasquillar el arma al recargar. Usuń zacięcie przy przeładowaniu - Des-enrayer l'arme au rechargement. + Désenrayer l'arme au rechargement Disinceppa l'arma quando si ricarica Uvolnit zbraň při přebití Desemperrar arma no recarregamento Исправлять клин при перезарядке - 再装填による弾詰りの解消 - 재장전시 탄걸림 해결 + 再装填による弾詰まり解消 + 재장전 시 기능고장 해결 重装弹匣以解决卡弹 重裝彈匣以解決卡彈 + Távolítsa el az akadályt újratöltéskor - + Reloading clears a weapon jam. Nachladen behebt eine Ladehemmung. Recargar el arma la desencasquilla. Przeładowywanie usuwa zacięcie - Recharger vide la chambre de l'arme + Les armes se désenrayent lors d'un rechargement. L'arma si disinceppa quando si ricarica Přebití uvolní zaseknutou zbraň. Recarregar desemperra arma. Перезарядка устраняет заклинивание оружия. - 再装填により、弾詰りを除去します。 - 탄걸림이 재장전시 해결됩니다. + 再装填により、弾詰まりを除去します。 + 기능고장이 재장전 시 해결됩니다. 利用重装弹匣来解决卡弹 利用重裝彈匣來解決卡彈 + Az újratöltés megszünteti a fegyver elakadását. + + + Unjam on Barrel Swap + 銃身交換による弾詰まり解消 + Désenrayer l'arme au changement de canon + Замена ствола устраняет клин оружия + Disinceppa l'arma col cambio canna + Usuń zacięcie przy wymianie lufy + 更换枪管清除卡弹 + 총열 교환 시 기능고장 해결 + Ladehemmung beim Wechseln des Laufes beheben. + Desencasquillar con el cambio de cañón + + + Controls whether swapping barrels clears a weapon jam. + 銃身を交換して弾詰まりの解消をできるようにします。 + Les armes se désenrayent lors d'un remplacement de canon. + Определяет, устраняет ли замена ствола заклинивание оружия. + Bestimmt, ob das Wechseln des Laufes eine Ladehemmung behebt. + Determina se la sostituzione della canna disinceppa l'arma. + Określa, czy wymiana lufy usuwa zacięcie się broni. + 通过更换枪管,以便清除卡弹。 + 총열을 교체하면서 기능고장을 해결합니다. + Controla si cambiar el cañón del arma la desencasquilla. - Chance of unjam failing + Chance of Unjam Failing Wahrscheinlichkeit, dass Ladehemmung nicht behoben wird Probabilidad de falla al desencasquillar. Szansa na porażkę usuw. zacięcia - Chance de rater le des-enrayement + Risque d'échec du désenrayement Probabilità di sbagliare a disinceppare l'arma Šance, že uvolnění zbraně selže Chance de falha de desemperramento Шанс неудачи при устранении клина - 弾詰りの除去を失敗する可能性 - 탄걸림 해결 시도 실패확률 + 弾詰まりの除去を失敗する可能性 + 기능고장 해결 시도 실패확률 解决卡弹失败机率 解決卡彈失敗機率 + Akadály eltávolítás hibájának esélye Probability that an unjam action might fail, requiring to be repeated. Wahrscheinlichkeit, dass der Versuch eine Ladehemmung zu beheben fehl schlägt und erneut durchgeführt werden muss. Probabilidad de que el proceso de desencasquille falle, teniendo que repetirlo. Szansa na to, że przy przeładowaniu broni zacięcie nie zostanie usunięte, przez co czynność będzie musiała zostać powtórzona ponownie. - Probabilité qu'une action de des-enrayement échoue, nécessitant de recommencer. - Probabilità che si possa sbagliare a caso a disinceppare l'arma. Richiede di ripetere. + Probabilité qu'une action de désenrayement échoue, nécessitant de recommencer. + Probabilità casuale che si possa sbagliare a disinceppare l'arma. Richiedendo di ripetere il disinceppamento. Probabilidade que uma ação de desemperramento falhe, tendo que ser repetida Вертоятность того, что устранение заклинивания не сработает, и его придется повторить. Pravděpodobnost, že uvolnění zbraně selže, je proto nutné tuto akci opakovat. - 弾詰りの除去を失敗する可能性が生まれ、もう一度動作を行う必要があります。 - 탄걸림 해결 시도시 실패할 확률이 있습니다. 이는 다시 탄걸림 해결을 시도해야함을 의미합니다. + 弾詰まり解除アクションに失敗し、繰り返しが必要になる確率。 + 기능고장 해결 시도시 실패할 확률이 있습니다. 이는 다시 기능고장 해결을 시도해야함을 의미합니다. 清除卡弹时有可能会失败,需要反覆进行清枪。 清除卡彈時有可能會失敗,需要反覆進行清槍。 + Valószínűsége annak, hogy egy akadály eltávolítás művelet kudarcot vall, megismétlést igényel. + + + Overheating Cookoff Coefficient + 過熱暴発係数 + Coefficient de l'auto-inflammation + Coefficiente di auto-combustione + Коэф. возгорания при перегреве + Selbstzündungskoeffizient bei Überhitzung + Współczynnik samozapłonu + 过热诱发系数 + 과열 쿡오프 계수 + Coeficiente para detonación inducida por calor debido a sobrecalentamiento + + + Coefficient for the heat required for cookoffs to occur.\nHigher values require more heat to cookoff.\nSet to 0 to disable cookoff. + 過熱によって暴発(コックオフ)が発生する確率の係数を設定します。\n高い値では暴発までに必要な過熱量が増加し、0 で暴発が無効化されます。 + Coefficient modifiant la quantité de chaleur requise pour que les munitions s'auto-inflamment dans la chambre de l'arme.\nPlus la valeur est élevée, plus l'arme doit être chaude pour que les munitions s'auto-inflamment.\nDéfinir sur 0 pour désactiver l'auto-inflammation. + Coefficiente che determina il calore richiesto per auto-incendiare munizioni/carburante.\nImpostare su 0 per disabilitare l'auto-combustione. + Коэффициент нагрева, при котором возникает возгорание. + Koeffizient für die zum Selbstzünden erforderliche Hitze.\nHöhere Werte erfordern mehr Hitze zum Selbstzünden.\nAuf 0 setzen, um das Selbstzünden zu deaktivieren. + Współczynnik modyfikujący ilość ciepła wymaganego do samozapłonu amunicji w komorze broni.\nIm wyższa wartość, tym gorętsza musi być broń, aby amunicja uległa samozapłonowi\nUstaw 0, aby wyłączyć samozapłon. + 发生热诱发的过热系数。\n数值越高,热诱发所需要的过热值越高。\n设置为0禁用热诱发。 + 쿡오프가 되기 위해 얼마나 과열되는가를 결정합니다. \n높을 수록 쿡오프 되기위해 더 뜨거운 열을 필요로 합니다.\n 0으로 설정하면 쿡오프 현상이 없어집니다. + Coeficiente para el calor requerido para que suceda la detonación inducida por calor.\nValores más altos requieren más calor para que se produzca.\nEstablecer a 0 para deshabilitar la detonación inducida por calor. Spare barrel @@ -218,10 +456,10 @@ Utilisé pour changer de canon. Используется для смены ствола. Használd a cső kicseréléséhez. - Use para trocar o cano/estriamento. - Usata per cambiare la canna. - 予身の交換に使用します。 - 총열을 바꿀때 사용합니다. + Use para trocar o cano. + Usata per sostituire una canna bollente. + 銃身の交換に使用します。 + 총열을 바꿀 때 사용합니다. 用来更换枪管 用來更換槍管 @@ -231,16 +469,76 @@ Arma encasquillada! Zacięcie! Zbraň se zasekla! - Arme enrayée + Arme enrayée ! Оружие заклинило! Megakadt a fegyver! Arma travada! Arma inceppata! 武器が詰まった! - 탄걸림! - 武器卡弹! + 기능고장! + 武器卡弹! 武器卡彈! + + Weapon cooked off! + 武器が暴発した! + Auto-inflammation des munitions ! + Оружие сдетонировало! + Munition durchgezündet! + Munizione auto-incendiata! + Samozapłon amunicji! + 武器发生热诱发! + 쿡오프가 일어납니다! + Arma disparada por sobrecalentamiento! + + + Failure to eject. + 排莢に失敗しました。 + Défaut d'éjection. + Не удалось достать. + Mancata espulsione. + Hülse wurde nicht ausgeworfen. + Nie udało się wyrzucić łuski. + 抛壳失败。 + 탄피가 약실에 낌. + Fallo en la expulsión. + + + Failure to extract. + 排出に失敗しました。 + Défaut d'extraction. + Mancata estrazione. + Не удалось извлечь. + Hülse wurde nicht ausgezogen. + Nie udało się wyjąć łuski. + 抽壳失败。 + 탄피가 배출되지 않음. + Fallo en la extracción. + + + Failure to feed. + 給弾に失敗しました。 + Défaut d'alimentation. + Mancata alimentazione. + Не удалось подать. + Patrone wurde nicht zugeführt. + Nie udało się załadować naboju. + 供弹失败。 + 탄이 장전 중 걸림. + Fallo en la alimentación. + + + Failure to fire. + 撃発に失敗しました。 + Défaut de tir. + Не удалось выстрелить. + Patrone wurde nicht gezündet! + Mancato innesco. + Nie udało się strzelić. + 未能开火。 + 발사가 되지 않음. + Fallo al disparar. + Clear jam Ladehemmung beheben @@ -251,9 +549,9 @@ Исправить клин оружия Akadás elhárítása Destravar arma - Ripulisci l'arma - 弾詰りを除去する - 탄걸림 해결 + Disinceppa l'arma + 弾詰まりを解消する + 기능고장 해결 清除卡弹 清除卡彈 @@ -263,13 +561,13 @@ Arma desencasquillada Zacięcie usunięte Zbraň uvolněna - Arme désenrayée + Arme désenrayée. Оружие исправлено Akadás elhárítva Arma destravada Arma pronta al fuoco - 弾詰りが除去されました - 탄걸림 해결됨 + 弾詰まりが解消した + 기능고장 해결됨 卡弹已清除 卡彈已清除 @@ -280,11 +578,11 @@ Porażka przy usuwaniu zacięcia Toujours enrayé ! Non si è disinceppata! - Zbrań se nepodařilo uvolnit + Zbraň se nepodařilo uvolnit Falha no desemperramento Не удалось исправить клин - 弾詰りの除去に失敗しました - 탄걸림 해결 실패 + 弾詰まりの解消に失敗した + 기능고장 해결 실패 卡弹未能清除 卡彈未能清除 @@ -294,7 +592,7 @@ Cambiar el cañón Wymień lufę Vyměnit hlaveň - Changer de canon + Remplacer le canon Сменить ствол Cső cserélése Substituir cano @@ -310,14 +608,14 @@ Cambiando el cañón... Wymienianie lufy... Měním hlaveň... - Changement du canon... + Remplacement du canon... Смена ствола... Cső kicserélése folyamatban... Substituindo cano... Sostituendo la canna... 銃身を交換しています・・・ - 총열 교체중... - 换枪管中... + 총열 교체 중... + 正在更换枪管... 換槍管中... @@ -326,7 +624,7 @@ Cañón cambiado Lufa wymieniona Hlaveň vyměněna - Canon changé + Canon remplacé. Ствол заменён Cső kicserélve Cano substituído @@ -347,7 +645,7 @@ Conferir temperatura da arma Controlla la temperatura della canna Проверить температуру оружия - 武器の温度を測る + 武器の温度を確認 무기 온도 확인 检查枪管温度 檢查槍管溫度 @@ -363,7 +661,7 @@ Проверить температуру оружия Conferir temperatura Controlla la temperatura della canna - 武器の温度を測る + 武器の温度を確認 무기 온도 확인 检查枪管温度 檢查槍管溫度 @@ -380,17 +678,18 @@ Controllando la temperatura... Проверка температуры... 温度を測っています・・・ - 무기 온도 확인중... - 检查枪管温度中... + 무기 온도 확인 중... + 正在检查枪管温度... 檢查槍管溫度中... Check spare barrels temperatures + Comprobar temperatura de los cañones de repuesto Verifica temperatura de canos reservas Vérifier la température des canons de rechange Проверить температуру запасных стволов Zkontrolovat teplotu náhradní hlavně - 予備銃身の温度を測る + 予備銃身の温度を確認 Sprawdź temperaturę zapasowych luf Temperatur der Wechselläufe prüfen 총열 온도 확인 @@ -400,6 +699,7 @@ Checking spare barrels temperatures... + Comprobando temperatura de los cañones de repuesto Verificando temperatura de canos reservas Vérification de la température des canons de rechange... Проверка температуры запасных стволов... @@ -407,11 +707,83 @@ 予備銃身の温度を測っています・・・ Sprawdzanie temperatury zapasowych luf... Prüfe Temperatur der Wechselläufe ... - 총열 온도 확인중... + 총열 온도 확인 중... Controllando la temperatura della canna di ricambio... - 检查枪管温度中... + 正在检查枪管温度... 檢查槍管溫度中... + + Cool weapon with... + 武器を・・・で冷却 + Refroidir l'arme avec... + Охладить оружие с... + Waffe mit... kühlen + Raffredda arma con... + Schłódź broń za pomocą... + 冷却武器... + 무기 온도 낮추기 + Enfriar arma con... + + + Cooling %1 with %2. + %1 を %2 で冷ましています。 + Refroidissement du %1 avec %2... + Охлаждение %1 с %2. + Kühle %1 mit %2. + Raffredda %1 con %2 + Chłodzenie %1 za pomocą %2. + 冷却 %1 至 %2。 + %1을 %2로 식히는 중. + Enfriando %1 con %2. + + + Cool weapon in water source. + 水源で武器を冷却 + Refroidir l'arme dans la source d'eau. + Охладить оружие в воде. + Kühle Waffe aus Wasserquelle. + Raffredda arma in acqua. + Schłódź broń wodą. + 用水源冷却武器。 + 물로 무기 식히기 + Enfriar arma con agua. + + + Cooling weapon in water source. + 水源で武器を冷ましています・・・ + Refroidissement de l'arme dans la source d'eau... + Охлаждение оружия в воде. + Waffe wird aus Wasserquelle gekühlt. + Raffreddando arma con l'acqua. + Chłodzenie broni wodą. + 在水源中冷却武器。 + 물로 무기 식히는 중. + Enfriando arma con agua... + + + Container doesn't have enough water. + 水源には十分な水量がありません。 + Le récipient ne contient pas suffisamment d'eau. + Воды недостаточно для охлаждения. + Behälter beinhaltet nicht genug Wasser. + Contenitore non ha abbastanza acqua. + Zbiornik nie ma wystarczającej ilości wody + 容器里的水不够。 + 물이 충분치 않습니다. + El contenedor no tiene suficiente agua. + + + Weapon is cool enough the water has stopped boiling. + 武器が冷え切り、水は沸騰を止めた。 + L'arme est suffisamment froide pour que l'eau ait cessé de bouillir. + Оружие достаточно холодное для прекращения кипения воды. + Waffe ist kalt genug, dass Wasser hat aufgehört zu kochen. + L'arma è abbastanza fredda, l'acqua ha smesso di bollire. + Broń jest wystarczająco schłodzona. Woda przestała się gotować. + 武器已经冷却,水已经停止沸腾了。 + 물이 끓지 않는 걸 보아 무기가 식은듯 하다. + El arma está lo suficientemente fría para no hacer hervir el agua. + Temperature Temperatur @@ -430,10 +802,11 @@ Cool Spare Barrel/s + Cañon/es de repuesto frio/s Cano/s reserva/s frio/s - Canon(s) de rechange froid + Canon(s) de rechange froid(s). Прохладные - Studená náhrandí hlaveň + Studená náhradní hlaveň 予備銃身は冷たい Zimne zapasowe lufy Kalte Wechselläufe @@ -444,10 +817,11 @@ Warm Spare Barrel/s + Cañon/es de repuesto templado/s Cano/s reserva/s morno/s - Canon(s) de rechange tiède + Canon(s) de rechange tiède(s). Теплые - Teplá náhrandí hlaveň + Teplá náhradní hlaveň 予備銃身は温かい Ciepłe zapasowe lufy Warme Wechselläufe @@ -458,10 +832,11 @@ Hot Spare Barrel/s + Cañon/es de repuesto caliente/s Cano/s reserva/s quente/s - Canon(s) de rechange chaud + Canon(s) de rechange chaud(s). Горячие - Horká náhrandí hlaveň + Horká náhradní hlaveň 予備銃身は熱い Gorące zapasowe lufy Heiße Wechselläufe @@ -472,59 +847,93 @@ Very Hot Spare Barrel/s + Cañon/es de repuesto muy caliente/s Cano/s reserva/s muito quente/s - Canon(s) de rechange très chaud + Canon(s) de rechange très chaud(s). Очень горячие - Velmi horká náhrandí hlaveň + Velmi horká náhradní hlaveň 予備銃身はとても熱い Bardzo gorące zapasowe lufy Sehr heiße Wechselläufe 매우 뜨거운 예비 총열 - Canna/e di Ricambio Estremamente Calda + Canna/e di Ricambio Bollente 备用枪管温度过热 備用槍管溫度過熱 Extremely Hot Spare Barrel/s + Cañon/es de repuesto extremadamente caliente/s Cano/s reserva/s extremamente quente/s - Canon(s) de rechange extrêmement chaud + Canon(s) de rechange extrêmement chaud(s). Запредельно горячие - Extrémně horká náhrandí hlaveň + Extrémně horká náhradní hlaveň 予備銃身は極めて熱い Ekstremalnie gorące zapasowe lufy Extrem heiße Wechselläufe 엄청나게 뜨거운 예비 총열 Canna/e di Ricambio Rovente - 备用枪管温度超级热 + 备用枪管温度非常热 備用槍管溫度超級熱 - - Overheating Enabled - Überhitzung aktiviert - Activada Sobrecalentamiento - Superaquecimento ativado - Surchauffe activée - Перегрев включен - Přehřívání povoleno - 過熱を有効化 - Przegrzewanie włączone - 과열 활성화 - Surriscaldamento Abilitato - 启用过热 - 啟用過熱 + + Bolt Type + Tipo di otturatore + 遊底(ボルト)形式 + 노리쇠 방식 + Тип болта + Type d'obturateur + Art des Verschlusses + Tipo de Cerrojo - - Master enable for the overheating/jamming module - Chave mestra para o módulo de superaquecimento/emperramento - Activateur maître pour le module de surchauffe / enrayement - Главный включатель для модуля перегрева/заклинивания - 過熱と弾詰まりモジュールを全て有効化します - Główny włącznik modułu przegrzewania/zacinania się broni - Hauptschalter, um die Überhitzung-/Ladehemmung-Module zu aktivieren - 과열/탄걸림 최종 활성화 - Abilitazione master per il modulo di surriscaldamento / inceppamento - 启用枪管过热/干扰模块 - 啟用槍管過熱/干擾模塊 + + Open Bolt + Otturatore Aperto + オープンボルト + 오픈 볼트 + Открыть болт + Obturateur ouvert + Offener Verschluss + Cerrojo Abierto + + + Closed Bolt + Otturatore Chiuso + クローズドボルト + 클로즈드 볼트 + Закрыть болт + Obturateur fermé + Geschlossener Verschluss + Cerrojo Cerrado + + + Barrel Type + Tipo di Canna + 銃身形式 + 총열 방식 + Тип ствола + Type de canon + Lauftyp + Tipo de Cañón + + + Non-Removeable + Non-Rimovibile + 取り外し不可 + 제거 불가 + Несъемный + Inamovible + Nicht entfernbar + No-Desmontable + + + Quick Change + Cambio Rapido + 即時交換可 + 신속 교체 + Быстросъемный + Changement rapide + Schnellwechsel + Cambiado Rápido diff --git a/addons/overpressure/ACE_Arsenal_Stats.hpp b/addons/overpressure/ACE_Arsenal_Stats.hpp index 906c50e8fb..d0de391691 100644 --- a/addons/overpressure/ACE_Arsenal_Stats.hpp +++ b/addons/overpressure/ACE_Arsenal_Stats.hpp @@ -6,7 +6,7 @@ class EGVAR(arsenal,stats) { stats[] = {QGVAR(angle)}; displayName = CSTRING(statBackblastAngle); showText = 1; - textStatement = QUOTE(params [ARR_2('_stat', '_config')]; format [ARR_2('%1°', getNumber (_config >> _stat select 0))]); + textStatement = QUOTE(params [ARR_2('_stat','_config')]; format [ARR_2('%1°',getNumber (_config >> _stat select 0))]); tabs[] = {{2}, {}}; }; class ACE_backblastRange: statBase { @@ -15,7 +15,7 @@ class EGVAR(arsenal,stats) { stats[] = {QGVAR(range)}; displayName = CSTRING(statBackblastRange); showText = 1; - textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _blastRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)', _blastRangeStat, (_blastRangeStat / 0.3048) toFixed 1)]); + textStatement = QUOTE(params [ARR_2('_stat','_config')]; private _blastRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)',_blastRangeStat,(_blastRangeStat / 0.3048) toFixed 1)]); tabs[] = {{2}, {}}; }; }; diff --git a/addons/overpressure/ACE_Settings.hpp b/addons/overpressure/ACE_Settings.hpp deleted file mode 100644 index 58e0d3d8ac..0000000000 --- a/addons/overpressure/ACE_Settings.hpp +++ /dev/null @@ -1,9 +0,0 @@ -class ACE_Settings { - class GVAR(distanceCoefficient) { - displayName = CSTRING(distanceCoefficient_displayName); - description = CSTRING(distanceCoefficient_toolTip); - typeName = "SCALAR"; - value = 1; - sliderSettings[] = {-1, 10, 5, 1}; - }; -}; diff --git a/addons/overpressure/CfgEventHandlers.hpp b/addons/overpressure/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/overpressure/CfgEventHandlers.hpp +++ b/addons/overpressure/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/overpressure/CfgWeapons.hpp b/addons/overpressure/CfgWeapons.hpp index 1f0814a487..7102e84d1b 100644 --- a/addons/overpressure/CfgWeapons.hpp +++ b/addons/overpressure/CfgWeapons.hpp @@ -7,6 +7,7 @@ class CfgWeapons { GVAR(angle) = 60; GVAR(range) = 10; GVAR(damage) = 0.7; + GVAR(offset) = 1; }; class Launcher_Base_F: Launcher {}; @@ -16,6 +17,7 @@ class CfgWeapons { GVAR(angle) = 40; GVAR(range) = 8; GVAR(damage) = 0.5; + GVAR(offset) = 1; }; class launch_Titan_short_base: launch_Titan_base { @@ -24,6 +26,7 @@ class CfgWeapons { GVAR(angle) = 30; GVAR(range) = 2; GVAR(damage) = 0.5; + GVAR(offset) = 0.85; }; class launch_NLAW_F: Launcher_Base_F { @@ -32,6 +35,7 @@ class CfgWeapons { GVAR(angle) = 30; GVAR(range) = 2; GVAR(damage) = 0.6; + GVAR(offset) = 1.05; }; class launch_RPG32_F: Launcher_Base_F { @@ -39,6 +43,22 @@ class CfgWeapons { GVAR(angle) = 60; GVAR(range) = 15; GVAR(damage) = 0.7; + GVAR(offset) = 1.2; + }; + + class launch_MRAWS_base_F: Launcher_Base_F { + GVAR(range) = 15; + GVAR(offset) = 1.05; + }; + + class launch_Vorona_base_F: Launcher_Base_F { + GVAR(angle) = 50; + GVAR(offset) = 0.88; + }; + + class launch_RPG7_F: Launcher_Base_F { + GVAR(angle) = 40; + GVAR(offset) = 0.9; }; class CannonCore; diff --git a/addons/overpressure/README.md b/addons/overpressure/README.md index fce4db7d3f..d79899a8d0 100644 --- a/addons/overpressure/README.md +++ b/addons/overpressure/README.md @@ -2,11 +2,3 @@ ace_overpressure ============= Adds backblast area to AT launchers and overpressure zones to tank cannons. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [KoffeinFlummi](https://github.com/KoffeinFlummi) diff --git a/addons/overpressure/XEH_PREP.hpp b/addons/overpressure/XEH_PREP.hpp index 1efd39d6e5..9d1e8e9725 100644 --- a/addons/overpressure/XEH_PREP.hpp +++ b/addons/overpressure/XEH_PREP.hpp @@ -1,6 +1,5 @@ - PREP(getDistance); PREP(overpressureDamage); -PREP(cacheOverPressureValues); +PREP(getOverPressureValues); PREP(firedEHOP); PREP(firedEHBB); diff --git a/addons/overpressure/XEH_postInit.sqf b/addons/overpressure/XEH_postInit.sqf index 02b0e71bb6..4b014e89e2 100644 --- a/addons/overpressure/XEH_postInit.sqf +++ b/addons/overpressure/XEH_postInit.sqf @@ -1,12 +1,17 @@ #include "script_component.hpp" -["ace_settingsInitialized", { - TRACE_1("settingsInit eh",GVAR(distanceCoefficient)); - if (GVAR(distanceCoefficient) <= 0) exitWith {}; +["CBA_settingsInitialized", { + TRACE_2("settingsInit eh",GVAR(backblastDistanceCoefficient),GVAR(overpressureDistanceCoefficient)); ["ace_overpressure", LINKFUNC(overpressureDamage)] call CBA_fnc_addEventHandler; - // Register fire event handler - ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + // Register fire event handlers + if (GVAR(backblastDistanceCoefficient) > 0) then { + ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; + }; + if (GVAR(overpressureDistanceCoefficient) > 0) then { + ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + }; + + GVAR(cacheHash) = createHashMap; }] call CBA_fnc_addEventHandler; diff --git a/addons/overpressure/XEH_preInit.sqf b/addons/overpressure/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/overpressure/XEH_preInit.sqf +++ b/addons/overpressure/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/overpressure/config.cpp b/addons/overpressure/config.cpp index 3815cc831f..7274cd5059 100644 --- a/addons/overpressure/config.cpp +++ b/addons/overpressure/config.cpp @@ -14,7 +14,6 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "ACE_Arsenal_Stats.hpp" diff --git a/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf b/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf deleted file mode 100644 index 7e984f993c..0000000000 --- a/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf +++ /dev/null @@ -1,57 +0,0 @@ -#include "script_component.hpp" -/* - * Author: joko // Jonas - * Cache the shot data for a given weapon/mag/ammo combination. - * Will use the config that has the highest priority. - * - * Arguments: - * 0: Weapon - * 1: Magazine - * 2: Ammo - * - * Return Value: - * Shot Config : - * 0: Angle - * 1: Range - * 2: Damage - * - * Example: - * ["cannon_125mm","Sh_125mm_APFSDS_T_Green","24Rnd_125mm_APFSDS_T_Green"] call ace_overpressure_fnc_cacheOverPressureValues - * - * Public: No - */ - -params ["_weapon", "_ammo", "_magazine"]; -TRACE_3("Parameter",_weapon,_magazine,_ammo); - -// get Priority Array from Config -private _array = [ - getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(priority)), - getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(priority)), - getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(priority)) -]; - -(_array call CBA_fnc_findMax) params ["", ["_indexOfMaxPriority", 0, [0]]]; - -TRACE_2("Priority Array",_array,_indexOfMaxPriority); - -// create the Config entry Point -private _config = [ - (configFile >> "CfgWeapons" >> _weapon), - (configFile >> "CfgMagazines" >> _magazine), - (configFile >> "CfgAmmo" >> _ammo) -] select _indexOfMaxPriority; -TRACE_1("ConfigPath",_config); - -// get the Variables out of the Configes and create a array with then -private _return = [ - (getNumber (_config >> QGVAR(angle))), - (getNumber (_config >> QGVAR(range))) * GVAR(distanceCoefficient), - (getNumber (_config >> QGVAR(damage))) -]; - -private _varName = format [QGVAR(values%1%2%3), _weapon, _ammo, _magazine]; -missionNameSpace setVariable [_varName, _return]; -TRACE_2("Return",_varName,_return); - -_return diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index fc5070e8a8..05a761bf06 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: joko // Jonas * Handle fire of local launchers. Called from the unified fired EH only for the local player. @@ -16,22 +16,20 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -// Bake variable name and check if the variable exists, call the caching function otherwise -private _varName = format [QGVAR(values%1%2%3), _weapon, _ammo, _magazine]; -private _var = if (isNil _varName) then { - [_weapon, _ammo, _magazine] call FUNC(cacheOverPressureValues); -} else { - missionNameSpace getVariable _varName; -}; -_var params ["_backblastAngle","_backblastRange","_backblastDamage"]; -TRACE_3("cache",_backblastAngle,_backblastRange,_backblastDamage); +// Retrieve backblast values +private _bbValues = [_weapon, _ammo, _magazine] call FUNC(getOverPressureValues); + +_bbValues params ["_backblastAngle", "_backblastRange", "_backblastDamage", "_offset"]; +_backblastRange = _backblastRange * GVAR(backblastDistanceCoefficient); + +TRACE_4("cache",_backblastAngle,_backblastRange,_backblastDamage,_offset); if (_backblastDamage <= 0) exitWith {}; -private _position = getPosASL _projectile; private _direction = [0, 0, 0] vectorDiff (vectorDir _projectile); +private _position = ((getPosASL _projectile) vectorAdd (_direction vectorMultiply _offset)); // Damage to others private _affected = (ASLtoAGL _position) nearEntities ["CAManBase", _backblastRange]; @@ -45,18 +43,23 @@ private _distance = 2 * ([_position, _direction, _backblastRange, _unit] call FU TRACE_1("Distance",_distance); if (_distance < _backblastRange) then { - private _alpha = sqrt (1 - _distance / _backblastRange); - private _beta = sqrt 0.5; + TRACE_2("",isDamageAllowed _unit,_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]); - private _damage = _alpha * _beta * _backblastDamage; - [_damage * 100] call BIS_fnc_bloodEffect; + // Skip damage if not allowed + if (isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { + private _alpha = sqrt (1 - _distance / _backblastRange); + private _beta = sqrt 0.5; - if (isClass (configFile >> "CfgPatches" >> "ACE_Medical")) then { - [_unit, _damage, "body", "backblast"] call EFUNC(medical,addDamageToUnit); - } else { - TRACE_1("",isDamageAllowed _unit); - if (!isDamageAllowed _unit) exitWith {}; // Skip damage if not allowed - _unit setDamage (damage _unit + _damage); + private _damage = _alpha * _beta * _backblastDamage; + TRACE_1("",_damage); + + [_damage * 100] call BIS_fnc_bloodEffect; + + if (GETEGVAR(medical,enabled,false)) then { + [_unit, _damage, "body", "backblast", _unit] call EFUNC(medical,addDamageToUnit); + } else { + _unit setDamage (damage _unit + _damage); + }; }; }; diff --git a/addons/overpressure/functions/fnc_firedEHOP.sqf b/addons/overpressure/functions/fnc_firedEHOP.sqf index 5871fae9b8..e011098b59 100644 --- a/addons/overpressure/functions/fnc_firedEHOP.sqf +++ b/addons/overpressure/functions/fnc_firedEHOP.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: joko // Jonas * Handle fire of Vehicle Weapons. Called from the unified fired EH only for the local player vehicle. @@ -16,22 +16,18 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); + +// Retrieve overpressure values +private _opValues = [_weapon, _ammo, _magazine] call FUNC(getOverPressureValues); + +_opValues params ["_dangerZoneAngle", "_dangerZoneRange", "_dangerZoneDamage"]; +_dangerZoneRange = _dangerZoneRange * GVAR(overpressureDistanceCoefficient); -// Bake variable name and check if the variable exists, call the caching function otherwise -private _varName = format [QGVAR(values%1%2%3), _weapon, _ammo, _magazine]; -private _var = if (isNil _varName) then { - [_weapon, _ammo, _magazine] call FUNC(cacheOverPressureValues); -} else { - missionNameSpace getVariable _varName; -}; -_var params ["_dangerZoneAngle","_dangerZoneRange","_dangerZoneDamage"]; TRACE_3("cache",_dangerZoneAngle,_dangerZoneRange,_dangerZoneDamage); if (_dangerZoneDamage <= 0) exitWith {}; - - // The weapon produces overpressure, calculate private _position = getPosASL _projectile; private _direction = vectorDir _projectile; diff --git a/addons/overpressure/functions/fnc_getDistance.sqf b/addons/overpressure/functions/fnc_getDistance.sqf index 3e36a3ea78..64ee563974 100644 --- a/addons/overpressure/functions/fnc_getDistance.sqf +++ b/addons/overpressure/functions/fnc_getDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 and esteldunedain * Calculate the distance to the first intersection of a line @@ -19,7 +19,7 @@ */ params ["_posASL", "_direction", "_maxDistance", "_shooter"]; -TRACE_4("params",_posASL,_direction,_maxDistance, _shooter); +TRACE_4("params",_posASL,_direction,_maxDistance,_shooter); private _intersections = lineIntersectsSurfaces [_posASL, _posASL vectorAdd (_direction vectorMultiply _maxDistance), _shooter, objNull, true, 99]; diff --git a/addons/overpressure/functions/fnc_getOverPressureValues.sqf b/addons/overpressure/functions/fnc_getOverPressureValues.sqf new file mode 100644 index 0000000000..374e9de9d6 --- /dev/null +++ b/addons/overpressure/functions/fnc_getOverPressureValues.sqf @@ -0,0 +1,65 @@ +#include "..\script_component.hpp" +/* + * Author: joko // Jonas + * Cache the shot data for a given weapon/mag/ammo combination. + * Will use the config that has the highest priority. + * + * Arguments: + * 0: Weapon + * 1: Magazine + * 2: Ammo + * + * Return Value: + * Shot Config : + * 0: Angle + * 1: Range + * 2: Damage + * 3: Offset + * + * Example: + * ["cannon_125mm","Sh_125mm_APFSDS_T_Green","24Rnd_125mm_APFSDS_T_Green"] call ace_overpressure_fnc_getOverPressureValues + * + * Public: No + */ + +params ["_weapon", "_ammo", "_magazine"]; +TRACE_3("Parameter",_weapon,_magazine,_ammo); + +// Check cache for weapon/ammo/mag combo +private _return = GVAR(cacheHash) get _this; +if (!isNil "_return") exitWith { + TRACE_3("CacheHit",_weapon,_magazine,_ammo); + _return +}; + +// get Priority Array from Config +private _array = [ + getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(priority)), + getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(priority)), + getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(priority)) +]; + +(_array call CBA_fnc_findMax) params ["", ["_indexOfMaxPriority", 0, [0]]]; + +TRACE_2("Priority Array",_array,_indexOfMaxPriority); + +// create the Config entry Point +private _config = [ + (configFile >> "CfgWeapons" >> _weapon), + (configFile >> "CfgMagazines" >> _magazine), + (configFile >> "CfgAmmo" >> _ammo) +] select _indexOfMaxPriority; +TRACE_1("ConfigPath",_config); + +// get the Variables out of the Configs and populate return array with them +_return = [ + (getNumber (_config >> QGVAR(angle))), + (getNumber (_config >> QGVAR(range))), + (getNumber (_config >> QGVAR(damage))), + (getNumber (_config >> QGVAR(offset))) +]; + +GVAR(cacheHash) set [_this, _return]; +TRACE_2("Return",_this,_return); + +_return diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index b648d291d0..12b7a820ca 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 and esteldunedain * Calculate and apply backblast damage to potentially affected local units @@ -23,14 +23,10 @@ params ["_firer", "_posASL", "_direction", "_weapon", "_magazine", "_ammo"]; -// Bake variable name and check if the variable exists, call the caching function otherwise -private _varName = format [QGVAR(values%1%2%3), _weapon, _ammo, _magazine]; -private _var = if (isNil _varName) then { - [_weapon, _ammo, _magazine] call FUNC(cacheOverPressureValues); -} else { - missionNameSpace getVariable _varName; -}; -_var params ["_overpressureAngle","_overpressureRange","_overpressureDamage"]; +// Retrieve overpressure values +private _opValues = [_weapon, _ammo, _magazine] call FUNC(getOverPressureValues); + +_opValues params ["_overpressureAngle", "_overpressureRange", "_overpressureDamage"]; TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); { @@ -46,22 +42,26 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); TRACE_4("Affected:",_x,_axisDistance,_distance,_angle); if (_angle < _overpressureAngle && {_distance < _overpressureRange} && {!lineIntersects _line} && {!terrainIntersectASL _line2}) then { + TRACE_2("",isDamageAllowed _unit,_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]); - private _alpha = sqrt (1 - _distance / _overpressureRange); - private _beta = sqrt (1 - _angle / _overpressureAngle); + // Skip damage if not allowed + if (isDamageAllowed _x && {_x getVariable [QEGVAR(medical,allowDamage), true]}) then { + private _alpha = sqrt (1 - _distance / _overpressureRange); + private _beta = sqrt (1 - _angle / _overpressureAngle); - private _damage = _alpha * _beta * _overpressureDamage; - TRACE_1("",_damage); + private _damage = _alpha * _beta * _overpressureDamage; + TRACE_1("",_damage); - // If the target is the ACE_player - if (_x == ACE_player) then {[_damage * 100] call BIS_fnc_bloodEffect}; + // If the target is the ACE_player + if (_x isEqualTo ACE_player) then { + [_damage * 100] call BIS_fnc_bloodEffect; + }; - if (isClass (configFile >> "CfgPatches" >> "ACE_Medical")) then { - [_x, _damage, "body", "backblast"] call EFUNC(medical,addDamageToUnit); - } else { - TRACE_1("",isDamageAllowed _x); - if (!isDamageAllowed _x) exitWith {}; // Skip damage if not allowed - _x setDamage (damage _x + _damage); + if (GETEGVAR(medical,enabled,false)) then { + [_x, _damage, "body", "backblast", _firer] call EFUNC(medical,addDamageToUnit); + } else { + _x setDamage (damage _x + _damage); + }; }; #ifdef DEBUG_MODE_FULL diff --git a/addons/overpressure/functions/script_component.hpp b/addons/overpressure/functions/script_component.hpp deleted file mode 100644 index d66ac7aec3..0000000000 --- a/addons/overpressure/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\overpressure\script_component.hpp" \ No newline at end of file diff --git a/addons/overpressure/initSettings.inc.sqf b/addons/overpressure/initSettings.inc.sqf new file mode 100644 index 0000000000..ece1230dcc --- /dev/null +++ b/addons/overpressure/initSettings.inc.sqf @@ -0,0 +1,23 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(DisplayName)]; + +[ + QGVAR(overpressureDistanceCoefficient), + "SLIDER", + [LSTRING(distanceCoefficient_displayName), LSTRING(distanceCoefficient_toolTip)], + _category, + [0, 10, 1, 1], + 1, + {[QGVAR(overpressureDistanceCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(backblastDistanceCoefficient), + "SLIDER", + [LSTRING(backblastDistanceCoefficient_displayName), LSTRING(backblastDistanceCoefficient_toolTip)], + _category, + [0, 10, 1, 1], + 1, + {[QGVAR(backblastDistanceCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index e66a31f608..0d43f01825 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -1,49 +1,95 @@ - - + + + Overpressure + 超压 + Überdruck + Sovrapressione + 과중압력 + Nadciśnienie + 超過圧力 + Перегрузка + Sobrepresiòn + Surpression + + Overpressure Distance Coefficient Überdruckentfernungskoeffizient - 過圧の距離係数 - 초과압력 거리 계수 + 超過圧力の距離係数 + 과중압력 거리 계수 Mnożnik dystansu nadciśnienia - Coéfficient de distance pour la surpression - Coefficente Distanza Sovrapressione - 高压影响距离系数 + Coefficient de distance pour la surpression + Coefficiente Distanza Sovrapressione + 超压影响距离系数 高壓影響距離係數 - Коэффициент избыточного давления + Коэф. избыточного давления + Coeficiente de Distância de Sobrepressão + Túlnyomás-távolság együtthatója + Koeficient vzdálenosti přetlaku + Coeficiente de distancia de sobrepresión - - Scales the overpressure effect [Default: 1] - Stellt den Koeffizient für die Überdruckentfernung ein [Standard: 1] - 過圧効果の範囲 [標準: 1] - 초과압력의 효과 크기 [기본설정: 1] - Skaluje efekt nadciśnienia [Domyślne: 1] - Échelonne les effets de la surpression [Par défaut : 1] - Scala l'effetto di sovrapressione [Predefinito: 1] - 高压影响的范围 [预设: 1] - 高壓影響的範圍 [預設: 1] - Степень зависимости избыточного давления от расстояния [По умолчанию: 1] + + Scales the overpressure effect + Stellt den Koeffizient für die Überdruckentfernung ein + 火砲による超過圧力の影響範囲の大きさ + 과중압력의 효과 크기 + Skaluje efekt nadciśnienia + Ajuste l'effet de surpression + Scala l'effetto di sovrapressione + 超压影响的范围 + 高壓影響的範圍 + Степень зависимости избыточного давления от расстояния + Escala o efeito de sobrepressão + Állítja a túlnyomás hatását + Nastavuje jak velký je efekt přetlaku + Escala el efecto de sobrepresión - + + Backblast Distance Coefficient + Коэффициент расстояния рекативной струи + Rückstrahl-Entfernung Multiplikator + Coefficiente distanza di svampata + 後方噴射の距離係数 + + + Scales the backblast effect + Масштабирует эффект реактивной струи + Skaliert den Rückstrahl-Effekt + Scala l'effetto delle svampate dei lanciarazzi + 無反動砲による後方噴射の影響範囲の大きさ + + Backblast range - Rückstoßbereich - 後方噴射の範囲 + Rückstrahlzone + 後方噴射範囲 向后喷射的范围 後方尾焰的範圍 Raggio della fiammata [lanciarazzi] Zasięg backblast'u Дальность реактивной струи + Alcance do Sopro de Disparo + Utóhatás távolsága + Portée du backblast + Dosah zpětné tlakové vlny (backblast) + Alcance del cono de fuego + 후폭풍 거리 - + Backblast angle - Rückstoßwinkel - 後方噴射の角度 + Rückstrahlwinkel + 後方噴射角度 向后喷射的角度 後方尾焰的角度 Angolo della fiammata [lanciarazzi] Kąt backblast'u Угол реактивной струи + Ângulo do Sopro de Disparo + Utóhatás aránya + Angle du backblast + Úhel zpětné tlakové vlny (backblast) + Ángulo del cono de fuego + 후폭풍 각도 diff --git a/addons/parachute/CfgEventHandlers.hpp b/addons/parachute/CfgEventHandlers.hpp index 8fa46b49f3..b1f81bfc20 100644 --- a/addons/parachute/CfgEventHandlers.hpp +++ b/addons/parachute/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/parachute/CfgVehicles.hpp b/addons/parachute/CfgVehicles.hpp index 5f1b750377..545d9a3705 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -21,6 +21,7 @@ class CfgVehicles { }; }; MACRO_HASRESERVE + GVAR(failureDelay) = 2; }; class ParachuteWest: ParachuteBase { MACRO_HASRESERVE @@ -56,7 +57,7 @@ class CfgVehicles { MACRO_HASRESERVE }; class Bag_Base; - class B_Parachute:Bag_Base { + class B_Parachute: Bag_Base { MACRO_HASRESERVE }; class B_B_Parachute_02_F: B_Parachute { @@ -100,4 +101,36 @@ class CfgVehicles { class B_Soldier_05_f; class B_Pilot_F: B_Soldier_05_f {backpack = "ACE_NonSteerableParachute";}; class I_Soldier_04_F; class I_pilot_F: I_Soldier_04_F {backpack = "ACE_NonSteerableParachute";}; class O_helipilot_F; class O_Pilot_F: O_helipilot_F {backpack = "ACE_NonSteerableParachute";}; + + class Plane_Base_F; + class Plane_CAS_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_CAS_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_03_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_04_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; }; diff --git a/addons/parachute/README.md b/addons/parachute/README.md index 3dd2608152..5bb3fd0050 100644 --- a/addons/parachute/README.md +++ b/addons/parachute/README.md @@ -2,11 +2,3 @@ ace_parachute =========== Improves parachutes and adds an altimeter. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [CorruptedHeart](https://github.com/CorruptedHeart) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/parachute/RscTitles.hpp b/addons/parachute/RscTitles.hpp index 277db4d2f9..48cf11bee4 100644 --- a/addons/parachute/RscTitles.hpp +++ b/addons/parachute/RscTitles.hpp @@ -13,37 +13,37 @@ class RscTitles { class AltimeterImage: RscPicture { idc = 1200; text = QPATHTOF(UI\watch_altimeter.paa); - x = 0.118437 * safezoneW + safezoneX; - y = 0.621 * safezoneH + safezoneY; - w = 0.20625 * safezoneW; - h = 0.341 * safezoneH; + x = "0.118437 * safezoneW + safezoneX"; + y = "0.621 * safezoneH + safezoneY"; + w = "0.20625 * safezoneW"; + h = "0.341 * safezoneH"; }; class HeightText: RscText { idc = 1100; text = "----"; - x = 0.200937 * safezoneW + safezoneX; - y = 0.764 * safezoneH + safezoneY; - w = 0.04125 * safezoneW; - h = 0.033 * safezoneH; + x = "0.200937 * safezoneW + safezoneX"; + y = "0.764 * safezoneH + safezoneY"; + w = "0.04125 * safezoneW"; + h = "0.033 * safezoneH"; colorBackground[] = {0,0,0,0}; colorText[] = {0,0,0,1}; }; class DecendRate: RscText { idc = 1000; text = "--"; - x = 0.21125 * safezoneW + safezoneX; - y = 0.742 * safezoneH + safezoneY; - w = 0.020625 * safezoneW; - h = 0.022 * safezoneH; + x = "0.21125 * safezoneW + safezoneX"; + y = "0.742 * safezoneH + safezoneY"; + w = "0.020625 * safezoneW"; + h = "0.022 * safezoneH"; colorText[] = {0,0,0,1}; }; class TimeText: RscText { idc = 1001; - text = "00:00"; - x = 0.206094 * safezoneW + safezoneX; - y = 0.819 * safezoneH + safezoneY; - w = 0.0309375 * safezoneW; - h = 0.022 * safezoneH; + text = "00:00:00"; + x = "0.202094 * safezoneW + safezoneX"; + y = "0.819 * safezoneH + safezoneY"; + w = "0.0380375 * safezoneW"; + h = "0.022 * safezoneH"; colorText[] = {0,0,0,1}; }; }; diff --git a/addons/parachute/XEH_PREP.hpp b/addons/parachute/XEH_PREP.hpp index 6edd22c260..916aa1ccdb 100644 --- a/addons/parachute/XEH_PREP.hpp +++ b/addons/parachute/XEH_PREP.hpp @@ -1,4 +1,5 @@ PREP(cutParachute); +PREP(handleFailureChance); PREP(handleInfoDisplayChanged); PREP(handleReserve); PREP(hideAltimeter); diff --git a/addons/parachute/XEH_postInit.sqf b/addons/parachute/XEH_postInit.sqf index 06e02f0757..f10748b0cf 100644 --- a/addons/parachute/XEH_postInit.sqf +++ b/addons/parachute/XEH_postInit.sqf @@ -34,7 +34,9 @@ if (!hasInterface) exitWith {}; }, {false}, [24, [false, false, false]], false] call CBA_fnc_addKeybind; // Handle reserve chute based on current backpack (fires when parachute opens too) -["loadout", FUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; // Don't show vanilla speed and height when in expert mode -["ace_infoDisplayChanged", {_this call FUNC(handleInfoDisplayChanged)}] call CBA_fnc_addEventHandler; +["ace_infoDisplayChanged", LINKFUNC(handleInfoDisplayChanged)] call CBA_fnc_addEventHandler; + +["vehicle", LINKFUNC(handleFailureChance)] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/parachute/XEH_preInit.sqf b/addons/parachute/XEH_preInit.sqf index 5a10c0bd83..d3aa4bd2d5 100644 --- a/addons/parachute/XEH_preInit.sqf +++ b/addons/parachute/XEH_preInit.sqf @@ -8,14 +8,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -[ - QGVAR(hideAltimeter), - "CHECKBOX", - [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], - format ["ACE %1", localize ELSTRING(common,DisplayName)], - true, - false, - {[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)} -] call cba_settings_fnc_init; +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/parachute/functions/fnc_cutParachute.sqf b/addons/parachute/functions/fnc_cutParachute.sqf index 286673af41..c66d9ff050 100644 --- a/addons/parachute/functions/fnc_cutParachute.sqf +++ b/addons/parachute/functions/fnc_cutParachute.sqf @@ -1,19 +1,23 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: joko, Jonas, SilentSpike + * Author: joko, Jonas, kymckay * Perform the cut parachute action (move unit out and delete) * * Arguments: - * 0: Object + * 0: Player + * 1: Parachute * * Return Value: * None * * Example: - * [player, vehicle player] call FUNC(cutParachute); + * [player, vehicle player] call ace_parachute_fnc_cutParachute; * * Public: No */ params ["_unit", "_parachute"]; +TRACE_2("cutParachute",_unit,_parachute); + +playSound3d ["A3\Sounds_F\characters\parachute\parachute_landing.wss", _unit]; _unit action ["GetOut", _parachute]; deleteVehicle _parachute; diff --git a/addons/parachute/functions/fnc_handleFailureChance.sqf b/addons/parachute/functions/fnc_handleFailureChance.sqf new file mode 100644 index 0000000000..a84817eef1 --- /dev/null +++ b/addons/parachute/functions/fnc_handleFailureChance.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: JoramD + * Handles percentage chance parachute failure. + * + * Arguments: + * 0: Unit + * 1: Vehicle + * + * Return Value: + * None + * + * Example: + * [player, vehicle player] call ace_parachute_fnc_handleFailureChance + * + * Public: No + */ + +params ["_unit", "_vehicle"]; + +if !(_vehicle isKindOf "ParachuteBase") exitWith {}; + +if (random 1 < GVAR(failureChance)) then { + private _failureDelay = getNumber (configOf _vehicle >> QGVAR(failureDelay)); + [FUNC(cutParachute), [_unit, _vehicle], _failureDelay] call CBA_fnc_waitAndExecute; +}; diff --git a/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf b/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf index f1589e1e04..44bf81deb8 100644 --- a/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf +++ b/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Hides the height and velocity display while freefalling or parachuting on higher difficulties. diff --git a/addons/parachute/functions/fnc_handleReserve.sqf b/addons/parachute/functions/fnc_handleReserve.sqf index 3df8d6607e..dd7ba04213 100644 --- a/addons/parachute/functions/fnc_handleReserve.sqf +++ b/addons/parachute/functions/fnc_handleReserve.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: joko, Jonas, SilentSpike + * Author: joko, Jonas, kymckay * Cache reserve parachute on player unit when their inventory changes and add it when they open their parachute * * Arguments: @@ -16,10 +16,10 @@ */ params ["_unit"]; -private _backpack = backpack _unit; +private _backpack = backpackContainer _unit; if ( - _backpack == "" && + isNull _backpack && {(vehicle _unit) isKindOf "ParachuteBase"} && {GETVAR(_unit,GVAR(hasReserve),false)} ) then { @@ -28,7 +28,7 @@ if ( SETVAR(vehicle _unit,GVAR(canCut),true); // Mark the parachute cuttable since reserve is present } else { // Case where inventory has changed otherwise (including when reserve is added) - private _backpackCfg = configFile >> "CfgVehicles" >> _backpack; + private _backpackCfg = configOf _backpack; private _hasReserve = getNumber (_backpackCfg >> "ace_hasReserveParachute") == 1; // Cache reserve parachute state and class when backpack changes diff --git a/addons/parachute/functions/fnc_hideAltimeter.sqf b/addons/parachute/functions/fnc_hideAltimeter.sqf index 280ee286b4..fc53f533d3 100644 --- a/addons/parachute/functions/fnc_hideAltimeter.sqf +++ b/addons/parachute/functions/fnc_hideAltimeter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes the altimeter from the screen. diff --git a/addons/parachute/functions/fnc_showAltimeter.sqf b/addons/parachute/functions/fnc_showAltimeter.sqf index e31d2863eb..f86f785cc6 100644 --- a/addons/parachute/functions/fnc_showAltimeter.sqf +++ b/addons/parachute/functions/fnc_showAltimeter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet * Displays the altimeter on screen. @@ -32,16 +32,18 @@ private _TimeText = _display displayCtrl 1001; _args params ["_unit", "_oldHeight", "_prevTime", "_HeightText", "_DecendRate", "_TimeText"]; if !(GVAR(AltimeterActive)) exitWith { - _pfhID call CBA_fnc_removePerFrameEventHandler; + _pfhID call CBA_fnc_removePerFrameHandler; }; if !("ACE_Altimeter" in assignedItems _unit) exitWith { call FUNC(hideAltimeter); - _pfhID call CBA_fnc_removePerFrameEventHandler; + _pfhID call CBA_fnc_removePerFrameHandler; }; - private _hour = floor daytime; - private _minute = floor ((daytime - _hour) * 60); + private _daytime = dayTime; + private _hour = floor _daytime; + private _minute = floor ((_daytime - _hour) * 60); + private _seconds = floor ((((_daytime - _hour) * 60) - _minute) * 60); private _curTime = CBA_missionTime; private _timeDiff = _curTime - _prevTime; @@ -52,9 +54,9 @@ private _TimeText = _display displayCtrl 1001; 0 }; - _TimeText ctrlSetText (format ["%1:%2", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber]); - _HeightText ctrlSetText (format ["%1", floor _height]); - _DecendRate ctrlSetText (format ["%1", _descentRate max 0]); + _TimeText ctrlSetText (format ["%1:%2:%3", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber, [_seconds, 2] call CBA_fnc_formatNumber]); + _HeightText ctrlSetText str floor _height; + _DecendRate ctrlSetText str (_descentRate max 0); (_this select 0) set [1, _height]; (_this select 0) set [2, _curTime]; diff --git a/addons/parachute/functions/script_component.hpp b/addons/parachute/functions/script_component.hpp deleted file mode 100644 index 29f2e63e07..0000000000 --- a/addons/parachute/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\parachute\script_component.hpp" diff --git a/addons/parachute/initSettings.inc.sqf b/addons/parachute/initSettings.inc.sqf new file mode 100644 index 0000000000..0c6804cff7 --- /dev/null +++ b/addons/parachute/initSettings.inc.sqf @@ -0,0 +1,18 @@ +private _category = [LELSTRING(common,categoryUncategorized), localize "str_dn_parachute"]; + +[ + QGVAR(hideAltimeter), + "CHECKBOX", + [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], + _category, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(failureChance), + "SLIDER", + LSTRING(FailureChance), + _category, + [0, 1, 0, 2, true], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/parachute/stringtable.xml b/addons/parachute/stringtable.xml index 2f5ceb4096..db48a6109c 100644 --- a/addons/parachute/stringtable.xml +++ b/addons/parachute/stringtable.xml @@ -16,6 +16,7 @@ 고도계 高度计 高度計 + Altimetre Altimeter Watch @@ -32,10 +33,11 @@ 고도계 시계 高度计手表 高度計手錶 + Altimetre Saati Used to show height, descent rate and the time. - Affiche la hauteur, le taux de descente et l'heure. + Permet d'afficher la hauteur, la vitesse de chute et l'heure. Zeigt Höhe, Fallgeschwindigkeit und Uhrzeit. Používané k zjištění výšky, rychlosti sestupu a času. Używany przez spadochroniarzy, pokazuje wysokość, prędkość opadania oraz czas. @@ -45,9 +47,10 @@ Usato per mostrare l'altitudine, la velocità di discesa e l'ora. Usado para mostrar altura, taxa de descida e o tempo. 高度や降下率、時間を見るのに使います。 - 높이와, 하강속도 그리고 시간을 보여줍니다. + 높이, 하강속도 그리고 시간을 보여줍니다. 用于显示高度,下降率和时间。 用於顯示高度,下降率和時間 + Yüksekliği, alçalma hızını ve zamanı göstermek için kullanılır. Non-Steerable Parachute @@ -59,11 +62,12 @@ Irányíthatatlan ejtőernyő Неуправляемый парашют Paracadute non manovrabile - Para-querdas não controlável + Paraquedas não controlável 非操作型パラシュート - 비-조종 낙하산 + 비조종 낙하산 非可操控降落伞 非可操控降落傘 + Yönlendirilemez Paraşüt Cut Parachute @@ -80,6 +84,7 @@ 낙하산 자르기 剪断降落伞 剪斷降落傘 + Paraşütü Kes Reserve Parachute @@ -87,7 +92,7 @@ Parachute de secours Spadochron awaryjny Tartalék ejtőernyő - Para-quedas de reserva + Paraquedas de reserva Запасной парашют Záložní padák Paracaídas de reserva @@ -96,6 +101,7 @@ 예비 낙하산 备用降落伞 備用降落傘 + Yedek Paraşüt Hide Freefall Altimeter @@ -106,6 +112,12 @@ 隐藏自由落体高度计 Schowaj wysokościomierz podczas swobodnego opadania Убрать высотомер при падении + Esconder Altímetro de queda livre + Masquer l'altimètre en chute libre + Schovat výškoměr v GUI při volném pádu + Ocultar altímetro de caída libre + Serbest Düşüş Altimetresini Gizle + 강하 시 고도계 숨기기 Hides the altitude and speed shown while free falling or parachuting. @@ -116,6 +128,24 @@ 在自由落体时或开伞下隐藏自由落体高度计。 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. + Cache l'altitude et la vitesse affichées, lors d'une chute libre ou d'un parachutage. + Schová výšku a rychlost v GUI při volném pádu a při použití padáku. + Oculta la altitud y la velocidad que se muestran en caída libre o en paracaídas. + Serbest düşme veya paraşütle atlama sırasında gösterilen yüksekliği ve hızı gizler. + 강하 시 고도와 속도를 보여주지 않습니다. + + + Parachute Failure Chance + Вероятность отказа парашюта + Chance de défaillance du parachute + 開傘失敗率 + Szansa na nieotwarcie się spadochronu + Wahrscheinlichkeit, dass ein Fallschirm sich nicht öffnet + Probabilità che l'apertura del paracadute fallisca + 开伞失败率 + 낙하산 펼치기 실패 확률 + Probabilidad de fallo de paracaidas diff --git a/addons/pronelauncher/$PBOPREFIX$ b/addons/pronelauncher/$PBOPREFIX$ new file mode 100644 index 0000000000..e7ea0fb878 --- /dev/null +++ b/addons/pronelauncher/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\pronelauncher diff --git a/addons/pronelauncher/CfgEventHandlers.hpp b/addons/pronelauncher/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9cc1b0427b --- /dev/null +++ b/addons/pronelauncher/CfgEventHandlers.hpp @@ -0,0 +1,5 @@ +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/pronelauncher/CfgMovesBasic.hpp b/addons/pronelauncher/CfgMovesBasic.hpp new file mode 100644 index 0000000000..336a446207 --- /dev/null +++ b/addons/pronelauncher/CfgMovesBasic.hpp @@ -0,0 +1,123 @@ +class CfgMovesBasic { + class Default; + class NoActions; + class Actions { + class CivilStandActions; + class CivilProneActions: CivilStandActions { + SecondaryWeapon = "ACE_LauncherProne"; + weaponOn = "ACE_LauncherProne"; + }; + class PistolStandActions; + class PistolProneActions: PistolStandActions { + SecondaryWeapon = "ACE_LauncherProne"; + weaponOn = "ACE_LauncherProne"; + }; + class RifleBaseStandActions; + class RifleProneActions: RifleBaseStandActions { + SecondaryWeapon = "ACE_LauncherProne"; + weaponOn = "ACE_LauncherProne"; + weaponOff = "AmovPpneMstpSrasWrflDnon"; + }; + class LauncherKneelActions: NoActions { + Lying = "AmovPknlMstpSrasWlnrDnon"; + PlayerProne = "AmovPknlMstpSrasWlnrDnon"; + Down = "AmovPknlMstpSrasWlnrDnon"; + }; + class LauncherStandActions: LauncherKneelActions { + Default = "AmovPercMstpSrasWlnrDnon"; + PlayerStand = "AmovPercMstpSrasWlnrDnon"; + Stand = "AmovPercMstpSrasWlnrDnon"; + Up = "AmovPknlMstpSrasWlnrDnon"; + Lying = "AmovPercMstpSrasWlnrDnon"; + PlayerProne = "AmovPercMstpSrasWlnrDnon"; + Down = "AmovPercMstpSrasWlnrDnon"; + }; + class ACE_LauncherProneActions: LauncherKneelActions { + StopRelaxed = "ACE_LauncherProne"; + Default = "ACE_LauncherProne"; + Up = "ACE_LauncherProne"; + Crouch = "ACE_LauncherProne"; + PlayerCrouch = "ACE_LauncherProne"; + Down = "ACE_LauncherProne"; + Stand = "ACE_LauncherProne"; + PlayerStand = "ACE_LauncherProne"; + TurnL = "AmovPpneMrunSrasWlnr_turnL"; + TurnLRelaxed = "AmovPpneMrunSrasWlnr_turnL"; + TurnR = "AmovPpneMrunSrasWlnr_turnR"; + TurnRRelaxed = "AmovPpneMrunSrasWlnr_turnR"; + Stop = "ACE_LauncherProne"; + Civil = "AmovPpneMstpSnonWnonDnon"; + CivilLying = "AmovPpneMstpSnonWnonDnon"; + BinocOff = "ACE_LauncherProne"; + Gear = "AinvPpneMstpSnonWnonDnon"; + BinocOn = "AwopPpneMstpSoptWbinDnon_Lnr"; + HandGunOn = "AmovPpneMstpSrasWpstDnon"; + stance = "ManStanceProne"; + ReloadRPG = "LauncherProne_Reload_Start"; + //GestureReloadRPG7[] = {"GestureReloadRPG7Kneel", "Gesture"}; + weaponOn = "ACE_LauncherProne"; + WeaponOff = "AmovPpneMstpSrasWrflDnon"; + WalkB = "AmovPpneMrunSrasWlnrDb"; + WalkRB = "AmovPpneMrunSrasWlnrDbr"; + WalkLB = "AmovPpneMrunSrasWlnrDbl"; + WalkR = "AmovPpneMrunSrasWlnrDr"; + WalkL = "AmovPpneMrunSrasWlnrDl"; + WalkRF = "AmovPpneMrunSrasWlnrDfr"; + WalkLF = "AmovPpneMrunSrasWlnrDfl"; + WalkF = "AmovPpneMrunSrasWlnrDf"; + PlayerWalkB = "AmovPpneMrunSrasWlnrDb"; + PlayerWalkRB = "AmovPpneMrunSrasWlnrDbr"; + PlayerWalkLB = "AmovPpneMrunSrasWlnrDbl"; + PlayerWalkR = "AmovPpneMrunSrasWlnrDr"; + PlayerWalkL = "AmovPpneMrunSrasWlnrDl"; + PlayerWalkRF = "AmovPpneMrunSrasWlnrDfr"; + PlayerWalkLF = "AmovPpneMrunSrasWlnrDfl"; + PlayerWalkF = "AmovPpneMrunSrasWlnrDf"; + SlowF = "AmovPpneMrunSrasWlnrDf"; + SlowLF = "AmovPpneMrunSrasWlnrDfl"; + SlowRF = "AmovPpneMrunSrasWlnrDfr"; + SlowL = "AmovPpneMrunSrasWlnrDl"; + SlowR = "AmovPpneMrunSrasWlnrDr"; + SlowLB = "AmovPpneMrunSrasWlnrDbl"; + SlowRB = "AmovPpneMrunSrasWlnrDbr"; + SlowB = "AmovPpneMrunSrasWlnrDb"; + PlayerSlowF = "AmovPpneMrunSrasWlnrDf"; + PlayerSlowLF = "AmovPpneMrunSrasWlnrDfl"; + PlayerSlowRF = "AmovPpneMrunSrasWlnrDfr"; + PlayerSlowL = "AmovPpneMrunSrasWlnrDl"; + PlayerSlowR = "AmovPpneMrunSrasWlnrDr"; + PlayerSlowLB = "AmovPpneMrunSrasWlnrDbl"; + PlayerSlowRB = "AmovPpneMrunSrasWlnrDbr"; + PlayerSlowB = "AmovPpneMrunSrasWlnrDb"; + FastF = "AmovPpneMrunSrasWlnrDf"; + FastLF = "AmovPpneMrunSrasWlnrDfl"; + FastRF = "AmovPpneMrunSrasWlnrDfr"; + FastL = "AmovPpneMrunSrasWlnrDl"; + FastR = "AmovPpneMrunSrasWlnrDr"; + FastLB = "AmovPpneMrunSrasWlnrDbl"; + FastRB = "AmovPpneMrunSrasWlnrDr"; + FastB = "AmovPpneMrunSrasWlnrDb"; + TactB = "AmovPpneMrunSrasWlnrDb"; + TactRB = "AmovPpneMrunSrasWlnrDbr"; + TactLB = "AmovPpneMrunSrasWlnrDbl"; + TactR = "AmovPpneMrunSrasWlnrDr"; + TactL = "AmovPpneMrunSrasWlnrDl"; + TactRF = "AmovPpneMrunSrasWlnrDfr"; + TactLF = "AmovPpneMrunSrasWlnrDfl"; + TactF = "AmovPpneMrunSrasWlnrDf"; + PlayerTactB = "AmovPpneMrunSrasWlnrDb"; + PlayerTactRB = "AmovPpneMrunSrasWlnrDbr"; + PlayerTactLB = "AmovPpneMrunSrasWlnrDbl"; + PlayerTactR = "AmovPpneMrunSrasWlnrDr"; + PlayerTactL = "AmovPpneMrunSrasWlnrDl"; + PlayerTactRF = "AmovPpneMrunSrasWlnrDfr"; + PlayerTactLF = "AmovPpneMrunSrasWlnrDfl"; + PlayerTactF = "AmovPpneMrunSrasWlnrDf"; + }; + class BinocProneLnrActions: LauncherKneelActions { + BinocOff = "ACE_LauncherProne"; + SecondaryWeapon = "ACE_LauncherProne"; + weaponOn = "ACE_LauncherProne"; + }; + }; +}; diff --git a/addons/pronelauncher/CfgMovesMaleSdr.hpp b/addons/pronelauncher/CfgMovesMaleSdr.hpp new file mode 100644 index 0000000000..5f4d8c207b --- /dev/null +++ b/addons/pronelauncher/CfgMovesMaleSdr.hpp @@ -0,0 +1,241 @@ +class CfgMovesMaleSdr: CfgMovesBasic { + class Default; + class TransAnimBase; + class AmovPpneMstpSrasWlnrDnon; + class States { + // Prone Stopped Launcher + class ACE_LauncherProne: AmovPpneMstpSrasWlnrDnon { + variantsAI[] = {}; + variantsPlayer[] = {}; + duty = -1.2; + showWeaponAim = 0; + disableWeapons = 0; + disableWeaponsLong = 0; + enableMissile = 1; + canPullTrigger = 1; + aimPrecision = 0.30000001; + speed = 1e+010; + actions = "ACE_LauncherProneActions"; + file = QPATHTOF(anim\ACE_Launcher_Lying.rtm); + interpolateFrom[] = { + "AmovPercMstpSrasWlnrDnon", 0.02, + "AmovPknlMstpSrasWlnrDnon", 0.02, + "AmovPpneMstpSrasWlnrDnon_turnL", 0.02, + "AmovPpneMstpSrasWlnrDnon_turnR", 0.02, + "AmovPpneMrunSrasWlnrDf", 0.02, + "AmovPpneMrunSrasWlnrDfl", 0.02, + "AmovPpneMrunSrasWlnrDl", 0.02, + "AmovPpneMrunSrasWlnrDbl", 0.02, + "AmovPpneMrunSrasWlnrDb", 0.02, + "AmovPpneMrunSrasWlnrDbr", 0.02, + "AmovPpneMrunSrasWlnrDr", 0.02, + "AmovPpneMrunSrasWlnrDfr", 0.02 + }; + connectTo[] = {}; + interpolateTo[] = { + "AmovPpneMstpSrasWlnrDnon_turnL", 0.02, + "AmovPpneMstpSrasWlnrDnon_turnR", 0.02, + "AmovPpneMstpSrasWlnrDnon_AmovPknlMstpSrasWlnrDnon", 0.02, + "AmovPpneMrunSrasWlnrDf", 0.02, + "AmovPpneMrunSrasWlnrDfl", 0.02, + "AmovPpneMrunSrasWlnrDl", 0.02, + "AmovPpneMrunSrasWlnrDbl", 0.02, + "AmovPpneMrunSrasWlnrDb", 0.02, + "AmovPpneMrunSrasWlnrDbr", 0.02, + "AmovPpneMrunSrasWlnrDr", 0.02, + "AmovPpneMrunSrasWlnrDfr", 0.02, + "AmovPpneMstpSrasWlnrDnon", 0.02, + "Unconscious", 0.02, + "Campaign_Base", 0.02 + }; + }; + // Prone Stopped Launcher Turn Left + class AmovPpneMstpSrasWlnrDnon_turnL: AmovPpneMstpSrasWlnrDnon { + actions = "ACE_LauncherProneActions"; + aimPrecision = 5; + connectTo[] += { + "AmovPpneMstpSrasWlnrDnon_turnL", 0.02 + }; + interpolateTo[] += { + "AmovPpneMstpSrasWlnrDnon", 0.02 + }; + }; + // Prone Stopped Launcher Turn Right + class AmovPpneMstpSrasWlnrDnon_turnR: AmovPpneMstpSrasWlnrDnon { + actions = "ACE_LauncherProneActions"; + aimPrecision = 5; + connectTo[] += { + "AmovPpneMstpSrasWlnrDnon_turnR", 0.02 + }; + interpolateTo[] += { + "AmovPpneMstpSrasWlnrDnon", 0.02 + }; + }; + // Prone Stopped Launcher -> Standing Stopped Launcher + //class AmovPpneMstpSrasWlnrDnon_AmovPercMstpSrasWlnrDnon: TransAnimBase { + // actions = "LauncherStandActions"; + // duty = 2; + // enableOptics = 1; + // reverse = "AmovPercMstpSrasWlnrDnon_AmovPpneMstpSrasWlnrDnon"; + // interpolateTo[] += { + // "AmovPercMstpSrasWlnrDnon", 0.02 + // }; + //}; + class AmovPpneMrunSrasWlnrDf: AmovPpneMstpSrasWlnrDnon { + speed = 0.600541; + duty = 0.6; + disableWeapons = 1; + disableWeaponsLong = 1; + enableMissile = 0; + canPullTrigger = 0; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDfl: AmovPpneMrunSrasWlnrDf { + speed = 0.833333; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDl: AmovPpneMrunSrasWlnrDf { + speed = 0.625; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDbl: AmovPpneMrunSrasWlnrDf { + speed = 0.702524; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDb: AmovPpneMrunSrasWlnrDf { + speed = 0.702524; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDbr: AmovPpneMrunSrasWlnrDf { + speed = 0.702524; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDr: AmovPpneMrunSrasWlnrDf { + speed = 0.859341; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class AmovPpneMrunSrasWlnrDfr: AmovPpneMrunSrasWlnrDf { + speed = 0.9375; + duty = 0.6; + actions = "ACE_LauncherProneActions"; + }; + class ProneLauncher_To_ProneRifle: AmovPpneMrunSrasWlnrDl { + speed = 0.9375; + duty = 0.6; + disableWeapons = 1; + actions = "ACE_LauncherProneActions"; + interpolateFrom[] = { + "ACE_LauncherProne", 0.015 + }; + interpolateTo[] = { + "ProneLauncher_To_ProneRifle_End", 0.02 + }; + }; + class ProneLauncher_To_ProneRifle_End: AmovPpneMrunSrasWlnrDf { + speed = 0.9375; + duty = 0.6; + disableWeapons = 1; + actions = "ACE_LauncherProneActions"; + interpolateTo[] = { + "AmovPpneMstpSrasWrflDnon", 0.02, + "amovppnemstpsnonwnondnon", 0.02, + "AmovPpneMstpSrasWpstDnon", 0.02 + }; + }; + class ProneRifle_To_ProneLauncher: ProneLauncher_To_ProneRifle { + speed = 0.76; + duty = 0.6; + interpolateFrom[] = { + "AmovPpneMstpSrasWrflDnon", 0.02 + }; + interpolateTo[] = { + "AmovPpneMrunSrasWlnrDf", 0.015, + "AmovPpneMrunSrasWlnrDr", 0.015, + "AmovPpneMrunSrasWlnrDl", 0.015, + "ACE_LauncherProne", 0.015 + }; + }; + class PronePistol_To_ProneLauncher: ProneLauncher_To_ProneRifle { + speed = 0.76; + duty = 0.6; + interpolateFrom[] = { + "AmovPpneMstpSrasWpstDnon", 0.015 + }; + interpolateTo[] = { + "AmovPpneMrunSrasWlnrDf", 0.015, + "AmovPpneMrunSrasWlnrDr", 0.015, + "AmovPpneMrunSrasWlnrDl", 0.015, + "ACE_LauncherProne", 0.015 + }; + }; + class ProneCivil_To_ProneLauncher: ProneLauncher_To_ProneRifle { + speed = 0.76; + duty = 0.6; + interpolateFrom[] = { + "AmovPpneMstpSnonWnonDnon", 0.015 + }; + interpolateTo[] = { + "AmovPpneMrunSrasWlnrDf", 0.015, + "AmovPpneMrunSrasWlnrDr", 0.015, + "AmovPpneMrunSrasWlnrDl", 0.015, + "ACE_LauncherProne", 0.015 + }; + }; + class AmovPercMstpSrasWlnrDnon_AmovPpneMstpSrasWlnrDnon: TransAnimBase { + mask = "weaponSwitching"; + }; + class AmovPpneMstpSrasWlnrDnon_AmovPknlMstpSrasWlnrDnon: TransAnimBase { + blockMobileSwitching = 0; + ConnectTo[] = {}; + InterpolateTo[] += { + "AmovPknlMstpSrasWlnrDnon", 0.02, + "AmovPercMstpSrasWlnrDnon", 0.02 + }; + }; + class LauncherProne_Reload_Start: AmovPpneMrunSrasWlnrDl { + actions = "ACE_LauncherProneActions"; + speed = 0.7375; + duty = 0.6; + disableWeapons = 1; + disableWeaponsLong = 1; + enableMissile = 0; + canPullTrigger = 0; + interpolateFrom[] = { + "ACE_LauncherProne", 0.02 + }; + interpolateTo[] = { + "LauncherProne_Reload_Mid", 0.005 + }; + }; + class LauncherProne_Reload_Mid: AmovPpneMrunSrasWlnrDr { + actions = "ACE_LauncherProneActions"; + speed = 0.7375; + duty = 0.6; + disableWeapons = 1; + disableWeaponsLong = 1; + enableMissile = 0; + canPullTrigger = 0; + interpolateTo[] = { + "LauncherProne_Reload_End", 0.005 + }; + }; + class LauncherProne_Reload_End: AmovPpneMrunSrasWlnrDf { + actions = "ACE_LauncherProneActions"; + speed = 0.7375; + duty = 0.6; + disableWeapons = 1; + disableWeaponsLong = 1; + enableMissile = 0; + canPullTrigger = 0; + interpolateTo[] = { + "ACE_LauncherProne", 0.02 + }; + }; + }; +}; diff --git a/addons/pronelauncher/README.md b/addons/pronelauncher/README.md new file mode 100644 index 0000000000..6158aff63e --- /dev/null +++ b/addons/pronelauncher/README.md @@ -0,0 +1,11 @@ +pronelauncher +======== + +Enables prone launcher animations. + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [PiZZADOX](https://github.com/PiZZADOX) diff --git a/addons/pronelauncher/XEH_postInit.sqf b/addons/pronelauncher/XEH_postInit.sqf new file mode 100644 index 0000000000..29d13abdf4 --- /dev/null +++ b/addons/pronelauncher/XEH_postInit.sqf @@ -0,0 +1,71 @@ +#include "script_component.hpp" + +addUserActionEventHandler ["Stand", "Activate", { // Stand (toggle) + if ((!alive ACE_player) || {!(isNull objectParent ACE_player)}) exitWith {}; + + private _launcherWeapon = secondaryWeapon ACE_player; + + if ((_launcherWeapon == "") || {currentWeapon ACE_player != _launcherWeapon}) exitwith {}; + + if ((stance ACE_player) == "PRONE") then { + TRACE_1("stand toggle",stance ACE_player); + ACE_player playMoveNow "AmovPpneMstpSrasWlnrDnon_AmovPknlMstpSrasWlnrDnon"; + ACE_player playMove "AmovPknlMstpSrasWlnrDnon_AmovPercMstpSrasWlnrDnon"; + }; +}]; + +addUserActionEventHandler ["Crouch", "Activate", { // Crouch (toggle) + if ((!alive ACE_player) || {!(isNull objectParent ACE_player)}) exitWith {}; + + private _launcherWeapon = secondaryWeapon ACE_player; + + if ((_launcherWeapon == "") || {currentWeapon ACE_player != _launcherWeapon}) exitwith {}; + + if ((stance ACE_player) == "PRONE") then { + TRACE_1("crouch toggle",stance ACE_player); + ACE_player playMoveNow "AmovPpneMstpSrasWlnrDnon_AmovPknlMstpSrasWlnrDnon"; + }; +}]; + +addUserActionEventHandler ["Prone", "Activate", { // Prone (toggle) + if ((!alive ACE_player) || {!(isNull objectParent ACE_player)}) exitWith {}; + + private _launcherWeapon = secondaryWeapon ACE_player; + + if ((_launcherWeapon == "") || {currentWeapon ACE_player != _launcherWeapon}) exitwith {}; + + TRACE_1("prone toggle",stance ACE_player); + + // Make unit go prone (resets if key is pressed, so need to redo animation) + ACE_player playMoveNow "ACE_LauncherProne"; +}]; + +addUserActionEventHandler ["MoveUp", "Activate", { // (X) Crouch / Stand Up + if ((!alive ACE_player) || {!(isNull objectParent ACE_player)}) exitWith {}; + + private _launcherWeapon = secondaryWeapon ACE_player; + + if ((_launcherWeapon == "") || {currentWeapon ACE_player != _launcherWeapon}) exitwith {}; + + if ((stance ACE_player) == "PRONE") then { + TRACE_1("moveUp from prone",stance ACE_player); + ACE_player playMoveNow "AmovPpneMstpSrasWlnrDnon_AmovPknlMstpSrasWlnrDnon"; + }; +}]; + +addUserActionEventHandler ["MoveDown", "Activate", { // (Z) Go Prone / Stand Up + if ((!alive ACE_player) || {!(isNull objectParent ACE_player)}) exitWith {}; + + private _launcherWeapon = secondaryWeapon ACE_player; + + if ((_launcherWeapon == "") || {currentWeapon ACE_player != _launcherWeapon}) exitwith {}; + + if ((stance ACE_player) == "PRONE") then { + TRACE_1("moveDown from prone",stance ACE_player); + ACE_player playMoveNow "AmovPpneMstpSrasWlnrDnon_AmovPknlMstpSrasWlnrDnon"; + ACE_player playMove "AmovPknlMstpSrasWlnrDnon_AmovPercMstpSrasWlnrDnon"; + } else { + TRACE_1("moveDown from non-prone",stance ACE_player); + ACE_player playMoveNow "ACE_LauncherProne"; + }; +}]; diff --git a/addons/pronelauncher/anim/ACE_Launcher_Lying.rtm b/addons/pronelauncher/anim/ACE_Launcher_Lying.rtm new file mode 100644 index 0000000000..6337573750 Binary files /dev/null and b/addons/pronelauncher/anim/ACE_Launcher_Lying.rtm differ diff --git a/addons/pronelauncher/config.cpp b/addons/pronelauncher/config.cpp new file mode 100644 index 0000000000..e0adba6675 --- /dev/null +++ b/addons/pronelauncher/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PiZZADOX"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMovesBasic.hpp" +#include "CfgMovesMaleSdr.hpp" +#include "CfgEventHandlers.hpp" diff --git a/addons/pronelauncher/script_component.hpp b/addons/pronelauncher/script_component.hpp new file mode 100644 index 0000000000..b645bfebe1 --- /dev/null +++ b/addons/pronelauncher/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT pronelauncher +#define COMPONENT_BEAUTIFIED Prone Launcher +#include "\z\ace\addons\main\script_mod.hpp" + +#define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_PRONELAUNCHER + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_PRONELAUNCHER + #define DEBUG_SETTINGS DEBUG_SETTINGS_PRONELAUNCHER +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/pylons/CfgEventHandlers.hpp b/addons/pylons/CfgEventHandlers.hpp index 0d3301d6e0..f6503c2479 100644 --- a/addons/pylons/CfgEventHandlers.hpp +++ b/addons/pylons/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/pylons/README.md b/addons/pylons/README.md index b2b6d9d064..bbca9d7e2b 100644 --- a/addons/pylons/README.md +++ b/addons/pylons/README.md @@ -2,10 +2,3 @@ ace_pylons ============ Adds an interface that allows players to configure aircraft pylons. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [654wak654](https://github.com/654wak654) diff --git a/addons/pylons/XEH_postInit.sqf b/addons/pylons/XEH_postInit.sqf index 3e0b9bb4f0..3167c0a838 100644 --- a/addons/pylons/XEH_postInit.sqf +++ b/addons/pylons/XEH_postInit.sqf @@ -14,10 +14,9 @@ GVAR(loadoutAction) = [ // create action private _isRearmVehicle = if (["ace_rearm"] call EFUNC(common,isModLoaded)) then { _vehicles findIf {[_x] call EFUNC(rearm,isSource)} != -1; } else { - private _cfgVehicle = configFile >> "CfgVehicles"; - _vehicles findIf {getNumber (_cfgVehicle >> typeOf _x >> "transportAmmo") > 0} != -1; + _vehicles findIf {getNumber ((configOf _x) >> "transportAmmo") > 0} != -1; }; - + (_isRearmVehicle && {[ace_player, _target] call FUNC(canConfigurePylons)}) } ] call EFUNC(interact_menu,createAction); @@ -27,7 +26,7 @@ GVAR(loadoutAction) = [ // create action private _typeOf = typeOf _vehicle; if (_typeOf in GVAR(aircraftWithPylons)) exitWith {}; - if (!isClass (configFile >> "CfgVehicles" >> _typeOf >> 'Components' >> 'TransportPylonsComponent')) exitWith {}; + if (!isClass ((configOf _vehicle) >> 'Components' >> 'TransportPylonsComponent')) exitWith {}; GVAR(aircraftWithPylons) pushBack _typeOf; [_typeOf, 0, ["ACE_MainActions"], GVAR(loadoutAction)] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/pylons/XEH_preInit.sqf b/addons/pylons/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/pylons/XEH_preInit.sqf +++ b/addons/pylons/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/pylons/functions/fnc_canConfigurePylons.sqf b/addons/pylons/functions/fnc_canConfigurePylons.sqf index 546d3e6766..56584a306b 100644 --- a/addons/pylons/functions/fnc_canConfigurePylons.sqf +++ b/addons/pylons/functions/fnc_canConfigurePylons.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Checks if given unit can access the pylon configuration dialog for the given aircraft. diff --git a/addons/pylons/functions/fnc_configurePylons.sqf b/addons/pylons/functions/fnc_configurePylons.sqf index 81313ce61e..fa3d54f011 100644 --- a/addons/pylons/functions/fnc_configurePylons.sqf +++ b/addons/pylons/functions/fnc_configurePylons.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Recursively shows the progress bar for each configured pylon. diff --git a/addons/pylons/functions/fnc_handleDisconnect.sqf b/addons/pylons/functions/fnc_handleDisconnect.sqf index 9ad646eb31..d3a77def59 100644 --- a/addons/pylons/functions/fnc_handleDisconnect.sqf +++ b/addons/pylons/functions/fnc_handleDisconnect.sqf @@ -1,23 +1,25 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Cleans up pylons on client disconnect. * * Arguments: - * 0: Player + * 0: Unit (not used) + * 1: ID (not used) + * 2: UID * * Return Value: * None * * Example: - * [] call ace_pylons_fnc_handleDisconnect + * [_unit, _id, _uid] call ace_pylons_fnc_handleDisconnect * * Public: No */ params ["", "", "_uid"]; -private _aircraft = GVAR(currentAircraftNamespace) getVariable ["_uid", objNull]; +private _aircraft = GVAR(currentAircraftNamespace) getVariable [_uid, objNull]; if (!isNull _aircraft) then { _aircraft setVariable [QGVAR(currentUser), objNull, true]; diff --git a/addons/pylons/functions/fnc_onButtonApply.sqf b/addons/pylons/functions/fnc_onButtonApply.sqf index 5603ed8d94..ee397ddd1e 100644 --- a/addons/pylons/functions/fnc_onButtonApply.sqf +++ b/addons/pylons/functions/fnc_onButtonApply.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Starts the pylon configuration. @@ -17,7 +17,7 @@ // Check for FRIES change private _checkbox = CONTROL(ID_DIALOG) ID_CHECKBOX_FRIES; -if (ctrlShown _checkbox && {!((cbChecked _checkbox) isEqualTo (_checkbox getVariable QGVAR(originalState)))}) then { +if (ctrlShown _checkbox && {(cbChecked _checkbox) isNotEqualTo (_checkbox getVariable QGVAR(originalState))}) then { if (cbChecked _checkbox) then { [GVAR(currentAircraft)] call EFUNC(fastroping,equipFRIES); } else { diff --git a/addons/pylons/functions/fnc_onButtonClose.sqf b/addons/pylons/functions/fnc_onButtonClose.sqf index c0f51e634a..95777de0cf 100644 --- a/addons/pylons/functions/fnc_onButtonClose.sqf +++ b/addons/pylons/functions/fnc_onButtonClose.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Handles the closing of the dialog. diff --git a/addons/pylons/functions/fnc_onButtonDelete.sqf b/addons/pylons/functions/fnc_onButtonDelete.sqf index eaf16cd99a..55c5a69ef2 100644 --- a/addons/pylons/functions/fnc_onButtonDelete.sqf +++ b/addons/pylons/functions/fnc_onButtonDelete.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Deletes the selected pylon configuration from profileNamespace. diff --git a/addons/pylons/functions/fnc_onButtonLoad.sqf b/addons/pylons/functions/fnc_onButtonLoad.sqf index af3183073a..3604a8273b 100644 --- a/addons/pylons/functions/fnc_onButtonLoad.sqf +++ b/addons/pylons/functions/fnc_onButtonLoad.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Loads selected pylon configuration from either config or profileNamespace. @@ -37,7 +37,7 @@ private _fnc_setSelections = { } forEach GVAR(comboBoxes); }; -private _pylonComponent = configFile >> "CfgVehicles" >> typeOf GVAR(currentAircraft) >> "Components" >> "TransportPylonsComponent"; +private _pylonComponent = configOf GVAR(currentAircraft) >> "Components" >> "TransportPylonsComponent"; private _loadoutFound = { if (getText (_x >> "displayName") isEqualTo _loadoutName) exitWith { // Get default turrets from config diff --git a/addons/pylons/functions/fnc_onButtonSave.sqf b/addons/pylons/functions/fnc_onButtonSave.sqf index 8f30ad1a58..022c614a80 100644 --- a/addons/pylons/functions/fnc_onButtonSave.sqf +++ b/addons/pylons/functions/fnc_onButtonSave.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Saves the selected pylon configuration to profileNamespace. diff --git a/addons/pylons/functions/fnc_onButtonTurret.sqf b/addons/pylons/functions/fnc_onButtonTurret.sqf index e6828bab99..2e1193e0e4 100644 --- a/addons/pylons/functions/fnc_onButtonTurret.sqf +++ b/addons/pylons/functions/fnc_onButtonTurret.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Handles init and click events of turret switch buttons. diff --git a/addons/pylons/functions/fnc_onComboSelChange.sqf b/addons/pylons/functions/fnc_onComboSelChange.sqf index aa71c65099..badf1a7794 100644 --- a/addons/pylons/functions/fnc_onComboSelChange.sqf +++ b/addons/pylons/functions/fnc_onComboSelChange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Handles various UI changes when a combobox' selection changes. diff --git a/addons/pylons/functions/fnc_onNameChange.sqf b/addons/pylons/functions/fnc_onNameChange.sqf index 70344baa80..653e1f678b 100644 --- a/addons/pylons/functions/fnc_onNameChange.sqf +++ b/addons/pylons/functions/fnc_onNameChange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Called when current loadout name is changed. diff --git a/addons/pylons/functions/fnc_onPylonMirror.sqf b/addons/pylons/functions/fnc_onPylonMirror.sqf index 949668ceb8..0dca961a42 100644 --- a/addons/pylons/functions/fnc_onPylonMirror.sqf +++ b/addons/pylons/functions/fnc_onPylonMirror.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Called when the "mirror" checkbox on the loadout dialog is checked. diff --git a/addons/pylons/functions/fnc_showDialog.sqf b/addons/pylons/functions/fnc_showDialog.sqf index 119489f4d8..9c0faab52d 100644 --- a/addons/pylons/functions/fnc_showDialog.sqf +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Shows the aircraft loadout dialog for given aircraft. @@ -48,7 +48,7 @@ if (GVAR(rearmNewPylons) || {_isCurator}) then { ctrlShow [ID_TEXT_BANNER, false]; }; -private _config = configFile >> "CfgVehicles" >> typeOf _aircraft; +private _config = configOf _aircraft; private _pylonComponent = _config >> "Components" >> "TransportPylonsComponent"; ctrlSetText [ID_PICTURE_AIRCRAFT, getText (_pylonComponent >> "uiPicture")]; @@ -93,6 +93,8 @@ GVAR(comboBoxes) = []; { _combo lbAdd getText (configFile >> "CfgMagazines" >> _x >> "displayName"); _combo lbSetData [_forEachIndex + 1, _x]; + private _description = getText (configFile >> "CfgMagazines" >> _x >> "descriptionShort"); + _combo lbSetTooltip [_forEachIndex + 1, _description]; if (_x == _mag) then { _index = _forEachIndex + 1; @@ -105,7 +107,7 @@ GVAR(comboBoxes) = []; private _mirroredIndex = getNumber (_x >> "mirroredMissilePos"); private _button = controlNull; - if (count allTurrets [_aircraft, false] > 0) then { + if ((allTurrets [_aircraft, false]) isNotEqualTo []) then { _button = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1]; private _turret = [_aircraft, _forEachIndex] call EFUNC(common,getPylonTurret); [_button, false, _turret] call FUNC(onButtonTurret); diff --git a/addons/pylons/functions/script_component.hpp b/addons/pylons/functions/script_component.hpp deleted file mode 100644 index 62e8ea51a0..0000000000 --- a/addons/pylons/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\pylons\script_component.hpp" diff --git a/addons/pylons/initSettings.inc.sqf b/addons/pylons/initSettings.inc.sqf new file mode 100644 index 0000000000..70b158957f --- /dev/null +++ b/addons/pylons/initSettings.inc.sqf @@ -0,0 +1,66 @@ +[ + QGVAR(enabledFromAmmoTrucks), + "CHECKBOX", + [LSTRING(EnabledFromAmmoTrucks), LSTRING(EnabledFromAmmoTrucks_description)], + LSTRING(Category_Pylons), + [true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(enabledForZeus), + "CHECKBOX", + [LSTRING(EnabledForZeus), LSTRING(EnabledForZeus_description)], + LSTRING(Category_Pylons), + [true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(rearmNewPylons), + "CHECKBOX", + [LSTRING(RearmNewPylons), LSTRING(RearmNewPylons_description)], + LSTRING(Category_Pylons), + [false], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(requireEngineer), + "CHECKBOX", + [LSTRING(RequireEngineer), LSTRING(RequireEngineer_description)], + LSTRING(Category_Pylons), + [false], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(requireToolkit), + "CHECKBOX", + [LSTRING(RequireToolkit), LSTRING(RequireToolkit_description)], + LSTRING(Category_Pylons), + [true], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(searchDistance), + "SLIDER", + [LSTRING(SearchDistance), LSTRING(SearchDistance_description)], + LSTRING(Category_Pylons), + [5, 50, 15, 0], + true, + { + params ["_searchDistance"]; + GVAR(searchDistanceSqr) = _searchDistance ^ 2; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(timePerPylon), + "SLIDER", + [LSTRING(TimePerPylon), LSTRING(TimePerPylon_description)], + LSTRING(Category_Pylons), + [1, 10, 5, 0], + true +] call CBA_fnc_addSetting; diff --git a/addons/pylons/initSettings.sqf b/addons/pylons/initSettings.sqf deleted file mode 100644 index 57a2a79efb..0000000000 --- a/addons/pylons/initSettings.sqf +++ /dev/null @@ -1,66 +0,0 @@ -[ - QGVAR(enabledFromAmmoTrucks), - "CHECKBOX", - [LSTRING(EnabledFromAmmoTrucks), LSTRING(EnabledFromAmmoTrucks_description)], - LSTRING(Category_Pylons), - [true], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(enabledForZeus), - "CHECKBOX", - [LSTRING(EnabledForZeus), LSTRING(EnabledForZeus_description)], - LSTRING(Category_Pylons), - [true], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(rearmNewPylons), - "CHECKBOX", - [LSTRING(RearmNewPylons), LSTRING(RearmNewPylons_description)], - LSTRING(Category_Pylons), - [false], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(requireEngineer), - "CHECKBOX", - [LSTRING(RequireEngineer), LSTRING(RequireEngineer_description)], - LSTRING(Category_Pylons), - [false], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(requireToolkit), - "CHECKBOX", - [LSTRING(RequireToolkit), LSTRING(RequireToolkit_description)], - LSTRING(Category_Pylons), - [true], - true -] call CBA_Settings_fnc_init; - -[ - QGVAR(searchDistance), - "SLIDER", - [LSTRING(SearchDistance), LSTRING(SearchDistance_description)], - LSTRING(Category_Pylons), - [5, 50, 15, 0], - true, - { - params ["_searchDistance"]; - GVAR(searchDistanceSqr) = _searchDistance ^ 2; - } -] call CBA_Settings_fnc_init; - -[ - QGVAR(timePerPylon), - "SLIDER", - [LSTRING(TimePerPylon), LSTRING(TimePerPylon_description)], - LSTRING(Category_Pylons), - [1, 10, 5, 0], - true -] call CBA_Settings_fnc_init; diff --git a/addons/pylons/menu.hpp b/addons/pylons/menu.hpp index 85ca6b1c95..143792e566 100644 --- a/addons/pylons/menu.hpp +++ b/addons/pylons/menu.hpp @@ -23,143 +23,143 @@ class GVAR(DialogLoadout) { class TextTitlebar: RscText { idc = ID_TEXT_TITLEBAR; text = CSTRING(AircraftLoadoutTitle); - x = 0.15835 * safezoneW + safezoneX; - y = 0.262 * safezoneH + safezoneY; - w = 0.68304 * safezoneW; - h = 0.028 * safezoneH; + x = "0.15835 * safezoneW + safezoneX"; + y = "0.262 * safezoneH + safezoneY"; + w = "0.68304 * safezoneW"; + h = "0.028 * safezoneH"; colorBackground[] = {"(profileNamespace getVariable ['GUI_BCG_RGB_R', 0.13])","(profileNamespace getVariable ['GUI_BCG_RGB_G', 0.54])","(profileNamespace getVariable ['GUI_BCG_RGB_B', 0.21])",1}; }; class BackgroundDialog: IGUIBack { idc = ID_BACKGROUND_DIALOG; - x = 0.15835 * safezoneW + safezoneX; - y = 0.29 * safezoneH + safezoneY; - w = 0.68304 * safezoneW; - h = 0.448 * safezoneH; + x = "0.15835 * safezoneW + safezoneX"; + y = "0.29 * safezoneH + safezoneY"; + w = "0.68304 * safezoneW"; + h = "0.448 * safezoneH"; colorBackground[] = {0,0,0,0.3}; }; class BackgroundPicture: IGUIBack { idc = ID_BACKGROUND_PICTURE; - x = 0.171616 * safezoneW + safezoneX; - y = 0.318 * safezoneH + safezoneY; - w = 0.440035 * safezoneW; - h = 0.392 * safezoneH; + x = "0.171616 * safezoneW + safezoneX"; + y = "0.318 * safezoneH + safezoneY"; + w = "0.440035 * safezoneW"; + h = "0.392 * safezoneH"; colorBackground[] = {0.3,0.3,0.3,1}; }; class PictureAircraft: RscPictureKeepAspect { idc = ID_PICTURE_AIRCRAFT; - x = 0.171616 * safezoneW + safezoneX; - y = 0.318 * safezoneH + safezoneY; - w = 0.440035 * safezoneW; - h = 0.392 * safezoneH; + x = "0.171616 * safezoneW + safezoneX"; + y = "0.318 * safezoneH + safezoneY"; + w = "0.440035 * safezoneW"; + h = "0.392 * safezoneH"; }; class CheckboxMirror: RscCheckBox { idc = ID_CHECKBOX_MIRROR; - x = 0.171616 * safezoneW + safezoneX; - y = 0.318 * safezoneH + safezoneY; - w = 0.0165 * safezoneW; - h = 0.028 * safezoneH; + x = "0.171616 * safezoneW + safezoneX"; + y = "0.318 * safezoneH + safezoneY"; + w = "0.0165 * safezoneW"; + h = "0.028 * safezoneH"; }; class TextMirror: RscText { idc = ID_TEXT_MIRROR; text = "$STR_3DEN_Object_Attribute_PylonsMirror_displayName"; tooltip="$STR_3DEN_Object_Attribute_PylonsMirror_tooltip"; - x = 0.188116 * safezoneW + safezoneX; - y = 0.318 * safezoneH + safezoneY; - w = 0.0656768 * safezoneW; - h = 0.028 * safezoneH; + x = "0.188116 * safezoneW + safezoneX"; + y = "0.318 * safezoneH + safezoneY"; + w = "0.0656768 * safezoneW"; + h = "0.028 * safezoneH"; colorBackground[] = {0,0,0,0.5}; }; class CheckboxFRIES: RscCheckBox { idc = ID_CHECKBOX_FRIES; - x = 0.171616 * safezoneW + safezoneX; - y = 0.346 * safezoneH + safezoneY; - w = 0.0165 * safezoneW; - h = 0.028 * safezoneH; + x = "0.171616 * safezoneW + safezoneX"; + y = "0.346 * safezoneH + safezoneY"; + w = "0.0165 * safezoneW"; + h = "0.028 * safezoneH"; }; class TextFRIES: RscText { idc = ID_TEXT_FRIES; text = "FRIES"; - x = 0.188116 * safezoneW + safezoneX; - y = 0.346 * safezoneH + safezoneY; - w = 0.0656768 * safezoneW; - h = 0.028 * safezoneH; + x = "0.188116 * safezoneW + safezoneX"; + y = "0.346 * safezoneH + safezoneY"; + w = "0.0656768 * safezoneW"; + h = "0.028 * safezoneH"; colorBackground[] = {0,0,0,0.5}; }; class TextListTitle: RscText { idc = ID_TEXT_LISTTITLE; - x = 0.624786 * safezoneW + safezoneX; - y = 0.318 * safezoneH + safezoneY; - w = 0.203437 * safezoneW; - h = 0.028 * safezoneH; + x = "0.624786 * safezoneW + safezoneX"; + y = "0.318 * safezoneH + safezoneY"; + w = "0.203437 * safezoneW"; + h = "0.028 * safezoneH"; colorBackground[] = {0,0,0,0.5}; }; class ListLoadouts: RscListBox { idc = ID_LIST_LOADOUTS; - x = 0.624786 * safezoneW + safezoneX; - y = 0.346 * safezoneH + safezoneY; - w = 0.203437 * safezoneW; - h = 0.294 * safezoneH; + x = "0.624786 * safezoneW + safezoneX"; + y = "0.346 * safezoneH + safezoneY"; + w = "0.203437 * safezoneW"; + h = "0.294 * safezoneH"; }; class EditLoadoutName: RscEdit { idc = ID_EDIT_LOADOUTNAME; - x = 0.624786 * safezoneW + safezoneX; - y = 0.64 * safezoneH + safezoneY; - w = 0.203437 * safezoneW; - h = 0.028 * safezoneH; + x = "0.624786 * safezoneW + safezoneX"; + y = "0.64 * safezoneH + safezoneY"; + w = "0.203437 * safezoneW"; + h = "0.028 * safezoneH"; colorBackground[] = {0,0,0,0.7}; }; class ButtonSave: RscButtonMenu { idc = ID_BUTTON_SAVE; action = QUOTE(call FUNC(onButtonSave)); text = "$STR_disp_int_save"; - x = 0.624786 * safezoneW + safezoneX; - y = 0.682 * safezoneH + safezoneY; - w = 0.0590625 * safezoneW; - h = 0.028 * safezoneH; + x = "0.624786 * safezoneW + safezoneX"; + y = "0.682 * safezoneH + safezoneY"; + w = "0.0590625 * safezoneW"; + h = "0.028 * safezoneH"; }; class ButtonLoad: RscButtonMenu { idc = ID_BUTTON_LOAD; action = QUOTE(call FUNC(onButtonLoad)); text = "$STR_disp_int_load"; - x = 0.69703 * safezoneW + safezoneX; - y = 0.682 * safezoneH + safezoneY; - w = 0.0590625 * safezoneW; - h = 0.028 * safezoneH; + x = "0.69703 * safezoneW + safezoneX"; + y = "0.682 * safezoneH + safezoneY"; + w = "0.0590625 * safezoneW"; + h = "0.028 * safezoneH"; }; class ButtonDelete: RscButtonMenu { idc = ID_BUTTON_DELETE; action = QUOTE(call FUNC(onButtonDelete)); text = "$STR_disp_delete"; - x = 0.769275 * safezoneW + safezoneX; - y = 0.682 * safezoneH + safezoneY; - w = 0.0590625 * safezoneW; - h = 0.028 * safezoneH; + x = "0.769275 * safezoneW + safezoneX"; + y = "0.682 * safezoneH + safezoneY"; + w = "0.0590625 * safezoneW"; + h = "0.028 * safezoneH"; }; class ButtonApply: RscButtonMenu { idc = ID_BUTTON_APPLY; action = QUOTE(call FUNC(onButtonApply)); text = "$STR_ui_debug_but_apply"; - x = 0.683895 * safezoneW + safezoneX; - y = 0.738 * safezoneH + safezoneY; - w = 0.0721875 * safezoneW; - h = 0.028 * safezoneH; + x = "0.683895 * safezoneW + safezoneX"; + y = "0.738 * safezoneH + safezoneY"; + w = "0.0721875 * safezoneW"; + h = "0.028 * safezoneH"; }; class ButtonClose: RscButtonMenu { idc = ID_BUTTON_CLOSE; text = "$STR_disp_cancel"; action = QUOTE(call FUNC(onButtonClose)); - x = 0.769275 * safezoneW + safezoneX; - y = 0.738 * safezoneH + safezoneY; - w = 0.0721875 * safezoneW; - h = 0.028 * safezoneH; + x = "0.769275 * safezoneW + safezoneX"; + y = "0.738 * safezoneH + safezoneY"; + w = "0.0721875 * safezoneW"; + h = "0.028 * safezoneH"; }; class TextBanner: RscText { idc = ID_TEXT_BANNER; text = CSTRING(BannerText); - x = 0.171616 * safezoneW + safezoneX; - y = 0.738 * safezoneH + safezoneY; - w = 0.440035 * safezoneW; - h = 0.028 * safezoneH; + x = "0.171616 * safezoneW + safezoneX"; + y = "0.738 * safezoneH + safezoneY"; + w = "0.440035 * safezoneW"; + h = "0.028 * safezoneH"; colorBackground[] = {0.5,0,0,0.5}; }; }; diff --git a/addons/pylons/stringtable.xml b/addons/pylons/stringtable.xml index a24650d543..1021a2fc15 100644 --- a/addons/pylons/stringtable.xml +++ b/addons/pylons/stringtable.xml @@ -9,13 +9,16 @@ 飞机武器配置 항공기 무장 AUSRÜSTUNG DES FLUGGERÄTS - ÉQUIPEMENTS DE L'AÉRONEF + ÉQUIPEMENT DE L'AÉRONEF WYPOSAŻENIE POJAZDU POWIETRZNEGO СНАРЯЖЕНИЕ САМОЛЕТА + LOADOUT DA AERONAVE + VÝZBROJ LETADLA + ARMAMENTO DE AERONAVE Loadouts for %1 - %1の兵装 + %1 の兵装 Armamenti per %1 %1用的武裝配置 %1用的武器配置 @@ -24,6 +27,9 @@ Équipements pour %1 Wyposażenia dla %1 Оснащение %1 + Loadouts para %1 + Sady výzbroje pro %1 + Armamento para %1 Configure Pylons @@ -31,11 +37,14 @@ Configura Piloni 定義派龍架 设定导弹挂架 - 파일런 설정 + 무장창 설정 Konfiguriere Außenlaststationen Configurer les pylônes Konfiguruj Pylony Настройка Пилонов + Configurar Pylons + Nastavit pylony + Configurar pilones ACE Pylons @@ -43,11 +52,14 @@ ACE Piloni ACE 派龍架 ACE 导弹挂架 - ACE 파일런 + ACE 무장창 ACE Außenlaststationen ACE Pylônes - Pylony ACE + ACE Pylony ACE Пилоны + ACE Pylons + ACE Pylony + ACE Pilones <empty> @@ -60,6 +72,10 @@ <vide> <puste> <пусто> + <vazio> + <prázdné> + <boş> + <vacío> Pylons that are colored red will have to be manually rearmed. @@ -67,47 +83,59 @@ I piloni di colore rosso devono essere riarmati manualmente. 以紅色標記出的派龍架必須以手動方式進行彈藥整補 以红色标记出的导弹挂架必须以手动方式进行弹药整补。 - 붉은색의 파일런은 수동으로 재무장해야 합니다. + 붉은색의 무장창은 수동으로 재무장해야 합니다. 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. + Pylony označené červeně budou muset být manuálně přezbrojeny. + Pilones de color rojo deben ser rearmados manualmente. %1 is already configuring this aircraft! - %1はすでにこの機体へ設定されています! + %1 は すでにこの機体へ設定されています! % sta già configurando questo aereo! %1已經正在定義此飛機的武裝配置! - %1已经正在定义此飞机的武器配置! + %1已经正在定义此飞机的武器配置! 이미 이 항공기에 장착되어 있음 (%1) %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! + %1 už nastavuje výzbroj tohoto letadla! + %1 ya está configurando esta aeronave! Replacing pylon %1 out of %2... - パイロン%1を作業し残り%2・・・ + %2 個中 %1 番目のパイロンを交換しています・・・ Sostituendo pilone %1 al posto di %2... 共有%2個派龍架,正在整補%1號派龍架中... - 共有%2个发射架,正在整装%1号挂架中... + 共有%2个发射架,正在整装%1号挂架... 교체중 (%2 -> %1) Ersetze Außenlaststation %1 von insgesamt %2 - Remplacement du pylône %1 sur %2 ... + Remplacement du pylône %1 sur %2... Wymiana pylonów %1 z %2... Замена пилона %1 из %2... + Substituindo pylon %1 de %2... + Nahrazuji pylon %1 z %2... + Reemplazando pilón %1 de %2... Stopped at pylon %1! - パイロン%1で停止しました! + %1 番目のパイロンで中断しました! Fermato al pilone %1! 已停止在%1號派龍架! - 已停止在%1号挂架! - %1 파일런이 멈춤 + 已在整装%1号挂架时停止! + %1 무장창이 멈춤 Gestoppt bei Außenlaststation %1 Arrêté au pylône %1 ! Zatrzymano na pylonie %1! Остановлено на пилоне %1! + Parado no pylon %1! + Přerušeno na pylonu %1! + Parado en pilón %1! Vehicle too far @@ -117,75 +145,102 @@ 载具过远 車両が遠すぎます Fahrzeug zu weit entfernt - Véhicule trop éloigné + Véhicule trop éloigné. Pojazd za daleko Техника слишком далеко + Veículo muito longe + Vozidlo je příliš daleko + Vehículo demasiado alejado Enable Pylons Menu for Zeus 启用宙斯导弹挂架菜单 啟用派龍架選單給宙斯 Abilita Menù Piloni da Zeus - Zeus でパイロン メニューを有効化 + Zeusでパイロン メニューを有効化 Aktiviert Außenlaststationsmenü im Zeus Activer le menu des pylônes (Zeus) Aktywuj Menu Pylonów dla Zeus'a Активировать Меню пилонов для Зевса + Ativar Menu de Pylon para Zeus + Povolit menu s pylony pro Zeuse + Habilitar menú de pilones para Zeus + 제우스 무장창 메뉴 활성화 Enables use of the zeus module. 允许启用宙斯模组 允啟使用宙斯模塊 - Abilita l'uso dal modulo di Zeus - Zeus モジュールでパイロン メニューを利用できます。 + Abilita l'uso del modulo Zeus + Zeusモジュールでパイロン メニューを利用できるようにします。 Aktiviert die Nutzung im Zeus - Autorise l'utilisation des modules Zeus + Permet l'utilisation des modules Zeus. Aktywuj wykorzystanie modułu zeus'a. Позволяет использовать модуль Зевса + Permite usar o módulo de Zeus + Povoluje použití daného Zeus modulu. + Habilita el uso del módulo de Zeus. + 제우스 무장창 메뉴를 사용할 수 있게 합니다. Enable Pylons Menu from Ammo Trucks 启用弹药车导弹挂架菜单 啟用從彈藥卡車使用派龍架選單 - Abilita Menù Piloni da mezzi rifornimento munizioni + Abilita Menù Piloni da mezzi di rifornimento munizioni 弾薬トラックからパイロン メニューを有効化 Aktiviert Außenlaststationsmenü von Munitionstransportern - Activer le menu des pylônes (camion de munitions) + Activer le menu des pylônes (camions de munitions) Aktywuj Menu Pylonów dla Ciężarówek z amunicją Меню пилонов из грузовика боеприпасов + Ativar Menu de Pylons de Caminhões de Munição + Povolit menu s pylony z muničních náklaďáků. + Habilitar menú de pilones desde camiones de munición + 탄약 차량 무장창 메뉴 활성화 Enables use of pylons menu from ammo trucks. 允许在弹药车上启用导弹挂架菜单 允許從彈藥卡車使用派龍架選單 - Abilita l'uso del Menù Piloni da mezzi rifornimento munizioni + Abilita l'uso del Menù Piloni da mezzi di rifornimento munizioni 弾薬給弾トラックからパイロン メニューを利用できます。 Aktiviert die Nutzung von Außenlaststationsmenü von Munitionstransportern. - Autorise l'utilisation du menu des pylônes depuis les camions de munitions. + Permet l'utilisation du menu des pylônes à partir des camions de ravitaillement 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. + Povoluje použití menu na nastavení pylonů z náklaďáků s municí. + Habilita el uso del menú de pilones desde camiones de munición. + 탄약 차량에서 무장창 메뉴를 불러올 수 있게 합니다. This aircraft doesn't have pylons 这架飞机没有导弹挂架 這架飛機沒有派龍架 Questo aereo non ha piloni - 航空機にパイロンがありません + この航空機にはパイロンがありません Dieses Flugzeug hat keine Außenlaststationen - Cet aéronef n'a pas de pylônes + Cet aéronef n'a pas de pylônes. Ten pojazd nie posiada pylonów Эта авиатехника не имеет пилонов + Essa aeronave não possui pylons + Toto letadlo nemá pylony + Esta aeronave no tiene pilones + 이 비행기는 무장창이 없습니다. Configure pylons module is disabled for zeus 宙斯模组的导弹挂架已禁用 宙斯模塊的派龍架設定已被禁用 - Il modulo per configurare i piloni da Zeus è disabilitato - Zeus のパイロン モジュールを無効化 + Il modulo Zeus per configurare i piloni è disabilitato + Zeusのパイロン編集を無効化 Die Konfiguration für das Außenlaststationen ist im Zeus deaktiviert - La configuration de pylônes est désactivé pour Zeus + Le module de configuration des 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 + Nastavení pylonů je vypnuto pro Zeuse + La configuración del módulo de pilones está deshabilitada para Zeus + 제우스 무장창 모듈 설정이 비활성화 되어있습니다. Rearm New Pylons @@ -193,11 +248,14 @@ Riarma Nuovi Piloni 重新整装新的导弹挂架 重新武装新的派龙架 - 새파일런 재무장 + 새 무장창 재무장 Neue Außenlaststationen. aufmunitionieren Réarmer les nouveaux pylônes Dozbrój Nowe Pylony Перевооружать новые пилоны + Rearmar novos pylons + Přezbrojit nové pylony + Rearmar nuevos pilones Automatically rearm new pylons from the nearest rearm vehicle. @@ -205,35 +263,44 @@ Riarma automaticamente i nuovi piloni dal veicoli di riarmo più vicino. 自動從附近的整補載具中為派龍架進行彈藥整補 自动从附近的整装载具中为导弹挂架进行弹药整装。 - 근처의 재무장 차량에서 빈 파일런을 자동으로 재무장 합니다. + 근처의 재무장 차량에서 빈 무장창을 자동으로 재무장 합니다. 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. + Réarme automatiquement les nouveaux pylônes à partir du véhicule de ravitaillement 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 + Automaticky přezbrojit nové pylony z nejbližšího vozidla s municí. + Rearma automáticamente nuevos pilones desde el vehículo de rearme más cercano. Time Per Pylon - パイロンへの時間 + パイロンあたりの所要時間 Tempo Per Pilone 派龍架整補所需時間(個別) - 导弹挂架整装所需时间(个别) - 파일런당 시간 + 导弹挂架整装所需时间(个别) + 무장창 당 시간 Zeit pro Außenlaststation Durée par pylône Czas na Pylon Время на пилон + Tempo por pylon + Čas na pylon + Tiempo por pilón The time it takes to replace each pylon (in seconds). - 各パイロンの置き換えにかかる時間を設定します。(秒) + 各パイロンの置き換えに掛かる時間。 (秒単位) Il tempo che impiega ogni pilone ad essere sostituito (in secondi). 每個派龍架需花多久時間進行整補(單位為秒) - 每个挂架需花多久时间进行整装单位为秒)。 - 파일런을 재설정 하는데 걸리는 시간 (초) + 每个挂架需花多久时间进行整装(单位为秒)。 + 무장창을 재설정 하는데 걸리는 시간 (초) 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) + Udává čas jaký trvá nahrazení každého pylonu (ve vteřinách). + El tiempo que lleva reemplazar cada pilón (en segundos). Search Distance @@ -243,38 +310,47 @@ 搜索距离 검색 반경 Suchdistanz - Distance de recherche + Distance ravitaillement Dystans Szukania Дальность поиска + Distância de procura + Vzdálenost hledání munice + Distancia de búsqueda The distance an aircraft needs to be from a rearm vehicle. 航空機と補給車両との間に必要な距離です。 La distanza necessaria per un aereo da un veicolo di riarmo. 設定飛機必須距離整補載具多少公尺才能進行彈藥整補 - 设定飞机必须距离整装载具多少公尺才能进行弹药整装。 + 设定飞机必须距离整装载具多少米才能进行弹药整装。 항공기에서 재보급 가능한 재무장 차량을 찾습니다. 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. + La distance maximale à laquelle un aéronef doit se trouver du véhicule de ravitaillement. Dystans, w jakim pojazd musi być od pojazdu dozbrajania. Дальность от авиатехники до грузовика (пункта) с боеприпасами + A distância que a aeronave precisa estar de um veículo de munições. + Maximální vzdálenost ze které je možné letadlo přezbrojit s vozidlem s municí. + La distancia a la que debe estar una aeronave de un vehículo de rearme. Require Engineer 工兵の必須化 - Necessita Ingegnere + Necessita Geniere 需要工兵 必须是工兵 정비병 요구 Benötigt Pionier - Requiert ingénieur + Ingénieur requis Wymaga Mechanika Требуется Инженер + Requer um engenheiro + Vyžadovat Inženýra + Requerir Ingeniero Require an engineer. 工兵を必須とします。 - Necessita un ingegnere. + Necessita un Geniere. 需要工兵才能進行彈藥整補 必须是工兵才能进行弹药整装。 정비병이 필요합니다. @@ -282,30 +358,39 @@ Requiert un ingénieur. Wymaga mechanika. Требуется роль Инженера + É necessário uma unidade definida como engenheiro para interagir com pylons. + Vyžaduje, aby hráč byl Inženýr. + Requerir un Ingeniero. Require Toolkit ツールキットの必須化 - Necessita Kit Riparazione + Necessita Kit Utensili 需要工具包 需要工具包 - 툴킷 요구 + 도구모음 요구 Benötigt Werkzeugkasten - Requiert trousse à outils + Trousse à outils requise Wymaga Narzędzi Требуется Набор инструментов + Requer Kit de Ferramentas + Vyžadovat sadu nářadí (toolkit). + Requerir Kit de herramientas Require a toolkit in inventory. インベントリ内にツールキットの存在を必須とします。 - Necessita un kit di riparazione nell'inventario + Necessita un kit utensili nell'inventario 需要工具包才能進行彈藥整補 需要工具包才能进行弹药整装。 - 툴킷이 필요합니다. + 도구모음이 필요합니다. 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. + Vyžaduje, aby hráč měl ve svém inventáři sadu nářadí (toolkit). + Requiere un Kit de herramientas en el inventario diff --git a/addons/quickmount/CfgEventHandlers.hpp b/addons/quickmount/CfgEventHandlers.hpp index 9426fa861e..bff1c64e94 100644 --- a/addons/quickmount/CfgEventHandlers.hpp +++ b/addons/quickmount/CfgEventHandlers.hpp @@ -1,17 +1,17 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient)); }; }; diff --git a/addons/quickmount/CfgVehicles.hpp b/addons/quickmount/CfgVehicles.hpp index a0b54df48b..afab89565e 100644 --- a/addons/quickmount/CfgVehicles.hpp +++ b/addons/quickmount/CfgVehicles.hpp @@ -43,16 +43,16 @@ class CfgVehicles { condition = QUOTE(call DFUNC(canShowFreeSeats)); \ statement = QUOTE(call DFUNC(getInNearest)); \ exceptions[] = {"isNotSwimming"}; \ - insertChildren = QUOTE((_this select 2) param [ARR_2(0, [])]); \ + insertChildren = QUOTE((_this select 2) param [ARR_2(0,[])]); \ }; \ }; \ }; \ class ACE_SelfActions { \ class GVAR(ChangeSeat) { \ displayName = CSTRING(ChangeSeat); \ + icon = QPATHTOF(UI\Seats_ca.paa); \ condition = QUOTE(call DFUNC(canShowFreeSeats)); \ - statement = ""; \ - insertChildren = QUOTE((_this select 2) param [ARR_2(0, [])]); \ + insertChildren = QUOTE(call DFUNC(addFreeSeatsActions)); \ }; \ } diff --git a/addons/quickmount/README.md b/addons/quickmount/README.md index 6e11fc8ae4..5b2a69f303 100644 --- a/addons/quickmount/README.md +++ b/addons/quickmount/README.md @@ -2,8 +2,3 @@ ace_quickmount ============ Adds a keybind to quickly enter the vehicle you are directly looking at. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Kingsley](https://github.com/jameslkingsley) diff --git a/addons/quickmount/UI/Seats_ca.paa b/addons/quickmount/UI/Seats_ca.paa new file mode 100644 index 0000000000..8e4678d5ca Binary files /dev/null and b/addons/quickmount/UI/Seats_ca.paa differ diff --git a/addons/quickmount/XEH_preInit.sqf b/addons/quickmount/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/quickmount/XEH_preInit.sqf +++ b/addons/quickmount/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/quickmount/config.cpp b/addons/quickmount/config.cpp index 063897aebc..d74d99c050 100644 --- a/addons/quickmount/config.cpp +++ b/addons/quickmount/config.cpp @@ -5,7 +5,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); authors[] = {"Kingsley"}; url = ECSTRING(main,URL); diff --git a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf index b49525d406..c1318e3f74 100644 --- a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf +++ b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Creates actions for vehicle free seats. @@ -29,21 +29,22 @@ #define TO_COMPARTMENT_STRING(var) if !(var isEqualType "") then {var = format [ARR_2("Compartment%1",var)]} // if unit isn't moved to new seat in TAKEN_SEAT_TIMEOUT, we move him back to his seat +#pragma hemtt suppress pw3_padded_arg file #define WAIT_IN_OR_MOVE_BACK \ [ARR_5( \ {!isNull objectParent (_this select 0)}, \ { \ - params [ARR_2("_player","_damageBlocked")]; \ - if (_damageBlocked) then {_player allowDamage true}; \ - LOG_1("moved in in %1 frames",diag_frameno-GVAR(frame)); \ + LOG_1("moved in after %1 frames",diag_frameno-GVAR(frame)); \ + (_this select 0) enableSimulation true; \ }, \ - [ARR_4(_player,_damageBlocked,_moveBackCode,_moveBackParams)], \ + [ARR_3(_player,_moveBackCode,_moveBackParams)], \ TAKEN_SEAT_TIMEOUT, \ { \ - params [ARR_4("_player","_damageBlocked","_moveBackCode","_moveBackParams")]; \ + params [ARR_3("_player","_moveBackCode","_moveBackParams")]; \ + WARNING_1("failed move in after %1 frames",diag_frameno-GVAR(frame)); \ [ARR_2(_player,_moveBackParams)] call _moveBackCode; \ - if (_damageBlocked) then {_player allowDamage true}; \ localize "str_mis_state_failed" call EFUNC(common,displayTextStructured); \ + _player enableSimulation true; \ } \ )] call CBA_fnc_waitUntilAndExecute; @@ -59,21 +60,13 @@ #define MOVE_IN_CODE(command) (_this select 0) command (_this select 1) private _fnc_move = { - (_this select 2) params ["_moveInCode", "_moveInParams", "_currentTurret", "_moveBackCode", "_moveBackParams", ["_enabledByAnimationSource", ""]]; - TRACE_7("fnc_move params",_moveInCode,_moveInParams,_currentTurret,_moveBackCode,_moveBackParams,_enabledByAnimationSource,call {GVAR(frame)=diag_frameno}); - - // check bugged FFV - if ( - !("" isEqualTo _enabledByAnimationSource) - && {1 > _target doorPhase _enabledByAnimationSource} - ) exitWith {}; + (_this select 2) params ["_moveInCode", "_moveInParams", "_currentTurret", "_moveBackCode", "_moveBackParams"]; + TRACE_6("fnc_move params",_moveInCode,_moveInParams,_currentTurret,_moveBackCode,_moveBackParams,call {GVAR(frame)=diag_frameno}); // workaround getting damage when moveOut while vehicle is moving - private _damageBlocked = false; - if (isDamageAllowed _player) then { - _player allowDamage false; - _damageBlocked = true; - }; + // also this helps with arma bug when unit is stuck in wrong anim when move in turret with configured enabledByAnimationSource + _player enableSimulation false; + private _preserveEngineOn = _player == driver _target && {isEngineOn _target}; moveOut _player; if (_preserveEngineOn) then {_target engineOn true}; @@ -89,12 +82,12 @@ private _fnc_move = { [ {params ["_target", "_player", "_currentTurret"]; IS_MOVED_OUT}, { - params ["", "_player", "", "_moveInCode", "_moveInParams", "_moveBackCode", "_moveBackParams", "_damageBlocked"]; - LOG_2("moved out in %1 frames",diag_frameno-GVAR(frame),call {GVAR(frame)=diag_frameno; 0}); + params ["", "_player", "", "_moveInCode", "_moveInParams", "_moveBackCode", "_moveBackParams"]; + LOG_2("moved out after %1 frames",diag_frameno-GVAR(frame),call {GVAR(frame)=diag_frameno; 0}); [_player, _moveInParams] call _moveInCode; WAIT_IN_OR_MOVE_BACK; }, - [_target, _player, _currentTurret, _moveInCode, _moveInParams, _moveBackCode, _moveBackParams, _damageBlocked] + [_target, _player, _currentTurret, _moveInCode, _moveInParams, _moveBackCode, _moveBackParams] ] call CBA_fnc_waitUntilAndExecute; }; @@ -102,7 +95,7 @@ scopeName "main"; params ["_vehicle", "_player"]; -private _vehicleConfig = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _vehicleConfig = configOf _vehicle; private _isInVehicle = _player in _vehicle; private _fullCrew = fullCrew [_vehicle, "", true]; @@ -166,7 +159,7 @@ private _cargoNumber = -1; }; } else { private ["_name", "_icon", "_statement", "_params"]; - switch (toLower _role) do { + switch (toLowerANSI _role) do { case "driver": { if ( lockedDriver _vehicle @@ -216,13 +209,7 @@ private _cargoNumber = -1; private _gunnerCompartments = (_turretConfig >> "gunnerCompartments") call BIS_fnc_getCfgData; TO_COMPARTMENT_STRING(_gunnerCompartments); if (_compartment != _gunnerCompartments) then {breakTo "crewLoop"}; - // due to arma bug the unit is stuck in wrong anim when move in turret with configured enabledByAnimationSource - private _enabledByAnimationSource = getText (_turretConfig >> "enabledByAnimationSource"); - if ( - !("" isEqualTo _enabledByAnimationSource) - && {1 > _vehicle doorPhase _enabledByAnimationSource} - ) then {breakTo "crewLoop"}; - _params = [{MOVE_IN_CODE(moveInTurret)}, [_vehicle, _turretPath], _currentTurret, _moveBackCode, _moveBackParams, _enabledByAnimationSource]; + _params = [{MOVE_IN_CODE(moveInTurret)}, [_vehicle, _turretPath], _currentTurret, _moveBackCode, _moveBackParams]; _statement = _fnc_move; }; _name = getText (_turretConfig >> "gunnerName"); diff --git a/addons/quickmount/functions/fnc_canShowFreeSeats.sqf b/addons/quickmount/functions/fnc_canShowFreeSeats.sqf index ac146a8c57..6812d9bf83 100644 --- a/addons/quickmount/functions/fnc_canShowFreeSeats.sqf +++ b/addons/quickmount/functions/fnc_canShowFreeSeats.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Checks if Free Seats menu can be shown. @@ -19,7 +19,6 @@ params ["_vehicle", "_unit", "_args"]; -_args set [0, []]; private _isInVehicle = _unit in _vehicle; GVAR(enabled) @@ -30,16 +29,22 @@ GVAR(enabled) } && {alive _vehicle} && {2 > locked _vehicle} +&& {isNull getConnectedUAVUnit _unit} +&& {simulationEnabled _vehicle} && { - -1 == crew _vehicle findIf {alive _x} - || {0.6 <= side group _unit getFriend side group _vehicle} + [_unit, _vehicle] call EFUNC(interaction,canInteractWithVehicleCrew) } && { 0.3 < vectorUp _vehicle select 2 // moveIn* and GetIn* don't work for flipped vehicles || {_vehicle isKindOf "Air"} // except Air } && { - private _subActions = _this call FUNC(addFreeSeatsActions); - _args set [0, _subActions]; - !([] isEqualTo _subActions) + _isInVehicle + || { + // because Get In action has its own statement + // we have to cache subactions in args and reuse them in insertChildren code + private _subActions = _this call FUNC(addFreeSeatsActions); + _args set [0, _subActions]; + [] isNotEqualTo _subActions + } } diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index b94ba8f0d9..5e6c21eb36 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Kingsley * Mount the player in the vehicle they are directly looking at based on their distance. @@ -25,7 +25,7 @@ if (!GVAR(enabled) || params [["_interactionTarget", objNull, [objNull]]]; TRACE_1("getInNearest",_interactionTarget); -private _start = AGLtoASL (ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot")); +private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; private _target = (_objects param [0, []]) param [2, objNull]; @@ -37,7 +37,7 @@ if ((isNull _target) && {alive _interactionTarget}) then { _target = (_objects param [0, []]) param [2, objNull]; }; -if (locked _target in [2,3]) exitWith { +if (locked _target in [2,3] || {!simulationEnabled _target}) exitWith { [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); true }; @@ -69,15 +69,15 @@ if (!isNull _target && { _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; if ((isNull _unit) || {!alive _unit}) then { - private _effectiveRole = toLower _role; + private _effectiveRole = toLowerANSI _role; if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner - if ((_effectiveRole == "driver") && {(getNumber (([_target] call CBA_fnc_getObjectConfig) >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) + if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) // Seats can be locked independently of the main vehicle if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; - if ((!(_turretPath isEqualTo [])) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; + if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; if (_effectiveRole == "turret") then { private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; @@ -95,7 +95,7 @@ if (!isNull _target && TRACE_2("",_effectiveRole,_x); if (_effectiveRole != _desiredRole) exitWith {}; - if (!(_turretPath isEqualTo [])) then { + if (_turretPath isNotEqualTo []) then { // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander ACE_player action ["GetInTurret", _target, _turretPath]; TRACE_3("Geting In Turret",_x,_role,_turretPath); diff --git a/addons/quickmount/functions/fnc_moduleInit.sqf b/addons/quickmount/functions/fnc_moduleInit.sqf index 216cda90c0..8544226a32 100644 --- a/addons/quickmount/functions/fnc_moduleInit.sqf +++ b/addons/quickmount/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Kingsley * Initializes the quick-mount module. diff --git a/addons/quickmount/functions/script_component.hpp b/addons/quickmount/functions/script_component.hpp deleted file mode 100644 index a91c3e1665..0000000000 --- a/addons/quickmount/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\quickmount\script_component.hpp" diff --git a/addons/quickmount/initSettings.inc.sqf b/addons/quickmount/initSettings.inc.sqf new file mode 100644 index 0000000000..88fa78bd64 --- /dev/null +++ b/addons/quickmount/initSettings.inc.sqf @@ -0,0 +1,52 @@ +[ + QGVAR(enabled), + "CHECKBOX", + [ELSTRING(common,Enabled), LSTRING(EnabledDescription)], + format ["ACE %1", LLSTRING(Category)], + true, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(distance), + "SLIDER", + [LSTRING(Distance), LSTRING(DistanceDescription)], + format ["ACE %1", LLSTRING(Category)], + [0, 10, DEFAULT_DISTANCE, 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(speed), + "SLIDER", + [LSTRING(Speed), LSTRING(SpeedDescription)], + format ["ACE %1", LLSTRING(Category)], + [0, 30, DEFAULT_SPEED, 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(priority), + "LIST", + [LSTRING(Priority), LSTRING(PriorityDescription)], + format ["ACE %1", LLSTRING(Category)], + [[0, 1, 2, 3], ["str_getin_pos_driver", "str_getin_pos_gunn", "str_getin_pos_comm", "str_getin_pos_passenger"], DEFAULT_PRIORITY], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(enableMenu), + "LIST", + ELSTRING(interact_menu,Category_InteractionMenu), + format ["ACE %1", LLSTRING(Category)], + [ + [0,1,2,3], + [ + "STR_A3_None", + "STR_rscMenu.hppRscGroupRootMenu_Items_GetIn1", + LSTRING(ChangeSeat), + "str_word_all" + ], + 3 + ] +] call CBA_fnc_addSetting; diff --git a/addons/quickmount/initSettings.sqf b/addons/quickmount/initSettings.sqf deleted file mode 100644 index f213357167..0000000000 --- a/addons/quickmount/initSettings.sqf +++ /dev/null @@ -1,52 +0,0 @@ -[ - QGVAR(enabled), - "CHECKBOX", - ELSTRING(common,Enabled), - format ["ACE %1", LLSTRING(Category)], - true, - true -] call CBA_settings_fnc_init; - -[ - QGVAR(distance), - "SLIDER", - [LSTRING(Distance), LSTRING(DistanceDescription)], - format ["ACE %1", LLSTRING(Category)], - [0, 10, DEFAULT_DISTANCE, 0], - true -] call CBA_settings_fnc_init; - -[ - QGVAR(speed), - "SLIDER", - [LSTRING(Speed), LSTRING(SpeedDescription)], - format ["ACE %1", LLSTRING(Category)], - [0, 30, DEFAULT_SPEED, 0], - true -] call CBA_settings_fnc_init; - -[ - QGVAR(priority), - "LIST", - [LSTRING(Priority), LSTRING(PriorityDescription)], - format ["ACE %1", LLSTRING(Category)], - [[0, 1, 2, 3], ["str_getin_pos_driver", "str_getin_pos_gunn", "str_getin_pos_comm", "str_getin_pos_passenger"], DEFAULT_PRIORITY], - false -] call CBA_settings_fnc_init; - -[ - QGVAR(enableMenu), - "LIST", - ELSTRING(interact_menu,Category_InteractionMenu), - format ["ACE %1", LLSTRING(Category)], - [ - [0,1,2,3], - [ - "STR_A3_None", - "STR_rscMenu.hppRscGroupRootMenu_Items_GetIn1", - LSTRING(ChangeSeat), - "str_word_all" - ], - 3 - ] -] call CBA_settings_fnc_init; diff --git a/addons/quickmount/stringtable.xml b/addons/quickmount/stringtable.xml index e6496fd86a..3ebff2f7d2 100644 --- a/addons/quickmount/stringtable.xml +++ b/addons/quickmount/stringtable.xml @@ -11,6 +11,10 @@ Szybkie wsiadanie 빠른 탑승 Быстрая посадка + Entrada Rápida + Entrée rapide + Rychlé nastoupení + Entrada rápida Vehicle quick mount @@ -22,6 +26,10 @@ 快速搭乘載具 빠른 차량 탑승 Быстрая посадка в технику + Entrada Rápida em Veículo + Entrée rapide véhicules + Rychlé nastoupení do vozidla + Entrada rápida vehículo Quickly enter the vehicle you are directly looking at. @@ -33,6 +41,11 @@ Szybko wsiądź do pojazdu, na który patrzysz. 빠르게 당신이 보고 있는 가까운 차량에 탑승합니다. Позволяет быстро сесть в технику, на которую вы смотрите + Rapidamente entra no veículo que você está olhando diretamente. + Permet d'entrer rapidement dans le véhicule que vous regardez. + Rychle nastoupit do vozidla na které se díváte. + Doğrudan bakmakta olduğunuz araca hızla girin. + Entrar rápidamente al vehículo al que estás mirando Vehicle Full @@ -42,8 +55,29 @@ 载具已满 載具已滿 Pojazd pełny - 만차 + 차량이 꽉 찼습니다 Мест нет + Veículo cheio + Véhicule plein + Vozidlo je plné + Araç Dolu + Vehículo completo + + + This option allows quick entry into the vehicle you are directly looking at. + Cette option permet d'entrer rapidement dans les véhicules que vous regardez. + 這個選項允許你能快速進入你直視的載具 + 这个选项允许你能快速进入你直视的载具 + Ta opcja umożliwia szybkie wsiadanie do pojazdu na który patrzysz. + Esta opção permite entrada rápida para o veículo que você está olhando + この機能により直接見ている車両へすぐさま搭乗できます。 + Questa opzione permette l'entrata rapida nel veicolo che si sta guardando. + Bu seçenek, doğrudan bakmakta olduğunuz araca hızlı giriş sağlar. + Tato možnost umožňuje rychle nastoupit do vozidla na které se díváte. + Эта опция разрешает быстро залезть в транспорт, на который вы смотрите. + Esta opción permite entrar rápidamente al vehículo al que estás mirando + Diese Option erlaubt es, schnell in das Fahrzeug, auf das der Spieler gerade zeigt, einzusteigen. + 보고 있는 차량에 신속히 탑승하게 합니다. Distance @@ -55,17 +89,27 @@ Odległość 거리 Дистанция + Distância + Distance + Vzdálenost + Mesafe + Distancia Maximum distance to check for vehicles. Maximale Entfernung zu Fahrzeugen - Distanza massima per controllare i veicoli. - 車両を確認できる最大距離 - 最大可检查载具的距离. + Distanza massima da controllare per presenza di veicoli. + 車両を検知できる最大距離を設定します。 + 最大可检查载具的距离。 最大可檢查載具的距離 Maksymalna odległość do pojazdu. 탑승 가능한 차량과의 거리 Максимальная дистанция для техники + Distância máxima para checar por veículos. + Distance de vérification maximale des véhicules. + Maximální vzdálenost od vozidel. + Araçların kontrol edilmesi için maksimum mesafe. + Distancia máxima para comprobar vehículos Vehicle Locked @@ -77,28 +121,43 @@ Pojazd zablokowany 차량 잠김 Техника закрыта + Veículo Trancado + Véhicule verrouillé + Vozidlo je zamčeno + Araç Kilitli + Vehículo bloqueado Maximum Speed (km/h) Maximale Geschwindigkeit (km/h) Velocità Massima (km/h) 最高速度 (km/h) - 最高速度 (公里/小时) + 最高速度(km/h) 最高速度 (公里/小時) Maksymalna prędkość (km/h) 최대 속도 (km/h) Макс. скорость (км/ч) + Velocidade Máxima (km/h) + Vitesse maximale (km/h) + Maximální rychlost (km/h) + Yüksek Hız (km/h) + Velocidad máxima (km/h) Maximum vehicle speed (km/h) allowed for player entry - Maximale Geschwindigkeit (km/h) für Schnellzugang + Maximale erlaubte Geschwindigkeit (km/h) für Schnellzugang Velocità massima del veicolo (km/h) consentita per far salire un giocatore - プレイヤーが搭乗できる限界速度 (km/h) + プレイヤーが搭乗できる最高速度 (km/h) を設定します。 设置玩家能在最高速度是多少的情况之下进入载具。 設置玩家能在最高多少的速度之下進入載具 Maksymalna prędkość pojazdu (km/h) pozwalająca graczowi wsiąść. 플레이어가 탑승 가능한 목표 차량의 최대 속도 Макс. скорость техники для посадки игрока (км/ч) + Velocidade máxima que o veículo pode estar para permitir entrada rápida. + Définit la vitesse maximale que peut avoir un véhicule en mouvement pour qu'un joueur réussisse à y entrer. + Maximální rychlost vozidla (km/h) při které hráči mohou nastoupit do vozidla + Oyuncu binmesi için izin verilen maksimum araç hızı (km / s) + Máxima velocidad del vehículo (km/h) para permitir la entrada de jugadores Prioritize Seat @@ -110,17 +169,27 @@ Priorytet zajmowanych pozycji 좌석 우선순위 지정 Приоритет мест + Priorizar Assento + Place prioritaire + Priorita sedadel + Koltuğa Öncelik Ver + Asiento prioritario Seat priority on entry Priorisierter Sitzplatz zum Schnellzugang Priorità del sedile in entrata - 搭乗時の優先順位 + 搭乗時の優先順位をします。 优先想进入哪个位置。 優先想進入哪個座位 Priorytet pozycji w pojeździe 탑승할 좌석의 우선순위를 지정합니다. Приоритет мест при посадке + Define qual o assento que vai priorizar a Entrada Rápida + Définit à quel poste s'asseoir en priorité lors de l'embarquement. + Priorita sedadla při nástupu + Araça binerken koltuk önceliği + Asiento prioritario en entrada Change seat @@ -129,6 +198,14 @@ 席の変更 Zmień zajmowaną pozycję Cambia posto + Mudar de Assento + 換座位 + 换座位 + Changer de place + Změnit sedadlo + Koltuk Değiştir + Cambiar asiento + 좌석 변경 diff --git a/addons/rangecard/CfgEventHandlers.hpp b/addons/rangecard/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/rangecard/CfgEventHandlers.hpp +++ b/addons/rangecard/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/rangecard/CfgVehicles.hpp b/addons/rangecard/CfgVehicles.hpp index 5974e62e69..ef54c49428 100644 --- a/addons/rangecard/CfgVehicles.hpp +++ b/addons/rangecard/CfgVehicles.hpp @@ -20,14 +20,14 @@ class CfgVehicles { statement = QUOTE(false call FUNC(openRangeCard)); showDisabled = 0; icon = QPATHTOF(UI\RangeCard_Icon.paa); - exceptions[] = {"notOnMap"}; + exceptions[] = {"notOnMap", "isNotInside"}; class GVAR(openCopy) { displayName = CSTRING(OpenRangeCardCopy); condition = QUOTE(call FUNC(canShowCopy) && !GVAR(RangeCardOpened)); statement = QUOTE(true call FUNC(openRangeCard)); showDisabled = 0; icon = QPATHTOF(UI\RangeCard_Icon.paa); - exceptions[] = {"notOnMap"}; + exceptions[] = {"notOnMap", "isNotInside"}; }; class GVAR(makeCopy) { displayName = CSTRING(CopyRangeCard); @@ -35,7 +35,7 @@ class CfgVehicles { statement = QUOTE(GVAR(zeroRangeCopy)=GVAR(zeroRange); GVAR(boreHeightCopy)=GVAR(boreHeight); GVAR(ammoClassCopy)=GVAR(ammoClass); GVAR(magazineClassCopy)=GVAR(magazineClass); GVAR(weaponClassCopy)=GVAR(weaponClass);); showDisabled = 0; icon = QPATHTOF(UI\RangeCard_Icon.paa); - exceptions[] = {"notOnMap"}; + exceptions[] = {"notOnMap", "isNotInside"}; }; }; }; diff --git a/addons/rangecard/CfgWeapons.hpp b/addons/rangecard/CfgWeapons.hpp index 659b0ecfcb..cb55b0dcac 100644 --- a/addons/rangecard/CfgWeapons.hpp +++ b/addons/rangecard/CfgWeapons.hpp @@ -11,9 +11,10 @@ class CfgWeapons { picture = QPATHTOF(UI\RangeCard_Icon.paa); icon = "iconObject_circle"; mapSize = 0.034; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.1; }; }; }; diff --git a/addons/rangecard/README.md b/addons/rangecard/README.md index 94169a3075..26046fc79a 100644 --- a/addons/rangecard/README.md +++ b/addons/rangecard/README.md @@ -2,10 +2,3 @@ ace_rangecards =============== Adds range cards. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/rangecard/RscTitles.hpp b/addons/rangecard/RscTitles.hpp index 8a2007b2b2..720f724be4 100644 --- a/addons/rangecard/RscTitles.hpp +++ b/addons/rangecard/RscTitles.hpp @@ -54,7 +54,7 @@ class RangeCard_RscListNBox: RscListNBox { colorDisabled[]={1,1,1,0.3}; }; - class ListScrollBar : ScrollBar { + class ListScrollBar: ScrollBar { }; }; @@ -147,7 +147,7 @@ class ACE_RangeCard_Dialog { y="safezoneY+0.181889+0.091"; w="0.25*1.62727*3/4"; h="0.0909445"; - columns[]={(0.03/2), (0.985/2)}; + columns[]={"0.03/2", "0.985/2"}; idcLeft=770101; idcRight=770102; }; @@ -157,7 +157,7 @@ class ACE_RangeCard_Dialog { y="safezoneY+0.181889+0.125"; w="0.405*1.62727*3/4"; h="0.0909445"; - columns[]={(0/9), (1/9), (2/9), (3/9), (4/9), (5/9), (5.9/9), (6.9/9), (7.8/9)}; + columns[]={"0/9", "1/9", "2/9", "3/9", "4/9", "5/9", "5.9/9", "6.9/9", "7.8/9"}; idcLeft=770201; idcRight=770202; }; @@ -167,7 +167,7 @@ class ACE_RangeCard_Dialog { y="safezoneY+0.181889+0.15"; w="0.25*1.62727*3/4"; h="0.0909445"; - columns[]={(0/6), (0.9/6), (1.8/6), (2.9/6), (3.8/6), (4.8/6)}; + columns[]={"0/6", "0.9/6", "1.8/6", "2.9/6", "3.8/6", "4.8/6"}; idcLeft=770301; idcRight=770302; }; @@ -177,8 +177,8 @@ class ACE_RangeCard_Dialog { y="safezoneY+0.181889+0.194"; w="0.72*1.62727*3/4"; h="1.62727"; - columns[]={(0/16), (1.2/16), (2.2/16), (3.2/16), (4.2/16), (5.1/16), (6.1/16), (7.1/16), (8.1/16), - (9/16), (10.2/16), (11/16), (11.9/16), (12.8/16), (13.7/16), (14.6/16)}; + columns[]={"0/16", "1.2/16", "2.2/16", "3.2/16", "4.2/16", "5.1/16", "6.1/16", "7.1/16", "8.1/16", + "9/16", "10.2/16", "11/16", "11.9/16", "12.8/16", "13.7/16", "14.6/16"}; idcLeft=770401; idcRight=770402; }; diff --git a/addons/rangecard/XEH_postInit.sqf b/addons/rangecard/XEH_postInit.sqf index 9e60821fc1..af4dfa923c 100644 --- a/addons/rangecard/XEH_postInit.sqf +++ b/addons/rangecard/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" - GVAR(RangeCardOpened) = false; GVAR(controls) = []; @@ -17,3 +15,7 @@ GVAR(boreHeightCopy) = 3.81; GVAR(ammoClassCopy) = "";//"ACE_762x51_Ball_M118LR"; GVAR(magazineClassCopy) = "";//"ACE_20Rnd_762x51_M118LR_Mag"; GVAR(weaponClassCopy) = "";//srifle_DMR_06_olive_F"; + +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" diff --git a/addons/rangecard/functions/fnc_calculateRangeCard.sqf b/addons/rangecard/functions/fnc_calculateRangeCard.sqf index ebeadf6b7e..d2347b8494 100644 --- a/addons/rangecard/functions/fnc_calculateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_calculateRangeCard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the range card data @@ -49,7 +49,8 @@ private _bulletSpeed = 0; private _gravity = [0, sin(_scopeBaseAngle) * -GRAVITY, cos(_scopeBaseAngle) * -GRAVITY]; private _deltaT = 1 / _simSteps; private _speedOfSound = 0; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { +private _isABenabled = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; +if (_isABenabled) then { _speedOfSound = _temperature call EFUNC(weather,calculateSpeedOfSound); }; @@ -68,7 +69,7 @@ if (_useABConfig) then { }; private _airFrictionCoef = 1; -if (!_useABConfig && (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { +if (!_useABConfig && _isABenabled) then { private _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); _airFrictionCoef = _airDensity / 1.22498; }; diff --git a/addons/rangecard/functions/fnc_canCopy.sqf b/addons/rangecard/functions/fnc_canCopy.sqf index ee85bcf096..6600cd5fca 100644 --- a/addons/rangecard/functions/fnc_canCopy.sqf +++ b/addons/rangecard/functions/fnc_canCopy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Checks if the target has a copyable range card diff --git a/addons/rangecard/functions/fnc_canShow.sqf b/addons/rangecard/functions/fnc_canShow.sqf index 6b3cf6997a..8917cf80f1 100644 --- a/addons/rangecard/functions/fnc_canShow.sqf +++ b/addons/rangecard/functions/fnc_canShow.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Tests if the Range Card can be shown @@ -15,4 +15,8 @@ * Public: No */ -(GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "" && !GVAR(RangeCardOpened) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player))) +GVAR(ammoClass) != "" && +GVAR(magazineClass) != "" && +GVAR(weaponClass) != "" && +!GVAR(RangeCardOpened) && +"ACE_RangeCard" in ([ACE_player] call EFUNC(common,uniqueItems)) diff --git a/addons/rangecard/functions/fnc_canShowCopy.sqf b/addons/rangecard/functions/fnc_canShowCopy.sqf index e4eb28b60b..7ede55823d 100644 --- a/addons/rangecard/functions/fnc_canShowCopy.sqf +++ b/addons/rangecard/functions/fnc_canShowCopy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Tests if the Range Card copy can be shown @@ -15,4 +15,8 @@ * Public: No */ -(GVAR(ammoClassCopy) != "" && GVAR(magazineClassCopy) != "" && GVAR(weaponClassCopy) != "" && !GVAR(RangeCardOpened) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player))) +GVAR(ammoClassCopy) != "" && +GVAR(magazineClassCopy) != "" && +GVAR(weaponClassCopy) != "" && +!GVAR(RangeCardOpened) && +"ACE_RangeCard" in ([ACE_player] call EFUNC(common,uniqueItems)) diff --git a/addons/rangecard/functions/fnc_onCloseDialog.sqf b/addons/rangecard/functions/fnc_onCloseDialog.sqf index 0a93eb897c..3a50f55a82 100644 --- a/addons/rangecard/functions/fnc_onCloseDialog.sqf +++ b/addons/rangecard/functions/fnc_onCloseDialog.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: joko // Jonas * Add the Reserve Parachute to Units or Save Backpack if is a Parachute in Unit diff --git a/addons/rangecard/functions/fnc_openRangeCard.sqf b/addons/rangecard/functions/fnc_openRangeCard.sqf index ed2bb9e241..be1cb821a9 100644 --- a/addons/rangecard/functions/fnc_openRangeCard.sqf +++ b/addons/rangecard/functions/fnc_openRangeCard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Opens the range card dialog diff --git a/addons/rangecard/functions/fnc_updateClassNames.sqf b/addons/rangecard/functions/fnc_updateClassNames.sqf index e13198bcfc..d0a9bbdc32 100644 --- a/addons/rangecard/functions/fnc_updateClassNames.sqf +++ b/addons/rangecard/functions/fnc_updateClassNames.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Updates the ammo and weapon class names diff --git a/addons/rangecard/functions/fnc_updateRangeCard.sqf b/addons/rangecard/functions/fnc_updateRangeCard.sqf index 9fc2c9ebab..c2c8673844 100644 --- a/addons/rangecard/functions/fnc_updateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_updateRangeCard.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Authors: Ruthberg * Updates the range card data @@ -14,7 +14,7 @@ * None * * Example: - * [1, 2, "ammo", "magazine", "weapon"] call ace_rangecard_fnc_openRangeCard + * [1, 2, "ammo", "magazine", "weapon"] call ace_rangecard_fnc_updateRangeCard * * Public: No */ @@ -33,7 +33,7 @@ if (_ammoClass == "" || _magazineClass == "" || _weaponClass == "") exitWith {}; GVAR(controls) = []; for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 790000 + _row]); _control ctrlSetPosition [safeZoneX + 0.183, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.062, 0.025]; if (_row in [0, 8, 18, 28, 38, 48]) then { @@ -47,7 +47,7 @@ for "_row" from 0 to 49 do { }; for "_column" from 0 to 8 do { for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + _column * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.249 + _column * 0.055, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.052, 0.025]; _control ctrlCommit 0; @@ -57,7 +57,7 @@ for "_column" from 0 to 8 do { }; for "_column" from 0 to 2 do { for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (9 +_column) * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.743 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025]; _control ctrlCommit 0; @@ -67,7 +67,7 @@ for "_column" from 0 to 2 do { }; for "_column" from 0 to 2 do { for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (12 +_column) * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.892 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025]; _control ctrlCommit 0; @@ -100,19 +100,24 @@ private _barrelLength = _weaponConfig select 2; private _muzzleVelocity = 0; private _bc = 0; -if (count (_ammoConfig select 6) > 0) then { +if ((_ammoConfig select 6) isNotEqualTo []) then { _bc = (_ammoConfig select 6) select 0; }; private _transonicStabilityCoef = _ammoConfig select 4; private _dragModel = _ammoConfig select 5; private _atmosphereModel = _ammoConfig select 8; -private _useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]); -if (_bc == 0) then { - _useABConfig = false; -}; +private _isABenabled = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bc != 0); +private _useBarrelLengthInfluence = ( + _isABenabled && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} +); +private _useAmmoTemperatureInfluence = ( + _isABenabled && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]} +); -if (_barrelLength > 0 && _useABConfig) then { +if (_barrelLength > 0 && _useBarrelLengthInfluence) then { _muzzleVelocity = [_barrelLength, _ammoConfig select 10, _ammoConfig select 11, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); } else { private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed"); @@ -128,7 +133,7 @@ if (_barrelLength > 0 && _useABConfig) then { ctrlSetText [770000, format["%1'' - %2 gr (%3)", round((_ammoConfig select 1) * 39.3700787) / 1000, round((_ammoConfig select 3) * 15.4323584), _ammoClass]]; if (_barrelLength > 0) then { - if (_useABConfig && _barrelTwist > 0) then { + if (_useBarrelLengthInfluence && _barrelTwist > 0) then { ctrlSetText [770002, format["Barrel: %1'' 1:%2'' twist", round(2 * _barrelLength * 0.0393700787) / 2, round(_barrelTwist * 0.0393700787)]]; } else { ctrlSetText [770002, format["Barrel: %1''", round(2 * _barrelLength * 0.0393700787) / 2]]; @@ -136,7 +141,7 @@ if (_barrelLength > 0) then { }; lnbAddRow [770100, ["4mps Wind(MRADs)", "1mps LEAD(MRADs)"]]; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { +if (_isABenabled) then { lnbAddRow [770100, ["Air/Ammo Temp", "Air/Ammo Temp"]]; lnbAddRow [770200, ["-15°C", " -5°C", " 5°C", " 10°C", " 15°C", " 20°C", " 25°C", " 30°C", " 35°C"]]; @@ -145,7 +150,7 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t ctrlSetText [77003, format["%1m ZERO", round(_zeroRange)]]; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { +if (_isABenabled) then { ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]]; ctrlSetText [77004 , format["B.P.: %1mb", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]]; } else { @@ -153,30 +158,30 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t ctrlSetText [77004 , ""]; }; -private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]]; -if (isNil {_cacheEntry}) then { - private _scopeBaseAngle = if (!_useABConfig) then { +private _cacheEntry = missionNamespace getVariable format [QGVAR(%1_%2_%3_%4_%5_%6_%7), _zeroRange, _boreHeight, _ammoClass, _weaponClass, _isABenabled, _useBarrelLengthInfluence, _useAmmoTemperatureInfluence]; +if (isNil "_cacheEntry") then { + private _scopeBaseAngle = if (!_isABenabled) then { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then { + if (_useAmmoTemperatureInfluence) then { { private _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift); private _mv = _muzzleVelocity + _mvShift; - [_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_useABConfig] call FUNC(calculateRangeCard); + [_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_isABenabled] call FUNC(calculateRangeCard); } forEach [-15, -5, 5, 10, 15, 20, 25, 30, 35]; } else { - [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_useABConfig] call FUNC(calculateRangeCard); + [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_isABenabled] call FUNC(calculateRangeCard); }; for "_i" from 0 to 9 do { GVAR(lastValidRow) pushBack count (GVAR(rangeCardDataElevation) select _i); while {count (GVAR(rangeCardDataElevation) select _i) < 50} do { - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_isABenabled) then { (GVAR(rangeCardDataElevation) select _i) pushBack "###"; (GVAR(rangeCardDataWindage) select _i) pushBack "##"; (GVAR(rangeCardDataLead) select _i) pushBack "##"; @@ -188,7 +193,7 @@ if (isNil {_cacheEntry}) then { }; }; - missionNamespace setVariable [format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]]; + missionNamespace setVariable [format [QGVAR(%1_%2_%3_%4_%5_%6_%7), _zeroRange, _boreHeight, _ammoClass, _weaponClass, _isABenabled, _useBarrelLengthInfluence, _useAmmoTemperatureInfluence], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]]; } else { GVAR(rangeCardDataElevation) = _cacheEntry select 0; GVAR(rangeCardDataWindage) = _cacheEntry select 1; diff --git a/addons/rangecard/functions/script_component.hpp b/addons/rangecard/functions/script_component.hpp deleted file mode 100644 index d4a493206b..0000000000 --- a/addons/rangecard/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\rangecard\script_component.hpp" diff --git a/addons/rangecard/initKeybinds.inc.sqf b/addons/rangecard/initKeybinds.inc.sqf new file mode 100644 index 0000000000..2e0828127d --- /dev/null +++ b/addons/rangecard/initKeybinds.inc.sqf @@ -0,0 +1,31 @@ +["ACE3 Equipment", QGVAR(RangeCardDialogKey), LLSTRING(RangeCardDialogKey), +{ + // Conditions: canInteract, canShow + if !([ACE_player, objNull, ["notOnMap", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if (GVAR(RangeCardOpened)) exitWith { + closeDialog 0; + false + }; + if !(call FUNC(canShow)) exitWith {false}; + // Statement + false call FUNC(openRangeCard); + true +}, +{false}, +[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) + +["ACE3 Equipment", QGVAR(RangeCardCopyDialogKey), LLSTRING(RangeCardCopyDialogKey), +{ + // Conditions: canInteract, canShowCopy + if !([ACE_player, objNull, ["notOnMap", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if (GVAR(RangeCardOpened)) exitWith { + closeDialog 0; + false + }; + if !(call FUNC(canShowCopy)) exitWith {false}; + // Statement + true call FUNC(openRangeCard); + true +}, +{false}, +[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) diff --git a/addons/rangecard/initKeybinds.sqf b/addons/rangecard/initKeybinds.sqf deleted file mode 100644 index cb6ff49206..0000000000 --- a/addons/rangecard/initKeybinds.sqf +++ /dev/null @@ -1,31 +0,0 @@ -["ACE3 Equipment", QGVAR(RangeCardDialogKey), localize "STR_ACE_RangeCard_RangeCardDialogKey", -{ - // Conditions: canInteract, canShow - if !([ACE_player, objNull, ["notOnMap", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (GVAR(RangeCardOpened)) exitWith { - closeDialog 0; - false - }; - if !(call FUNC(canShow)) exitWith {false}; - // Statement - false call FUNC(openRangeCard); - true -}, -{false}, -[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) - -["ACE3 Equipment", QGVAR(RangeCardCopyDialogKey), localize "STR_ACE_RangeCard_RangeCardCopyDialogKey", -{ - // Conditions: canInteract, canShowCopy - if !([ACE_player, objNull, ["notOnMap", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (GVAR(RangeCardOpened)) exitWith { - closeDialog 0; - false - }; - if !(call FUNC(canShowCopy)) exitWith {false}; - // Statement - true call FUNC(openRangeCard); - true -}, -{false}, -[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) \ No newline at end of file diff --git a/addons/rangecard/stringtable.xml b/addons/rangecard/stringtable.xml index 5862981e16..859bb2e048 100644 --- a/addons/rangecard/stringtable.xml +++ b/addons/rangecard/stringtable.xml @@ -12,10 +12,11 @@ Távolsági kártya Таблица поправок Tavola Balistica - 射表 + レンジカード (射表) 사거리표 - 弹道射表 + 射表 彈道射表 + Menzil Kartı 50 METER increments -- MRAD/MRAD (reticle/turrets) @@ -24,14 +25,15 @@ Přidat 50 METRŮ -- MRAD/MRAD (síťka/věže) 50-Meter-Schritte MRAD/MRAD (Fadenkreuz/Geschützturm) Incrementos de 50 METROS - MRAD/MRAD (retícula/torres) - Incrément de 50m -- MRAD/MRAD (réticule/tourelle) + Incréments de 50 MÈTRES -- MRAD/MRAD (réticule/tourelles) 50 MÉTERES lépések - MRAD/MRAD (célzó/lövegek) Шаг 50 МЕТРОВ - MRAD/MRAD (сетка/маховички) Incrementi per 50 METRI - MRAD/MRAD (reticolo/torrette) - 50 メートル増やす -- MRAD/MRAD (照準線/砲塔) + 50 メートル単位 -- MRAD/MRAD (レチクル/タレット) 50 미터 늘리기 -- MRAD/MRAD (조준선/포탑) - 50公尺增量 -- 毫弧度/毫弧度 (瞄镜分划线/调整纽) + 50米增量 -- 毫弧度/毫弧度(瞄镜分划线/调整纽) 50公尺增量 -- 毫弧度/毫弧度 (瞄鏡分劃線/調整紐) + 50 METER increments -- MRAD/MRAD (reticle/turrets) Open Range Card @@ -44,10 +46,11 @@ Távolsági kártya kinyitása Открыть таблицу поправок Apri Tavola Balistica - 射表を開く + レンジカードを開く 사거리표 열기 - 开启弹道射表 + 开启射表 開啟彈道射表 + Menzil Kartını Aç Open Range Card Copy @@ -60,10 +63,11 @@ Távolsági kártya-másolat kinyitása Открыть копию таблицы поправок Apri Copia Tavola Balistica - 複製された射表を開く + レンジカードの複製を開く 복제 사거리표 열기 - 开启弹道射表副本 + 开启射表副本 開啟彈道射表副本 + Menzil Kartının Kopyasını Aç Open Range Card @@ -71,15 +75,16 @@ Abrir tarjeta de distancias Otevřít vzdálenostní tabulku Öffne Entfernungsspinne - Abrir tabela de distäncias + Abrir tabela de distâncias Ouvrir la table de tir Távolsági kártya kinyitása Открыть таблицу поправок Apri Tavola Balistica - 射表を開く + レンジカードを開く 사거리표 열기 - 开启弹道射表 + 开启射表 開啟彈道射表 + Menzil Kartını Aç Open Range Card Copy @@ -92,10 +97,11 @@ Távolsági kártya-másolat kinyitása Открыть копию таблицы поправок Apri Copia Tavola Balistica - 複製された射表を開く + レンジカードの複製を開く 복제 사거리표 열기 - 开启弹道射表副本 + 开启射表副本 開啟彈道射表副本 + Menzil Kartının Kopyasını Aç Copy Range Card @@ -103,15 +109,16 @@ Copiar tarjeta de distancias Kopírovat vzdálenostní tabulku Kopiere Entfernungsspinne - Copiar tabela de distäncias + Copiar tabela de distâncias Recopier la table de tir Távolsági kártya másolása Скопировать таблицу поправок Copia Tavola Balistica - 射表を複製する + レンジカードを複製 사거리표 복제 - 复制弹道射表 + 复制射表 複製彈道射表 + Menzil Kartını Kopyala diff --git a/addons/realisticnames/Attachments.hpp b/addons/realisticnames/Attachments.hpp new file mode 100644 index 0000000000..a861bb4a04 --- /dev/null +++ b/addons/realisticnames/Attachments.hpp @@ -0,0 +1,174 @@ +//attachments + +class ItemCore; + +class acc_flashlight: ItemCore { + displayName = CSTRING(flashlight_Name); +}; + +class optic_MRD: ItemCore { + displayName = CSTRING(optic_mrd_Name); +}; +class optic_MRD_black: optic_MRD { + displayName = CSTRING(optic_mrd_black_Name); +}; + +class optic_Hamr: ItemCore { + displayName = CSTRING(optic_hamr); +}; +class optic_Hamr_khk_F: optic_Hamr { + displayName = CSTRING(optic_hamr_khk); +}; +class ACE_optic_Hamr_2D: optic_Hamr { + displayName = CSTRING(optic_hamr_2d); +}; +class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { + displayName = CSTRING(optic_hamr_pip); +}; + +class optic_Arco: ItemCore { + displayName = CSTRING(optic_arco); +}; +class optic_Arco_blk_F: optic_Arco { + displayName = CSTRING(optic_arco_blk); +}; +class optic_Arco_ghex_F: optic_Arco { + displayName = CSTRING(optic_arco_ghex); +}; +class ACE_optic_Arco_2D: optic_Arco { + displayName = CSTRING(optic_arco_2d); +}; +class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { + displayName = CSTRING(optic_arco_pip); +}; +class optic_Arco_lush_F: optic_Arco { + displayName = CSTRING(optic_arco_lush); +}; +class optic_Arco_arid_F: optic_Arco { + displayName = CSTRING(optic_arco_arid); +}; +class optic_Arco_AK_blk_F: optic_Arco_blk_F { + displayName = CSTRING(optic_arco_ak_blk); +}; +class optic_Arco_AK_lush_F: optic_Arco_lush_F { + displayName = CSTRING(optic_arco_ak_lush); +}; +class optic_Arco_AK_arid_F: optic_Arco_arid_F { + displayName = CSTRING(optic_arco_ak_arid); +}; + +class optic_ERCO_blk_f: optic_Arco { + displayName = CSTRING(optic_erco_blk); +}; +class optic_ERCO_khk_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_khk); +}; +class optic_ERCO_snd_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_snd); +}; + +class optic_LRPS: ItemCore { + displayName = CSTRING(optic_lrps); +}; +class optic_LRPS_ghex_F: optic_LRPS { + displayName = CSTRING(optic_lrps_ghex); +}; +class optic_LRPS_tna_F: optic_LRPS { + displayName = CSTRING(optic_lrps_tna); +}; +class ACE_optic_LRPS_2D: optic_LRPS { + displayName = CSTRING(optic_lrps_2d); +}; +class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { + displayName = CSTRING(optic_lrps_pip); +}; + +class optic_AMS_base; +class optic_AMS: optic_AMS_base { + displayName = CSTRING(optic_ams); +}; +class optic_AMS_khk: optic_AMS { + displayName = CSTRING(optic_ams_khk); +}; +class optic_AMS_snd: optic_AMS { + displayName = CSTRING(optic_ams_snd); +}; + +class optic_KHS_base; +class optic_KHS_blk: optic_KHS_base { + displayName = CSTRING(optic_khs_blk); +}; +class optic_KHS_hex: optic_KHS_blk { + displayName = CSTRING(optic_khs_hex); +}; +class optic_KHS_old: ItemCore { + displayName = CSTRING(optic_khs_old); +}; +class optic_KHS_tan: optic_KHS_blk { + displayName = CSTRING(optic_khs_tan); +}; + +class optic_DMS: ItemCore { + displayName = CSTRING(optic_dms); +}; +class optic_DMS_ghex_F: optic_DMS { + displayName = CSTRING(optic_dms_ghex); +}; +class optic_DMS_weathered_F: optic_DMS { + displayName = CSTRING(optic_dms_weathered); +}; +class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { + displayName = CSTRING(optic_dms_weathered_kir); +}; + +class optic_holosight: ItemCore { + displayName = CSTRING(optic_holosight); +}; +class optic_Holosight_blk_F: optic_holosight { + displayName = CSTRING(optic_holosight_blk); +}; +class optic_Holosight_khk_F: optic_holosight { + displayName = CSTRING(optic_holosight_khk); +}; +class optic_Holosight_lush_F: optic_holosight { + displayName = CSTRING(optic_holosight_lush); +}; +class optic_Holosight_arid_F: optic_holosight { + displayName = CSTRING(optic_holosight_arid); +}; +class optic_Holosight_smg: ItemCore { + displayName = CSTRING(optic_holosight_smg); +}; +class optic_Holosight_smg_blk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_blk); +}; +class optic_Holosight_smg_khk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_khk); +}; + +class optic_MRCO: ItemCore { + displayName = CSTRING(optic_MRCO); +}; +class ACE_optic_MRCO_2D: optic_MRCO { + displayName = CSTRING(optic_MRCO_2d); +}; +class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { + displayName = CSTRING(optic_MRCO_pip); +}; + +class optic_Yorris: ItemCore { + displayName = CSTRING(optic_Yorris); +}; + +class optic_ACO: ItemCore { + displayName = CSTRING(optic_ACO); +}; +class optic_ACO_grn: ItemCore { + displayName = CSTRING(optic_ACO_grn); +}; +class optic_ACO_smg: ItemCore { + displayName = CSTRING(optic_ACO_smg); +}; +class optic_ACO_grn_smg: ItemCore { + displayName = CSTRING(optic_ACO_grn_smg); +}; diff --git a/addons/realisticnames/CfgMagazines.hpp b/addons/realisticnames/CfgMagazines.hpp index bacaed93dc..be7ce2b2a5 100644 --- a/addons/realisticnames/CfgMagazines.hpp +++ b/addons/realisticnames/CfgMagazines.hpp @@ -390,6 +390,12 @@ class CfgMagazines { class DemoCharge_Remote_Mag: SatchelCharge_Remote_Mag { displayName = CSTRING(DemoCharge_Name); }; + class ACE_SatchelCharge_Remote_Mag_Throwable: CA_Magazine { + displayName = CSTRING(SatchelChargeThrowable_Name); + }; + class ACE_DemoCharge_Remote_Mag_Throwable: ACE_SatchelCharge_Remote_Mag_Throwable { + displayName = CSTRING(DemoChargeThrowable_Name); + }; // hand grenades class HandGrenade: CA_Magazine { @@ -447,19 +453,19 @@ class CfgMagazines { class PylonRack_3Rnd_Missile_AGM_02_F: PylonRack_1Rnd_Missile_AGM_02_F { displayName = "AGM-65 Maverick G 3x"; // [vanilla: Macer 3x - Missile_AGM_02_Plane_CAS_01_F] }; - class magazine_Missile_AGM_02_x1 : VehicleMagazine { + class magazine_Missile_AGM_02_x1: VehicleMagazine { displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] }; - class PylonMissile_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 { + class PylonMissile_Missile_AGM_02_x1: magazine_Missile_AGM_02_x1 { displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] }; - class PylonMissile_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 { + class PylonMissile_Missile_AGM_02_x2: magazine_Missile_AGM_02_x1 { displayName = "AGM-65 Maverick G 2x"; // [vanilla: Macer 2x - Missile_AGM_02_Plane_CAS_01_F] }; - class PylonRack_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 { + class PylonRack_Missile_AGM_02_x1: magazine_Missile_AGM_02_x1 { displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] }; - class PylonRack_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 { + class PylonRack_Missile_AGM_02_x2: magazine_Missile_AGM_02_x1 { displayName = "AGM-65 Maverick G 2x"; // [vanilla: Macer 2x - Missile_AGM_02_Plane_CAS_01_F] }; class 2Rnd_LG_scalpel; @@ -474,7 +480,7 @@ class CfgMagazines { }; class PylonRack_7Rnd_Rocket_04_HE_F: 7Rnd_Rocket_04_HE_F { displayName = "Hydra 70 7x HE"; // [vanilla: Shrieker 7x HE - Rocket_04_HE_Plane_CAS_01_F] - }; + }; class PylonRack_7Rnd_Rocket_04_AP_F: 7Rnd_Rocket_04_AP_F { displayName = "Hydra 70 7x AP"; // [vanilla: Shrieker 7x AP - Rocket_04_AP_Plane_CAS_01_F] }; diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 9b0ab1b95a..29ac412957 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -183,14 +183,14 @@ class CfgVehicles { }; class APC_Wheeled_02_base_F; - class O_APC_Wheeled_02_base_F : APC_Wheeled_02_base_F { + class O_APC_Wheeled_02_base_F: APC_Wheeled_02_base_F { displayName = CSTRING(APC_Wheeled_02_rcws_Name); }; class APC_Wheeled_02_base_v2_F; - class O_APC_Wheeled_02_rcws_v2_F : APC_Wheeled_02_base_v2_F { + class O_APC_Wheeled_02_rcws_v2_F: APC_Wheeled_02_base_v2_F { displayName = CSTRING(APC_Wheeled_02_rcws_Name); }; - class O_T_APC_Wheeled_02_rcws_v2_ghex_F : APC_Wheeled_02_base_v2_F { + class O_T_APC_Wheeled_02_rcws_v2_ghex_F: APC_Wheeled_02_base_v2_F { displayName = CSTRING(APC_Wheeled_02_rcws_Name); }; @@ -249,6 +249,10 @@ class CfgVehicles { class O_Truck_02_medical_F: Truck_02_medical_base_F { displayName = CSTRING(Truck_02_medical_Name); }; + class Truck_02_water_base_F; + class C_IDAP_Truck_02_water_F: Truck_02_water_base_F { + displayName = CSTRING(Truck_02_water_Name); + }; class I_Truck_02_transport_F: Truck_02_transport_base_F { displayName = CSTRING(Truck_02_transport_Name); }; @@ -283,6 +287,12 @@ class CfgVehicles { class C_Truck_02_box_F: Truck_02_box_base_F { displayName = CSTRING(Truck_02_box_Name); }; + class C_IDAP_Truck_02_transport_F: Truck_02_transport_base_F { + displayName = CSTRING(Truck_02_transport_Name); + }; + class C_IDAP_Truck_02_F: Truck_02_base_F { + displayName = CSTRING(Truck_02_covered_Name); + }; class Truck_03_base_F; class O_Truck_03_transport_F: Truck_03_base_F { @@ -384,6 +394,9 @@ class CfgVehicles { class I_Heli_Transport_02_F: Heli_Transport_02_base_F { displayName = CSTRING(Heli_Transport_02_Name); }; + class C_IDAP_Heli_Transport_02_F: Heli_Transport_02_base_F { + displayName = CSTRING(Heli_Transport_02_Name); + }; // planes class Plane_CAS_01_base_F; @@ -421,7 +434,7 @@ class CfgVehicles { }; class Plane_Fighter_04_Base_F; - class I_Plane_Fighter_04_F : Plane_Fighter_04_Base_F { + class I_Plane_Fighter_04_F: Plane_Fighter_04_Base_F { displayName = CSTRING(Plane_Fighter_04_Name); }; @@ -737,12 +750,11 @@ class CfgVehicles { // APEX/Tanoa // Jeep Wrangler - class Offroad_02_base_F; - class Offroad_02_unarmed_base_F : Offroad_02_base_F {}; - class C_Offroad_02_unarmed_F: Offroad_02_unarmed_base_F { + class Car_F; + class Offroad_02_base_F: Car_F { displayName = CSTRING(C_Offroad_02_unarmed); }; - class I_C_Offroad_02_unarmed_F: Offroad_02_unarmed_base_F { + class Offroad_02_unarmed_base_F: Offroad_02_base_F { displayName = CSTRING(C_Offroad_02_unarmed); }; class Offroad_02_at_base_F: Offroad_02_base_F { @@ -778,78 +790,78 @@ class CfgVehicles { // Polaris DAGOR (Prowler) class LSV_01_base_F; - class LSV_01_armed_base_F : LSV_01_base_F { + class LSV_01_armed_base_F: LSV_01_base_F { displayName = CSTRING(lsv_01_armed); }; - class LSV_01_unarmed_base_F : LSV_01_base_F { + class LSV_01_unarmed_base_F: LSV_01_base_F { displayName = CSTRING(lsv_01_unarmed); }; - class LSV_01_light_base_F : LSV_01_base_F { + class LSV_01_light_base_F: LSV_01_base_F { displayName = CSTRING(lsv_01_light); }; - class LSV_01_AT_base_F : LSV_01_base_F { + class LSV_01_AT_base_F: LSV_01_base_F { displayName = CSTRING(lsv_01_at); }; // Light Strike Vehicle Mk. II (Qilin) class LSV_02_base_F; - class LSV_02_armed_base_F : LSV_02_base_F { + class LSV_02_armed_base_F: LSV_02_base_F { displayName = CSTRING(lsv_02_armed); }; - class LSV_02_unarmed_base_F : LSV_02_base_F { + class LSV_02_unarmed_base_F: LSV_02_base_F { displayName = CSTRING(lsv_02_unarmed); }; - class LSV_02_AT_base_F : LSV_02_base_F { + class LSV_02_AT_base_F: LSV_02_base_F { displayName = CSTRING(lsv_02_at); }; // Rooikat 120 (Rhino MGS) class AFV_Wheeled_01_base_F; - class B_AFV_Wheeled_01_cannon_F : AFV_Wheeled_01_base_F { + class B_AFV_Wheeled_01_cannon_F: AFV_Wheeled_01_base_F { displayName = CSTRING(afv_wheeled_01); }; - class B_T_AFV_Wheeled_01_cannon_F : AFV_Wheeled_01_base_F { + class B_T_AFV_Wheeled_01_cannon_F: AFV_Wheeled_01_base_F { displayName = CSTRING(afv_wheeled_01); }; class AFV_Wheeled_01_up_base_F; - class B_AFV_Wheeled_01_up_cannon_F : AFV_Wheeled_01_up_base_F { + class B_AFV_Wheeled_01_up_cannon_F: AFV_Wheeled_01_up_base_F { displayName = CSTRING(afv_wheeled_01_up); }; - class B_T_AFV_Wheeled_01_up_cannon_F : AFV_Wheeled_01_up_base_F { + class B_T_AFV_Wheeled_01_up_cannon_F: AFV_Wheeled_01_up_base_F { displayName = CSTRING(afv_wheeled_01_up); }; // T-14 Armata (T-140 Angara) class MBT_04_cannon_base_F; - class O_MBT_04_cannon_F : MBT_04_cannon_base_F { + class O_MBT_04_cannon_F: MBT_04_cannon_base_F { displayName = CSTRING(MBT_04_cannon); }; - class O_T_MBT_04_cannon_F : MBT_04_cannon_base_F { + class O_T_MBT_04_cannon_F: MBT_04_cannon_base_F { displayName = CSTRING(MBT_04_cannon); }; class MBT_04_command_base_F; // Keep "K" designation for command variant. - class O_MBT_04_command_F : MBT_04_command_base_F { + class O_MBT_04_command_F: MBT_04_command_base_F { displayName = CSTRING(MBT_04_command); }; - class O_T_MBT_04_command_F : MBT_04_command_base_F { + class O_T_MBT_04_command_F: MBT_04_command_base_F { displayName = CSTRING(MBT_04_command); }; // Wiesel 2 (AWC 302 Nyx) class LT_01_AA_base_F; - class I_LT_01_AA_F : LT_01_AA_base_F { + class I_LT_01_AA_F: LT_01_AA_base_F { displayName = CSTRING(LT_01_AA); }; class LT_01_AT_base_F; - class I_LT_01_AT_F : LT_01_AT_base_F { + class I_LT_01_AT_F: LT_01_AT_base_F { displayName = CSTRING(LT_01_AT); }; class LT_01_cannon_base_F; - class I_LT_01_cannon_F : LT_01_cannon_base_F { + class I_LT_01_cannon_F: LT_01_cannon_base_F { displayName = CSTRING(LT_01_cannon); }; class LT_01_scout_base_F; - class I_LT_01_scout_F : LT_01_scout_base_F { + class I_LT_01_scout_F: LT_01_scout_base_F { displayName = CSTRING(LT_01_scout); }; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index af04d90310..5b0e33e98c 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -2,6 +2,7 @@ class Mode_SemiAuto; class Mode_FullAuto; class CfgWeapons { + #include "Attachments.hpp" // assault rifles // MX @@ -12,6 +13,9 @@ class CfgWeapons { class arifle_MX_Black_F: arifle_MX_F { displayName = CSTRING(arifle_MX_Black_Name); }; + class arifle_MX_khk_F: arifle_MX_Black_F { + displayName = CSTRING(arifle_MX_Khaki_Name); + }; class arifle_MXC_F: arifle_MX_Base_F { displayName = CSTRING(arifle_MXC_Name); @@ -19,6 +23,9 @@ class CfgWeapons { class arifle_MXC_Black_F: arifle_MXC_F { displayName = CSTRING(arifle_MXC_Black_Name); }; + class arifle_MXC_khk_F: arifle_MXC_Black_F { + displayName = CSTRING(arifle_MXC_Khaki_Name); + }; class arifle_MX_GL_F: arifle_MX_Base_F { displayName = CSTRING(arifle_MX_GL_Name); @@ -26,6 +33,9 @@ class CfgWeapons { class arifle_MX_GL_Black_F: arifle_MX_GL_F { displayName = CSTRING(arifle_MX_GL_Black_Name); }; + class arifle_MX_GL_khk_F: arifle_MX_GL_Black_F { + displayName = CSTRING(arifle_MX_GL_Khaki_Name); + }; class arifle_MX_SW_F: arifle_MX_Base_F { displayName = CSTRING(arifle_MX_SW_Name); @@ -33,6 +43,9 @@ class CfgWeapons { class arifle_MX_SW_Black_F: arifle_MX_SW_F { displayName = CSTRING(arifle_MX_SW_Black_Name); }; + class arifle_MX_SW_khk_F: arifle_MX_SW_Black_F { + displayName = CSTRING(arifle_MX_SW_Khaki_Name); + }; class arifle_MXM_F: arifle_MX_Base_F { displayName = CSTRING(arifle_MXM_Name); @@ -40,6 +53,9 @@ class CfgWeapons { class arifle_MXM_Black_F: arifle_MXM_F { displayName = CSTRING(arifle_MXM_Black_Name); }; + class arifle_MXM_khk_F: arifle_MXM_Black_F { + displayName = CSTRING(arifle_MXM_Khaki_Name); + }; // Katiba class arifle_katiba_Base_F; @@ -93,7 +109,7 @@ class CfgWeapons { class arifle_Mk20_GL_plain_F: arifle_Mk20_GL_F { displayName = CSTRING(arifle_Mk20_GL_plain_Name); }; - + // P90 (1.86) class SMG_03_TR_BASE; class SMG_03_TR_black: SMG_03_TR_BASE { @@ -133,7 +149,7 @@ class CfgWeapons { class SMG_03C_TR_hex: SMG_03C_TR_black { displayName = CSTRING(P90_TR_Hex_Name); }; - class SMG_03C_black: SMG_03C_Base { + class SMG_03C_black: SMG_03C_BASE { displayName = CSTRING(P90_Black_Name); }; class SMG_03C_khaki: SMG_03C_black { @@ -145,8 +161,8 @@ class CfgWeapons { class SMG_03C_hex: SMG_03C_black { displayName = CSTRING(P90_Hex_Name); }; - - + + // Vector class SMG_01_Base; @@ -247,10 +263,10 @@ class CfgWeapons { }; class launch_Vorona_base_F; - class launch_O_Vorona_brown_F : launch_Vorona_base_F { + class launch_O_Vorona_brown_F: launch_Vorona_base_F { displayName = CSTRING(launch_Vorona_brown); }; - class launch_O_Vorona_green_F : launch_Vorona_base_F { + class launch_O_Vorona_green_F: launch_Vorona_base_F { displayName = CSTRING(launch_Vorona_green); }; @@ -418,7 +434,7 @@ class CfgWeapons { class Missile_AGM_01_Plane_CAS_02_F: Missile_AGM_02_Plane_CAS_01_F { displayName = "Kh-25MTP"; }; - class missiles_Vorona : MissileLauncher { + class missiles_Vorona: MissileLauncher { displayName = CSTRING(missiles_vorona); }; @@ -502,6 +518,13 @@ class CfgWeapons { }; }; + class LMG_Minigun_heli: LMG_Minigun { + displayName = "M134 Minigun"; + class manual: manual { + displayName = "M134 Minigun"; + }; + }; + class HMG_127: LMG_RCWS { displayName = "M2"; class manual: MGun { @@ -509,8 +532,8 @@ class CfgWeapons { }; }; - class HMG_127_APC : HMG_127 {}; - class ACE_HMG_127_KORD : HMG_127_APC { + class HMG_127_APC: HMG_127 {}; + class ACE_HMG_127_KORD: HMG_127_APC { displayName = "6P49 Kord"; }; @@ -557,7 +580,7 @@ class CfgWeapons { displayName = "Mini-Spike"; }; - class missiles_SAAMI : MissileLauncher { + class missiles_SAAMI: MissileLauncher { displayName = "FIM-92F"; }; @@ -596,8 +619,8 @@ class CfgWeapons { class cannon_125mm: CannonCore { displayName = "2A46"; }; - - class cannon_125mm_advanced : cannon_125mm { + + class cannon_125mm_advanced: cannon_125mm { displayName = "2A82-1M"; }; @@ -616,9 +639,9 @@ class CfgWeapons { displayName = "L94A1"; }; class ACE_LMG_coax_ext_MG3: LMG_coax_ext { - displayName = "H&K MG3"; + displayName = "Rheinmetall MG3"; }; - class ACE_LMG_coax_DenelMG4 : LMG_coax { + class ACE_LMG_coax_DenelMG4: LMG_coax { displayName = "Denel MG4"; }; @@ -666,16 +689,16 @@ class CfgWeapons { displayName = "L21A1 RARDEN"; }; }; - - class autocannon_30mm_RCWS : autocannon_Base_F { + + class autocannon_30mm_RCWS: autocannon_Base_F { displayName = "2A42"; }; - class cannon_20mm : autocannon_Base_F { - class AP : autocannon_Base_F {}; - class HE : autocannon_Base_F {}; + class cannon_20mm: autocannon_Base_F { + class AP: autocannon_Base_F {}; + class HE: autocannon_Base_F {}; }; - class ACE_cannon_20mm_Rh202 : cannon_20mm { + class ACE_cannon_20mm_Rh202: cannon_20mm { displayName = "MK20 Rh 202"; class AP: AP { displayName = "MK20 Rh 202"; @@ -685,125 +708,20 @@ class CfgWeapons { }; }; - //attachments - - class Itemcore; - - class acc_flashlight: ItemCore { - displayName = "UTG Defender 126"; - }; - - class optic_hamr : ItemCore { - displayName = CSTRING(optic_hamr); - }; - class optic_Hamr_khk_F : optic_hamr { - displayName = CSTRING(optic_hamr_khk); - }; - - class optic_Arco : ItemCore { - displayName = CSTRING(optic_arco); - }; - class optic_Arco_blk_F : optic_Arco { - displayName = CSTRING(optic_arco_blk); - }; - class optic_Arco_ghex_F : optic_Arco { - displayName = CSTRING(optic_arco_ghex); - }; - - class optic_ERCO_blk_f : optic_Arco { - displayName = CSTRING(optic_erco_blk); - }; - class optic_ERCO_khk_f : optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_khk); - }; - class optic_ERCO_snd_f : optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_snd); - }; - - class optic_LRPS : ItemCore { - displayName = CSTRING(optic_lrps); - }; - class optic_LRPS_ghex_F : optic_LRPS { - displayName = CSTRING(optic_lrps_ghex); - }; - class optic_LRPS_tna_F : optic_LRPS { - displayName = CSTRING(optic_lrps_tna); - }; - - class optic_AMS_base; - class optic_AMS: optic_AMS_base { - displayName = CSTRING(optic_ams); - }; - class optic_AMS_khk: optic_AMS { - displayName = CSTRING(optic_ams_khk); - }; - class optic_AMS_snd: optic_AMS { - displayName = CSTRING(optic_ams_snd); - }; - - class optic_KHS_base; - class optic_KHS_blk: optic_KHS_base { - displayName = CSTRING(optic_khs_blk); - }; - class optic_KHS_hex: optic_KHS_blk { - displayName = CSTRING(optic_khs_hex); - }; - class optic_KHS_old: ItemCore { - displayName = CSTRING(optic_khs_old); - }; - class optic_KHS_tan: optic_KHS_blk { - displayName = CSTRING(optic_khs_tan); - }; - - class optic_DMS : ItemCore { - displayName = CSTRING(optic_dms); - }; - class optic_DMS_ghex_F : optic_DMS { - displayName = CSTRING(optic_dms_ghex); - }; - - class optic_holosight : ItemCore { - displayName = CSTRING(optic_holosight); - }; - class optic_Holosight_blk_F : optic_holosight { - displayName = CSTRING(optic_holosight_blk); - }; - class optic_Holosight_khk_F : optic_holosight { - displayName = CSTRING(optic_holosight_khk); - }; - class optic_Holosight_smg : ItemCore { - displayName = CSTRING(optic_holosight_smg); - }; - class optic_Holosight_smg_blk_F : optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_blk); - }; - class optic_Holosight_smg_khk_F : optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_khk); - }; - - class optic_MRCO : ItemCore { - displayName = CSTRING(optic_MRCO); - }; - - class optic_Yorris : ItemCore { - displayName = CSTRING(optic_Yorris); - }; - - class optic_ACO : ItemCore { - displayName = CSTRING(optic_ACO); - }; - class optic_ACO_grn : ItemCore { - displayName = CSTRING(optic_ACO_grn); - }; - class optic_ACO_smg : ItemCore { - displayName = CSTRING(optic_ACO_smg); - }; - class optic_ACO_grn_smg : ItemCore { - displayName = CSTRING(optic_ACO_grn_smg); - }; - // APEX/Tanoa + // Type 115 + class arifle_ARX_base_F; + class arifle_ARX_blk_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_blk_Name); + }; + class arifle_ARX_ghex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_ghex_Name); + }; + class arifle_ARX_hex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_hex_Name); + }; + // QBZ-95 and variants class arifle_CTAR_base_F; class arifle_CTAR_blk_F: arifle_CTAR_base_F { @@ -922,9 +840,165 @@ class CfgWeapons { class hgun_P07_khk_F: hgun_P07_F { displayName = CSTRING(hgun_P07_khk); }; + class hgun_P07_blk_F: hgun_P07_F { + displayName = CSTRING(hgun_P07_blk); + }; // Makarov 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 + + // CZ 581 Shotgun + class sgun_HunterShotgun_01_base_F; + class sgun_HunterShotgun_01_F: sgun_HunterShotgun_01_base_F { + displayName = CSTRING(sgun_huntershotgun_01_Name); + }; + class sgun_HunterShotgun_01_sawedoff_base_F; + class sgun_HunterShotgun_01_sawedoff_F: sgun_HunterShotgun_01_sawedoff_base_F { + displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name); + }; + + // FNX-45 (Green) + class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F { + displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); + }; + + // 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/README.md b/addons/realisticnames/README.md index 6cd05351f6..a22849cb35 100644 --- a/addons/realisticnames/README.md +++ b/addons/realisticnames/README.md @@ -2,11 +2,3 @@ ace_realisticnames ================== Changes the names of various weapons and vehicles to those of their real life counterparts. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/realisticnames/addon.toml b/addons/realisticnames/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/realisticnames/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/realisticnames/config.cpp b/addons/realisticnames/config.cpp index c97c9a82e0..8cf6232906 100644 --- a/addons/realisticnames/config.cpp +++ b/addons/realisticnames/config.cpp @@ -1,12 +1,20 @@ #include "script_component.hpp" +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\norealisticnames\script_component.hpp") +#define PATCH_SKIP "No Realistic Names" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_common", "ace_optics"}; author = ECSTRING(common,ACETeam); authors[] = {"KoffeinFlummi","TaoSensai","commy2"}; url = ECSTRING(main,URL); @@ -20,3 +28,5 @@ class CfgPatches { #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" + +#endif diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 84a55ff177..70b78e6d25 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -15,7 +15,8 @@ XM312 XM312 XM312重機槍 - XM312重机枪 + XM312 + XM312 XM312A @@ -31,23 +32,25 @@ XM312A XM312A XM312A重機槍 - XM312A重机枪 + XM312A + XM312A XM312 (High) XM312 (Hoch) XM312 (Alto) - XM312 (Haut) + XM312 (Haute) XM312 (Vysoká montáž) XM312 (Wysoki) XM312 (Высокий) XM312 (Alta) XM312 (Magasított) - XM312 (Alta) - XM312 (高) + XM312 (Alto) + XM312 (ハイマウント) XM312 (높음) XM312重機槍 (高射腳架) - XM312重机枪 (高射脚架) + XM312(高) + XM312 (Yüksek) XM307 @@ -63,7 +66,8 @@ XM307 XM307 XM307榴彈機槍 - XM307榴弹机枪 + XM307 + XM307 XM307A @@ -79,23 +83,25 @@ XM307A XM307A XM307A榴彈機槍 - XM307A榴弹机枪 + XM307A + XM307A XM307 (High) XM307 (Hoch) XM307 (Alto) - XM307 (Haut) + XM307 (Haute) XM307 (Vysoká montáž) XM307 (Wysoki) XM307 (Высокий) XM307 (Alta) XM307 (Magasított) - XM307 (Alta) - XM307 (高) + XM307 (Alto) + XM307 (ハイマウント) XM307 (높음) XM307榴彈機槍 (高射腳架) - XM307榴弹机枪 (高射脚架) + XM307(高) + XM307 (Yüksek) Mini-Spike Launcher (AT) @@ -104,14 +110,15 @@ Poste de tir Mini-Spike (AC) Mini-Spike Odpalovač (AT) Wyrzutnia Mini-Spike (AT) - Mini-Spike Пусковое устройство (ПТРК) + Mini-Spike ПУ (ПТРК) Lança-mísseis Mini-Spike (AC) Mini-Spike rakétarendszer (Tankelhárító) Lanciatore Mini-Spike (AC) - ミニスパイク ランチャー (対戦) - Mini-Spike Launcher (대전차) + ミニスパイク ランチャー (対戦車) + 스파이크 미사일 발사기 (대전차) "迷你長釘"導彈發射器 (反坦克) - "迷你长钉"导弹发射器 (反坦克) + "迷你长钉"(反坦) + Mini-Spike Launcher (AT) Mini-Spike Launcher (AA) @@ -120,14 +127,15 @@ 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) ミニスパイク ランチャー (対空) - Mini-Spike Launcher (대공) + 스파이크 미사일 발사기 (대공) "迷你長釘"導彈發射器 (防空) - "迷你长钉"导弹发射器 (防空) + "迷你长钉"(防空) + Mini-Spike Launcher (AA) YABHON-R3 @@ -143,7 +151,8 @@ YABHON-R3 YABHON-R3 "亞伯罕-R3型"空中無人載具 - "亚伯罕-R3型"空中无人载具 + "联合"-R3 + YABHON-R3 YABHON-R3 (CAS) @@ -159,7 +168,8 @@ YABHON-R3 (CAS) YABHON-R3 (근접지원) "亞伯罕-R3型"空中無人載具 (近空支援) - "亚伯罕-R3型"空中无人载具 (近空支援) + "联合"-R3(近空支援) + YABHON-R3 (CAS) M-ATV @@ -175,7 +185,8 @@ M-ATV M-ATV 防地雷反伏擊全地形車 - 防地雷反伏击全地形车 + M-ATV + M-ATV M-ATV (HMG) @@ -184,14 +195,15 @@ M-ATV (CKM) M-ATV (HMG) M-ATV (HMG) - M-ATV (Пулемёт) + M-ATV (с пулемётом) M-ATV (HMG) M-ATV (nehézgéppuska) M-ATV (HMG) M-ATV (HMG) - M-ATV (HMG) + M-ATV (중기관총) 防地雷反伏擊全地形車 (重機槍) - 防地雷反伏击全地形车 (重机枪) + M-ATV(重机枪) + M-ATV (HMG) M-ATV (GMG) @@ -200,14 +212,15 @@ M-ATV (GMG) M-ATV (GMG) M-ATV (GMG) - M-ATV (Гранатомёт) + M-ATV (с гранатомётом) M-ATV (GMG) M-ATV (gránátgéppuska) M-ATV (GMG) M-ATV (GMG) - M-ATV (GMG) + M-ATV (유탄기관총) 防地雷反伏擊全地形車 (榴彈機槍) - 防地雷反伏击全地形车 (榴弹机枪) + M-ATV(榴弹发射器) + M-ATV (GMG) Merkava Mk IV M @@ -221,9 +234,10 @@ Merkava Mk IV M Merkava Mk IV M メルカバ Mk IV M - Merkava Mk IV M + 메르카바 Mk IV M "梅卡瓦4代"主戰坦克 - "梅卡瓦4代"主战坦克 + "梅卡瓦"4M + Merkava Mk IV M Merkava Mk IV LIC @@ -237,9 +251,10 @@ Merkava Mk IV LIC Merkava Mk IV LIC メルカバ Mk IV LIC - Merkava Mk IV LIC + 메르카바 Mk IV LIC "梅卡瓦4代"主戰坦克 城市版 - "梅卡瓦4代"主战坦克 城市版 + "梅卡瓦"4M 城市版 + Merkava Mk IV LIC Sholef @@ -252,10 +267,11 @@ Sholef Sholef Sholef - ショルフ - Sholef + ショレフ + 숄레프 자주포 "神槍"自走炮 - "神枪"自走炮 + "神枪" + Sholef Seara @@ -269,9 +285,10 @@ Seara Seara シアラ - Seara + 시아라 다연장로켓 "希拉"多管火箭車 - "希拉"多管火箭车 + "希拉" + Seara Namer @@ -284,10 +301,11 @@ Namer Namer Namer - ネイマー - Namer + ナメル + 나메르 병력수송장갑차 "花豹"裝甲運兵車 - "花豹"装甲运兵车 + "花豹" + Namer Bardelas @@ -300,10 +318,11 @@ Bardelas Bardelas Bardelas - バーラデラス - Bardelas + バルデラス + 바델라스 자주대공포 "布萊德斯"防空車 - "布莱德斯"防空车 + "布莱德斯" + Bardelas Badger IFV @@ -316,10 +335,11 @@ Badger IFV Badger IFV Badger IFV - バッジ IFV - Badger IFV + バジャー IFV + 뱃져 보병전투차 "蜜獾"步兵戰車 - "蜜獾"步兵战车 + "蜜獾" + Badger IFV Nemmera @@ -333,9 +353,10 @@ Nemmera Nemmera ネマラ - Nemmera + 네메라 공병장갑차 "雌豹"戰鬥工程車 - "雌豹"战斗工程车 + "雌豹" + Nemmera HEMTT Transport @@ -344,14 +365,15 @@ HEMTT Transportowy HEMTT (valník) HEMTT Transport - HEMTT Транспортный + HEMTT (транспортный) HEMTT Transporte HEMTT szállítójármű HEMTT da trasporto - HEMTT 輸送型 + HEMTT 輸送 HEMTT 수송 重型增程機動戰術卡車 (運輸) - 重型增程机动战术卡车 (运输) + HEMTT(运输) + HEMTT Nakil HEMTT Transport (covered) @@ -360,14 +382,15 @@ HEMTT Transportowy (zakryty) HEMTT (valník-krytý) HEMTT Transport (bâché) - HEMTT Транспортный (крытый) + HEMTT (транспортный, крытый) HEMTT Transporte (coberto) HEMTT szállítójármű (ponyvás) HEMTT da trasporto (coperto) - HEMTT 輸送型 (幌) + HEMTT 輸送 (幌) HEMTT 수송 (덮개) 重型增程機動戰術卡車 (運輸, 棚布) - 重型增程机动战术卡车 (运输, 棚布) + HEMTT(运输,棚布) + HEMTT Nakil (Kapalı) HEMTT @@ -383,7 +406,8 @@ HEMTT HEMTT 重型增程機動戰術卡車 - 重型增程机动战术卡车 + HEMTT + HEMTT HEMTT Container @@ -392,14 +416,15 @@ HEMTT Kontener HEMTT (skříňový) HEMTT Conteneur - HEMTT Контейнер + HEMTT (контейнер) HEMTT Contêiner HEMTT (konténer) HEMTT portacontainer - HEMTT コンテナ型 + HEMTT コンテナ HEMTT 컨테이너 重型增程機動戰術卡車 (貨櫃) - 重型增程机动战术卡车 (货柜) + HEMTT(货柜) + HEMTT Konteynır HEMTT Medical @@ -408,14 +433,15 @@ HEMTT Medyczny HEMTT (zdravotnický) HEMTT Médical - HEMTT Медицинский + HEMTT (медицинский) HEMTT Médico HEMTT (egészségügyi) HEMTT Medico - HEMTT 救急車 + HEMTT 衛生 HEMTT 의료 重型增程機動戰術卡車 (醫療) - 重型增程机动战术卡车 (医疗) + HEMTT(医疗) + HEMTT Medikal HEMTT Ammo @@ -424,14 +450,15 @@ HEMTT Amunicyjny HEMTT (muniční) HEMTT Munitions - HEMTT Боеприпасы + HEMTT (боеприпасы) HEMTT Munições HEMTT (lőszerszállító) - HEMTT di rifornimento munizioni - HEMTT 弾薬給弾型 + HEMTT Munizioni + HEMTT 弾薬 HEMTT 탄약 重型增程機動戰術卡車 (彈藥) - 重型增程机动战术卡车 (弹药) + HEMTT(弹药) + HEMTT Cephane HEMTT Fuel @@ -440,14 +467,15 @@ HEMTT Cysterna HEMTT (cisterna) HEMTT Citerne - HEMTT Заправщик + HEMTT (топливозаправщик) HEMTT Combustível HEMTT (üzemanyag-szállító) - HEMTT di rifornimento carburante - HEMTT 燃料給油車 + HEMTT Carburante + HEMTT 燃料 HEMTT 연료 重型增程機動戰術卡車 (燃油) - 重型增程机动战术卡车 (燃油) + HEMTT(燃油) + HEMTT Yakıt HEMTT Repair @@ -456,14 +484,15 @@ HEMTT Naprawczy HEMTT (opravárenský) HEMTT Réparation - HEMTT Ремонтный + HEMTT (ремонтный) HEMTT Reparador HEMTT (szerelő-jármű) - HEMTT Riparatore - HEMTT 修理型 + HEMTT Riparazioni + HEMTT 修理 HEMTT 수리 重型增程機動戰術卡車 (維修) - 重型增程机动战术卡车 (维修) + HEMTT(维修) + HEMTT Tamir Fennek @@ -472,14 +501,15 @@ Fennek Fennek Fennek - Феннек + Fennek Fennek Fennek Fennek フェネック - Fennek + 페넥 "非洲小狐"防地雷反伏擊車 - "非洲小狐"防地雷反伏击车 + "非洲小狐" + Fennek Fennek (HMG) @@ -488,14 +518,15 @@ Fennek (CKM) Fennek (HMG) Fennek (HMG) - Феннек (Пулемёт) + Fennek (с пулемётом) Fennek (HMG) Fennek (nehézgéppuska) Fennek (HMG) フェネック (HMG) - Fennek (HMG) + 페넥 (중기관총) "非洲小狐"防地雷反伏擊車 (重機槍) - "非洲小狐"防地雷反伏击车 (重机枪) + "非洲小狐"(重机枪) + Fennek (HMG) Fennek (GMG) @@ -504,14 +535,15 @@ Fennek (GMG) Fennek (GMG) Fennek (GMG) - Феннек (Гранатомёт) + Fennek (с гранатомётом) Fennek (GMG) Fennek (gránátgéppuska) Fennek (GMG) フェネック (GMG) - Fennek (GMG) + 페넥 (유탄기관총) "非洲小狐"防地雷反伏擊車 (榴彈機槍) - "非洲小狐"防地雷反伏击车 (榴弹机枪) + "非洲小狐"(榴弹发射器) + Fennek (GMG) Leopard 2SG @@ -520,14 +552,15 @@ Leopard 2SG Leopard 2SG Leopard 2SG - Леопард 2SG + Leopard 2SG Leopard 2SG Leopard 2SG Leopard 2SG - レオパルド 2SG - Leopard 2SG + レオパルト2SG + 레오파르트 2SG "豹2型新加坡版"主戰坦克 - "豹2型新加坡版"主战坦克 + "豹"2 新加坡版 + Leopard 2SG FV510 Warrior @@ -536,14 +569,15 @@ FV510 Warrior FV510 Warrior FV510 Warrior - FV510 Уорриор + FV510 Warrior FV510 Warrior FV510 Warrior FV510 Warrior - FV510 ウォーリアー - FV510 Warrior - FV510"戰士"步兵戰車 - FV510"战士"步兵战车 + FV510 ウォーリア + FV510 워리어 보병전투차 + FV510 "戰士"步兵戰車 + FV510 "战士" + FV510 Warrior Pandur II @@ -557,9 +591,10 @@ Pandur II Pandur II パンデュール II - Pandur II + 판두르 II 병력수송장갑차 "潘德2型"裝甲運兵車 - "潘德2型"装甲运兵车 + "潘德"二型 + Pandur II KamAZ Transport @@ -568,14 +603,15 @@ KamAZ transportowy KamAZ (valník) KamAZ Transport - КамАЗ Транспортный + КамАЗ (транспортный) KamAZ Transporte KamAZ szállítójármű KamAZ da trasporto - KamAZ 輸送型 - KamAZ 수송 + KamAZ 輸送 + 카마즈 수송 "卡瑪斯"卡車 (運輸) - "卡玛斯"卡车 (运输) + "卡玛兹"(运输) + KamAZ Nakil KamAZ Transport (covered) @@ -584,14 +620,15 @@ KamAZ Transportowy (zakryty) KamAZ (valník-krytý) KamAZ Transport (bâché) - КамАЗ Транспортный (крытый) + КамАЗ (транспортный, крытый) KamAZ Transporte (coberto) KamAZ szállítójármű (ponyvás) KamAZ da trasporto (coperto) - KamAZ 輸送型 (幌) - KamAZ 수송 (덮개) + KamAZ 輸送 (幌) + 카마즈 수송 (덮개) "卡瑪斯"卡車 (運輸, 棚布) - "卡玛斯"卡车 (运输, 棚布) + "卡玛兹"(运输,棚布) + KamAZ Nakil (Kapalı) KamAZ Ammo @@ -600,14 +637,15 @@ KamAZ Amunicyjny KamAZ (muniční) KamAZ Munitions - КамАЗ Боеприпасы + КамАЗ (боеприпасы) KamAZ Munições KamAZ (lőszerszállító) - KamAZ di rifornimento munizioni - KamAZ 弾薬給弾型 - KamAZ 탄약 + KamAZ Munizioni + KamAZ 弾薬 + 카마즈 탄약 "卡瑪斯"卡車 (彈藥) - "卡玛斯"卡车 (弹药) + "卡玛兹"(弹药) + KamAZ Cephane KamAZ Fuel @@ -616,14 +654,15 @@ KamAZ cysterna KamAZ (cisterna) KamAZ Citerne - КамАЗ Заправщик + КамАЗ (топливозаправщик) KamAZ Combustível KamAZ (üzemanyag-szállító) - KamAZ di rifornimento carburante - KamzAZ 燃料給油車 - KamAZ 연료 + KamAZ Carburante + KamAZ 燃料 + 카마즈 연료 "卡瑪斯"卡車 (燃油) - "卡玛斯"卡车 (燃油) + "卡玛兹"(燃油) + KamAZ Yakıt KamAZ Repair @@ -632,14 +671,15 @@ KamAZ Naprawczy KamAZ (opravárenský) KamAZ Réparation - КамАЗ Ремонтный + КамАЗ (ремонтный) KamAZ Reparador KamAZ (szerelő-jármű) - KamAZ riparatore - KamzAZ 修理型 - KamAZ 수리 + KamAZ Riparazioni + KamAZ 修理 + 카마즈 수리 "卡瑪斯"卡車 (維修) - "卡玛斯"卡车 (维修) + "卡玛兹"(维修) + KamAZ Tamir KamAZ Medical @@ -648,24 +688,40 @@ KamAZ Medyczny KamAZ (zdravotnický) KamAZ Médical - КамАЗ Медицинский + КамАЗ (медицинский) KamAZ Médico KamAZ (egészségügyi) KamAZ Medico - KamAZ 救急車 - KamAZ 의료 + KamAZ 衛生 + 카마즈 의료 "卡瑪斯"卡車 (醫療) - "卡玛斯"卡车 (医疗) + "卡玛兹"(医疗) + KamAZ Medikal + + + KamAZ Water + KamAZ Água + KamAZ 給水 + КамАЗ (водоноситель) + 카마즈 급수 + KamAS Wasser + KamAZ Acqua KamAZ MRL KamAS MRL "卡瑪斯"卡車 (多管火箭) - "卡玛斯"卡车 (多管火箭) + "卡玛兹"(多管火箭) KamAZ MRL KamAZ MRL KamAZ MRL КамАЗ РСЗО + KamAZ MRL + KamAZ LRM + KamAZ MRL (raketové dělostřelectvo) + KamAZ MRL + KamAZ + 카마즈 다연장로켓 Karatel @@ -674,14 +730,15 @@ Karatel Karatel Karatel - Kаратель + Каратель Karatel Karatel Karatel カラテル - Karatel + 카라텔 "懲罰者"防地雷反伏擊車 - "惩罚者"防地雷反伏击车 + "宪兵" + Karatel Karatel (HMG) @@ -690,14 +747,15 @@ Karatel (CKM) Karatel (HMG) Karatel (HMG) - Kаратель (Пулемёт) + Каратель (с пулемётом) Karatel (HMG) Karatel (nehézgéppuska) Karatel (HMG) カラテル (HMG) - Karatel (HMG) + 카라텔 (중기관총) "懲罰者"防地雷反伏擊車 (重機槍) - "惩罚者"防地雷反伏击车 (重机枪) + "宪兵"(重机枪) + Karatel (HMG) Karatel (GMG) @@ -706,14 +764,15 @@ Karatel (GMG) Karatel (GMG) Karatel (GMG) - Kаратель (Гранатомёт) + Каратель (с гранатомётом) Karatel (GMG) Karatel (gránátgéppuska) Karatel (GMG) カラテル (GMG) - Karatel (GMG) + 카라텔 (유탄기관총) "懲罰者"防地雷反伏擊車 (榴彈機槍) - "惩罚者"防地雷反伏击车 (榴弹机枪) + "宪兵"(榴弹发射器) + Karatel (GMG) T100 Black Eagle @@ -727,9 +786,10 @@ T100 Fekete Sas T100 Black Eagle T100 ブラック イーグル - T100 Black Eagle - T100"黑鷹"主戰坦克 - T100"黑鹰"主战坦克 + T-100 블랙 이글 + T100 "黑鷹"主戰坦克 + T-100 "黑鹰" + T100 Black Eagle 2S9 Sochor @@ -743,9 +803,10 @@ 2S9 Sochor 2S9 Sochor 2S9 ソーカー - 2S9 Sochor - 2S9"薩克爾"自走砲 - 2S9"萨克尔"自走炮 + 2S9 소코르 + 2S9 "薩克爾"自走砲 + 2S9 "索科尔" + 2S9 Sochor BM-2T Stalker @@ -759,9 +820,10 @@ BM-2T Stalker BM-2T Stalker BM-2T ストーカー - BM-2T Stalker + BM-2T 스토커 BM-2T"潛行者"步兵戰車 - BM-2T"潜行者"步兵战车 + BM-2T "潜行者" + BM-2T Stalker ZSU-35 Tigris @@ -775,9 +837,10 @@ ZSU-35 Tigris ZSU-35 Tigris ZSU-35 ティグリス - ZSU-35 Tigris - ZSU-35"虎式"防空車 - ZSU-35"虎式"防空车 + ZSU-35 티그리스 + ZSU-35 "虎式"防空車 + ZSU-35 "底格里斯" + ZSU-35 Tigris Otokar ARMA @@ -791,9 +854,10 @@ Otokar ARMA Otokar ARMA オトカ アルマ - Otokar ARMA - "奧托卡-阿爾默"裝甲運兵車 - "奥托卡-阿尔默"装甲运兵车 + 오토카르 아르마 APC + "奧托卡—阿爾默"裝甲運兵車 + 奥托卡尔 "阿玛" + Otokar ARMA Typhoon Transport @@ -802,14 +866,15 @@ Typhoon Transportowy KamAZ Typhoon (valník) Typhoon Transport - Тайфун Транспортный + Тайфун (транспортный) Typhoon Transporte Typhoon szállítójármű Typhoon da trasporto - タイフーン 輸送型 - Typhoon 수송 + タイフーン 輸送 + 타이푼 수송 "颱風"卡車 (運輸) - "台风"卡车 (运输) + "台风"(运输) + Typhoon Nakil Typhoon Transport (covered) @@ -818,14 +883,15 @@ Typhoon Transportowy (przykryty) KamAZ Typhoon (valník-krytý) Typhoon Transport (bâché) - Тайфун Транспортный (крытый) + Тайфун (крытый) Typhoon Transporte (coberto) Typhoon szállítójármű (ponyvás) Typhoon da trasporto (coperto) - タイフーン 輸送型 (幌) - Typhoon 수송 (덮개) + タイフーン 輸送 (幌) + 타이푼 수송 (덮개) "颱風"卡車 (運輸, 棚布) - "台风"卡车 (运输, 棚布) + "台风"(运输,棚布) + Typhoon Nakil (Kapalı) Typhoon Device @@ -834,14 +900,15 @@ Typhoon Urządzenie KamAZ Typhoon (zařízení) Typhoon Dispositif - Тайфун Устройство + Тайфун (устройство) Typhoon Dispositivo Typhoon (eszköz) - Typhoon per dispositivo - タイフーン デバイス型 - Typhoon 장치 + Typhoon con Dispositivo + タイフーン デバイス + 타이푼 장치 "颱風"卡車 (精密設備) - "台风"卡车 (精密设备) + "台风"(装置) + Typhoon Cihaz Typhoon Ammo @@ -850,14 +917,15 @@ Typhoon Amunicyjny KamAZ Typhoon (muniční) Typhoon Munitions - Тайфун Боеприпасы + Тайфун (боеприпасы) Typhoon Munições Typhoon (lőszerszállító) - Typhoon di rifornimento munizioni - タイフーン 弾薬給弾型 - Typhoon 탄약 + Typhoon Munizioni + タイフーン 弾薬 + 타이푼 탄약 "颱風"卡車 (彈藥) - "台风"卡车 (弹药) + "台风"(弹药) + Typhoon Cephane Typhoon Fuel @@ -866,14 +934,15 @@ Typhoon Cysterna KamAZ Typhoon (cisterna) Typhoon Citerne - Тайфун Заправщик + Тайфун (топливозаправщик) Typhoon Combustível Typhoon (üzemanyag-szállító) - Typhoon di rifornimento carburante - タイフーン 燃料給油車 - Typhoon 연료 + Typhoon Carburante + タイフーン 燃料 + 타이푼 연료 "颱風"卡車 (燃油) - "台风"卡车 (燃油) + "台风"(燃油) + Typhoon Yakıt Typhoon Repair @@ -882,14 +951,15 @@ Typhoon Naprawczy KamAZ Typhoon (opravárenský) Typhoon Réparation - Тайфун Ремонтный + Тайфун (ремонтный) Typhoon Reparador Typhoon (szerelő-jármű) - Typhoon riparatore - タイフーン 修理型 - Typhoon 수리 + Typhoon Riparazioni + タイフーン 修理 + 타이푼 수리 "颱風"卡車 (維修) - "台风"卡车 (维修) + "台风"(维修) + Typhoon Tamir Typhoon Medical @@ -898,14 +968,15 @@ Typhoon Medyczny KamAZ Typhoon (zdravotnický) Typhoon Médical - Тайфун Медицинский + Тайфун (медицинский) Typhoon Médico Typhoon (egészségügyi) - Typhoon medico - タイフーン 救急車 - Typhoon 의료 + Typhoon Medico + タイフーン 衛生 + 타이푼 의료 "颱風"卡車 (醫療) - "台风"卡车 (医疗) + "台风"(医疗) + Typhoon Medikal RAH-66 Comanche @@ -913,15 +984,16 @@ RAH-66 Comanche RAH-66 Comanche RAH-66 Comanche - RAH-66 Commanche - RAH-66 Команч + RAH-66 Comanche + RAH-66 Comanche RAH-66 Comanche RAH-66 Comanche RAH-66 Comanche RAH-66 コマンチ - RAH-66 Comanche - RAH-66"卡曼契"攻擊直升機 - RAH-66"卡曼契"攻击直升机 + RAH-66 코만치 + RAH-66 "卡曼契"攻擊直升機 + RAH-66 "科曼奇" + RAH-66 Comanche MH-6 Little Bird @@ -935,9 +1007,10 @@ MH-6 Little Bird MH-6 Little Bird MH-6 リトル バード - MH-6 Little Bird - MH-6"小鳥"運輸直升機 - MH-6"小鸟"运输直升机 + MH-6 리틀버드 + MH-6 "小鳥"運輸直升機 + MH-6 "小鸟" + MH-6 Little Bird AH-6 Little Bird @@ -951,9 +1024,10 @@ AH-6 Little Bird AH-6 Little Bird AH-6 リトル バード - AH-6 Little Bird - AH-6"小鳥"武裝直升機 - AH-6"小鸟"武装直升机 + AH-6 리틀버드 + AH-6 "小鳥"武裝直升機 + AH-6 "小鸟" + AH-6 Little Bird CH-47I Chinook @@ -967,9 +1041,10 @@ CH-47I Chinook CH-47I Chinook CH-47I チヌーク - CH-47I Chinook + CH-47I 치누크 CH-47I"契努克"運輸直升機 - CH-47I"契努克"运输直升机 + CH-47I "支努干" + CH-47I Chinook CH-47I Chinook (unarmed) @@ -983,9 +1058,10 @@ CH-47I Chinook (disarmato) CH-47I Chinook (desarmado) CH-47I チヌーク (非武装) - CH-47I Chinook (비무장) + CH-47I 치누크 (비무장) CH-47I"契努克"運輸直升機 (無武裝) - CH-47I"契努克"运输直升机 (无武装) + CH-47I "支努干"(无武装) + CH-47I Chinook (silahsız) A-10D Thunderbolt II @@ -994,14 +1070,15 @@ A-10D Thunderbolt II A-10D Thunderbolt II A-10D Thunderbolt II - A-10D Тандерболт II + A-10D Thunderbolt II A-10D Thunderbolt II A-10D Thunderbolt II A-10D Thunderbolt II A-10D サンダーボルト II - A-10D Thunderbolt II + A-10D 썬더볼트 II A-10D"雷霆二式"攻擊機 - A-10D"雷霆二式"攻击机 + A-10D "雷霆"二式 + A-10D Thunderbolt II AW159 Wildcat @@ -1015,9 +1092,10 @@ AW159 Wildcat AW159 Wildcat AW159 ワイルドキャット - AW159 Wildcat - AW159"野貓"直升機 - AW159"野猫"直升机 + AW159 와일드캣 + AW159 "野貓"直升機 + AW159 "野猫" + AW159 Wildcat AW159 Wildcat (unarmed) @@ -1031,9 +1109,10 @@ AW159 Wildcat (fegyvertelen) AW159 Wildcat (disarmato) AW159 ワイルドキャット (非武装) - AW159 Wildcat (비무장) - AW159"野貓"直升機 (無武裝) - AW159"野猫"直升机 (无武装) + AW159 와일드캣 (비무장) + AW159 "野貓"直升機 (無武裝) + AW159 "野猫"(无武装) + AW159 Wildcat (silahsız) AW101 Merlin @@ -1042,14 +1121,15 @@ AW101 Merlin AW101 Merlin AW101 Merlin - AW101 Мерлин + AW101 Merlin AW101 Merlin AW101 Merlin AW101 Merlin AW101 マーリン - AW101 Merlin - AW101"灰背隼"運輸直升機 - AW101"灰背隼"运输直升机 + AW101 멀린 + AW101 "灰背隼"運輸直升機 + AW101 "灰背隼" + AW101 Merlin L-159 ALCA @@ -1058,14 +1138,15 @@ L-159 ALCA L-159 ALCA L-159 ALCA - L-159 Альбатрос + L-159 ALCA L-159 ALCA L-159 ALCA L-159 ALCA L-159 ALCA L-159 ALCA L-159先進輕型戰鬥機 - L-159先进轻型战斗机 + L-159 ALCA + L-159 ALCA L-159 ALCA (CAS) @@ -1074,14 +1155,15 @@ L-159 ALCA (CAS) L-159 ALCA (CAS) L-159 ALCA (CAS) - L-159 Альбатрос (CAS) + L-159 ALCA (поддержка) L-159 ALCA (CAS) L-159 ALCA (Légitámogató) L-159 ALCA (CAS) L-159 ALCA (CAS) L-159 ALCA (근접지원) L-159先進輕型戰鬥機 (近空支援) - L-159先进轻型战斗机 (近空支援) + L-159 ALCA(近空支援) + L-159 ALCA (CAS) L-159 ALCA (AA) @@ -1090,14 +1172,15 @@ L-159 ALCA (AA) L-159 ALCA (AA) L-159 ALCA (AA) - L-159 Альбатрос (AA) - L-159 ALCA (ВВ) + L-159 ALCA (ВВ) + L-159 ALCA (AA) L-159 ALCA (Repülő-elhárító) L-159 ALCA (AA) L-159 ALCA (対空) L-159 ALCA (대공) L-159先進輕型戰鬥機 (空對空) - L-159先进轻型战斗机 (空对空) + L-159 ALCA(空对空) + L-159 ALCA (AA) JAS 39 Gripen @@ -1106,13 +1189,14 @@ JAS 39 Gripen JAS 39 Gripen JAS 39 Gripen - JAS 39 Грипен + JAS 39 Gripen JAS 39 Gripen JAS 39 Gripen JAS 39 グリペン JAS 39 그리펜 JAS 39 獅鷲戰鬥機 - JAS 39 狮鹫战斗机 + JAS 39 "狮鹫" + JAS 39 Gripen Ka-60 Kasatka @@ -1126,9 +1210,10 @@ Ka-60 Kasatka Ka-60 Kasatka Ka-60 カサートカ - Ka-60 Kasatka - Ka-60"逆戟鯨"直升機 - Ka-60"逆戟鲸"直升机 + Ka-60 카사트카 + Ka-60 "逆戟鯨"直升機 + Ka-60 "虎鲸" + Ka-60 Kasatka Ka-60 Kasatka (Black & White) @@ -1138,12 +1223,13 @@ Ka-60 Kasatka (bianco e nero) Ka-60 Kasatka (czarno-biały) Ka-60 Kasatka (preto e branco) - Ka-60 Касатка (белый и черный) + Ka-60 Касатка (чёрно-белый) Ka-60 Kasatka (blanco y negro) - Ka-60 カサートカ (黒 & 白) - Ka-60 Kasatka (검정 및 하양) - Ka-60"逆戟鯨"直升機 (黑&白) - Ka-60"逆戟鲸"直升机 (黑&白) + Ka-60 カサートカ (ブラック & ホワイト) + Ka-60 카사트카 (검정 및 하양) + Ka-60 "逆戟鯨"直升機 (黑&白) + Ka-60 "虎鲸"(黑白) + Ka-60 Kasatka (Siyah & Beyaz) Ka-60 Kasatka (unarmed) @@ -1157,9 +1243,10 @@ Ka-60 Kasatka (fegyvertelen) Ka-60 Kasatka (disarmato) Ka-60 カサートカ (非武装) - Ka-60 Kasatka (비무장) - Ka-60"逆戟鯨"直升機 (無武裝) - Ka-60"逆戟鲸"直升机 (无武装) + Ka-60 카사트카 (비무장) + Ka-60 "逆戟鯨"直升機 (無武裝) + Ka-60 "虎鲸"(无武装) + Ka-60 Kasatka (Silahsız) Yak-130 @@ -1174,8 +1261,9 @@ Yak-130 Yak-130 Yak-130 - Yak-130"手套"攻擊機 - Yak-130"手套"攻击机 + Yak-130 "手套"攻擊機 + Yak-130 + Yak-130 MD 500 @@ -1190,8 +1278,9 @@ MD 500 MD 500 MD 500 - MD 500"防衛者"直升機 - MD 500"防卫者"直升机 + MD 500 "防衛者"直升機 + MD 500 "防卫者" + MD 500 M4A1 SLAM @@ -1207,7 +1296,8 @@ M4A1 SLAM M4A1 SLAM M4A1指向性反裝甲地雷 - M4A1指向性反装甲地雷 + M4A1 指向性反装甲地雷 + M4A1 SLAM M18A1 Claymore @@ -1219,11 +1309,12 @@ M18A1 Клеймор M18A1 Claymore M18A1 Claymore akna - M18A1 Claymore Mina antiuomo + M18A1 Claymore Mina Antiuomo M18A1 クレイモア M18A1 클레이모어 - M18A1"闊刀"地雷 - M18A1"阔刀"地雷 + M18A1 "闊刀"地雷 + M18A1 "阔剑" + M18A1 Claymore M183 Demolition Charge Assembly @@ -1231,15 +1322,29 @@ Conjunto de carga de demolición M183 Ładunek burzący M183 Demoliční nálož M183 - M183 Charge de Démolition - M183 Комплектный подрывной заряд + M183 Charge de démolition + M183 комплектный подрывной заряд M183 Sacola de Demolição M183 romboló töltet - M183 Demolition Charge Assembly + M183 Carica da Demolizioni M183 梱包爆薬 M183 폭파 장약 조립 M183炸藥包 - M183炸药包 + M183 炸药包 + M183 Demolition Charge Assembly + + + M183 Demolition Charge (Throwable) + M183 Charge de démolition (lançable) + M183 Carica da Demolizioni (Lanciabile) + M183 梱包爆薬 (投擲仕様) + M183 Demolition Charge (Throwable) + Carga de demolición M183 (Lanzable) + M183 комплектный подрывной заряд (бросаемый) + Ładunek burzący M183 (Rzucany) + M183 Geballte Sprengladung (Werfbar) + M183 炸药包(可投掷) + M183 폭파 장약 (투척) M112 Demolition Block @@ -1247,15 +1352,29 @@ Bloque de demolición M112 Ładunek burzący M112 Výbušná nálož M112 - M112 Block de Démolition + M112 Bloc de démolition M112 подрывной заряд M112 Carga de Demolição M112 romboló tömb - M112 da Demolizione + M112 Blocco da Demolizione M112 爆薬ブロック M112 폭파 블럭 M112塑性炸藥 - M112塑性炸药 + M112 塑性炸药 + M112 Demolition Block + + + M112 Demolition Charge (Throwable) + M112 Bloc de démolition (lançable) + M112 Blocco da Demolizione (Lanciabile) + M112 爆薬ブロック (投擲仕様) + M112 Demolition Charge (Throwable) + Bloque de demolición M112 (Lanzable) + M112 подрывной заряд (бросаемый) + Ładunek burzący M112 (Rzucany) + M112 Sprengladung (Werfbar) + M112 塑性炸药(可投掷) + M112 폭파 장약 (투척) M67 Fragmentation Grenade @@ -1271,7 +1390,8 @@ M67 破片手榴弾 M67 세열 수류탄 M67破片手榴彈 - M67破片手榴弹 + M67 破片手榴弹 + M67 El Bombası V40 Mini-Grenade @@ -1279,7 +1399,15 @@ Mini Granata V40 V40 小型手榴弾 Mini-granat V40 - V40 Мини-граната + V40 мини-граната + Mini Granada V40 + V40 Mini-Grenade + V40迷你手榴彈 + V40 Mini-Granát + Mini Granada V40 + V40 Mini-El Bombası + V40 迷你手榴弹 + V40 소형 수류탄 M83 Smoke Grenade (White) @@ -1288,14 +1416,15 @@ Granat dymny M83 (Biały) M83 Kouřový Granát (Bílý) M83 Grenade fumigène (Blanche) - M83 дымовая граната (Белый) + M83 дымовая граната (белый) M83 Granada de fumaça (Branca) M83 füstgránát (Fehér) M83 Granata fumogena (Bianco) - M18 発煙手榴弾 (白) + M83 発煙手榴弾 (白) M83 연막탄 (하양) M83煙霧彈 (白色) - M83烟雾弹 (白色) + M83 烟雾弹(白色) + M83 Sis Bombası (Beyaz) M18 Smoke Grenade (Blue) @@ -1304,14 +1433,15 @@ Granat dymny M18 (Niebieski) M18 Kouřový Granát (Modrý) M18 Grenade fumigène (Bleue) - M18 дымовая граната (Синий) + M18 дымовая граната (синий) M18 Granada de fumaça (Azul) M18 füstgránát (Kék) M18 Granata fumogena (Blu) M18 発煙手榴弾 (青) M18 연막탄 (파랑) M18煙霧彈 (藍色) - M18烟雾弹 (蓝色) + M18 烟雾弹(蓝色) + M83 Sis Bombası (Mavi) M18 Smoke Grenade (Green) @@ -1320,14 +1450,15 @@ Granat dymny M18 (Zielony) M18 Kouřový Granát (Zelený) M18 Grenade fumigène (Verte) - M18 дымовая граната (Зелёный) + M18 дымовая граната (зелёный) M18 Granada de fumaça (Verde) M18 füstgránát (Zöld) M18 Granata fumogena (Verde) - M18 煙幕手榴弾 (緑) + M18 発煙手榴弾 (緑) M18 연막탄 (초록) M18煙霧彈 (綠色) - M18烟雾弹 (绿色) + M18 烟雾弹(绿色) + M83 Sis Bombası (Yeşil) M18 Smoke Grenade (Orange) @@ -1336,14 +1467,15 @@ Granat dymny M18 (Pomarańczowy) M18 Kouřový Granát (Oranžový) M18 Grenade fumigène (Orange) - M18 дымовая граната (Оранжевый) + M18 дымовая граната (оранжевый) M18 Granada de fumaça (Laranja) M18 füstgránát (Narancssárga) M18 Granata fumogena (Arancione) M18 発煙手榴弾 (橙) M18 연막탄 (주황) M18煙霧彈 (橘色) - M18烟雾弹 (橘色) + M18 烟雾弹(橘色) + M83 Sis Bombası (Turuncu) M18 Smoke Grenade (Purple) @@ -1352,14 +1484,15 @@ Granat dymny M18 (Fioletowy) M18 Kouřový Granát (Fialový) M18 Grenade fumigène (Pourpre) - M18 дымовая граната (Пурпурный) + M18 дымовая граната (пурпурный) M18 Granada de fumaça (Roxa) M18 füstgránát (Lila) M18 Granata fumogena (Viola) M18 発煙手榴弾 (紫) M18 연막탄 (보라) M18煙霧彈 (紫色) - M18烟雾弹 (紫色) + M18 烟雾弹(紫色) + M83 Sis Bombası (Mor) M18 Smoke Grenade (Red) @@ -1368,14 +1501,15 @@ Granat dymny M18 (Czerwony) M18 Kouřový Granát (Červený) M18 Grenade fumigène (Rouge) - M18 дымовая граната (Красный) + M18 дымовая граната (красный) M18 Granada de fumaça (Vermelha) M18 füstgránát (Piros) M18 Granata fumogena (Rosso) - M18 煙幕手榴弾 (赤) + M18 発煙手榴弾 (赤) M18 연막탄 (빨강) M18煙霧彈 (紅色) - M18烟雾弹 (红色) + M18 烟雾弹(红色) + M83 Sis Bombası (Kırmızı) M18 Smoke Grenade (Yellow) @@ -1384,14 +1518,15 @@ Granat dymny M18 (Żółty) M18 Kouřový Granát (Žlutý) M18 Grenade fumigène (Jaune) - M183 дымовая граната (Жёлтый) + M18 дымовая граната (жёлтый) M18 Granada de fumaça (Amarela) M18 füstgránát (Sárga) M18 Granata fumogena (Giallo) M18 発煙手榴弾 (黄) M18 연막탄 (노랑) M18煙霧彈 (黃色) - M18烟雾弹 (黄色) + M18 烟雾弹(黄色) + M83 Sis Bombası (Sarı) M15 Anti-Tank Mine @@ -1403,11 +1538,12 @@ M15 противотанковая мина M15 Mina anticarro M15 harckocsiakna - M15 Mine anticarro + M15 Mina Anticarro M15 対戦車地雷 M15 대전차지뢰 M15反坦克地雷 - M15反坦克地雷 + M15 反坦克地雷 + M15 Anti-Tank Mayını VS-50 Anti-Personnel Mine @@ -1416,14 +1552,15 @@ Mina przeciwpiechotna VS-50 VS-50 Protipěchotní mina VS-50 Mine AP - VS-50 Противопехотная мина + VS-50 противопехотная мина VS-50 Mina antipessoal VS-50 gyalogsági taposóakna - VS-50 Mine antiuomo + VS-50 Mina Antiuomo VS-50 対人地雷 VS-50 대인지뢰 VS-50反人員地雷 - VS-50反人员地雷 + VS-50 反人员地雷 + VS-50 Anti-Personel Mayını M26 Anti-Personnel Bounding Mine @@ -1431,15 +1568,16 @@ Mina antipersona M26 Mina przeciwpiechotna M26 M26 Protipěchotní mina - M26 Mine AP bondissante - M26 Противопехотная мина + M26 Mine AP bondissante + M26 противопехотная мина M26 Mina saltadora antipessoal M26 gyalogsági ugróakna - M26 Mine saltanti antiuomo + M26 Mina Antiuomo Saltante M26 対人跳躍地雷 M26 대인도약지뢰 M26反人員彈跳雷 - M26反人员弹跳雷 + M26 反人员跳雷 + M26 Anti Personel Mayını PMR-3 Anti-Personnel Tripwire Mine @@ -1448,14 +1586,15 @@ Mina przeciwpiechotna PMR-3 PMR-3 Protipěchotní mina (drát) PMR-3 Mine AP à traction - PMR-3 Противопехотная мина + PMR-3 противопехотная мина PMR-3 Mina antipessoal (armadilha) PMR-3 botlódrótos gyalogsági akna - PMR-3 Mine antiuomo - PMR-3 仕掛け型対人地雷 + PMR-3 Mina Antiuomo + PMR-3 仕掛け線対人地雷 PMR-3 대인인계철선지뢰 PMR-3反人員絆線雷 - PMR-3反人员绊线雷 + PMR-3 反人员绊雷 + PMR-3 Telli Anti Personel Mayını P99 @@ -1471,7 +1610,8 @@ P99 P99 P99手槍 - P99手枪 + P99 + P99 MP-443 Grach @@ -1481,13 +1621,14 @@ MP-443 Grach MP-443 Grach MP-443 Grach - МР-443 "Грач" + МР-443 Грач MP-443 Grach MP-443 Grach MP-433 グラッチ - MP-443 Grach - MP-443"烏鴉"手槍 - MP-443"乌鸦"手枪 + MP-443 그라치 + MP-443 "烏鴉"手槍 + MP-443 "乌鸦" + MP-443 Grach Custom Covert II @@ -1499,11 +1640,12 @@ Custom Covert II Custom Covert II Custom Covert II - ACP-C2 - カスタム コンバート II - Custom Covert II + Custom Covert II + カスタム コバートⅡ + 커스텀 커버트 II 特裝隱蔽Ⅱ型手槍 - 特装隐蔽Ⅱ型手枪 + 金柏特特装隐蔽二型 + Custom Covert II FNX-45 Tactical @@ -1516,10 +1658,46 @@ FNX-45 Tactical FNX-45 Tactical FNX-45 Tactical + FNX-45 Tactical FNX-45 タクティカル - FNX-45 Tactical + FNX-45 택티컬 FNX-45戰術型手槍 - FNX-45战术型手枪 + FNX-45 战术型 + + + CZ 581 + CZ 581 + CZ 581 + CZ 581 + CZ 581 + CZ 581 + CZ 581 + + + CZ 581 (Sawed-Off) + CZ 581 (Cano serrado) + CZ 581 (ソードオフ) + CZ 581 (Sawed-Off) + CZ 581 (소드오프) + CZ 581 (Abgesägt) + CZ 581 (Canne mozze) + + + FNX-45 Tactical (Green) + FNX-45 Tactical (Grün) + 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 택티컬 (초록) + FNX-45戰術型手槍 (綠色) + FNX-45 战术型(绿色) Chiappa Rhino 60DS @@ -1533,9 +1711,10 @@ Chiappa Rhino 60DS Chiappa Rhino 6DS チアッパ ライノ 60DS - Chiappa Rhino 60DS + 키아파 라이노 60DS 齊亞帕"犀牛"60DS左輪手槍 - 齐亚帕"犀牛"60DS左轮手枪 + 齐亚帕"犀牛" 60DS + Chiappa Rhino 60DS Taurus Judge @@ -1549,9 +1728,10 @@ Taurus Judge Taurus Judge タウルス ジャッジ - Taurus Judge + 타우러스 저지 金牛座"法官"信號槍 - 金牛座"法官"信号枪 + 金牛座"法官" + Taurus Judge NLAW @@ -1567,7 +1747,8 @@ NLAW NLAW 次世代輕型反坦克導彈發射器 - 次世代轻型反坦克导弹发射器 + NLAW + NLAW RPG-32 @@ -1580,10 +1761,28 @@ РПГ-32 RPG-32 RPG-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) @@ -1593,13 +1792,14 @@ Mini-Spike (AA) Mini-Spike (Repülő-elhárító) Mini-Spike (AA) - Mini-Spike (ПВО) + Mini-Spike (ЗРК) Mini-Spike (AA) Mini-Spike (AA) ミニスパイク (対空) - Mini-Spike (대공) + 스파이크 미사일 (대공) "迷你長釘"導彈發射器 (防空) - "迷你长钉"导弹发射器 (防空) + "迷你长钉"(防空) + Mini-Spike (AA) Mini-Spike (AT) @@ -1609,13 +1809,14 @@ Mini-Spike (AC) Mini-Spike (Tankelhárító) Mini-Spike (AT) - Mini-Spike (ПТ) + Mini-Spike (ПТРК) Mini-Spike (AT) - Mini-Spike (AT) - ミニスパイク (対地) - Mini-Spike (대전차) + Mini-Spike (AC) + ミニスパイク (対戦車) + 스파이크 미사일 (대전차) "迷你長釘"導彈發射器 (反坦克) - "迷你长钉"导弹发射器 (反坦克) + "迷你长钉"(反坦) + Mini-Spike (AT) Metis-M @@ -1623,32 +1824,47 @@ Metis-M Метис-М "麥士蒂索人"-M型反坦克導彈 - "麦士蒂索人"-M型反坦克导弹 + "麦士蒂索"-M Metis-M メチス-M Metis-M + Metis-M + Metis-M + Metis-M + Metis-M + 메티스-M Metis-M (Brown) Metis-M (Braun) Metis-M (Brun) - Метис-М (Коричневый) + Метис-М (коричневый) "麥士蒂索人"-M型反坦克導彈(棕色) - "麦士蒂索人"-M型反坦克导弹(棕色) + "麦士蒂索"-M(棕色) Metis-M (Marrone) - メチス-M (茶) + メチス-M (ブラウン) Metis-M (Brązowy) + Metis-M (Marrom) + Metis-M (hnědý) + Metis-M (Marrón) + Metis-M (Kahverengi) + 메티스-M (갈색) Metis-M (Green) Metis-M (Grün) - Metis-M (Verde) - Метис-М (Зелёный) + Metis-M (Vert) + Метис-М (зелёный) "麥士蒂索人"-M型反坦克導彈(綠色) - "麦士蒂索人"-M型反坦克导弹(绿色) + "麦士蒂索"-M(绿色) Metis-M (Verde) - メチス-M (緑) + メチス-M (グリーン) Metis-M (Zielony) + Metis-M (Verde) + Metis-M (zelený) + Metis-M (Verde) + Metis-M (Yeşil) + 메티스-M (녹색) MX @@ -1664,7 +1880,8 @@ MX MX MX突擊步槍 - MX突击步枪 + MX + MX MX (Black) @@ -1674,13 +1891,30 @@ MX (Noir) MX (Fekete) MX (Negro) - MX (Чёрный) + MX (чёрный) MX (Preto) MX (Nero) - MX (黒) + MX (ブラック) MX (검정) MX突擊步槍 (黑色) - MX突击步枪 (黑色) + MX(黑色) + MX (Siyah) + + + MX (Khaki) + MX (Khaki) + MX(卡其) + MX (Kaki) + MX (Caqui) + MX (Cachi) + MX (Khaki) + MX (хаки) + MX (Khaki) + MX (Cáqui) + MX (카키) + MX(卡其色) + MX (カーキ) + MX (Haki) MXC @@ -1696,7 +1930,8 @@ MXC MXC MXC卡賓步槍 - MXC卡宾步枪 + MXC + MXC MXC (Black) @@ -1706,13 +1941,30 @@ MXC (Noir) MXC (Fekete) MXC (Negro) - MXC (Чёрный) + MXC (чёрный) MXC (Preto) MXC (Nero) - MXC (黒) + MXC (ブラック) MXC (검정) MXC卡賓步槍 (黑色) - MXC卡宾步枪 (黑色) + MXC(黑色) + MXC (Siyah) + + + MXC (Khaki) + MXC (Khaki) + MXC(卡其) + MXC (Kaki) + MXC (Caqui) + MXC (Cachi) + MXC (Khaki) + MXC (хаки) + MXC (Khaki) + MXC (Cáqui) + MXC (카키) + MXC(卡其色) + MXC (カーキ) + MXC (Haki) MX 3GL @@ -1728,7 +1980,8 @@ MX 3GL MX 3GL MX突擊步槍 (3連裝榴彈) - MX突击步枪 (3连装榴弹) + MX 3GL + MX 3GL MX 3GL (Black) @@ -1738,13 +1991,30 @@ MX 3GL (Noir) MX 3GL (Fekete) MX 3GL (Negro) - MX 3GL (Чёрный) + MX 3GL (чёрный) MX 3GL (Preto) MX 3GL (Nero) - MX 3GL (黒) + MX 3GL (ブラック) MX 3GL (검정) - MX突擊步槍 (3連裝榴彈-黑色) - MX突击步枪 (3连装榴弹-黑色) + MX突擊步槍 (3連裝榴彈—黑色) + MX 3GL(黑色) + MX 3GL (Siyah) + + + MX 3GL (Khaki) + MX 3GL (Khaki) + MX 3GL(卡其) + MX 3GL (Kaki) + MX 3GL (Caqui) + MX 3GL (Cachi) + MX 3GL (Khaki) + MX 3GL (хаки) + MX 3GL (Khaki) + MX 3GL (Cáqui) + MX 3GL (카키) + MX 3GL(卡其色) + MX 3GL (カーキ) + MX 3GL (Haki) MX LSW @@ -1760,7 +2030,8 @@ MX LSW MX LSW MX輕型機槍 - MX轻型机枪 + MX LSW + MX LSW MX LSW (Black) @@ -1770,13 +2041,30 @@ MX LSW (Noir) MX LSW (Fekete) MX LSW (Negro) - MX LSW (Чёрный) + MX LSW (чёрный) MX LSW (Preto) MX LSW (Nero) - MX LSW (黒) + MX LSW (ブラック) MX LSW (검정) MX輕型機槍 (黑色) - MX轻型机枪 (黑色) + MX LSW(黑色) + MX LSW (Siyah) + + + MX LSW (Khaki) + MX LSW (Khaki) + MX LSW(卡其) + MX LSW (Kaki) + MX LSW (Caqui) + MX LSW (Cachi) + MX LSW (Khaki) + MX LSW (хаки) + MX LSW (Khaki) + MX LSW (Cáqui) + MX LSW (카키) + MX LSW(卡其色) + MX LSW (カーキ) + MX LSW (Haki) MXM @@ -1792,7 +2080,8 @@ MXM MXM MXM精準步槍 - MXM精准步枪 + MXM + MXM MXM (Black) @@ -1802,13 +2091,30 @@ MXM (Noir) MXM (Fekete) MXM (Negro) - MXM (Чёрный) + MXM (чёрный) MXM (Preto) MXM (Nero) MXM (ブラック) MXM (검정) MXM精準步槍 (黑色) - MXM精准步枪 (黑色) + MXM(黑色) + MXM (Siyah) + + + MXM (Khaki) + MXM (Khaki) + MXM(卡其) + MXM (Kaki) + MXM (Caqui) + MXM (Cachi) + MXM (Khaki) + MXM (хаки) + MXM (Khaki) + MXM (Cáqui) + MXM (카키) + MXM(卡其色) + MXM (カーキ) + MXM (Haki) KH2002 Sama @@ -1820,11 +2126,12 @@ KH2002 Sama KH2002 Сама KT2002 Sama - KT2002 Katiba + KH2002 Sama KH2002 サマ - KH2002 Sama - KH2002"海白爾"突擊步槍 - KH2002"海白尔"突击步枪 + KH2002 사마 + KH2002 "海白爾"突擊步槍 + KH2002 Sama + KH2002 Sama KH2002C Sama @@ -1836,11 +2143,12 @@ KH2002C Sama KH2002C Сама KT2002C Sama - KT2002C Katiba + KH2002C Sama KH2002C サマ - KH2002C Sama + KH2002C 사마 KH2002C"海白爾"卡賓步槍 - KH2002C"海白尔"卡宾步枪 + KH2002C Sama + KH2002C Sama KH2002 Sama KGL @@ -1852,11 +2160,12 @@ KH2002 Sama KGL KH2002 Сама KGL KT2002 Sama KGL - KT2002 Katiba KGL + KH2002 Sama KGL KH2002 サマ KGL - KH2002 Sama KGL - KH2002"海白爾"突擊步槍 (榴彈) - KH2002"海白尔"突击步枪 (榴弹) + KH2002 사마 KGL + KH2002 "海白爾"突擊步槍 (榴彈) + KH2002 Sama KGL + KH2002 Sama KGL F2000 (Camo) @@ -1866,13 +2175,14 @@ F2000 (Camo) F2000 (Terepmintás) F2000 (Camuflaje) - F2000 (Камо) + F2000 (камуфляжный) F2000 (Camo) - F2000 (Camo) - F2000 (カモフラージュ) + F2000 (Mimetica) + F2000 (AAF迷彩) F2000 (위장) F2000突擊步槍 (迷彩) - F2000突击步枪 (迷彩) + F2000(迷彩) + F2000 (Kamuflaj) F2000 @@ -1888,7 +2198,8 @@ F2000 F2000 F2000突擊步槍 - F2000突击步枪 + F2000 + F2000 F2000 Tactical (Camo) @@ -1898,13 +2209,14 @@ F2000 Tactical (Camo) F2000 Tactical (Terepmintás) F2000 Tactical (Camuflaje) - F2000 Tactical (Камо) + F2000 Tactical (камуфляжный) F2000 Tactical (Camo) - F2000 Tactical (Camo) - F2000 タクティカル (迷彩) - F2000 Tactical (위장) + F2000 Tactical (Mimetica) + F2000 タクティカル (AAF迷彩) + F2000 택티컬 (위장) F2000戰術型突擊步槍 (迷彩) - F2000战术型突击步枪 (迷彩) + F2000 战术型(迷彩) + F2000 Tactical (Kamuflaj) F2000 Tactical @@ -1918,9 +2230,10 @@ F2000 Tactical F2000 Tactical F2000 タクティカル - F2000 Tactical + F2000 택티컬 F2000戰術型突擊步槍 - F2000战术型突击步枪 + F2000 战术型 + F2000 Tactical F2000 EGLM (Camo) @@ -1930,13 +2243,14 @@ F2000 EGLM (Camo) F2000 EGLM (Terepmintás) F2000 EGLM (Camuflaje) - F2000 EGLM (Камо) + F2000 EGLM (камуфляжный) F2000 EGLM (Camo) - F2000 EGLM (Camo) - F2000 EGLM (カモフラージュ) + F2000 EGLM (Mimetica) + F2000 EGLM (AAF迷彩) F2000 EGLM (위장) - F2000突擊步槍 (榴彈-迷彩) - F2000突击步枪 (榴弹-迷彩) + F2000突擊步槍 (榴彈—迷彩) + F2000 ELGM(迷彩) + F2000 EGLM (Kamuflaj) F2000 EGLM @@ -1952,7 +2266,8 @@ F2000 EGLM F2000 EGLM F2000突擊步槍 (榴彈) - F2000突击步枪 (榴弹) + F2000 ELGM + F2000 EGLM TAR-21 @@ -1968,7 +2283,8 @@ TAR-21 TAR-21 TAR-21突擊步槍 - TAR-21突击步枪 + TAR-21 + TAR-21 CTAR-21 @@ -1984,7 +2300,8 @@ CTAR-21 CTAR-21 CTAR-21卡賓步槍 - CTAR-21卡宾步枪 + CTAR-21 + CTAR-21 GTAR-21 EGLM @@ -2000,7 +2317,8 @@ GTAR-21 EGLM GTAR-21 EGLM GTAR-21突擊步槍 (榴彈) - GTAR-21突击步枪 (榴弹) + GTAR-21 EGLM + GTAR-21 EGLM Vector SMG @@ -2014,9 +2332,10 @@ Vector SMG Vector SMG ベクター SMG - Vector SMG + 벡터 SMG "維克特"衝鋒槍 - "维克特"冲锋枪 + Vector 冲锋枪 + Vector SMG Scorpion Evo 3 A1 @@ -2029,10 +2348,11 @@ Scorpion Evo 3 A1 Scorpion Evo 3 A1 Scorpion Evo 3 A1 - スコーピオン エボ 3 A1 - Scorpion Evo 3 A1 + スコーピオン Evo 3 A1 + 스콜피온 에보 3 A1 "蠍式"Evo 3 A1衝鋒槍 - "蝎式"Evo 3 A1冲锋枪 + Evo 3 A1 "蝎" + Scorpion Evo 3 A1 CPW @@ -2048,7 +2368,8 @@ CPW CPW 緊湊型個人衝鋒槍 - 紧凑型个人冲锋枪 + CPW + CPW RFB SDAR @@ -2064,7 +2385,8 @@ RFB SDAR RFB SDAR 犢牛式水陸兩用步槍 - 犊牛式水陆两用步枪 + RFB SDAR + RFB SDAR Stoner 99 LMG @@ -2077,10 +2399,11 @@ Stoner 99 LMG Stoner 99 LMG Stoner 99 LMG - ストーナー 99 LMG - Stoner 99 LMG + ストーナー99 LMG + 스토너 99 LMG 斯通納99輕機槍 - 斯通纳99轻机枪 + 斯通纳 99 + Stoner 99 LMG Negev NG7 @@ -2094,25 +2417,27 @@ Negev NG7 Negev NG7 ネゲフ NG7 - Negev NG7 + 네게브 NG7 內蓋夫NG7機槍 - 内盖夫NG7机枪 + 内格夫 NG7 + Negev NG7 Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR - Mk 14 Mod 1 EBR + Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR - Mk14 Mod 1 EBR + Mk.14 Mod 1 EBR Mk14一型增強型戰鬥步槍 - Mk14一型增强型战斗步枪 + Mk14 Mod 1 EBR + Mk14 Mod 1 EBR GM6 Lynx @@ -2126,9 +2451,10 @@ GM6 Lynx GM6 Lynx GM6 リンクス - GM6 Lynx - GM6"天貓"反器材狙擊步槍 - GM6"天猫"反器材狙击步枪 + GM6 링스 + GM6 "天貓"反器材狙擊步槍 + GM6 "猞猁" + GM6 Lynx GM6 Lynx (Camo) @@ -2138,13 +2464,14 @@ GM6 Lynx (Camo) GM6 Gepárd (Terepmintás) GM6 Lynx (Camuflaje) - GM6 Lynx (Камо) + GM6 Lynx (камуфляжный) GM6 Lynx (Camo) - GM6 Lynx (Camo) - GM6 リンクス (カモフラージュ) - GM6 Lynx (위장) - GM6"天貓"反器材狙擊步槍 (迷彩) - GM6"天猫"反器材狙击步枪 (迷彩) + GM6 Lynx (Mimetica) + GM6 リンクス (六角形迷彩) + GM6 링스 (위장) + GM6 "天貓"反器材狙擊步槍 (迷彩) + GM6 "猞猁"(迷彩) + GM6 Lynx (Kamufulaj) M200 Intervention @@ -2158,9 +2485,10 @@ M200 Intervention M200 Intervention M200 インターベンション - M200 Intervention + M200 인터벤션 M200干預型狙擊步槍 - M200干预型狙击步枪 + M200 "干预" + M200 Intervention M200 Intervention (Camo) @@ -2170,13 +2498,14 @@ M200 Intervention (Camo) M200 Intervention (Terepmintás) M200 Intervention (Camuflaje) - M200 Intervention (Камо) + M200 Intervention (камуфляжный) M200 Intervention (Camo) - M200 Intervention (Camo) - M200 インターベンション (カモフラージュ) - M200 Intervention (위장) + M200 Intervention (Mimetica) + M200 インターベンション (迷彩) + M200 인터벤션 (위장) M200干預型狙擊步槍 (迷彩) - M200干预型狙击步枪 (迷彩) + M200 "干预"(迷彩) + M200 Intervention (kamuflaj) VS-121 @@ -2192,7 +2521,8 @@ VS-121 VS-121 VS-121狙擊步槍 - VS-121狙击步枪 + VS-121 + VS-121 Noreen "Bad News" ULR @@ -2206,57 +2536,61 @@ Noreen "Bad News"ULR Noreen "Bad News" ULR ノレーン "バッド ニュース" ULR - Noreen "Bad News" ULR + 노린 "배드뉴스" ULR 諾琳"壞消息"極距狙擊步槍 - 诺琳"坏消息"极距狙击步枪 + 诺琳 "坏消息" 极距狙击步枪 + Noreen "Bad News" ULR Noreen "Bad News" ULR (Black) Noreen "Bad News" ULR (Černá) Noreen "Bad News" ULR (Noir) Noreen "Bad News" ULR (Negro) - Noreen "Bad News" ULR (Чёрный) + Noreen "Bad News" ULR (чёрный) Noreen "Bad News" ULR (Schwarz) Noreen "Bad News" ULR (czarny) Noreen "Bad News" ULR (Nero) Noreen "Bad News"ULR (Fekete) Noreen "Bad News" ULR (Preto) ノレーン "バッド ニュース" ULR (ブラック) - Noreen "Bad News" ULR (검정) + 노린 "배드뉴스" ULR (검정) 諾琳"壞消息"極距狙擊步槍 (黑色) - 诺琳"坏消息"极距狙击步枪 (黑色) + 诺琳 "坏消息" 极距狙击步枪(黑色) + Noreen "Bad News" ULR (Siyah) Noreen "Bad News" ULR (Camo) Noreen "Bad News" ULR (Kamufláž) Noreen "Bad News" ULR (Camo) Noreen "Bad News" ULR (Camuflaje) - Noreen "Bad News" ULR (Камо) + Noreen "Bad News" ULR (камуфляжный) Noreen "Bad News" ULR (Tarnmuster) Noreen "Bad News" ULR (kamuflaż) - Noreen "Bad News" ULR (Camo) + Noreen "Bad News" ULR (Mimetica) Noreen "Bad News"ULR (Terepmintás) Noreen "Bad News" ULR (Camuflagem) - ノレーン "バッド ニュース" ULR (カモフラージュ) - Noreen "Bad News" ULR (위장) + ノレーン "バッド ニュース" ULR (CTRG迷彩) + 노린 "배드뉴스" ULR (위장) 諾琳"壞消息"極距狙擊步槍 (迷彩) - 诺琳"坏消息"极距狙击步枪 (迷彩) + 诺琳 "坏消息" 极距狙击步枪(迷彩) + Noreen "Bad News" ULR (Kamufulaj) Noreen "Bad News" ULR (Sand) Noreen "Bad News" ULR (Písková) Noreen "Bad News" ULR (Beige) Noreen "Bad News" ULR (Arena) - Noreen "Bad News" ULR (Песочный) + Noreen "Bad News" ULR (песочный) Noreen "Bad News" ULR (sandfarben) Noreen "Bad News" ULR (piaskowy) Noreen "Bad News" ULR (Sabbia) Noreen "Bad News"ULR (Homok) Noreen "Bad News" ULR (Deserto) - ノレーン "バッド ニュース" ULR (砂地) - Noreen "Bad News" ULR (모래) + ノレーン "バッド ニュース" ULR (サンド) + 노린 "배드뉴스" ULR (모래) 諾琳"壞消息"極距狙擊步槍 (沙色) - 诺琳"坏消息"极距狙击步枪 (沙色) + 诺琳 "坏消息" 极距狙击步枪(沙色) + Noreen "Bad News" ULR (Çöl) SIG 556 @@ -2270,89 +2604,95 @@ SIG 556 SIG 556 SIG 556 - SIG 556 + 시그 556 SIG 556精準步槍 - SIG 556精准步枪 + SIG 556 + SIG 556 SIG 556 (Black) SIG 556 (Černá) SIG 556 (Noir) SIG 556 (Negro) - SIG 556 (Чёрный) + SIG 556 (чёрный) SIG 556 (czarny) SIG 556 (Schwarz) SIG 556 (Nero) SIG 556 (Fekete) SIG 556 (Preto) SIG 556 (ブラック) - SIG 556 (검정) + 시그 556 (검정) SIG 556精準步槍 (黑色) - SIG 556精准步枪 (黑色) + SIG 556(黑色) + SIG 556 (Siyah) - + SIG 556 (Khaki) SIG 556 (Khaki) SIG 556 (Kaki) SIG 556 (Caqui) - SIG 556 (Хаки) - SIG 556 (khaki) + SIG 556 (хаки) + SIG 556 (Khaki) SIG 556 (Khaki) - SIG 556 (Khaki) + SIG 556 (Cachi) SIG 556 (Khaki) SIG 556 (Caqui) - SIG 556 (土埃) - SIG 556 (카키) + SIG 556 (カーキ) + 시그 556 (카키) SIG 556精準步槍 (卡其色) - SIG 556精准步枪 (卡其色) + SIG 556(卡其色) + SIG 556 (Haki) SIG 556 (Sand) SIG 556 (Písková) SIG 556 (Beige) SIG 556 (Arena) - SIG 556 (Песочный) + SIG 556 (песочный) SIG 556 (piaskowy) SIG 556 (sandfarben) SIG 556 (Sabbia) SIG 556 (Homok) SIG 556 (Deserto) - SIG 556 (砂地) - SIG 556 (모래) + SIG 556 (サンド) + 시그 556 (모래) SIG 556精準步槍 (沙色) - SIG 556精准步枪 (沙色) + SIG 556(沙色) + SIG 556 (Kum) SIG 556 (Camo) SIG 556 (Kamufláž) SIG 556 (Camo) SIG 556 (Camuflaje) - SIG 556 (Камо) + SIG 556 (камуфляжный) SIG 556 (kamuflaż) SIG 556 (Tarnmuster) - SIG 556 (Camo) + SIG 556 (Mimetica) SIG 556 (Terepmintás) SIG 556 (Camuflagem) - SIG 556 (カモフラージュ) - SIG 556 (위장) + SIG 556 (MTP迷彩) + 시그 556 (위장) SIG 556精準步槍 (迷彩) - SIG 556精准步枪 (迷彩) + SIG 556(迷彩) + SIG 556 (Kamufulaj) SIG 556 (Woodland) SIG 556 (Lesní) SIG 556 (Woodland) SIG 556 (Bosque) - SIG 556 (Лесной) + SIG 556 (Woodland) SIG 556 (leśny) SIG 556 (Grünes Tarnmuster) - SIG 556 (Woodland) + SIG 556 (Boschivo) SIG 556 (Erdőmintás) SIG 556 (Floresta) - SIG 556 (森林) - SIG 556 (우드랜드) + SIG 556 (森林迷彩) + 시그 556 (수풀) SIG 556精準步槍 (森林迷彩) - SIG 556精准步枪 (森林迷彩) + SIG 556(森林迷彩) + SIG 556 (Orman) ASP-1 Kir @@ -2365,42 +2705,45 @@ ASP-1 Kir ASP-1 Kir ASP-1 Kir - ASP-1 Kir - ASP-1 キール - ASP-1"基爾"消音狙擊步槍 - ASP-1"基尔"消音狙击步枪 + ASP-1 キール + ASP-1 키르 + ASP-1 "基爾"消音狙擊步槍 + ASP-1 "基尔" + ASP-1 Kir ASP-1 Kir (Black) ASP-1 Kir (Černá) ASP-1 Kir (Noir) ASP-1 Kir (Negro) - ASP-1 Kir (Чёрный) + ASP-1 Kir (чёрный) ASP-1 Kir (Schwarz) ASP-1 Kir (czarny) ASP-1 Kir (Nero) ASP-1 Kir (Fekete) ASP-1 Kir (Preto) ASP-1 キール (ブラック) - ASP-1 Kir (검정) - ASP-1"基爾"消音狙擊步槍 (黑色) - ASP-1"基尔"消音狙击步枪 (黑色) + ASP-1 키르 (검정) + ASP-1 "基爾"消音狙擊步槍 (黑色) + ASP-1 "基尔"(黑色) + ASP-1 Kir (Siyah) ASP-1 Kir (Tan) ASP-1 Kir (Žlutohnědá) ASP-1 Kir (Tan) ASP-1 Kir (Tan) - ASP-1 Kir (Бронзовый) + ASP-1 Kir (пустынный) ASP-1 Kir (Hellbraun) ASP-1 Kir (Tan) - ASP-1 Kir (Tan) + ASP-1 Kir (Marroncino) ASP-1 Kir (Cserszín) ASP-1 Kir (Deserto) - ASP-1 キール (黄褐) - ASP-1 Kir (황갈) - ASP-1"基爾"消音狙擊步槍 (黃褐色) - ASP-1"基尔"消音狙击步枪 (黄褐色) + ASP-1 キール (タン) + ASP-1 키르 (황갈) + ASP-1 "基爾"消音狙擊步槍 (黃褐色) + ASP-1 "基尔"(沙色) + ASP-1 Kir (Tan) Cyrus @@ -2414,57 +2757,61 @@ Cyrus Cyrus サイラス - Cyrus + 사이러스 "居鲁士"狙擊步槍 - "居鲁士"狙击步枪 + "居鲁士" + Cyrus Cyrus (Black) Cyrus (Černá) Cyrus (Noir) Cyrus (Negro) - Cyrus (Чёрный) + Cyrus (чёрный) Cyrus (Schwarz) Cyrus (czarny) Cyrus (Nero) Cyrus (Fekete) Cyrus (Preto) サイラス (ブラック) - Cyrus (검정) + 사이러스 (검정) "居鲁士"狙擊步槍 (黑色) - "居鲁士"狙击步枪 (黑色) + "居鲁士"(黑色) + Cyrus (Siyah) Cyrus (Hex) Cyrus (Hex) Cyrus (Hex) Cyrus (Hex) - Cyrus (Гекс) + Cyrus (гекс) Cyrus (Hex) Cyrus (hex) Cyrus (Hex) Cyrus (Hex) Cyrus (Hex) - サイラス (蜂巣) - Cyrus (육각) + サイラス (六角形迷彩) + 사이러스 (육각) "居鲁士"狙擊步槍 (數位蜂巢迷彩) - "居鲁士"狙击步枪 (数位蜂巢迷彩) + "居鲁士"(蜂巢迷彩) + Cyrus (Hex) Cyrus (Tan) Cyrus (Žlutohnědá) Cyrus (Tan) Cyrus (Tan) - Cyrus (Бронза) + Cyrus (пустынный) Cyrus (Hellbraun) Cyrus (podpalany) - Cyrus (Tan) + Cyrus (Marroncino) Cyrus (Cserszín) Cyrus (Deserto) サイラス (タン) - Cyrus (황갈) + 사이러스 (황갈) "居鲁士"狙擊步槍 (黃褐色) - "居鲁士"狙击步枪 (黄褐色) + "居鲁士"(沙色) + Cyrus (Tan) M14 @@ -2480,39 +2827,42 @@ M14 M14 M14精準步槍 - M14精准步枪 + M14 + M14 M14 (Camo) M14 (Kamufláž) M14 (Camo) M14 (Camuflaje) - M14 (Камо) + M14 (камуфляжный) M14 (kamuflaż) M14 (Tarnmuster) - M14 (Camo) + M14 (Mimetica) M14 (Terepmintás) M14 (Camuflagem) - M14 (カモフラージュ) + M14 (迷彩) M14 (위장) M14精準步槍 (迷彩) - M14精准步枪 (迷彩) + M14(迷彩) + M14 (Kamufulaj) M14 (Olive) M14 (Olivová) M14 (Olive) M14 (Oliva) - M14 (Олива) + M14 (олива) M14 (oliwkowy) M14 (Olivgrün) - M14 (Olive) + M14 (Oliva) M14 (Olíva) M14 (Oliva) - M14 (オリーブド ラブ) + M14 (オリーブ) M14 (올리브) M14精準步槍 (橄欖色) - M14精准步枪 (橄榄色) + M14(橄榄色) + M14 (Zeytin Yeşili) HK121 @@ -2528,39 +2878,42 @@ HK 121 HK121 HK121中型機槍 - HK121中型机枪 + HK121 + HK121 HK121 (Hex) HK121 (Hex) HK121 (Hex) HK121 (Hex) - HK121 (Гекс) + HK121 (гекс) HK121 (Hex) HK121 (hex) HK121 (Hex) HK121 (Hex) HK121 (Hex) - HK 121 (蜂巣) + HK 121 (六角形迷彩) HK121 (육각) HK121中型機槍 (數位蜂巢迷彩) - HK121中型机枪 (数位蜂巢迷彩) + HK121(蜂巢迷彩) + HK121 (Hex) HK121 (Tan) HK121 (Žlutohnědá) HK121 (Tan) HK121 (Tan) - HK121 (Бронза) + HK121 (пустынный) HK121 (Hellbraun) HK121 (podpalany) - HK121 (Tan) + HK121 (Marroncino) HK121 (Cserszín) HK121 (Deserto) - HK 121 (黄褐) + HK 121 (タン) HK121 (황갈) HK121機槍 (黃褐色) - HK121机枪 (黄褐色) + HK121(沙色) + HK121 (Tan) LWMMG @@ -2576,7 +2929,8 @@ LWMMG LWMMG 輕量化中型機槍 - 轻量化中型机枪 + LWMMG + LWMMG LWMMG (MTP) @@ -2589,17 +2943,18 @@ LWMMG (MTP) LWMMG (MTP) LWMMG (MTP) - LWMMG (マルチカモ) + LWMMG (MTP迷彩) LWMMG (MTP) 輕量化中型機槍 (多地形迷彩) - 轻量化中型机枪 (多地形迷彩) + LWMMG(多地形迷彩) + LWMMG (MTP) LWMMG (Black) LWMMG (Černá) LWMMG (Noir) LWMMG (Negro) - LWMMG (Чёрный) + LWMMG (чёрный) LWMMG (czarny) LWMMG (Schwarz) LWMMG (Nero) @@ -2608,23 +2963,25 @@ LWMMG (ブラック) LWMMG (검정) 輕量化中型機槍 (黑色) - 轻量化中型机枪 (黑色) + LWMMG(黑色) + LWMMG (Siyah) LWMMG (Sand) LWMMG (Písková) SPMG (Beige) LWMMG (Arena) - LWMMG (Песочный) + LWMMG (песочный) LWMMG (piaskowy) LWMMG (sandfarben) LWMMG (Sabbia) LWMMG (Homok) LWMMG (Deserto) - LWMMG (砂地) + LWMMG (サンド) LWMMG (모래) 輕量化中型機槍 (沙色) - 轻量化中型机枪 (沙色) + LWMMG(沙色) + LWMMG (Kum) Jeep Wrangler @@ -2638,29 +2995,42 @@ Jeep Wrangler Jeep Wrangler ジープ ラングラー - Jeep Wrangler + 지프 랭글러 "牧馬人"吉普車 "牧马人"吉普车 + Jeep Wrangler Jeep Wrangler (SPG-9) Jeep Wrangler (SPG-9) - "牧马人"吉普车(SPG-9火箭筒) + "牧马人"吉普车(SPG-9火箭筒) "牧馬人"吉普車 (SPG-9火箭筒) ジープ ラングラー (SPG-9) Jeep Wrangler (SPG-9) Jeep Wrangler (SPG-9) Jeep Wrangler (СПГ-9) + Jeep Wrangler (SPG-9) + Jeep Wrangler (SPG-9) + Jeep Wrangler (SPG-9) + Jeep Wrangler (SPG-9) + Jeep Wrangler (SPG-9) + 지프 랭글러 (SPG-9) Jeep Wrangler (LMG) Jeep Wrangler (LMG) - "牧马人"吉普车(轻机枪) + "牧马人"吉普车(轻机枪) "牧馬人"吉普車 (輕機槍) ジープ ラングラー (LMG) Jeep Wrangler (LMG) Jeep Wrangler (LMG) - Jeep Wrangler (Пулемет) + Jeep Wrangler (с пулемётом) + Jeep Wrangler (LMG) + Jeep Wrangler (LMG) + Jeep Wrangler (LMG) + Jeep Wrangler (LMG) + Jeep Wrangler (LMG) + 지프 랭글러 (경기관총) Cessna TTx @@ -2674,9 +3044,10 @@ Cessna TTx Cessna TTx セスナ TTx - Cessna TTx + 세스나 TTx "賽斯納"TTx單引擎飛機 - "赛斯纳"TTx单引擎飞机 + "赛斯纳"TTx 单引擎飞机 + Cessna TTx Cessna TTx (Racing) @@ -2690,9 +3061,10 @@ Cessna TTx (Racing) Cessna TTx (Racing) セスナ TTx (レース仕様) - Cessna TTx (경주용) + 세스나 TTx (경주용) "賽斯納"TTx單引擎飛機 (競速) - "赛斯纳"TTx单引擎飞机 (竞速) + "赛斯纳"TTx 单引擎飞机(竞速) + Cessna TTx (Racing) Burraq UCAV @@ -2705,17 +3077,45 @@ Burraq UCAV Burraq UCAV Burraq UCAV - ブラーク UCAV - Burraq UCAV + ブラク UCAV + 부라크 UCAV "柏拉格"空中無人戰鬥載具 - "柏拉格"空中无人战斗载具 + "柏拉格" 战斗无人机 + Burraq UCAV + + + Type 115 (Black) + Type 115 (Preto) + Type 115 (ブラック) + Type 115 (чёрный) + 115식 보총 (검정) + Type 115 (Schwarz) + Type 115 (Nero) + + + Type 115 (Green Hex) + Type 115 (Verde Hex) + Type 115 (緑六角形迷彩) + Type 115 (зелёный гекс) + 115식 보총 (초록육각) + Type 115 (Hex Grün) + Type 115 (Hex Verde) + + + Type 115 (Hex) + Type 115 (Hex) + Type 115 (六角形迷彩) + Type 115 (гекс) + 115식 보총 (육각) + Type 115 (Hex) + Type 115 (Hex) QBZ-95-1 (Black) QBZ-95-1 (Černá) QBZ-95-1 (Noir) QBZ-95-1 (Negro) - QBZ-95-1 (Чёрный) + QBZ-95-1 (чёрный) QBZ-95-1 (czarny) QBZ-95-1 (Schwarz) QBZ-95-1 (Nero) @@ -2724,23 +3124,25 @@ QBZ-95-1 (ブラック) QBZ-95-1 (검정) QBZ-95-1式自動步槍 (黑色) - QBZ-95-1式自动步枪 (黑色) + 95-1式自动步枪(黑色) + QBZ-95-1 (Siyah) QBZ-95-1 (Green Hex) QBZ-95-1 (Hex Grün) QBZ-95-1 (Hex Verde) - QBZ-95-1 (zielony hex) + QBZ-95-1 (Zielony hex) QBZ-95-1 (Zelený Hex) - QBZ-95-1 (Hex Verte) - QBZ-95-1 (Зелёный Гекс) + QBZ-95-1 (Hex Vert) + QBZ-95-1 (зелёный гекс) QBZ-95-1 (Verde Hex) QBZ-95-1 (Zöld Hex) QBZ-95-1 (Hex Verde) - QBZ-95-1 (緑ヘックス) + QBZ-95-1 (緑六角形迷彩) QBZ-95-1 (초록육각) QBZ-95-1式自動步槍 (綠色數位蜂巢迷彩) - QBZ-95-1式自动步枪 (绿色数位蜂巢迷彩) + 95-1式自动步枪(绿色蜂巢迷彩) + QBZ-95-1 (Yeşil Hex) QBZ-95-1 (Hex) @@ -2749,21 +3151,22 @@ QBZ-95-1 (hex) QBZ-95-1 (Hex) QBZ-95-1 (Hex) - QBZ-95-1 (Гекс) + QBZ-95-1 (гекс) QBZ-95-1 (Hex) QBZ-95-1 (Hex) QBZ-95-1 (Hex) - QBZ-95-1 (ヘックス) + QBZ-95-1 (六角形迷彩) QBZ-95-1 (육각) QBZ-95-1式自動步槍 (數位蜂巢迷彩) - QBZ-95-1式自动步枪 (数位蜂巢迷彩) + 95-1式自动步枪(蜂巢迷彩) + QBZ-95-1 (Hex) QBZ-95-1 GL (Black) QBZ-95-1 GL (Černá) QBZ-95-1 GL (Noir) QBZ-95-1 GL (Negro) - QBZ-95-1 GL (Чёрный) + QBZ-95-1 GL (чёрный) QBZ-95-1 GL (czarny) QBZ-95-1 GL (Schwarz) QBZ-95-1 GL (Nero) @@ -2771,24 +3174,26 @@ QBZ-95-1 GL (Preto) QBZ-95-1 GL (ブラック) QBZ-95-1 GL (검정) - QBZ-95-1式自動步槍 (榴彈-黑色) - QBZ-95-1式自动步枪 (榴弹-黑色) + QBZ-95-1式自動步槍 (榴彈—黑色) + 95-1式自动步枪 10A式榴弹(黑色) + QBZ-95-1 GL (Siyah) QBZ-95-1 GL (Green Hex) QBZ-95-1 GL (Hex Grün) QBZ-95-1 GL (Hex Verde) - QBZ-95-1 GL (zielony hex) + QBZ-95-1 GL (Zielony hex) QBZ-95-1 GL (Zelený Hex) - QBZ-95-1 GL (Hex Verte) - QBZ-95-1 GL (Зелёный Гекс) + QBZ-95-1 GL (Hex Vert) + QBZ-95-1 GL (зелёный гекс) QBZ-95-1 GL (Verde Hex) QBZ-95-1 GL (Zöld Hex) QBZ-95-1 GL (Hex Verde) - QBZ-95-1 GL (緑ヘックス) + QBZ-95-1 GL (緑六角形迷彩) QBZ-95-1 GL (초록육각) - QBZ-95-1式自動步槍 (榴彈-綠色數位蜂巢迷彩) - QBZ-95-1式自动步枪 (榴弹-绿色数位蜂巢迷彩) + QBZ-95-1式自動步槍 (榴彈—綠色數位蜂巢迷彩) + 95-1式自动步枪 10A式榴弹(绿色蜂巢迷彩) + QBZ-95-1 GL (Yeşil Hex) QBZ-95-1 GL (Hex) @@ -2797,46 +3202,49 @@ QBZ-95-1 GL (hex) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) - QBZ-95-1 GL (Гекс) + QBZ-95-1 GL (гекс) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) - QBZ-95-1 GL (ヘックス) + QBZ-95-1 GL (六角形迷彩) QBZ-95-1 GL (육각) - QBZ-95-1式自動步槍 (榴彈-數位蜂巢迷彩) - QBZ-95-1式自动步枪 (榴弹-数位蜂巢迷彩) + QBZ-95-1式自動步槍 (榴彈—數位蜂巢迷彩) + 95-1式自动步枪 10A式榴弹(蜂巢迷彩) + QBZ-95-1 GL (Hex) QBZ-95-1 LSW (Black) QBZ-95-1 LSW (Černá) QBZ-95-1 LSW (Noir) QBZ-95-1 LSW (Negro) - QBZ-95-1 LSW (Чёрный) + QBZ-95-1 LSW (чёрный) QBZ-95-1 LSW (czarny) QBZ-95-1 LSW (Schwarz) QBZ-95-1 LSW (Nero) QBZ-95-1 LSW (Fekete) QBZ-95-1 LSW (Preto) - QBZ-95-1 LSW (黒) + QBZ-95-1 LSW (ブラック) QBZ-95-1 LSW (검정) QBZ-95-1式輕機槍 (黑色) - QBZ-95-1式轻机枪 (黑色) + 95-1式班用机枪(黑色) + QBZ-95-1 LSW (Siyah) QBZ-95-1 LSW (Green Hex) QBZ-95-1 LSW (Hex Grün) QBZ-95-1 LSW (Hex Verde) - QBZ-95-1 LSW (zielony hex) + QBZ-95-1 LSW (Zielony hex) QBZ-95-1 LSW (Zelený Hex) - QBZ-95-1 LSW (Hex Verte) - QBZ-95-1 LSW (Зелёный Гекс) + QBZ-95-1 LSW (Hex Vert) + QBZ-95-1 LSW (зелёный гекс) QBZ-95-1 LSW (Verde Hex) QBZ-95-1 LSW (Zöld Hex) QBZ-95-1 LSW (Hex Verde) - QBZ-95-1 LSW (緑ヘックス) + QBZ-95-1 LSW (緑六角形迷彩) QBZ-95-1 LSW (초록육각) QBZ-95-1式輕機槍 (綠色數位蜂巢迷彩) - QBZ-95-1式轻机枪 (绿色数位蜂巢迷彩) + 95-1式班用机枪(绿色蜂巢迷彩) + QBZ-95-1 LSW (Yeşil Hex) QBZ-95-1 LSW (Hex) @@ -2845,21 +3253,22 @@ QBZ-95-1 LSW (hex) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) - QBZ-95-1 LSW (Гекс) + QBZ-95-1 LSW (гекс) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) - QBZ-95-1 LSW (ヘックス) + QBZ-95-1 LSW (六角形迷彩) QBZ-95-1 LSW (육각) QBZ-95-1式輕機槍 (數位蜂巢迷彩) - QBZ-95-1式轻机枪 (数位蜂巢迷彩) + 95-1式班用机枪(蜂巢迷彩) + QBZ-95-1 LSW (Hex) QBU-88 (Black) QBU-88 (Černá) QBU-88 (Noir) QBU-88 (Negro) - QBU-88 (Чёрный) + QBU-88 (чёрный) QBU-88 (czarny) QBU-88 (Schwarz) QBU-88 (Nero) @@ -2868,23 +3277,25 @@ QBU-88 (ブラック) QBU-88 (검정) QBU-88式狙擊步槍 (黑色) - QBU-88式狙击步枪 (黑色) + 88式狙击步枪(黑色) + QBU-88 (Siyah) QBU-88 (Green Hex) QBU-88 (Hex Grün) QBU-88 (Hex Verde) - QBU-88 (zielony hex) + QBU-88 (Zielony hex) QBU-88 (Zelený Hex) - QBU-88 (Hex Verte) - QBU-88 (Зелёный Гекс) + QBU-88 (Hex Vert) + QBU-88 (зелёный гекс) QBU-88 (Verde Hex) QBU-88 (Zöld Hex) QBU-88 (Hex Verde) - QBU-88 (緑ヘックス) + QBU-88 (緑六角形迷彩) QBU-88 (초록육각) QBU-88式狙擊步槍 (綠色數位蜂巢迷彩) - QBU-88式狙击步枪 (绿色数位蜂巢迷彩) + 88式狙击步枪(绿色蜂巢迷彩) + QBU-88 (Yeşil Hex) QBU-88 (Hex) @@ -2893,14 +3304,15 @@ QBU-88 (hex) QBU-88 (Hex) QBU-88 (Hex) - QBU-88 (Гекс) + QBU-88 (гекс) QBU-88 (Hex) QBU-88 (Hex) QBU-88 (Hex) - QBU-88 (ヘックス) + QBU-88 (六角形迷彩) QBU-88 (육각) QBU-88式狙擊步槍 (數位蜂巢迷彩) - QBU-88式狙击步枪 (数位蜂巢迷彩) + 88式狙击步枪(蜂巢迷彩) + QBU-88 (Hex) GM6 Lynx (Green Hex) @@ -2908,15 +3320,16 @@ GM6 Lynx (Hex Verde) GM6 Lynx (Zielony hex) GM6 Lynx (Zelený Hex) - GM6 Lynx (Hex Verte) - GM6 Lynx (Зелёный Гекс) + GM6 Lynx (Hex Vert) + GM6 Lynx (зелёный гекс) GM6 Lynx (Verde Hex) GM6 Lynx (Zöld Hex) GM6 Lynx (Hex Verde) - GM6 リンクス (緑ヘックス) - GM6 Lynx (초록육각) - GM6"天貓"反器材狙擊步槍 (綠色數位蜂巢迷彩) - GM6"天猫"反器材狙击步枪 (绿色数位蜂巢迷彩) + GM6 リンクス (緑六角形迷彩) + GM6 링스 (초록육각) + GM6 "天貓"反器材狙擊步槍 (綠色數位蜂巢迷彩) + GM6 "猞猁"(绿色蜂巢迷彩) + GM6 Lynx (Yeşil Hex) FN Minimi SPW @@ -2930,9 +3343,10 @@ FN Minimi SPW FN Minimi SPW FN ミニミ SPW - FN Minimi SPW + FN 미니미 SPW FN Minimi班用自動機槍 - FN Minimi班用自动机枪 + FN Minimi 班用自动机枪 + FN Minimi SPW M200 Intervention (Tropic) @@ -2945,10 +3359,11 @@ M200 Intervention (тропик) M200 Intervention (Trópico) M200 Intervention (Tropico) - M200 インターベンション (熱帯) - M200 Intervention (열대) + M200 インターベンション (熱帯ジャングル迷彩) + M200 인터벤션 (열대) M200干預型狙擊步槍 (熱帶迷彩) - M200干预型狙击步枪 (热带迷彩) + M200 "干预"(热带迷彩) + M200 Intervention (Tropic) MP5K @@ -2964,231 +3379,263 @@ MP5K MP5K MP5K衝鋒槍 - MP5K冲锋枪 + MP5K + MP5K - HK416A5 11" (Black) - HK416A5 11" (Černá) - HK416A5 11" (Noir) - HK416A5 11" (Negro) - HK416A5 11" (Чёрный) - HK416A5 11" (czarny) - HK416A5 11" (Schwarz) - HK416A5 11" (Nero) - HK416A5 11" (Fekete) - HK416A5 11" (Preto) - HK416A5 11" (ブラック) - HK416A5 11" (검정) - HK416A5 11"突擊步槍 (黑色) - HK416A5 11"突击步枪 (黑色) + HK416A5 11 " (Black) + HK416A5 11 " (Černá) + HK416A5 11 " (Noir) + HK416A5 11 " (Negro) + HK416A5 11 " (чёрный) + HK416A5 11 " (czarny) + HK416A5 11 " (Schwarz) + HK416A5 11 " (Nero) + HK416A5 11 " (Fekete) + HK416A5 11 " (Preto) + HK416A5 11 " (ブラック) + HK416A5 11인치 (검정) + HK416A5 11 "突擊步槍 (黑色) + HK416A5 11英寸(黑色) + HK416A5 11 " (Siyah) - HK416A5 11" (Khaki) - HK416A5 11" (Khaki) - HK416A5 11" (Kaki) - HK416A5 11" (Caqui) - HK416A5 11" (Хаки) - HK416A5 11" (khaki) - HK416A5 11" (Khaki) - HK416A5 11" (Khaki) - HK416A5 11" (Khaki) - HK416A5 11" (Caqui) - HK416A5 11" (カーキ) - HK416A5 11" (카키) - HK416A5 11"突擊步槍 (卡其色) - HK416A5 11"突击步枪 (卡其色) + HK416A5 11 " (Khaki) + HK416A5 11 " (Khaki) + HK416A5 11 " (Kaki) + HK416A5 11 " (Caqui) + HK416A5 11 " (хаки) + HK416A5 11 " (Khaki) + HK416A5 11 " (Khaki) + HK416A5 11 " (Cachi) + HK416A5 11 " (Khaki) + HK416A5 11 " (Caqui) + HK416A5 11 " (カーキ) + HK416A5 11인치 (카키) + HK416A5 11 "突擊步槍 (卡其色) + HK416A5 11英寸(卡其色) + HK416A5 11 " (Haki) - HK416A5 11" (Sand) - HK416A5 11" (Písková) - HK416A5 11" (Beige) - HK416A5 11" (Arena) - HK416A5 11" (Песочный) - HK416A5 11" (sandfarben) - HK416A5 11" (piaskowy) - HK416A5 11" (Sabbia) - HK416A5 11" (Homok) - HK416A5 11" (Deserto) - HK416A5 11" (サンド) - HK416A5 11" (모래) - HK416A5 11"突擊步槍 (沙色) - HK416A5 11"突击步枪 (沙色) + HK416A5 11 " (Sand) + HK416A5 11 " (Písková) + HK416A5 11 " (Beige) + HK416A5 11 " (Arena) + HK416A5 11 " (песочный) + HK416A5 11 " (sandfarben) + HK416A5 11 " (piaskowy) + HK416A5 11 " (Sabbia) + HK416A5 11 " (Homok) + HK416A5 11 " (Deserto) + HK416A5 11 " (サンド) + HK416A5 11인치 (모래) + HK416A5 11 "突擊步槍 (沙色) + HK416A5 11英寸(沙色) + HK416A5 11 " (Kum) - HK416A5 11" GL (Black) - HK416A5 11" GL (Černá) - HK416A5 11" GL (Noir) - HK416A5 11" GL (Negro) - HK416A5 11" GL (Чёрный) - HK416A5 11" GL (czarny) - HK416A5 11" GL (Schwarz) - HK416A5 11" GL (Nero) - HK416A5 11" GL (Fekete) - HK416A5 11" GL (Preto) - HK416A5 11" GL (ブラック) - HK416A5 11" GL (검정) - HK416A5 11"突擊步槍 (榴彈-黑色) - HK416A5 11"突击步枪 (榴弹-黑色) + HK416A5 11 " GL (Black) + HK416A5 11 " GL (Černá) + HK416A5 11 " GL (Noir) + HK416A5 11 " GL (Negro) + HK416A5 11 " GL (чёрный) + HK416A5 11 " GL (czarny) + HK416A5 11 " GL (Schwarz) + HK416A5 11 " GL (Nero) + HK416A5 11 " GL (Fekete) + HK416A5 11 " GL (Preto) + HK416A5 11 " GL (ブラック) + HK416A5 11인치 GL (검정) + HK416A5 11 "突擊步槍 (榴彈—黑色) + HK416A5 11英寸 GLM(黑色) + HK416A5 11 " GL (Siyah) - HK416A5 11" GL (Khaki) - HK416A5 11" GL (Khaki) - HK416A5 11" GL (Kaki) - HK416A5 11" GL (Caqui) - HK416A5 11" GL (Хаки) - HK416A5 11" GL (khaki) - HK416A5 11" GL (Khaki) - HK416A5 11" GL (Khaki) - HK416A5 11" GL (Khaki) - HK416A5 11" GL (Caqui) - HK416A5 11" GL (カーキ) - HK416A5 11" GL (카키) - HK416A5 11"突擊步槍 (榴彈-卡其色) - HK416A5 11"突击步枪 (榴弹-卡其色) + HK416A5 11 " GL (Khaki) + HK416A5 11 " GL (Khaki) + HK416A5 11 " GL (Kaki) + HK416A5 11 " GL (Caqui) + HK416A5 11 " GL (хаки) + HK416A5 11 " GL (Khaki) + HK416A5 11 " GL (Khaki) + HK416A5 11 " GL (Cachi) + HK416A5 11 " GL (Khaki) + HK416A5 11 " GL (Caqui) + HK416A5 11 " GL (カーキ) + HK416A5 11인치 GL (카키) + HK416A5 11 "突擊步槍 (榴彈—卡其色) + HK416A5 11英寸 GLM(卡其色) + HK416A5 11 " GL (Hakii) - HK416A5 11" GL (Sand) - HK416A5 11" GL (Písková) - HK416A5 11" GL (Beige) - HK416A5 11" GL (Arena) - HK416A5 11" GL (Песочный) - HK416A5 11" GL (sandfarben) - HK416A5 11" GL (piaskowy) - HK416A5 11" GL (Sabbia) - HK416A5 11" GL (Homok) - HK416A5 11" GL (Deserto) - HK416A5 11" GL (サンド) - HK416A5 11" GL (모래) - HK416A5 11"突擊步槍 (榴彈-沙色) - HK416A5 11"突击步枪 (榴弹-沙色) + HK416A5 11 " GL (Sand) + HK416A5 11 " GL (Písková) + HK416A5 11 " GL (Beige) + HK416A5 11 " GL (Arena) + HK416A5 11 " GL (песочный) + HK416A5 11 " GL (sandfarben) + HK416A5 11 " GL (piaskowy) + HK416A5 11 " GL (Sabbia) + HK416A5 11 " GL (Homok) + HK416A5 11 " GL (Deserto) + HK416A5 11 " GL (サンド) + HK416A5 11인치 GL (모래) + HK416A5 11 "突擊步槍 (榴彈—沙色) + HK416A5 11英寸 GLM(沙色) + HK416A5 11 " GL (Çöl) - HK416A5 14.5" (Black) - HK416A5 14.5" (Černá) - HK416A5 14.5" (Noir) - HK416A5 14.5" (Negro) - HK416A5 14.5" (Чёрный) - HK416A5 14.5" (czarny) - HK416A5 14.5" (Schwarz) - HK416A5 14.5" (Nero) - HK416A5 14.5" (Fekete) - HK416A5 14.5" (Preto) - HK416A5 14.5" (黒) - HK416A5 14.5" (검정) - HK416A5 14.5"突擊步槍 (黑色) - HK416A5 14.5"突击步枪 (黑色) + HK416A5 14.5 " (Black) + HK416A5 14.5 " (Černá) + HK416A5 14.5 " (Noir) + HK416A5 14.5 " (Negro) + HK416A5 14.5 " (чёрный) + HK416A5 14.5 " (czarny) + HK416A5 14.5 " (Schwarz) + HK416A5 14.5 " (Nero) + HK416A5 14.5 " (Fekete) + HK416A5 14.5 " (Preto) + HK416A5 14.5 " (ブラック) + HK416A5 14.5인치 (검정) + HK416A5 14.5 "突擊步槍 (黑色) + HK416A5 14.5英寸(黑色) + HK416A5 14.5 " (Siyah) - HK416A5 14.5" (Khaki) - HK416A5 14.5" (Khaki) - HK416A5 14.5" (Kaki) - HK416A5 14.5" (Caqui) - HK416A5 14.5" (Хаки) - HK416A5 14.5" (khaki) - HK416A5 14.5" (Khaki) - HK416A5 14.5" (Khaki) - HK416A5 14.5" (Khaki) - HK416A5 14.5" (Caqui) - HK416A5 14.5" (カーキ) - HK416A5 14.5" (카키) - HK416A5 14.5"突擊步槍 (卡其色) - HK416A5 14.5"突击步枪 (卡其色) + HK416A5 14.5 " (Khaki) + HK416A5 14.5 " (Khaki) + HK416A5 14.5 " (Kaki) + HK416A5 14.5 " (Caqui) + HK416A5 14.5 " (хаки) + HK416A5 14.5 " (Khaki) + HK416A5 14.5 " (Khaki) + HK416A5 14.5 " (Cachi) + HK416A5 14.5 " (Khaki) + HK416A5 14.5 " (Caqui) + HK416A5 14.5 " (カーキ) + HK416A5 14.5인치 (카키) + HK416A5 14.5 "突擊步槍 (卡其色) + HK416A5 14.5英寸(卡其色) + HK416A5 14.5 " (Haki) - HK416A5 14.5" (Sand) - HK416A5 14.5" (Písková) - HK416A5 14.5" (Beige) - HK416A5 14.5" (Arena) - HK416A5 14.5" (Песочный) - HK416A5 14.5" (sandfarben) - HK416A5 14.5" (piaskowy) - HK416A5 14.5" (Sabbia) - HK416A5 14.5" (Homok) - HK416A5 14.5" (Deserto) - HK416A5 14.5" (サンド) - HK416A5 14.5" (모래) - HK416A5 14.5"突擊步槍 (沙色) - HK416A5 14.5"突击步枪 (沙色) + HK416A5 14.5 " (Sand) + HK416A5 14.5 " (Písková) + HK416A5 14.5 " (Beige) + HK416A5 14.5 " (Arena) + HK416A5 14.5 " (песочный) + HK416A5 14.5 " (sandfarben) + HK416A5 14.5 " (piaskowy) + HK416A5 14.5 " (Sabbia) + HK416A5 14.5 " (Homok) + HK416A5 14.5 " (Deserto) + HK416A5 14.5 " (サンド) + HK416A5 14.5인치 (모래) + HK416A5 14.5 "突擊步槍 (沙色) + HK416A5 14.5英寸(沙色) + HK416A5 14.5 " (Kum) - HK417A2 20" (Black) - HK417A2 20" (Černá) - HK417A2 20" (Noir) - HK417A2 20" (Negro) - HK417A2 20" (Чёрный) - HK417A2 20" (czarny) - HK417A2 20" (Schwarz) - HK417A2 20" (Nero) - HK417A2 20" (Fekete) - HK417A2 20" (Preto) - HK417A2 20" (ブラック) - HK417A2 20" (검정) - HK417A2 20"突擊步槍 (黑色) - HK417A2 20"突击步枪 (黑色) + HK417A2 20 " (Black) + HK417A2 20 " (Černá) + HK417A2 20 " (Noir) + HK417A2 20 " (Negro) + HK417A2 20 " (чёрный) + HK417A2 20 " (czarny) + HK417A2 20 " (Schwarz) + HK417A2 20 " (Nero) + HK417A2 20 " (Fekete) + HK417A2 20 " (Preto) + HK417A2 20 " (ブラック) + HK417A2 20인치 (검정) + HK417A2 20 "突擊步槍 (黑色) + HK417A2 20英寸(黑色) + HK417A2 20 " (Siyah) - HK417A2 20" (Khaki) - HK417A2 20" (Khaki) - HK417A2 20" (Kaki) - HK417A2 20" (Caqui) - HK417A2 20" (Хаки) - HK417A2 20" (khaki) - HK417A2 20" (Khaki) - HK417A2 20" (Khaki) - HK417A2 20" (Khaki) - HK417A2 20" (Caqui) - HK417A2 20" (カーキ) - HK417A2 20" (카키) - HK417A2 20"突擊步槍 (卡其色) - HK417A2 20"突击步枪 (卡其色) + HK417A2 20 " (Khaki) + HK417A2 20 " (Khaki) + HK417A2 20 " (Kaki) + HK417A2 20 " (Caqui) + HK417A2 20 " (хаки) + HK417A2 20 " (Khaki) + HK417A2 20 " (Khaki) + HK417A2 20 " (Cachi) + HK417A2 20 " (Khaki) + HK417A2 20 " (Caqui) + HK417A2 20 " (カーキ) + HK417A2 20인치 (카키) + HK417A2 20 "突擊步槍 (卡其色) + HK417A2 20英寸(卡其色) + HK417A2 20 " (Haki) - HK417A2 20" (Sand) - HK417A2 20" (Písková) - HK417A2 20" (Beige) - HK417A2 20" (Arena) - HK417A2 20" (Песочный) - HK417A2 20" (sandfarben) - HK417A2 20" (piaskowy) - HK417A2 20" (Sabbia) - HK417A2 20" (Homok) - HK417A2 20" (Deserto) - HK417A2 20" (サンド) - HK417A2 20" (모래) - HK417A2 20"突擊步槍 (沙色) - HK417A2 20"突击步枪 (沙色) + HK417A2 20 " (Sand) + HK417A2 20 " (Písková) + HK417A2 20 " (Beige) + HK417A2 20 " (Arena) + HK417A2 20 " (песочный) + HK417A2 20 " (sandfarben) + HK417A2 20 " (piaskowy) + HK417A2 20 " (Sabbia) + HK417A2 20 " (Homok) + HK417A2 20 " (Deserto) + HK417A2 20 " (サンド) + HK417A2 20인치 (모래) + HK417A2 20 "突擊步槍 (沙色) + HK417A2 20英寸(沙色) + HK417A2 20 " (Kum) RPG-32 (Green Hex) RPG-32 (Hex Grün) RPG-32 (Hex Verde) - RPG-32 (zielony hex) + RPG-32 (Zielony hex) RPG-32 (Zelený Hex) - RPG-32 (Hex Verte) - RPG-32 (Зелёный Гекс) + RPG-32 (Hex Vert) + RPG-32 (зелёный гекс) RPG-32 (Verde Hex) RPG-32 (Zöld Hex) RPG-32 (Hex Verde) - RPG-32 (緑ヘックス) + RPG-32 (緑六角形迷彩) RPG-32 (초록육각) RPG-32火箭發射器 (綠色數位蜂巢迷彩) - RPG-32火箭发射器 (绿色数位蜂巢迷彩) + RPG-32(绿色蜂巢迷彩) + RPG-32 (Yeşil Hex) P99 (Khaki) P99 (Khaki) P99 (Kaki) P99 (Caqui) - P99 (Хаки) - P99 (khaki) + P99 (хаки) + P99 (Khaki) P99 (Khaki) - P99 (Khaki) + P99 (Cachi) P99 (Khaki) P99 (Caqui) P99 (カーキ) P99 (카키) P99半自動手槍 (卡其色) - P99半自动手枪 (卡其色) + P99(卡其色) + P99 (Haki) + + + P99 (Black) + P99 (Černá) + P99 (Noir) + P99 (Negro) + P99 (чёрный) + P99 (czarny) + P99 (Schwarz) + P99 (Nero) + P99 (Fekete) + P99 (Preto) + P99 (ブラック) + P99 (검정) + P99半自動手槍 (黑色) + P99(黑色) + P99 (Siyah) Makarov PM @@ -3197,164 +3644,282 @@ Makarowa PM Makarov PM Makarov PM - Макарова ПМ + ПМ Makarov PM Makarov PM Makarov PM マカロフ PM - Makarov PM + 마카로프 PM "馬卡洛夫"手槍 - "马卡洛夫"手枪 + "马卡洛夫" + Makarov PM Polaris DAGOR (XM312) Polaris DAGOR (XM312) ポラリス DAGOR (XM312) "北極星"先進佈署越野車 (XM312重機槍) - "北极星"先进布署越野车 (XM312重机枪) + "北极星"(XM312) Polaris DAGOR (XM312) Polaris DAGOR (XM312) Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + 폴라리스 DAGOR (XM312) Polaris DAGOR (Mini-Spike AT) Polaris DAGOR (Mini-Spike PzAbw) - "北极星"先进布署越野车("迷你长钉"反坦克导弹发射器) + "北极星"("迷你长钉"反坦) "北極星"先進佈署越野車("迷你長釘"反坦克導彈發射器) Polaris DAGOR (Mini-Spike AT) - ポラリス DAGOR (ミニスパイク対戦) + ポラリス DAGOR (ミニスパイク 対戦車) Polaris DAGOR (Mini-Spike AT) Polaris DAGOR (ПТ Mini-Spike) + Polaris DAGOR (Mini-Spike AT) + Polaris DAGOR (Mini-Spike AC) + Polaris DAGOR (Mini-Spike AT) + Polaris DAGOR (Mini-Spike AT) + Polaris DAGOR (Mini-Spike AT) + 폴라리스 DAGOR (스파이크 미사일 대전차) Polaris DAGOR Polaris DAGOR ポラリス DAGOR "北極星"先進佈署越野車 - "北极星"先进布署越野车 + "北极星" Polaris DAGOR Polaris DAGOR Polaris DAGOR + Polaris DAGOR + Polaris DAGOR + Polaris DAGOR + Polaris DAGOR + Polaris DAGOR + 폴라리스 DAGOR Polaris DAGOR (light) Polaris DAGOR (leicht) - ポラリス DAGOR (軽) + ポラリス DAGOR (軽装) "北極星"先進佈署越野車 (輕型) - "北极星"先进布署越野车 (轻型) + "北极星"(轻型) Polaris DAGOR (leggero) Polaris DAGOR (light) - Polaris DAGOR (легкий) + Polaris DAGOR (лёгкий) + Polaris DAGOR (leve) + Polaris DAGOR (léger) + Polaris DAGOR (lehký) + Polaris DAGOR (light) + Polaris DAGOR (ligero) + 폴라리스 DAGOR (경량) LSV Mk. II (M134) LSV Mk. II (M134) 輕型突擊車2式 (M134迷你機炮) - 轻型突击车2式 (M134迷你机炮) + 轻型突击车二型(M134) LSV Mk. II (M134) LSV Mk. II (M134) LSV Mk. II (M134) LSV Mk. II (M134) + LSV Mk. II (M134) + 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) LSV Mk. II (Metis-M) - 轻型突击车2式 ("麦士蒂索人"-M型反坦克导弹) + 轻型突击车二型("麦士蒂索"-M) 輕型突擊車2式 ("麥士蒂索人"-M型反坦克導彈) 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 (Metis-M) + LSV Mk. II (Metis-M) + LSV Mk. II (Metis-M) + LSV Mk. II (Metis-M) + LSV Mk.II (메티스-M) LSV Mk. II LSV Mk. II 輕型突擊車2式 - 轻型突击车2式 + 轻型突击车二型 LSV Mk. II LSV Mk. II LSV Mk. II LSV Mk. II + LSV Mk. II + LSV Mk. II + LSV Mk. II + LSV Mk. II + LSV Mk. II + LSV Mk.II Rooikat 120 Rooikat 120 - "狞猫"120主炮轮式装甲车 + "狞猫" 120 "獰貓"120主炮輪式裝甲車 ルーイカット 120 Rooikat 120 Rooikat 120 Rooikat 120 + Rooikat 120 + Rooikat 120 + Rooikat 120 + Rooikat 120 + Rooikat 120 + 루이캇트 120 Rooikat 120 UP Rooikat 120 UP - "狞猫"120主炮轮式装甲车 (城市版) + "狞猫" 120 城市版 "獰貓"120主炮輪式裝甲車 (城市版) ルーイカット 120 UP Rooikat 120 UP Rooikat 120 UP Rooikat 120 UP + Rooikat 120 UP + Rooikat 120 UP + Rooikat 120 UP + Rooikat 120 UP + Rooikat 120 UP + 루이캇트 120 시가전형 T-14 Armata T-14 Armata Т-14 Армата - T-14"阿玛塔"主战坦克 - T-14"阿瑪塔"主戰坦克 + T-14 "阿玛塔" + T-14 "阿瑪塔"主戰坦克 T-14 アルマータ T-14 Armata T-14 Armata + T-14 Armata + T-14 Armata + T-14 Armata + T-14 Armata + T-14 Armata + T-14 아르마타 T-14K Armata T-14K Armata Т-14К Армата - T-14K"阿玛塔"主战坦克 + T-14K "阿玛塔" T-14K"阿瑪塔"主戰坦克 T-14K アルマータ T-14K Armata T-14K Armata + T-14K Armata + T-14K Armata + T-14K Armata + T-14K Armata + T-14K Armata + T-14K 아르마타 Wiesel 2 Ozelot (AA) - Wiesel 2 Ozelot (FlaRaWaTrg) - "鼬鼠"2装甲车 (防空) + Wiesel 2 Ozelot (LeFlaSys) + "鼬鼠"2(防空) "鼬鼠"2裝甲車 (防空) ウィーゼル 2 オゼロット (対空) Wiesel 2 Ozelot (AA) Wiesel 2 Ozelot (AA) - Wiesel 2 Ozelot (ПВО) + Wiesel 2 Ozelot (ЗРК) + Wiesel 2 Ozelot (AA) + Wiesel 2 Ozelot (AA) + Wiesel 2 Ozelot (AA) + Wiesel 2 Ozelot (AA) + Wiesel 2 Ozelot (AA) + 비젤 2 오셀롯 (대공) Wiesel 2 (ATGM) Wiesel 2 (PzAbw) - "鼬鼠"2装甲车 (反坦导弹) + "鼬鼠"2(反坦) "鼬鼠"2裝甲車 (反坦導彈) ウィーゼル 2 (ATGM) Wiesel 2 (ATGM) Wiesel 2 (ATGM) - Wiesel 2 (ПТ) + Wiesel 2 (ПТРК) + Wiesel 2 (ATGM) + Wiesel 2 (ATGM) + Wiesel 2 (ATGM) + Wiesel 2 (ATGM) + Wiesel 2 (ATGM) + 비젤 2 (대전차유도) Wiesel 2 (MK20) Wiesel 2 (MK20) - "鼬鼠"2装甲车 (MK20机炮) + "鼬鼠"2(MK20) "鼬鼠"2裝甲車 (MK20機炮) ウィーゼル 2 (MK20) Wiesel 2 (MK20) Wiesel 2 (MK20) Wiesel 2 (MK20) + Wiesel 2 (MK20) + Wiesel 2 (MK20) + Wiesel 2 (MK20) + Wiesel 2 (MK20) + Wiesel 2 (MK20) + 비젤 2 (MK20) Wiesel 2 RFCV (Radar) Wiesel 2 AFF (Radar) - "鼬鼠"2装甲车 (雷达) + "鼬鼠"2(雷达) "鼬鼠"2裝甲車 (雷達) - ウィーゼル 2 (レーダー) + ウィーゼル 2 RFCV (レーダー) Wiesel 2 RFCV (Radar) Wiesel 2 RFCV (Radar) - Wiesel 2 RFCV (Радар) + Wiesel 2 RFCV (радар) + Wiesel 2 RFCV (Radar) + Wiesel 2 RFCV (Radar) + Wiesel 2 RFCV (Radar) + Wiesel 2 RFCV (Radar) + Wiesel 2 RFCV (Radar) + 비젤 2 RFCV (레이더) + + + UTG Defender 126 + UTG Defender 126 + UTG ディフェンダー 126 + UTG Defender 126 + UTG 디펜더 126 + UTG Defender 126 + UTG Defender 126 + + + EOTech MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + 이오텍 MRDS + EOTech MRDS + EOTech MRDS + + + EOTech MRDS (Black) + EOTech MRDS (Preto) + EOTech MRDS (ブラック) + EOTech MRDS (чёрный) + 이오텍 MRDS (검정) + EOTech MRDS (Schwarz) + EOTech MRDS (Nero) Leupold Mark 4 HAMR @@ -3365,75 +3930,248 @@ Leupold Mark 4 HAMR Leupold Mark 4 HAMR Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + 류폴드 마크 4 HAMR Leupold Mark 4 HAMR (Khaki) Leupold Mark 4 HAMR (Khaki) Leupold Mark 4 HAMR (卡其色) - Leupold Mark 4 HAMR (卡其色) + Leupold Mark 4 HAMR(卡其色) Leupold Mark 4 HAMR (カーキ) - Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (Cachi) Leupold Mark 4 HAMR (Khaki) - Leupold Mark 4 HAMR (Хаки) + Leupold Mark 4 HAMR (хаки) + Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (Kaki) + Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (Haki) + Leupold Mark 4 HAMR (Caqui) + 류폴드 마크 4 HAMR (카키) + + + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR(2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + Leupold Mark 4 HAMR (2D) + 류폴드 마크 4 HAMR (2D) + + + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR(画中画) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + Leupold Mark 4 HAMR (PIP) + 류폴드 마크 4 HAMR (PIP) ELCAN SpecterOS (Tan) ELCAN SpecterOS (Beige) ELCAN SpecterOS (黃褐色) - ELCAN SpecterOS (黄褐色) + ELCAN SpecterOS(沙色) ELCAN SpecterOS (タン) - ELCAN SpecterOS (Tan) + ELCAN SpecterOS (Marroncino) ELCAN SpecterOS (Tan) - ELCAN SpecterOS (Бронза) + ELCAN SpecterOS (пустынный) + ELCAN SpecterOS (Bege) + ELCAN SpecterOS (Tan) + ELCAN SpecterOS (Žlutohnědá) + ELCAN SpecterOS (Tan) + ELCAN SpecterOS (Tan) + 엘칸 스펙터OS (황갈) ELCAN SpecterOS (Black) ELCAN SpecterOS (Schwarz) ELCAN SpecterOS (黑色) - ELCAN SpecterOS (黑色) + ELCAN SpecterOS(黑色) ELCAN SpecterOS (ブラック) ELCAN SpecterOS (Nero) ELCAN SpecterOS (Czarny) - ELCAN SpecterOS (Черный) + ELCAN SpecterOS (чёрный) + ELCAN SpecterOS (Preto) + ELCAN SpecterOS (Noire) + ELCAN SpecterOS (Černá) + ELCAN SpecterOS (Siyah) + ELCAN SpecterOS (Negra) + 엘칸 스펙터OS (검정) ELCAN SpecterOS (Green Hex) ELCAN SpecterOS (綠色數位蜂巢迷彩) - ELCAN SpecterOS (绿色数位蜂巢迷彩) - ELCAN SpecterOS (緑ヘックス) - ELCAN SpecterOS (Verde Hex) + ELCAN SpecterOS(绿色蜂巢迷彩) + ELCAN SpecterOS (緑六角形迷彩) + ELCAN SpecterOS (Hex Verde) ELCAN SpecterOS (Zielony Hex) - ELCAN SpecterOS (Зеленый Гекс) + ELCAN SpecterOS (зелёный гекс) + ELCAN SpecterOS (Verde Hex) + ELCAN SpecterOS (Hex Verte) + ELCAN SpecterOS (Zelený Hex) + ELCAN SpecterOS (Yeşil Hex) + ELCAN SpecterOS (Verde Hex) + ELCAN SpecterOS (Hex Grün) + 엘칸 스펙터OS (초록육각) + + + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS(2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + ELCAN SpecterOS (2D) + 엘칸 스펙터OS (2D) + + + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS(画中画) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + ELCAN SpecterOS (PIP) + 엘칸 스펙터OS (PIP) + + + ELCAN SpecterOS (Lush) + ELCAN SpecterOS (Leśny) + ELCAN SpecterOS (Forêt) + ELCAN SpecterOS (Verdeggiante) + ELCAN SpecterOS (緑地迷彩) + ELCAN SpecterOS (Grün) + ELCAN SpecterOS(繁茂) + 엘칸 스펙터OS (초목) + ELCAN SpecterOS (обильная растительность) + ELCAN SpecterOS (Exuberante) + + + ELCAN SpecterOS (Arid) + ELCAN SpecterOS (Jałowy) + ELCAN SpecterOS (Désert) + ELCAN SpecterOS (Arido) + ELCAN SpecterOS (乾燥地帯迷彩) + ELCAN SpecterOS (Trocken) + ELCAN SpecterOS(干旱) + 엘칸 스펙터OS (건조) + ELCAN SpecterOS (сухая местность) + ELCAN SpecterOS (Árido) + + + ELCAN SpecterOS 7.62 (Black) + ELCAN SpecterOS 7.62 (Czarny) + ELCAN SpecterOS 7.62 (Noire) + ELCAN SpecterOS 7.62 (Nero) + ELCAN SpecterOS 7.62 (ブラック) + ELCAN SpecterOS 7.62 (Schwarz) + ELCAN SpecterOS 7.62(黑色) + 엘칸 스펙터OS 7.62 (검정) + ELCAN SpecterOS 7.62 (чёрный) + ELCAN SpecterOS 7.62 (Negro) + + + ELCAN SpecterOS 7.62 (Lush) + ELCAN SpecterOS 7.62 (Leśny) + ELCAN SpecterOS 7.62 (Forêt) + ELCAN SpecterOS 7.62 (Verdeggiante) + ELCAN SpecterOS 7.62 (緑地迷彩) + ELCAN SpecterOS 7.62 (Grün) + ELCAN SpecterOS 7.62(繁茂) + 엘칸 스펙터OS 7.62 (초목) + ELCAN SpecterOS 7.62 (обильная растительность) + ELCAN SpecterOS 7.62 (Exuberante) + + + ELCAN SpecterOS 7.62 (Arid) + ELCAN SpecterOS 7.62 (Jałowy) + ELCAN SpecterOS 7.62 (Désert) + ELCAN SpecterOS 7.62 (Arido) + ELCAN SpecterOS 7.62 (乾燥地帯迷彩) + ELCAN SpecterOS 7.62 (Trocken) + ELCAN SpecterOS 7.62(干旱) + 엘칸 스펙터OS 7.62 (건조) + ELCAN SpecterOS 7.62 (сухая местность) + ELCAN SpecterOS 7.62 (Árido) SIG BRAVO4 / ROMEO3 (Black) SIG BRAVO4 / ROMEO3 (Schwarz) SIG BRAVO4 / ROMEO3 (黑色) - SIG BRAVO4 / ROMEO3 (黑色) + SIG BRAVO4 / ROMEO3(黑色) SIG BRAVO4 / ROMEO3 (ブラック) SIG BRAVO4 / ROMEO3 (Nero) SIG BRAVO4 / ROMEO3 (Czarny) - SIG BRAVO4 / ROMEO3 (Черный) + SIG BRAVO4 / ROMEO3 (чёрный) + SIG BRAVO4 / ROMEO3 (Preto) + SIG BRAVO4 / ROMEO3 (Noire) + SIG BRAVO4 / ROMEO3 (Černá) + SIG BRAVO4 / ROMEO3 (Siyah) + SIG BRAVO4 / ROMEO3 (Negra) + 시그 브라보4 / 로미오3 (검정) SIG BRAVO4 / ROMEO3 (Khaki) SIG BRAVO4 / ROMEO3 (Khaki) SIG BRAVO4 / ROMEO3 (卡其色) - SIG BRAVO4 / ROMEO3 (卡其色) + SIG BRAVO4 / ROMEO3(卡其色) SIG BRAVO4 / ROMEO3 (カーキ) - SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (Cachi) SIG BRAVO4 / ROMEO3 (Khaki) - SIG BRAVO4 / ROMEO3 (Хаки) + SIG BRAVO4 / ROMEO3 (хаки) + SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (Kaki) + SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (Haki) + SIG BRAVO4 / ROMEO3 (Caqui) + 시그 브라보4 / 로미오3 (카키) SIG BRAVO4 / ROMEO3 (Sand) SIG BRAVO4 / ROMEO3 (Beige) SIG BRAVO4 / ROMEO3 (沙色) - SIG BRAVO4 / ROMEO3 (沙色) + SIG BRAVO4 / ROMEO3(沙色) SIG BRAVO4 / ROMEO3 (サンド) SIG BRAVO4 / ROMEO3 (Sabbia) SIG BRAVO4 / ROMEO3 (Piasek) - SIG BRAVO4 / ROMEO3 (Песочный) + SIG BRAVO4 / ROMEO3 (песочный) + SIG BRAVO4 / ROMEO3 (Areia) + SIG BRAVO4 / ROMEO3 (Beige) + SIG BRAVO4 / ROMEO3 (Písková) + SIG BRAVO4 / ROMEO3 (Kum) + SIG BRAVO4 / ROMEO3 (Arena) + 시그 브라보4 / 로미오3 (사막) Nightforce NXS @@ -3443,88 +4181,189 @@ Nightforce NXS Nightforce NXS Nightforce NXS + Nightforce NXS + Nightforce NXS + Nightforce NXS + Nightforce NXS + Nightforce NXS + Nightforce NXS + 나이트포스 NXS Nightforce NXS (Green Hex) Nightforce NXS (綠色數位蜂巢迷彩) - Nightforce NXS (绿色数位蜂巢迷彩) - Nightforce NXS (緑ヘックス) - Nightforce NXS (Verde Hex) + Nightforce NXS(绿色蜂巢迷彩) + Nightforce NXS (緑六角形迷彩) + Nightforce NXS (Hex Verde) Nightforce NXS (Zielony Hex) - Nightforce NXS (Зеленый Гекс) + Nightforce NXS (зелёный гекс) + Nightforce NXS (Verde Hex) + Nightforce NXS (Hex Verte) + Nightforce NXS (Zelený Hex) + Nightforce NXS (Yeşil Hex) + Nightforce NXS (Verde Hex) + Nightforce NXS (Hex Grün) + 나이트포스 NXS (초록육각) Nightforce NXS (Jungle) Nightforce NXS (Dschungel) Nightforce NXS (叢林色) - Nightforce NXS (丛林色) - Nightforce NXS (ジャングル) + Nightforce NXS(丛林色) + Nightforce NXS (熱帯ジャングル迷彩) Nightforce NXS (Giungla) Nightforce NXS (Dżungla) - Nightforce NXS (Джунгли) + Nightforce NXS (джунгли) + Nightforce NXS (Selva) + Nightforce NXS (Jungle) + Nightforce NXS (Džungle) + Nightforce NXS (Orman) + Nightforce NXS (Jungla) + 나이트포스 NXS (정글) + + + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS(2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + Nightforce NXS (2D) + 나이트포스 NXS (2D) + + + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS(画中画) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (PIP) + Nightforce NXS (BIB) + 나이트포스 NXS (PIP) US Optics MR-10 (Black) US Optics MR-10 (Black) - US Optics MR-10 (Black) + US Optics MR-10(黑色) US Optics MR-10 (ブラック) US Optics MR-10 (Czarny) - Ottica US MR-10 (nera) - US Optics MR-10 (Черный) + Ottica US MR-10 (Nera) + US Optics MR-10 (чёрный) + US Optics MR-10 (Preto) + US Optics MR-10 (Noire) + US Optics MR-10 (Černá) + US Optics MR-10 (Siyah) + US Optics MR-10 (Negra) + US Optics MR-10 (Schwarz) + US 옵틱스 MR-10 (검정) US Optics MR-10 (Khaki) US Optics MR-10 (Khaki) - US Optics MR-10 (Khaki) + US Optics MR-10(卡其色) US Optics MR-10 (カーキ) US Optics MR-10 (Khaki) - Ottica US MR-10 (cachi) - US Optics MR-10 (Хаки) + Ottica US MR-10 (Cachi) + US Optics MR-10 (хаки) + US Optics MR-10 (Khaki) + US Optics MR-10 (Kaki) + US Optics MR-10 (Khaki) + US Optics MR-10 (Haki) + US Optics MR-10 (Caqui) + US Optics MR-10 (Khaki) + US 옵틱스 MR-10 (카키) US Optics MR-10 (Sand) US Optics MR-10 (Sand) - US Optics MR-10 (Sand) + US Optics MR-10(沙色) US Optics MR-10 (サンド) US Optics MR-10 (Piasek) - Ottica US MR-10 (sabbia) - US Optics MR-10 (Песочный) + Ottica US MR-10 (Sabbia) + US Optics MR-10 (песочный) + US Optics MR-10 (Areia) + US Optics MR-10 (Beige) + US Optics MR-10 (Písková) + US Optics MR-10 (Kum) + US Optics MR-10 (Arena) + US Optics MR-10 (Sand) + US 옵틱스 MR-10 (사막) KAHLES Helia (Black) KAHLES Helia (Black) - KAHLES Helia (Black) + KAHLES Helia(黑色) KAHLES ヘリア (ブラック) KAHLES Helia (Czarny) - KAHLES Helia (nero) - KAHLES Helia (Черный) + KAHLES Helia (Nero) + KAHLES Helia (чёрный) + KAHLES Helia (Preto) + KAHLES Helia (Noire) + KAHLES Helia (Černá) + KAHLES Helia (Siyah) + KAHLES Helia (Negra) + KAHLES Helia (Schwarz) + 칼레스 헬리아 (검정) KAHLES Helia (Hex) KAHLES Helia (Hex) - KAHLES Helia (Hex) - KAHLES ヘリア (ヘックス) + KAHLES Helia(蜂巢迷彩) + KAHLES ヘリア (六角形迷彩) KAHLES Helia (Hex) - KAHLES Helia (esagonale) - KAHLES Helia (Гекс) + KAHLES Helia (Hex) + KAHLES Helia (гекс) + KAHLES Helia (Hex) + KAHLES Helia (Hex) + KAHLES Helia (Hex) + KAHLES Helia (Hex) + KAHLES Helia (Hex) + KAHLES Helia (Hex) + 칼레스 헬리아 (육각) KAHLES Helia (Old) KAHLES Helia (Old) - KAHLES Helia (Old) + KAHLES Helia(旧) KAHLES ヘリア (使い古し) KAHLES Helia (Stary) - KAHLES Helia (vecchio) - KAHLES Helia (Старый) + KAHLES Helia (Vecchio) + KAHLES Helia (старый) + KAHLES Helia (Velho) + KAHLES Helia (Usée) + KAHLES Helia (Stará) + KAHLES Helia (Eski) + KAHLES Helia (Vieja) + KAHLES Helia (Alt) + 칼레스 헬리아 (낡음) KAHLES Helia (Tan) KAHLES Helia (Tan) - KAHLES Helia (Tan) - KAHLES Helia (タン) + KAHLES Helia(沙色) + KAHLES ヘリア (タン) KAHLES Helia (Tan) - KAHLES Helia (marroncino) - KAHLES Helia (Бронза) + KAHLES Helia (Marroncino) + KAHLES Helia (пустынный) + KAHLES Helia (Bege) + KAHLES Helia (Tan) + KAHLES Helia (Žlutohnědá) + KAHLES Helia (Tan) + KAHLES Helia (Tan) + KAHLES Helia (Tan) + 칼레스 헬리아 (황갈) Burris XTR II @@ -3534,75 +4373,173 @@ Burris XTR II Burris XTR II Burris XTR II + Burris XTR II + Burris XTR II + Burris XTR II + Burris XTR II + Burris XTR II + Burris XTR II + 버리스 XTR II Burris XTR II (Green Hex) Burris XTR II (綠色數位蜂巢迷彩) - Burris XTR II (绿色数位蜂巢迷彩) - Burris XTR II (緑ヘックス) - Burris XTR II (Green Hex) + Burris XTR II(绿色蜂巢迷彩) + Burris XTR II (緑六角形迷彩) + Burris XTR II (Hex Verde) Burris XTR II (Zielony Hex) - Burris XTR II (Зеленый Гекс) + Burris XTR II (зелёный гекс) + Burris XTR II (Verde Hex) + Burris XTR II (Hex Verte) + Burris XTR II (Zelený Hex) + Burris XTR II (Yeşil Hex) + Burris XTR II (Verde Hex) + Burris XTR II (Hex Grün) + 버리스 XTR II (초록육각) + + + Burris XTR II (Old) + Burris XTR II (Stary) + Burris XTR II (Usée) + Burris XTR II (Vecchio) + Burris XTR II (使い古し) + Burris XTR II (Alt) + Burris XTR II(陈旧) + 버리스 XTR II (낡음) + Burris XTR II (старый) + Burris XTR II (Viejo) + + + Burris XTR II (ASP-1 Kir) + Burris XTR II (ASP-1 Kir) + Burris XTR II (ASP-1 Kir) + Burris XTR II (APS-1 Kir) + Burris XTR II (ASP-1 キール用) + Burris XTR II (ASP-1 Kir) + Burris XTR II(ASP-1 Kir) + 버리스 XTR II (ASP-1 키르용) + Burris XTR II (ASP-1 Kir) + Burris XTR II (ASP-1 Kir) EOTech XPS3 (Tan) EOTech XPS3 (Beige) EOTech XPS3 (黃褐色) - EOTech XPS3 (黄褐色) + EOTech XPS3(沙色) EOTech XPS3 (タン) - EOTech XPS3 (Tan) + EOTech XPS3 (Marroncino) EOTech XPS3 (Tan) - EOTech XPS3 (Бронза) + EOTech XPS3 (пустынный) + EOTech XPS3 (Bege) + EOTech XPS3 (Tan) + EOTech XPS3 (Žlutohnědá) + EOTech XPS3 (Tan) + EOTech XPS3 (Tan) + 이오텍 XPS3 (황갈) EOTech XPS3 (Black) EOTech XPS3 (Schwarz) EOTech XPS3 (黑色) - EOTech XPS3 (黑色) + EOTech XPS3(黑色) EOTech XPS3 (ブラック) - EOTech XPS3 (Black) + EOTech XPS3 (Nero) EOTech XPS3 (Czarny) - EOTech XPS3 (Черный) + EOTech XPS3 (чёрный) + EOTech XPS3 (Preto) + EOTech XPS3 (Noire) + EOTech XPS3 (Černá) + EOTech XPS3 (Siyah) + EOTech XPS3 (Negra) + 이오텍 XPS3 (검정) EOTech XPS3 (Khaki) EOTech XPS3 (Khaki) EOTech XPS3 (卡其色) - EOTech XPS3 (卡其色) + EOTech XPS3(卡其色) EOTech XPS3 (カーキ) - EOTech XPS3 (Khaki) + EOTech XPS3 (Cachi) EOTech XPS3 (Khaki) - EOTech XPS3 (Хаки) + EOTech XPS3 (хаки) + EOTech XPS3 (Khaki) + EOTech XPS3 (Kaki) + EOTech XPS3 (Khaki) + EOTech XPS3 (Haki) + EOTech XPS3 (Caqui) + 이오텍 XPS3 (카키) + + + EOTech XPS3 (Lush) + EOTech XPS3 (Leśny) + EOTech XPS3 (Forêt) + EOTech XPS3 (Verdeggiante) + EOTech XPS3 (緑地迷彩) + EOTech XPS3 (Grün) + EOTech XPS3(繁茂) + 이오텍 XPS3 (초목) + EOTech XPS3 (обильная растительность) + EOTech XPS3 (Exuberante) + + + EOTech XPS3 (Arid) + EOTech XPS3 (Jałowy) + EOTech XPS3 (Désert) + EOTech XPS3 (Arido) + EOTech XPS3 (乾燥地帯迷彩) + EOTech XPS3 (Trocken) + EOTech XPS3(干旱) + 이오텍 XPS3 (건조) + EOTech XPS3 (сухая местность) + EOTech XPS3 (Árido) EOTech XPS3 SMG (Tan) EOTech XPS3 SMG (Beige) EOTech XPS3 SMG (黃褐色) - EOTech XPS3 SMG (黄褐色) + EOTech XPS3(冲锋枪用,沙色) EOTech XPS3 SMG (タン) - EOTech XPS3 SMG (Tan) + EOTech XPS3 SMG (Marroncino) EOTech XPS3 SMG (Tan) - EOTech XPS3 SMG (Бронза) + EOTech XPS3 SMG (пустынный) + EOTech XPS3 SMG (Bege) + EOTech XPS3 SMG (Tan) + EOTech XPS3 SMG (Žlutohnědá) + EOTech XPS3 SMG (Tan) + EOTech XPS3 SMG (Tan) + 이오텍 XPS3 SMG (황갈) EOTech XPS3 SMG (Black) EOTech XPS3 SMG (Schwarz) EOTech XPS3 SMG (黑色) - EOTech XPS3 SMG (黑色) + EOTech XPS3(冲锋枪用,黑色) EOTech XPS3 SMG (ブラック) EOTech XPS3 SMG (Nero) EOTech XPS3 SMG (Czarny) - EOTech XPS3 SMG (Черный) + EOTech XPS3 SMG (чёрный) + EOTech XPS3 SMG (Preto) + EOTech XPS3 SMG (Noire) + EOTech XPS3 SMG (Černá) + EOTech XPS3 SMG (Siyah) + EOTech XPS3 SMG (Negra) + 이오텍 XPS3 SMG (검정) EOTech XPS3 SMG (Khaki) EOTech XPS3 SMG (Khaki) EOTech XPS3 SMG (卡其色) - EOTech XPS3 SMG (卡其色) + EOTech XPS3(冲锋枪用,卡其色) EOTech XPS3 SMG (カーキ) - EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (Cachi) EOTech XPS3 SMG (Khaki) - EOTech XPS3 SMG (Хаки) + EOTech XPS3 SMG (хаки) + EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (Kaki) + EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (Hakii) + EOTech XPS3 SMG (Caqui) + 이오텍 XPS3 SMG (카키) IOR-Valdada Pitbull 2 @@ -3612,6 +4549,45 @@ IOR-Valdada Pitbull 2 IOR-Valdada Pitbull 2 IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada 핏불 2 + + + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2(2D) + IOR-Valdada ピットブル 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada Pitbull 2 (2D) + IOR-Valdada 핏불 2 (2D) + + + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2(画中画) + IOR-Valdada ピットブル 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (PIP) + IOR-Valdada Pitbull 2 (BIB) + IOR-Valdada 핏불 2 (PIP) Burris FastFire 2 @@ -3621,53 +4597,84 @@ Burris FastFire 2 Burris FastFire 2 Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 + 버리스 패스트파이어 2 C-More Railway (Red) C-More Railway (Rot) C-More Railway (紅色) - C-More Railway (红色) - C-More レイルウェイ (赤) + C-More Railway(红色) + C-More レイルウェイ (レッド) C-More Railway (Rosso) C-More Railway (Czerwony) - C-More Railway (Красный) + C-More Railway (красный) + C-More Railway (Vermelho) + C-More Railway (Rouge) + C-More Railway (Červený) + C-More Railway (Kırmızı) + C-More Railway (Roja) + 씨모어 레일웨이 (빨강) C-More Railway (Green) C-More Railway (Grün) C-More Railway (綠色) - C-More Railway (绿色) - C-More レイルウェイ (緑) + C-More Railway(绿色) + C-More レイルウェイ (グリーン) C-More Railway (Verde) C-More Railway (Zielony) - C-More Railway (Зеленый) + C-More Railway (зелёный) + C-More Railway (Verde) + C-More Railway (Verte) + C-More Railway (Zelený) + C-More Railway (Yeşil) + C-More Railway (Verde) + 씨모어 레일웨이 (초록) C-More Railway SMG (Red) C-More Railway SMG (Rot) C-More Railway SMG (紅色) - C-More Railway SMG (红色) - C-More レイルウェイ SMG (赤) + C-More Railway(冲锋枪用,红色) + C-More レイルウェイ SMG (レッド) C-More Railway SMG (Rosso) C-More Railway SMG (Czerwony) - C-More Railway SMG (Красный) + C-More Railway SMG (красный) + C-More Railway SMG (Vermelho) + C-More Railway SMG (Rouge) + C-More Railway SMG (Červený) + C-More Railway SMG (Kırmızı) + C-More Railway SMG (Roja) + 씨모어 레일웨이 SMG (빨강) C-More Railway SMG (Green) C-More Railway SMG (Grün) C-More Railway SMG (綠色) - C-More Railway SMG (绿色) - C-More レイルウェイ SMG (緑) + C-More Railway(冲锋枪用,绿色) + C-More レイルウェイ SMG (グリーン) C-More Railway SMG (Verde) C-More Railway SMG (Zielony) - C-More Railway SMG (Зеленый) + C-More Railway SMG (зелёный) + C-More Railway SMG (Verde) + C-More Railway SMG (Verte) + C-More Railway SMG (Zelený) + C-More Railway SMG (Yeşil) + C-More Railway SMG (Verde) + 씨모어 레일웨이 SMG (초록) P90 TR (Black) P90 TR (Černá) P90 TR (Noir) P90 TR (Negro) - P90 TR (Чёрный) + P90 TR (чёрный) P90 TR (czarny) P90 TR (Schwarz) P90 TR (Nero) @@ -3675,63 +4682,67 @@ P90 TR (Preto) P90 TR (ブラック) P90 TR (黑色) - P90 TR (黑色) - P90 TR (Black) + P90 TR(黑色) + P90 TR (검정) + P90 TR (Siyah) P90 TR (Khaki) P90 TR (Khaki) P90 TR (Kaki) P90 TR (Caqui) - P90 TR (Хаки) - P90 TR (khaki) + P90 TR (хаки) + P90 TR (Khaki) P90 TR (Khaki) - P90 TR (Khaki) + P90 TR (Cachi) P90 TR (Khaki) P90 TR (Caqui) P90 TR (カーキ) P90 TR (沙色) - P90 TR (沙色) - P90 TR (Khaki) + P90 TR(沙色) + P90 TR (카키) + P90 TR (Haki) P90 TR (Camo) P90 TR (Kamufláž) P90 TR (Camo) P90 TR (Camuflaje) - P90 TR (Камо) + P90 TR (камуфляжный) P90 TR (kamuflaż) P90 TR (Camo) - P90 TR (Camo) + P90 TR (Mimetica) P90 TR (Terepmintás) P90 TR (Camuflagem) - P90 TR (カモフラージュ) + P90 TR (AAF迷彩) P90 TR (迷彩) - P90 TR (迷彩) - P90 TR (Camo) + P90 TR(迷彩) + P90 TR (위장) + P90 TR (Kamufulaj) P90 TR (Hex) P90 TR (Hex) P90 TR (Hex) P90 TR (Hex) - P90 TR (Гекс) + P90 TR (гекс) P90 TR (Hex) P90 TR (hex) P90 TR (Hex) P90 TR (Hex) P90 TR (Hex) - P90 TR (ヘックス) + P90 TR (六角形迷彩) P90 TR (數位蜂巢迷彩) - P90 TR (数位蜂巢迷彩) - P90 TR (Hex) + P90 TR(蜂巢迷彩) + P90 TR (육각) + P90 TR (Hex) P90 (Black) P90 (Černá) P90 (Noir) P90 (Negro) - P90 (Чёрный) + P90 (чёрный) P90 (czarny) P90 (Schwarz) P90 (Nero) @@ -3739,63 +4750,67 @@ P90 (Preto) P90 (ブラック) P90 (黑色) - P90 (黑色) - P90 (Black) + P90(黑色) + P90 (검정) + P90 (Siyah) P90 (Khaki) P90 (Khaki) P90 (Kaki) P90 (Caqui) - P90 (Хаки) - P90 (khaki) + P90 (хаки) + P90 (Khaki) P90 (Khaki) - P90 (Khaki) + P90 (Cachi) P90 (Khaki) P90 (Caqui) P90 (カーキ) P90 (沙色) - P90 (沙色) - P90 (Khaki) + P90(沙色) + P90 (카키) + P90 (Haki) P90 (Camo) P90 (Kamufláž) P90 (Camo) P90 (Camuflaje) - P90 (Камо) + P90 (камуфляжный) P90 (kamuflaż) P90 (Camo) - P90 (Camo) + P90 (Mimetica) P90 (Terepmintás) P90 (Camuflagem) - P90 (カモフラージュ) + P90 (AAF迷彩) P90 (迷彩) - P90 (迷彩) - P90 (Camo) + P90(迷彩) + P90 (위장) + P90 (Kamufulaj) P90 (Hex) P90 (Hex) P90 (Hex) P90 (Hex) - P90 (Гекс) + P90 (гекс) P90 (Hex) P90 (hex) P90 (Hex) P90 (Hex) P90 (Hex) - P90 (ヘックス) + P90 (六角形迷彩) P90 (數位蜂巢迷彩) - P90 (数位蜂巢迷彩) - P90 (Hex) + P90(蜂巢迷彩) + P90 (육각) + P90 (Hex) PS90 TR (Black) PS90 TR (Černá) PS90 TR (Noir) PS90 TR (Negro) - PS90 TR (Чёрный) + PS90 TR (чёрный) PS90 TR (czarny) PS90 TR (Schwarz) PS90 TR (Nero) @@ -3803,63 +4818,67 @@ PS90 TR (Preto) PS90 TR (ブラック) PS90 TR (黑色) - PS90 TR (黑色) - PS90 TR (Black) + PS90 TR(黑色) + PS90 TR (검정) + PS90 TR (Siyah) PS90 TR (Khaki) PS90 TR (Khaki) PS90 TR (Kaki) PS90 TR (Caqui) - PS90 TR (Хаки) - PS90 TR (khaki) + PS90 TR (хаки) + PS90 TR (Khaki) PS90 TR (Khaki) - PS90 TR (Khaki) + PS90 TR (Cachi) PS90 TR (Khaki) PS90 TR (Caqui) PS90 TR (カーキ) PS90 TR (沙色) - PS90 TR (沙色) - PS90 TR (Khaki) + PS90 TR(沙色) + PS90 TR (카키) + PS90 TR (Haki) PS90 TR (Camo) PS90 TR (Kamufláž) PS90 TR (Camo) PS90 TR (Camuflaje) - PS90 TR (Камо) + PS90 TR (камуфляжный) PS90 TR (kamuflaż) PS90 TR (Camo) - PS90 TR (Camo) + PS90 TR (Mimetica) PS90 TR (Terepmintás) PS90 TR (Camuflagem) - PS90 TR (カモフラージュ) + PS90 TR (AAF迷彩) PS90 TR (迷彩) - PS90 TR (迷彩) - PS90 TR (Camo) + PS90 TR(迷彩) + PS90 TR (위장) + PS90 TR (Kamufulaj) PS90 TR (Hex) PS90 TR (Hex) PS90 TR (Hex) PS90 TR (Hex) - PS90 TR (Гекс) + PS90 TR (гекс) PS90 TR (Hex) PS90 TR (hex) PS90 TR (Hex) PS90 TR (Hex) PS90 TR (Hex) - PS90 TR (ヘックス) + PS90 TR (六角形迷彩) PS90 TR (數位蜂巢迷彩) - PS90 TR (数位蜂巢迷彩) - PS90 TR (Hex) + PS90 TR(蜂巢迷彩) + PS90 TR (육각) + PS90 TR (Hex) PS90 (Black) PS90 (Černá) PS90 (Noir) PS90 (Negro) - PS90 (Чёрный) + PS90 (чёрный) PS90 (czarny) PS90 (Schwarz) PS90 (Nero) @@ -3867,78 +4886,83 @@ PS90 (Preto) PS90 (ブラック) PS90 (黑色) - PS90 (黑色) - PS90 (Black) + PS90(黑色) + PS90 (검정) + PS90 (Siyah) PS90 (Khaki) PS90 (Khaki) PS90 (Kaki) PS90 (Caqui) - PS90 (Хаки) - PS90 (khaki) + PS90 (хаки) + PS90 (Khaki) PS90 (Khaki) - PS90 (Khaki) + PS90 (Cachi) PS90 (Khaki) PS90 (Caqui) PS90 (カーキ) PS90 (沙色) - PS90 (沙色) - PS90 (Khaki) + PS90(沙色) + PS90 (카키) + PS90 (Haki) PS90 (Camo) PS90 (Kamufláž) PS90 (Camo) PS90 (Camuflaje) - PS90 (Камо) + PS90 (камуфляжный) PS90 (kamuflaż) PS90 (Camo) - PS90 (Camo) + PS90 (Mimetica) PS90 (Terepmintás) PS90 (Camuflagem) - PS90 (カモフラージュ) + PS90 (AAF迷彩) PS90 (迷彩) - PS90 (迷彩) - PS90 (Camo) + PS90(迷彩) + PS90 (위장) + PS90 (Kamufulaj) PS90 (Hex) PS90 (Hex) PS90 (Hex) PS90 (Hex) - PS90 (Гекс) + PS90 (гекс) PS90 (Hex) PS90 (hex) PS90 (Hex) PS90 (Hex) PS90 (Hex) - PS90 (ヘックス) + PS90 (六角形迷彩) PS90 (數位蜂巢迷彩) - PS90 (数位蜂巢迷彩) - PS90 (Hex) + PS90(蜂巢迷彩) + PS90 (육각) + PS90 (Hex) 5.7mm 50Rnd Mag 5,7mm 50-as Tár 5,7mm 50-Patronen-Magazin Cargador de 50 balas SD de 5,7mm - Ch. 5,7mm 50Cps + Ch. 5,7 mm 50 Cps Magazynek 5,7mm 50rd 5.7mm 50náb. Zásobník Carregador de 50 projéteis de 5.7mm Caricatore 5.7mm 50Rnd Магазин из 50-ти 5,7 мм - 5.7mm 50 発入り弾倉 - 5.7mm 50發 彈匣 - 5.7mm 50发 弹匣 - 5.7mm 50Rnd Mag + 5.7mm 50Rnd マガジン + 5.7mm 50發 彈匣 + 5.7 mm 50发 弹匣 + 5.7mm 50발 들이 탄창 + 5.7mm 50Rnd Şarjör Caliber: 5.7mm<br />Rounds: 50<br />Used in: P90 Kaliber: 5,7mm<br />Patronen: 50<br />Eingesetzt von: P90 Kaliber: 5,7mm<br />Pociski: 50<br />Używany w: P90 - Calibre : 5,7mm<br />Cartouches : 50<br />Utilisé avec : P90 + Calibre : 5,7 mm<br />Cartouches : 50<br />Utilisé avec : P90 Calibre: 5.7mm<br />Balas: 50<br />Se usa en: P90 Калибр: 5,7 мм<br />Патронов: 50<br />Используются с: P90 Calibro: 5.7mm<br />Munizioni: 50<br />In uso su: P90 @@ -3946,9 +4970,554 @@ Calibre: 5.7mm<br />Cartuchos: 50<br />Usado em: P90 Kaliber: 5,7mm<br />Lövedékek: 50<br />Használható: P90 口径: 5.7mm<br />装弾数: 50<br />次で使用: P90 - 口徑: 5.7mm<br />發數: 50<br />使用於: P90 - 口径: 5.7mm<br />发数: 50<br />使用于: P90 - 구경: 5.7mm<br />장탄수: 50<br />사용됨: P90 + 口徑: 5.7毫米<br />發數: 50<br />使用於: P90 + 口径:5.7 mm<br />发数:50<br />使用于:P90 + 구경: 5.7mm<br />장탄수: 50<br />사용처: P90 + Kalibre: 5.7mm<br />Mermi: 50<br />Kullanıyor: 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 (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 (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 GP-34 + AK-15 GL + AK-15 GL + AK-15 GL + + + AK-15 GL (Lush) + AK-15 GL (草木茂盛) + AK-15 GL (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 GP-34(繁茂) + AK-15 GL (緑地迷彩) + AK-15 GL (Gür) + AK-15 GL (esőerdő) + + + AK-15 GL (Arid) + AK-15 GL (乾燥氣候) + AK-15 GL (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 GP-34(干旱) + 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 (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 (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 (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 (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 (Noire) + 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) + 스토너 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 그롯 + MSBS Grot + MSBS グロート + 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 그롯 (검정) + MSBS Grot(黑色) + MSBS グロート (ブラック) + MSBS Grot (Siyah) + MSBS Grot (Fekete) + + + MSBS Grot (Camo) + MSBS Grot(迷彩) + MSBS Grot (Camo) + MSBS Grot (Camuflaje) + MSBS Grot (Mimetica) + MSBS Grot (Kamuflaż) + MSBS Grot (камуфляжный) + MSBS Grot (Tarnmuster) + MSBS Grot (Kamufláž) + MSBS Grot (Camo) + MSBS 그롯 (위장) + MSBS Grot(迷彩) + MSBS グロート (LDF迷彩) + MSBS Grot (Kamuflaj) + MSBS Grot (Terepmintás) + + + MSBS Grot (Sand) + MSBS Grot(沙色) + MSBS Grot (Beige) + MSBS Grot (Arena) + MSBS Grot (Sabbia) + MSBS Grot (Piaskowy) + MSBS Grot (песочный) + MSBS Grot (Sandfarben) + MSBS Grot (Písková) + MSBS Grot (Deserto) + MSBS 그롯 (모래) + MSBS Grot(沙色) + MSBS グロート (サンド) + 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 그롯 GL + MSBS Grot GPBO-40 + MSBS グロート 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 그롯 GL (검정) + MSBS Grot GPBO-40(黑色) + MSBS グロート 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 (Mimetica) + MSBS Grot GL (Kamuflaż) + MSBS Grot GL (камуфляжный) + MSBS Grot GL (Tarnmuster) + MSBS Grot GL (Kamufláž) + MSBS Grot GL (Camo) + MSBS 그롯 GL (위장) + MSBS Grot GPBO-40(迷彩) + MSBS グロート GL (LDF迷彩) + MSBS Grot GL (Kamuflaj) + MSBS Grot GL (Terepmintás) + + + MSBS Grot GL (Sand) + MSBS Grot GL(沙色) + MSBS Grot GL (Beige) + 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 그롯 GL (모래) + MSBS Grot GPBO-40(沙色) + MSBS グロート 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 그롯 MR + MSBS Grot MR + MSBS グロート 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 그롯 MR (검정) + MSBS Grot MR(黑色) + MSBS グロート 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 (Mimetica) + MSBS Grot MR (Kamuflaż) + MSBS Grot MR (камуфляжный) + MSBS Grot MR (Tarnmuster) + MSBS Grot MR (Kamufláž) + MSBS Grot MR (Camo) + MSBS 그롯 MR (위장) + MSBS Grot MR(迷彩) + MSBS グロート MR (LDF迷彩) + MSBS Grot MR (Kamuflaj) + MSBS Grot MR (Terepmintás) + + + MSBS Grot MR (Sand) + MSBS Grot MR(沙色) + MSBS Grot MR (Beige) + 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 그롯 MR (모래) + MSBS Grot MR(沙色) + MSBS グロート 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 그롯 SG + MSBS Grot SG + MSBS グロート 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 그롯 SG (검정) + MSBS Grot SG(黑色) + MSBS グロート 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 (Mimetica) + MSBS Grot SG (Kamuflaż) + MSBS Grot SG (камуфляжный) + MSBS Grot SG (Tarnmuster) + MSBS Grot SG (Kamufláž) + MSBS Grot SG (Camo) + MSBS 그롯 SG (위장) + MSBS Grot SG(迷彩) + MSBS グロート SG (LDF迷彩) + MSBS Grot SG (Kamuflaj) + MSBS Grot SG (Terepmintás) + + + MSBS Grot SG (Sand) + MSBS Grot SG(沙色) + MSBS Grot SG (Beige) + 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 그롯 SG (모래) + MSBS Grot SG(沙色) + MSBS グロート SG (サンド) + MSBS Grot SG (Kum) + MSBS Grot SG (Homok) diff --git a/addons/realisticweights/CfgWeapons.hpp b/addons/realisticweights/CfgWeapons.hpp index 25b83815b4..771b32b96f 100644 --- a/addons/realisticweights/CfgWeapons.hpp +++ b/addons/realisticweights/CfgWeapons.hpp @@ -1,5 +1,8 @@ class CfgWeapons { - class Rifle_Base_F; + class Rifle; + class Rifle_Base_F: Rifle { + class WeaponSlotsInfo; + }; class Rifle_Long_Base_F: Rifle_Base_F { class WeaponSlotsInfo; }; @@ -112,13 +115,94 @@ class CfgWeapons { }; }; + // - HK416A5 -------------------------------------------------------------- + class arifle_SPAR_01_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 68.8; + }; + }; + class arifle_SPAR_01_GL_base_F: arifle_SPAR_01_base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 96.8; + }; + }; + class arifle_SPAR_02_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 76.9; + }; + }; + + // - HK417A2 -------------------------------------------------------------- + class arifle_SPAR_03_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 104.5; + }; + }; + + // - AK15 - Weights taken from the 2020 AK-15 ----------------------------- + class arifle_AK12_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 82.5; + }; + }; + class arifle_AK12_GL_base_F: arifle_AK12_base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 113.5; + }; + }; + class arifle_AK12U_base_F: arifle_AK12_base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 65; + }; + }; + class arifle_RPK12_base_F: arifle_AK12_base_F { // Estimated difference by comparing RPK to AKM (+1.5kg) + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 115.5; + }; + }; + + // - AKM ------------------------------------------------------------------ + class arifle_AKM_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 67; + }; + }; + + // - AKS-74U -------------------------------------------------------------- + class arifle_AKS_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 60; + }; + }; + + // - MSBS ----------------------------------------------------------------- + class arifle_MSBS65_base_F: Rifle_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 82.7; + }; + }; + class arifle_MSBS65_GL_base_F: arifle_MSBS65_base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 124.5; + }; + }; + class arifle_MSBS65_UBS_base_F: arifle_MSBS65_base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 115.7; + }; + }; + class arifle_MSBS65_Mark_base_F: arifle_MSBS65_base_F { + class WeaponSlotsInfo { + mass = 101; + }; + }; // - LMGs --------------------------------------------------------------------- // - Stoner LMG ----------------------------------------------------------- class LMG_Mk200_F: Rifle_Long_Base_F { class WeaponSlotsInfo: WeaponSlotsInfo { - mass = 100; + mass = 114; }; }; @@ -129,6 +213,13 @@ class CfgWeapons { }; }; + // - FN Minimi SPW -------------------------------------------------------- + class LMG_03_base_F: Rifle_Long_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 154.4; + }; + }; + // - DMRs --------------------------------------------------------------------- @@ -218,6 +309,18 @@ class CfgWeapons { }; }; + class ACE_launch_NLAW_ready_F: launch_NLAW_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 195; // 275 - 80 + }; + }; + + class ACE_launch_NLAW_used_F: launch_NLAW_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 195; // 275 - 80 + }; + }; + // - RPG-32 --------------------------------------------------------------- class launch_RPG32_F: Launcher_Base_F { class WeaponSlotsInfo: WeaponSlotsInfo { @@ -238,6 +341,27 @@ class CfgWeapons { }; }; + // - RPG-7 ---------------------------------------------------------------- + class launch_RPG7_F: Launcher_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 139; + }; + }; + + // - MAAWS Mk4 ------------------------------------------------------------ + class launch_MRAWS_base_F: Launcher_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 145.5; + }; + }; + + // - Metis-M -------------------------------------------------------------- + class launch_Vorona_base_F: Launcher_Base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 224.8; + }; + }; + // - Pistols ------------------------------------------------------------------ @@ -311,9 +435,6 @@ class CfgWeapons { // - M14 ------------------------------------------------------------------ class DMR_06_base_F: Rifle_Long_Base_F { - class WeaponSlotsInfo; - }; - class srifle_DMR_06_camo_F: DMR_06_base_F { class WeaponSlotsInfo: WeaponSlotsInfo { mass = 92; }; diff --git a/addons/realisticweights/config.cpp b/addons/realisticweights/config.cpp index a26144aeca..91c1ea00aa 100644 --- a/addons/realisticweights/config.cpp +++ b/addons/realisticweights/config.cpp @@ -5,7 +5,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_common","ace_disposable"}; author = ECSTRING(common,ACETeam); authors[] = {"BaerMitUmlaut"}; url = ECSTRING(main,URL); diff --git a/addons/rearm/Cfg3DEN.hpp b/addons/rearm/Cfg3DEN.hpp index 05eb3c05ff..e5e52dbcd0 100644 --- a/addons/rearm/Cfg3DEN.hpp +++ b/addons/rearm/Cfg3DEN.hpp @@ -1,6 +1,6 @@ +#define VANILLA_REARMCARGO (if (getAmmoCargo _this > 0) then {getAmmoCargo _this} else {-1}) #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) -#define DEFAULT_REARMCARGO GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(defaultSupply),-1) - +#define DEFAULT_REARMCARGO GET_NUMBER(configOf _this >> 'GVAR(defaultSupply)',VANILLA_REARMCARGO) class Cfg3DEN { class Object { diff --git a/addons/rearm/CfgAmmo.hpp b/addons/rearm/CfgAmmo.hpp index 78151796c0..4bbd2fc2f7 100644 --- a/addons/rearm/CfgAmmo.hpp +++ b/addons/rearm/CfgAmmo.hpp @@ -1,183 +1,183 @@ class CfgAmmo { class BombCore; - class LaserBombCore : BombCore { + class LaserBombCore: BombCore { GVAR(caliber) = 250; // Default caliber for bombs }; class MissileCore; - class MissileBase : MissileCore { + class MissileBase: MissileCore { GVAR(caliber) = 250; // Default caliber for missiles }; - class Missile_AA_04_F : MissileBase { + class Missile_AA_04_F: MissileBase { GVAR(dummy) = QGVAR(Missile_AA_04_F); }; - class Missile_AA_03_F : Missile_AA_04_F { + class Missile_AA_03_F: Missile_AA_04_F { GVAR(dummy) = QGVAR(Missile_AA_03_F); }; - class Rocket_04_HE_F : MissileBase { + class Rocket_04_HE_F: MissileBase { GVAR(caliber) = 70; GVAR(dummy) = QGVAR(Rocket_04_HE_F); }; - class Rocket_03_HE_F : Rocket_04_HE_F { + class Rocket_03_HE_F: Rocket_04_HE_F { GVAR(dummy) = QGVAR(Rocket_03_HE_F); }; - class Rocket_04_AP_F : Rocket_04_HE_F { + class Rocket_04_AP_F: Rocket_04_HE_F { GVAR(dummy) = QGVAR(Rocket_04_AP_F); }; - class Rocket_03_AP_F : Rocket_04_AP_F { + class Rocket_03_AP_F: Rocket_04_AP_F { GVAR(dummy) = QGVAR(Rocket_03_AP_F); }; - class M_PG_AT : MissileBase { + class M_PG_AT: MissileBase { GVAR(caliber) = 70; GVAR(dummy) = QGVAR(M_PG_AT); }; - class Missile_AGM_02_F : MissileBase { + class Missile_AGM_02_F: MissileBase { GVAR(dummy) = QGVAR(Missile_AGM_02_F); }; - class Missile_AGM_01_F : Missile_AGM_02_F { + class Missile_AGM_01_F: Missile_AGM_02_F { GVAR(dummy) = QGVAR(Missile_AGM_01_F); }; class RocketCore; - class RocketBase : RocketCore { + class RocketBase: RocketCore { GVAR(caliber) = 70; // Default caliber for rockets }; - class R_80mm_HE : RocketBase { + class R_80mm_HE: RocketBase { GVAR(caliber) = 80; GVAR(dummy) = QGVAR(R_80mm_HE); }; - class R_60mm_HE : R_80mm_HE { + class R_60mm_HE: R_80mm_HE { GVAR(caliber) = 60; GVAR(dummy) = QGVAR(R_60mm_HE); }; class BulletBase; - class B_19mm_HE : BulletBase { + class B_19mm_HE: BulletBase { GVAR(caliber) = 19; }; - class B_20mm : BulletBase { + class B_20mm: BulletBase { GVAR(caliber) = 20; }; class B_20mm_AP: BulletBase { GVAR(caliber) = 20; }; - class B_25mm : BulletBase { + class B_25mm: BulletBase { GVAR(caliber) = 25; }; - class B_30mm_AP : BulletBase { + class B_30mm_AP: BulletBase { GVAR(caliber) = 30; }; - class B_30mm_HE : B_19mm_HE { + class B_30mm_HE: B_19mm_HE { GVAR(caliber) = 30; }; - class Gatling_30mm_HE_Plane_CAS_01_F : BulletBase { + class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { GVAR(caliber) = 30; }; - class B_35mm_AA : BulletBase { + class B_35mm_AA: BulletBase { GVAR(caliber) = 35; }; class B_30mm_APFSDS; - class B_40mm_APFSDS : B_30mm_APFSDS { + class B_40mm_APFSDS: B_30mm_APFSDS { GVAR(caliber) = 40; }; - class B_40mm_GPR : B_30mm_HE { + class B_40mm_GPR: B_30mm_HE { GVAR(caliber) = 40; }; class GrenadeBase; - class G_40mm_HE : GrenadeBase { + class G_40mm_HE: GrenadeBase { GVAR(caliber) = 39; }; class ShellBase; - class R_230mm_fly : ShellBase { + class R_230mm_fly: ShellBase { GVAR(dummy) = QGVAR(R_230mm_fly); }; - class Sh_120mm_APFSDS : Shellbase { + class Sh_120mm_APFSDS: ShellBase { GVAR(caliber) = 120; }; - class Sh_105mm_APFSDS : Sh_120mm_APFSDS { + class Sh_105mm_APFSDS: Sh_120mm_APFSDS { GVAR(caliber) = 105; }; - class Sh_125mm_APFSDS : Sh_120mm_APFSDS { + class Sh_125mm_APFSDS: Sh_120mm_APFSDS { GVAR(caliber) = 125; }; - class Sh_120mm_HE : ShellBase { + class Sh_120mm_HE: ShellBase { GVAR(caliber) = 120; }; - class Sh_125mm_HE : Sh_120mm_HE { + class Sh_125mm_HE: Sh_120mm_HE { GVAR(caliber) = 125; }; - class Sh_125mm_HEAT : Sh_125mm_HE { + class Sh_125mm_HEAT: Sh_125mm_HE { GVAR(caliber) = 125; }; - class Sh_105mm_HEAT_MP : Sh_125mm_HEAT { + class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { GVAR(caliber) = 105; }; - class Sh_155mm_AMOS : ShellBase { + class Sh_155mm_AMOS: ShellBase { GVAR(caliber) = 155; }; - class Sh_82mm_AMOS : Sh_155mm_AMOS { + class Sh_82mm_AMOS: Sh_155mm_AMOS { GVAR(caliber) = 82; }; class Sh_82mm_AMOS_LG; - class Sh_155mm_AMOS_LG : Sh_82mm_AMOS_LG { + class Sh_155mm_AMOS_LG: Sh_82mm_AMOS_LG { GVAR(caliber) = 155; }; class ShotDeployBase; - class Smoke_82mm_AMOS_White : ShotDeployBase { + class Smoke_82mm_AMOS_White: ShotDeployBase { GVAR(caliber) = 82; }; class FlareCore; - class Flare_82mm_AMOS_White : FlareCore { + class Flare_82mm_AMOS_White: FlareCore { GVAR(caliber) = 82; }; - class SmokeLauncherAmmo : BulletBase { + class SmokeLauncherAmmo: BulletBase { GVAR(caliber) = 250; }; - class CMflareAmmo : BulletBase { + class CMflareAmmo: BulletBase { GVAR(caliber) = 39; }; class SubmunitionBase; - class Sh_82mm_AMOS_guided : SubmunitionBase { + class Sh_82mm_AMOS_guided: SubmunitionBase { GVAR(caliber) = 82; }; - class Sh_155mm_AMOS_guided : Sh_82mm_AMOS_guided { + class Sh_155mm_AMOS_guided: Sh_82mm_AMOS_guided { GVAR(caliber) = 155; }; - class R_230mm_HE : SubmunitionBase { + class R_230mm_HE: SubmunitionBase { GVAR(caliber) = 230; }; - class Mine_155mm_AMOS_range : SubmunitionBase { + class Mine_155mm_AMOS_range: SubmunitionBase { GVAR(caliber) = 155; }; - class Cluster_155mm_AMOS : SubmunitionBase { + class Cluster_155mm_AMOS: SubmunitionBase { GVAR(caliber) = 155; }; - class Smoke_120mm_AMOS_White : SubmunitionBase { + class Smoke_120mm_AMOS_White: SubmunitionBase { GVAR(caliber) = 155; }; - class AT_Mine_155mm_AMOS_range : SubmunitionBase { + class AT_Mine_155mm_AMOS_range: SubmunitionBase { GVAR(caliber) = 155; }; - class Bo_Mk82 : BombCore { + class Bo_Mk82: BombCore { GVAR(dummy) = QGVAR(Bo_Mk82); }; diff --git a/addons/rearm/CfgEventHandlers.hpp b/addons/rearm/CfgEventHandlers.hpp index 077779a642..a737ccd1f3 100644 --- a/addons/rearm/CfgEventHandlers.hpp +++ b/addons/rearm/CfgEventHandlers.hpp @@ -1,13 +1,13 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; @@ -21,7 +21,7 @@ class Extended_Init_EventHandlers { class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/rearm/CfgMagazines.hpp b/addons/rearm/CfgMagazines.hpp index a509377182..7f70238086 100644 --- a/addons/rearm/CfgMagazines.hpp +++ b/addons/rearm/CfgMagazines.hpp @@ -1,56 +1,56 @@ class CfgMagazines { class CA_Magazine; - class 60Rnd_CMFlareMagazine : CA_Magazine { + class 60Rnd_CMFlareMagazine: CA_Magazine { displayName = CSTRING(Mag_60Rnd_CMFlareMagazine); }; class VehicleMagazine; - class SmokeLauncherMag : VehicleMagazine { + class SmokeLauncherMag: VehicleMagazine { displayName = CSTRING(Mag_SmokeLauncherMag); }; - class SmokeLauncherMag_boat : VehicleMagazine { + class SmokeLauncherMag_boat: VehicleMagazine { displayName = CSTRING(Mag_SmokeLauncherMag); }; - class 1000Rnd_Gatling_30mm_Plane_CAS_01_F : VehicleMagazine { + class 1000Rnd_Gatling_30mm_Plane_CAS_01_F: VehicleMagazine { displayName = CSTRING(Mag_1000Rnd_Gatling_30mm_Plane_CAS_01_F); }; - class 500Rnd_Cannon_30mm_Plane_CAS_02_F : 1000Rnd_Gatling_30mm_Plane_CAS_01_F { + class 500Rnd_Cannon_30mm_Plane_CAS_02_F: 1000Rnd_Gatling_30mm_Plane_CAS_01_F { displayName = CSTRING(Mag_500Rnd_Cannon_30mm_Plane_CAS_02_F); }; - class 2Rnd_Missile_AA_04_F : VehicleMagazine { + class 2Rnd_Missile_AA_04_F: VehicleMagazine { displayName = CSTRING(Mag_2Rnd_Missile_AA_04_F); }; - class 2Rnd_Missile_AA_03_F : 2Rnd_Missile_AA_04_F { + class 2Rnd_Missile_AA_03_F: 2Rnd_Missile_AA_04_F { displayName = CSTRING(Mag_2Rnd_Missile_AA_03_F); }; - class 6Rnd_Missile_AGM_02_F : VehicleMagazine { + class 6Rnd_Missile_AGM_02_F: VehicleMagazine { displayName = CSTRING(Mag_6Rnd_Missile_AGM_02_F); }; - class 4Rnd_Missile_AGM_01_F : 6Rnd_Missile_AGM_02_F { + class 4Rnd_Missile_AGM_01_F: 6Rnd_Missile_AGM_02_F { displayName = CSTRING(Mag_4Rnd_Missile_AGM_01_F); }; - class 7Rnd_Rocket_04_HE_F : VehicleMagazine { + class 7Rnd_Rocket_04_HE_F: VehicleMagazine { displayName = CSTRING(Mag_7Rnd_Rocket_04_HE_F); }; - class 20Rnd_Rocket_03_HE_F : 7Rnd_Rocket_04_HE_F { + class 20Rnd_Rocket_03_HE_F: 7Rnd_Rocket_04_HE_F { displayName = CSTRING(Mag_20Rnd_Rocket_03_HE_F); }; - class 7Rnd_Rocket_04_AP_F : 7Rnd_Rocket_04_HE_F { + class 7Rnd_Rocket_04_AP_F: 7Rnd_Rocket_04_HE_F { displayName = CSTRING(Mag_7Rnd_Rocket_04_AP_F); }; - class 20Rnd_Rocket_03_AP_F : 7Rnd_Rocket_04_AP_F { + class 20Rnd_Rocket_03_AP_F: 7Rnd_Rocket_04_AP_F { displayName = CSTRING(Mag_20Rnd_Rocket_03_AP_F); }; - class 4Rnd_Bomb_04_F : VehicleMagazine { + class 4Rnd_Bomb_04_F: VehicleMagazine { displayName = CSTRING(Mag_4Rnd_Bomb_04_F); }; - class 2Rnd_Bomb_03_F : 4Rnd_Bomb_04_F { + class 2Rnd_Bomb_03_F: 4Rnd_Bomb_04_F { displayName = CSTRING(Mag_2Rnd_Bomb_03_F); }; }; diff --git a/addons/rearm/CfgVehicles.hpp b/addons/rearm/CfgVehicles.hpp index c12ee16066..9d36d5baae 100644 --- a/addons/rearm/CfgVehicles.hpp +++ b/addons/rearm/CfgVehicles.hpp @@ -102,60 +102,49 @@ class CfgVehicles { class Truck_03_base_F; class O_Truck_03_ammo_F: Truck_03_base_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; class Truck_02_base_F; class Truck_02_Ammo_base_F: Truck_02_base_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; class B_Truck_01_mover_F; class B_Truck_01_ammo_F: B_Truck_01_mover_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; class B_APC_Tracked_01_base_F; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; class Heli_Transport_04_base_F; class O_Heli_Transport_04_ammo_F: Heli_Transport_04_base_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; class Pod_Heli_Transport_04_base_F; class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; class Slingload_01_Base_F; class B_Slingload_01_Ammo_F: Slingload_01_Base_F { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; - class ReammoBox_F; - class NATO_Box_Base: ReammoBox_F{}; + class NATO_Box_Base; class Box_NATO_AmmoVeh_F: NATO_Box_Base { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; - class EAST_Box_Base: ReammoBox_F{}; + class EAST_Box_Base; class Box_East_AmmoVeh_F: EAST_Box_Base { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; - class IND_Box_Base: ReammoBox_F{}; + class IND_Box_Base; class Box_IND_AmmoVeh_F: IND_Box_Base { - transportAmmo = 0; GVAR(defaultSupply) = 1200; }; diff --git a/addons/rearm/README.md b/addons/rearm/README.md index 4d6dc966a1..010e9cf526 100644 --- a/addons/rearm/README.md +++ b/addons/rearm/README.md @@ -3,9 +3,3 @@ ace_rearm The Rearm module introduces ability to rearm vehicles on different realistic levels. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [GitHawk] (https://github.com/GitHawk) -- [Jonpas] (https://github.com/jonpas) diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf index 3da59af9bd..61ec35b8de 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -1,34 +1,44 @@ #include "script_component.hpp" -GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace; GVAR(configTypesAdded) = []; -["ace_settingsInitialized", { - TRACE_2("settingsInit",GVAR(level),GVAR(supply)); - ["LandVehicle", "Init", {_this call FUNC(initSupplyVehicle)}, true, ["StaticWeapon"], true] call CBA_fnc_addClassEventHandler; - ["ReammoBox_F", "Init", {_this call FUNC(initSupplyVehicle)}, true, [], true] call CBA_fnc_addClassEventHandler; -}] call CBA_fnc_addEventHandler; +GVAR(magazineNameCache) = createHashMap; +GVAR(usedMagazineNames) = createHashMap; -["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; -[QGVAR(initSupplyVehicle), { +[QGVAR(initSupplyVehicle), { TRACE_1("initSupplyVehicle EH",_this); // Warning: this can run before settings are init [FUNC(initSupplyVehicle), _this] call EFUNC(common,runAfterSettingsInit); }] call CBA_fnc_addEventHandler; -["vehicle", { - params ["_unit"]; - [_unit] call FUNC(dropAmmo); -}] call CBA_fnc_addPlayerEventHandler; +["CBA_settingsInitialized", { + TRACE_3("settingsInit",GVAR(enabled),GVAR(level),GVAR(supply)); -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {params ["_unit"]; [_unit] call FUNC(dropAmmo)}]; -}; + // need these events before enabled check for zeus rearm + [QGVAR(rearmEntireVehicleSuccessEH), LINKFUNC(rearmEntireVehicleSuccess)] call CBA_fnc_addEventHandler; + [QGVAR(rearmEntireVehicleSuccessLocalEH), LINKFUNC(rearmEntireVehicleSuccessLocal)] call CBA_fnc_addEventHandler; + [QGVAR(makeDummyEH), LINKFUNC(makeDummy)] call CBA_fnc_addEventHandler; + [QGVAR(rearmSuccessEH), LINKFUNC(rearmSuccess)] call CBA_fnc_addEventHandler; + [QGVAR(rearmSuccessLocalEH), LINKFUNC(rearmSuccessLocal)] call CBA_fnc_addEventHandler; -[QGVAR(makeDummyEH), LINKFUNC(makeDummy)] call CBA_fnc_addEventHandler; -[QGVAR(rearmEntireVehicleSuccessEH), LINKFUNC(rearmEntireVehicleSuccess)] call CBA_fnc_addEventHandler; -[QGVAR(rearmEntireVehicleSuccessLocalEH), LINKFUNC(rearmEntireVehicleSuccessLocal)] call CBA_fnc_addEventHandler; -[QGVAR(rearmSuccessEH), LINKFUNC(rearmSuccess)] call CBA_fnc_addEventHandler; -[QGVAR(rearmSuccessLocalEH), LINKFUNC(rearmSuccessLocal)] call CBA_fnc_addEventHandler; + if (!GVAR(enabled)) exitWith {}; + ["AllVehicles", "Init", LINKFUNC(initSupplyVehicle), true, ["Man", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; + ["ReammoBox_F", "Init", LINKFUNC(initSupplyVehicle), true, [], true] call CBA_fnc_addClassEventHandler; + ["House", "Init", LINKFUNC(initSupplyVehicle), true, [], true] call CBA_fnc_addClassEventHandler; -GVAR(magazineNameCache) = [] call CBA_fnc_createNamespace; -GVAR(originalMagazineNames) = []; + // placed in editor static objects don't trigger init + { + _x call FUNC(initSupplyVehicle); + } forEach allMissionObjects "Static"; + + ["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; + + ["vehicle", { + params ["_unit"]; + [_unit] call FUNC(dropAmmo); + }] call CBA_fnc_addPlayerEventHandler; + + if (isServer) then { + addMissionEventHandler ["HandleDisconnect", {params ["_unit"]; [_unit] call FUNC(dropAmmo)}]; + }; + +}] call CBA_fnc_addEventHandler; diff --git a/addons/rearm/XEH_preInit.sqf b/addons/rearm/XEH_preInit.sqf index 10156a7d1c..4aa8cb80ad 100644 --- a/addons/rearm/XEH_preInit.sqf +++ b/addons/rearm/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" DFUNC(rearm_statement) = { // moved from config because of build problems TRACE_1("rearm_statement",_this); diff --git a/addons/rearm/XEH_preStart.sqf b/addons/rearm/XEH_preStart.sqf index 022888575e..b013b04b86 100644 --- a/addons/rearm/XEH_preStart.sqf +++ b/addons/rearm/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Test binarization one time at startup - ref https://github.com/acemod/ACE3/pull/8093 +private _test = getText (configFile >> "Cfg3DEN" >> "Object" >> "AttributeCategories" >> "ace_attributes" >> "Attributes" >> "ace_rearm_rearmCargo" >> "defaultValue"); +if !("else {" in _test) then { + ERROR("3den attribute has ERROR [check binarization]"); +}; diff --git a/addons/rearm/dev/test_debugConfigs.sqf b/addons/rearm/dev/test_debugConfigs.sqf index 8b61bf195f..be287686ca 100644 --- a/addons/rearm/dev/test_debugConfigs.sqf +++ b/addons/rearm/dev/test_debugConfigs.sqf @@ -1,14 +1,21 @@ // ["vehicleTransportAmmo"] call ace_common_fnc_runTests; // execVM "z\ace\addons\rearm\dev\test_debugConfigs.sqf"; -#include "\z\ace\addons\rearm\script_component.hpp" +#include "..\script_component.hpp" private _testPass = true; -INFO("Showing CfgVehicles with vanilla transportAmmo"); +INFO("Showing CfgVehicles with vanilla transportAmmo and without XEH"); + +private _badCfgVehicles = toString { + getNumber (_x >> "scope") == 2 + && {getNumber (_x >> "transportAmmo") > 0} + && {!isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init")} +}; + { - WARNING_2("Type [%1] needs config [transportAmmo: %2]", configName _x, getNumber (_x >> 'transportAmmo')); + diag_log text format ["Class %1: %2 [%3] needs XEH", configName _x, configName inheritsFrom _x, configSourceMod _x]; _testPass = false; -} forEach (configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportAmmo')) > 0}", true]); +} forEach (_badCfgVehicles configClasses (configFile >> "CfgVehicles")); _testPass diff --git a/addons/rearm/functions/fnc_addMagazineToSupply.sqf b/addons/rearm/functions/fnc_addMagazineToSupply.sqf index 1f646e3598..a143a22592 100644 --- a/addons/rearm/functions/fnc_addMagazineToSupply.sqf +++ b/addons/rearm/functions/fnc_addMagazineToSupply.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Adds magazines to the supply. [Global Effects] @@ -49,7 +49,7 @@ if (GVAR(supply) == 2) then { private _magazineIdx = -1; { _x params ["_magazine", "_rounds"]; - if ((_magazine isEqualTo _magazineClass)) exitWith { + if (_magazine isEqualTo _magazineClass) exitWith { _magazineIdx = _forEachIndex; }; } forEach _magazineSupply; diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index cb54ca5c1e..200dd2f2b4 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Show the resupplyable ammunition of all surrounding vehicles. @@ -18,14 +18,21 @@ params ["_truck", "_player"]; -private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20]; -_vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}}; +private _vehicles = nearestObjects [_truck, ["AllVehicles"], GVAR(distance)]; +_vehicles = _vehicles select { + _x != _truck + && {!(_x isKindOf "CAManBase")} + && {alive _x} + && {!(_x getVariable [QGVAR(disabled), false])} +}; private _cswCarryMagazines = []; private _vehicleActions = []; { private _vehicle = _x; - + private _displayName = getText (configOf _vehicle >> "displayName"); + private _distanceStr = (ACE_player distance _vehicle) toFixed 1; + private _actionName = format ["%1 (%2m)", _displayName, _distanceStr]; // Array of magazines that can be rearmed in the vehicle private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0}; @@ -43,8 +50,8 @@ private _vehicleActions = []; TRACE_2("can add",_x,_magazineHelper); - if (!(_magazineHelper isEqualTo [])) then { - private _icon = getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Icon"); + if (_magazineHelper isNotEqualTo []) then { + private _icon = getText(configOf _vehicle >> "Icon"); if !((_icon select [0, 1]) == "\") then { _icon = ""; }; @@ -52,7 +59,7 @@ private _vehicleActions = []; // [Level 0] adds a single action to rearm the entire vic private _action = [ _vehicle, - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), + _actionName, _icon, {_this call FUNC(rearmEntireVehicle)}, {true}, @@ -79,7 +86,7 @@ private _vehicleActions = []; private _action = [ _vehicle, - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), + _actionName, _icon, {}, {true}, @@ -92,7 +99,7 @@ private _vehicleActions = []; }; } forEach _vehicles; -if (!(_cswCarryMagazines isEqualTo [])) then { +if (_cswCarryMagazines isNotEqualTo []) then { _cswCarryMagazines = _cswCarryMagazines arrayIntersect _cswCarryMagazines; _cswCarryMagazines = _cswCarryMagazines select {[_truck, _x] call FUNC(hasEnoughSupply)}; private _baseAction = [QGVAR(cswTake), "CSW", "", {}, {true}] call EFUNC(interact_menu,createAction); diff --git a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf index 1ab5377aad..f218276350 100644 --- a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf +++ b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Adds all magazines of a vehicle to the supply. @@ -27,7 +27,7 @@ TRACE_2("addVehicleMagazinesToSupply",_truck,_vehicle); if (isNull _truck) exitWith {}; if (_vehicle isEqualType objNull) then {_vehicle = typeOf _vehicle}; if (_vehicle == "") exitWith { - ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string); + ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_vehicle); }; private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { @@ -36,10 +36,8 @@ private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); TRACE_2("",_turretPath,_magazines); { [_truck, _x] call FUNC(addMagazineToSupply); - false - } count _magazines; - false -} count _turrets; + } forEach _magazines; +} forEach _turrets; // 1.70 pylons private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; diff --git a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf index 824eb07f78..85c23f27d9 100644 --- a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Checks if unit can read supply counter. [Only for GVAR(supply) > 0] diff --git a/addons/rearm/functions/fnc_canRearm.sqf b/addons/rearm/functions/fnc_canRearm.sqf index bda5d8088c..8d2b0b58e5 100644 --- a/addons/rearm/functions/fnc_canRearm.sqf +++ b/addons/rearm/functions/fnc_canRearm.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Check if a unit can rearm. diff --git a/addons/rearm/functions/fnc_canStoreAmmo.sqf b/addons/rearm/functions/fnc_canStoreAmmo.sqf index b0f22b6e07..5eb954fe34 100644 --- a/addons/rearm/functions/fnc_canStoreAmmo.sqf +++ b/addons/rearm/functions/fnc_canStoreAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check if a unit can store ammo in an ammo truck. @@ -17,7 +17,7 @@ */ params ["_truck", "_unit"]; - + (alive _unit) && {!isNull (_unit getVariable [QGVAR(dummy), objNull])} && {alive _truck} diff --git a/addons/rearm/functions/fnc_canTakeAmmo.sqf b/addons/rearm/functions/fnc_canTakeAmmo.sqf index 5b0a41f9b2..6d4e9d4492 100644 --- a/addons/rearm/functions/fnc_canTakeAmmo.sqf +++ b/addons/rearm/functions/fnc_canTakeAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check if a unit can pick up ammo. diff --git a/addons/rearm/functions/fnc_createDummy.sqf b/addons/rearm/functions/fnc_createDummy.sqf index 05f6f3505b..45318cd13f 100644 --- a/addons/rearm/functions/fnc_createDummy.sqf +++ b/addons/rearm/functions/fnc_createDummy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Creates a carryable ammunition dummy object. diff --git a/addons/rearm/functions/fnc_disable.sqf b/addons/rearm/functions/fnc_disable.sqf index 4812c34cfb..82b3c39839 100644 --- a/addons/rearm/functions/fnc_disable.sqf +++ b/addons/rearm/functions/fnc_disable.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Disables being able to rearm a vehicle's turrets. [Global Effects] * * Arguments: * 0: Vehicle - * 1: Disable (optional) + * 1: Disable (default: true) * * Return Value: * None diff --git a/addons/rearm/functions/fnc_dropAmmo.sqf b/addons/rearm/functions/fnc_dropAmmo.sqf index d4c68ea34b..af4b74ee77 100644 --- a/addons/rearm/functions/fnc_dropAmmo.sqf +++ b/addons/rearm/functions/fnc_dropAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Drops a magazine, optionally deletes it and optionally unholsters the wepaon. diff --git a/addons/rearm/functions/fnc_getAllRearmTurrets.sqf b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf index 95f773e1bb..41edfeaabf 100644 --- a/addons/rearm/functions/fnc_getAllRearmTurrets.sqf +++ b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Tuupertunut * Returns all turrets in a vehicle. diff --git a/addons/rearm/functions/fnc_getCaliber.sqf b/addons/rearm/functions/fnc_getCaliber.sqf index c43c0ecbf2..2d58ef0344 100644 --- a/addons/rearm/functions/fnc_getCaliber.sqf +++ b/addons/rearm/functions/fnc_getCaliber.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Get the caliber of the ammo in a magazine and return its parameters. diff --git a/addons/rearm/functions/fnc_getMagazineName.sqf b/addons/rearm/functions/fnc_getMagazineName.sqf index f83d71e470..e961831c8c 100644 --- a/addons/rearm/functions/fnc_getMagazineName.sqf +++ b/addons/rearm/functions/fnc_getMagazineName.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: PabstMirror - * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE) + * Author: PabstMirror, johnb43 + * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE). * * Arguments: * 0: Magazine Classname @@ -10,7 +10,7 @@ * Display Name * * Example: - * ["B_20mm_AP"] call ace_rearm_fnc_getMagazineName + * "60Rnd_20mm_AP_shells" call ace_rearm_fnc_getMagazineName * * Public: No */ @@ -18,31 +18,31 @@ params ["_className"]; TRACE_1("getMagazineName",_className); -private _magName = GVAR(magazineNameCache) getVariable _className; -if (isNil "_magName") then { - private _displayName = getText(configFile >> "CfgMagazines" >> _className >> "displayName"); +GVAR(magazineNameCache) getOrDefaultCall [_className, { + private _cfgMagazines = configFile >> "CfgMagazines"; + private _displayName = getText (_cfgMagazines >> _className >> "displayName"); + if (_displayName == "") then { _displayName = _className; WARNING_1("Magazine is missing display name [%1]",_className); }; - if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; }; + // [CSW] prefix is localised + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _displayName = trim (_displayName regexReplace [LELSTRING(csw,regex), ""]); + }; - GVAR(magazineNameCache) setVariable [_className, _displayName]; - GVAR(originalMagazineNames) pushBack _displayName; + // If the display name exists already, add displayNameShort to the existing entry + private _existingClassname = GVAR(usedMagazineNames) get _displayName; + + if (!isNil "_existingClassname") then { + GVAR(magazineNameCache) set [_existingClassname, format ["%1: %2", _displayName, getText (_cfgMagazines >> _existingClassname >> "displayNameShort")]]; + + _displayName = format ["%1: %2", _displayName, getText (_cfgMagazines >> _className >> "displayNameShort")]; + }; + + GVAR(usedMagazineNames) set [_displayName, _className]; TRACE_2("Adding to cache",_className,_displayName); - // go through all existing cache entries and update if there now are duplicates - { - private _xMagName = GVAR(magazineNameCache) getVariable _x; - if ((_xMagName == _displayName) && {({_xMagName == _x} count GVAR(originalMagazineNames)) > 1}) then { - private _xMagName = format ["%1: %2", _displayName, getText(configFile >> "CfgMagazines" >> _x >> "displayNameShort")]; - GVAR(magazineNameCache) setVariable [_x, _xMagName]; - TRACE_2("Using unique name",_x,_xMagName); - }; - } forEach (allVariables GVAR(magazineNameCache)); - - _magName = GVAR(magazineNameCache) getVariable _className; -}; - -_magName + _displayName +}, true] // return diff --git a/addons/rearm/functions/fnc_getMaxMagazines.sqf b/addons/rearm/functions/fnc_getMaxMagazines.sqf index 45f90d6579..9cf262d59d 100644 --- a/addons/rearm/functions/fnc_getMaxMagazines.sqf +++ b/addons/rearm/functions/fnc_getMaxMagazines.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Calculates the maximum number of magazines a turret can hold according to config. diff --git a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf index 9dbcf463eb..078af4d887 100644 --- a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf +++ b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Tuupertunut * Returns information about every magazine that can be rearmed in the vehicle. Multiple mags of @@ -30,7 +30,7 @@ params ["_vehicle"]; private _magazineInfo = []; // 1.70 pylons -private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; +private _pylonConfigs = configProperties [configOf _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; { private _pylonConfig = _x; @@ -41,14 +41,14 @@ private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf private _pylonMagazine = (getPylonMagazines _vehicle) select (_pylonIndex - 1); // Only care about pylons that have a magazine. - if (!(_pylonMagazine isEqualTo "")) then { + if (_pylonMagazine isNotEqualTo "") 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); + private _pylonTurret = [_vehicle, _forEachIndex] call EFUNC(common,getPylonTurret); _magazineInfo pushBack [_pylonMagazine, _pylonTurret, true, _pylonIndex, 1, 1, _maxRounds, [_currentRounds]]; }; @@ -58,10 +58,19 @@ private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { private _turretPath = _x; - private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); + private _magazineClasses = []; - // _magazines without duplicates - private _magazineClasses = _magazines arrayIntersect _magazines; + if (_vehicle getVariable [QGVAR(scriptedLoadout), false]) then { + { + _x params ["_className", "_turretCurrent"]; + if (_turretPath isEqualTo _turretCurrent) then { + _magazineClasses pushBackUnique _className; + }; + } forEach (magazinesAllTurrets _vehicle); + } else { + _magazineClasses = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); + _magazineClasses = _magazineClasses arrayIntersect _magazineClasses; + }; { private _magazineClass = _x; diff --git a/addons/rearm/functions/fnc_getSupplyCount.sqf b/addons/rearm/functions/fnc_getSupplyCount.sqf index 892764b76f..867328751f 100644 --- a/addons/rearm/functions/fnc_getSupplyCount.sqf +++ b/addons/rearm/functions/fnc_getSupplyCount.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Get the supply count. @@ -25,8 +25,8 @@ if (GVAR(supply) != 1) exitWith { private _supply = _truck getVariable QGVAR(currentSupply); if (isNil "_supply") then { - if (isNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply))) then { - _supply = getNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply)); + if (isNumber (configOf _truck >> QGVAR(defaultSupply))) then { + _supply = getNumber (configOf _truck >> QGVAR(defaultSupply)); } else { _supply = 1200; }; diff --git a/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf index 56a2fbdf05..e253d13e64 100644 --- a/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf +++ b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Returns all magazines a turret of a vehicle object can hold according to config. diff --git a/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf index 2e914f3e7a..1daa4ca722 100644 --- a/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf +++ b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Tuupertunut * Returns the current ammo counts in all magazines of given class in turret. @@ -23,5 +23,4 @@ params ["_vehicle", "_turretPath", "_magazineClass"]; -private _ammo = magazinesAllTurrets _vehicle select {(_x select 0) isEqualTo _magazineClass && {(_x select 1) isEqualTo _turretPath}} apply {_x select 2}; -_ammo +magazinesAllTurrets _vehicle select {(_x select 0) == _magazineClass && {(_x select 1) isEqualTo _turretPath}} apply {_x select 2} diff --git a/addons/rearm/functions/fnc_grabAmmo.sqf b/addons/rearm/functions/fnc_grabAmmo.sqf index 8a72ec2cf1..d355485309 100644 --- a/addons/rearm/functions/fnc_grabAmmo.sqf +++ b/addons/rearm/functions/fnc_grabAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Grabs an dummy ammo. diff --git a/addons/rearm/functions/fnc_handleKilled.sqf b/addons/rearm/functions/fnc_handleKilled.sqf index 6ba6e4f4ee..1909980b1f 100644 --- a/addons/rearm/functions/fnc_handleKilled.sqf +++ b/addons/rearm/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Handles medical on set dead event. diff --git a/addons/rearm/functions/fnc_handleRespawn.sqf b/addons/rearm/functions/fnc_handleRespawn.sqf index a1ddd97301..3261501955 100644 --- a/addons/rearm/functions/fnc_handleRespawn.sqf +++ b/addons/rearm/functions/fnc_handleRespawn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: unknown * Called when a unit is Respawned diff --git a/addons/rearm/functions/fnc_handleUnconscious.sqf b/addons/rearm/functions/fnc_handleUnconscious.sqf index 18a8af4b56..3ff341a85c 100644 --- a/addons/rearm/functions/fnc_handleUnconscious.sqf +++ b/addons/rearm/functions/fnc_handleUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Handles medical on unconscious event. diff --git a/addons/rearm/functions/fnc_hasEnoughSupply.sqf b/addons/rearm/functions/fnc_hasEnoughSupply.sqf index 1af5d96a50..8b606bdf6f 100644 --- a/addons/rearm/functions/fnc_hasEnoughSupply.sqf +++ b/addons/rearm/functions/fnc_hasEnoughSupply.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check whether enough supply is left to take the magazine. @@ -44,7 +44,6 @@ if (GVAR(supply) == 2) exitWith { { _x params ["_magazine", "_rounds"]; if ((_magazine isEqualTo _magazineClass) && (_rounds > 0)) exitWith {_magazinePresent = true; }; - false - } count _magazineSupply; + } forEach _magazineSupply; _magazinePresent }; diff --git a/addons/rearm/functions/fnc_initSupplyVehicle.sqf b/addons/rearm/functions/fnc_initSupplyVehicle.sqf index 72b807d810..4ab04fcaf6 100644 --- a/addons/rearm/functions/fnc_initSupplyVehicle.sqf +++ b/addons/rearm/functions/fnc_initSupplyVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Githawk, PabstMirror * Adds rearm supply actions to a vehicle or ammo container. @@ -15,17 +15,28 @@ * Public: No */ -if (!hasInterface) exitWith {}; // For now we just add actions, so no need non-clients +if (!GVAR(enabled)) exitWith {}; params ["_vehicle"]; + private _typeOf = typeOf _vehicle; +private _configOf = configOf _vehicle; TRACE_2("initSupplyVehicle",_vehicle,_typeOf); +if (local _vehicle && {getAmmoCargo _vehicle > 0}) then { + _vehicle setAmmoCargo 0; +}; + +if (!hasInterface) exitWith {}; // For now we just add actions, so no need non-clients + if (!alive _vehicle) exitWith {}; -private _configSupply = getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(defaultSupply)); +private _configSupply = getNumber (_configOf >> QGVAR(defaultSupply)); +if (_configSupply == 0) then { + _configSupply = getNumber (_configOf >> "transportAmmo"); +}; private _isSupplyVehicle = _vehicle getVariable [QGVAR(isSupplyVehicle), false]; -private _oldRearmConfig = isClass (configFile >> "CfgVehicles" >> _typeOf >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(takeAmmo)); +private _oldRearmConfig = isClass (_configOf >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(takeAmmo)); TRACE_3("",_configSupply,_isSupplyVehicle,_oldRearmConfig); if ((_configSupply <= 0) && {!_isSupplyVehicle} && {!_oldRearmConfig}) exitWith {}; // Ignore if not enabled @@ -75,4 +86,3 @@ if (_oldRearmConfig || {_configSupply > 0}) then { [_vehicle, 0, ["ACE_MainActions"], _actionTakeAmmo] call EFUNC(interact_menu,addActionToObject); [_vehicle, 0, ["ACE_MainActions"], _actionStoreAmmo] call EFUNC(interact_menu,addActionToObject); }; - diff --git a/addons/rearm/functions/fnc_isSource.sqf b/addons/rearm/functions/fnc_isSource.sqf index 175ab60f8e..f4bffa3191 100644 --- a/addons/rearm/functions/fnc_isSource.sqf +++ b/addons/rearm/functions/fnc_isSource.sqf @@ -1,11 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: shukari * Returns if vehicle or object is a rearm source. * * Arguments: - * 0: target - * 1: check for vanilla rearm vehicle (default: false) + * 0: Target * * Return Value: * None @@ -15,16 +14,13 @@ * * Public: Yes */ -params [ - ["_target", objNull, [objNull]], - ["_testVanillaRearm", false, [false]] - ]; +params [["_target", objNull, [objNull]]]; if ((_target getVariable [QGVAR(currentSupply), 0]) < 0) exitWith {false}; - -private _vehCfg = configFile >> "CfgVehicles" >> typeOf _target; + +private _vehCfg = configOf _target; private _vanillaCargoConfig = getNumber (_vehCfg >> "transportAmmo"); private _rearmCargoConfig = getNumber (_vehCfg >> QGVAR(defaultSupply)); private _supplyVehicle = _target getVariable [QGVAR(isSupplyVehicle), false]; -_rearmCargoConfig > 0 || {_supplyVehicle} || {_testVanillaRearm && _vanillaCargoConfig > 0} +_rearmCargoConfig > 0 || {_supplyVehicle} || {_vanillaCargoConfig > 0} diff --git a/addons/rearm/functions/fnc_makeDummy.sqf b/addons/rearm/functions/fnc_makeDummy.sqf index d319d3587e..b79d2b96ac 100644 --- a/addons/rearm/functions/fnc_makeDummy.sqf +++ b/addons/rearm/functions/fnc_makeDummy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Make a dummy object by disabling collision and turning it. diff --git a/addons/rearm/functions/fnc_makeSource.sqf b/addons/rearm/functions/fnc_makeSource.sqf index c96c3a214a..85acbfa43a 100644 --- a/addons/rearm/functions/fnc_makeSource.sqf +++ b/addons/rearm/functions/fnc_makeSource.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: shukari (template from refuel makeSource) * Makes an object into a rearm source. @@ -30,7 +30,7 @@ params [ ["_addToCurrent", false, [false]] ]; TRACE_3("makeSource",_source,_rearmCargo,_addToCurrent); - + if (isNull _source) exitWith {}; private _currentSupply = if (_addToCurrent) then { @@ -41,16 +41,22 @@ private _currentSupply = if (_addToCurrent) then { _source setVariable [QGVAR(currentSupply), _currentSupply + _rearmCargo, true]; -private _rearmCargoConfig = getNumber (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(defaultSupply)); +private _config = configOf _source; +private _rearmCargoConfig = getNumber (_config >> QGVAR(defaultSupply)); +if (_rearmCargoConfig == 0) then { + _rearmCargoConfig = getNumber (_config >> "transportAmmo"); +}; -// already initialized because this is a config rearm vehicle -if (_rearmCargoConfig > 0 || _source getVariable [QGVAR(isSupplyVehicle), false]) exitWith {}; +// initialize if it's not a config rearm vehicle +if (!(_rearmCargoConfig > 0 && _source getVariable [QGVAR(isSupplyVehicle), false])) then { + _source setVariable [QGVAR(isSupplyVehicle), true, true]; -_source setVariable [QGVAR(isSupplyVehicle), true, true]; + // only add if menu does not already exist + if (isNil {_source getVariable QGVAR(initSupplyVehicle_jipID)}) then { + private _jipID = [QGVAR(initSupplyVehicle), [_source]] call CBA_fnc_globalEventJIP; + [_jipID, _source] call CBA_fnc_removeGlobalEventJIP; + _source setVariable [QGVAR(initSupplyVehicle_jipID), _jipID]; + }; +}; -// check if menu already exists -if (!isNil {_source getVariable QGVAR(initSupplyVehicle_jipID)}) exitWith {}; - -private _jipID = [QGVAR(initSupplyVehicle), [_source]] call CBA_fnc_globalEventJIP; -[_jipID, _source] call CBA_fnc_removeGlobalEventJIP; -_source setVariable [QGVAR(initSupplyVehicle_jipID), _jipID]; +[QGVAR(rearmSourceInitalized), [_source]] call CBA_fnc_globalEvent; diff --git a/addons/rearm/functions/fnc_moduleRearmSettings.sqf b/addons/rearm/functions/fnc_moduleRearmSettings.sqf index 4b61cfa2ee..c241078474 100644 --- a/addons/rearm/functions/fnc_moduleRearmSettings.sqf +++ b/addons/rearm/functions/fnc_moduleRearmSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Module for adjusting the rearm settings. diff --git a/addons/rearm/functions/fnc_pickUpAmmo.sqf b/addons/rearm/functions/fnc_pickUpAmmo.sqf index a47885e716..f080015a5e 100644 --- a/addons/rearm/functions/fnc_pickUpAmmo.sqf +++ b/addons/rearm/functions/fnc_pickUpAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Starts progress bar for picking up a specific kind of magazine from the ground. diff --git a/addons/rearm/functions/fnc_readSupplyCounter.sqf b/addons/rearm/functions/fnc_readSupplyCounter.sqf index 11abdc3ae8..f298579705 100644 --- a/addons/rearm/functions/fnc_readSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_readSupplyCounter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Get the remaining ammunition amount. @@ -51,15 +51,14 @@ if (GVAR(supply) == 1) then { private _numChars = count (localize LSTRING(Hint_RemainingAmmo)); private _text = ""; private _magazines = _truck getVariable QGVAR(magazineSupply); - if !(isNil "_magazines") then { + if (!isNil "_magazines") then { { _x params ["_magazineClass", "_rounds"]; private _line = format ["%1: %2", _magazineClass call FUNC(getMagazineName), _rounds]; _numChars = _numChars max (count _line); _text = format ["%1
%2", _text, _line]; _supply = _supply + 0.5; - false - } count _magazines; + } forEach _magazines; }; if (_supply > 1.5) then { [[LSTRING(Hint_RemainingAmmo), _text], _supply, _unit, (_numChars/2.9)] call EFUNC(common,displayTextStructured); diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf index 2556096c11..81f467a5ca 100644 --- a/addons/rearm/functions/fnc_rearm.sqf +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Starts progress bar for rearming a vehicle. @@ -43,10 +43,10 @@ private _magazineDisplayName = _magazineClass call FUNC(getMagazineName); [_target, _unit, _turretPath, _magazineCount, _magazineClass, (REARM_COUNT select _idx), _pylon], {(_this select 0) call FUNC(rearmSuccess)}, "", - format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName], + format [localize LSTRING(RearmAction), getText(configOf _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..74de2afe56 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Starts progress bar for rearming an entire vehicle. @@ -25,10 +25,10 @@ TRACE_3("rearmEntireVehicle",_truck,_player,_vehicle); [_truck, _vehicle, _player], {(_this select 0) call FUNC(rearmEntireVehicleSuccess)}, "", - format [localize LSTRING(BasicRearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], + format [localize LSTRING(BasicRearmAction), getText(configOf _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_rearmEntireVehicleSuccess.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf index 699b37ed40..396b501dab 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Rearm an entire vehicle. @@ -28,8 +28,7 @@ if (isServer) then { } else { [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; }; - false - } count _turrets; + } forEach _turrets; } else { [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; }; diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf index 8bf8244dd7..b734f0db13 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Tuupertunut * Rearm an entire turret locally. diff --git a/addons/rearm/functions/fnc_rearmSuccess.sqf b/addons/rearm/functions/fnc_rearmSuccess.sqf index d0610dbb5a..5be575bed1 100644 --- a/addons/rearm/functions/fnc_rearmSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmSuccess.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Rearms a vehicle, after progress bar finishes, pass args to machine where turret is local. diff --git a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf index 922d25b646..f41dff6ea9 100644 --- a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Rearms a vehicle on the turret owner. @@ -34,7 +34,7 @@ if (_pylon > 0) exitWith { _vehicle setPylonLoadOut [_pylon, _magazineClass, true, _turretPath]; [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _rounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; + getText(configOf _vehicle >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; } else { // Fill only at most _numRounds if (_turretPath isEqualTo [-1]) then {_turretPath = [];}; // Convert back to pylon turret format @@ -45,7 +45,7 @@ if (_pylon > 0) exitWith { _vehicle setAmmoOnPylon [_pylon, _newCount]; [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _numRounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; + getText(configOf _vehicle >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; }; }; @@ -54,7 +54,7 @@ private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMax private _ammoCounts = [_vehicle, _turretPath, _magazineClass] call FUNC(getTurretMagazineAmmo); TRACE_3("start",_magazineClass,_maxMagazines,_ammoCounts); -private _ammoToAdd = if (GVAR(level) == 2) then {_numRounds} else {_rounds}; +private _ammoToAdd = [_rounds, _numRounds] select (GVAR(level) == 2); private _ammoAdded = 0; private _arrayModified = false; // skip needing to remove and re-add mags, if we are only adding new ones @@ -74,7 +74,7 @@ while {((count _ammoCounts) < _maxMagazines) && {_ammoToAdd > 0}} do { _ammoToAdd = _ammoToAdd - _xAdd; _ammoAdded = _ammoAdded + _xAdd; _ammoCounts pushBack _xAdd; - if (!_arrayModified) then { + if (_arrayModified) then { TRACE_1("adding new mag to array",_xAdd); } else { TRACE_1("adding new mag directly",_xAdd); @@ -90,4 +90,4 @@ if (_ammoAdded == 0) exitWith {ERROR_1("could not load any ammo - %1",_this);}; [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _ammoAdded, _magazineClass call FUNC(getMagazineName), -getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; +getText(configOf _vehicle >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; diff --git a/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf b/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf index b6e6c4d0d2..3398254057 100644 --- a/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf +++ b/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Removes a magazine from the supply. @@ -57,7 +57,7 @@ if (GVAR(supply) == 2) then { private _magazineIdx = -1; { _x params ["_magazine"]; - if ((_magazine isEqualTo _magazineClass)) exitWith { + if (_magazine isEqualTo _magazineClass) exitWith { _magazineIdx = _forEachIndex; }; } forEach _magazineSupply; diff --git a/addons/rearm/functions/fnc_setSupplyCount.sqf b/addons/rearm/functions/fnc_setSupplyCount.sqf index 41b3016dba..e6eae13a7b 100644 --- a/addons/rearm/functions/fnc_setSupplyCount.sqf +++ b/addons/rearm/functions/fnc_setSupplyCount.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Sets the supply count. [Global Effects] diff --git a/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf index c2abe8a132..9744986f97 100644 --- a/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf +++ b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Tuupertunut * Sets the ammo counts of all magazines of given class in turret. @@ -57,7 +57,7 @@ if (!_magLoadedInWeapon) then { * 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 = [_loadedWeapon] call CBA_fnc_compatibleMagazines; + private _allowedMagClassesInWeapon = [_loadedWeapon, true] 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]]] */ @@ -77,7 +77,7 @@ if (!_magLoadedInWeapon) then { { _x params ["_loopMagClass", "_loopAmmoCounts"]; - if (!(_loopMagClass isEqualTo _magazineClass)) then { + if (_loopMagClass isNotEqualTo _magazineClass) then { { _vehicle addMagazineTurret [_loopMagClass, _turretPath, _x]; } forEach _loopAmmoCounts; diff --git a/addons/rearm/functions/fnc_storeAmmo.sqf b/addons/rearm/functions/fnc_storeAmmo.sqf index 18b316d601..e9f57369f3 100644 --- a/addons/rearm/functions/fnc_storeAmmo.sqf +++ b/addons/rearm/functions/fnc_storeAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Stores ammo in an ammo truck. @@ -33,7 +33,7 @@ private _magazineClass = _attachedDummy getVariable [QGVAR(magazineClass), "#noV [_unit, true, true] call FUNC(dropAmmo); }, "", - format [localize LSTRING(StoreAmmoAction), _magazineClass call FUNC(getMagazineName), getText(configFile >> "CfgVehicles" >> (typeOf _truck) >> "displayName")], + format [localize LSTRING(StoreAmmoAction), _magazineClass call FUNC(getMagazineName), getText(configOf _truck >> "displayName")], {true}, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_takeAmmo.sqf b/addons/rearm/functions/fnc_takeAmmo.sqf index 1c1e325de8..6a53e4dfdd 100644 --- a/addons/rearm/functions/fnc_takeAmmo.sqf +++ b/addons/rearm/functions/fnc_takeAmmo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Starts progress bar for picking up a specific kind of magazine from an ammo truck. @@ -30,7 +30,7 @@ REARM_HOLSTER_WEAPON; private _targetName = if (_vehicle == _unit) then { "CSW" } else { - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName") + getText(configOf _vehicle >> "displayName") }; [ diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf index e00d430f99..717d549b86 100644 --- a/addons/rearm/functions/fnc_takeSuccess.sqf +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Takes a magazine from an ammo truck. diff --git a/addons/rearm/functions/script_component.hpp b/addons/rearm/functions/script_component.hpp deleted file mode 100644 index 515b56ddc7..0000000000 --- a/addons/rearm/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\rearm\script_component.hpp" diff --git a/addons/rearm/initSettings.inc.sqf b/addons/rearm/initSettings.inc.sqf new file mode 100644 index 0000000000..6489bd9326 --- /dev/null +++ b/addons/rearm/initSettings.inc.sqf @@ -0,0 +1,35 @@ +private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + ELSTRING(common,Enabled), + _category, + true, + true, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(level), "LIST", + [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], + _category, + [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(supply), "LIST", + [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], + _category, + [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(distance), "SLIDER", + [LLSTRING(RearmSettings_distance_DisplayName), LLSTRING(RearmSettings_distance_Description)], + _category, + [10, 50, 20, 0], + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/rearm/initSettings.sqf b/addons/rearm/initSettings.sqf deleted file mode 100644 index 0e5e421747..0000000000 --- a/addons/rearm/initSettings.sqf +++ /dev/null @@ -1,19 +0,0 @@ -// CBA Settings [ADDON: ace_rearm]: - -[ - QGVAR(level), "LIST", - [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(DisplayName)], - [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(supply), "LIST", - [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(DisplayName)], - [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml index 7cbe3f4f51..b8dfd37f77 100644 --- a/addons/rearm/stringtable.xml +++ b/addons/rearm/stringtable.xml @@ -11,6 +11,10 @@ Réarmement Dozbrajanie Перевооружение + Rearme + Přezbrojení + Rearmar + 재보급 Rearm Settings @@ -36,9 +40,9 @@ Tento modul umožňuje upravovat systém přezbrojení. Questo modulo ti consente di cambiare le impostazioni del sistema Riarmo. Este módulo permite cambiar los parámetros de rearme. - Ce module autorise l'amélioration du système de réarmement. + Ce module vous permet d'ajuster les paramètres du système de réarmement. 再武装システムの設定を微調整します。 - 이 모듈은 재보급시의 설정을 바꿀수 있게해줍니다. + 이 모듈은 재보급시의 설정을 바꿀수 있게 해줍니다. 此模块允许你调整整装系统设定 此模塊允許你調整整裝系統設定 @@ -49,10 +53,10 @@ Степень перевооружения Quantidade de rearme Rychlost přezbrojení - Ammontare Riarmo + Velocità Riarmo Velocidad de rearme Quantité à réarmer - 再武装が可能な量 + 再武装の所要時間 재보급 양 整装所需时间 整裝所需時間 @@ -66,10 +70,10 @@ Jak rychle bude vozidlo přezbrojeno? Quanto velocemente dovrebbe essere riarmato un veicolo? Cuán rápido es el proceso de rearme? - A quelle vitesse devrait être réarmé un véhicule ? - 車両を再武装する早さを設定します。 + Définit la vitesse à laquelle s'effectue le réarmement. + 車両がどれくらいの早さで再武装されるか? 차량을 얼마나 빨리 재보급 시킵니까? - 载具多快会整装完毕? + 载具多快会整装完毕? 載具多快會整裝完畢? @@ -81,7 +85,7 @@ Celé vozidlo Tutto il Veicolo Vehículo completo - Véhicule entier + Tout le véhicule 車両全体 모든 차량 整个载具 @@ -96,7 +100,7 @@ Celý zásobník Tutto il Caricatore Cargador completo - Chargeur entier + Le chargeur entier マガジン全体 모든 탄창 整个弹匣 @@ -109,10 +113,10 @@ В зависимости от калибра Quantidade baseada no calibre Rychlost závisí na ráži - Ammontare basato sul calibro + Quantità basata sul calibro Cantidad basada en el calibre - Quantité basée sur le calibre - 口径に基づいた量 + En fonction du calibre + 口径に基づいて 구경에 따라 수량 설정 基于口径决定所耗时间 基於口徑決定所耗時間 @@ -126,20 +130,26 @@ 彈藥補給 Zapas amunicji 탄약 보급 - Approvisionnement en munitions + Quantité d'approvisionnement Запас боеприпасов + Suprimento de Munições + Zásoba munice + Suministro de munición How much ammunition does an ammo truck carry? Wie viel Munition transportiert ein Munitionslaster? Quante munizioni può trasportare un camion? 弾薬トラックの運搬量を設定します。 - 弹药卡车会携带多少的弹药? + 弹药卡车会携带多少的弹药? 彈藥卡車會攜帶多少的彈藥? Ile amunicji przewozi ciężarówka? - 탄약 차량은 얼마나 많은 양의 탄약을 가질 수 있음? - Quelle quantité de munitions un camion doit-il transporter ? + 탄약 차량은 얼마나 많은 양의 탄약을 가질 수 있습니까? + Définit la quantité de munitions que le camion de ravitaillement transporte. Какой боезапас перевозит грузовик с боеприпасами? + Quanta munição um caminhão de munições carrega? + Kolik munice naklaďák uveze? + ¿Cuánta munición carga el camión de armamento? Unlimited ammo supply @@ -149,9 +159,12 @@ 无限弹药 無限彈藥 Nielimitowany zapas amunicji - 무한의 탄약 - Approvisionnement en munitions illimité + 무한 탄약 보급 + Munitions illimitées Неограниченный боезапас + Suprimento Ilimitado de Munição + Nekonečná zásoba + Suministro de munición ilimitado Limited ammo supply based on caliber @@ -161,9 +174,12 @@ 基于口径限制弹药数量 基於口徑限制彈藥數量 Zapas amunicji zależny od kalibru - 구경에 따라 제한된 탄약 - Approvisionnement en munitions limité basé sur le calibre. + 구경에 따라 제한된 탄약 보급 + En fonction du calibre Ограниченный боезапас в зависимости от калибра + Munição Limitada ao Calibre + Konečná zásoba v závislosti na kalibru + Suministro de munición limitado en base al calibre Only specific Magazines @@ -174,8 +190,11 @@ 只有指定的彈藥 Tylko konkretne magazynki 특정 탄약만 - Seulement des chargeurs spécifiques + Chargeurs spécifiques uniquement Только определенные магазины + Apenas carregadores específicos + Pouze specifické zásobníky + Únicamente cargadores específicos Check remaining ammunition @@ -188,54 +207,69 @@ 남은 탄약 확인 Vérifier les munitions restantes Проверить остаток БК + Checar munição restante + Zkontrolovat zbývající munici + Comprobar munición restante Checking remaining ammunition... Überprüfe verbleibende Munition... Controllando le munizioni rimanenti - 残弾薬を確認中… - 正在检查剩余的弹药中... + 残弾薬を確認中・・・ + 正在检查剩余的弹药... 正在檢查剩餘的彈藥中... Sprawdzanie ilości amunicji... - 남은 탄약 확인중... + 남은 탄약 확인 중... Vérification des munitions restantes... Проверка остатка боекомплекта... + Checando Munição... + Kontroluji zbývající munici... + Comprobando munición restante... There is ammunition worth %1 points left. Es ist noch Munition für %1 Punkte übrig. - E' presente una penalità delle munizioni %1 punti rimanenti. - 弾薬は%1残っています。 - 还剩下%1多的弹药. + Sono presenti ancora munizioni del valore di %1 punti. + 弾薬は %1 残っています。 + 还剩下%1多的弹药。 還剩下%1多的彈藥. Pozostało %1 punktów amunicji. - 여기에는 최소 %1 포인트의 탄약이 남았습니다. + %1 의 탄약이 남아 있습니다. Il reste des munitions d'une valeur de %1 points. Остаток единиц БК: %1 + Possui munição equivalente a %1 pontos restantes. + Zbývá ještě %1 muničních bodů. + Queda munición equivalente a un 1% The following ammunition is left:%1 Folgende Munition ist übrig:%1 - Mancano le seguenti:%1 - この弾薬の残りは:%1 - 以下剩余的弹药:%1 + Rimangono le seguenti munizioni:%1 + この弾薬は残り: %1 + 以下剩余的弹药:%1 以下剩餘的彈藥:%1 Pozostała amunicja: %1 다음의 탄약이 남음 : %1 - Il reste les munitions suivantes %1 + Il reste les munitions suivantes : %1. Оставшийся боекомплект: %1 + A munição que restou: %1 + Zbývá následující munice:%1 + Queda la siguiente munición: 1% There is no ammunition left. Es ist keine Munition übrig. Non ci sono munizioni rimanenti. 弾薬は残っていない - 已经没有剩余的弹药了. + 已经没有剩余的弹药了。 已經沒有剩餘的彈藥了. Brak amunicji w zapasie. - 여기에는 탄약이 남지 않았습니다. - Il n'y a plus de munitions + 탄약이 남지 않았습니다. + Il n'y a plus de munitions. Запас боекомплекта пуст + Não há munição sobrando. + Už nezbývá žádná munice. + No queda munición Rearm @@ -251,6 +285,7 @@ 재보급 整装 整裝 + Yeniden Doldur Rearming %1 with %2... @@ -262,9 +297,9 @@ Riarmando %1 con %2... Rearmando %1 con %2... Réarmement de %1 avec %2... - %1に%2を再武装中… - %2을 %1에 재보급중... - %2正整装到%1中... + %1 に %2 を再武装中・・・ + %2을 %1에 재보급 중... + 正在整装%2到%1... %2正整裝到%1中... @@ -277,9 +312,9 @@ Riarmando %1... Rearmando %1... Réarmement de %1... - %1を再武装中… - %1 재보급중... - 整装%1中... + %1 を再武装中・・・ + %1 재보급 중... + 正在整装%1... 整裝%1中... @@ -291,10 +326,10 @@ Beru %1 pro %2... Sto prendendo %1 per %2... Tomando %1 para %2... - Prend %1 pour %2... - %1を%2用として取得中… - %2를 위해 %1 가져오는중... - 拿取%1给%2中... + Prise de %1 pour %2... + %1 を %2 用に取得中・・・ + %2를 위해 %1 가져오는 중... + 正在拿取%1给%2... 拿取%1給%2中... @@ -311,6 +346,7 @@ 탄약 가지기 取得弹药 取得彈藥 + Cephane al Pick up ammo @@ -326,6 +362,7 @@ 탄약 줍기 捡起弹药 撿起彈藥 + Cephaneyi al Store ammo @@ -352,9 +389,9 @@ Sto riponendo %1 in %2... Guardando %1 en %2... Stocke %1 dans %2... - %1を%2へ格納中… - %2에 %1 보관중... - 储存%1到%2中... + %1 を %2 へ格納中・・・ + %2에 %1 보관 중... + 正在储存%1到%2... 儲存%1到%2中... @@ -366,10 +403,11 @@ Sto raccogliendo le munizioni... Levantando munición... Ramassage des munitions... - 弾薬を拾得中… - 탄약 줍는중... - 捡起弹药中... + 弾薬を拾得中・・・ + 탄약 줍는 중... + 正在捡起弹药... 撿起彈藥中... + Sbírám munici... Rearmed %1 rounds of %2 on %3 @@ -380,8 +418,8 @@ Přezbrojeno % nábojů z %2 u %3 Riarmati %1 colpi di %2 su %3 Rearmadas %1 rondas de %2 en %3 - %1 balles réarmées de %2 dans %3 - %1発の%2を%3に装填しました + %1 balles réarmées de %2 dans %3. + %1 発の %2 を %3 に装填しました %3에 2%의 %1 탄약 재보급 整装了%1发%2到%3上 整裝了%1發%2到%3上 @@ -400,13 +438,14 @@ 연막 차장 烟幕弹 煙幕彈 + Sis Ekranı Flares Světlice Fusées Leuchtkörper - Razzi luminosi + Illuminanti Flary Sinalizadores ЛТЦ @@ -415,6 +454,7 @@ 기만체 热焰弹 熱焰彈 + Flareler 30mm HEI @@ -425,11 +465,12 @@ 30mm HEI 30mm HEI 30mm HEI - 30mm HEI - 30mm 焼夷りゅう弾 + 30 mm HEI + 30mm HEI 30mm 고폭소이탄 - 30mm 高爆燃烧弹 + 30 mm 高爆燃烧 30mm 高爆燃燒彈 + 30mm HEI 30mm HEI-T @@ -440,11 +481,12 @@ 30mm HEI-T 30mm HEI-T 30mm HEI-T - 30mm HEI-T - 30mm 焼夷曳光りゅう弾 + 30 mm HEI-T + 30mm HEI-T 30mm 고폭소이예광탄 - 30mm 高爆燃烧曳光弹 + 30 mm 高爆燃烧曳光 30mm 高爆燃燒曳光彈 + 30mm HEI-T AIM-9 Sidewinder @@ -457,9 +499,10 @@ AIM-9 Sidewinder AIM-9 Sidewinder AIM-9 サイドワインダー - AIM-9 Sidewinder + AIM-9 사이드와인더 AIM-9 响尾蛇 AIM-9 響尾蛇 + AIM-9 Sidewinder Wympel R-73 @@ -472,9 +515,10 @@ Wympel R-73 Wympel R-73 ヴィンペル R-73 - Vympel R-73 + 빔펠 R-73 Wympel R-73 Wympel R-73 + Wympel R-73 AGM-65 Maverick @@ -487,9 +531,10 @@ AGM-65 Maverick AGM-65 Maverick AGM-65 マーベリック - AGM-65 Maverick + AGM-65 매버릭 AGM-65 小牛 AGM-65 小牛 + AGM-65 Maverick Kh-25MTP @@ -505,6 +550,7 @@ Kh-25MTP Kh-25MTP Kh-25MTP + Kh-25MTP Hydra 70 HE @@ -516,10 +562,11 @@ Hydra 70 HE Hydra 70 HE Hydra 70 HE - ハイドラ 70 りゅう弾 - Hydra 70 고폭탄 + ハイドラ 70 HE + 히드라 70 고폭탄 九头蛇 70 高爆弹 九頭蛇 70 高爆彈 + Hydra 70 HE S-8 HE @@ -531,10 +578,11 @@ S-8 HE S-8 HE S-8 HE - S-8 りゅう弾 + S-8 HE S-8 고폭탄 S-8 高爆弹 S-8 高爆彈 + S-8 HE Hydra 70 AP @@ -545,11 +593,12 @@ Hydra 70 AP Hydra 70 AP Hydra 70 AP - Hydra 70 徹甲弾 + Hydra 70 AP ハイドラ 70 AP - Hydra 70 철갑탄 + 히드라 70 철갑탄 九头蛇 70 反人员弹 九頭蛇 70 反人員彈 + Hydra 70 AP S-8 AP @@ -561,10 +610,11 @@ S-8 AP S-8 AP S-8 AP - S-8 徹甲弾 + S-8 AP S-8 철갑탄 S-8 反人员弹 S-8 反人員彈 + S-8 AP GBU-12 @@ -580,6 +630,7 @@ GBU-12 GBU-12 GBU-12 + GBU-12 FAB-250M-54 @@ -595,22 +646,67 @@ FAB-250M-54 FAB-250M-54 FAB-250M-54 + FAB-250M-54 Rearm Cargo Munitionsvorrat - 再武装用カーゴ + 再武装用資源積載量 Ładunek Dozbrajający - Rifornimento Munizioni + Munizioni Caricate Боеприпасы для перевооружения + Carga de Rearme + 整裝用貨物 + 重整军备货物 + Stock de munitions + Sklad munice + Cargar munición + 화물 재무장 The cargo for rearming (-1 disable) Der Munitionsvorrat, zum Aufmunitionieren von Fahrzeugen (-1 deaktiviert) - カーゴからの再武装 (-1 で無効化) + 再武装に使用する資源の積載量 (-1 で補給無効) Ładunek do dozbrajania (-1 wyłączy) - Il rifornimento delle munizioni (-1 per disabilitarlo) + Il carico di munizioni per poter riarmare (-1 per disabilitarlo) Объем боеприпасов для перевооружения (-1 для отмены) + A Carga para Rearmamento (-1 para desativar) + 貨物可以提高多少次整裝(-1為停用) + 重新武装的货物(-1禁用) + Le quantité de munitions (en points), qui est disponible pour du réarmement (-1 pour désactiver). + Objekt pro přezbrojování (-1 pro vypnutí) + Cantidad de munición restante para rearmado (-1 para deshabilitar) + 화물을 재무장합니다 (-1 설정시 비활성화) + + + Rearm distance + Distance de réarmement + Aufrüstbereich + Distância para Rearmar + 再武装距離 + 整裝距離 + 整装距离 + Distanza di riarmo + Přezbrojovací vzdálenost + Odległość przezbrojenia + Дистанция перевооружения + Distancia de rearmado + 재무장 거리 + + + The maximum distance a vehicle can be rearmed at + Distance maximale à laquelle un véhicule peut être réarmé. + Die maximale Distanz, über die ein Fahrzeug Aufmunitioniert werden kann + A distância máxima que um veículo pode ser rearmado/municiado. + 車両から再武装できる最大距離 + 與載具之最大可整裝距離 + 车辆可重新整装的最大距离 + La distanza massima da cui un veicolo può essere riarmato + Maximální vzdálenost na jakou může být vozidlo přezbrojeno + Maksymalna odległość na jakiej pojazd może zostać przezbrojony + Максимальная дистанция для перевооружения + Máxima distancia a la que un vehículo puede ser rearmado + 차량이 재무장 할 수 있는 최대 거리를 설정합니다. diff --git a/addons/recoil/CfgEventHandlers.hpp b/addons/recoil/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/recoil/CfgEventHandlers.hpp +++ b/addons/recoil/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/recoil/CfgRecoils.hpp b/addons/recoil/CfgRecoils.hpp index 4b473919d5..c6482937ae 100644 --- a/addons/recoil/CfgRecoils.hpp +++ b/addons/recoil/CfgRecoils.hpp @@ -14,242 +14,558 @@ class CfgRecoils { class Default { // doc: http://forums.bistudio.com/showthread.php?188999-Recoil-Overhaul-Feedback&s=dba8590ec07adb5ffa87f72d38dde6fc&p=2886744&viewfull=1#post2886744 // {horizontal axis position, vertical axis position, horizontal magnitude, vertical magnitude} - muzzleOuter[] = {0*MUZZLERIGHT_POS,0.4*MUZZLECLIMB_POS,0.5*MUZZLERIGHT_MAG,0.6*MUZZLECLIMB_MAG}; + muzzleOuter[] = { + QUOTE(0*MUZZLERIGHT_POS), + QUOTE(0.4*MUZZLECLIMB_POS), + QUOTE(0.5*MUZZLERIGHT_MAG), + QUOTE(0.6*MUZZLECLIMB_MAG) + }; // restricted area inside the outer ellipse where the recoil cannot end muzzleInner[] = {0,0.05,0.2,0.2}; // minimum and maximum interval for backward force - kickBack[] = {0.05*KICKBACK,0.1*KICKBACK}; - permanent = 0.1*MUZZLEPERM; - temporary = 0.01*MUZZLETEMP; + kickBack[] = { + QUOTE(0.05*KICKBACK), + QUOTE(0.1*KICKBACK) + }; + permanent = QUOTE(0.1*MUZZLEPERM); + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_default: Default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - muzzleInner[] = {0,0,0.1,0.1}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - permanent = 0.1*MUZZLEPERM; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + muzzleInner[] = {0, + 0, + 0.1, + 0.1 + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + permanent = QUOTE(0.1*MUZZLEPERM); + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_mk20: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,0.6*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.01*KICKBACK,0.03*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(0.6*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.01*KICKBACK), + QUOTE(0.03*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_mk20c: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,0.8*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(0.8*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_trg20: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_trg21: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,0.8*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.01*KICKBACK,0.03*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(0.8*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.01*KICKBACK), + QUOTE(0.03*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_mx: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.4*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.4*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_mxc: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,1.2*MUZZLECLIMB_POS,0.4*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(1.2*MUZZLECLIMB_POS), + QUOTE(0.4*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_sw: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,0.8*MUZZLECLIMB_POS,0.5*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(0.8*MUZZLECLIMB_POS), + QUOTE(0.5*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; }; class recoil_mxm: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,0.8*MUZZLECLIMB_POS,0.4*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(0.8*MUZZLECLIMB_POS), + QUOTE(0.4*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_ktb: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_ktbc: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,1.2*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(1.2*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_smg_01: recoil_default { - muzzleOuter[] = {0.1*MUZZLERIGHT_POS,0.8*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.01*KICKBACK,0.03*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.1*MUZZLERIGHT_POS), + QUOTE(0.8*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.01*KICKBACK), + QUOTE(0.03*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_smg_02: recoil_default { - muzzleOuter[] = {0.1*MUZZLERIGHT_POS,0.6*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.01*KICKBACK,0.02*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.1*MUZZLERIGHT_POS), + QUOTE(0.6*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.01*KICKBACK), + QUOTE(0.02*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_pdw: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.02*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.02*MUZZLETEMP); }; class recoil_sdar: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.3*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.3*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_pistol_p07: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - temporary = 0.03*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + temporary = QUOTE(0.03*MUZZLETEMP); }; class recoil_pistol_rook40: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - temporary = 0.02*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + temporary = QUOTE(0.02*MUZZLETEMP); }; class recoil_pistol_acpc2: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.04*KICKBACK,0.08*KICKBACK}; - temporary = 0.04*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.04*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.04*MUZZLETEMP); }; class recoil_pistol_4five: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.04*KICKBACK,0.08*KICKBACK}; - temporary = 0.06*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.04*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.06*MUZZLETEMP); }; class recoil_pistol_zubr: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.04*KICKBACK,0.08*KICKBACK}; - temporary = 0.08*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.04*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.08*MUZZLETEMP); }; class recoil_pistol_signal: recoil_default { - muzzleOuter[] = {0.2*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.2*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.02*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.2*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.2*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.02*MUZZLETEMP); }; class recoil_rpg: recoil_default { - muzzleOuter[] = {2*MUZZLERIGHT_POS,3*MUZZLECLIMB_POS,1*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.08*KICKBACK,0.1*KICKBACK}; - temporary = 0.1*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(2*MUZZLERIGHT_POS), + QUOTE(3*MUZZLECLIMB_POS), + QUOTE(1*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.08*KICKBACK), + QUOTE(0.1*KICKBACK) + }; + temporary = QUOTE(0.1*MUZZLETEMP); }; class recoil_nlaw: recoil_default { - muzzleOuter[] = {2*MUZZLERIGHT_POS,3*MUZZLECLIMB_POS,1*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.06*KICKBACK,0.08*KICKBACK}; - temporary = 0.08*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(2*MUZZLERIGHT_POS), + QUOTE(3*MUZZLECLIMB_POS), + QUOTE(1*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.06*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.08*MUZZLETEMP); }; class recoil_titan_long: recoil_default { - muzzleOuter[] = {2*MUZZLERIGHT_POS,3*MUZZLECLIMB_POS,1*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.1*KICKBACK,0.12*KICKBACK}; - temporary = 0.15*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(2*MUZZLERIGHT_POS), + QUOTE(3*MUZZLECLIMB_POS), + QUOTE(1*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.1*KICKBACK), + QUOTE(0.12*KICKBACK) + }; + temporary = QUOTE(0.15*MUZZLETEMP); }; class recoil_titan_short: recoil_default { - muzzleOuter[] = {2*MUZZLERIGHT_POS,3*MUZZLECLIMB_POS,1*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.1*KICKBACK,0.12*KICKBACK}; - temporary = 0.12*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(2*MUZZLERIGHT_POS), + QUOTE(3*MUZZLECLIMB_POS), + QUOTE(1*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.1*KICKBACK), + QUOTE(0.12*KICKBACK) + }; + temporary = QUOTE(0.12*MUZZLETEMP); }; class recoil_mk200: recoil_default { - muzzleOuter[] = {0.4*MUZZLERIGHT_POS,0.6*MUZZLECLIMB_POS,0.6*MUZZLERIGHT_MAG,0.2*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.4*MUZZLERIGHT_POS), + QUOTE(0.6*MUZZLECLIMB_POS), + QUOTE(0.6*MUZZLERIGHT_MAG), + QUOTE(0.2*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; }; class recoil_zafir: recoil_default { - muzzleOuter[] = {0.5*MUZZLERIGHT_POS,1*MUZZLECLIMB_POS,0.7*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.08*KICKBACK}; - temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.5*MUZZLERIGHT_POS), + QUOTE(1*MUZZLECLIMB_POS), + QUOTE(0.7*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; }; class recoil_m320: recoil_default { - muzzleOuter[] = {1*MUZZLERIGHT_POS,3*MUZZLECLIMB_POS,0.5*MUZZLERIGHT_MAG,0.6*MUZZLECLIMB_MAG}; - kickBack[] = {0.08*KICKBACK,0.1*KICKBACK}; - temporary = 0.02*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(1*MUZZLERIGHT_POS), + QUOTE(3*MUZZLECLIMB_POS), + QUOTE(0.5*MUZZLERIGHT_MAG), + QUOTE(0.6*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.08*KICKBACK), + QUOTE(0.1*KICKBACK) + }; + temporary = QUOTE(0.02*MUZZLETEMP); }; class recoil_gm6: recoil_default { - muzzleOuter[] = {1.4*MUZZLERIGHT_POS,3.5*MUZZLECLIMB_POS,0.7*MUZZLERIGHT_MAG,0.8*MUZZLECLIMB_MAG}; - kickBack[] = {0.1*KICKBACK,0.12*KICKBACK}; - temporary = 0.025*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(1.4*MUZZLERIGHT_POS), + QUOTE(3.5*MUZZLECLIMB_POS), + QUOTE(0.7*MUZZLERIGHT_MAG), + QUOTE(0.8*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.1*KICKBACK), + QUOTE(0.12*KICKBACK) + }; + temporary = QUOTE(0.025*MUZZLETEMP); }; class recoil_ebr: recoil_default { - muzzleOuter[] = {0.4*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.6*MUZZLERIGHT_MAG,0.4*MUZZLECLIMB_MAG}; - kickBack[] = {0.04*KICKBACK,0.07*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.4*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.6*MUZZLERIGHT_MAG), + QUOTE(0.4*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.04*KICKBACK), + QUOTE(0.07*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_dmr_01: recoil_default { - muzzleOuter[] = {0.5*MUZZLERIGHT_POS,2*MUZZLECLIMB_POS,0.5*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.08*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.5*MUZZLERIGHT_POS), + QUOTE(2*MUZZLECLIMB_POS), + QUOTE(0.5*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_dmr_02: recoil_default { - muzzleOuter[] = {0.5*MUZZLERIGHT_POS,2.5*MUZZLECLIMB_POS,0.6*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.06*KICKBACK,0.08*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.5*MUZZLERIGHT_POS), + QUOTE(2.5*MUZZLECLIMB_POS), + QUOTE(0.6*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.06*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_dmr_03: recoil_default { - muzzleOuter[] = {0.3*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.5*MUZZLERIGHT_MAG,0.4*MUZZLECLIMB_MAG}; - kickBack[] = {0.03*KICKBACK,0.06*KICKBACK}; - temporary = 0.005*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.3*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.5*MUZZLERIGHT_MAG), + QUOTE(0.4*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.03*KICKBACK), + QUOTE(0.06*KICKBACK) + }; + temporary = QUOTE(0.005*MUZZLETEMP); }; class recoil_dmr_04: recoil_default { - muzzleOuter[] = {0.4*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.5*MUZZLERIGHT_MAG,0.4*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.04*KICKBACK}; - temporary = 0.015*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.4*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.5*MUZZLERIGHT_MAG), + QUOTE(0.4*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.04*KICKBACK) + }; + temporary = QUOTE(0.015*MUZZLETEMP); }; class recoil_dmr_05: recoil_default { - muzzleOuter[] = {0.5*MUZZLERIGHT_POS,2.5*MUZZLECLIMB_POS,0.8*MUZZLERIGHT_MAG,0.6*MUZZLECLIMB_MAG}; - kickBack[] = {0.08*KICKBACK,0.1*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.5*MUZZLERIGHT_POS), + QUOTE(2.5*MUZZLECLIMB_POS), + QUOTE(0.8*MUZZLERIGHT_MAG), + QUOTE(0.6*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.08*KICKBACK), + QUOTE(0.1*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_dmr_06: recoil_default { - muzzleOuter[] = {0.5*MUZZLERIGHT_POS,2*MUZZLECLIMB_POS,0.7*MUZZLERIGHT_MAG,0.5*MUZZLECLIMB_MAG}; - kickBack[] = {0.05*KICKBACK,0.1*KICKBACK}; - temporary = 0.01*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.5*MUZZLERIGHT_POS), + QUOTE(2*MUZZLECLIMB_POS), + QUOTE(0.7*MUZZLERIGHT_MAG), + QUOTE(0.5*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.05*KICKBACK), + QUOTE(0.1*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); }; class recoil_mmg_01: recoil_default { - muzzleOuter[] = {0.6*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.8*MUZZLERIGHT_MAG,0.3*MUZZLECLIMB_MAG}; - kickBack[] = {0.02*KICKBACK,0.08*KICKBACK}; - temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.6*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.8*MUZZLERIGHT_MAG), + QUOTE(0.3*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.02*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; }; class recoil_mmg_02: recoil_default { - muzzleOuter[] = {0.5*MUZZLERIGHT_POS,1.5*MUZZLECLIMB_POS,0.6*MUZZLERIGHT_MAG,0.4*MUZZLECLIMB_MAG}; - kickBack[] = {0.04*KICKBACK,0.08*KICKBACK}; - temporary = 0.01*MUZZLETEMP; //0.005*MUZZLETEMP; + muzzleOuter[] = { + QUOTE(0.5*MUZZLERIGHT_POS), + QUOTE(1.5*MUZZLECLIMB_POS), + QUOTE(0.6*MUZZLERIGHT_MAG), + QUOTE(0.4*MUZZLECLIMB_MAG) + }; + kickBack[] = { + QUOTE(0.04*KICKBACK), + QUOTE(0.08*KICKBACK) + }; + temporary = QUOTE(0.01*MUZZLETEMP); //0.005*MUZZLETEMP; }; }; diff --git a/addons/recoil/README.md b/addons/recoil/README.md index 0c81cde34a..e6193e3f85 100644 --- a/addons/recoil/README.md +++ b/addons/recoil/README.md @@ -2,10 +2,3 @@ ace_recoil =========== Tweaks weapon recoils and adds camera shake. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/recoil/XEH_postInit.sqf b/addons/recoil/XEH_postInit.sqf index 29e5464612..639b22d6f9 100644 --- a/addons/recoil/XEH_postInit.sqf +++ b/addons/recoil/XEH_postInit.sqf @@ -1,4 +1,4 @@ #include "script_component.hpp" // Register fire event handler -["ace_firedPlayer", DFUNC(camShake)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(camShake)] call CBA_fnc_addEventHandler; diff --git a/addons/recoil/functions/fnc_camshake.sqf b/addons/recoil/functions/fnc_camshake.sqf index f5fa820b65..d68da81db7 100644 --- a/addons/recoil/functions/fnc_camshake.sqf +++ b/addons/recoil/functions/fnc_camshake.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Orginal by Ryan Schultz, edited by KoffeinFlummi, commy2 * Adds camera shake when firing. Called from the unified fired EH only for the local player. @@ -11,20 +11,20 @@ * None * * Example: - * [player, (currentWeapon player), (currentMuzzle player)] call ace_recoil_fnc_camShake; + * [player, (currentWeapon player), (currentMuzzle player)] call ace_recoil_fnc_camshake; * * Public: No */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); #define BASE_POWER 0.40 #define BASE_TIME 0.19 #define BASE_FREQ 13 #define RECOIL_COEF 40 -if (toLower _weapon in ["throw", "put"]) exitWith {}; +if (toLowerANSI _weapon in ["throw", "put"]) exitWith {}; private _powerMod = ([0, -0.1, -0.1, 0, -0.2] select (["STAND", "CROUCH", "PRONE", "UNDEFINED", ""] find stance _unit)) + ([0, -1, 0, -1] select (["INTERNAL", "EXTERNAL", "GUNNER", "GROUP"] find cameraView)); diff --git a/addons/recoil/functions/script_component.hpp b/addons/recoil/functions/script_component.hpp deleted file mode 100644 index 24cb1ba776..0000000000 --- a/addons/recoil/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\recoil\script_component.hpp" \ No newline at end of file diff --git a/addons/refuel/ACE_Refuel_Positions.hpp b/addons/refuel/ACE_Refuel_Positions.hpp new file mode 100644 index 0000000000..78af5b6d48 --- /dev/null +++ b/addons/refuel/ACE_Refuel_Positions.hpp @@ -0,0 +1,96 @@ +class GVAR(positions) { + Altis[] = { /* Altis */ {"Land_fs_feed_F", {{3757,13478,0},{4001,12592,0},{5023,14430,0},{5769,20086,0},{6199,15081,0},{6798,15561,0},{8482,18261,0},{9026,15729,0},{9206,12112,0},{11832,14156,0},{12025,15830,0},{14173,16542,0},{14221,18303,0},{15297,17566,0},{15781,17453,0},{16751,12513,0},{16875,15469,0},{17417,13937,0},{19961,11454,0},{20785,16666,0},{21231,7117,0},{23379,19799,0},{25701,21373,0}}}}; + Stratis[] = { /* Stratis */ {"Land_FuelStation_Feed_F", {{2708,5788,0}}}}; + VR[] = {}; + Malden[] = { /* Malden 2035 */ + {"Land_fs_feed_F", {{3227,6291,0},{5111,9062,0},{5504,3500,0},{6633,8807,0},{7047,7052,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7224,7772,0},{8047,4023,0}}}, + {"Land_FuelStation_Feed_F", {{10063,3988,0},{11600,4477,0}}} + }; + Tanoa[] = { /* Tanoa */ + {"Land_fs_feed_F", {{2132,3360,0},{2452,7435,0},{3030,11316,0},{5174,8806,0},{5380,4093,0},{5594,12508,0},{7978,7419,0},{8319,9709,0},{8494,12432,0},{8954,13678,0},{8970,10332,0},{10827,6490,0},{10941,9855,0},{11146,5152,0},{11631,2999,0},{14261,11513,0},{14365,8743,0}}}, + {"Land_FuelStation_01_pump_F", {{1865,12128,0},{5409,9905,0},{5682,10165,0},{5776,4222,0},{5793,10825,0},{6592,13080,0},{6887,7491,0},{7359,7998,0},{9954,13467,0},{11635,13047,0},{11694,2271,0},{12613,7583,0}}} + }; + Enoch[] = { /* Livonia */ + {"Land_FuelStation_03_pump_F", {{2008,7365,0},{6259,3949,0}}}, + {"Land_FuelStation_Feed_F", {{10208,2173,0}}} + }; + + Bootcamp_ACR[] = { /* CUP Bukovina */ {"Land_A_FuelStation_Feed", {{652,473,0},{2849,1612,0}}}}; + Woodland_ACR[] = { /* CUP Bystrica */ {"Land_A_FuelStation_Feed", {{447,1381,0},{1302,2185,0},{1855,6852,0},{4102,1195,0},{4755,4499,0}}}}; + chernarus[] = { /* CUP Chernarus (Autumn) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2692,5602,0},{2997,7471,0},{3648,8968,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6705,2996,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10446,8866,0},{10726,10786,0},{12988,10076,0},{13385,6603,0}}}}; + chernarus_summer[] = { /* CUP Chernarus (Summer) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5606,0},{2998,7473,0},{3652,8973,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0}}}}; + Chernarus_Winter[] = { /* CUP Chernarus (Winter) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5604,0},{2997,7471,0},{3657,8979,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9503,2019,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{12994,10075,0},{13385,6603,0}}}}; + cup_chernarus_A3[] = { /* CUP Chernarus 2020 */ + {"Land_fs_feed_F", {{2511,5279,0}}}, + {"Land_FuelStation_03_pump_F", {{313,9385,0},{1129,2400,0},{2021,2242,0},{2692,5602,0},{2991,7471,1},{3007,12654,0},{3648,8968,0},{4328,13081,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6699,3001,0},{7255,7662,0},{7494,12662,0},{9502,2005,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0},{13569,13329,0}}} + }; + Desert_E[] = { /* CUP Desert */ }; + porto[] = { /* CUP Porto */ }; + ProvingGrounds_PMC[] = { /* CUP Proving Grounds */ {"Land_FuelStation_Feed_PMC", {{698,1208,0}}}}; + intro[] = { /* CUP Rahmadi */ }; + sara[] = { /* CUP Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + sara_dbe1[] = { /* CUP United Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + saralite[] = { /* CUP Southern Sahrani */ + {"Land_Benzina_schnell", {{3593,6663,0},{4347,3080,0},{4553,2427,0},{5288,3663,0},{6052,6715,0},{6353,3354,0},{6876,7467,0},{7409,4073,0}}}, + {"Land_Fuelstation_army", {{4688,7059,0}}} + }; + Shapur_BAF[] = { /* CUP Shapur */ {"Land_Ind_FuelStation_Feed_EP1", {{1512,1298,0}}}}; + takistan[] = { /* CUP Takistan */ {"Land_Ind_FuelStation_Feed_EP1", {{2004,11720,0},{3081,9848,0},{3549,4197,0},{5538,9284,0},{5836,5771,0},{7497,1818,0},{8248,7800,0},{10422,6328,0},{10647,11021,0}}}}; + Mountains_ACR[] = { /* CUP Takistan Mountains */ {"Land_Ind_FuelStation_Feed_EP1", {{2962,4197,0},{5249,5771,0}}}}; + utes[] = { /* CUP Utes */ }; + zargabad[] = { /* CUP Zargabad */ {"Land_Ind_FuelStation_Feed_EP1", {{3736,2784,0},{3867,4208,0},{3871,5980,0},{5027,1906,0}}}}; + + pja310[] = { /* G.O.S Al Rayak */ {"Land_Ind_FuelStation_Feed_EP1", {{887,18588,0},{964,18356,0},{1196,18463,0},{1872,8754,0},{2051,8437,0},{2125,8238,0},{2240,8584,0},{2310,8566,0},{2366,3901,0},{2879,13142,0},{3880,10361,0},{4056,13261,0},{4122,13487,0},{4302,13628,0},{4475,13377,0},{4556,13742,0},{6461,3372,0},{7216,6059,0},{7228,6344,0},{7416,6099,0},{7472,6838,0},{7591,6081,0},{11650,3536,0},{14863,7292,0},{16466,18897,0},{16476,19116,0},{16642,18994,0},{16676,19199,0},{16858,10558,0},{16908,9959,0},{17120,3706,0},{17100,4375,0},{18056,4133,0},{18229,4066,0},{18235,4571,0},{18814,5010,0}}}}; + australia[] = { /* Aussie Australia v5.09 */ + {"Land_fs_feed_F", {{4614,16978,0},{5509,19273,0},{5487,19276,0},{5508,19330,0},{5540,19357,0},{5564,19377,0},{5623,19376,0},{5643,19352,0},{6355,17860,0},{12811,27772,0},{15837,33438,0},{16335,33436,0},{16367,33436,0},{17127,33902,0},{20754,12737,0},{20874,12793,0},{20901,12793,1},{22127,25635,0},{22127,25666,0},{22162,25712,0},{22194,25712,0},{22213,25630,0},{22315,19235,0},{22595,24757,0},{24909,13855,0},{25050,12786,0},{25071,12786,0},{26085,11260,1},{26212,11174,0},{26824,28005,0},{27719,17108,0},{27757,12033,0},{28473,35132,0},{30707,11879,0},{31091,5370,0},{31096,10918,0},{31096,10945,0},{31165,10914,0},{31165,10958,0},{31313,16763,0},{31515,9673,0},{31515,9652,0},{31758,4861,0},{32224,2736,0},{33919,13364,0},{33936,13350,0},{34789,26383,0},{35274,26021,2},{35786,12148,0},{35765,12170,0},{35835,12145,0},{35833,12188,0},{35812,12210,0},{36199,16479,0},{36399,13140,0},{36593,12065,0},{36574,13089,0},{36595,13089,0},{36597,13282,0},{38153,14544,0},{38520,18891,0},{38515,20173,0},{38535,20198,0},{38565,20198,0}}}, + {"Land_FuelStation_01_pump_F", {{5495,18693,0},{32067,29608,0},{32087,29611,0},{33215,4147,0},{37293,13172,0},{37293,13193,0}}}, + {"Land_FuelStation_Feed_F", {{19303,16449,0},{31064,20116,0}}} + }; + Farabad[] = { /* Farabad */ + {"Land_Benzina_schnell", {{592,7505,0},{804,1445,0},{3132,3129,0}}}, + {"Land_fs_feed_F", {{1920,4960,0},{5052,4703,1},{9456,9277,0}}}, + {"Land_FuelStation_01_pump_F", {{2378,6248,0},{7092,534,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{4788,5525,0}}} + }; + IslaPera[] = { /* Isla Pera */ + {"Land_fs_feed_F", {{1855,2866,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{3981,2065,0},{5306,8796,0},{9236,4287,0}}} + }; + VTF_Lybor[] = { /* Lybor */ + {"Land_FuelStation_03_pump_F", {{3879,3823,0}}}, + {"Land_FuelStation_Feed_F", {{1831,2694,0},{2175,3323,0},{3304,2981,0},{4271,3024,0}}} + }; + rof_mok[] = { /* Mull of Kintyre, Scotland */ + {"Land_A_FuelStation_Feed", {{12837,5124,1},{15271,17533,0},{19453,21896,0}}}, + {"Land_fs_feed_F", {{7492,17369,0}}}, + {"Land_Fuelstation", {{10284,18679,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{9762,16325,0}}} + }; + pulau[] = { /* Pulau */ + {"Land_fs_feed_F", {{2368,3128,0},{4891,7168,0},{7358,7368,0}}}, + {"Land_FuelStation_Feed_F", {{5994,5789,0}}} + }; + WL_Rosche[] = { /* Rosche, Germany (2.0) */ + {"Land_fs_feed_F", {{693,4803,0},{12059,6700,0},{13320,14822,0}}}, + {"Land_FuelStation_01_pump_F", {{447,6859,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{1437,5455,0}}} + }; + Kapaulio[] = { /* Saint Kapaulio */ + {"Land_fs_feed_F", {{931,7647,0},{958,6796,0},{2034,9426,0},{2563,9427,0},{3500,8110,0},{3602,6082,0},{4222,6308,0},{4561,693,0},{8077,5906,0},{8434,13145,0},{8525,17299,0},{9265,7155,0},{10527,18267,0},{12078,1846,0},{12833,6464,0},{13433,6327,0},{14084,6308,0},{14172,7786,0},{14831,4649,0},{16080,14743,0},{17356,2312,0},{18047,5254,0},{18318,5042,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{18039,18139,0}}}, + {"Land_FuelStation_Feed_F", {{756,12133,0},{1239,7346,0},{1726,17469,0},{3113,10070,0},{3828,8362,0},{5668,16967,0},{7435,14185,0},{7543,12107,0},{8366,6086,0},{9672,9586,0},{11749,12255,0},{12802,10022,0},{13989,3591,0},{15198,10900,0},{19063,1654,0},{19378,18517,0}}} + }; + pabst_yellowstone[] = { /* Yellowstone */ + {"Land_fs_feed_F", {{3075,7426,0},{7060,3626,0},{7950,4060,0},{7974,4072,0}}}, + {"Land_FuelStation_01_pump_F", {{4565,1953,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7072,3676,0}}}, + {"Land_FuelStation_Feed_F", {{4678,3971,0},{6391,5174,0}}} + }; +}; diff --git a/addons/refuel/Cfg3DEN.hpp b/addons/refuel/Cfg3DEN.hpp index 3dbc91c2cf..00d5453d95 100644 --- a/addons/refuel/Cfg3DEN.hpp +++ b/addons/refuel/Cfg3DEN.hpp @@ -1,8 +1,5 @@ -#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define GET_1ST_ARRAY(config) (if (isArray (config)) then {getArray (config) select 0} else {[ARR_3(0,0,0)]}) - -#define DEFAULT_FUELCARGO GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(fuelCargo),REFUEL_DISABLED_FUEL) -#define DEFAULT_HOOKS GET_1ST_ARRAY(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(hooks)) +#define DEFAULT_HOOKS GET_1ST_ARRAY(configOf _this >> QQGVAR(hooks)) class Cfg3DEN { class Object { @@ -14,8 +11,8 @@ class Cfg3DEN { tooltip = CSTRING(fuelCargo_edenDesc); property = QGVAR(fuelCargo); control = "EditShort"; - expression = QUOTE(if (_value != DEFAULT_FUELCARGO) then {[ARR_2(_this,_value)] call DFUNC(makeSource)}); - defaultValue = QUOTE(DEFAULT_FUELCARGO); + expression = QUOTE(if (_value != (_this call FUNC(getFuelCargo))) then {[ARR_2(_this,_value)] call FUNC(makeSource)}); + defaultValue = QUOTE(_this call FUNC(getFuelCargo)); validate = "number"; condition = "(1-objectBrain)*(1-objectAgent)"; typeName = "NUMBER"; @@ -25,7 +22,7 @@ class Cfg3DEN { tooltip = CSTRING(hooks_edenDesc); property = QGVAR(hooks); control = "EditXYZ"; - expression = QUOTE(if !(_value isEqualTo DEFAULT_HOOKS) then {_this setVariable [ARR_3('%s',[_value],true)]}); + expression = QUOTE(if (_value isNotEqualTo DEFAULT_HOOKS) then {_this setVariable [ARR_3('%s',[_value],true)]}); defaultValue = QUOTE(DEFAULT_HOOKS); condition = "(1-objectBrain)*(1-objectAgent)"; }; diff --git a/addons/refuel/CfgEventHandlers.hpp b/addons/refuel/CfgEventHandlers.hpp index c8d6e21596..dec955b5a8 100644 --- a/addons/refuel/CfgEventHandlers.hpp +++ b/addons/refuel/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index efcd1aa3a2..44575a141d 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,47 +1,18 @@ -#define MACRO_NOZZLE_ACTIONS \ - class ACE_Actions { \ - class ACE_MainActions { \ - displayName = CSTRING(Refuel); \ - distance = REFUEL_ACTION_DISTANCE; \ - position = "[0,-0.025,0.125]"; \ - condition = "true"; \ - statement = ""; \ - exceptions[] = {INTERACT_EXCEPTIONS}; \ - showDisabled = 0; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - class GVAR(PickUpNozzle) { \ - displayName = CSTRING(TakeNozzle); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \ - statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeNozzle)); \ - exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - class GVAR(TurnOn) { \ - displayName = CSTRING(TurnOn); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOn)); \ - statement = QUOTE([ARR_2(_player,_target)] call DFUNC(turnOn)); \ - exceptions[] = {INTERACT_EXCEPTIONS}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - class GVAR(TurnOff) { \ - displayName = CSTRING(TurnOff); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOff)); \ - statement = QUOTE([ARR_2(_player,_target)] call DFUNC(turnOff)); \ - exceptions[] = {INTERACT_EXCEPTIONS}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - class GVAR(Disconnect) { \ - displayName = CSTRING(Disconnect); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDisconnect)); \ - statement = QUOTE([ARR_2(_player,_target)] call DFUNC(disconnect)); \ - exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - }; \ - }; +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} class CBA_Extended_EventHandlers; +class CfgNonAIVehicles { + class GVAR(fuelHoseSegment) { + scope = 2; + displayName = "Fuel Hose"; + simulation = "ropesegment"; + autocenter = 0; + animated = 0; + model = QPATHTOF(data\hose.p3d); + }; +}; + class CfgVehicles { class ACE_Module; class ACE_moduleRefuelSettings: ACE_Module { @@ -66,20 +37,79 @@ class CfgVehicles { typeName = "NUMBER"; defaultValue = 12; }; + class progressDuration { + displayName = CSTRING(RefuelSettings_progressDuration_DisplayName); + typeName = "NUMBER"; + defaultValue = 2; + }; }; }; class ThingX; class GVAR(fuelNozzle): ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + XEH_INHERITED; - MACRO_NOZZLE_ACTIONS displayName = QGVAR(fuelNozzle); scope = 1; scopeCurator = 1; model = QPATHTOF(data\nozzle.p3d); + destrType = "DestructNo"; + + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(Refuel); + distance = REFUEL_ACTION_DISTANCE; + position = "[0,-0.025,0.125]"; + condition = "true"; + statement = ""; + exceptions[] = {INTERACT_EXCEPTIONS}; + showDisabled = 0; + icon = QPATHTOF(ui\icon_refuel_interact.paa); + class GVAR(PickUpNozzle) { + displayName = CSTRING(TakeNozzle); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeNozzle)); + exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; + icon = QPATHTOF(ui\icon_refuel_interact.paa); + }; + class GVAR(TurnOn) { + displayName = CSTRING(TurnOn); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOn)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(turnOn)); + exceptions[] = {INTERACT_EXCEPTIONS}; + icon = QPATHTOF(ui\icon_refuel_interact.paa); + }; + class GVAR(TurnOn_Container) { + displayName = CSTRING(TurnOn_Container); + condition = QUOTE([ARR_3(_player,_target,true)] call FUNC(canTurnOn)); + statement = QUOTE([ARR_3(_player,_target,true)] call FUNC(turnOn)); + exceptions[] = {INTERACT_EXCEPTIONS}; + icon = QPATHTOF(ui\icon_refuel_interact.paa); + }; + class GVAR(TurnOff) { + displayName = CSTRING(TurnOff); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOff)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(turnOff)); + exceptions[] = {INTERACT_EXCEPTIONS}; + icon = QPATHTOF(ui\icon_refuel_interact.paa); + }; + class GVAR(Disconnect) { + displayName = CSTRING(Disconnect); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDisconnect)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(disconnect)); + exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; + icon = QPATHTOF(ui\icon_refuel_interact.paa); + }; + }; + }; + }; + + class Rope; + class GVAR(fuelHose): Rope { + hiddenSelections[] = {"rope"}; + hiddenSelectionsTextures[] = {"#(argb,8,8,3)color(0.009,0.009,0.009,1.0,co)"}; + segmentType = QGVAR(fuelHoseSegment); + model = QPATHTOF(data\hose.p3d); }; class All; @@ -242,15 +272,9 @@ class CfgVehicles { }; class Van_01_fuel_base_F: Van_01_base_F { - GVAR(hooks)[] = {{0.38,-3.17,-.7},{-0.41,-3.17,-.7}}; + GVAR(hooks)[] = {{0.38,-3.17,-0.7},{-0.41,-3.17,-0.7}}; GVAR(fuelCargo) = 2000; }; - class C_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; - class I_G_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; class Tank_F: Tank { GVAR(fuelCapacity) = 1200; @@ -265,8 +289,7 @@ class CfgVehicles { class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - transportFuel = 0; //3k - GVAR(hooks)[] = {{-1.08,-4.81,-.8}}; + GVAR(hooks)[] = {{-1.08,-4.81,-0.8}}; GVAR(fuelCargo) = 1000; }; @@ -358,6 +381,11 @@ class CfgVehicles { GVAR(canReceive) = 0; }; + class UGV_02_Base_F: Tank_F { + // ED-1D and ED-1E are electrical + GVAR(canReceive) = 0; + }; + class UAV: Plane {}; class UAV_02_base_F: UAV { @@ -372,7 +400,6 @@ class CfgVehicles { // Vanilla fuel vehicles class Truck_02_fuel_base_F: Truck_02_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; GVAR(fuelCargo) = 10000; }; @@ -381,14 +408,12 @@ class CfgVehicles { }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { - transportFuel = 0; //3k - GVAR(hooks)[] = {{.28,-4.99,-.3},{-.25,-4.99,-.3}}; + GVAR(hooks)[] = {{0.28,-4.99,-0.3},{-0.25,-4.99,-0.3}}; GVAR(fuelCargo) = 10000; }; class O_Truck_03_fuel_F: Truck_03_base_F { - transportFuel = 0; //3k - GVAR(hooks)[] = {{1.3,-1.59,-.62},{-1.16,-1.59,-.62}}; + GVAR(hooks)[] = {{1.3,-1.59,-0.62},{-1.16,-1.59,-0.62}}; GVAR(fuelCargo) = 10000; }; @@ -401,20 +426,17 @@ class CfgVehicles { class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { - transportFuel = 0; //3k - GVAR(hooks)[] = {{-1.49,1.41,-.3}}; + GVAR(hooks)[] = {{-1.49,1.41,-0.3}}; GVAR(fuelCargo) = 10000; }; class Slingload_01_Base_F: Slingload_base_F {}; class B_Slingload_01_Fuel_F: Slingload_01_Base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; GVAR(fuelCargo) = 10000; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.52,1.14,-1.18}}; GVAR(fuelCargo) = 10000; }; @@ -431,11 +453,7 @@ class CfgVehicles { }; }; class Land_StorageBladder_01_F: StorageBladder_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - transportFuel = 0; //60k + XEH_INHERITED; GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; @@ -451,31 +469,35 @@ class CfgVehicles { }; }; class Land_FlexibleTank_01_F: FlexibleTank_base_F { - transportFuel = 0; //300 GVAR(hooks)[] = {{0, 0, 0.5}}; GVAR(fuelCargo) = 300; }; // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0,0,-0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_fs_feed_F: House_Small_F { - transportFuel = 0; //50k - GVAR(hooks)[] = {{-0.4,0.022,-.23}}; + XEH_INHERITED; + GVAR(hooks)[] = {{-0.4,0.022,-0.23}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_malevil_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; + GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; + GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class Land_FuelStation_03_pump_F: House_F { // Enoch + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; diff --git a/addons/refuel/README.md b/addons/refuel/README.md index 6e3d226693..96d3a35914 100644 --- a/addons/refuel/README.md +++ b/addons/refuel/README.md @@ -3,9 +3,3 @@ ace_refuel The Refuel module introduces ability to refuel vehicles on different realistic levels. -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [GitHawk] (https://github.com/GitHawk) -- [Jonpas] (https://github.com/jonpas) diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index e4c5298036..cb9279500b 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -1,4 +1,5 @@ PREP(canCheckFuel); +PREP(canConnectNozzle); PREP(canDisconnect); PREP(canReturnNozzle); PREP(canTakeNozzle); @@ -8,7 +9,9 @@ PREP(checkFuel); PREP(connectNozzleAction); PREP(disconnect); PREP(dropNozzle); +PREP(getCapacity); PREP(getFuel); +PREP(getFuelCargo); PREP(handleDisconnect); PREP(handleRespawn); PREP(initSource); diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf index e6c0ad5b93..d007266e5f 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,95 +1,150 @@ #include "script_component.hpp" -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; -}; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; -[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + ["All", "InitPost", { + params ["_vehicle"]; + if (getFuelCargo _vehicle <= 0) exitWith {}; + TRACE_1("initPost",_vehicle); -if (!hasInterface) exitWith {}; + if (local _vehicle) then { + _vehicle setFuelCargo 0; + LOG("initPost setFuelCargo"); + }; + }, true, ["Man"], true] call CBA_fnc_addClassEventHandler; -["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + if (isServer) then { + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + }; -["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + private _cfgPositions = configFile >> QGVAR(positions) >> worldName; + if (isArray _cfgPositions) then { + { + _x params ["_class", "_positions"]; + { + private _objects = _x nearObjects [_class, 30]; + if (_objects isEqualTo []) then { + WARNING_3("no pumps %1 found near %2 %3",_class,worldName,_x); + } else { + { + // terrain fuel pumps don't trigger init and must setFuelCargo on each client + _x setFuelCargo 0; + } forEach _objects; + }; + } forEach _positions; + } forEach getArray _cfgPositions; -GVAR(mainAction) = [ - QGVAR(Refuel), - localize LSTRING(Refuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {}, - { - alive _target - && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} - && {REFUEL_DISABLED_FUEL != [_target] call FUNC(getFuel)} - }, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE -] call EFUNC(interact_menu,createAction); + // placed in editor static objects don't trigger init but synchronize fuel cargo + // placed in editor vehicles both trigger init and synchronize fuel cargo + { + if (getFuelCargo _x > 0 && {local _x}) then { + TRACE_1("allMissionObjects",_x); + _x setFuelCargo 0; + }; + } forEach allMissionObjects ""; + } else { + // here are both terrain and editor static objects + WARNING_2("World %1: %2 is not configured; can load slower",worldName,QGVAR(positions)); + private _halfWorldSize = worldSize / 2; + private _worldCenter = [_halfWorldSize, _halfWorldSize]; + _halfWorldSize = _halfWorldSize * sqrt 2; + private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); -GVAR(actions) = [ - [QGVAR(TakeNozzle), - localize LSTRING(TakeNozzle), + { + { + _x setFuelCargo 0; + } forEach (_worldCenter nearObjects [_x, _halfWorldSize]); + } forEach _baseStaticClasses; + }; + + [QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + + if (!hasInterface) exitWith {}; + + ["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + + ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + + GVAR(mainAction) = [ + QGVAR(Refuel), + localize LSTRING(Refuel), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(TakeNozzle)}, - {[_player, _target] call FUNC(canTakeNozzle)}, + {}, + { + alive _target + && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} + && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} + }, {}, [], [0,0,0], REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuelCounter), - localize LSTRING(CheckFuelCounter), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(readFuelCounter)}, - {true}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuel), - localize LSTRING(CheckFuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(checkFuel)}, - {[_player, _target] call FUNC(canCheckFuel)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(Return), - localize LSTRING(Return), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(returnNozzle)}, - {[_player, _target] call FUNC(canReturnNozzle)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction) -]; + ] call EFUNC(interact_menu,createAction); -// init menu for config refuel vehicles -private _cacheRefuelClasses = call (uiNamespace getVariable [QGVAR(cacheRefuelClasses), {[[],[]]}]); -_cacheRefuelClasses params [["_staticClasses", [], [[]]], ["_dynamicClasses", [], [[]]]]; + GVAR(actions) = [ + [QGVAR(TakeNozzle), + localize LSTRING(TakeNozzle), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(canTakeNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuelCounter), + localize LSTRING(CheckFuelCounter), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(readFuelCounter)}, + {true}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuel), + localize LSTRING(CheckFuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(checkFuel)}, + {[_player, _target] call FUNC(canCheckFuel)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(Return), + localize LSTRING(Return), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(returnNozzle)}, + {[_player, _target] call FUNC(canReturnNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction) + ]; -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + private _staticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesStatic)); + private _baseDynamicClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseDynamic)); + + // init menu for config refuel vehicles { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to static",_x); -} forEach _staticClasses; + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to static",_x); + } forEach _staticClasses; -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to dynamic",_x); -} forEach _dynamicClasses; + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to dynamic",_x); + } forEach _baseDynamicClasses; -#ifdef DRAW_HOOKS_POS -addMissionEventHandler ["Draw3D", { - private _source = cursorObject; - private _cfgPos = getArray (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(hooks)); - private _dynPos = _source getVariable [QGVAR(hooks), []]; - { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; - } forEach ([_dynPos, _cfgPos] select (_dynPos isEqualTo [])); -}]; -#endif + #ifdef DRAW_HOOKS_POS + addMissionEventHandler ["Draw3D", { + private _source = cursorObject; + private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); + private _dynPos = _source getVariable [QGVAR(hooks), _cfgPos]; + { + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; + } forEach _dynPos; + }]; + #endif +}] call CBA_fnc_addEventHandler; diff --git a/addons/refuel/XEH_preInit.sqf b/addons/refuel/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/refuel/XEH_preInit.sqf +++ b/addons/refuel/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/refuel/XEH_preStart.sqf b/addons/refuel/XEH_preStart.sqf index fa5fe4acda..308ca30a9b 100644 --- a/addons/refuel/XEH_preStart.sqf +++ b/addons/refuel/XEH_preStart.sqf @@ -4,27 +4,44 @@ // cache refuel vehicles, see XEH_postInit.sqf private _staticClasses = []; -private _dynamicClasses = []; +private _baseStaticClasses = []; +private _baseDynamicClasses = []; +private _cacheRefuelCargo = createHashMap; { - private _fuelCargo = getNumber (_x >> QGVAR(fuelCargo)); + private _transportFuel = getNumber (_x >> "transportFuel"); + private _fuelCargo = [_x >> QGVAR(fuelCargo), "NUMBER", _transportFuel] call CBA_fnc_getConfigEntry; if (_fuelCargo > 0 || {_fuelCargo == REFUEL_INFINITE_FUEL}) then { private _sourceClass = configName _x; + private _noXEH = !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init"); + private _isPublic = getNumber (_x >> "scope") == 2; // check if we can use actions with inheritance if ( - !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init") // addActionToClass relies on XEH init - || {configName _x isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class + _noXEH // addActionToClass relies on XEH init + || {_sourceClass isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class ) then { - if (2 == getNumber (_x >> "scope")) then { - _staticClasses pushBackUnique _sourceClass; + if (_isPublic) then { + if (_noXEH) then { + WARNING_3("Class %1: %2 [%3] needs XEH",_sourceClass,configName inheritsFrom _x,configSourceMod _x); + }; + _staticClasses pushBack _sourceClass; + if (_baseStaticClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseStaticClasses pushBack _sourceClass; + }; }; } else { - if (-1 == _dynamicClasses findIf {_sourceClass isKindOf _x}) then { - _dynamicClasses pushBackUnique _sourceClass; + if (_baseDynamicClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseDynamicClasses pushBack _sourceClass; }; }; + if (_isPublic) then { + _cacheRefuelCargo set [_sourceClass, _fuelCargo]; + }; }; -} forEach ('true' configClasses (configFile >> "CfgVehicles")); +} forEach ("true" configClasses (configFile >> "CfgVehicles")); -TRACE_2("compiled",count _staticClasses,count _dynamicClasses); -uiNamespace setVariable [QGVAR(cacheRefuelClasses), compileFinal str [_staticClasses, _dynamicClasses]]; +TRACE_3("found",count _staticClasses,count _baseStaticClasses,count _baseDynamicClasses); +uiNamespace setVariable [QGVAR(cacheRefuelClassesStatic), compileFinal (_staticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseStatic), compileFinal (_baseStaticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseDynamic), compileFinal (_baseDynamicClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelCargo), compileFinal _cacheRefuelCargo]; diff --git a/addons/refuel/config.cpp b/addons/refuel/config.cpp index 39765e323c..79b97994f1 100644 --- a/addons/refuel/config.cpp +++ b/addons/refuel/config.cpp @@ -3,17 +3,18 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; - weapons[] = {QGVAR(fuelNozzle)}; + units[] = {QGVAR(fuelNozzle)}; + weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); - authors[] = {"GitHawk"}; + authors[] = {"GitHawk", "QuantX"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; +#include "ACE_Refuel_Positions.hpp" #include "ACE_Settings.hpp" #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/refuel/data/hose.cfg b/addons/refuel/data/hose.cfg new file mode 100644 index 0000000000..a49123a444 --- /dev/null +++ b/addons/refuel/data/hose.cfg @@ -0,0 +1,7 @@ +class CfgModels { + class hose { + sectionsInherit = ""; + sections[] = {"rope"}; + skeletonName = ""; + }; +}; \ No newline at end of file diff --git a/addons/refuel/data/hose.p3d b/addons/refuel/data/hose.p3d new file mode 100644 index 0000000000..cc233eacf6 Binary files /dev/null and b/addons/refuel/data/hose.p3d differ diff --git a/addons/refuel/defines.hpp b/addons/refuel/defines.hpp new file mode 100644 index 0000000000..761eb08641 --- /dev/null +++ b/addons/refuel/defines.hpp @@ -0,0 +1,4 @@ +#define REFUEL_INFINITE_FUEL -10 +#define REFUEL_DISABLED_FUEL -1 +#define REFUEL_ACTION_DISTANCE 7 +#define REFUEL_NOZZLE_ACTION_DISTANCE 2 diff --git a/addons/refuel/dev/exportTerrainRefuelPositions.sqf b/addons/refuel/dev/exportTerrainRefuelPositions.sqf new file mode 100644 index 0000000000..c7f9abfb2f --- /dev/null +++ b/addons/refuel/dev/exportTerrainRefuelPositions.sqf @@ -0,0 +1,95 @@ +// call compileScript ["z\ace\addons\refuel\dev\exportTerrainRefuelPositions.sqf"] +// can be run in Eden Editor console + +#include "\z\ace\addons\refuel\script_component.hpp" + +{ + if (!isArray (configFile >> QGVAR(positions) >> configName _x)) then { + WARNING_1("need configs on [%1]",configName _x); + }; +} forEach ("true" configClasses (configFile >> "CfgWorldList")); + + + +private _basePumps = []; +private _totalCount = 0; +private _posCount = 0; +private _message = ""; +private _halfWorldSize = worldSize / 2; +private _worldCenter = [_halfWorldSize, _halfWorldSize]; +_halfWorldSize = _halfWorldSize * sqrt 2; + +private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); +private _class = ""; +private _objects = []; +private _positions = []; +private _object = objNull; +private _pos = []; + +{ + _class = _x; + _objects = _worldCenter nearObjects [_class, _halfWorldSize]; + if (_objects isEqualTo []) then { + continue; + }; + ADD(_totalCount,count _objects); + _positions = []; + { + _object = _x; + _pos = ASLToAGL getPosASL _object; + if (-1 < _positions findIf {60 > _x distance _pos && {20 < _x distance _pos}}) then { + _message = "INCREASE DISTANCE " + str _pos; + }; + if (-1 == _positions findIf {20 > _x distance _pos}) then { + _positions pushBack (_pos apply {round _x}); + INC(_posCount); + }; + } forEach _objects; + _positions sort true; // sort positions by smallest first + _basePumps pushBack [_class, _positions]; +} forEach _baseStaticClasses; + +_basePumps sort true; // sort pump classes alphabetically + +// check final array as it's calculated in postInit +private _checkCount = 0; +{ + _x params ["_class", "_positions"]; + private _pumps = []; + { + _pumps append (_x nearObjects [_class, 30]); + } forEach _positions; + _pumps = _pumps arrayIntersect _pumps; + _checkCount = _checkCount + count _pumps; +} forEach _basePumps; +if (_checkCount != _totalCount) then { + _message = "WRONG COUNT " + str _checkCount; +}; + +// export text +private _nl = toString [10]; +private _multipleBasePumps = 1 < count _basePumps; +private _output = [format [" %1[] = { /* %2 */", worldName, getText (configfile >> "CfgWorlds" >> worldName >> "description")]]; +{ + if (_forEachIndex > 0) then {_output pushBack ","}; + _x params ["_class", "_positions"]; + if (_multipleBasePumps) then { + _output pushBack (_nl + " "); + } else { + _output pushBack " "; + }; + _output pushBack format ["{""%1"", {", _class]; + { + if (_forEachIndex > 0) then {_output pushBack ","}; + _output pushBack format ["{%1,%2,%3}", _x#0, _x#1, _x#2]; + } forEach _positions; + _output pushBack "}}"; +} forEach _basePumps; +if (_multipleBasePumps) then {_output pushBack (_nl + " ")}; +if (_basePumps isEqualTo []) then {_output pushBack " "}; +_output pushBack ("};" + _nl); + +_output = _output joinString ""; + +copyToClipboard _output; +[_totalCount, _posCount, _message, _output] diff --git a/addons/refuel/dev/test_debugConfigs.sqf b/addons/refuel/dev/test_debugConfigs.sqf index 834d3626bf..52ff8a962a 100644 --- a/addons/refuel/dev/test_debugConfigs.sqf +++ b/addons/refuel/dev/test_debugConfigs.sqf @@ -1,18 +1,18 @@ // ["vehicleTransportFuel"] call ace_common_fnc_runTests; // execVM "z\ace\addons\refuel\dev\test_debugConfigs.sqf"; -#include "\z\ace\addons\refuel\script_component.hpp" +#include "..\script_component.hpp" private _testPass = true; -diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; -private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +INFO("Showing CfgVehicles with transportFuel and without XEH"); +private _badCfgVehicles = ' + 2 == getNumber (_x >> "scope") + && {0 < getNumber (_x >> "transportFuel")} + && {!isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init")} +' configClasses (configFile >> "CfgVehicles"); { - if ((configName _x) isKindOf "Car") then { - diag_log text format ["Car [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - } else { - diag_log text format ["Non-car? [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - }; -} forEach _fuelTrucks; + diag_log text format ["Class %1: %2 [%3] needs XEH", configName _x, configName inheritsFrom _x, configSourceMod _x]; +} forEach _badCfgVehicles; _testPass diff --git a/addons/refuel/functions/fnc_canCheckFuel.sqf b/addons/refuel/functions/fnc_canCheckFuel.sqf index f7bb8a4aa8..97aadaf91b 100644 --- a/addons/refuel/functions/fnc_canCheckFuel.sqf +++ b/addons/refuel/functions/fnc_canCheckFuel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas, GitHawk * Checks if unit can check fuel. @@ -23,4 +23,4 @@ params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; {!local _unit} || {!alive _source} || {([_unit, _source] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE} || - {(_source call FUNC(getFuel) == REFUEL_INFINITE_FUEL)}) + {(_source call FUNC(getCapacity)) in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL]}) diff --git a/addons/refuel/functions/fnc_canConnectNozzle.sqf b/addons/refuel/functions/fnc_canConnectNozzle.sqf new file mode 100644 index 0000000000..b1a85a2868 --- /dev/null +++ b/addons/refuel/functions/fnc_canConnectNozzle.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: QuantX + * Checks if an object can have a nozzle connected to it. + * + * Arguments: + * 0: Object + * + * Return Value: + * Can nozzle be connected + * + * Example: + * [myVehicle] call ace_refuel_fnc_canConnectNozzle; + * [myJerryCan] call ace_refuel_fnc_canConnectNozzle; + * + * Public: No + */ + +params [["_object", objNull, [objNull]]]; + +// Make sure object doesn't already have a nozzle connected +if (isNull _object || {!isNull (_object getVariable [QGVAR(nozzle), objNull])} ) exitWith {false}; + +// Can't fuel a jerry can that is connected to another object +if (_object getVariable [QGVAR(jerryCan), false]) exitWith {!(_object getVariable [QGVAR(isConnected), false])}; + +// We need to check "canReceive" before we check if the tank can be filled +// This handles the edge case where a fuel truck has an infintite supply (i.e. the truck can be refueled, but the tank cannot) +(getNumber ((configOf _object) >> QGVAR(canReceive)) == 1) || + {!(([_object] call FUNC(getCapacity)) in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])} diff --git a/addons/refuel/functions/fnc_canDisconnect.sqf b/addons/refuel/functions/fnc_canDisconnect.sqf index 1288d9f103..813706431a 100644 --- a/addons/refuel/functions/fnc_canDisconnect.sqf +++ b/addons/refuel/functions/fnc_canDisconnect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check if a unit can disconnect a fuel nozzle diff --git a/addons/refuel/functions/fnc_canReturnNozzle.sqf b/addons/refuel/functions/fnc_canReturnNozzle.sqf index aef2e96fa0..ad74d9c962 100644 --- a/addons/refuel/functions/fnc_canReturnNozzle.sqf +++ b/addons/refuel/functions/fnc_canReturnNozzle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check if a unit can return a fuel nozzle diff --git a/addons/refuel/functions/fnc_canTakeNozzle.sqf b/addons/refuel/functions/fnc_canTakeNozzle.sqf index 82ca8452bc..f2fa4a6a9c 100644 --- a/addons/refuel/functions/fnc_canTakeNozzle.sqf +++ b/addons/refuel/functions/fnc_canTakeNozzle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check if a unit can take a fuel nozzle @@ -22,8 +22,9 @@ if (isNull _unit || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {!alive _object} || - {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || - {typeOf _object == QGVAR(fuelNozzle) && {!isNull (attachedTo _object)}} || // Not carried by someone else + {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || // Not already carrying a nozzle + {(_object getVariable [QGVAR(jerryCan), false]) && {!isNull (_object getVariable [QGVAR(nozzle), objNull])}} || // Prevent jerry cans from being picked up if they have a nozzle connected + {!([_unit, _object, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith))} || // Not carried by someone else {([_unit, _object] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE}) exitWith {false}; !(_object getVariable [QGVAR(isConnected), false]) && {!(_unit getVariable [QGVAR(isRefueling), false])} diff --git a/addons/refuel/functions/fnc_canTurnOff.sqf b/addons/refuel/functions/fnc_canTurnOff.sqf index 624cfde552..2e141fd2db 100644 --- a/addons/refuel/functions/fnc_canTurnOff.sqf +++ b/addons/refuel/functions/fnc_canTurnOff.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Check if a unit can turn off a fuel nozzle diff --git a/addons/refuel/functions/fnc_canTurnOn.sqf b/addons/refuel/functions/fnc_canTurnOn.sqf index 855837d97c..a33861c754 100644 --- a/addons/refuel/functions/fnc_canTurnOn.sqf +++ b/addons/refuel/functions/fnc_canTurnOn.sqf @@ -1,11 +1,12 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk - * Check if a unit can turn on a fuel nozzle + * Check if a unit can turn on a fuel nozzle. * * Arguments: * 0: Unit * 1: Nozzle + * 2: Refuel container (default: false) * * Return Value: * Can turn on @@ -16,7 +17,7 @@ * Public: No */ -params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_refuelContainer", false, [false]]]; if (isNull _unit || {isNull _nozzle} || @@ -24,7 +25,18 @@ if (isNull _unit || {!local _unit} || {(_nozzle distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; +private _source = _nozzle getVariable [QGVAR(source), objNull]; +private _sink = _nozzle getVariable [QGVAR(sink), objNull]; + +if (isNull _source || {isNull _sink}) exitWith {false}; + +private _isSinkFull = if (_refuelContainer) then { + ([_sink] call FUNC(getCapacity)) in [REFUEL_DISABLED_FUEL, REFUEL_INFINITE_FUEL, [_sink] call FUNC(getFuel)] +} else { + fuel _sink == 1 +}; + !(_nozzle getVariable [QGVAR(isRefueling), false]) && - {[_nozzle getVariable QGVAR(source)] call FUNC(getFuel) != 0} && - {!isNull (_nozzle getVariable [QGVAR(sink), objNull])} && - {(fuel (_nozzle getVariable QGVAR(sink))) < 1} + {(([_source] call FUNC(getCapacity)) == REFUEL_INFINITE_FUEL) || {[_source] call FUNC(getFuel) > 0}} && // Make sure the source has fuel + {!_isSinkFull} && // Make sure the sink isn't full + {!(_refuelContainer && {_source == _sink})}; // No endless container ot itself loop diff --git a/addons/refuel/functions/fnc_checkFuel.sqf b/addons/refuel/functions/fnc_checkFuel.sqf index 275ad7999b..9a4bcbab86 100644 --- a/addons/refuel/functions/fnc_checkFuel.sqf +++ b/addons/refuel/functions/fnc_checkFuel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Get the remaining fuel amount @@ -21,7 +21,7 @@ params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; private _fuel = [_source] call FUNC(getFuel); [ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION * 2), + GVAR(progressDuration) * 2, [_unit, _source, _fuel], { params ["_args"]; diff --git a/addons/refuel/functions/fnc_connectNozzleAction.sqf b/addons/refuel/functions/fnc_connectNozzleAction.sqf index 7c626c2359..502e1dc3a4 100644 --- a/addons/refuel/functions/fnc_connectNozzleAction.sqf +++ b/addons/refuel/functions/fnc_connectNozzleAction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk et.al. * Calculates a connection for refueling. @@ -23,10 +23,10 @@ params [["_unit", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_startin private _bestPosASL = []; -private _bestPosDistance = 1e99; +private _bestPosDistance = 1e38; private _viewPos = _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0,0,1])) vectorMultiply 3); -private _modelVector = _startingPosASL vectorFromTo (AGLtoASL (_sink modelToWorld [0,0,0])); -private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_sink modelToWorld [0,0,-1])); +private _modelVector = _startingPosASL vectorFromTo (_sink modelToWorldWorld [0,0,0]); +private _modelVectorLow = _startingPosASL vectorFromTo (_sink modelToWorldWorld [0,0,-1]); { private _endPosASL = _x; @@ -50,8 +50,8 @@ private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_sink modelToW _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0,-0.25,1])) vectorMultiply 3), _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [-0.25,-0.25,1])) vectorMultiply 3), _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0.25,-0.25,1])) vectorMultiply 3), - AGLtoASL (_sink modelToWorld [0,0,0]), // Try old method of just using model center - AGLtoASL (_sink modelToWorld [0,0,-0.5]) + _sink modelToWorldWorld [0,0,0], // Try old method of just using model center + _sink modelToWorldWorld [0,0,-0.5] ]; //Checks (too close to center or can't attach) @@ -65,7 +65,7 @@ _bestPosASL = _bestPosASL vectorAdd ((_bestPosASL vectorFromTo _startingPosASL) private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); [ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), + GVAR(progressDuration), [_unit, _nozzle, _sink, _attachPosModel], { params ["_args"]; @@ -73,6 +73,8 @@ private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); _unit setVariable [QGVAR(nozzle), nil, true]; _unit setVariable [QGVAR(isRefueling), false]; + private _source = _nozzle getVariable QGVAR(source); + detach _nozzle; _nozzle attachTo [_sink, _endPosTestOffset]; _endPosTestOffset params ["_x", "_y"]; @@ -111,25 +113,41 @@ private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); _nozzle setVariable [QGVAR(isConnected), true, true]; _sink setVariable [QGVAR(nozzle), _nozzle, true]; - _source = _nozzle getVariable QGVAR(source); - private _fuel = [_source] call FUNC(getFuel); - if (_fuel == REFUEL_INFINITE_FUEL) then { - _source setVariable [QGVAR(fuelCounter), 0, true]; - } else { - _source setVariable [QGVAR(fuelCounter), _fuel, true]; - }; + // Reset fuel counter + _source setVariable [QGVAR(fuelCounter), 0, true]; + + // Let other players access nozzle + [objNull, _nozzle] call EFUNC(common,claim); [_unit, _sink, _nozzle, _endPosTestOffset] call FUNC(refuel); - if ([_unit, _nozzle] call FUNC(canTurnOn)) then { - _unit setVariable [QGVAR(tempFuel), nil]; - [_unit, _nozzle] call FUNC(turnOn); - } else { - [localize LSTRING(CouldNotTurnOn)] call EFUNC(common,displayText); + private _canReceive = getNumber ((configOf _sink) >> QGVAR(canReceive)) == 1; + private _isContainer = ([_sink] call FUNC(getCapacity)) != REFUEL_DISABLED_FUEL; + + // Decide if cargo or vehicle will be refueled + switch (true) do { + case (_canReceive && {!_isContainer || {_sink == _source}}): { + // is not a refueling vehicle or refueling vehicle tries to refuel itself + if ([_unit, _nozzle, false] call FUNC(canTurnOn)) then { + [_unit, _nozzle, false] call FUNC(turnOn); + } else { + [localize LSTRING(CouldNotTurnOn)] call EFUNC(common,displayTextStructured); + }; + }; + case (!_canReceive && _isContainer): { + if ([_unit, _nozzle, true] call FUNC(canTurnOn)) then { + [_unit, _nozzle, true] call FUNC(turnOn); + } else { + [localize LSTRING(CouldNotTurnOn)] call EFUNC(common,displayTextStructured); + }; + }; + default { + /* Target is a refueling vehicle, let user manually decide if he wants to refuel cargo or vehicle itself */ + }; }; }, "", - localize LSTRING(ConnectAction), + localize ([LSTRING(ConnectAction), LSTRING(ConnectFuelCanisterAction)] select (_nozzle getVariable [QGVAR(jerryCan), false])), {true}, [INTERACT_EXCEPTIONS] ] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_disconnect.sqf b/addons/refuel/functions/fnc_disconnect.sqf index b227b9fcc9..1bc1b2b8e8 100644 --- a/addons/refuel/functions/fnc_disconnect.sqf +++ b/addons/refuel/functions/fnc_disconnect.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk - * Disconnect a fuel nozzle. + * Disconnects a fuel nozzle and makes unit pick it up. * * Arguments: - * 0: Unit + * 0: Unit (default: objNull) * 1: Nozzle * * Return Value: @@ -27,4 +27,6 @@ _nozzle setVariable [QGVAR(sink), nil, true]; _nozzle setVariable [QGVAR(isConnected), false, true]; [objNull, _nozzle, true] call FUNC(dropNozzle); -[_unit, _nozzle] call FUNC(takeNozzle); +if (!isNull _unit) then { + [_unit, _nozzle] call FUNC(takeNozzle); +}; diff --git a/addons/refuel/functions/fnc_dropNozzle.sqf b/addons/refuel/functions/fnc_dropNozzle.sqf index 69b08b9026..ee37a869e1 100644 --- a/addons/refuel/functions/fnc_dropNozzle.sqf +++ b/addons/refuel/functions/fnc_dropNozzle.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Detaches the fuel nozzle, drops it and removes player variables. * * Arguments: - * 0: Unit (optional) + * 0: Unit (default: objNull) * 1: Nozzle * 2: Disconnect Only * @@ -24,6 +24,9 @@ TRACE_3("dropNozzle",_unit,_nozzle,_disconnectOnly); detach _nozzle; _nozzle setVariable [QGVAR(isRefueling), false, true]; +// Remove claim on nozzle +[objNull, _nozzle] call EFUNC(common,claim); + if (_disconnectOnly) exitWith {}; _nozzle setVelocity [0, 0, 0]; diff --git a/addons/refuel/functions/fnc_getCapacity.sqf b/addons/refuel/functions/fnc_getCapacity.sqf new file mode 100644 index 0000000000..c6218831da --- /dev/null +++ b/addons/refuel/functions/fnc_getCapacity.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: QuantX + * Gets the capacity of a fuel source's tank. + * + * Arguments: + * 0: Fuel Source + * + * Return Value: + * Fuel capacity (-10 means infinte fuel, -1 means not a fuel source, >0 is a capacity in liters) + * + * Example: + * [fuelTruck] call ace_refuel_fnc_getCapacity + * + * Public: Yes + */ + +params [["_source", objNull, [objNull]]]; + +if (isNull _source) exitWith {REFUEL_DISABLED_FUEL}; + +private _capacity = _source getVariable QGVAR(capacity); + +// Initialize fuel truck if needed +if (isNil "_capacity") then { + // Check if this object has a fuelCargo config entry + private _fuelCargo = configOf _source >> QGVAR(fuelCargo); + _capacity = if (isNumber _fuelCargo) then {getNumber _fuelCargo} else {REFUEL_DISABLED_FUEL}; + + // Set capacity even if this isn't a fuel source to save on config lookup time in the event this function is used in a loop + _source setVariable [QGVAR(capacity), _capacity, true]; + // handle weird edge case when trying to run on "camera"/CfgNonAIVehicles which won't support setVariable and will inf-loop + if (isNil {_source getVariable QGVAR(capacity)}) exitWith { WARNING_1("trying to getCapacity from non-CfgVehicle %1",_this); }; + [_source, _capacity] call FUNC(setFuel); +}; + +_capacity; diff --git a/addons/refuel/functions/fnc_getFuel.sqf b/addons/refuel/functions/fnc_getFuel.sqf index ecba330363..6bc82ee2d7 100644 --- a/addons/refuel/functions/fnc_getFuel.sqf +++ b/addons/refuel/functions/fnc_getFuel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Get the remaining fuel amount. @@ -22,8 +22,8 @@ if (isNull _source) exitWith {0}; private _fuel = _source getVariable QGVAR(currentFuelCargo); if (isNil "_fuel") then { - _fuel = getNumber (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(fuelCargo)); - _source setVariable [QGVAR(currentFuelCargo), _fuel, true]; + // Calling getCapacity will initialize the fuel source and return the amount of fuel in the tank + _fuel = [_source] call FUNC(getCapacity); }; _fuel diff --git a/addons/refuel/functions/fnc_getFuelCargo.sqf b/addons/refuel/functions/fnc_getFuelCargo.sqf new file mode 100644 index 0000000000..360679013e --- /dev/null +++ b/addons/refuel/functions/fnc_getFuelCargo.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Returns vehicle fuel amount from config (cached). + * + * Arguments: + * 0: Fuel Source + * + * Return Value: + * Fuel amount from config + * + * Example: + * cursorObject call ace_refuel_fnc_getFuelCargo + * + * Public: No + */ + +params ["_source"]; + +(uiNamespace getVariable QGVAR(cacheRefuelCargo)) getOrDefault [typeOf _source, REFUEL_DISABLED_FUEL] diff --git a/addons/refuel/functions/fnc_handleDisconnect.sqf b/addons/refuel/functions/fnc_handleDisconnect.sqf index ebf0d729ea..cf4b37cce9 100644 --- a/addons/refuel/functions/fnc_handleDisconnect.sqf +++ b/addons/refuel/functions/fnc_handleDisconnect.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Cleans up refuel on client disconnect. diff --git a/addons/refuel/functions/fnc_handleRespawn.sqf b/addons/refuel/functions/fnc_handleRespawn.sqf index 893f893724..e82421626c 100644 --- a/addons/refuel/functions/fnc_handleRespawn.sqf +++ b/addons/refuel/functions/fnc_handleRespawn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Clean variables on unit respawn. diff --git a/addons/refuel/functions/fnc_initSource.sqf b/addons/refuel/functions/fnc_initSource.sqf index c484c151f4..5d5d6f2ea4 100644 --- a/addons/refuel/functions/fnc_initSource.sqf +++ b/addons/refuel/functions/fnc_initSource.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Adds refuel menu to object. diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index 4c4cd22aa1..31a91a30d7 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Makes an object into a jerry can. @@ -16,17 +16,27 @@ * Public: Yes */ +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeJerryCan), _this]; +}; + +if (!GVAR(enabled)) exitWith {}; + params [["_target", objNull, [objNull]], ["_fuelAmount", 20, [0]]]; if (isNull _target || {_target isKindOf "AllVehicles"} || {_target getVariable [QGVAR(jerryCan), false]}) exitWith {}; -if (isServer) then { - [_target, _fuelAmount] call FUNC(setFuel); // has global effects -}; _target setVariable [QGVAR(jerryCan), true]; _target setVariable [QGVAR(source), _target]; +_target setVariable [QGVAR(capacity), _fuelAmount]; + +if (isServer) then { + [_target, _fuelAmount] call FUNC(setFuel); // has global effects + [QGVAR(jerryCanInitalized), [_target]] call CBA_fnc_globalevent; +}; // Main Action private _action = [QGVAR(Refuel), @@ -37,19 +47,21 @@ private _action = [QGVAR(Refuel), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); // Add pickup _action = [QGVAR(PickUpNozzle), - localize LSTRING(TakeNozzle), + localize LSTRING(TakeFuelCanister), QPATHTOF(ui\icon_refuel_interact.paa), {[_player, _target] call FUNC(takeNozzle)}, {[_player, _target] call FUNC(canTakeNozzle)}, {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOn @@ -61,7 +73,34 @@ _action = [QGVAR(TurnOn), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); +[_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); + +// Add turnOn container +_action = [QGVAR(TurnOn_Container), + localize LSTRING(TurnOn_Container), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target, true] call FUNC(turnOn)}, + {[_player, _target, true] call FUNC(canTurnOn)}, + {}, + [], + [0, 0, 0], + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); +[_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); + +// Add check fuel +_action = [QGVAR(CheckFuel), + localize LSTRING(CheckFuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(checkFuel)}, + {[_player, _target] call FUNC(canCheckFuel)}, + {}, + [], + [0,0,0], + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOff @@ -73,17 +112,19 @@ _action = [QGVAR(TurnOff), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add disconnect _action = [QGVAR(Disconnect), - localize LSTRING(Disconnect), + localize LSTRING(DisconnectFuelCanister), QPATHTOF(ui\icon_refuel_interact.paa), {[_player, _target] call FUNC(disconnect)}, {[_player, _target] call FUNC(canDisconnect)}, {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf index 7b2179adab..9d76635849 100644 --- a/addons/refuel/functions/fnc_makeSource.sqf +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Makes an object into a refuel source. @@ -25,25 +25,47 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeSource), _this]; }; +if (!GVAR(enabled)) exitWith {}; + params [ ["_source", objNull, [objNull]], ["_fuelCargo", 0, [0]], ["_hooks", nil, [[]]] ]; -TRACE_3("makeSource",_source,_fuelCargo,_hooks); -private _fuelCargoConfig = getNumber (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(fuelCargo)); +private _fuelCargoConfig = _source call FUNC(getFuelCargo); + +TRACE_4("makeSource",_source,_fuelCargo,_hooks,_fuelCargoConfig); if ( isNull _source || {_fuelCargo < 0 && {!(_fuelCargo in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])}} - || {_fuelCargo != 0 && {_fuelCargo == _fuelCargoConfig}} ) exitWith {}; -[_source, _fuelCargo] call FUNC(setFuel); +// We might be removing fuel from an object that in config doesn't have fuel, but was given fuel via this function prior +if (_fuelCargo == REFUEL_DISABLED_FUEL && {_fuelCargoConfig == REFUEL_DISABLED_FUEL}) exitWith { + if (isNil {_source getVariable QGVAR(currentFuelCargo)}) exitWith {}; + + _source setVariable [QGVAR(currentFuelCargo), nil, true]; + _source setVariable [QGVAR(capacity), REFUEL_DISABLED_FUEL, true]; + + private _jipID = _source getVariable QGVAR(initSource_jipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _source setVariable [QGVAR(initSource_jipID), nil]; +}; + +private _capacity = if (_fuelCargo < 0) then {_fuelCargo} else {_fuelCargoConfig max _fuelCargo}; + +_source setVariable [QGVAR(capacity), _capacity, true]; if (_fuelCargo == REFUEL_DISABLED_FUEL) exitWith {}; +[_source, _fuelCargo] call FUNC(setFuel); + if ( !isNil "_hooks" && {_hooks isEqualTypeAll []} @@ -52,9 +74,11 @@ if ( _source setVariable [QGVAR(hooks), _hooks, true]; }; -// check if menu already exists -if (_fuelCargoConfig != 0 || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; +// only add if menu doesn't already exist +if (_fuelCargoConfig != REFUEL_DISABLED_FUEL || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; [_jipID, _source] call CBA_fnc_removeGlobalEventJIP; _source setVariable [QGVAR(initSource_jipID), _jipID]; + +[QGVAR(sourceInitialized), [_source]] call CBA_fnc_globalEvent; diff --git a/addons/refuel/functions/fnc_moduleRefuelSettings.sqf b/addons/refuel/functions/fnc_moduleRefuelSettings.sqf index fabdad1706..4ab654dd66 100644 --- a/addons/refuel/functions/fnc_moduleRefuelSettings.sqf +++ b/addons/refuel/functions/fnc_moduleRefuelSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Module for adjusting the refuel settings. @@ -23,5 +23,6 @@ if !(_activated) exitWith {}; [_logic, QGVAR(rate), "rate"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(hoseLength), "hoseLength"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(progressDuration), "progressDuration"] call EFUNC(common,readSettingFromModule); -INFO_2("Refuel Module Initialized with flow rate: %1 - hoseLength: %2",GVAR(rate), GVAR(hoseLength)) +INFO_3("Refuel Module Initialized with flow rate: %1 - hoseLength: %2 - progressDuration: %3",GVAR(rate),GVAR(hoseLength),GVAR(progressDuration)) diff --git a/addons/refuel/functions/fnc_onMouseButtonDown.sqf b/addons/refuel/functions/fnc_onMouseButtonDown.sqf index 2111be99e8..b103cedff7 100644 --- a/addons/refuel/functions/fnc_onMouseButtonDown.sqf +++ b/addons/refuel/functions/fnc_onMouseButtonDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Mouse button down event. @@ -42,10 +42,11 @@ private _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0. if (cameraView == "EXTERNAL") then { _virtualPosASL = _virtualPosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); }; + if ( !isNull _cursorObject && {_distance < REFUEL_NOZZLE_ACTION_DISTANCE} - && {1 == getNumber (configFile >> "CfgVehicles" >> (typeOf _cursorObject) >> QGVAR(canReceive))} + && {[_cursorObject] call FUNC(canConnectNozzle)} && {isNull (_cursorObject getVariable [QGVAR(nozzle), objNull])} && {!lineIntersects [eyePos _unit, _virtualPosASL, _unit]} ) then { diff --git a/addons/refuel/functions/fnc_readFuelCounter.sqf b/addons/refuel/functions/fnc_readFuelCounter.sqf index cc851a549f..5ed8e20a62 100644 --- a/addons/refuel/functions/fnc_readFuelCounter.sqf +++ b/addons/refuel/functions/fnc_readFuelCounter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Reads the fuel counter. @@ -18,12 +18,6 @@ params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; -private _currentFuel = [_source] call FUNC(getFuel); -private _fuelCounter = if (_currentFuel == REFUEL_INFINITE_FUEL) then { - _source getVariable [QGVAR(fuelCounter), 0] -} else { - (_source getVariable [QGVAR(fuelCounter), _currentFuel]) - _currentFuel -}; - -private _fuelCounter = 0.01 * round (100 * _fuelCounter); +private _fuelCounter = _source getVariable [QGVAR(fuelCounter), 0]; +_fuelCounter = 0.01 * round (100 * _fuelCounter); [[LSTRING(Hint_FuelCounter), _fuelCounter], 1.5, _unit] call EFUNC(common,displayTextStructured); diff --git a/addons/refuel/functions/fnc_refuel.sqf b/addons/refuel/functions/fnc_refuel.sqf index 4717f1206c..1cf7b4377a 100644 --- a/addons/refuel/functions/fnc_refuel.sqf +++ b/addons/refuel/functions/fnc_refuel.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: GitHawk + * Author: GitHawk, QuantX * Refuels the vehicle. * * Arguments: @@ -20,86 +20,113 @@ params [["_unit", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_connectToPoint", [0,0,0], [[]], 3]]; -private _config = configFile >> "CfgVehicles" >> typeOf _sink; - -private _rate = getNumber (_config >> QGVAR(flowRate)) * GVAR(rate); -private _maxFuel = getNumber (_config >> QGVAR(fuelCapacity)); +private _config = configOf _sink; +private _rate = if (isNumber (_config >> QGVAR(flowRate))) then { + getNumber (_config >> QGVAR(flowRate)) * GVAR(rate) +} else { + // Jerry cans for example have no flow rate defined, default to 1 + GVAR(rate) +}; +// How much fuel is in a vehicle's fuel tank +private _maxFuelTank = getNumber (_config >> QGVAR(fuelCapacity)); // Fall back to vanilla fuelCapacity value (only air and sea vehicles don't have this defined by default by us) // Air and sea vehicles have that value properly defined in liters, unlike ground vehicles which is is formula of (range * tested factor) - different fuel consumption system than ground vehicles -if (_maxFuel == 0) then { - _maxFuel = getNumber (_config >> "fuelCapacity"); +if (_maxFuelTank == 0) then { + _maxFuelTank = getNumber (_config >> "fuelCapacity"); }; [{ params ["_args", "_pfID"]; - _args params [["_source", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_rate", 1, [0]], ["_startFuel", 0, [0]], ["_maxFuel", 0, [0]], ["_connectFromPoint", [0,0,0], [[]], 3], ["_connectToPoint", [0,0,0], [[]], 3]]; + _args params [["_source", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_rate", 1, [0]], ["_maxFuelTank", 1, [0]], ["_connectFromPoint", [0,0,0], [[]], 3], ["_connectToPoint", [0,0,0], [[]], 3]]; if !(_nozzle getVariable [QGVAR(isConnected), false]) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; }; + // Quit if target or fuel tank got destroyed if (!alive _source || {!alive _sink}) exitWith { - [objNull, _nozzle] call FUNC(dropNozzle); - _nozzle setVariable [QGVAR(isConnected), false, true]; - if (_nozzle isKindOf "Land_CanisterFuel_F") then { _nozzle setVariable [QEGVAR(cargo,canLoad), true, true]; }; - _nozzle setVariable [QGVAR(sink), nil, true]; - _sink setVariable [QGVAR(nozzle), nil, true]; + [objNull, _nozzle] call FUNC(disconnect); [_pfID] call CBA_fnc_removePerFrameHandler; }; + + // Quit if hose distance was exceeded private _hoseLength = _source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; private _tooFar = ((_sink modelToWorld _connectToPoint) distance (_source modelToWorld _connectFromPoint)) > (_hoseLength - 2); if (_tooFar && {!(_nozzle getVariable [QGVAR(jerryCan), false])}) exitWith { [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); - - [objNull, _nozzle] call FUNC(dropNozzle); - _nozzle setVariable [QGVAR(isConnected), false, true]; - if (_nozzle isKindOf "Land_CanisterFuel_F") then { _nozzle setVariable [QEGVAR(cargo,canLoad), true, true]; }; - _nozzle setVariable [QGVAR(sink), nil, true]; - _sink setVariable [QGVAR(nozzle), nil, true]; + [objNull, _nozzle] call FUNC(disconnect); [_pfID] call CBA_fnc_removePerFrameHandler; }; + // Main fueling process private _finished = false; private _fueling = _nozzle getVariable [QGVAR(isRefueling), false]; if (_fueling) then { - private _fuelInSource = [_source] call FUNC(getFuel); - if (_fuelInSource == 0) exitWith { - [LSTRING(Hint_SourceEmpty), 2, _unit] call EFUNC(common,displayTextStructured); - _nozzle setVariable [QGVAR(lastTickMissionTime), nil]; - _nozzle setVariable [QGVAR(isRefueling), false, true]; - }; - + private _refuelContainer = _nozzle getVariable [QGVAR(refuelContainer), false]; + + // Use special cargo refuel rate when refueling containers + // TODO: Add flow dedicated input/output flow rates for every container and use the lower of the two instead + if (_refuelContainer) then {_rate = GVAR(cargoRate)}; + // Calculate rate using mission time to take time acceleration and pause into account - private _rateTime = _rate * (CBA_missionTime - (_nozzle getVariable [QGVAR(lastTickMissionTime), CBA_missionTime])); + private _addedFuel = _rate * (CBA_missionTime - (_nozzle getVariable [QGVAR(lastTickMissionTime), CBA_missionTime])); _nozzle setVariable [QGVAR(lastTickMissionTime), CBA_missionTime]; - if !(_fuelInSource == REFUEL_INFINITE_FUEL) then { - _fuelInSource = _fuelInSource - _rateTime; + // Figure out exactly how much fuel to transfer while being sure not to take too much from source + private _fuelInSource = [_source] call FUNC(getFuel); + if (([_source] call FUNC(getCapacity)) != REFUEL_INFINITE_FUEL) then { + if (_addedFuel > _fuelInSource) then { + _addedFuel = _fuelInSource; + _fuelInSource = 0; + _finished = true; + [LSTRING(Hint_SourceEmpty), 2, _unit] call EFUNC(common,displayTextStructured); + } else { + _fuelInSource = _fuelInSource - _addedFuel; + }; + }; + + private _fuelInSink = (if (_refuelContainer) then { + [_sink] call FUNC(getFuel) } else { - _source setVariable [QGVAR(fuelCounter), (_source getVariable [QGVAR(fuelCounter), 0]) + _rateTime, true]; - }; - if (_fuelInSource < 0 && {_fuelInSource > REFUEL_INFINITE_FUEL}) then { - _fuelInSource = 0; - _finished = true; - [LSTRING(Hint_SourceEmpty), 2, _unit] call EFUNC(common,displayTextStructured); - }; - - private _fuelInSink = (_unit getVariable [QGVAR(tempFuel), _startFuel]) + ( _rateTime / _maxFuel); - if (_fuelInSink > 1) then { - _fuelInSink = 1; + // How full the gas tank is. We keep our own record, since `fuel _sink` doesn't update quick enough + (_nozzle getVariable [QGVAR(tempFuel), fuel _sink]) * _maxFuelTank + }) + _addedFuel; + + // Add fuel to target while being sure not to put too much into sink + private _maxFuelContainer = [_sink] call FUNC(getCapacity); + private _maxFuel = [_maxFuelTank, _maxFuelContainer] select _refuelContainer; + if (_fuelInSink >= _maxFuel) then { + // Put any extra fuel back + _fuelInSource = _fuelInSource + (_fuelInSink - _maxFuel); + _addedFuel = _maxFuel - _fuelInSink; + // We're done + _fuelInSink = _maxFuel; _finished = true; [LSTRING(Hint_Completed), 2, _unit] call EFUNC(common,displayTextStructured); }; - _unit setVariable [QGVAR(tempFuel), _fuelInSink]; + + if (_refuelContainer) then { + [_sink, _fuelInSink] call FUNC(setFuel); + } else { + private _fillRatio = _fuelInSink / _maxFuelTank; + [QEGVAR(common,setFuel), [_sink, _fillRatio], _sink] call CBA_fnc_targetEvent; + _nozzle setVariable [QGVAR(tempFuel), _fillRatio]; + }; + + // Increment fuel counter + _source setVariable [QGVAR(fuelCounter), (_source getVariable [QGVAR(fuelCounter), 0]) + _addedFuel, true]; + + [QGVAR(tick), [_source, _sink, _addedFuel, _refuelContainer]] call CBA_fnc_localEvent; - [QEGVAR(common,setFuel), [_sink, _fuelInSink], _sink] call CBA_fnc_targetEvent; [_source, _fuelInSource] call FUNC(setFuel); } else { - _unit setVariable [QGVAR(tempFuel), fuel _sink]; + _nozzle setVariable [QGVAR(tempFuel), fuel _sink]; }; - if (_finished) exitWith { + // Reset variables when done + if (_finished) then { + [QGVAR(stopped), [_source, _sink]] call CBA_fnc_localEvent; _nozzle setVariable [QGVAR(lastTickMissionTime), nil]; _nozzle setVariable [QGVAR(isRefueling), false, true]; }; @@ -109,8 +136,7 @@ if (_maxFuel == 0) then { _unit, _nozzle, _rate, - fuel _sink, - _maxFuel, + _maxFuelTank, _nozzle getVariable [QGVAR(attachPos), [0,0,0]], _connectToPoint ]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_returnNozzle.sqf b/addons/refuel/functions/fnc_returnNozzle.sqf index 3cc2f773f0..ea84f6a518 100644 --- a/addons/refuel/functions/fnc_returnNozzle.sqf +++ b/addons/refuel/functions/fnc_returnNozzle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk, Jonpas * Returns the nozzle back to source vehicle. @@ -23,7 +23,7 @@ private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; if (isNull _nozzle || {_source != _nozzle getVariable QGVAR(source)}) exitWith {}; [ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), + GVAR(progressDuration), [_unit, _nozzle, _source], { params ["_args"]; @@ -43,6 +43,10 @@ if (isNull _nozzle || {_source != _nozzle getVariable QGVAR(source)}) exitWith { deleteVehicle _helper; }; deleteVehicle _nozzle; + + // Restore ability to drag and carry this object + _source setVariable [QEGVAR(dragging,canCarry), _source getVariable [QGVAR(canCarryLast), false], true]; + _source setVariable [QEGVAR(dragging,canDrag), _source getVariable [QGVAR(canDragLast), false], true]; [_source, "blockEngine", "ACE_Refuel", false] call EFUNC(common,statusEffect_set); }, diff --git a/addons/refuel/functions/fnc_setFuel.sqf b/addons/refuel/functions/fnc_setFuel.sqf index f95596f4f1..b458dba80f 100644 --- a/addons/refuel/functions/fnc_setFuel.sqf +++ b/addons/refuel/functions/fnc_setFuel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Set the remaining fuel amount. @@ -18,7 +18,12 @@ params [["_source", objNull, [objNull]], ["_fuel", nil, [0]]]; -if (isNull _source || - {isNil "_fuel"}) exitWith {}; +// Ensure valid fuel quantity +if (isNull _source || {isNil "_fuel"}) exitWith {}; -_source setVariable [QGVAR(currentFuelCargo), _fuel, true]; +// Make sure this is actually a finite fuel source +private _capacity = [_source] call FUNC(getCapacity); +if (_capacity in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL]) exitWith {}; + +// Don't overfill or underfill tank +_source setVariable [QGVAR(currentFuelCargo), (_fuel min _capacity) max 0, true]; diff --git a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf index 9fae9abdab..611fa85e90 100644 --- a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf +++ b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * PFH while nozzle is in hands. @@ -35,11 +35,9 @@ TRACE_2("start",_unit,_nozzle); _args params ["_unit", "_nozzle"]; if !( - alive _unit + _unit call EFUNC(common,isAwake) && {"" isEqualTo currentWeapon _unit || {_unit call EFUNC(common,isSwimming)}} && {[_unit, objNull, [INTERACT_EXCEPTIONS, "notOnMap"]] call EFUNC(common,canInteractWith)} - && {!("unconscious" isEqualTo toLower animationState _unit)} - && {!(_unit getVariable ["ACE_isUnconscious", false])} ) exitWith { TRACE_3("stop dead/weapon/interact/uncon",_unit,alive _unit,currentWeapon _unit); DROP_NOZZLE @@ -71,7 +69,7 @@ TRACE_2("start",_unit,_nozzle); END_PFH }; - if !(_unit == vehicle _unit && {_unit isEqualTo ACE_player}) exitWith { + if (_unit == vehicle _unit && {_unit isNotEqualTo ACE_player}) exitWith { TRACE_2("stop vehicle/player",_unit,vehicle _unit); DROP_NOZZLE UNHOLSTER_WEAPON @@ -95,11 +93,8 @@ TRACE_2("start",_unit,_nozzle); getCursorObjectParams params ["_cursorObject", "", "_distance"]; if (!isNull _cursorObject && {_distance < REFUEL_NOZZLE_ACTION_DISTANCE}) then { - if ( - 1 == getNumber (configFile >> "CfgVehicles" >> (typeOf _cursorObject) >> QGVAR(canReceive)) - && {isNull (_cursorObject getVariable [QGVAR(nozzle), objNull])} - ) then { - _hintLMB = localize LSTRING(Connect); + if ([_cursorObject] call FUNC(canConnectNozzle)) then { + _hintLMB = localize ([LSTRING(Connect), LSTRING(ConnectFuelCanister)] select (_nozzle getVariable [QGVAR(jerryCan), false])); }; if ([_unit, _cursorObject] call FUNC(canReturnNozzle)) then { _hintRMB = localize LSTRING(Return); @@ -107,7 +102,7 @@ TRACE_2("start",_unit,_nozzle); }; private _hint = [_hintLMB, _hintRMB]; - if !(_hint isEqualTo (_unit getVariable [QGVAR(hint), []])) then { + if (_hint isNotEqualTo (_unit getVariable [QGVAR(hint), []])) then { _unit setVariable [QGVAR(hint), _hint]; _hint call EFUNC(interaction,showMouseHint); }; diff --git a/addons/refuel/functions/fnc_takeNozzle.sqf b/addons/refuel/functions/fnc_takeNozzle.sqf index 83e38c1be6..cd8f8b4eb4 100644 --- a/addons/refuel/functions/fnc_takeNozzle.sqf +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Take a fuel nozzle either from a fuel truck/station or from the ground. @@ -22,7 +22,7 @@ params [ ]; [ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), + GVAR(progressDuration), [_unit, _object], { params ["_args"]; @@ -32,22 +32,28 @@ params [ private _source = _object; private _nozzle = _object; - if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on muzzle either connected or on ground + if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on nozzle either connected or on ground _source = _nozzle getVariable QGVAR(source); if (_nozzle getVariable [QGVAR(jerryCan), false]) then { _nozzle attachTo [_unit, [0,1,0], "pelvis"]; } else { _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; }; + + // Don't allow other players to take nozzle + [_unit, _nozzle] call EFUNC(common,claim); } else { // func is called on fuel truck _nozzle = QGVAR(fuelNozzle) createVehicle [0,0,0]; _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; + // Don't allow other players to take nozzle + [_unit, _nozzle] call EFUNC(common,claim); + private _ropeTarget = _source; if !(_source isKindOf "AllVehicles") then { private _helper = QGVAR(helper) createVehicle [0,0,0]; [QEGVAR(common,hideObjectGlobal), [_helper, true]] call CBA_fnc_serverEvent; - if ((getText (configFile >> "CfgVehicles" >> typeOf _source >> "simulation")) isEqualTo "thingX") then { + if ((getText (configOf _source >> "simulation")) isEqualTo "thingX") then { _helper attachTo [_source, [0,0,0]]; } else { _helper setPosWorld (getPosWorld _source); @@ -57,7 +63,7 @@ params [ _nozzle setVariable [QGVAR(helper), _helper, true]; _ropeTarget = _helper; }; - private _attachPos = _source getVariable [QGVAR(hooks), getArray (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(hooks))]; + private _attachPos = _source getVariable [QGVAR(hooks), getArray (configOf _source >> QGVAR(hooks))]; if (_attachPos isEqualTo []) then { _attachPos = [[0,0,0]]; }; @@ -69,7 +75,7 @@ params [ _attachPos = _attachPos select (_hookDistances find selectMin _hookDistances); }; private _hoseLength = _source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; - private _rope = ropeCreate [_ropeTarget, _attachPos, _nozzle, [0, -0.20, 0.12], _hoseLength]; + private _rope = ropeCreate [_ropeTarget, _attachPos, _nozzle, [0, -0.20, 0.12], _hoseLength, [], [], QGVAR(fuelHose)]; _nozzle setVariable [QGVAR(rope), _rope, true]; _nozzle setVariable [QGVAR(attachPos), _attachPos, true]; _nozzle setVariable [QGVAR(source), _source, true]; @@ -77,6 +83,13 @@ params [ [_source, "blockEngine", "ACE_Refuel", true] call EFUNC(common,statusEffect_set); _source setVariable [QGVAR(isConnected), true, true]; _source setVariable [QGVAR(ownedNozzle), _nozzle, true]; + + // Prevent moving the fuel source while the hose is out + _source setVariable [QGVAR(canCarryLast), _source getVariable [QEGVAR(dragging,canCarry), false], true]; + _source setVariable [QGVAR(canDragLast), _source getVariable [QEGVAR(dragging,canDrag), false], true]; + + _source setVariable [QEGVAR(dragging,canCarry), false, true]; + _source setVariable [QEGVAR(dragging,canDrag), false, true]; }; _unit setVariable [QGVAR(nozzle), _nozzle, true]; @@ -93,7 +106,7 @@ params [ [_unit, _nozzle] call FUNC(startNozzleInHandsPFH); }, {}, - localize LSTRING(TakeNozzleAction), + localize ([LSTRING(TakeNozzleAction), LSTRING(TakeFuelCanisterAction)] select (_object getVariable [QGVAR(jerryCan), false])), {true}, [INTERACT_EXCEPTIONS_REFUELING] ] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_turnOff.sqf b/addons/refuel/functions/fnc_turnOff.sqf index 1448a0d145..8d2a5b83df 100644 --- a/addons/refuel/functions/fnc_turnOff.sqf +++ b/addons/refuel/functions/fnc_turnOff.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Turn off a fuel nozzle. @@ -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..6fc88c85ad 100644 --- a/addons/refuel/functions/fnc_turnOn.sqf +++ b/addons/refuel/functions/fnc_turnOn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: GitHawk * Turn on a fuel nozzle. @@ -6,6 +6,7 @@ * Arguments: * 0: Unit * 1: Nozzle + * 2: Refuel container (default: false) * * Return Value: * None @@ -16,8 +17,10 @@ * Public: No */ -params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_refuelContainer", false, [false]]]; _nozzle setVariable [QGVAR(lastTickMissionTime), CBA_missionTime]; +_nozzle setVariable [QGVAR(refuelContainer), _refuelContainer]; _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/functions/script_component.hpp b/addons/refuel/functions/script_component.hpp deleted file mode 100644 index 167c1e614a..0000000000 --- a/addons/refuel/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\refuel\script_component.hpp" diff --git a/addons/refuel/initSettings.inc.sqf b/addons/refuel/initSettings.inc.sqf new file mode 100644 index 0000000000..2888ad190c --- /dev/null +++ b/addons/refuel/initSettings.inc.sqf @@ -0,0 +1,43 @@ +private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; + +[ + QGVAR(enabled), "CHECKBOX", + ELSTRING(common,Enabled), + _category, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(rate), "SLIDER", + [LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)], + _category, + [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(cargoRate), "SLIDER", + [LSTRING(RefuelSettings_speedCargo_DisplayName), LSTRING(RefuelSettings_speedCargo_Description)], + _category, + [0,250,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(hoseLength), "SLIDER", + [LSTRING(RefuelSettings_hoseLength_DisplayName)], + _category, + [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(progressDuration), "TIME", + [LSTRING(RefuelSettings_progressDuration_DisplayName), LSTRING(RefuelSettings_progressDuration_Description)], + _category, + [0, 10, 2], // [min, max, default value] + true // isGlobal +] call CBA_fnc_addSetting; diff --git a/addons/refuel/initSettings.sqf b/addons/refuel/initSettings.sqf deleted file mode 100644 index b16cff3230..0000000000 --- a/addons/refuel/initSettings.sqf +++ /dev/null @@ -1,19 +0,0 @@ -// CBA Settings [ADDON: ace_refuel]: - -[ - QGVAR(rate), "SLIDER", - [LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(hoseLength), "SLIDER", - [LSTRING(RefuelSettings_hoseLength_DisplayName)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], - [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; diff --git a/addons/refuel/script_component.hpp b/addons/refuel/script_component.hpp index be346e0cca..76d9b67819 100644 --- a/addons/refuel/script_component.hpp +++ b/addons/refuel/script_component.hpp @@ -2,7 +2,6 @@ #define COMPONENT_BEAUTIFIED Refuel #include "\z\ace\addons\main\script_mod.hpp" -// #define FAST_PROGRESSBARS // #define DRAW_HOOKS_POS // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE @@ -18,17 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define REFUEL_INFINITE_FUEL -10 -#define REFUEL_DISABLED_FUEL -1 -#define REFUEL_ACTION_DISTANCE 7 -#define REFUEL_NOZZLE_ACTION_DISTANCE 2 -#define REFUEL_PROGRESS_DURATION 2 - -#ifdef FAST_PROGRESSBARS - #define TIME_PROGRESSBAR(X) ((X) * 0.075) -#else - #define TIME_PROGRESSBAR(X) (X) -#endif +#include "\z\ace\addons\refuel\defines.hpp" #define INTERACT_EXCEPTIONS_REFUELING "isNotInside", "isNotOnLadder", "isNotSwimming" #define INTERACT_EXCEPTIONS INTERACT_EXCEPTIONS_REFUELING, "isNotRefueling" diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index 293c37b2d7..648ee38c6d 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -10,11 +10,12 @@ Nastavení tankování Impostazioni Rifornimento Parámetros de reabastecimiento - Réglages de ravitaillement + Paramètres de ravitaillement 給油設定 재급유 설정 加油设定 加油設定 + Yakıt Doldurma Ayarları Flow Rate @@ -23,13 +24,14 @@ Скорость заправки Velocidade da vazão Rychlost tankování - Portata Flusso + Portata di Flusso Caudal de llenado - Vitesse du ravitaillement + Débit de la pompe 流量 주유량 油料流量 油料流量 + Doldurma Hızı How fast should a vehicle be refueled? @@ -38,13 +40,36 @@ Как быстро техника должна быть заправлена? Quão rápido deve ser o veículo reabastecido? Jak rychle bude vozidlo natankováno? - Quanto velocemente dovrebbe essere rifornito un veicolo? + Quanto velocemente si può rifornire un veicolo? Cuán rápido se reabastecen los vehículos? - A quelle vitesse devrait être ravitaillé un véhicule ? + Définit la vitesse de ravitaillement en carburant des véhicules. どのくらいの速さで車両へ給油しますか? 차량이 얼마나 빨리 재급유될 수 있습니까? - 载具多快会加油完毕? + 载具多快会加油完毕? 載具多快會加油完畢? + Bir araca ne kadar hızlı yakıt ikmali yapılmalıdır? + + + Cargo Flow Rate + 화물 주유량 + Caudal de llenado de la carga + 貨物流量 + Portata di Flusso al Carico + Prędkość Tankowania Ładunku + Frachtflussrate + Vitesse de ravitaillement + Скорость заполнения груза + + + How fast should a fuel source's tank be filled? + 연료 공급처의 저장 탱크를 얼마나 빨리 채웁니까? + Cómo de rápido puede llenarse una fuente de combustible. + どのくらいの速さで給油源へ給油しますか? + Quanto velocemente si può rifornire il carico di carburante di un veicolo? + Jak szybko zbiornik paliwa powinien być napełniany? + Wie schnell sollte der Tank einer Kraftstoffquelle gefüllt werden? + A quelle vitesse le réservoir de carburant doit-il être rempli ? + Как быстро должен заполняться бак источника топлива? Refuel @@ -55,11 +80,12 @@ Natankovat Rifornisci Reabastecer - Ravitaillement + Faire le plein 給油 재급유 加油 加油 + Yakıt Doldurma Take fuel nozzle @@ -68,13 +94,14 @@ Взять топливный шланг Pegar o bocal de combustível Vzít výdejní pistoli - Prendi manica benzina + Prendi Pistola Erogatrice Tomar surtidor - Prendre la pompe + Prendre le pistolet 給油ノズルを取る 주유기 획득 - 拿取燃料喷嘴 + 拿取加油枪 拿取燃料噴嘴 + Yakıt Pompasını Al Taking fuel nozzle... @@ -83,13 +110,14 @@ Берем топливный шланг... Pegando o bocal de combustível... Beru výdejní pistoli... - Prendendo manicotto benzina... + Prendendo Pistola Erogatrice... Tomando surtidor... - Prise de la pompe... + Prise du pistolet... 給油ノズルを取っています・・・ - 주유기 획득중... - 拿取燃料喷嘴中... + 주유기 획득 중... + 正在拿取加油枪... 拿取燃料噴嘴中... + Yakıt Pompası Alınıyor... Connect fuel nozzle @@ -98,13 +126,14 @@ Присоединить топливный шланг Conectar o bocal de combustível Připojit výdejní pistoli - Collega manica benzina + Collega Pistola Erogatrice Conectar surtidor - Connecter la pompe + Introduire le pistolet 給油ノズルを接続する 주유기 꼽기 - 连接燃料喷嘴 + 连接加油枪 連接燃料噴嘴 + Yakıt Pompasını Bağla Connecting fuel nozzle... @@ -113,13 +142,14 @@ Присоединяем топливный шланг... Conectando o bocal de combustível... Připojuji výdejní pistoli... - Collegando manicotto benzina... + Collegando Pistola Erogatrice... Conectando surtidor... - Connection de la pompe... + Introduction du pistolet... 給油ノズルを接続しています・・・ - 주유기 꼽는중... - 连结燃料喷嘴中... + 주유기 꼽는 중... + 正在连接加油枪... 連結燃料噴嘴中... + Yakıt Pompası Bağlanıyor... Disconnect fuel nozzle @@ -128,13 +158,14 @@ Отсоединить топливный шланг Desconectar o bocal de combustível Odpojit výdejní pistoli - Scollega manicotto benzina + Scollega Pistola Erogatrice Desconectar surtidor - Déconnecter la pompe + Retirer le pistolet 給油ノズルを外す 주유기 뽑기 - 断开燃料喷嘴 + 断开加油枪 斷開燃料噴嘴 + Yakıt Pompası Çıkar Connect @@ -145,11 +176,12 @@ Připojit Collega Conectar - Connecter + Raccorder 接続 꼽기 - 连结 + 连接 連結 + Bağlan Check remaining fuel @@ -158,13 +190,14 @@ Проверить остаток топлива Verificar combustível restante Zkontrolovat zůstatek paliva - Controlla benzina rimanente + Controlla carburante rimanente Verificar combustible remanente Vérifier le carburant restant 残燃料を見る 남은 연료 확인 检查剩余燃料 檢查剩餘燃料 + Kalan yakıtı kontrol et Checking remaining fuel... @@ -173,13 +206,14 @@ Проверяем остаток топлива... Verificando combustível restante... Kontroluji zůstatek paliva... - Controllando la benzina rimanente... + Controllando carburante rimanente... Verificando combustible remanente,,, - Vérifie le carburant restant... + Vérification du carburant restant... 残燃料を見ています・・・ 남은 연료 확인중... - 检查剩余燃料中... + 正在检查剩余燃料... 檢查剩餘燃料中... + Kalan Yakıt Kontrol Ediliyor... There are %1 liters left. @@ -191,10 +225,11 @@ Sono rimasti %1 litri. Quedan %1 litros. Il reste %1 litres. - 後 %1 リットル残っています。 + あと %1 リットル残っています。 %1 리터 남음 - 剩下%1公升的燃料。 + 剩下%1升的燃料。 剩下%1公升的燃料。 + %1 litre kaldı. There is no fuel left. @@ -203,13 +238,14 @@ Топлива нет. Não há combustível Bez paliva. - Non è rimasta più benzina. + Non c'è alcun carburante rimanente. No queda combustible. Il n'y a plus de carburant. もう燃料は残っていません。 연료 없음. 没有剩余的燃料 沒有剩餘的燃料 + Yakıt Kalmadı Cancel @@ -225,6 +261,7 @@ 취소 取消 取消 + Iptal Failed @@ -235,11 +272,12 @@ Neúspěšný Fallito Falló - Echoué + Échec 失敗 실패 失败 失敗 + Başarısız Stop fueling @@ -248,13 +286,14 @@ Остановить заправку Parar reabastecimento Zastavit tankování - Ferma rifornimento + Interrompi rifornimento Detener reabastecimiento Arrêter le ravitaillement 給油を止める 그만 재급유하기 停止加油 停止加油 + Yakıt Doldurmayı Durdur Start fueling @@ -265,11 +304,23 @@ Začít tankovat Inizia rifornimento Comenzar reabastecimiento - Débute le ravitaillement + Débuter le ravitaillement 給油を始める 재급유 시작 开始加油 開始加油 + Yakıt Doldurmayı Başlat + + + Start fueling (container) + Betankung beginnen (Container) + 연료 재급유 시작 (컨테이너) + Inizia rifornimento (Contenitore) + Iniciando repostado (contenedor) + 給油を始める (コンテナ) + Rozpocznij tankowanie (zbiornik) + Commencer le ravitaillement (container) + Начать заправку топливом (контейнер) Couldn't turn on fuel nozzle @@ -277,10 +328,15 @@ Impossibile iniziare il rifornimento 給油を始められませんでした 無法開啟燃料噴嘴 - 无法开启燃料喷嘴 + 无法开启加油枪 주유기를 켤 수 없습니다. Nie można włączyć dyszy paliwowej Не удалось включить топливный пистолет + Não foi possível ativar o bico de combustível + Impossible de démarrer la pompe + Nepodařilo se zapnout trysku + Yakıt pompası başlatılamadı + No se pudo activar la boquilla de la manguera %1 Liters fueled @@ -291,11 +347,12 @@ %1 litrů natankováno %1 litri riforniti %1 lt reabastecido - %1 litres ravitaillés - %1 リッターを給油しました + %1 litres pompés. + %1 リットル給油した %1 리터 재급유됨 - 已加入%1公升的燃料 + 已加入%1升的燃料 已加入%1公升的燃料 + %1 Litre Dolduruldu The fuel source is empty. @@ -304,13 +361,14 @@ Источник топлива пустой. A fonte de combustível está vazia. Zdroj paliva je prázdný. - La fonte di benzina è vuota. + La fonte di carburante è vuota. La fuente de combustible está vacía. La source de carburant est vide. 給油元は空です。 - 燃料来源已空. + 燃料来源已空。 燃料來源已空. 연료공급처가 비었음. + Yakıt tankı boş. Maximum fuel hose length reached. @@ -319,13 +377,14 @@ Достигнута максимальная длина шланга. Distância máxima da mangueira de combustível alcançada. Dosažena maximální délka hadice - Distanza massima della pompa raggiunta. + Raggiunta lunghezza massima della tubazione. Máxima longitud de manguera alcanzada. - Tuyau tendu au maximum + Tuyau tendu au maximum. 給油ホースはもうこれ以上届きません。 주유기 호스 최대 거리에 도달함. 已加满至最大油量。 已加滿至最大油量。 + Maksimum yakıt hortumu uzunluğuna ulaşıldı. Fueling completed @@ -336,11 +395,12 @@ Tankování dokončeno Rifornimento completato Reabastecimiento completado - Ravitaillement terminé + Ravitaillement terminé. 給油を完了しました 재급유 완료함 加油完毕 加油完畢 + Yakıt Doldurma Tamamlandı Fueling stopped @@ -349,13 +409,14 @@ Заправка остановлена Reabastecimento parado Tankování zastaveno - Rifornimento fermato + Rifornimento interrotto Reabastecimiento detenido - Ravitaillement stoppé + Ravitaillement arrêté. 給油を止めました 재급유 멈춤 已停止加油 已停止加油 + Yakıt Doldurma Durduruldu Fueling started @@ -366,11 +427,12 @@ Tankování zahájeno Rifornimento iniziato Comenzó el reabastecimiento - Ravitaillement débuté + Ravitaillement démarré. 給油を始めました 재급유 시작함 已开始加油 已開始加油 + Yakıt Doldurma Başlatıldı Return fuel nozzle @@ -379,13 +441,14 @@ Вернуть топливный шланг Retornar bocal de combustível Vrátit výdejní pistoli - Riponi manicotto benzina + Riponi Pistola Erogatrice Devolver surtidor - Retourner la pompe + Ranger le pistolet 給油ノズルを戻す 주유기 반환 - 放回燃料喷嘴 + 放回加油枪 放回燃料噴嘴 + Yakıt Pompasını Geri Koy Returning fuel nozzle... @@ -394,13 +457,14 @@ Возвращаем топливный шланг... Retornando bocal de combustível... Vracím výdejní pistoli... - Riponendo la manica della benzina... + Riponendo la Pistola Erogatrice... Devolviendo el surtidor... - Retourne la pompe + Rangement du pistolet... 給油ノズルを戻しています・・・ - 주유기 반환중 - 放回燃料喷嘴中... + 주유기 반환 중 + 正在放回加油枪... 放回燃料噴嘴中... + Yakıt Pompası Geri Koyuluyor Check fuel counter @@ -409,13 +473,14 @@ Проверить счетчик топлива Verificar contador de combustível Zkonrolovat palivoměr - Controlla indicatore livello benzina + Controlla livello carburante Verificar el contador de combustible Vérifier le compteur 燃料計を見る - 연로카운터 확인 + 연료카운터 확인 检查燃料表 檢查燃料表 + Yakıt tankını kontrol et %1 liters have been fueled. @@ -426,68 +491,164 @@ %1 litrů bylo natankováno. %1 litri sono stati riforniti. Se reabastecieron %1 lt - %1 litres ont été écoulés. - %1 リッターが給油されました。 + %1 litres ont été pompés. + %1 リットル給油されました。 %1 리터가 재급유되었습니다. - 已加入%1公升 + 已加入%1升 已加入%1公升 + %1 litre dolduruldu + + + Pick up fuel canister + Treibstoffkanister aufheben + Raccogli contenitore di carburante + 燃料キャニスターを持つ + 연료통 집어들기 + Взять канистру с топливом + Ramasser le réservoir de carburant + Coger garrafa de combustible + + + Picking fuel canister up... + Hebe Treibstoffkanister auf... + Raccogliendo contenitore di carburante... + 燃料キャニスターを持ち上げています・・・ + 연료통 집어드는 중... + Поднимаю канистру с топливом... + Ramasser les bidons de carburant... + Cogiendo garrafa de combustible... + + + Connect fuel canister + Treibstoffkanister anschließen + Collega contenitore di carburante + 燃料キャニスターを接続する + 연료통 꽂기 + Подсоединить канистру с топливом + Raccorder le réservoir de carburant + Conectar garrafa de combustible + + + Connecting fuel canister... + Schließe Treibstoffkanister an... + Collegando contenitore di carburante... + 燃料キャニスターを接続しています・・・ + 연료통 꽂는 중... + Подсоединение топливной канистры... + Raccorder le réservoir de carburant... + Conectando garrafa de combustible... + + + Disconnect fuel canister + Treibstoffkanister lösen + Scollega contenitore di carburante + 燃料キャニスターを外します + 연료통 빼기 + Отсоединить канистру с топливом + Débrancher le réservoir de carburant + Desconectar garrafa de combustible Refuel hose length Betankung Schlauchlänge Reabastecer longitud de manguera - Rifiuta lungezza tubo + Lunghezza tubazione di rifornimento 給油ホースの長さ 加油软管长度 加油軟管長度 Długość węża paliwowego 주유기 호스 길이 Длина заправочного шланга + Comprimento da Mangueira de Combustível + Longueur du tuyau + Délka hadice na palivo + Yakıt hortumu uzunluğu + + + Pump/Hose Interaction Time + Pompa/Hortum Etkileşim Süresi + 펌프/호스 상호작용 시간 + Время взаимодействия со шлангом + Tiempo de interacción con la Bomba/Manguera + Tempo di interazione Pompa/Pistola + ポンプ/ホースのインタラクション所要時間 + Czas Interakcji z Pompą/Wężem + Interaktionszeit zwischen Pumpe und Schlauch + Temps d'interaction pompe/tuyau + + + How long refuel interactions take in seconds. + Saniye biriminde yakıt ikmali etkileşimlerinin süresi. + 연료 재보급 상호작용에 걸리는 시간(초)입니다. + Время в секундах, которое занимает взаимодействие со шлангом. + Cuanto tiempo en segundos tardan las interacciones de repostado. + Durata delle interazioni in secondi. + 燃料補給に掛かる時間。 (秒単位) + Jak długo powinna trwać interakcja tankowania w sekundach. + Wie lange Auftank-Interaktionen in Sekunden dauern. + Durée des interactions de ravitaillement en secondes. Fuel Cargo Volume Tankvolumen Объем топлива для заправки - 貯油量 - Capacità Carburante Cargo + 給油用燃料積載量 + Capacità di Carico Carburante 儲油量 储油量 연료통 크기 Pojemność Ładunku Paliwa + Capacidade de Combustível + Volume de la citerne + Objem palivové cisterny + Doldurma Hız + Volumen del depósito The fuel volume available for refueling (-1 disable, -10 if infinite) Das Tankvolumen, welches zum Nachtanken verfügbar ist (-1 deaktiviert, -10 unendlich) Объем топлива, доступный для заправки других машин (-1 отключить, -10 если неограничен) - 給油用の貯油量を設定できます (-1で無効、-10で無限) - La capacità del carburante disponibile per il rifornimento (-1 disabilita, -10 se infinito) + 給油に使用する燃料の積載量 (-1で補給無効、-10で無限補給) + La capacità di carburante disponibile al rifornimento altrui (-1 disabilita, -10 se infinito) 設定有多少油料可供載具進行加油(-1時關閉,-10為無限油量) - 设定有多少油料可供载具进行加油(-1时关闭,-10为无限油量) - 재급유에 사용 할 수 있는 연료량 (-1=비활성, -10=무한) + 设定有多少油料可供载具进行加油(-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) + Le volume de carburant disponible pour le ravitaillement (-1 pour désactiver, -10 pour quantité illimitée). + Objem paliva k tankování (-1 pro vypnutí, -10 pro nekonečno) + El volumen de combustible disponible para llenar (-1 desactivado, -10 es infinito) Refuel Hose attach coordinates Befestigungskoordinaten der Zapfpistole Координаты крепления шланга 給油ノズルの取り付け座標 - Coordinate del tubo di rifornimento + Coordinate di attacco tubazione 加油軟管安裝位置 加油软管安装位置 재급유기 부착 좌표 Koordynaty przyłączenia węża paliwowego + Coords. do encaixe para Mangueira + Coordonnées du pistolet + Souřadnice pro připojení hadice na palivo + Coordenadas de la boquilla de la manguera Model coordinates used to attach refuel hose Modelkoordinaten zum Anheften der Zapfpistole Координаты модели, куда крепится заправочный шланг 給油ノズルの取り付けにモデル座標を使用します - Coordinate del modello utilizzate per il fissaggio del tubo + Coordinate del modello utilizzate per l'attacco della tubazione di rifornimento 設定加油軟管會安裝到模型的哪個位置上 设定加油软管会安装到模型的哪个位置上 재급유기 부착에 쓰이는 모델 좌표 Modelowe koordynaty wykorzystane do przyłączenia węża paliwowego + As coordenadas do modelo usado para conectar a mangueira ao veículo + Coordonnées du modèle 3D où est attaché le tuyau ravitaillement. + Souřadnice na modelu pro připojení hadice na palivo. + Coordenadas del modelo usado para la boquilla de la manguera diff --git a/addons/reload/ACE_Arsenal_Stats.hpp b/addons/reload/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..8311a62632 --- /dev/null +++ b/addons/reload/ACE_Arsenal_Stats.hpp @@ -0,0 +1,13 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_isBelt: statBase { + scope = 2; + priority = -1; + stats[] = {"ACE_isBelt"}; + displayName = CSTRING(LinkBelt); + showText = 1; + textStatement = QUOTE(localize QUOTE(ELSTRING(Common,Enabled))); + condition = QUOTE(params[ARR_2('_stat','_config')]; (getNumber (_config >> _stat select 0)) == 1); + tabs[] = {{}, {4}}; + }; +}; diff --git a/addons/reload/ACE_Settings.hpp b/addons/reload/ACE_Settings.hpp index 82e9f32637..c08d45babb 100644 --- a/addons/reload/ACE_Settings.hpp +++ b/addons/reload/ACE_Settings.hpp @@ -1,10 +1,5 @@ class ACE_Settings { class GVAR(displayText) { - category = ECSTRING(common,ACEKeybindCategoryWeapons); - typeName = "BOOL"; - isClientSettable = 1; - value = 1; - displayName = CSTRING(SettingDisplayTextName); - description = CSTRING(SettingDisplayTextDesc); + movedToSQF = 1; }; }; diff --git a/addons/reload/ACE_UI.hpp b/addons/reload/ACE_UI.hpp index cfc2a26f9c..6dae3e5147 100644 --- a/addons/reload/ACE_UI.hpp +++ b/addons/reload/ACE_UI.hpp @@ -1,7 +1,7 @@ class ACE_UI { class ammoCount { class conditions { - ADDON = "cameraOn == (getConnectedUAV ACE_player)"; + ADDON = "false"; }; }; }; diff --git a/addons/reload/CfgActions.hpp b/addons/reload/CfgActions.hpp index a76be64ba3..acadf95385 100644 --- a/addons/reload/CfgActions.hpp +++ b/addons/reload/CfgActions.hpp @@ -1,6 +1,6 @@ class CfgActions { class LoadMagazine; - class LoadEmptyMagazine : LoadMagazine { + class LoadEmptyMagazine: LoadMagazine { showWindow = 0; textDefault = ""; }; diff --git a/addons/reload/CfgEventHandlers.hpp b/addons/reload/CfgEventHandlers.hpp index 25731670fa..f76ea983d1 100644 --- a/addons/reload/CfgEventHandlers.hpp +++ b/addons/reload/CfgEventHandlers.hpp @@ -1,26 +1,25 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_Take_EventHandlers { class CAManBase { class ACE_AmmoIndicatorReload { - clientTake = QUOTE(params ['_unit']; if (_unit == ACE_player && {GVAR(DisplayText)} && {(_this select 1) in [ARR_3(uniformContainer _unit, vestContainer _unit, backpackContainer _unit)]} && {_this select 2 == currentMagazine _unit}) then {[ARR_2(_unit, vehicle _unit)] call FUNC(displayAmmo)};); + clientTake = QUOTE(_this call FUNC(onTake)); }; }; }; diff --git a/addons/reload/CfgMagazines.hpp b/addons/reload/CfgMagazines.hpp index 965bc3c225..e7a7d8e041 100644 --- a/addons/reload/CfgMagazines.hpp +++ b/addons/reload/CfgMagazines.hpp @@ -12,6 +12,9 @@ class CfgMagazines { class 150Rnd_93x64_Mag: CA_Magazine { // Mag for HK121 (MMG_01) [DLC Opfor Heavy Gunner] ACE_isBelt = 1; }; + class 10Rnd_93x64_DMR_05_Mag: 150Rnd_93x64_Mag { // Mag for Cyrus (DMR_05) [DLC Opfor Sharpshooter] + ACE_isBelt = 0; + }; class 130Rnd_338_Mag: CA_Magazine { // Mag for LWMMG (MMG_02) [DLC Blufor Heavy Gunner] ACE_isBelt = 1; }; diff --git a/addons/reload/CfgVehicles.hpp b/addons/reload/CfgVehicles.hpp index fe1e9672e6..5a05f03734 100644 --- a/addons/reload/CfgVehicles.hpp +++ b/addons/reload/CfgVehicles.hpp @@ -1,18 +1,29 @@ class CfgVehicles { class Man; class CAManBase: Man { + class ACE_SelfActions { + class ACE_Equipment { + class GVAR(checkAmmo) { + displayName = CSTRING(checkAmmo); + condition = QUOTE(GVAR(showCheckAmmoSelf) && {_player call FUNC(canCheckAmmoSelf)}); + statement = QUOTE(call FUNC(checkAmmo)); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; + }; + }; + }; + class ACE_Actions { class ACE_Weapon { - class GVAR(LinkBelt) { - displayName = CSTRING(LinkBelt); - distance = 2.0; - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(getAmmoToLinkBelt)) > 0); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(startLinkingBelt)); + class GVAR(linkBelt) { + displayName = CSTRING(linkBelt); + distance = 2; + condition = QUOTE(([ARR_2(_player,_target)] call FUNC(getAmmoToLinkBelt)) > 0); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(startLinkingBelt)); exceptions[] = {"isNotInside"}; }; - class GVAR(CheckAmmo) { + class GVAR(checkAmmo) { displayName = CSTRING(checkAmmo); - distance = 2.0; + distance = 2; condition = QUOTE(call FUNC(canCheckAmmo)); statement = QUOTE(call FUNC(checkAmmo)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; @@ -25,14 +36,57 @@ class CfgVehicles { class StaticWeapon: LandVehicle { class ACE_Actions { class ACE_MainActions { - class GVAR(CheckAmmo) { + class GVAR(checkAmmo) { displayName = CSTRING(checkAmmo); - distance = 2.0; + distance = 2; condition = QUOTE(call FUNC(canCheckAmmo)); statement = QUOTE(call FUNC(checkAmmo)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; }; }; }; + + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; + }; + + class Tank: LandVehicle { + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; + }; + + class Car: LandVehicle { + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; + }; + + class Air; + class Helicopter: Air { + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; }; }; diff --git a/addons/reload/CfgWeapons.hpp b/addons/reload/CfgWeapons.hpp new file mode 100644 index 0000000000..0d52ae8f5c --- /dev/null +++ b/addons/reload/CfgWeapons.hpp @@ -0,0 +1,16 @@ +class CfgWeapons { + class HMG_01; + class HMG_static: HMG_01 { + type = 1; // makes it possible to swap to the fullest magazine + }; + + class GMG_F; + class GMG_20mm: GMG_F { + type = 1; + }; + + class CannonCore; + class mortar_82mm: CannonCore { + type = 1; + }; +}; diff --git a/addons/reload/README.md b/addons/reload/README.md index 6eca14fdd7..4e8031265e 100644 --- a/addons/reload/README.md +++ b/addons/reload/README.md @@ -2,11 +2,3 @@ ace_reload ========== Hides the default reload indicators, making it necessary to manually check your magazine. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/reload/XEH_PREP.hpp b/addons/reload/XEH_PREP.hpp index f2b386ac37..1a62a9f5bd 100644 --- a/addons/reload/XEH_PREP.hpp +++ b/addons/reload/XEH_PREP.hpp @@ -1,6 +1,9 @@ - PREP(canCheckAmmo); +PREP(canCheckAmmoSelf); +PREP(canSwapTurretMagazine); PREP(getAmmoToLinkBelt); PREP(checkAmmo); PREP(displayAmmo); +PREP(onTake); PREP(startLinkingBelt); +PREP(swapTurretMagazine); diff --git a/addons/reload/XEH_postInit.sqf b/addons/reload/XEH_postInit.sqf index 3e1b95f9bf..a219efed0a 100644 --- a/addons/reload/XEH_postInit.sqf +++ b/addons/reload/XEH_postInit.sqf @@ -1,63 +1,70 @@ // by esteldunedain #include "script_component.hpp" -if (!hasInterface) exitWith {}; - -// Add keybinds -["ACE3 Weapons", QGVAR(checkAmmo), localize LSTRING(checkAmmo), { - // Conditions: canInteract - if !([ACE_player, vehicle ACE_player, ["isNotInside", "isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if !(ACE_player call CBA_fnc_canUseWeapon || {(vehicle ACE_player) isKindOf "StaticWeapon"}) exitWith {false}; - // Ignore if controlling UAV (blocks radar keybind) - if (!isNull (ACE_controlledUAV param [0, objNull])) exitWith {false}; - - // Statement - [ACE_player, ACE_player] call FUNC(checkAmmo); - true -}, {false}, [19, [false, true, false]], false] call CBA_fnc_addKeybind; - +// To propagate the setAmmo change, do it on all clients +// See https://github.com/acemod/ACE3/issues/1119 and https://feedback.bistudio.com/T167015 [QGVAR(syncAmmo), { - //To propagate the setAmmo change, do it on all clients params ["_unit", "_weapon", "_ammo"]; TRACE_3("syncAmmo EH",_unit,_weapon,_ammo); - _unit setAmmo [_weapon, _ammo]; }] call CBA_fnc_addEventHandler; // Listen for attempts to link ammo [QGVAR(ammoLinked), { - params ["_receiver", "_giver", "_magazine"]; - - private _magazineType = currentMagazine _receiver; - private _magazineCfg = configFile >> "CfgMagazines" >> _magazineType; + params ["_target", "_unit", "_magazineInfo"]; + _magazineInfo params ["_magazine", "_ammo"]; // Return the magazine if it's the wrong type - if (_magazineType != (_magazine select 0)) exitWith { - [QGVAR(ammoReturned), [_giver,_receiver,_magazine], [_giver]] call CBA_fnc_targetEvent; + if (currentMagazine _target != _magazine) exitWith { + [QGVAR(ammoReturned), [_unit, _target, _magazineInfo, false], _unit] call CBA_fnc_targetEvent; }; - private _ammoCount = _receiver ammo currentWeapon _receiver; - private _ammoMissing = getNumber (_magazineCfg >> "count") - _ammoCount; + private _currentWeapon = currentWeapon _target; + private _currentAmmo = _target ammo _currentWeapon; + private _magazineCfg = configFile >> "CfgMagazines" >> _magazine; + private _ammoMissing = getNumber (_magazineCfg >> "count") - _currentAmmo; // Return the magazine if the belt is full or empty - if ((_ammoCount == 0) || _ammoMissing == 0) exitWith { - [QGVAR(ammoReturned), [_giver,_receiver,_magazine], [_giver]] call CBA_fnc_targetEvent; + if (_currentAmmo == 0 || {_ammoMissing == 0}) exitWith { + [QGVAR(ammoReturned), [_unit, _target, _magazineInfo, false], _unit] call CBA_fnc_targetEvent; }; // Add the ammo - private _ammoAdded = _ammoMissing min (_magazine select 1); - [QGVAR(syncAmmo), [_receiver, currentWeapon _receiver, _ammoCount + _ammoAdded]] call CBA_fnc_globalEvent; + private _ammoAdded = _ammoMissing min _ammo; + [QGVAR(syncAmmo), [_target, _currentWeapon, _currentAmmo + _ammoAdded]] call CBA_fnc_globalEvent; - if ((_magazine select 1) - _ammoAdded > 0) then { - [QGVAR(ammoReturned), [_giver, _receiver, [_magazineType, (_magazine select 1) - _ammoAdded]], [_giver]] call CBA_fnc_targetEvent; + // Return left over ammo to reloading unit + if (_ammo - _ammoAdded > 0) then { + [QGVAR(ammoReturned), [_unit, _target, [_magazine, _ammo - _ammoAdded], true], _unit] call CBA_fnc_targetEvent; }; }] call CBA_fnc_addEventHandler; // Listen for returned magazines [QGVAR(ammoReturned), { - params ["_receiver", "", "_magazine"]; - TRACE_2("ammoReturned EH",_receiver,_magazine); + params ["_unit", "_target", "_magazineInfo", "_success"]; + TRACE_3("ammoReturned EH",_unit,_target,_magazineInfo); - _receiver addMagazine _magazine; + // If inventory is full, magazine will be dropped on the ground + [_unit, _magazineInfo select 0, _magazineInfo select 1, true] call CBA_fnc_addMagazine; + + [[LSTRING(BeltNotLinked), LSTRING(BeltLinked)] select _success] call EFUNC(common,displayTextStructured); }] call CBA_fnc_addEventHandler; + +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" + +// Reload when default reload keybind is pressed +addUserActionEventHandler ["ReloadMagazine", "Activate", { + private _vehicle = objectParent ACE_player; + + // If on foot, skip + if (isNull _vehicle) exitWith {}; + + // weaponState is only updated after 3 frames, so wait to run checks in case we're doing an engine reload at the same time + [{ + if !(_this call FUNC(canSwapTurretMagazine)) exitWith {}; + + _this call FUNC(swapTurretMagazine); + }, [_vehicle, ACE_player], 3] call CBA_fnc_execAfterNFrames; +}]; diff --git a/addons/reload/XEH_preInit.sqf b/addons/reload/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/reload/XEH_preInit.sqf +++ b/addons/reload/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/reload/config.cpp b/addons/reload/config.cpp index 21e28d35f5..f4871f1354 100644 --- a/addons/reload/config.cpp +++ b/addons/reload/config.cpp @@ -14,9 +14,11 @@ class CfgPatches { }; }; -#include "CfgVehicles.hpp" -#include "CfgMagazines.hpp" -#include "CfgEventHandlers.hpp" #include "CfgActions.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" +#include "ACE_Arsenal_Stats.hpp" #include "ACE_Settings.hpp" #include "ACE_UI.hpp" diff --git a/addons/reload/functions/fnc_canCheckAmmo.sqf b/addons/reload/functions/fnc_canCheckAmmo.sqf index 9632d0b4b1..96b9f88d50 100644 --- a/addons/reload/functions/fnc_canCheckAmmo.sqf +++ b/addons/reload/functions/fnc_canCheckAmmo.sqf @@ -1,13 +1,13 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: CAA-Picard - * Check if the player can check the ammo of the target. + * Author: CAA-Picard, johnb43 + * Check if a unit can check the ammo of the target. * * Arguments: - * 0: Target + * 0: Unit equipped with the weapon * * Return Value: - * Can link belt + * Can check ammo * * Example: * [cursorObject] call ace_reload_fnc_canCheckAmmo @@ -17,26 +17,18 @@ params ["_target"]; -// Return true for static weapons if they have been fired once, @todo 1.40 this work-around doesn't work anymore +// Static weapons if (_target isKindOf "StaticWeapon") exitWith { - if (currentMagazine _target != "") exitWith {true}; - - // no check ammo action on destroyed static weapons + // No check ammo action on destroyed static weapons if (!alive _target) exitWith {false}; - private _found = false; + if (currentMagazine _target != "") exitWith {true}; - { - if (_x select 2) exitWith { - _found = true; - }; - false - } count magazinesAmmoFull _target; - - _found + // Check for loaded magazines + (magazinesAmmoFull _target) findIf {_x select 2} != -1 }; -// Return false for all other vehicles +// All other vehicles if !(_target isKindOf "CAManBase") exitWith {false}; // For men diff --git a/addons/reload/functions/fnc_canCheckAmmoSelf.sqf b/addons/reload/functions/fnc_canCheckAmmoSelf.sqf new file mode 100644 index 0000000000..0427fb33e1 --- /dev/null +++ b/addons/reload/functions/fnc_canCheckAmmoSelf.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Check if the player can check his own ammo. + * + * Arguments: + * 0: Player + * + * Return Value: + * Can check ammo for self + * + * Example: + * [player] call ace_reload_fnc_canCheckAmmoSelf + * + * Public: No + */ + +params ["_player"]; + +_player call CBA_fnc_canUseWeapon && {currentWeapon _player != ""} && {!((vehicle _player) isKindOf "StaticWeapon")} diff --git a/addons/reload/functions/fnc_canSwapTurretMagazine.sqf b/addons/reload/functions/fnc_canSwapTurretMagazine.sqf new file mode 100644 index 0000000000..114a124776 --- /dev/null +++ b/addons/reload/functions/fnc_canSwapTurretMagazine.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, johnb43 + * Check if the player can reload their vehicle's magazine to one with more ammo. + * + * Arguments: + * 0: Vehicle + * 1: Player + * + * Return Value: + * Can swap turret magazine + * + * Example: + * [vehicle player, player] call ace_reload_fnc_canSwapTurretMagazine + * + * Public: No + */ + +params ["_vehicle", "_unit"]; +TRACE_2("canSwapTurretMagazine",_vehicle,_unit); + +private _turretPath = _vehicle unitTurret _unit; +if (_turretPath in [[-1], []]) exitWith {false}; // skip driver / cargo +if !(_vehicle turretLocal _turretPath) exitWith {false}; // just to be safe + +(weaponState [_vehicle, _turretPath]) params ["_weapon", "_muzzle", "", "_magazine", "_ammoCount", "_roundReloadPhase", "_magazineReloadPhase"]; +TRACE_5("",_weapon,_muzzle,_magazine,_ammoCount,typeOf _vehicle); + +if ((_weapon == "") || {_weapon != _muzzle}) exitWith {false}; // skip multi-muzzle (he/ap auto-cannons) +if (_magazine == "") exitWith {false}; +if (_roundReloadPhase + _magazineReloadPhase != 0) exitWith {false}; // can't reload while already reloading or while shooting +if (isText (configFile >> "CfgMagazines" >> _magazine >> "pylonWeapon")) exitWith {false}; +if (getNumber (configFile >> "CfgWeapons" >> _weapon >> "type") % 2 == 1) exitWith {false}; // engine support for magazine swapping + +private _maxAmmo = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); +if ((_ammoCount == 0) || {_ammoCount == _maxAmmo}) exitWith {false}; + +private _magAmmoCounts = []; + +// Get count of rounds in magazines +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if ((_xMag == _magazine) && {_xTurret isEqualTo _turretPath}) then { + _magAmmoCounts pushBack _xAmmo; + }; +} forEach (magazinesAllTurrets _vehicle); + +TRACE_1("",_magAmmoCounts); + +// Select maximum +(selectMax _magAmmoCounts) > _ammoCount diff --git a/addons/reload/functions/fnc_checkAmmo.sqf b/addons/reload/functions/fnc_checkAmmo.sqf index 8239dfcde7..f558d91769 100644 --- a/addons/reload/functions/fnc_checkAmmo.sqf +++ b/addons/reload/functions/fnc_checkAmmo.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain - * Count the ammo of the currently loaded magazine or count rifle grenades. Play animation and display message. + * Author: commy2, esteldunedain + * Play animation and display message. * * Arguments: - * 0: Target. - * 1: Player + * 0: Unit equipped with the weapon + * 1: Unit wanting to check the ammo * * Return Value: * None @@ -16,13 +16,14 @@ * Public: No */ -params ["_target", "_player"]; +params ["_target", "_unit"]; -if (_player == _target) then { +if (_unit == _target) then { if ((vehicle _target) isKindOf "StaticWeapon") then { _target = vehicle _target; }; + [_unit, "Gear", 1] call EFUNC(common,doGesture); }; -[FUNC(displayAmmo), [_target], 1] call CBA_fnc_waitAndExecute; +[FUNC(displayAmmo), _target, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/reload/functions/fnc_displayAmmo.sqf b/addons/reload/functions/fnc_displayAmmo.sqf index 9b018131d4..68e176587a 100644 --- a/addons/reload/functions/fnc_displayAmmo.sqf +++ b/addons/reload/functions/fnc_displayAmmo.sqf @@ -1,16 +1,16 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain + * Author: commy2, esteldunedain * Display the ammo of the currently loaded magazine of the target or count rifle grenades. * * Arguments: - * 0: Target + * 0: Unit equipped with the weapon * * Return Value: * None * * Example: - * [bob] call ace_reload_fnc_displayAmmo + * [player] call ace_reload_fnc_displayAmmo * * Public: No */ @@ -19,77 +19,92 @@ params ["_target"]; -private _weapon = currentWeapon _target; -private _muzzle = currentMuzzle _target; -private _magazine = currentMagazine _target; +private _isStaticWeapon = _target isKindOf "StaticWeapon"; + +// currentWeapon, currentMagazine and weaponState return "" for static weapons before they have been entered once +(if (_isStaticWeapon) then { + private _weapon = currentWeapon _target; -// currentWeapon returns "" for static weapons before they are shot once -if (_target isKindOf "StaticWeapon") then { if (_weapon == "") then { - if (count (weapons _target) == 1) then { - _weapon = (weapons _target) select 0; - _muzzle = _weapon; + private _weapons = weapons _target; + + if (count _weapons == 1) then { + _weapon = _weapons select 0; }; }; + private _magazine = currentMagazine _target; + if (_magazine == "") then { // Try to get magazine using magazinesAmmoFull - private _magazines = magazinesAmmoFull _target; - { if (_x select 2) exitWith { _magazine = _x select 0; }; - } forEach _magazines; + } forEach magazinesAmmoFull _target; + }; + + // currentMuzzle always returns "" + [_weapon, _weapon, "", _magazine] +} else { + weaponState _target +}) params ["_weapon", "_muzzle", "", "_magazine"]; + +TRACE_3("",_weapon,_muzzle,_magazine); + +if ("" == _weapon) exitWith {}; + +private _ammo = _target ammo _muzzle; +private _magazineCfg = configFile >> "CfgMagazines" >> _magazine; +private _maxRounds = getNumber (_magazineCfg >> "count") max 1; +private _count = -1; // Show a count instead of ammo bars (ignore if -1) + +// If secondary muzzle is selected or no magazine in current muzzle +if (_muzzle != _weapon || {_magazine == ""}) then { + // Check if no or empty magazine; If true, just show count of compatible magazines + if (_ammo == 0) exitWith { + _magazine = ""; // Make sure, as it could also be secondary muzzle being selected + + private _compatibleMagazines = compatibleMagazines [_weapon, _muzzle]; + + _count = {_x in _compatibleMagazines} count (magazines _target); + }; + + // singleShot, so show count of identical mags available instead of ammo bars + if (_ammo > 0 && {_maxRounds == 1}) exitWith { + _count = 1 + ({_x == _magazine} count (magazines _target)); }; }; -if (_magazine == "") exitWith {}; -if (_weapon == "") exitWith {}; -if (!( _muzzle isEqualType "")) then {_muzzle = _weapon}; - -private _showNumber = false; -private _ammo = 0; -private _maxRounds = 1; -private _count = 0; - -// not grenade launcher -if (_muzzle == _weapon) then { - _maxRounds = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count") max 1; - - _ammo = _target ammo _weapon; +private _ammoBarsStructuredText = if (_count >= 0) then { + parseText format ["%1x", _count] +} else { if (_maxRounds >= COUNT_BARS) then { _count = round (COUNT_BARS * _ammo / _maxRounds); - if (_ammo > 0) then {_count = _count max 1}; - if (_ammo < _maxRounds) then {_count = _count min (COUNT_BARS - 1)}; + if (_ammo > 0) then { + _count = _count max 1; + }; + + if (_ammo < _maxRounds) then { + _count = _count min (COUNT_BARS - 1); + }; } else { _count = _ammo; }; - // grenade launcher -} else { - _showNumber = true; - - _count = if (_magazine != "") then { - {_x == _magazine} count (magazines _target + [_magazine]) - } else { - {_x in getArray (configFile >> "CfgWeapons" >> _weapon >> _muzzle >> "Magazines")} count magazines _target - }; -}; - -private _ammoBarsStructuredText = if (_showNumber) then { - parseText format ["%1x", _count] -} else { - private _color = [((2 * (1 - _ammo / _maxRounds)) min 1), ((2 * _ammo / _maxRounds) min 1), 0]; + private _color = [(2 * (1 - _ammo / _maxRounds)) min 1, (2 * _ammo / _maxRounds) min 1, 0]; private _string = ""; + for "_a" from 1 to _count do { _string = _string + "|"; }; + private _text = [_string, _color] call EFUNC(common,stringToColoredText); _string = ""; + for "_a" from (_count + 1) to (_maxRounds min COUNT_BARS) do { _string = _string + "|"; }; @@ -97,14 +112,23 @@ private _ammoBarsStructuredText = if (_showNumber) then { composeText [_text, [_string, "#808080"] call EFUNC(common,stringToColoredText)]; }; +if (_isStaticWeapon) then { + // Vehicle mags usually don't have pictures, so just show the text above ammo count + private _loadedName = getText (_magazineCfg >> "displayNameShort"); + + if (_loadedName == "") then { + _loadedName = getText (_magazineCfg >> "displayName"); + }; -if (_target isKindOf "StaticWeapon") then { - //Vehicle mags (usualy) don't have pictures, so just show the text above ammo count - private _loadedName = getText (configFile >> "CfgMagazines" >> _magazine >> "displaynameshort"); _loadedName = parseText format ["%1", _loadedName]; + private _text = composeText [_loadedName, linebreak, _ammoBarsStructuredText]; [_text] call EFUNC(common,displayTextStructured); } else { - private _picture = getText (configFile >> "CfgMagazines" >> _magazine >> "picture"); - [_ammoBarsStructuredText, _picture] call EFUNC(common,displayTextPicture); + if (_magazine != "") then { + private _picture = getText (_magazineCfg >> "picture"); + [_ammoBarsStructuredText, _picture] call EFUNC(common,displayTextPicture); + } else { + [_ammoBarsStructuredText, 1] call EFUNC(common,displayTextStructured); + }; }; diff --git a/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf b/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf index 3701b32d8b..60bfdd918a 100644 --- a/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf +++ b/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf @@ -1,11 +1,11 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain, phyma - * Check if the target has an MG equiped with belt system that the player can link + * Check if the target has an MG equipped with belt system that a unit can link. * * Arguments: - * 0: Player - * 1: Target + * 0: Unit wanting to link the belt + * 1: Unit equipped with the weapon * * Return Value: * Maximum ammo of magazine (-1 on error) @@ -16,12 +16,12 @@ * Public: No */ -params ["_player", "_target"]; +params ["_unit", "_target"]; -if (vehicle _target != _target) exitWith {-1}; +if !(isNull objectParent _target) exitWith {-1}; -private _magazineType = currentMagazine _target; -private _magazineCfg = configFile >> "CfgMagazines" >> _magazineType; +private _magazine = currentMagazine _target; +private _magazineCfg = configFile >> "CfgMagazines" >> _magazine; if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {-1}; @@ -29,14 +29,13 @@ if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {-1}; private _ammoCount = _target ammo currentWeapon _target; // Exit if the belt is full or empty -if (_ammoCount == 0 || getNumber (_magazineCfg >> "count") - _ammoCount == 0) exitWith {-1}; +if (_ammoCount == 0 || {getNumber (_magazineCfg >> "count") - _ammoCount == 0}) exitWith {-1}; -// Check if the player has any of the same magazines -// Calculate max ammo +// Check if the unit has any of the same magazines and calculate max ammo private _maxAmmo = 0; { _maxAmmo = _maxAmmo max (_x select 1); -} forEach (magazinesAmmo _player select {_x select 0 == _magazineType}); +} forEach (magazinesAmmo _unit select {(_x select 0) == _magazine}); _maxAmmo diff --git a/addons/reload/functions/fnc_onTake.sqf b/addons/reload/functions/fnc_onTake.sqf new file mode 100644 index 0000000000..b3312c888c --- /dev/null +++ b/addons/reload/functions/fnc_onTake.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: jokoho48 + * Called from "Take" EH. + * + * Arguments: + * 0: Unit + * 1: Container + * 2: Item + * + * Return Value: + * None + * + * Example: + * [player, backpackContainer player, "ACE_Banana"] call ace_reload_fnc_onTake + * + * Public: No + */ + +params ["_unit", "_container", "_item"]; + +if ( + _unit == ACE_player && + {GVAR(displayText)} && + {_item == currentMagazine _unit} && + {_container in [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]} +) then { + _unit call FUNC(displayAmmo); +}; diff --git a/addons/reload/functions/fnc_startLinkingBelt.sqf b/addons/reload/functions/fnc_startLinkingBelt.sqf index 54fc1921d7..3c116c1532 100644 --- a/addons/reload/functions/fnc_startLinkingBelt.sqf +++ b/addons/reload/functions/fnc_startLinkingBelt.sqf @@ -1,58 +1,59 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: esteldunedain - * Start linking the belt + * Author: esteldunedain, johnb43 + * Start linking the belt. * * Arguments: - * 0: Player - * 1: Target + * 0: Unit linking the belt + * 1: Unit equipped with the weapon * * Return Value: * None * * Example: - * [bob, kevin] call ace_reload_fnc_startLinkingBelt + * [player, cursorTarget] call ace_reload_fnc_startLinkingBelt * * Public: No */ -params ["_player", "_target"]; +params ["_unit", "_target"]; -if (vehicle _target != _target) exitWith {false}; +if !(isNull objectParent _target) exitWith {false}; -private _magazineType = currentMagazine _target; +private _magazine = currentMagazine _target; +private _ammo = [_unit, _target] call FUNC(getAmmoToLinkBelt); - -private _maxAmmo = [_player, _target] call FUNC(getAmmoToLinkBelt); - -//if _maxAmmo is below 0 we quit -if (_maxAmmo <= 0) exitWith {}; +// If _ammo is below 0 we quit +if (_ammo <= 0) exitWith {}; // Condition to call each frame private _condition = { - (_this select 0) params ["_player", "_target"]; - ([_player, _target, []] call EFUNC(common,canInteractWith)) && ((_player distance _target) < 3) && ((speed _target) < 1) + (_this select 0) params ["_unit", "_target"]; + + ([_unit, _target, []] call EFUNC(common,canInteractWith)) && {(_unit distance _target) < 3} && {(speed _target) < 1} }; private _onFinish = { - (_this select 0) params ["_player", "_target", "_magazine"]; + (_this select 0) params ["_unit", "_target", "_magazineInfo"]; + + // Remove the magazine with given remaining ammo; If not possible, quit + if !([_unit, _magazineInfo select 0, _magazineInfo select 1] call EFUNC(common,removeSpecificMagazine)) exitWith { + [LSTRING(BeltNotLinked)] call EFUNC(common,displayTextStructured); + }; // Raise event on remote unit - [QGVAR(ammoLinked), [_target, _player, _magazine], [_target]] call CBA_fnc_targetEvent; + [QGVAR(ammoLinked), [_target, _unit, _magazineInfo], _target] call CBA_fnc_targetEvent; }; private _onFailure = { - (_this select 0) params ["_player", "_target", "_magazine"]; - [_player, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + (_this select 0) params ["_unit"]; - // Add back the magazine with the former ammo count - _player addMagazine _magazine; + [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + + [LSTRING(BeltNotLinked)] call EFUNC(common,displayTextStructured); }; -[_player, "PutDown"] call EFUNC(common,doGesture); - -// Remove the magazine with maximum remaining ammo -[_player, _magazineType, _maxAmmo] call EFUNC(common,removeSpecificMagazine); +[_unit, "PutDown"] call EFUNC(common,doGesture); // Call progress bar -[4, [_player, _target, [_magazineType, _maxAmmo]], _onFinish, _onFailure, (localize LSTRING(LinkingBelt)), _condition, ["isNotInside"]] call EFUNC(common,progressBar); +[4, [_unit, _target, [_magazine, _ammo]], _onFinish, _onFailure, LLSTRING(LinkingBelt), _condition, ["isNotInside"]] call EFUNC(common,progressBar); diff --git a/addons/reload/functions/fnc_swapTurretMagazine.sqf b/addons/reload/functions/fnc_swapTurretMagazine.sqf new file mode 100644 index 0000000000..c4574398d1 --- /dev/null +++ b/addons/reload/functions/fnc_swapTurretMagazine.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, johnb43 + * Reloads a vehicles turret to a new magazine. + * + * Arguments: + * 0: Vehicle + * 1: Player + * + * Return Value: + * None + * + * Example: + * [vehicle player, player] call ace_reload_fnc_swapTurretMagazine + * + * Public: No + */ + +params ["_vehicle", "_unit"]; +TRACE_2("swapTurretMagazine",_vehicle,_unit); + +private _turretPath = _vehicle unitTurret _unit; +(weaponState [_vehicle, _turretPath]) params ["_weapon", "_muzzle", "", "_magazine"]; +TRACE_3("",_weapon,_magazine,typeOf _vehicle); + +private _magazinesAllTurrets = []; + +// Get magazines that are of the correct type; Exclude empty mags +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if ((_xMag == _magazine) && {_xTurret isEqualTo _turretPath} && {_xAmmo > 0}) then { + _magazinesAllTurrets pushBack _x; + }; +} forEach (magazinesAllTurrets _vehicle); + +// Get count of rounds in magazines, then select maximum +private _magAmmoCounts = _magazinesAllTurrets apply {_x select 2}; +private _mag = _magazinesAllTurrets select (_magAmmoCounts find (selectMax _magAmmoCounts)); + +TRACE_2("",_magAmmoCounts,_mag); + +_unit action ["loadMagazine", _vehicle, _unit, _mag select 4, _mag select 3, _weapon, _muzzle]; diff --git a/addons/reload/functions/script_component.hpp b/addons/reload/functions/script_component.hpp deleted file mode 100644 index 572f1fca84..0000000000 --- a/addons/reload/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\reload\script_component.hpp" \ No newline at end of file diff --git a/addons/reload/initKeybinds.inc.sqf b/addons/reload/initKeybinds.inc.sqf new file mode 100644 index 0000000000..cf2ae07ffb --- /dev/null +++ b/addons/reload/initKeybinds.inc.sqf @@ -0,0 +1,16 @@ +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +// Add Keybinds +["ACE3 Weapons", QGVAR(checkAmmo), LSTRING(checkAmmo), { + // Conditions: canInteract + if !([ACE_player, vehicle ACE_player, ["isNotInside", "isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Ignore if controlling UAV (blocks radar keybind) + if (!isNull (ACE_controlledUAV param [0, objNull])) exitWith {false}; + // Conditions: specific + if !(ACE_player call FUNC(canCheckAmmoSelf)) exitWith {false}; + + // Statement + [ACE_player, ACE_player] call FUNC(checkAmmo); + + true +}, {false}, [DIK_R, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + R diff --git a/addons/reload/initSettings.inc.sqf b/addons/reload/initSettings.inc.sqf new file mode 100644 index 0000000000..1110ee125b --- /dev/null +++ b/addons/reload/initSettings.inc.sqf @@ -0,0 +1,15 @@ +[ + QGVAR(displayText), + "CHECKBOX", + [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], + ELSTRING(common,ACEKeybindCategoryWeapons), + true // default value +] call CBA_fnc_addSetting; + +[ + QGVAR(showCheckAmmoSelf), + "CHECKBOX", + [LSTRING(SettingShowCheckAmmoSelf), LSTRING(SettingShowCheckAmmoSelfDesc)], + ELSTRING(common,ACEKeybindCategoryWeapons), + false // default value +] call CBA_fnc_addSetting; diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index 2a7764dc04..2c4bbcab76 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -8,12 +8,12 @@ Проверять боезапас при перезарядке Zkontrolovat munici při nabití Sprawdź stan amunicji przy przeładowaniu broni - Vérification des munitions au rechargement + Vérifier les munitions au rechargement Lőszer ellenőrzése a fegyver újratöltésekor Controlla le munizioni durante il ricaricamento Conferir munição ao recarregar a arma 再装填された武器の弾薬を確認 - 재장전시 장탄수 확인 + 재장전 시 장탄수 확인 在重新装填时检查弹药 在重新裝填時檢查彈藥 @@ -24,21 +24,51 @@ Проверяет количество патронов в новом магазине при перезарядке. Kontroluje munice při nabití nového zásobníku. Pokaż stan amunicji w nowym magazynku przy przeładowaniu broni - Vérification du nombre de munition au rechargement + Vérifie les munitions du nouveau chargeur lors du rechargement d'une arme. A lőszer ellenőrzése az új tárad behelyezésekor újratöltés közben. Controlla le munizioni rimanenti nel caricatore in fase di cambio caricatore. Confere a munição no seu novo carregador ao recarregar a arma 新しく装填された弾倉の弾薬を確認します。 - 재장전시 새탄창에 있는 탄약을 확인합니다. - 在重新装填时检查新弹匣上的弹药. + 재장전 시 새 탄창에 있는 탄약을 확인합니다. + 在重新装填时检查新弹匣上的弹药。 在重新裝填時檢查新彈匣上的彈藥. + + Always show check ammo self interaction + Zawsze pokazuj interakcję od sprawdzania amunicji + Mostra sempre l'autointerazione di controllo delle munizioni + Vždy zobrazit kontrolu munice v menu vlastní interakce + セルフ インタラクションへ弾薬確認を常に表示 + 總是在自我互動中顯示檢查彈藥動作 + 总是在自我互动中显示检查弹药动作 + Toujours afficher l'action de vérification des munitions + Sempre mostrar a opção de checar a própria munição + Всегда показывать проверку боеприпасов + Mostrar siempre la autointeracción de comprobar munición + Zeige immer die Selbstinteraktion zur Prüfung der Munition an. + 상호작용에 탄약 확인을 항상 띄우기 + + + Shows check ammo self interaction even when not in static weapons. + Pokazuje interakcję od sprawdzania amunicji poza bronią statyczną. + Mostra l'autointerazione di controllo delle munizioni anche quando non si è in un'arma statica. + Zobrazuje kontrolu munice v menu vlastní interakce i pokud hráč nepoužívá statickou zbraň. + 設置型火器を使っていなくても、セルフ インタラクションへ弾薬確認を常に表示します。 + 即使不是固定式支援武器也依然在自我互動中顯示檢查彈藥動作 + 即使不是固定式支援武器也依然在自我互动中显示检查弹药动作 + Permet d'afficher l'action de vérification des munitions du menu d'interaction personnel, même si le joueur n'utilise pas d'arme statique. + Mostra a opção de ver sua própria munição mesmo quando não em armas estáticas. + Показывать проверку боеприпасов даже вне стационарного орудия + Mostrar la comprobación de la munición incluso cuando no está en armas estáticas + Zeigt die Selbstinteraktion der Munitionsüberprüfung an, auch wenn nicht in statischen Waffen. + 탄약 확인을 상호작용에서 할 수 있도록 합니다. + Check Ammo Munition prüfen Comprobar munición Sprawdź amunicję - Vérifier Munitions + Vérifier les munitions Lőszerellenőrzés Zkontrolovat Munici Controlla le munizioni @@ -48,6 +78,7 @@ 장탄수 확인 检查弹药 檢查彈藥 + Cephaneni Kontrol Et Ammo @@ -64,6 +95,7 @@ 장탄수 弹药 彈藥 + Cephane Link belt @@ -74,28 +106,50 @@ Podłącz taśmę Gurt anhängen Töltényheveder összekötése - Attacca la tracolla + Combina nastro Ligar cintos de munição - ベルトをつなげる - 벨트 연결 + ベルトを繋げる + 탄띠 연결 连接弹链 連接彈鏈 Linking belt... - Attache d'une bande... + Attachage d'une bande... Enlazando cinta... Сцепка лент... Spojuji pás... Podłączanie taśmy... Gurt anhängen... Töltényheveder összekötése folyamatban... - Attaccando la tracolla... + Combinando nastro... Ligando cintos... - ベルトをつなげています・・・ - 벨트 연결중... - 连接弹链中... + ベルトを繋げています・・・ + 탄띠 연결 중... + 正在连接弹链... 連接彈鏈中... + + Belt was linked + Bande a été attachée + Gurt wurde angehängt + Nastro combinato + ベルトがリンクされた + Taśma została połączona + 탄띠가 연결되었습니다 + Ремень был пристегнут + Cinta enganchada + + + Belt could not be linked + Bande n'a pas pu être attachée + Gurt konnte nicht angehängt werden + Non è stato possibile combinare il nastro + ベルトはリンクされなかった + Taśma nie mogła być połączona + 탄띠를 연결할 수 없습니다 + Ремень не удалось пристегнуть + La cinta no ha podido ser enganchada + diff --git a/addons/reloadlaunchers/ACE_Arsenal_Stats.hpp b/addons/reloadlaunchers/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..9b42950c4d --- /dev/null +++ b/addons/reloadlaunchers/ACE_Arsenal_Stats.hpp @@ -0,0 +1,13 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ADDON: statBase { + scope = 2; + priority = -1; + stats[] = {QGVAR(enabled)}; + displayName = CSTRING(featureDescription); + showText = 1; + textStatement = QUOTE(localize QUOTE(ELSTRING(Common,Enabled))); + condition = QUOTE(params[ARR_2('_stat','_config')]; (getNumber (_config >> _stat select 0)) == 1); + tabs[] = {{2}, {}}; + }; +}; diff --git a/addons/reloadlaunchers/CfgEventHandlers.hpp b/addons/reloadlaunchers/CfgEventHandlers.hpp index becf395052..f6503c2479 100644 --- a/addons/reloadlaunchers/CfgEventHandlers.hpp +++ b/addons/reloadlaunchers/CfgEventHandlers.hpp @@ -1,18 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/reloadlaunchers/CfgVehicles.hpp b/addons/reloadlaunchers/CfgVehicles.hpp index eccd30d1f7..6ce2f4b852 100644 --- a/addons/reloadlaunchers/CfgVehicles.hpp +++ b/addons/reloadlaunchers/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class Man; class CAManBase: Man { diff --git a/addons/reloadlaunchers/CfgWeapons.hpp b/addons/reloadlaunchers/CfgWeapons.hpp index 08fbdb76b0..75a688bf28 100644 --- a/addons/reloadlaunchers/CfgWeapons.hpp +++ b/addons/reloadlaunchers/CfgWeapons.hpp @@ -1,11 +1,18 @@ - class CfgWeapons { class Launcher_Base_F; class launch_Titan_base: Launcher_Base_F { GVAR(enabled) = 1; }; - class launch_RPG32_F: Launcher_Base_F { GVAR(enabled) = 1; }; + class launch_RPG7_F: Launcher_Base_F { + GVAR(enabled) = 1; + }; + class launch_MRAWS_base_F: Launcher_Base_F { + GVAR(enabled) = 1; + }; + class launch_Vorona_base_F: Launcher_Base_F { + GVAR(enabled) = 1; + }; }; diff --git a/addons/reloadlaunchers/README.md b/addons/reloadlaunchers/README.md index 2b6357200b..67b047772a 100644 --- a/addons/reloadlaunchers/README.md +++ b/addons/reloadlaunchers/README.md @@ -2,10 +2,3 @@ ace_reloadlaunchers =========== Add the ability to reload someone else's launcher. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) diff --git a/addons/reloadlaunchers/XEH_PREP.hpp b/addons/reloadlaunchers/XEH_PREP.hpp index b730d2780e..4d63905e75 100644 --- a/addons/reloadlaunchers/XEH_PREP.hpp +++ b/addons/reloadlaunchers/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(addMissileReloadActions); PREP(canLoad); PREP(getLoadableMissiles); diff --git a/addons/reloadlaunchers/XEH_postInit.sqf b/addons/reloadlaunchers/XEH_postInit.sqf index 8c18d430c4..af5fba3bf5 100644 --- a/addons/reloadlaunchers/XEH_postInit.sqf +++ b/addons/reloadlaunchers/XEH_postInit.sqf @@ -1,4 +1,26 @@ // by commy2 #include "script_component.hpp" -[QGVAR(reloadLauncher), {_this call DFUNC(reloadLauncher)}] call CBA_fnc_addEventHandler; +[QGVAR(reloadStarted), { + params ["_unit", "_target"]; + + // Don't show notification if target is local AI + if (GVAR(displayStatusText) && {!local _unit} && {_target call EFUNC(common,isPlayer)}) then { + private _message = format [LLSTRING(LoadingStarted), _unit call EFUNC(common,getName)]; + + [_message] call EFUNC(common,displayTextStructured); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(reloadAborted), { + params ["_unit", "_target"]; + + // Don't show notification if target is local AI + if (GVAR(displayStatusText) && {!local _unit} && {_target call EFUNC(common,isPlayer)}) then { + private _message = format [LLSTRING(LoadingAborted), _unit call EFUNC(common,getName)]; + + [_message] call EFUNC(common,displayTextStructured); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(reloadLauncher), LINKFUNC(reloadLauncher)] call CBA_fnc_addEventHandler; diff --git a/addons/reloadlaunchers/XEH_preInit.sqf b/addons/reloadlaunchers/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/reloadlaunchers/XEH_preInit.sqf +++ b/addons/reloadlaunchers/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/reloadlaunchers/config.cpp b/addons/reloadlaunchers/config.cpp index 09f01e0594..30407c4d7b 100644 --- a/addons/reloadlaunchers/config.cpp +++ b/addons/reloadlaunchers/config.cpp @@ -14,7 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Arsenal_Stats.hpp" #include "CfgEventHandlers.hpp" - #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf index 42af3e5027..1d54ba0fde 100644 --- a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf +++ b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf @@ -1,17 +1,17 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 - * Create one action per reloadable missile + * Create one action per reloadable missile. * * Arguments: - * 1: Target - * 0: Player + * 0: Unit equipped with the launcher + * 1: Unit wanting to execute the reload * * Return Value: * Children actions * * Example: - * [bob, kevin] call ace_reloadlaunchers_fnc_addMissileReloadActions + * [cursorTarget, player] call ace_reloadlaunchers_fnc_addMissileReloadActions * * Public: No * @@ -20,8 +20,9 @@ params ["_target", "_unit"]; TRACE_2("params",_target,_unit); -//Fast exit for common case: +// Fast exit for common cases private _weapon = secondaryWeapon _target; + if ((_weapon == "") || {(getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(enabled))) == 0}) exitWith { TRACE_1("weapon not supported",_weapon); [] @@ -32,16 +33,18 @@ private _actions = []; private _loadableMissiles = [_unit, _weapon] call FUNC(getLoadableMissiles); TRACE_2("",_weapon,_loadableMissiles); +private _cfgMagazines = configFile >> "CfgMagazines"; + { private _name = format [QGVAR(Missile_%1), _x]; - private _displayName = format [localize LSTRING(LoadMagazine), getText (configFile >> "CfgMagazines" >> _x >> "displayName")]; + private _displayName = format [LLSTRING(LoadMagazine), getText (_cfgMagazines >> _x >> "displayName")]; private _statement = { - (_this select 2) call DFUNC(load); + (_this select 2) call FUNC(load); }; private _condition = { - (_this select 2) call DFUNC(canLoad) + (_this select 2) call FUNC(canLoad) }; private _action = [_name, _displayName, "", _statement, _condition, {}, [_unit, _target, _weapon, _x], "", 4] call EFUNC(interact_menu,createAction); diff --git a/addons/reloadlaunchers/functions/fnc_canLoad.sqf b/addons/reloadlaunchers/functions/fnc_canLoad.sqf index af08ed8013..3e5d6303d1 100644 --- a/addons/reloadlaunchers/functions/fnc_canLoad.sqf +++ b/addons/reloadlaunchers/functions/fnc_canLoad.sqf @@ -1,19 +1,19 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Check of the unit can reload the launcher of target unit. + * Author: commy2, johnb43 + * Check if the unit can reload the launcher of the target unit. * * Arguments: - * 0: Unit to do the reloading - * 1: Unit eqipped with launcher - * 2: weapon name - * 3: missile name + * 0: Unit wanting to execute the reload + * 1: Unit equipped with the launcher + * 2: Launcher name + * 3: Missile name * * Return Value: * None * * Example: - * [bob, kevin, "weapon", "missile"] call ace_reloadlaunchers_fnc_canLoad + * [player, cursorTarget, "launch_RPG32_F", "RPG32_F"] call ace_reloadlaunchers_fnc_canLoad * * Public: No */ @@ -21,21 +21,24 @@ params ["_unit", "_target", "_weapon", "_magazine"]; TRACE_4("params",_unit,_target,_weapon,_magazine); -if (!alive _target) exitWith {false}; -if (vehicle _target != _target) exitWith {false}; +// Target must be awake +if !(_target call EFUNC(common,isAwake)) exitWith {false}; + +// Target must not be in a vehicle +if !(isNull objectParent _target) exitWith {false}; if !([_unit, _target, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; -// target is awake -if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; +// Target must not be captive +if (_target getVariable [QEGVAR(captives,isHandcuffed), false] || {_target getVariable [QEGVAR(captives,isSurrendering), false]}) exitWith {false}; -// has secondary weapon equipped -if !(_weapon in weapons _target) exitWith {false}; - -// check if the target really needs to be reloaded -if (count secondaryWeaponMagazine _target > 0) exitWith {false}; - -// check if the launcher is compatible +// Check if the launcher is compatible if (getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(enabled)) == 0) exitWith {false}; -// check if the magazine compatible with targets launcher +// Check if target has its secondary weapon equipped +if !(_weapon in weapons _target) exitWith {false}; + +// Check if the target's launcher's primary muzzle really needs to be reloaded +if (_target ammo _weapon != 0) exitWith {false}; + +// Check if the magazine is compatible with target's launcher _magazine in ([_unit, _weapon] call FUNC(getLoadableMissiles)) diff --git a/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf b/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf index 6bded89110..271fcf5a0d 100644 --- a/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf +++ b/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf @@ -1,17 +1,17 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Return all magazine types from reloaders inventory that are compatible with given weapon. + * Author: commy2, johnb43 + * Return all magazine types from reloader's inventory that are compatible with the given launcher. * * Arguments: - * 0: Unit to to the reload - * 1: A launcher + * 0: Unit wanting to execute the reload + * 1: Launcher name * * Return Value: * Reloable magazines * * Example: - * [bob, launcher] call ace_reloadlaunchers_fnc_getLoadableMissiles + * [player, "launch_RPG32_F"] call ace_reloadlaunchers_fnc_getLoadableMissiles * * Public: No */ @@ -19,11 +19,5 @@ params ["_unit", "_weapon"]; TRACE_2("params",_unit,_weapon); -// get available magazines of reloader, Note: "magazines" does not include currently loaded magazines -private _magazines = magazines _unit; - -// case sensitvity -_magazines = _magazines apply {toLower _x}; - -// get reloaders magazine types compatible with targets launcher. No duplicates. -getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines") select {toLower _x in _magazines} // return +// Look for primary muzzle magazines only +(compatibleMagazines [_weapon, "this"]) arrayIntersect (magazines _unit) diff --git a/addons/reloadlaunchers/functions/fnc_load.sqf b/addons/reloadlaunchers/functions/fnc_load.sqf index 27d4cafbf2..6ef32e4539 100644 --- a/addons/reloadlaunchers/functions/fnc_load.sqf +++ b/addons/reloadlaunchers/functions/fnc_load.sqf @@ -1,19 +1,19 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Reload a launcher + * Author: commy2, johnb43, drofseh + * Start reloading a launcher, reload started by the unit who has the missile. * * Arguments: - * 0: Unit with magazine - * 1: Unit with launcher - * 2: weapon name - * 3: missile name + * 0: Unit executing the reload + * 1: Unit equipped with the launcher + * 2: Launcher name + * 3: Missile name * * Return Value: * None * * Example: - * [bob, kevin, "weapon", "missile"] call ace_reloadlaunchers_fnc_load + * [player, cursorTarget, "launch_RPG32_F", "RPG32_F"] call ace_reloadlaunchers_fnc_load * * Public: No */ @@ -21,30 +21,67 @@ params ["_unit", "_target", "_weapon", "_magazine"]; TRACE_4("params",_unit,_target,_weapon,_magazine); -private _reloadTime = if (isNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(buddyReloadTime))) then { - getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(buddyReloadTime)) +private _config = configFile >> "CfgWeapons" >> _weapon >> QGVAR(buddyReloadTime); + +private _reloadTime = if (isNumber _config) then { + getNumber _config } else { - 2.5 + getNumber (configFile >> "CfgWeapons" >> _weapon >> "magazineReloadTime") min 2.5 }; -// do animation +// Play animation [_unit] call EFUNC(common,goKneeling); -// show progress bar +// Notify unit that is being reloaded that reload has been started +[QGVAR(reloadStarted), [_unit, _target], _target] call CBA_fnc_targetEvent; +// Show progress bar private _onSuccess = { - (_this select 0 select 0) removeMagazine (_this select 0 select 3); - [QGVAR(reloadLauncher), _this select 0, _this select 0 select 1] call CBA_fnc_targetEvent; + (_this select 0) params ["_unit", "_target", "_weapon", "_magazine"]; - [localize LSTRING(LauncherLoaded)] call DEFUNC(common,displayTextStructured); + // Check if the unit has any of the same magazines and calculate max ammo + private _maxAmmo = 0; + + { + _maxAmmo = _maxAmmo max (_x select 1); + } forEach (magazinesAmmo _unit select {(_x select 0) == _magazine}); + + // Check if the launcher can still be loaded; If possible, then try to remove magazine + if !(_maxAmmo > 0 && {[_unit, _target, _weapon, _magazine] call FUNC(canLoad)} && {[_unit, _magazine, _maxAmmo] call EFUNC(common,removeSpecificMagazine)}) exitWith { + // Notify unit that was being reloaded that reload has been stopped + [QGVAR(reloadAborted), [_unit, _target], _target] call CBA_fnc_targetEvent; + + // Notify reloading unit about failure + if (GVAR(displayStatusText)) then { + [LSTRING(LauncherNotLoaded)] call EFUNC(common,displayTextStructured); + }; + }; + + // Reload target's launcher + [QGVAR(reloadLauncher), [_unit, _target, _weapon, _magazine, _maxAmmo], _target] call CBA_fnc_targetEvent; + + // Notify reloading unit about success + if (GVAR(displayStatusText)) then { + [LSTRING(LauncherLoaded)] call EFUNC(common,displayTextStructured); + }; }; private _onFailure = { - [localize ELSTRING(common,ActionAborted)] call DEFUNC(common,displayTextStructured); + (_this select 0) params ["_unit", "_target"]; + + // Notify unit that was being reloaded that reload has been stopped + [QGVAR(reloadAborted), [_unit, _target], _target] call CBA_fnc_targetEvent; + + // Notify reloading unit about failure + if (GVAR(displayStatusText)) then { + [LSTRING(LauncherNotLoaded)] call EFUNC(common,displayTextStructured); + }; }; private _condition = { - (_this select 0) call DFUNC(canLoad) && {(_this select 0 select 0) distance (_this select 0 select 1) < 4} + (_this select 0) params ["_unit", "_target"]; + + (_this select 0) call FUNC(canLoad) && {_unit distance _target < 4} }; -[_reloadTime, [_unit, _target, _weapon, _magazine], _onSuccess, _onFailure, localize LSTRING(LoadingLauncher), _condition, ["isNotInside", "isNotSwimming"]] call EFUNC(common,progressBar); +[_reloadTime, [_unit, _target, _weapon, _magazine], _onSuccess, _onFailure, LLSTRING(LoadingLauncher), _condition, ["isNotInside", "isNotSwimming"]] call EFUNC(common,progressBar); diff --git a/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf b/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf index 58f6b6556a..592c3af283 100644 --- a/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf +++ b/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf @@ -1,30 +1,32 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2 - * Reload a launcher + * Author: commy2, johnb43, drofseh + * Reload a launcher for the unit who has the launcher. + * If the ammo argument is nil, a full magazine will be given. * * Arguments: - * 0: Unit to do the reloading - * 1: Target to rload - * 2: weapon name - * 3: missile name + * 0: Unit executing the reload + * 1: Unit equipped with the launcher + * 2: Launcher name + * 3: Missile name + * 4: Ammo count * * Return Value: * None * * Example: - * [bob, kevin, "weapon", "missile"] call ace_reloadlaunchers_fnc_realoadLauncher + * [player, cursorTarget, "launch_RPG32_F", "RPG32_F"] call ace_reloadlaunchers_fnc_reloadLauncher * * Public: No */ -params ["_unit","_target","_weapon","_magazine"]; -TRACE_4("params",_unit,_target,_weapon,_magazine); +params ["_unit", "_target", "_weapon", "_magazine", "_ammo"]; +TRACE_5("params",_unit,_target,_weapon,_magazine,_ammo); -_target selectWeapon _weapon; +// Add magazine to launcher immediately +_target addWeaponItem [_weapon, [_magazine, _ammo], true]; -if (currentWeapon _target != _weapon) exitWith {}; -if (currentMagazine _target != "") exitWith {}; - -// command is wip, reload time for launchers is not intended. -_target addWeaponItem [_weapon, _magazine]; +// Don't show notification if target is local AI +if (GVAR(displayStatusText) && {!local _unit} && {_target call EFUNC(common,isPlayer)}) then { + [LSTRING(LauncherLoaded)] call EFUNC(common,displayTextStructured); +}; diff --git a/addons/reloadlaunchers/functions/script_component.hpp b/addons/reloadlaunchers/functions/script_component.hpp deleted file mode 100644 index 9c129f36b1..0000000000 --- a/addons/reloadlaunchers/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\reloadlaunchers\script_component.hpp" \ No newline at end of file diff --git a/addons/reloadlaunchers/initSettings.inc.sqf b/addons/reloadlaunchers/initSettings.inc.sqf new file mode 100644 index 0000000000..687a74ef37 --- /dev/null +++ b/addons/reloadlaunchers/initSettings.inc.sqf @@ -0,0 +1,8 @@ +[ + QGVAR(displayStatusText), + "CHECKBOX", + [LSTRING(SettingDisplayStatusTextName), LSTRING(SettingDisplayStatusTextDesc)], + ELSTRING(common,ACEKeybindCategoryWeapons), + true, + 2 +] call CBA_fnc_addSetting; diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index eef4c9e50a..b55ccde170 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -1,6 +1,28 @@ + + Display notifications for buddy loading + バディローディング時の通知表示 + Wyświetlanie powiadomień o ładowaniu przez asystenta + Buddy Nachlade Nachricht anzeigen + Mostra avviso di ricarica da parte del coppio + 동료의 장전에 대한 알림 표시 + Affichage de notifications lors d'une rechargement par un ami + Отображает уведомления о загрузке помощника + Mostrar notificaciones para recarga de compañero + + + Displays notifications when an assistant loads a gunner's launcher. + 助手が射手のランチャーを装填した際に通知を表示します。 + Wyświetla powiadomienie, gdy asystent ładuje wyrzutnię. + Zeigt Benachrichtigungen an, wenn ein Assistent den Werfer eines Richtschützen lädt. + Mostra un avviso quando un assistente sta ricaricando il proprio lanciatore. + 부사수가 사수의 발사기를 장전할 때 알림을 표시합니다. + Affiche une notofication lorsqu'un assistant recharge l'arme du tireur. + Отображает уведомления, когда помощник загружает пусковую установку стрелка. + Mostrar notificaciones cuando un asistente recarga el lanzador del tirador. + Load launcher Panzerabwehr laden @@ -10,12 +32,35 @@ Załaduj wyrzutnię Charger lanceur Kilövö betöltése - Carica lanciamissili + Carica lanciatore Recarregar lançador - ランチャーに装填 + ランチャーを装填 무기 재장전 - 装载发射器 + 装填发射器 裝載發射器 + Fırlatıcıyı Yükle + + + %1 is loading your launcher + %1 lädt deine Panzerabwehr + %1 charge ton lanceur + %1 sta caricando il tuo lanciatore + %1 がランチャーを装填しています + %1 ładuje twoją wyrzutnię + %1이(가) 당신의 발사기를 장전했습니다. + %1 загружает Вашу установку + %1 está cargando tu lanzador + + + %1 stopped loading your launcher + %1 hat aufgehört, deine Panzerabwehr zu laden + %1 a arrêté de charger ton lanceur + %1 ha smesso di caricare il tuo lanciatore + %1 がランチャーの装填を中断しました + %1 przestał ładować twoją wyrzutnię + %1이(가) 당신의 발사기 장전을 멈췄습니다. + %1 прекратил загружать Вашу установку + %1 paró de cargar tu lanzador Loading launcher... @@ -26,12 +71,13 @@ Nabíjím odpalovač... Ładowanie wyrzutni... Kilövő betöltés alatt... - Caricando il lanciamissili... + Caricando il lanciatore... Recarregando lançador... - ランチャーに装填中・・・ - 무기 재장전중... - 装载发射器中... + ランチャーを装填中・・・ + 무기 재장전 중... + 正在装填发射器... 裝載發射器中... + Fırlatıcı Yükleniyor... Launcher loaded @@ -42,28 +88,52 @@ Odpalovač nabit Wyrzutnia załadowana Kilövő betöltve - Lanciamissili caricato + Lanciatore caricato Lançador Carregado - ランチャーに装填完了 + ランチャーの装填完了 무기 재장전됨 - 发射器装载完毕 + 发射器装填完毕 發射器裝載完畢 + Fırlatıcı Yüklendi Load %1 - Charge %1 + Charge %1. Lade %1 Cargar %1 Загрузка %1 Nabít %1 Załadowano %1 %1 betöltése - Caricato %1 + Carica %1 Recarregar %1 - %1 を装填 + %1 を装填します %1 장전 - 装载%1 + 装填%1 裝載%1 + %1 Yüklendi + + + Launcher could not be loaded + Panzerabwehr konnte nicht geladen werden + Impossibile caricare il lanciatore + Le lanceur n'a pas pu être chargé + ランチャーを装填できませんでした + Wyrzutnia nie mogła być załadowana + 발사기를 장전할 수 없습니다. + Не удалось загрузить пусковую установку + El lanzador no ha podido ser cargado + + + Buddy Loading + Ładowanie przez Asystenta + 부사수 장전 중 + Caricamento da coppio + Chargement par un ami + Nachladen durch Kamerad + バディローディング + Перезарядка помощником + Cargado de Compañero diff --git a/addons/repair/ACE_Repair.hpp b/addons/repair/ACE_Repair.hpp index ec0624e2dc..344c509b2f 100644 --- a/addons/repair/ACE_Repair.hpp +++ b/addons/repair/ACE_Repair.hpp @@ -3,17 +3,18 @@ class ACE_Repair { class ReplaceWheel { displayName = CSTRING(ReplaceWheel); displayNameProgress = CSTRING(ReplacingWheel); + forceDisplayName = 0; repairLocations[] = {"All"}; requiredEngineer = QGVAR(engineerSetting_Wheel); - repairingTime = 10; + repairingTime = QGVAR(wheelChangeTime); repairingTimeSelfCoef = 1; items = QGVAR(wheelRepairRequiredItems); - condition = QUOTE(call FUNC(canReplaceWheel)); + condition = QFUNC(canReplaceWheel); itemConsumed = 0; claimObjects[] = {{"ACE_Wheel"}}; - callbackSuccess = QUOTE(call FUNC(doReplaceWheel)); + callbackSuccess = QFUNC(doReplaceWheel); callbackFailure = ""; callbackProgress = ""; @@ -21,31 +22,43 @@ class ACE_Repair { animationCallerProne = "Acts_carFixingWheel"; animationCallerSelf = "Acts_carFixingWheel"; animationCallerSelfProne = "Acts_carFixingWheel"; + loopAnimation = 0; litter[] = {}; }; class RemoveWheel: ReplaceWheel { displayName = CSTRING(RemoveWheel); displayNameProgress = CSTRING(RemovingWheel); - condition = QUOTE(call FUNC(canRemove)); - callbackSuccess = QUOTE(call FUNC(doRemoveWheel)); + condition = QFUNC(canRemove); + callbackSuccess = QFUNC(doRemoveWheel); + claimObjects[] = {}; + }; + class PatchWheel: ReplaceWheel { + displayName = CSTRING(PatchWheel); + displayNameProgress = CSTRING(PatchingWheel); + condition = QFUNC(canPatchWheel); + repairingTime = QFUNC(getPatchWheelTime); + callbackProgress = QFUNC(doPatchWheelProgress); + items = QGVAR(patchWheelRequiredItems); + requiredEngineer = QGVAR(engineerSetting_Wheel); + callbackSuccess = ""; claimObjects[] = {}; }; class MiscRepair: ReplaceWheel { displayName = CSTRING(Repairing); // let's make empty string an auto generated string displayNameProgress = CSTRING(RepairingHitPoint); - condition = QUOTE(call FUNC(canMiscRepair)); + condition = QFUNC(canMiscRepair); requiredEngineer = QGVAR(engineerSetting_Repair); - repairingTime = 15; - callbackSuccess = QUOTE(call FUNC(doRepair)); - items[] = {"ToolKit"}; + repairingTime = QGVAR(miscRepairTime); + callbackSuccess = QFUNC(doRepair); + items = QGVAR(miscRepairRequiredItems); itemConsumed = QGVAR(consumeItem_ToolKit); claimObjects[] = {}; }; class RepairTrack: MiscRepair { displayName = CSTRING(Repairing); displayNameProgress = CSTRING(RepairingHitPoint); - condition = QUOTE(call FUNC(canRepairTrack)); - callbackSuccess = QUOTE(call FUNC(doRepairTrack)); + condition = QFUNC(canRepairTrack); + callbackSuccess = QFUNC(doRepairTrack); requiredEngineer = QGVAR(engineerSetting_Wheel); claimObjects[] = {{"ACE_Track"}}; itemConsumed = 0; @@ -53,27 +66,31 @@ class ACE_Repair { class RemoveTrack: MiscRepair { displayName = CSTRING(RemoveTrack); displayNameProgress = CSTRING(RemovingTrack); - condition = QUOTE(call FUNC(canRemove)); - callbackSuccess = QUOTE(call FUNC(doRemoveTrack)); + condition = QFUNC(canRemove); + callbackSuccess = QFUNC(doRemoveTrack); requiredEngineer = QGVAR(engineerSetting_Wheel); itemConsumed = 0; }; class ReplaceTrack: RemoveTrack { displayName = CSTRING(ReplaceTrack); displayNameProgress = CSTRING(ReplacingTrack); - condition = QUOTE(call FUNC(canReplaceTrack)); - callbackSuccess = QUOTE(call FUNC(doReplaceTrack)); + condition = QFUNC(canReplaceTrack); + callbackSuccess = QFUNC(doReplaceTrack); requiredEngineer = QGVAR(engineerSetting_Wheel); claimObjects[] = {{"ACE_Track"}}; }; class FullRepair: MiscRepair { displayName = CSTRING(fullRepair); displayNameProgress = CSTRING(fullyRepairing); + forceDisplayName = 1; + loopAnimation = 1; requiredEngineer = QGVAR(engineerSetting_fullRepair); repairLocations[] = {QGVAR(fullRepairLocation)}; - repairingTime = 30; - condition = "-1 != ((getAllHitPointsDamage _target param [2,[]]) findIf {_x > 0})"; - callbackSuccess = QUOTE(call FUNC(doFullRepair)); + repairingTime = QFUNC(getFullRepairTime); + condition = "((getAllHitPointsDamage _target) select 2) findIf {_x > 0} != -1"; + callbackSuccess = QFUNC(doFullRepair); + callbackProgress = QFUNC(fullRepairProgress); + items = QGVAR(fullRepairRequiredItems); itemConsumed = QGVAR(consumeItem_ToolKit); }; }; diff --git a/addons/repair/ACE_Settings.hpp b/addons/repair/ACE_Settings.hpp index 82217bc5ad..45e8b15aa9 100644 --- a/addons/repair/ACE_Settings.hpp +++ b/addons/repair/ACE_Settings.hpp @@ -1,4 +1,3 @@ -// Warning: do not remove without handling wheelRepairRequiredItems's _values config on line 32 [used in repair/canRepair] class ACE_Settings { class GVAR(displayTextOnRepair) { movedToSQF = 1; @@ -29,7 +28,6 @@ class ACE_Settings { }; class GVAR(wheelRepairRequiredItems) { movedToSQF = 1; - _values[] = {{}, {"ToolKit"}}; }; class GVAR(autoShutOffEngineWhenStartingRepair) { movedToSQF = 1; diff --git a/addons/repair/CfgActions.hpp b/addons/repair/CfgActions.hpp deleted file mode 100644 index 5dbd0ca7a6..0000000000 --- a/addons/repair/CfgActions.hpp +++ /dev/null @@ -1,9 +0,0 @@ -class CfgActions { - class None; - class Repair: None { - show = 0; - }; - class RepairVehicle: None { - show = 0; - }; -}; diff --git a/addons/repair/CfgEden.hpp b/addons/repair/CfgEden.hpp index 03614b3a2f..2cd1ed9e2e 100644 --- a/addons/repair/CfgEden.hpp +++ b/addons/repair/CfgEden.hpp @@ -1,7 +1,8 @@ +#define VANILLA_ISREPAIRVEHICLE (parseNumber (getRepairCargo _this > 0)) #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define DEFAULT_ISENGINEER ([ARR_2(0,1)] select (_this getUnitTrait 'engineer')) -#define DEFAULT_ISREPAIRVEHICLE GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(canRepair),0) +#define DEFAULT_ISREPAIRVEHICLE GET_NUMBER(configOf _this >> QQGVAR(canRepair),VANILLA_ISREPAIRVEHICLE) class ctrlToolbox; @@ -17,7 +18,7 @@ class Cfg3DEN { attributeLoad = "(_this controlsGroupCtrl 100) lbSetCurSel (((_value + 1) min 3) max 0);"; attributeSave = "(lbCurSel (_this controlsGroupCtrl 100)) - 1"; class Controls: Controls { - class Title: Title{}; + class Title: Title {}; class Value: ctrlToolbox { idc = 100; style = "0x02"; @@ -69,7 +70,7 @@ class Cfg3DEN { property = QGVAR(editorLoadedTracks); control = "Edit"; expression = "_this setVariable ['%s',_value];"; - defaultValue = "[0,1] select (_this isKindOf 'Tank')"; // must match pre init script + defaultValue = "parseNumber (_this isKindOf 'Tank')"; // must match post init script validate = "number"; condition = "objectHasInventoryCargo"; typeName = "NUMBER"; @@ -78,7 +79,7 @@ class Cfg3DEN { displayName = CSTRING(editorLoadedWheels); tooltip = CSTRING(editorLoadedWheels_tooltip); property = QGVAR(editorLoadedWheels); - defaultValue = "[0,1] select (_this isKindOf 'Car')"; // must match pre init script + defaultValue = "parseNumber (_this isKindOf 'Car')"; // must match post init script }; }; }; diff --git a/addons/repair/CfgEventHandlers.hpp b/addons/repair/CfgEventHandlers.hpp index 3e47f9f96f..6991392d83 100644 --- a/addons/repair/CfgEventHandlers.hpp +++ b/addons/repair/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp index a41c2db501..ce74737b76 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -3,10 +3,6 @@ class ACE_MainActions { \ class GVAR(Repair) { \ displayName = CSTRING(Repair); \ - condition = "true"; \ - statement = ""; \ - runOnHover = 1; \ - showDisabled = 0; \ icon = "\A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; \ distance = 4; \ exceptions[] = {"isNotSwimming", "isNotOnLadder"}; \ @@ -100,7 +96,7 @@ class CfgVehicles { defaultValue = 1; }; class wheelRepairRequiredItems { - displayName = CSTRING(wheelRepairRequiredItems_name); + displayName = CSTRING(WheelRepairRequiredItems_DisplayName); description = CSTRING(wheelRepairRequiredItems_description); typeName = "NUMBER"; class values { @@ -327,6 +323,7 @@ class CfgVehicles { class ACE_Track: ACE_RepairItem_Base { EGVAR(cargo,size) = 2; EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; author = "Hawkins"; scope = 2; model = QPATHTOF(data\ace_track.p3d); @@ -357,6 +354,7 @@ class CfgVehicles { class ACE_Wheel: ACE_RepairItem_Base { EGVAR(cargo,size) = 1; EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; author = "Hawkins"; scope = 2; model = QPATHTOF(data\ace_wheel.p3d); @@ -377,13 +375,14 @@ class CfgVehicles { // can not take damage individually though, because of limitations of the thingX simulation type class HitPoints { class HitBody { - armor = 0.6; + armor = 1; material = -1; name = "mat_rim"; visual = "mat_rim"; passThrough = 1; radius = 0.1; explosionShielding = 1; + minimalHit = 1; }; }; @@ -400,40 +399,19 @@ class CfgVehicles { }; editorPreview = QPATHTOF(data\preview_wheel.jpg); - }; - // disable vanilla repair - // "getNumber (_x >> ""transportRepair"") > 0" configClasses (configFile >> "CfgVehicles") - class ReammoBox_F; - class Land_RepairDepot_01_base_F: ReammoBox_F { // TanksDLC - Repair Depo Thing - GVAR(canRepair) = 1; - transportRepair = 0; - }; - class Van_02_base_F; - class Van_02_service_base_F: Van_02_base_F { // OrangeDLC - GVAR(canRepair) = 1; - transportRepair = 0; - }; - - class Slingload_01_Base_F; - class B_Slingload_01_Repair_F: Slingload_01_Base_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; - - class Helicopter_Base_H; - class Heli_Transport_04_base_F: Helicopter_Base_H { - GVAR(hitpointGroups)[] = { {"HitEngine", {"HitEngine1", "HitEngine2"}} }; - }; - class O_Heli_Transport_04_repair_F: Heli_Transport_04_base_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; - - class Pod_Heli_Transport_04_base_F; - class Land_Pod_Heli_Transport_04_repair_F: Pod_Heli_Transport_04_base_F { - GVAR(canRepair) = 1; - transportRepair = 0; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class GVAR(Patch) { + displayName = CSTRING(PatchWheel); + distance = 4; + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canPatchRemovedWheel)); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(patchRemovedWheel)); + exceptions[] = {"isNotDragging", "isNotCarrying", "isNotOnLadder", "isNotSwimming", "isNotSitting"}; + icon = QPATHTOF(ui\patch_ca.paa); + }; + }; + }; }; class Heli_Transport_02_base_F; @@ -447,41 +425,10 @@ class CfgVehicles { }; class B_APC_Tracked_01_base_F; - class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; - class B_APC_Tracked_01_AA_F: B_APC_Tracked_01_base_F { GVAR(hitpointPositions)[] = {{"HitTurret", {0,-2,0}}}; }; - class Offroad_01_base_F; - class Offroad_01_repair_base_F: Offroad_01_base_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; - - class B_Truck_01_mover_F; - class B_Truck_01_Repair_F: B_Truck_01_mover_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; - - class B_Truck_01_fuel_F: B_Truck_01_mover_F { // the fuel hemet apparently can repair. GJ BI - transportRepair = 0; - }; - - class Truck_02_base_F; - class Truck_02_box_base_F: Truck_02_base_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; - - class Truck_02_medical_base_F: Truck_02_box_base_F { - GVAR(canRepair) = 0; - }; - class Car_F: Car { class HitPoints; }; @@ -501,10 +448,6 @@ class CfgVehicles { }; }; }; - class O_Truck_03_repair_F: Truck_03_base_F { - GVAR(canRepair) = 1; - transportRepair = 0; - }; class Quadbike_01_base_F: Car_F { GVAR(hitpointPositions)[] = { {"HitEngine", {0, 0.5, -0.7}}, {"HitFuel", {0, 0, -0.5}} }; diff --git a/addons/repair/README.md b/addons/repair/README.md index 5cf5e8f89a..28762b44ac 100644 --- a/addons/repair/README.md +++ b/addons/repair/README.md @@ -2,12 +2,3 @@ ace_repair =========== Adds repair system. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [Glowbal](https://github.com/Glowbal) -- [Jonpas](https://github.com/jonpas) diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 7c2e5a1f15..16e11b7476 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -2,22 +2,29 @@ PREP(addRepairActions); PREP(addSpareParts); PREP(canMiscRepair); +PREP(canPatchRemovedWheel); +PREP(canPatchWheel); PREP(canRemove); PREP(canRepair); PREP(canRepairTrack); PREP(canReplaceTrack); PREP(canReplaceWheel); PREP(doFullRepair); +PREP(doPatchWheelProgress); PREP(doRemoveTrack); PREP(doRemoveWheel); PREP(doRepair); PREP(doRepairTrack); PREP(doReplaceTrack); PREP(doReplaceWheel); +PREP(fullRepairProgress); PREP(getClaimObjects); +PREP(getFullRepairTime); PREP(getHitPointString); +PREP(getSelectionsToIgnore); +PREP(getPatchWheelTime); PREP(getPostRepairDamage); -PREP(getWheelHitPointsWithSelections); +PREP(getRepairItems); PREP(hasItems); PREP(isEngineer); PREP(isInRepairFacility); @@ -31,6 +38,7 @@ PREP(moduleAssignRepairVehicle); PREP(moduleAssignRepairFacility); PREP(moduleRepairSettings); PREP(normalizeHitPoints); +PREP(patchRemovedWheel); PREP(repair); PREP(repair_failure); PREP(repair_success); diff --git a/addons/repair/XEH_postInit.sqf b/addons/repair/XEH_postInit.sqf index 2cbbd8c3e1..2e9a9178ff 100644 --- a/addons/repair/XEH_postInit.sqf +++ b/addons/repair/XEH_postInit.sqf @@ -1,20 +1,88 @@ #include "script_component.hpp" -[QGVAR(setVehicleDamage), {_this call FUNC(setDamage)}] call CBA_fnc_addEventHandler; -[QGVAR(setVehicleHitPointDamage), {_this call FUNC(setHitPointDamage)}] call CBA_fnc_addEventHandler; +["CBA_settingsInitialized", { -// wheels -[QGVAR(setWheelHitPointDamage), { - params ["_object", "_hitPoint", "_damage"]; - private _damageDisabled = !isDamageAllowed _object; + if (!GVAR(enabled)) exitWith {}; - if (_damageDisabled) then { - _object allowDamage true; + [QGVAR(setVehicleDamage), LINKFUNC(setDamage)] call CBA_fnc_addEventHandler; + [QGVAR(setVehicleHitPointDamage), LINKFUNC(setHitPointDamage)] call CBA_fnc_addEventHandler; + [QGVAR(setWheelHitPointDamage), { + params ["_object", "_hitPoint", "_damage"]; + private _damageDisabled = !isDamageAllowed _object; + + if (_damageDisabled) then { + _object allowDamage true; + }; + + _object setHitPointDamage [_hitPoint, _damage]; + + if (_damageDisabled) then { + _object allowDamage false; + }; + }] call CBA_fnc_addEventHandler; + + + // placed in editor static objects don't trigger init + { + if (local _x && {getRepairCargo _x > 0}) then { + _x setRepairCargo 0; + TRACE_3("setRepairCargo static",_x,typeOf _x,getRepairCargo _x); + }; + } forEach allMissionObjects "Static"; + + ["All", "InitPost", { + params ["_vehicle"]; + if !(local _vehicle && {getRepairCargo _vehicle > 0}) exitWith {}; + _vehicle setRepairCargo 0; + TRACE_3("setRepairCargo vehicle",_vehicle,typeOf _vehicle,getRepairCargo _vehicle); + }, true, ["Man"], true] call CBA_fnc_addClassEventHandler; + + ["CAManBase", "InitPost", { + params ["_unit"]; + if !(local _unit && {_unit getUnitTrait "engineer"}) exitWith {}; + _unit setUnitTrait ["engineer", false]; + if (_unit getVariable ["ACE_IsEngineer", -1] isEqualTo -1) then { + _unit setVariable ["ACE_IsEngineer", true, true]; + }; + TRACE_3("setUnitTrait",_unit,typeOf _unit,_unit getUnitTrait "engineer"); + }, true, [], true] call CBA_fnc_addClassEventHandler; + + + GVAR(allToolKits) = call (uiNamespace getVariable QGVAR(allToolKits)); + + ["ACE_RepairItem_Base", "killed", { + params ["_object"]; + + [{deleteVehicle _this}, _object, 5] call CBA_fnc_waitAndExecute; + }, true, [], true] call CBA_fnc_addClassEventHandler; + + // load tracks and wheels + if (isServer) then { + private _fnc_addSpareItems = { + if (!GVAR(addSpareParts)) exitWith {}; + params ["_vehicle"]; + + private _spareTracks = _vehicle getVariable QGVAR(editorLoadedTracks); + if (isNil "_spareTracks") then { + private _defaultCount = parseNumber (_vehicle isKindOf "Tank"); // must match eden attribute default + _spareTracks = [configOf _vehicle >> QGVAR(spareTracks), "NUMBER", _defaultCount] call CBA_fnc_getConfigEntry; + }; + if (_spareTracks > 0) then { + [_vehicle, _spareTracks, "ACE_Track"] call FUNC(addSpareParts); + }; + + private _spareWheels = _vehicle getVariable QGVAR(editorLoadedWheels); + if (isNil "_spareWheels") then { + private _defaultCount = parseNumber (_vehicle isKindOf "Car"); // must match eden attribute default + _spareWheels = [configOf _vehicle >> QGVAR(spareWheels), "NUMBER", _defaultCount] call CBA_fnc_getConfigEntry; + }; + if (_spareWheels > 0) then { + [_vehicle, _spareWheels, "ACE_Wheel"] call FUNC(addSpareParts); + }; + }; + + ["Tank", "initPost", _fnc_addSpareItems, true, [], true] call CBA_fnc_addClassEventHandler; + ["Car", "initPost", _fnc_addSpareItems, true, [], true] call CBA_fnc_addClassEventHandler; }; - _object setHitPointDamage [_hitPoint, _damage]; - - if (_damageDisabled) then { - _object allowDamage false; - }; }] call CBA_fnc_addEventHandler; diff --git a/addons/repair/XEH_preInit.sqf b/addons/repair/XEH_preInit.sqf index 216a16fcf7..894773534a 100644 --- a/addons/repair/XEH_preInit.sqf +++ b/addons/repair/XEH_preInit.sqf @@ -6,39 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" - -["ACE_RepairItem_Base", "killed", { - params ["_object"]; - - [{deleteVehicle _this}, _object, 5] call CBA_fnc_waitAndExecute; -}] call CBA_fnc_addClassEventHandler; - -// load tracks and wheels -if (isServer) then { - private _fnc_addSpareItems = { - if (!GVAR(addSpareParts)) exitWith {}; - params ["_vehicle"]; - - private _spareTracks = _vehicle getVariable QGVAR(editorLoadedTracks); - if (isNil "_spareTracks") then { - _spareTracks = [0, 1] select (_vehicle isKindOf "Tank"); // must match eden attribute default - }; - if (_spareTracks > 0) then { - [_vehicle, _spareTracks, "ACE_Track"] call FUNC(addSpareParts); - }; - - private _spareWheels = _vehicle getVariable QGVAR(editorLoadedWheels); - if (isNil "_spareWheels") then { - _spareWheels = [0, 1] select (_vehicle isKindOf "Car"); // must match eden attribute default - }; - if (_spareWheels > 0) then { - [_vehicle, _spareWheels, "ACE_Wheel"] call FUNC(addSpareParts); - }; - }; - - ["Tank", "initPost", _fnc_addSpareItems] call CBA_fnc_addClassEventHandler; - ["Car", "initPost", _fnc_addSpareItems] call CBA_fnc_addClassEventHandler; -}; +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/repair/XEH_preStart.sqf b/addons/repair/XEH_preStart.sqf index 022888575e..a01df24b79 100644 --- a/addons/repair/XEH_preStart.sqf +++ b/addons/repair/XEH_preStart.sqf @@ -1,3 +1,8 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +uiNamespace setVariable [ + QGVAR(allToolKits), + compileFinal str (QUOTE(getNumber (_x >> 'ItemInfo' >> 'type') == TYPE_TOOLKIT) configClasses (configFile >> "CfgWeapons") apply {configName _x}) +]; diff --git a/addons/repair/config.cpp b/addons/repair/config.cpp index 1dbe9b46b1..05ee4bac01 100644 --- a/addons/repair/config.cpp +++ b/addons/repair/config.cpp @@ -16,7 +16,6 @@ class CfgPatches { #include "ACE_Repair.hpp" #include "ACE_Settings.hpp" -#include "CfgActions.hpp" #include "CfgEden.hpp" #include "CfgEventHandlers.hpp" #include "CfgMoves.hpp" diff --git a/addons/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf index 3a1f0c8d0f..182b2f7a08 100644 --- a/addons/repair/dev/draw_showRepairInfo.sqf +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -1,26 +1,27 @@ // PabstMirror // [] execVM "\z\ace\addons\repair\dev\draw_showRepairInfo.sqf"; -#include "\z\ace\addons\repair\script_component.hpp" +#include "..\script_component.hpp" addMissionEventHandler ["Draw3D", { + if (isGamePaused) exitWith {}; if !((cursorObject isKindOf "Car") || (cursorObject isKindOf "Tank") || (cursorObject isKindOf "Air")) exitWith {}; - private _config = configFile >> "CfgVehicles" >> (typeOf cursorObject); + private _config = configOf cursorObject; private _hitpointPositions = getArray (_config >> QGVAR(hitpointPositions)); private _hitpointGroups = getArray (_config >> QGVAR(hitpointGroups)); (getAllHitPointsDamage cursorObject) params [["_hitPoints", []], ["_hitSelections", []]]; - ([cursorObject] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + ([cursorObject] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _output = []; - + { private _selection = _x; private _hitpoint = _hitPoints select _forEachIndex; if ((_selection != "") && {_hitPoint != ""}) then { - if (((toLower _hitPoint) find "glass") != -1) exitWith {}; + if ("glass" in (toLowerANSI _hitPoint)) exitWith {}; private _info = ""; private _color = [1,0,0,1]; @@ -28,7 +29,7 @@ addMissionEventHandler ["Draw3D", { _info = _info + "[Wheel]"; _color = [0,1,0,1]; }; - if (!((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) then { + if !((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"]) then { _info = _info + format ["[depends: %1]", getText (_config>> "HitPoints" >> _hitpoint >> "depends")]; _color = [0,0,1,1] }; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index c409591911..16711d7b8a 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: commy2, SilentSpike + * Author: commy2, kymckay * Checks if the vehicles class already has the actions initialized, otherwise add all available repair options. Calleed from init EH. * * Arguments: @@ -15,52 +15,56 @@ * Public: No */ -if (!hasInterface) exitWith {}; +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addRepairActions), _this]; +}; + +if !(hasInterface && {GVAR(enabled)}) exitWith {}; params ["_vehicle"]; private _type = typeOf _vehicle; -TRACE_2("addRepairActions", _vehicle,_type); +TRACE_2("addRepairActions",_vehicle,_type); // do nothing if the class is already initialized private _initializedClasses = GETMVAR(GVAR(initializedClasses),[]); if (_type in _initializedClasses) exitWith {}; +if (_type == "") exitWith {}; + +// get selections to ignore +private _selectionsToIgnore = _vehicle call FUNC(getSelectionsToIgnore); // get all hitpoints and selections (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _hitPointsAddedNames = []; private _hitPointsAddedStrings = []; private _hitPointsAddedAmount = []; -private _processedSelections = []; private _icon = ["a3\ui_f\data\igui\cfg\actions\repair_ca.paa", "#FFFFFF"]; +private _vehCfg = configOf _vehicle; // Custom position can be defined via config for associated hitpoint -private _hitpointPositions = getArray (configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions)); -// Associated hitpoints can be grouped via config to produce a single repair action -private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups)); +private _hitpointPositions = getArray (_vehCfg >> QGVAR(hitpointPositions)); +// Get turret paths +private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehicle, "commander", true])) apply {_x # 3}; { private _selection = _x; - private _hitpoint = toLower (_hitPoints select _forEachIndex); - if (_selection in _wheelHitSelections) then { - // Wheels should always be unique - if (_selection in _processedSelections) exitWith {TRACE_3("Duplicate Wheel",_hitpoint,_forEachIndex,_selection);}; + private _hitpoint = toLowerANSI (_hitPoints select _forEachIndex); - private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; + // Skip ignored selections + if (_forEachIndex in _selectionsToIgnore) then { + TRACE_3("Skipping ignored hitpoint",_hitpoint,_forEachIndex,_selection); + continue + }; + + if (_selection in _wheelHitSelections) then { + private _position = compile format ["_target selectionPosition ['%1', 'HitPoints', 'AveragePoint'];", _selection]; TRACE_3("Adding Wheel Actions",_hitpoint,_forEachIndex,_selection); - // An action to remove the wheel is required - private _name = format ["Remove_%1_%2", _forEachIndex, _hitpoint]; - private _text = localize LSTRING(RemoveWheel); - private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)}; - private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)}; - private _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2, nil, FUNC(modifySelectionInteraction)] call EFUNC(interact_menu,createAction); - [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); - // An action to replace the wheel is required _name = format ["Replace_%1_%2", _forEachIndex, _hitpoint]; _text = localize LSTRING(ReplaceWheel); @@ -69,38 +73,50 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); - _processedSelections pushBack _selection; + // Create a wheel interaction + private _root = format ["Wheel_%1_%2", _forEachIndex, _hitpoint]; + private _action = [_root, localize LSTRING(Wheel), ["","#FFFFFF"], {}, {true}, {}, [_hitpoint], _position, 2, nil, LINKFUNC(modifySelectionInteraction)] call EFUNC(interact_menu,createAction); + [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); + + // An action to remove the wheel is required + private _name = format ["Remove_%1_%2", _forEachIndex, _hitpoint]; + private _text = localize LSTRING(RemoveWheel); + private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)}; + private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)}; + private _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); + [_type, 0, [_root], _action] call EFUNC(interact_menu,addActionToClass); + + // An action to patch the wheel is required. + private _name = format ["Patch_%1_%2", _forEachIndex, _hitpoint]; + private _patchIcon = QPATHTOF(ui\patch_ca.paa); + private _text = localize LSTRING(PatchWheel); + private _condition = {("vehicle" in GVAR(patchWheelLocation)) && {[_this select 1, _this select 0, _this select 2 select 0, "PatchWheel"] call DFUNC(canRepair)}}; + private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "PatchWheel"] call DFUNC(repair)}; + private _action = [_name, _text, _patchIcon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); + [_type, 0, [_root], _action] call EFUNC(interact_menu,addActionToClass); } else { - // Empty selections don't exist - if (_selection isEqualTo "") exitWith { TRACE_3("Skipping Empty Sel",_hitpoint,_forEachIndex,_selection); }; - // Empty hitpoints don't contain enough information - if (_hitpoint isEqualTo "") exitWith { TRACE_3("Skipping Empty Hit",_hitpoint,_forEachIndex,_selection); }; - // Ignore glass hitpoints - if ((_hitpoint find "glass") != -1) exitWith { TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); }; - // Ignore hitpoints starting with # (seems to be lights) - if ((_hitpoint select [0,1]) == "#") exitWith { TRACE_3("Skipping # hit",_hitpoint,_forEachIndex,_selection); }; - // Ignore ERA/Slat armor (vanilla uses hitera_/hitslat_, pre-1.82 RHS uses era_) - // ToDo: see how community utilizes new armor system, could also check getText (_hitpointConfig >> "simulation") - if (((_hitpoint select [0,7]) == "hitera_") || {(_hitpoint select [0,8]) == "hitslat_"} || {(_hitpoint select [0,4]) == "era_"}) exitWith { TRACE_3("Skipping ERA/SLAT",_hitpoint,_forEachIndex,_selection); }; - - - //Depends hitpoints shouldn't be modified directly (will be normalized) - // Biki: Clearing 'depends' in case of inheritance cannot be an empty string (rpt warnings), but rather a "0" value. - if (!((getText (configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) exitWith { - TRACE_3("Skip Depends",_hitpoint,_forEachIndex,_selection); + // Some hitpoints do not have a selection but do have an armorComponent value (seems to mainly be RHS) + // Ref https://community.bistudio.com/wiki/Arma_3_Damage_Enhancement + // this code won't support identically named hitpoints (e.g. commander turret: Duplicate HitPoint name 'HitTurret') + private _armorComponent = ""; + if (_selection == "") then { + private _hitpointsCfg = "configName _x == _hitpoint" configClasses (_vehCfg >> "HitPoints"); + if (_hitpointsCfg isNotEqualTo []) then { + _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); + }; + if (_armorComponent == "") then { + { + private _turretHitpointCfg = ([_vehCfg, _x] call CBA_fnc_getTurret) >> "HitPoints"; + private _hitpointsCfg = "configName _x == _hitpoint" configClasses _turretHitpointCfg; + if (_hitpointsCfg isNotEqualTo []) exitWith { + TRACE_2("turret hitpoint configFound",_hitpoint,_x); + _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); + }; + } forEach _turretPaths; + }; + if (_armorComponent != "") then { INFO_3("%1: %2 no selection: using armorComponent %3",_type,_hitpoint,_armorComponent); }; }; - private _childHitPoint = false; - { - { - if (_hitpoint == _x) exitWith { - _childHitPoint = true; - }; - } forEach (_x select 1); - } forEach _hitpointGroups; - // If the current selection is associated with a child hitpoint, then skip - if (_childHitPoint) exitWith { TRACE_3("childHitpoint",_hitpoint,_forEachIndex,_selection); }; - // Find the action position private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; { @@ -116,6 +132,17 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR }; } forEach _hitpointPositions; + // if no selection then use the FireLOD to position the action + if ((_selection == "") && {_position isEqualTo {_target selectionPosition ['', 'HitPoints'];}}) then { + if ((_vehicle selectionPosition [_armorComponent, "FireGeometry"]) isEqualTo [0,0,0]) then { + WARNING_3("[%1: %2: %3] armorComponent does not exist?",_type,_hitpoint,_armorComponent); + _position = [0,0,0]; // just stick it on mainActions + } else { + _position = compile format ["_target selectionPosition ['%1', 'FireGeometry'];", _armorComponent]; + }; + TRACE_1("using armorComponent position",_position); + }; + // Prepare the repair action private _name = format ["Repair_%1_%2", _forEachIndex, _selection]; @@ -126,8 +153,6 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR _hitPointsAddedAmount = _trackArray select 2; if (_hitpoint in TRACK_HITPOINTS) then { - // Tracks should always be unique - if (_selection in _processedSelections) exitWith {TRACE_3("Duplicate Track",_hitpoint,_forEachIndex,_selection);}; _position = compile format ["private _return = _target selectionPosition ['%1', 'HitPoints']; _return set [1, 0]; _return", _selection]; TRACE_4("Adding RepairTrack",_hitpoint,_forEachIndex,_selection,_text); private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(canRepair)}; @@ -146,8 +171,6 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); }; }; - - _processedSelections pushBack _selection; }; } forEach _hitSelections; diff --git a/addons/repair/functions/fnc_addSpareParts.sqf b/addons/repair/functions/fnc_addSpareParts.sqf index c83397ed4b..0f2a5c26cc 100644 --- a/addons/repair/functions/fnc_addSpareParts.sqf +++ b/addons/repair/functions/fnc_addSpareParts.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Adds spare parts to the vehicle. Before SettingsInitialized only collect for later execution. diff --git a/addons/repair/functions/fnc_canMiscRepair.sqf b/addons/repair/functions/fnc_canMiscRepair.sqf index b9fe842a19..d5e55c5a13 100644 --- a/addons/repair/functions/fnc_canMiscRepair.sqf +++ b/addons/repair/functions/fnc_canMiscRepair.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Check if misc repair action can be done, called from callbackSuccess. @@ -24,7 +24,7 @@ params ["_caller", "_target", "_hitPointIndex"]; if !([_caller, _target, ["isNotDragging", "isNotCarrying", "isNotSwimming", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Get hitpoint groups if available -private _hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(hitpointGroups); +private _hitpointGroupConfig = configOf _target >> QGVAR(hitpointGroups); private _hitpointGroup = []; if (isArray _hitpointGroupConfig) then { private _hitPointClassname = _allHitPoints select _hitPointIndex; diff --git a/addons/repair/functions/fnc_canPatchRemovedWheel.sqf b/addons/repair/functions/fnc_canPatchRemovedWheel.sqf new file mode 100644 index 0000000000..261b3e5699 --- /dev/null +++ b/addons/repair/functions/fnc_canPatchRemovedWheel.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, Brett Mayson + * Check if the unit can patch a wheel not on a vehicle. + * + * Arguments: + * 0: Unit that does the patching + * 1: Wheel to patch + * + * Return Value: + * Can patch wheel? + * + * Example: + * [unit, vehicle] call ace_repair_fnc_canPatchRemovedWheel + * + * Public: No + */ + +params ["_unit", "_target"]; +TRACE_2("params",_unit,_target); + +if (GVAR(patchWheelEnabled) == -1) exitWith {false}; +if !("ground" in GVAR(patchWheelLocation)) exitWith {false}; +if ((GVAR(patchWheelRequiredItems) isEqualTo [ANY_TOOLKIT_FAKECLASS]) && {!([_unit, [GVAR(allToolKits)]] call FUNC(hasItems))}) exitWith {false}; +if !([_unit, GVAR(patchWheelEnabled)] call FUNC(isEngineer)) exitWith {false}; + +(damage _target > GVAR(patchWheelMaximumRepair)) diff --git a/addons/repair/functions/fnc_canPatchWheel.sqf b/addons/repair/functions/fnc_canPatchWheel.sqf new file mode 100644 index 0000000000..0338f05729 --- /dev/null +++ b/addons/repair/functions/fnc_canPatchWheel.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, Brett Mayson + * Check if the unit can patch given wheel of the vehicle. + * + * Arguments: + * 0: Unit that does the patching + * 1: Vehicle to patch + * 2: Selected wheel hitpoint + * + * Return Value: + * Can patch wheel? + * + * Example: + * [unit, vehicle, "hitpoint"] call ace_repair_fnc_canPatchWheel + * + * Public: No + */ + +params ["_unit", "_target", "_hitPoint"]; +TRACE_3("params",_unit,_target,_hitPoint); + +if (GVAR(patchWheelEnabled) == -1) exitWith {false}; + +private _damage = _target getHitPointDamage _hitPoint; + +if (_damage == 1) exitWith {false}; + +if !([_unit, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; + +(_damage > GVAR(patchWheelMaximumRepair)) diff --git a/addons/repair/functions/fnc_canRemove.sqf b/addons/repair/functions/fnc_canRemove.sqf index 77fc7b0eb4..b487964535 100644 --- a/addons/repair/functions/fnc_canRemove.sqf +++ b/addons/repair/functions/fnc_canRemove.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit can remove given wheel/track of the vehicle. diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index 93d5eef7a0..ff61450b12 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if the repair action can be performed. @@ -37,18 +37,8 @@ private _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { }; if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitWith {false}; -//Items can be an array of required items or a string to a ACE_Setting array -private _items = if (isArray (_config >> "items")) then { - getArray (_config >> "items"); -} else { - private _settingName = getText (_config >> "items"); - private _settingItemsArray = getArray (configFile >> "ACE_Settings" >> _settingName >> "_values"); - if ((isNil _settingName) || {(missionNamespace getVariable _settingName) >= (count _settingItemsArray)}) exitWith { - ERROR("bad setting"); ["BAD"] - }; - _settingItemsArray select (missionNamespace getVariable _settingName); -}; -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; +private _items = _config call FUNC(getRepairItems); +if (_items isNotEqualTo [] && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; private _return = true; if (getText (_config >> "condition") != "") then { @@ -75,14 +65,14 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { if (_x == "field") exitWith {_return = true;}; if (_x == "RepairFacility" && _repairFacility) exitWith {_return = true;}; if (_x == "RepairVehicle" && _repairVeh) exitWith {_return = true;}; - if !(isNil _x) exitWith { + if (!isNil _x) exitWith { private _val = missionNamespace getVariable _x; if (_val isEqualType 0) then { _return = switch (_val) do { @@ -100,7 +90,7 @@ if (!_return) exitWith {false}; //Check that there are required objects nearby private _requiredObjects = getArray (_config >> "claimObjects"); -if (!(_requiredObjects isEqualTo [])) then { +if (_requiredObjects isNotEqualTo []) then { private _objectsAvailable = [_caller, 5, _requiredObjects] call FUNC(getClaimObjects); if (_objectsAvailable isEqualTo []) then { TRACE_2("Missing Required Objects",_requiredObjects,_objectsAvailable); diff --git a/addons/repair/functions/fnc_canRepairTrack.sqf b/addons/repair/functions/fnc_canRepairTrack.sqf index 8559ff1a9c..1ee88d373e 100644 --- a/addons/repair/functions/fnc_canRepairTrack.sqf +++ b/addons/repair/functions/fnc_canRepairTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit can replace given track of the vehicle. diff --git a/addons/repair/functions/fnc_canReplaceTrack.sqf b/addons/repair/functions/fnc_canReplaceTrack.sqf index d975c60efb..abafa79835 100644 --- a/addons/repair/functions/fnc_canReplaceTrack.sqf +++ b/addons/repair/functions/fnc_canReplaceTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit can replace given track of the vehicle. diff --git a/addons/repair/functions/fnc_canReplaceWheel.sqf b/addons/repair/functions/fnc_canReplaceWheel.sqf index 54e8e8cdf6..dae0a0e9d4 100644 --- a/addons/repair/functions/fnc_canReplaceWheel.sqf +++ b/addons/repair/functions/fnc_canReplaceWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Check if the unit can replace given wheel of the vehicle. diff --git a/addons/repair/functions/fnc_doFullRepair.sqf b/addons/repair/functions/fnc_doFullRepair.sqf index fb248e6a2f..5027fcf280 100644 --- a/addons/repair/functions/fnc_doFullRepair.sqf +++ b/addons/repair/functions/fnc_doFullRepair.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Fully repairs vehicle. diff --git a/addons/repair/functions/fnc_doPatchWheelProgress.sqf b/addons/repair/functions/fnc_doPatchWheelProgress.sqf new file mode 100644 index 0000000000..4d9b84ebc2 --- /dev/null +++ b/addons/repair/functions/fnc_doPatchWheelProgress.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, Brett Mayson + * Called by repair action / progress bar. Raise events to set the new hitpoint damage. + * + * Arguments: + * 0: Unit that does the patching + * 1: Vehicle to patch + * 2: Selected wheel hitpoint + * + * Return Value: + * Should patching continue? + * + * Example: + * [unit, vehicle, "hitpoint"] call ace_repair_fnc_doPatchWheelProgress + * + * Public: No + */ + +params ["_args", "_elapsedTime", "_totalTime"]; +_args params ["_unit", "_vehicle", "_hitPoint"]; +TRACE_3("params",_unit,_vehicle,_hitPoint); + +// get current hitpoint damage +private _hitPointDamage = _vehicle getHitPointDamage _hitPoint; + +private _iterationsRemaining = ceil ((_hitPointDamage - GVAR(patchWheelMaximumRepair)) / PATCH_WHEEL_STEP_TIME) - 1; +if ((_totalTime - _elapsedTime) > _iterationsRemaining * GVAR(patchWheelTime)) exitWith {true}; + +_hitPointDamage = (_hitPointDamage - PATCH_WHEEL_STEP_TIME) max GVAR(patchWheelMaximumRepair); + +// raise event to set the new hitpoint damage +[QGVAR(setWheelHitPointDamage), [_vehicle, _hitPoint, _hitPointDamage], _vehicle] call CBA_fnc_targetEvent; + +(_hitPointDamage > GVAR(patchWheelMaximumRepair)) diff --git a/addons/repair/functions/fnc_doRemoveTrack.sqf b/addons/repair/functions/fnc_doRemoveTrack.sqf index d15993752f..6e882061ce 100644 --- a/addons/repair/functions/fnc_doRemoveTrack.sqf +++ b/addons/repair/functions/fnc_doRemoveTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. diff --git a/addons/repair/functions/fnc_doRemoveWheel.sqf b/addons/repair/functions/fnc_doRemoveWheel.sqf index 127859a5b9..4715bf080f 100644 --- a/addons/repair/functions/fnc_doRemoveWheel.sqf +++ b/addons/repair/functions/fnc_doRemoveWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. diff --git a/addons/repair/functions/fnc_doRepair.sqf b/addons/repair/functions/fnc_doRepair.sqf index c17858d8b3..58dd4590bb 100644 --- a/addons/repair/functions/fnc_doRepair.sqf +++ b/addons/repair/functions/fnc_doRepair.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. @@ -7,6 +7,7 @@ * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpointIndex + * 3: Repair action classname * * Return Value: * None @@ -17,10 +18,11 @@ * Public: No */ -params ["_unit", "_vehicle", "_hitPointIndex"]; -TRACE_3("params",_unit,_vehicle,_hitPointIndex); +params ["_unit", "_vehicle", "_hitPointIndex", "_action"]; +TRACE_4("params",_unit,_vehicle,_hitPointIndex,_action); -private _postRepairDamageMin = [_unit] call FUNC(getPostRepairDamage); +// override minimum damage if doing full repair +private _postRepairDamageMin = [_unit, _action isEqualTo "fullRepair"] call FUNC(getPostRepairDamage); (getAllHitPointsDamage _vehicle) params ["_allHitPoints"]; private _hitPointClassname = _allHitPoints select _hitPointIndex; @@ -33,13 +35,13 @@ private _hitPointNewDamage = (_hitPointCurDamage - 0.5) max _postRepairDamageMin if (_hitPointNewDamage < _hitPointCurDamage) then { // raise event to set the new hitpoint damage - TRACE_3("repairing main point", _vehicle, _hitPointIndex, _hitPointNewDamage); + TRACE_3("repairing main point",_vehicle,_hitPointIndex,_hitPointNewDamage); [QGVAR(setVehicleHitPointDamage), [_vehicle, _hitPointIndex, _hitPointNewDamage], _vehicle] call CBA_fnc_targetEvent; _hitPointCurDamage = _hitPointNewDamage; }; // Get hitpoint groups if available -private _hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(hitpointGroups); +private _hitpointGroupConfig = configOf _vehicle >> QGVAR(hitpointGroups); if (isArray _hitpointGroupConfig) then { // Retrieve hitpoint subgroup if current hitpoint is main hitpoint of a group { @@ -55,7 +57,7 @@ if (isArray _hitpointGroupConfig) then { private _subPointCurDamage = _vehicle getHitIndex _hitPointIndex; private _subPointNewDamage = (_subPointCurDamage - 0.5) max _postRepairDamageMin; if (_subPointNewDamage < _subPointCurDamage) then { - TRACE_3("repairing sub point", _vehicle, _subHitIndex, _subPointNewDamage); + TRACE_3("repairing sub point",_vehicle,_subHitIndex,_subPointNewDamage); [QGVAR(setVehicleHitPointDamage), [_vehicle, _subHitIndex, _subPointNewDamage], _vehicle] call CBA_fnc_targetEvent; }; }; diff --git a/addons/repair/functions/fnc_doRepairTrack.sqf b/addons/repair/functions/fnc_doRepairTrack.sqf index 71d06b60f2..519a3f78d6 100644 --- a/addons/repair/functions/fnc_doRepairTrack.sqf +++ b/addons/repair/functions/fnc_doRepairTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ERROR_1("Bad Track", _claimedObjects); + ERROR_1("Bad Track",_claimedObjects); }; // can't use a destroyed track diff --git a/addons/repair/functions/fnc_doReplaceTrack.sqf b/addons/repair/functions/fnc_doReplaceTrack.sqf index 60dd486f44..a512089c89 100644 --- a/addons/repair/functions/fnc_doReplaceTrack.sqf +++ b/addons/repair/functions/fnc_doReplaceTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Replaces a track. @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ERROR_1("Bad Track", _claimedObjects); + ERROR_1("Bad Track",_claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_doReplaceWheel.sqf b/addons/repair/functions/fnc_doReplaceWheel.sqf index e42c7cabf2..7ec617127c 100644 --- a/addons/repair/functions/fnc_doReplaceWheel.sqf +++ b/addons/repair/functions/fnc_doReplaceWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Repairs a vehicle's wheel with a ACE_wheel spare part object. @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_wheel", objNull]]; if ((isNull _wheel) || {!([_unit, _wheel, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - WARNING_1("Bad Claimed Wheel", _claimedObjects); + WARNING_1("Bad Claimed Wheel",_claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_fullRepairProgress.sqf b/addons/repair/functions/fnc_fullRepairProgress.sqf new file mode 100644 index 0000000000..b021c492c0 --- /dev/null +++ b/addons/repair/functions/fnc_fullRepairProgress.sqf @@ -0,0 +1,49 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Handles full repair by periodically repairing damaged hitpoints. + * + * Arguments: + * 0: Arguments + * 0: Engineer + * 1: Vehicle + * 2: Hitpoint (unused) + * 3: Repair action classname + * 1: Elapsed Time + * 2: Total Time + * + * Return Value: + * Continue Repair + * + * Example: + * [[objNull, player], 5, 10] call ace_repair_fnc_fullRepairProgress + * + * Public: No + */ + +params ["_args", "_elapsedTime", "_totalTime"]; +_args params ["_engineer", "_vehicle", "", "_action"]; + +if !((alive _vehicle) && {(abs speed _vehicle) < 1}) exitWith {false}; // make sure vehicle doesn't drive off + +// Not enough time has elapsed to repair a hitpoint +if (_totalTime - _elapsedTime > ([_engineer, _vehicle] call FUNC(getFullRepairTime)) - (GVAR(miscRepairTime) * GVAR(timeCoefficientFullRepair))) exitWith {true}; + +private _allHitPointsDamage = getAllHitPointsDamage _vehicle; +_allHitPointsDamage params ["_hitPoints", "", "_damageValues"]; + +private _selectionsToIgnore = _vehicle call FUNC(getSelectionsToIgnore); + +private _firstDamagedIndex = { + if (_x > 0 && {!(_forEachIndex in _selectionsToIgnore)}) exitWith {_forEachIndex}; + -1 +} forEach _damageValues; + +// Stop repairing if there are no more damaged hitpoints +// callBackSuccess to FUNC(doFullRepair) for ignored hitpoints +if (_firstDamagedIndex == -1) exitWith {true}; + +// Repair the first damaged hitpoint +[_engineer, _vehicle, _firstDamagedIndex, _action] call FUNC(doRepair); + +true diff --git a/addons/repair/functions/fnc_getClaimObjects.sqf b/addons/repair/functions/fnc_getClaimObjects.sqf index a654952417..ca02ef14c1 100644 --- a/addons/repair/functions/fnc_getClaimObjects.sqf +++ b/addons/repair/functions/fnc_getClaimObjects.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Returns array of required nearby repair objects (wheels/tracks). @@ -7,6 +7,7 @@ * 0: Unit that does the repairing * 1: Max range to seach from unit (meters) * 2: Array of arrays of classnames + * 3: Sort objects by damage (default: false) * * Return Value: * Array of objects, or [] if not all available @@ -17,29 +18,29 @@ * Public: Yes */ -params ["_unit", "_maxRange", "_objectsToClaim"]; -TRACE_3("params",_unit,_maxRange,_objectsToClaim); +params ["_unit", "_maxRange", "_objectsToClaim", ["_sortByDamage", false]]; +TRACE_4("params",_unit,_maxRange,_objectsToClaim,_sortByDamage); private _return = []; { private _requiredList = _x; //eg ["ace_track", "ace_track"] - private _ableToAquire = []; //will be array of ojbects + private _ableToAquire = []; //will be array of objects { - private _nearObjects = nearestObjects [_unit, [_x], _maxRange]; - private _canClaimObject = objNull; + private _nearObjects = _unit nearEntities [_x, _maxRange]; + if (_sortByDamage && {count _nearObjects > 1}) then { + _nearObjects = _nearObjects apply {[damage _x, _x]}; + _nearObjects sort true; + _nearObjects = _nearObjects apply {_x select 1}; + }; { - if ((!(_x in _ableToAquire)) - && {[_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)} - &&{(damage _x) < 1} - ) exitWith { _canClaimObject = _x; }; + if (!(_x in _ableToAquire) && {(_x getVariable [QEGVAR(common,owner), objNull]) in [objNull, _unit]}) exitWith { // skip claimed objects + _ableToAquire pushBack _x + }; } forEach _nearObjects; - if (isNull _canClaimObject) exitWith {}; - _ableToAquire pushBack _canClaimObject; - } forEach _x; + } forEach _requiredList; TRACE_2("Check required equals available",_requiredList,_ableToAquire); if ((count _ableToAquire) == (count _requiredList)) exitWith {_return = _ableToAquire}; - false -} count _objectsToClaim; +} forEach _objectsToClaim; _return diff --git a/addons/repair/functions/fnc_getFullRepairTime.sqf b/addons/repair/functions/fnc_getFullRepairTime.sqf new file mode 100644 index 0000000000..a570685328 --- /dev/null +++ b/addons/repair/functions/fnc_getFullRepairTime.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Calculates the Full Repair time based on the amount of hitpoints to repair + * + * Arguments: + * 0: Engineer + * 1: Vehicle + * + * Return Value: + * Repair Time + * + * Example: + * [player, vehicle] call ace_repair_fnc_getFullRepairTime + * + * Public: No + */ + +params ["_engineer", "_vehicle"]; + +private _allHitPointsDamage = getAllHitPointsDamage _vehicle; +_allHitPointsDamage params ["_hitPoints", "", "_damageValues"]; + +private _selectionsToIgnore = _vehicle call FUNC(getSelectionsToIgnore); + +private _repairsNeeded = 0; +private _doExtraRepair = false; +{ + if (_x <= 0) then {continue}; // skip hitpoints that don't need repairs + if (_forEachIndex in _selectionsToIgnore) then { // only add extra repair for ignore hitpoints if they're damaged + _doExtraRepair = true; + continue + }; + _repairsNeeded = _repairsNeeded + ceil (_x / 0.5); // repair is capped at 0.5 in FUNC(doRepair) +} forEach _damageValues; + +if (_doExtraRepair) then { + _repairsNeeded = _repairsNeeded + 1; +}; + +_repairsNeeded * GVAR(miscRepairTime) * GVAR(timeCoefficientFullRepair) // return diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index 7439d35c12..23a57f8895 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Finds the localized string of the given hitpoint name or uses default text if none found. @@ -20,24 +20,19 @@ */ params ["_hitPoint", "_textLocalized", "_textDefault", ["_trackArray", []]]; +_trackArray params [["_trackNames", []], ["_trackStrings", []], ["_trackAmount", []]]; -private _track = (count _trackArray > 0); -private _trackNames = []; -private _trackStrings = []; -private _trackAmount = []; - -if (_track) then { - _trackNames = _trackArray select 0; - _trackStrings = _trackArray select 1; - _trackAmount = _trackArray select 2; -}; +private _track = _trackArray isNotEqualTo []; // Prepare first part of the string from stringtable //IGNORE_STRING_WARNING(str_ace_repair_hit); private _text = LSTRING(Hit); +// Remove # prefix +if ((_hitpoint select [0, 1]) == "#") then { _hitPoint = _hitPoint select [1] }; + // Remove "Hit" from hitpoint name if one exists -private _toFind = if ((toLower _hitPoint) find "hit" == 0) then { +private _toFind = if ((toLowerANSI _hitPoint) find "hit" == 0) then { [_hitPoint, 3] call CBA_fnc_substr } else { _hitPoint @@ -83,7 +78,7 @@ for "_i" from 0 to (count _hitPoint) do { // Don't display part name if no string is found in stringtable if (_text == LSTRING(Hit)) then { - if (_hitPoint != "") then { LOG_1("Hitpoint [%1] - could not be localized", _hitPoint); }; + if (_hitPoint != "") then { LOG_1("Hitpoint [%1] - could not be localized",_hitPoint); }; _text = _textDefault; }; diff --git a/addons/repair/functions/fnc_getPatchWheelTime.sqf b/addons/repair/functions/fnc_getPatchWheelTime.sqf new file mode 100644 index 0000000000..7406261e79 --- /dev/null +++ b/addons/repair/functions/fnc_getPatchWheelTime.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Calculate the time to patch the wheel + * + * Arguments: + * 0: Unit that does the patching + * 1: Vehicle to patch + * 2: Selected wheel hitpoint + * + * Return Value: + * Patching time + * + * Example: + * [unit, vehicle, "hitpoint"] call ace_repair_fnc_getPatchWheelTime + * + * Public: No + */ + +params ["_unit", "_vehicle", "_hitPoint"]; + +// get current hitpoint damage +private _hitPointDamage = (_vehicle getHitPointDamage _hitPoint) - GVAR(patchWheelMaximumRepair); + +ceil (_hitPointDamage / PATCH_WHEEL_STEP_TIME) * GVAR(patchWheelTime) diff --git a/addons/repair/functions/fnc_getPostRepairDamage.sqf b/addons/repair/functions/fnc_getPostRepairDamage.sqf index d8ed7d3804..5135ba25a7 100644 --- a/addons/repair/functions/fnc_getPostRepairDamage.sqf +++ b/addons/repair/functions/fnc_getPostRepairDamage.sqf @@ -1,13 +1,14 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Returns the damage threshold based on settings and unit type. * * Arguments: * 0: Unit that does the repairing + * 1: Override for full repair (default: false) * * Return Value: - * 0: Rpair Damage Threshold + * 0: Repair Damage Threshold * * Example: * [unit] call ace_repair_fnc_getPostRepairDamage @@ -15,13 +16,13 @@ * Public: No */ -params ["_unit"]; -TRACE_1("params",_unit); +params ["_unit", ["_override", false]]; +TRACE_2("params",_unit,_override); -//If in facility or near vehicle then complete repair of hitpoint: -if (([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)})) exitWith {0}; +//If in facility, near vehicle, or doing full repair then complete repair of hitpoint: +if ((_override || {[_unit] call FUNC(isInRepairFacility)} || {[_unit] call FUNC(isNearRepairVehicle)})) exitWith {0}; -private _class = _unit getVariable ["ACE_IsEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer")]; +private _class = _unit getVariable ["ACE_IsEngineer", getNumber (configOf _unit >> "engineer")]; //If advanced or more qualified than min, then use engineer threshold: if ((_class isEqualTo 2) || {[_unit, GVAR(engineerSetting_Repair) + 1] call FUNC(isEngineer)}) exitWith { (GVAR(repairDamageThreshold_Engineer) min GVAR(repairDamageThreshold)) diff --git a/addons/repair/functions/fnc_getRepairItems.sqf b/addons/repair/functions/fnc_getRepairItems.sqf new file mode 100644 index 0000000000..95eaffcf02 --- /dev/null +++ b/addons/repair/functions/fnc_getRepairItems.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Returns the items required for repair. + * + * Arguments: + * 0: Repair config + * + * Return Value: + * 0: Required items + * + * Example: + * [_config] call ace_repair_fnc_getRepairItems + * + * Public: No + */ + +params [["_config", configNull]]; + +// Items can be an array of required items or a string to a missionNamespace variable +private _items = if (isArray (_config >> "items")) then { + getArray (_config >> "items"); +} else { + missionNamespace getVariable [getText (_config >> "items"), []] +}; + +// handle "any toolkit" setting +if (_items isEqualTo [ANY_TOOLKIT_FAKECLASS]) then { + TRACE_1("any toolkit",_items); + + // array element inside items array means "any of these items" + _items = [GVAR(allToolKits)]; +}; + +TRACE_2("get repair items",_config,_items); + +_items diff --git a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf new file mode 100644 index 0000000000..455b58c040 --- /dev/null +++ b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf @@ -0,0 +1,153 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, kymckay, LinkIsGrim + * Get list of vehicle hitpoints to ignore + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * HitPoints to ignore + * + * Example: + * [vehicle] call ace_repair_fnc_getSelectionsToIgnore + * + * Public: No + */ + +params ["_vehicle"]; + +private _type = typeOf _vehicle; +TRACE_2("getSelectionsToIgnore",_vehicle,_type); +private _initializedClasses = missionNamespace getVariable [QGVAR(hitPointsToIgnoreInitializedClasses), createHashMap]; +if (_type in _initializedClasses) exitWith {_initializedClasses get _type}; + +private _vehCfg = configOf _vehicle; +private _hitpointGroups = getArray (_vehCfg >> QGVAR(hitpointGroups)); +private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehicle, "commander", true])) apply {_x # 3}; + +(getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; +// get hitpoints of wheels with their selections +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + +private _indexesToIgnore = []; +private _processedSelections = []; + +{ + private _selection = _x; + private _hitpoint = toLowerANSI (_hitPoints select _forEachIndex); + private _isWheelOrTrack = _selection in _wheelHitSelections || {_hitpoint in _wheelHitPoints} || {_hitpoint in TRACK_HITPOINTS}; + + if (_hitpoint isEqualTo "") then { // skip empty hitpoint + _indexesToIgnore pushBack _forEachIndex; + continue + }; + + if (_isWheelOrTrack && {_selection in _processedSelections || {_selection isEqualTo ""}}) then { // skip duplicate or empty selection wheel/track + TRACE_3("Skipping duplicate Wheel/Track or empty selection",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping duplicate wheel, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _indexesToIgnore pushBack _forEachIndex; + _processedSelections pushBack _selection; + continue + }; + + if ("glass" in _hitpoint) then { // skip glass + TRACE_3("Skipping glass",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping glass, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _indexesToIgnore pushBack _forEachIndex; + _processedSelections pushBack _selection; + continue + }; + + if (_hitpoint select [0,7] isEqualTo "hitera_" || {_hitpoint select [0,8] isEqualTo "hitslat_"} || {_hitpoint select [0,4] isEqualTo "era_"}) then { // skip era/slat + TRACE_3("Skipping ERA/Slat HitPoint",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping ERA/SLAT, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _indexesToIgnore pushBack _forEachIndex; + _processedSelections pushBack _selection; + continue + }; + + private _armorComponent = ""; + if (_selection == "") then { // some hitpoints have empty selection but defined armor component (mostly RHS) + { + private _turretHitpointCfg = ([_vehCfg, _x] call CBA_fnc_getTurret) >> "HitPoints"; + private _hitpointsCfg = "configName _x == _hitpoint" configClasses _turretHitpointCfg; + if (_hitpointsCfg isNotEqualTo []) exitWith { + TRACE_2("turret hitpoint configFound",_hitpoint,_x); + _hitpointsCfg = _hitpointsCfg # 0; + // only do turret hitpoints and stuff linked to visuals + if ( + (_hitpoint in ["hitturret", "hitgun"]) || + {(getNumber (_hitpointsCfg >> "isGun")) == 1} || + {(getNumber (_hitpointsCfg >> "isTurret")) == 1} || + {(getText (_hitpointsCfg >> "visual")) != ""} + ) then { + _armorComponent = getText (_hitpointsCfg >> "armorComponent"); + }; + }; + } forEach _turretPaths; + if (_armorComponent == "") then { + private _hitpointsCfg = "configName _x == _hitpoint" configClasses (_vehCfg >> "HitPoints"); + if (_hitpointsCfg isNotEqualTo []) then { + _hitpointsCfg = _hitpointsCfg # 0; + if ( + (getNumber (_hitpointsCfg >> "isGun")) == 1 || + {(getNumber (_hitpointsCfg >> "isTurret")) == 1} || + {(getText (_hitpointsCfg >> "visual")) != ""} + ) then { + _armorComponent = getText (_hitpointsCfg >> "armorComponent"); + }; + }; + }; + }; + + if ((_selection == "") && {_armorComponent == ""}) then { + TRACE_3("Skipping no selection OR armor component",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping no selection OR armor component, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _indexesToIgnore pushBack _forEachIndex; + _processedSelections pushBack _selection; + continue + }; + + if !(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"]) then { // skip depends hitpoints, should be normalized by engine + TRACE_3("Skipping depends hitpoint",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping depends hitpoint, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + + private _groupIndex = _hitpointGroups findIf {_x # 0 == _hitpoint}; + if (_groupIndex != -1) then { + ERROR_2("[%1] hitpoint [%2] is both a group-parent and a depends and will be unrepairable",_type,_hitpoint); + ERROR_1("group: %1",_hitpointGroups # _groupIndex); + }; + + _indexesToIgnore pushBack _forEachIndex; + _processedSelections pushBack _selection; + continue + }; + + if (ANY_OF(_hitpointGroups,ANY_OF(_x select 1,_x == _hitpoint))) then { // skip child hitpoints + TRACE_3("Skipping child hitpoint",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping child hitpoint, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _indexesToIgnore pushBack _forEachIndex; + _processedSelections pushBack _selection; + continue + }; + + _processedSelections pushBack _selection; +} forEach _hitSelections; + +_initializedClasses set [_type, _indexesToIgnore]; +missionNamespace setVariable [QGVAR(hitPointsToIgnoreInitializedClasses), _initializedClasses]; + +_indexesToIgnore diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf deleted file mode 100644 index fe072859b2..0000000000 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ /dev/null @@ -1,97 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Returns the wheel hitpoints and their selections. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * 0: Wheel hitpoints - * 1: Wheel hitpoint selections in model coordinates - * - * Example: - * [car1] call ace_repair_fnc_getWheelHitPointsWithSelections - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -// get the vehicles wheel config -private _wheels = configFile >> "CfgVehicles" >> typeOf _vehicle >> "Wheels"; - -// exit with nothing if the vehicle has no wheels class -if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; - -// get all hitpoints and selections -(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; - -// get all wheels and read selections from config -_wheels = "true" configClasses _wheels; - -private _wheelHitPoints = []; -private _wheelHitPointSelections = []; - -{ - private _wheelName = configName _x; - private _wheelCenter = getText (_x >> "center"); - private _wheelBone = getText (_x >> "boneName"); - private _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - - TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - - private _wheelHitPoint = ""; - private _wheelHitPointSelection = ""; - - //Commy's orginal method - { - if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. - _wheelHitPoint = _hitPoints select _forEachIndex; - _wheelHitPointSelection = _hitPointSelections select _forEachIndex; - TRACE_2("wheel found [Orginal]", _wheelName, _wheelHitPoint); - }; - } forEach _hitPointSelections; - - - if (_vehicle isKindOf "Car") then { - //Backup method, search for the closest hitpoint to the wheel's center selection pos. - //Ref #2742 - RHS's HMMWV - if (_wheelHitPoint == "") then { - private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; - if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; - - - private _bestDist = 99; - private _bestIndex = -1; - { - if (_x != "") then { - //Filter out things that definitly aren't wheeels (#3759) - if ((toLower (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; - private _xPos = _vehicle selectionPosition _x; - if (_xPos isEqualTo [0,0,0]) exitWith {}; - private _xDist = _wheelCenterPos distance _xPos; - if (_xDist < _bestDist) then { - _bestIndex = _forEachIndex; - _bestDist = _xDist; - }; - }; - } forEach _hitPointSelections; - - TRACE_2("closestPoint",_bestDist,_bestIndex); - if (_bestIndex != -1) then { - _wheelHitPoint = _hitPoints select _bestIndex; - _wheelHitPointSelection = _hitPointSelections select _bestIndex; - TRACE_2("wheel found [Backup]", _wheelName, _wheelHitPoint); - }; - }; - }; - - if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { - _wheelHitPoints pushBack _wheelHitPoint; - _wheelHitPointSelections pushBack _wheelHitPointSelection; - }; -} forEach _wheels; - -[_wheelHitPoints, _wheelHitPointSelections] diff --git a/addons/repair/functions/fnc_hasItems.sqf b/addons/repair/functions/fnc_hasItems.sqf index 9b54647c8d..0eff622d20 100644 --- a/addons/repair/functions/fnc_hasItems.sqf +++ b/addons/repair/functions/fnc_hasItems.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if the engineer has all items. @@ -29,4 +29,4 @@ private _return = true; }; } forEach _items; -_return; +_return diff --git a/addons/repair/functions/fnc_isEngineer.sqf b/addons/repair/functions/fnc_isEngineer.sqf index 6a80b1012e..2962e4f8ad 100644 --- a/addons/repair/functions/fnc_isEngineer.sqf +++ b/addons/repair/functions/fnc_isEngineer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, KoffeinFlummi, commy2 * Check if a unit is any engineer class. @@ -22,7 +22,14 @@ private _class = _unit getVariable ["ACE_IsEngineer", _unit getUnitTrait "engine // This if statement is here for copmatability with the common variant of isEngineer, which requires a bool. // We cannot move this function to common because we require the GVAR(engineerSetting_Repair), which only makes sense to include in the repair module. -if (_class isEqualType false) then {_class = [0, 1] select _class}; +if (_class isEqualType false) then {_class = parseNumber _class}; TRACE_3("isEngineer",_unit,_engineerN,_class); -_class >= _engineerN; +if (_class >= _engineerN) exitWith {true}; +if (!GVAR(locationsBoostTraining)) exitWith {false}; + +if ([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)}) then { + _class = _class + 1; // Boost engineer training by one: untrained becomes engineer, engineer becomes advanced engineer +}; + +_class >= _engineerN diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index 10ef95ed66..51cc5424bb 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Checks if a unit is in a repair facility. @@ -10,33 +10,32 @@ * Is inside a repair facility * * Example: - * [unit] call ace_repair_fnc_isInRepairFacility + * player call ace_repair_fnc_isInRepairFacility * * Public: Yes */ -params ["_object"]; -TRACE_1("params",_object); +#define CHECK_OBJECTS(var) ((var) findIf _checkObject != -1) -private _position = getPosASL _object; -private _isInBuilding = false; +params [["_unit", objNull, [objNull]]]; +TRACE_1("params",_unit); private _checkObject = { - if ( - _x getVariable ["ACE_isRepairFacility", getNumber (configFile >> "CfgVehicles" >> typeOf _x >> QGVAR(canRepair))] > 0 - && {!(_x isKindOf "AllVehicles")} // check if it's not repair vehicle - && {alive _x} - ) exitWith { - _isInBuilding = true; + private _config = configOf _x; + private _canRepair = getNumber (_config >> QGVAR(canRepair)); + if (_canRepair == 0) then { + _canRepair = getNumber (_config >> "transportRepair"); }; + + _x getVariable ["ACE_isRepairFacility", _canRepair > 0] in [1, true] // can be integer or boolean + && {!(_x isKindOf "AllVehicles")} // check if it's not repair vehicle + && {alive _x} }; -private _objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]); -_checkObject forEach _objects; +private _fnc_check = { + private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2]; + CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position,_position vectorAdd [ARR_3(0,0,10)],_unit)]) + || {CHECK_OBJECTS(_unit nearObjects 7.5)} +}; -if (_isInBuilding) exitWith {true}; - -_objects = _object nearObjects 7.5; -_checkObject forEach _objects; - -_isInBuilding +[[], _fnc_check, _unit, QGVAR(inRepairFacilityCache), IN_REPAIR_FACILITY_CACHE_EXPIRY] call EFUNC(common,cachedCall); diff --git a/addons/repair/functions/fnc_isNearRepairVehicle.sqf b/addons/repair/functions/fnc_isNearRepairVehicle.sqf index 1243c0f95b..d319273e64 100644 --- a/addons/repair/functions/fnc_isNearRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isNearRepairVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi * Checks if a unit is near an engineering vehicle. @@ -15,14 +15,14 @@ * Public: Yes */ +#define CHECK_OBJECTS(var) ((var) findIf {alive _x && {[_x] call FUNC(isRepairVehicle)}} != -1) + params ["_unit"]; TRACE_1("params",_unit); -private _nearObjects = nearestObjects [_unit, ["Air", "LandVehicle", "Slingload_base_F"], 20]; +private _fnc_check = { + private _nearObjects = nearestObjects [_unit, ["Air", "LandVehicle", "Slingload_base_F"], 20]; + CHECK_OBJECTS(_nearObjects) +}; -private _return = false; -{ - if (alive _x && {[_x] call FUNC(isRepairVehicle)}) exitWith {_return = true;}; -} forEach _nearObjects; - -_return; +[[], _fnc_check, _unit, QGVAR(nearRepairVehicleCache), NEAR_REPAIR_VEHICLE_CACHE_EXPIRY] call EFUNC(common,cachedCall); diff --git a/addons/repair/functions/fnc_isRepairVehicle.sqf b/addons/repair/functions/fnc_isRepairVehicle.sqf index 6e7ddcab27..0d89f1b8e8 100644 --- a/addons/repair/functions/fnc_isRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isRepairVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Check if vehicle is a engineering vehicle. @@ -10,7 +10,7 @@ * Is engineering vehicle * * Example: - * [vehicle] call ace_repair_fnc_isRepairVehicle + * cursorObject call ace_repair_fnc_isRepairVehicle * * Public: Yes */ @@ -20,6 +20,11 @@ TRACE_1("params",_vehicle); if (_vehicle isKindOf "CAManBase") exitWith {false}; +private _config = configOf _vehicle; +private _canRepair = getNumber (_config >> QGVAR(canRepair)); +if (_canRepair == 0) then { + _canRepair = getNumber (_config >> "transportRepair"); +}; // Value can be integer or boolean -private _value = _vehicle getVariable ["ACE_isRepairVehicle", getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(canRepair))]; +private _value = _vehicle getVariable ["ACE_isRepairVehicle", _canRepair > 0]; _value in [1, true] // return diff --git a/addons/repair/functions/fnc_modifyInteraction.sqf b/addons/repair/functions/fnc_modifyInteraction.sqf index 235afd9223..7bf77d462d 100644 --- a/addons/repair/functions/fnc_modifyInteraction.sqf +++ b/addons/repair/functions/fnc_modifyInteraction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, mharis001 * Modifies the base interaction point for repair items to show its current damage. @@ -24,4 +24,4 @@ params ["_target", "", "", "_actionData"]; private _color = ceil linearConversion [0, 1, damage _target, 0, 8, true]; TRACE_2("Modifying icon color",_target,_color); (_actionData select 2) set [1, DAMAGE_COLOR_SCALE select _color]; - + diff --git a/addons/repair/functions/fnc_modifySelectionInteraction.sqf b/addons/repair/functions/fnc_modifySelectionInteraction.sqf index 66d7ae5e4b..6e7d2af41a 100644 --- a/addons/repair/functions/fnc_modifySelectionInteraction.sqf +++ b/addons/repair/functions/fnc_modifySelectionInteraction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654, mharis001 * Modifies interaction icon color of vehicle selection to show its current damage. diff --git a/addons/repair/functions/fnc_moduleAddSpareParts.sqf b/addons/repair/functions/fnc_moduleAddSpareParts.sqf index a70f821ffc..cb6da371d7 100644 --- a/addons/repair/functions/fnc_moduleAddSpareParts.sqf +++ b/addons/repair/functions/fnc_moduleAddSpareParts.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Adds spare parts to a vehicle. @@ -30,8 +30,7 @@ if (!isNull _logic) then { // Add synchronized objects to list { _list pushBack _x; - nil - } count (synchronizedObjects _logic); + } forEach (synchronizedObjects _logic); if (_list isEqualTo []) exitWith {}; @@ -40,6 +39,5 @@ if (!isNull _logic) then { // Add spare parts { [_x, _amount, _part, true] call FUNC(addSpareParts); - false - } count _list; + } forEach _list; }; diff --git a/addons/repair/functions/fnc_moduleAssignEngineer.sqf b/addons/repair/functions/fnc_moduleAssignEngineer.sqf index 1949da087a..2789d4da07 100644 --- a/addons/repair/functions/fnc_moduleAssignEngineer.sqf +++ b/addons/repair/functions/fnc_moduleAssignEngineer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Assign an engineer role to a unit. diff --git a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf index c071058ad6..71e5ad0d74 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Assign a repair facility. diff --git a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf index 4f5c601cce..c2bbb7db48 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Assign a repair vehicle. diff --git a/addons/repair/functions/fnc_moduleRepairSettings.sqf b/addons/repair/functions/fnc_moduleRepairSettings.sqf index 831b9a2619..66c372e146 100644 --- a/addons/repair/functions/fnc_moduleRepairSettings.sqf +++ b/addons/repair/functions/fnc_moduleRepairSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Adjusts repair damage settings. diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index fb07147a6a..97f34c22db 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Used to normalize dependant hitpoints. May overwrite some global variables that are named like hitpoints or "Total" though... @@ -16,14 +16,14 @@ */ params ["_vehicle"]; -TRACE_2("params",_vehicle, typeOf _vehicle); +TRACE_2("params",_vehicle,typeOf _vehicle); // Can't execute all commands if the vehicle isn't local, exit if that's so -if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; +if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1",_vehicle);}; (getAllHitPointsDamage _vehicle) params [["_allHitPoints", []]]; -private _config = configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints"; +private _config = configOf _vehicle >> "HitPoints"; private _realHitPoints = []; private _dependentHitPoints = []; @@ -33,7 +33,7 @@ private _dependentHitPointScripts = []; { if ((_x != "") && {isClass (_config >> _x)} && {!(_x in _realHitPoints)}) then { _realHitPoints pushBack _x; - if (!((getText (_config >> _x >> "depends")) in ["", "0"])) then { + if !((getText (_config >> _x >> "depends")) in ["", "0"]) then { _dependentHitPoints pushBack _x; _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends"); }; @@ -46,15 +46,22 @@ TRACE_2("",_realHitPoints,_dependentHitPoints); if (_dependentHitPoints isEqualTo []) exitWith {}; -// Define global variables -Total = damage _vehicle; +// Define global variables and save original values +private _savedGlobals = [["total", total]]; +total = damage _vehicle; { + _savedGlobals pushBack [_x, missionNamespace getVariable _x]; missionNamespace setVariable [_x, _vehicle getHitPointDamage _x]; } forEach _realHitPoints; // apply normalized damage to all dependand hitpoints { private _damage = call (_dependentHitPointScripts select _forEachIndex); - TRACE_2("setting depend hitpoint", _x, _damage); + TRACE_2("setting depend hitpoint",_x,_damage); _vehicle setHitPointDamage [_x, _damage]; } forEach _dependentHitPoints; + +// Restore global variables +{ + missionNamespace setVariable _x; +} forEach _savedGlobals; diff --git a/addons/repair/functions/fnc_patchRemovedWheel.sqf b/addons/repair/functions/fnc_patchRemovedWheel.sqf new file mode 100644 index 0000000000..b0978013d5 --- /dev/null +++ b/addons/repair/functions/fnc_patchRemovedWheel.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Patch a wheel that is not on a vehicle + * + * Arguments: + * 0: Unit that does the patching + * 1: Wheel to patch + * + * Return Value: + * None + * + * Example: + * [unit, vehicle] call ace_repair_fnc_patchRemovedWheel + * + * Public: No + */ + +params ["_unit", "_target"]; + +[_unit, "Acts_carFixingWheel"] call EFUNC(common,doAnimation); + +private _wheelDamage = (damage _target) - GVAR(patchWheelMaximumRepair); + +[ceil (_wheelDamage / 0.05) * GVAR(patchWheelTime), [_target], {}, {}, LLSTRING(PatchingWheel), { + params ["_args"]; + _args params ["_target"]; + private _damage = damage _target; + + private _iterationsRemaining = ceil ((_damage - GVAR(patchWheelMaximumRepair)) / 0.05) - 1; + if ((_totalTime - _elapsedTime) > _iterationsRemaining * GVAR(patchWheelTime)) exitWith {true}; + + _damage = (_damage - 0.05) max GVAR(patchWheelMaximumRepair); + + _target setDamage _damage; + + _damage > GVAR(patchWheelMaximumRepair) +}] call ace_common_fnc_progressBar; + diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 9edd36bc83..526b2d506b 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Starts the repair process. @@ -43,18 +43,8 @@ if ((isEngineOn _target) && {!GVAR(autoShutOffEngineWhenStartingRepair)}) exitWi false }; -//Items can be an array of required items or a string to a ACE_Setting array -private _items = if (isArray (_config >> "items")) then { - getArray (_config >> "items"); -} else { - private _settingName = getText (_config >> "items"); - private _settingItemsArray = getArray (configFile >> "ACE_Settings" >> _settingName >> "_values"); - if ((isNil _settingName) || {(missionNamespace getVariable _settingName) >= (count _settingItemsArray)}) exitWith { - ERROR("bad setting"); ["BAD"] - }; - _settingItemsArray select (missionNamespace getVariable _settingName); -}; -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; +private _items = _config call FUNC(getRepairItems); +if (_items isNotEqualTo [] && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; private _return = true; if (getText (_config >> "condition") != "") then { @@ -80,14 +70,14 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { if (_x == "field") exitWith {_return = true;}; if (_x == "RepairFacility" && _repairFacility) exitWith {_return = true;}; if (_x == "RepairVehicle" && _repairVeh) exitWith {_return = true;}; - if !(isNil _x) exitWith { + if (!isNil _x) exitWith { private _val = missionNamespace getVariable _x; if (_val isEqualType 0) then { _return = switch (_val) do { @@ -104,8 +94,8 @@ if (!("All" in _repairLocations)) then { private _requiredObjects = getArray (_config >> "claimObjects"); private _claimObjectsAvailable = []; -if (!(_requiredObjects isEqualTo [])) then { - _claimObjectsAvailable = [_caller, 5, _requiredObjects] call FUNC(getClaimObjects); +if (_requiredObjects isNotEqualTo []) then { + _claimObjectsAvailable = [_caller, 5, _requiredObjects, true] call FUNC(getClaimObjects); if (_claimObjectsAvailable isEqualTo []) then { TRACE_2("Missing Required Objects",_requiredObjects,_claimObjectsAvailable); _return = false @@ -117,7 +107,7 @@ if !(_return && alive _target) exitWith {false}; //Claim required objects { - TRACE_2("Claiming", _x, (typeOf _x)); + TRACE_2("Claiming",_x,(typeOf _x)); [_caller, _x, false] call EFUNC(common,claim); } forEach _claimObjectsAvailable; @@ -140,8 +130,12 @@ if (_consumeItems > 0) then { private _callbackProgress = getText (_config >> "callbackProgress"); if (_callbackProgress == "") then { _callbackProgress = { - (_this select 0) params ["", "_target"]; - (alive _target) && {(abs speed _target) < 1} // make sure vehicle doesn't drive off + (_this select 0) params ["_caller", "_target", "", "", "", "", "_claimObjectsAvailable"]; + ( + (alive _target) && + {(abs speed _target) < 1} && // make sure vehicle doesn't drive off + {_claimObjectsAvailable findIf {!alive _x || {_x getVariable [QEGVAR(common,owner), objNull] isNotEqualTo _caller}} == -1} // make sure claim objects are still available + ) }; } else { if (isNil _callbackProgress) then { @@ -154,6 +148,7 @@ if (_callbackProgress == "") then { // Player Animation private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); +private _loopAnim = (getNumber (_config >> "loopAnimation")) isEqualTo 1; _caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller]; // Cannot use secondairy weapon for animation @@ -177,16 +172,33 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { } else { _caller setVariable [QGVAR(repairPrevAnimCaller), animationState _caller]; }; + _caller setVariable [QGVAR(repairCurrentAnimCaller), toLowerANSI _callerAnim]; [_caller, _callerAnim] call EFUNC(common,doAnimation); }; }; -private _soundPosition = AGLToASL (_caller modelToWorldVisual (_caller selectionPosition "RightHand")); +if (_loopAnim) then { + private _animDoneEh = _caller addEventHandler ["AnimDone", { + params ["_caller", "_anim"]; + if (_anim isEqualTo (_caller getVariable [QGVAR(repairCurrentAnimCaller), ""])) then { + [{ + params ["_caller", "_anim"]; + if !(isNil {_caller getVariable QGVAR(repairCurrentAnimCaller)}) then { + TRACE_2("loop",_caller,_anim); + _this call EFUNC(common,doAnimation) + }; + }, [_caller, _anim], 2.5] call CBA_fnc_waitAndExecute; + }; + }]; + _caller setVariable [QGVAR(repairLoopAnimEh), _animDoneEh]; +}; + +private _soundPosition = _caller modelToWorldVisualWorld (_caller selectionPosition "RightHand"); ["Acts_carFixingWheel", _soundPosition, nil, 50] call EFUNC(common,playConfigSound3D); // Get repair time private _repairTime = [ - configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(repairTimes) >> configName _config, + configOf _target >> QGVAR(repairTimes) >> configName _config, "number", -1 ] call CBA_fnc_getConfigEntry; @@ -219,7 +231,10 @@ private _hitPointClassname = if (_hitPoint isEqualType "") then { }; private _processText = getText (_config >> "displayNameProgress"); private _backupText = format [localize LSTRING(RepairingHitPoint), _hitPointClassname]; -([_hitPointClassname, _processText, _backupText] call FUNC(getHitPointString)) params ["_text"]; +private _text = _processText; +if (getNumber (_config >> "forceDisplayName") isNotEqualTo 1) then { + _text = ([_hitPointClassname, _processText, _backupText] call FUNC(getHitPointString)) select 0; +}; TRACE_4("display",_hitPoint,_hitPointClassname,_processText,_text); diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index 83cce85e0d..f9de2a8ae6 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Callback when repair fails. @@ -29,9 +29,13 @@ TRACE_5("params",_caller,_target,_selectionName,_className,_usersOfItems); if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; + +_caller removeEventHandler ["AnimDone", _caller getVariable [QGVAR(repairLoopAnimEh), -1]]; +_caller setVariable [QGVAR(repairLoopAnimEh), nil]; if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; +_caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); @@ -47,7 +51,7 @@ if (_weaponSelect != "") then { //Unclaim repair objects: { - TRACE_2("Releasing", _x, (typeOf _x)); + TRACE_2("Releasing",_x,(typeOf _x)); [objNull, _x, false] call EFUNC(common,claim); } forEach _claimedObjects; @@ -61,7 +65,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index a86be84244..6248082779 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Callback when repair completes. @@ -29,9 +29,13 @@ TRACE_4("params",_caller,_target,_selectionName,_className); if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; + +_caller removeEventHandler ["AnimDone", _caller getVariable [QGVAR(repairLoopAnimEh), -1]]; +_caller setVariable [QGVAR(repairLoopAnimEh), nil]; if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; +_caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); @@ -43,7 +47,7 @@ if (_weaponSelect != "") then { //Unclaim repair objects: { - TRACE_2("Releasing", _x, (typeOf _x)); + TRACE_2("Releasing",_x,(typeOf _x)); [objNull, _x, false] call EFUNC(common,claim); } forEach _claimedObjects; @@ -56,7 +60,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_setDamage.sqf b/addons/repair/functions/fnc_setDamage.sqf index ba51c22c0d..3c7e23dc76 100644 --- a/addons/repair/functions/fnc_setDamage.sqf +++ b/addons/repair/functions/fnc_setDamage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Sets the structural damage of a vehicle without altering the hitPoints, requires local vehicle. @@ -6,6 +6,7 @@ * Arguments: * 0: Local Vehicle to Damage * 1: Total Damage + * 2: Use destruction effects * * Return Value: * None @@ -16,7 +17,7 @@ * Public: No */ -params ["_vehicle", "_damage"]; +params ["_vehicle", "_damage", ["_useEffects", false]]; TRACE_2("params",_vehicle,_damage); // can't execute all commands if the vehicle isn't local. exit here. @@ -31,7 +32,7 @@ if (_damageDisabled) then { _vehicle allowDamage true; }; -_vehicle setDamage _damage; +_vehicle setDamage [_damage, _useEffects]; // restore original hitpoint damage values { diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index 0e8a805689..0a6051e084 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Set the hitpoint damage and change the structural damage acordingly, requires local vehicle. @@ -8,7 +8,7 @@ * 0: Local Vehicle to Damage * 1: Selected hitpoint INDEX * 2: Total Damage - * 3: Skip destruction effects + * 3: Use destruction effects * * Return Value: * None @@ -19,17 +19,17 @@ * Public: No */ -params ["_vehicle", "_hitPointIndex", "_hitPointDamage", ["_useEffects", true]]; +params ["_vehicle", "_hitPointIndex", "_hitPointDamage", ["_useEffects", false]]; TRACE_4("params",_vehicle,typeOf _vehicle,_hitPointIndex,_hitPointDamage); // can't execute all commands if the vehicle isn't local. exit here. -if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; +if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1",_vehicle);}; // get all hitpoints and selections and damages (getAllHitPointsDamage _vehicle) params [["_allHitPoints", []], ["_allHitPointsSelections", []], ["_allHitPointDamages", []]]; // exit if the hitpoint is not valid -if ((_hitPointIndex < 0) || {_hitPointIndex >= (count _allHitPoints)}) exitWith {ERROR_2("NOT A VALID HITPOINT: %1-%2", _hitPointIndex,_vehicle);}; +if ((_hitPointIndex < 0) || {_hitPointIndex >= (count _allHitPoints)}) exitWith {ERROR_2("NOT A VALID HITPOINT: %1-%2",_hitPointIndex,_vehicle);}; // save structural damage and sum of hitpoint damages @@ -44,7 +44,7 @@ private _hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - if ((!isNil {_vehicle getHit _selectionName}) && {_x != ""}) then { _realHitpointCount = _realHitpointCount + 1; - if ((((toLower _x) find "glass") == -1) && {(getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { + if (!("glass" in (toLowerANSI _x)) && {(getText (configOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { _hitPointDamageSumOld = _hitPointDamageSumOld + (_allHitPointDamages select _forEachIndex); if (_forEachIndex == _hitPointIndex) then { _hitPointDamageRepaired = (_allHitPointDamages select _forEachIndex) - _hitPointDamage; diff --git a/addons/repair/functions/fnc_spawnObject.sqf b/addons/repair/functions/fnc_spawnObject.sqf index 9dce6a7e01..7dc5f96219 100644 --- a/addons/repair/functions/fnc_spawnObject.sqf +++ b/addons/repair/functions/fnc_spawnObject.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Spawns an object of specified string, at specified position with specified damage taken. diff --git a/addons/repair/functions/fnc_useItem.sqf b/addons/repair/functions/fnc_useItem.sqf index 760be7a39b..2827d7afb9 100644 --- a/addons/repair/functions/fnc_useItem.sqf +++ b/addons/repair/functions/fnc_useItem.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Use Equipment if any is available. diff --git a/addons/repair/functions/fnc_useItems.sqf b/addons/repair/functions/fnc_useItems.sqf index b6da87aecc..edc18bcb16 100644 --- a/addons/repair/functions/fnc_useItems.sqf +++ b/addons/repair/functions/fnc_useItems.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Use Equipment items if any is available. diff --git a/addons/repair/functions/script_component.hpp b/addons/repair/functions/script_component.hpp deleted file mode 100644 index 80a7b2eb74..0000000000 --- a/addons/repair/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\repair\script_component.hpp" diff --git a/addons/repair/initSettings.inc.sqf b/addons/repair/initSettings.inc.sqf new file mode 100644 index 0000000000..e39bb93a76 --- /dev/null +++ b/addons/repair/initSettings.inc.sqf @@ -0,0 +1,197 @@ +private _category = format ["ACE %1", LLSTRING(Repair)]; +private _catFullRepair = [_category, LLSTRING(fullRepair)]; + +[ + QGVAR(enabled), "CHECKBOX", + ELSTRING(common,Enabled), + _category, + true, + true, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(displayTextOnRepair), "CHECKBOX", + [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], + _category, + true // default value +] call CBA_fnc_addSetting; + +[ + QGVAR(engineerSetting_repair), "LIST", + [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], + _category, + [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(engineerSetting_wheel), "LIST", + [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], + _category, + [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(patchWheelEnabled), "LIST", + [LSTRING(patchWheelEnabled_name), LSTRING(patchWheelEnabled_description)], + _category, + [[-1,0,1,2],["str_player_none", LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // default value + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(patchWheelRequiredItems), + "LIST", + [LSTRING(patchWheelRequiredItems_DisplayName), LSTRING(patchWheelRequiredItems_Description)], + _category, + [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(patchWheelLocation), + "LIST", + [LSTRING(patchWheelLocation_DisplayName), LSTRING(patchWheelLocation_Description)], + _category, + [[["ground", "vehicle"], ["vehicle"], ["ground"]], ["str_difficulty_any", LSTRING(patchWheelOnVehicle), LSTRING(patchWheelOnGround)], 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(repairDamageThreshold), "SLIDER", + [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], + _category, + [0, 1, 0.6, 1, true], + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(repairDamageThreshold_engineer), "SLIDER", + [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], + _category, + [0, 1, 0.4, 1, true], + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(consumeItem_toolKit), "LIST", // fnc_repair expects number + [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], + _category, + [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(locationsBoostTraining), + "CHECKBOX", + [ELSTRING(common,LocationsBoostTraining_DisplayName), LSTRING(LocationsBoostTraining_Description)], + _category, + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(fullRepairLocation), "LIST", + [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], + _catFullRepair, + [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(engineerSetting_fullRepair), "LIST", + [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], + _catFullRepair, + [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(timeCoefficientFullRepair), "SLIDER", + [LSTRING(timeCoefficientFullRepair_name), LSTRING(timeCoefficientFullRepair_description)], + _catFullRepair, + [0,3,1.5,2], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(addSpareParts), "CHECKBOX", + [LSTRING(addSpareParts_name), LSTRING(addSpareParts_description)], + _category, + true, // default value + true, // isGlobal + {[QGVAR(addSpareParts), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(wheelRepairRequiredItems), + "LIST", + [LSTRING(WheelRepairRequiredItems_DisplayName), LSTRING(WheelRepairRequiredItems_Description)], + _category, + [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(miscRepairRequiredItems), + "LIST", + [LSTRING(MiscRepairRequiredItems_DisplayName), LSTRING(MiscRepairRequiredItems_Description)], + _category, + [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(fullRepairRequiredItems), + "LIST", + [LSTRING(FullRepairRequiredItems_DisplayName), LSTRING(FullRepairRequiredItems_Description)], + _catFullRepair, + [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(autoShutOffEngineWhenStartingRepair), "CHECKBOX", + [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], + _category, + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(miscRepairTime), "SLIDER", + [LSTRING(miscRepairTime_name), LSTRING(miscRepairTime_description)], + _category, + [0,60,15,-1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true +] call CBA_fnc_addSetting; + +[ + QGVAR(wheelChangeTime), "SLIDER", + [LSTRING(wheelChangeTime_name), LSTRING(wheelChangeTime_description)], + _category, + [0,60,10,-1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true +] call CBA_fnc_addSetting; + +[ + QGVAR(patchWheelTime), + "SLIDER", + [LSTRING(patchWheelTime_DisplayName), LSTRING(patchWheelTime_Description)], + _category, + [0.1, 60, 5, 1], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(patchWheelMaximumRepair), + "SLIDER", + [LSTRING(patchWheelMaximumRepair_DisplayName), LSTRING(patchWheelMaximumRepair_Description)], + _category, + [0, 1, 0.3, 1, true], + true +] call CBA_fnc_addSetting; diff --git a/addons/repair/initSettings.sqf b/addons/repair/initSettings.sqf deleted file mode 100644 index e226085a29..0000000000 --- a/addons/repair/initSettings.sqf +++ /dev/null @@ -1,101 +0,0 @@ -// CBA Settings [ADDON: ace_repair]: - -[ - QGVAR(displayTextOnRepair), "CHECKBOX", - [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - true, // default value - false, // isGlobal - {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(engineerSetting_repair), "LIST", - [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(engineerSetting_wheel), "LIST", - [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(repairDamageThreshold), "SLIDER", - [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [0,1,0.6,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(repairDamageThreshold_engineer), "SLIDER", - [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [0,1,0.4,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(consumeItem_toolKit), "LIST", // fnc_repair expects number - [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(fullRepairLocation), "LIST", - [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(engineerSetting_fullRepair), "LIST", - [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(addSpareParts), "CHECKBOX", - [LSTRING(addSpareParts_name), LSTRING(addSpareParts_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - true, // default value - true, // isGlobal - {[QGVAR(addSpareParts), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(wheelRepairRequiredItems), "LIST", - [LSTRING(wheelRepairRequiredItems_name), LSTRING(wheelRepairRequiredItems_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - [[0,1],["None", "ToolKit"],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(wheelRepairRequiredItems), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(autoShutOffEngineWhenStartingRepair), "CHECKBOX", - [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], - false, // default value - true, // isGlobal - {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; diff --git a/addons/repair/script_component.hpp b/addons/repair/script_component.hpp index 7ec3be3233..9fab647079 100644 --- a/addons/repair/script_component.hpp +++ b/addons/repair/script_component.hpp @@ -19,3 +19,11 @@ #define TRACK_HITPOINTS ["hitltrack", "hitrtrack"] #define DAMAGE_COLOR_SCALE ["#FFFFFF", "#FFFF7E", "#FFEC4D", "#FFD52C", "#FCB121", "#FF9916", "#FF7D16", "#FF4400", "#FF0000"] + +#define IN_REPAIR_FACILITY_CACHE_EXPIRY 1 + +#define NEAR_REPAIR_VEHICLE_CACHE_EXPIRY 1 + +#define ANY_TOOLKIT_FAKECLASS QGVAR(anyToolKit) + +#define PATCH_WHEEL_STEP_TIME 0.05 diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index c1ac98892f..850f9dee7f 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -1,11 +1,11 @@ - + Spare Track Ersatzkette Oruga de repuesto - Chenille de réserve + Chenille de rechange Zapasowa gąsienica Esteira reserva Náhradní pásy @@ -16,6 +16,7 @@ 예비 궤도 备用履带 備用履帶 + Yedek Parça Spare Wheel @@ -32,12 +33,24 @@ 예비 바퀴 备用轮胎 備用輪胎 + Yedek Tekerlek + + + Wheel + Rad + Rueda + タイヤ + Koło + Ruota + 바퀴 + Roue + Колесо Change Wheel Reifen wechseln Cambiar rueda - Changer Roue + Changer la roue Wymień koło Trocar roda Sostituisci la ruota @@ -48,6 +61,7 @@ 바퀴 교체 更换轮胎 更換輪胎 + Tekerleği Değiştir Replacing Wheel... @@ -60,9 +74,10 @@ Sostituendo la ruota... Remplacement de la roue... タイヤを交換しています・・・ - 바퀴 교체중... - 更换轮胎中... + 바퀴 교체 중... + 正在更换轮胎... 更換輪胎中... + Tekerlek Takılıyor Wheel replaced @@ -73,17 +88,18 @@ Kolo vyměněno Rueda cambiada Ruota sostituita - Roue remplacée + Roue remplacée. タイヤを交換しました 바퀴 교체됨 轮胎更换完毕 輪胎更換完畢 + Tekerlek Takıldı Remove Wheel Reifen entfernen Quitar rueda - Démonter Roue + Démonter la roue Zdejmij koło Odstranit kolo Remover roda @@ -94,6 +110,7 @@ 바퀴 제거 卸下轮胎 卸下輪胎 + Tekerleği Sök Removing Wheel... @@ -106,9 +123,10 @@ Rimuovendo la ruota... Démontage de la roue... タイヤを外しています・・・ - 바퀴 제거중... - 卸下轮胎中... + 바퀴 제거 중... + 正在卸下轮胎... 卸下輪胎中... + Tekerlek Sökülüyor Wheel removed @@ -119,11 +137,12 @@ Kolo odstraněno Rueda quitada Ruota rimossa - Roue démontée + Roue démontée. タイヤを外しました 바퀴 제거됨 轮胎卸下完毕 輪胎卸下完畢 + Tekerlek Söküldü Change Track @@ -139,6 +158,7 @@ 궤도 교체 更换履带 更換履帶 + Parçayı Değiştir Replacing Track... @@ -151,9 +171,10 @@ Sostituendo il cingolo... Remplacement de la chenille... 履帯を交換しています・・・ - 궤도 교체중... - 更换履带中... + 궤도 교체 중... + 正在更换履带... 更換履帶中... + Parça Değişiyor... Track replaced @@ -164,11 +185,12 @@ Pás vyměněn Oruga cambiada Cingolo sostituito - Chenille remplacée + Chenille remplacée. 履帯を交換しました 궤도 교체됨 履带更换完毕 履帶更換完畢 + Parça Değişti Remove Track @@ -179,11 +201,12 @@ Odstranit pás Quitar oruga Rimuovi cingolo - Enlever la chenille + Démonter la chenille 履帯を外す 궤도 제거 卸下履带 卸下履帶 + Parçayı Sök Removing Track... @@ -194,11 +217,12 @@ Odstraňuji pás... Quitando oruga... Rimuovendo il cingolo... - Enlèvement de la chenille... + Démontage de la chenille... 履帯を外しています・・・ - 궤도 제거중... - 卸下履带中... + 궤도 제거 중... + 正在卸下履带... 卸下履帶中... + Parça Sökülüyor... Track removed @@ -209,11 +233,12 @@ Pás odstraněn Oruga quitada Cingolo rimosso - Chenille enlevée + Chenille démontée. 履帯を外しました 궤도 제거됨 履带卸下完毕 履帶卸下完畢 + Parça Söküldü Full Repair @@ -224,11 +249,12 @@ Kompletní oprava Reparación completa Riparazione completa - Réparations complètes + Réparer complètement 完全に修理 완전수리 完整维修 完整維修 + Tam Onarım Repairing Vehicle... @@ -241,9 +267,44 @@ Riparando il veicolo... Réparation du véhicule... 車両を修理しています・・・ - 차량 수리중... - 维修载具中... + 차량 수리 중... + 正在维修载具... 維修載具中... + Tamir Ediliyor... + + + Full Repair Time Coefficient + 完全修理所要時間係数 + Współczynnik Czasu Pełnej Naprawy + Vollständiger Reparaturzeitkoeffizient + Coefficiente di riparazione completa + 전체 수리 시간 계수 + Coefficient du temps de réparation complète + Коэффициент времени полного ремонта + Coeficiente de Tiempo de Reparación Completa + + + Modifies how long it takes to perform a Full Repair.\nThe repair time is based on the amount of repairs needed for each part, including those normally inaccessible. + 完全修復に掛かる時間を変更します。\n修理所要時間は、通常アクセスできない部品も含め、各部品に必要な修理量に基づいて決定されます。 + Determina la durata di una riparazione completa.\nIl tempo richiesto si basa sul numero di riparazioni necessarie, include quelle su componenti normalmente inaccessibili. + Modyfikuje czas potrzebny do wykonania Pełnej Naprawy. Czas naprawy jest oparty na ilości napraw potrzebnych dla każdej części, w tym tych normalnie niedostępnych. + Ändert, wie lange es dauert, eine vollständige Reparatur durchzuführen.\nDie Reparaturzeit basiert auf der Menge der erforderlichen Reparaturen für jedes Teil, einschließlich derjenigen, die normalerweise nicht zugänglich sind. + 전체적인 수리를 수행하는 데 걸리는 시간을 수정합니다.\n수리 시간은 일반적으로 접근할 수 없는 부품을 포함하여 각 부품에 필요한 수리 시간을 기준으로 합니다. + Modifie la durée que prend une réparation complète.\nLe temps de réparation est basé sur la quantité de réparations requises pour chaque partie, incluant celles qui sont normalement inaccessibles. + Изменяет время, необходимое для выполнения полного ремонта.\nВремя ремонта зависит от объема ремонтных работ, необходимых для каждой детали, включая те, которые обычно недоступны. + Modifica cuánto tiempo lleva realizar una Reparación Completa.\nEl tiempo de reparación está basado en la cantidad de reparaciones necesarias para cada parte, incluyendo aquellas que normalmente no son accesibles. + + + Boost engineer training when in repair vehicles or facilities. Untrained becomes engineer, engineer becomes advanced engineer. + Améliore les compétences en ingénierie des unités en fonction du lieu où elles se trouvent ; notamment dans les véhicules de réparation ou les ateliers.\nUn soldat non formé devient ingénieur, un ingénieur devient ingénieur avancé. + 修理車両か施設内では工兵能力を上昇させます。兵士は工兵になり、工兵は上級工兵になります。 + Aumenta la formazione di Geniere se in veicoli o strutture di riparazioni. Se non addestrato diventa Geniere, se ingegnere diventa Geniere avanzato. + Повысьте подготовку инженеров при ремонте транспортных средств или объектов. Нетренированный становится инженером, инженер становится продвинутым инженером. + Steigert die Ausbildung von Pionieren, wenn Sie sich in Reparaturfahrzeugen oder -einrichtungen befinden. Aus Ungelerntem wird Pionier, aus Pionier wird ein fortgeschrittener Pionier. + Zwiększ wyszkolenie inżynierów w pojazdach i budynkach naprawczych. Niewyszkoleni zostają inżynierami, inżynierowie zostają zaawansowanymi inżynierami. + 在修理车辆或设施时,提升工程师训练。未受过训练的变成工程师,工程师晋升为高级工程师。 + 수리 차량이나 시설 주위에 있으면 수리 수준을 높입니다. 정비병이 아닌 사람은 정비병이 되고, 정비병은 정비사가 됩니다. + Aumenta las capacidades del ingeniero cuando se encuentra en un vehículo o instalacion de raparacion de vehículos. Quien no es ingeniero, pasa a serlo, y quien es ingeniero, pasa a ser ingeniero avanzado. Full Repair Locations @@ -254,11 +315,12 @@ Oblast pro kompletní opravu Lugares de reparación completa Luoghi Riparazione Completa - Lieu de réparation complète - 完全修理できる場所 + Endroits pour réparation complète + 完全修理可能な場所 완전수리 구역 完整维修地点 完整維修地點 + Tam Onarım Konumu At what locations can a vehicle be fully repaired? @@ -269,10 +331,10 @@ ¿En qué lugares puede un vehículo ser reparado totalmente? V které oblasti může být vozidlo plně opraveno? In quali luoghi è possibile riparare completamente un veicolo? - Où peuvent être réparés complètement les véhicules ? + Définit les lieux permettant de réparer intégralement un véhicule. どのような場所で車両の完全な修理を出来るようにしますか? 어느 구역에서 차량을 완전히 수리할 수 있게 합니까? - 什么位置可以完整维修载具? + 什么位置可以完整维修载具? 什麼位置可以完整維修載具? @@ -284,11 +346,12 @@ Povolit kompletní opravu Permitir reparación completa Consenti Riparazione Completa - Autoriser les réparations complètes. + Réparations complètes autorisées pour 完全修理を許可 완전 수리 활성화 允许完整维修 允許完整維修 + Tam Onarıma Izin Ver Who can perform a full repair on a vehicle? @@ -299,11 +362,12 @@ ¿Quién puede realizar una reparación completa de un vehículo? Kdo může provést úplné opravy na vozidle? Chi può eseguire una riparazione completa su un veicolo? - Qui peut faire une réparation complète ? + Définit qui peut effectuer une réparation complète sur un véhicule. 誰が車両の完全な修理を出来るようにしますか? 누가 완전 수리를 할 수 있습니까? - 谁可以完整维修载具? + 谁可以完整维修载具? 誰可以完整維修載具? + Kimler araçta tam onarım yapabilir? Add Spare Parts @@ -319,6 +383,7 @@ 예비 부품 더하기 添加备件 添加備件 + Yedek Parça Ekle Add spare parts to vehicles (requires Cargo component)? @@ -328,18 +393,18 @@ ¿Añadir repuestos para vehículos (requiere componente de carga)? Добавлять запасные части в технику (требуется модуль Грузоперевозок)? Přidat náhradní díly do vozidla (vyžaduje úložný prostor)? - Aggiungi parti di ricambio ai veicoli (richiede componente Cargo)? - Ajouter des pièces de rechage aux véhicules ? (à besoin du système de cargaison) - 車両へ予備部品を追加しますか(カーゴ コンポーネントが必要)? + Aggiungi parti di ricambio ai veicoli (richiede spazio nel carico)? + Ajoute des pièces de rechange aux véhicules (nécessite le système de cargaison). + 車両へ予備部品を追加しますか? (貨物室が必要) 차량에 예비 부품을 더합니까?(짐칸 요소 필요) - 添加载具备件 (需相关货物组件)? + 添加载具备件(需相关货物组件)? 添加載具備件 (需相關貨物組件)? Repair Reparieren Reparación - Réparer + Réparation Napraw Opravit Reparar @@ -350,6 +415,7 @@ 수리 维修 維修 + Tamir Display text on repair @@ -360,7 +426,7 @@ Zobrazit text při opravě Mostrar texto en la reparación Mostra testo mentre ripari - Afficher du texte pendant la réparation + Afficher du texte lors des réparations 修理時に文章で通知する 수리시 화면에 글자 표시 显示维修文本 @@ -375,7 +441,7 @@ Mostrar una notificación cada vez que se reparare un vehículo Zobrazit oznámení kdykoliv opravíš vozidlo Mostra una notifica quando stai riparando un veicolo - Afficher une notification lorsque l'on répare un véhicule + Affiche une notification lorsque vous réparez un véhicule. 車両の修理を始めると、画面に通知を出します 수리시 화면에 글자로 알림이 뜹니다 每当维修载具时显示通知 @@ -393,15 +459,16 @@ javítása... Ремонтируем... 修理しています・・・ - 수리중... - 维修中... + 수리 중... + 正在维修... 維修中... + Tamir Ediliyor... Repairing %1... Repariere %1... Reparando %1... - Réparation %1... + Réparation de %1... Naprawianie %1... Opravuji %1... Reparando %1... @@ -409,15 +476,16 @@ %1 javítása... Ремонтируем %1... %1 を修理しています・・・ - %1 수리중... - 维修%1中... + %1 수리 중... + 正在维修%1... 維修%1中... + Tamir Ediliyor %1... Repaired %1 %1 repariert Reparado %1 - %1 réparé(e) + %1 réparé(e). Naprawiono %1 %1 - opraveno Reparado %1 @@ -428,6 +496,7 @@ %1 수리됨 已维修%1 已維修%1 + Tamir Edildi %1 Fully repaired part @@ -438,26 +507,26 @@ Kompletně opravená část Parte totalmente reparado Parte riparata completamente - Pièce entièrement réparée + Pièce entièrement réparée. 完全に修理された部品 - 부분 완벽히 수리됨 + 완전수리된 부품 完整维修部分 完整維修部分 - Partially repaired %1 + Partially repaired part Bauteil zum Teil repariert - Częściowo naprawiono: %1 - %1 parcialmente reparado - Частично отремонтировано: %1 - Parcialmente reparada %1 - %1 - částečně opraveno - %1 parzialmente riparato - %1 pratiquement réparée - %1 を部分的に修理しました - %1 부분적으로 수리됨 - %1已完成部分维修 - %1已完成部分維修 + Częściowo naprawiono część + Parte parcialmente reparado + Частично отремонтировано часть + Parcialmente reparada parte + Díl částečně opraveno + Parte parzialmente riparata + Pièce partiellement réparé(e). + 部品 を部分的に修理しました + 부품 부분적으로 수리됨 + 零件已完成部分维修 + 零件已完成部分維修 Fully repaired %1 @@ -468,7 +537,7 @@ %1 - kompletně opraveno Totalmente reparada %1 %1 completamente riparato - %1 entièrement réparée + %1 entièrement réparé(e). %1 を完全に修理しました %1 완전히 수리됨 %1已完整维修 @@ -483,7 +552,7 @@ Parcialmente reparada %1 %1 - částečně opraveno %1 parzialmente riparato - %1 pratiquement réparée + %1 partiellement réparé(e). %1 を部分的に修理しました %1 부분적으로 수리됨 %1已完成部分维修 @@ -504,6 +573,7 @@ 몸체 车身 車身 + Vücut Hull @@ -516,10 +586,27 @@ Scafo Test Корпус - 機体 + 構造体 선체 车壳 車殼 + Gövde + + + Light + + Léger + Claro + Luci + Light + Светлый + Hell + Světlá + Claro + 조명 + 轻型 + 照明 + Işık Engine @@ -536,6 +623,7 @@ 엔진 引擎 引擎 + Motor Left Horizontal Stabilizer @@ -547,10 +635,11 @@ Stabilizzatore Orizzontale Sinistro Stabilisateur horizontal gauche Linkes Höhenleitwerk - 左側の水平安定機 + 左側水平安定装置 왼쪽 수평안정판 左侧悬挂稳定 左側懸掛穩定 + Sol Yatay Sabitleyici Right Horizontal Stabilizer @@ -562,10 +651,11 @@ Stabilizzatore Orizzontale Destro Stabilisateur horizontal droit Rechtes Höhenleitwerk - 右側の水平安定機 + 右側水平安定装置 오른쪽 수평안정판 右侧悬挂稳定 右側懸掛穩定 + Sağ Yatay Sabitleyici Vertical Stabilizer @@ -577,10 +667,11 @@ Stabilizzatore Verticale Stabilisateur vertical Seitenleitwerk - 車両スタビライザ + 垂直安定装置 수직 안정판 垂直稳定 垂直穩定 + Dikey Sabitleyici Fuel Tank @@ -597,6 +688,7 @@ 연료 탱크 油箱 油箱 + Yakıt Tankeri Transmission @@ -607,11 +699,12 @@ Transmissão Transmisión Trasmissione - Instruments + Transmission 変速機 변속기 变速箱 變速箱 + Vites Gear @@ -621,12 +714,13 @@ Engrenagem Rueda Podvozek - Motore - Trains d'attérissage + Carrello + Trains d'atterrissage ギア 기어 齿轮 齒輪 + Vites Starter @@ -642,6 +736,7 @@ 점화기 发动机 發動機 + Marş Tail @@ -657,6 +752,7 @@ 꼬리 尾翼 尾翼 + Kuyruk Pitot Tube @@ -667,11 +763,12 @@ Tubo de Pitot Tubo del pitot Tubo di Pitot - Sonde pitot + Tube de Pitot ピトー管 동압관 空速管 空速管 + Pilot Tüpü Static Port @@ -682,8 +779,8 @@ Puerto estático Statický port Porta Statica - Port statique - スタティック ポート + Système pitot-statique + 静圧管 정압공 静态端口 靜態端口 @@ -702,6 +799,7 @@ 탄약 弹药 彈藥 + Cephane Turret @@ -718,6 +816,7 @@ 포탑 炮塔 砲塔 + Taret Gun @@ -732,8 +831,9 @@ Пушку - + + Silah Commander Turret @@ -743,13 +843,14 @@ Dowódca Wieżyczka Velitel Věž Comandante Torre - Comandante Torretta + Torretta Comandante Parancsnok Lövegtorony Башня командира - 車長の砲塔 + 車長砲塔 지휘관 포탑 指挥官 炮塔 指揮官 砲塔 + Komutan Tareti Commander Gun @@ -759,13 +860,14 @@ Dowódca Działo Velitel Kanón Comandante Canhão - Comandante Cannone + Cannone Comandante Parancsnok Ágyú Пушка командира - 車長の砲 + 車長砲 지휘관 포 指挥官 枪 指揮官 槍 + Komutan Silahı Missiles @@ -781,6 +883,7 @@ 미사일 导弹 導彈 + Füzeler Left Track @@ -793,7 +896,7 @@ Cingolo sinistro Bal lánctalp Левую гусеницу - 左の履帯 + 左履帯 왼쪽 궤도 左履带 左履帶 @@ -809,7 +912,7 @@ Cingolo destro Jobb lánctalp Правую гусеницу - 右の履帯 + 右履帯 오른쪽 궤도 右履带 右履帶 @@ -818,14 +921,14 @@ Left Front Wheel Linkes Vorderrad Rueda frontal izquierda - Roue avant-gauche + Roue avant gauche Przednie lewe koło Levé přední Kolo Roda Dianteira Esquerda Ruota frontale sinistra Bal első kerék Левое переднее колесо - 左の前輪 + 左前輪 왼쪽 앞바퀴 左前轮 左前輪 @@ -834,14 +937,14 @@ Right Front Wheel Rechtes Vorderrad Rueda frontal derecha - Roue avant-droite + Roue avant droite Przednie prawe koło Pravé přední Kolo Roda Dianteira Direita Ruota frontale destra Jobb első kerék Правое переднее колесо - 右の前輪 + 右前輪 오른쪽 앞바퀴 右前轮 右前輪 @@ -850,14 +953,14 @@ Second Left Front Wheel Zweites linkes Vorderrad Segunda rueda frontal izquierda - Deuxième roue avant-gauche + Deuxième roue avant gauche Drugie przednie lewe koło Druhé Levé přední Kolo Segunda Roda Dianteira Esquerda Seconda ruota frontale sinistra Második bal első kerék Второе переднее левое колесо - 左の 2 つめの前輪 + 左第二前輪 왼쪽 두번째 바퀴 第二左前轮 第二左前輪 @@ -866,14 +969,14 @@ Second Right Front Wheel Zweites rechtes Vorderrad Segunda rueda frontal derecha - Deuxième roue avant-droite + Deuxième roue avant droite Drugie przednie prawe koło Druhé Pravé přední Kolo Segunda Roda Dianteira Direita Seconda ruota frontale destra Második jobb hátsó kerék Второе правое переднее колесо - 右の 2 つめの前輪 + 右第二前輪 오른쪽 두번째 바퀴 第二右前轮 第二右前輪 @@ -882,14 +985,14 @@ Left Middle Wheel Linkes mittleres Rad Rueda central izquierda - Roue centre-gauche + Roue centrale gauche Środkowe lewe koło Levé prostřední Kolo Roda Intermediária Esquerda Ruota centrale sinistra Bal középső kerék Левое среднее колесо - 左の中央の前輪 + 左中央輪 왼쪽 가운데 바퀴 左中轮 左中輪 @@ -898,14 +1001,14 @@ Right Middle Wheel Rechtes mittleres Rad Rueda central derecha - Roue centre-droite + Roue centrale droite Środkowe prawe koło Pravé prostřední Kolo Roda Intermediária Direita Ruota centrale destra Jobb középső kerék Правое среднее колесо - 右の中央の前輪 + 右中央輪 오른족 가운데 바퀴 右中轮 右中輪 @@ -914,14 +1017,14 @@ Left Rear Wheel Linkes Hinterrad Rueda trasera izquierda - Roue arrière-gauche + Roue arrière gauche Tylnie lewe koło Levé zadní Kolo Roda Traseira Esquerda Ruota posteriore sinistra Bal hátsó kerék Левое заднее колесо - 左の後輪 + 左後輪 왼쪽 뒤쪽 바퀴 左后轮 左後輪 @@ -930,14 +1033,14 @@ Right Rear Wheel Rechtes Hinterrad Rueda trasera derecha - Roue arrière-droite + Roue arrière droite Tylnie prawe koło Pravé zadní Kolo Roda Traseira Direita Ruota posteriore destra Jobb hátsó kerék Правое заднее колесо - 右の後輪 + 右後輪 오른쪽 뒤쪽 바퀴 右后轮 右後輪 @@ -969,26 +1072,28 @@ Rotore principale Főrotor Несущий винт - 主翼 + メインローター 주 로터 主旋翼 主旋翼 + Ana Rotor Tail Rotor Heckrotor Rotor de cola - Rotor anticouple + Rotor de queue Tylni rotor Ocasní Rotor Rotor de Cauda Rotore di coda Farokrotor Рулевой винт - テイル ローター + テールローター 꼬리 로터 尾桨 尾槳 + Arka Rotor Winch @@ -1004,6 +1109,7 @@ 윈치 绞盘 絞盤 + Vinç Glass (right) @@ -1018,8 +1124,9 @@ Стекло (справа) ガラス (右) 유리 (오른쪽) - 玻璃 (右) + 玻璃(右) 玻璃 (右) + Cam(Sağ) Glass (left) @@ -1034,8 +1141,9 @@ Стекло (слава) ガラス (左) 유리 (왼쪽) - 玻璃 (左) + 玻璃(左) 玻璃 (左) + Cam (sol) Glass @@ -1052,15 +1160,16 @@ 유리 玻璃 玻璃 + Cam ERA ERA ERA - ERA + Corrazza Reattiva Reaktivpanzerung ERA - ERA + Blindage réactif ERA ДЗ ERA @@ -1076,8 +1185,8 @@ Ремонт Ajustes de reparación Nastavení oprav - Impostazioni Riparazioni - Réglages de réparation + Impostazioni di Riparazione + Paramètres des réparations 修理設定 수리 설정 修复设定 @@ -1093,7 +1202,7 @@ Poskytuje rozsáhlý systém oprav pro všechny typy vozidel. Fornisce un sistema di riparazione per tutti i tipi di veicoli. Fournit un système de réparation pour tous les types de véhicules. - 全種類の車両に修理システムを適用しますか? + あらゆる車種に対応した修理システムを提供します。 모든 차량에 대해 수리 시스템을 제공합니다. 提供修复系统给所有载具 提供修復系統給所有載具 @@ -1107,11 +1216,12 @@ Kdokoliv Cualquiera Chiunque - Tout le monde + N'importe qui だれでも 모두 任何人 任何人 + Herkes Engineer only @@ -1122,37 +1232,39 @@ Pouze inženýr Solo ingeniero Solo Geniere - Ingénieurs seulement + Ingénieurs uniquement 工兵のみ 오직 정비공만 只有工兵 只有工兵 + Sadece Mühendis Advanced Engineer only Instandsetzer Solo Geniere avanzato 上級工兵のみ - 只有维修专精兵 + 只有维修专业兵 只有維修專精兵 Tylko zaawansowani mechanicy 고급 정비공만 Только продвинутые инженеры + Somente engenheiro avançado + Ing. avancés uniquement + Pouze pokročilý inženýr + Solo ingeniero avanzado + Sadece Gelişmiş Mühendis - Allow Wheel + Allow Wheel Replacement Erlaube Radwechsel + Permetti sostituzione ruote Wymiana kół - Permite rodas Разрешить замену колес - Možnost Výměny Kol - Permitir rueda - Consenti Ruota - Autoriser les roues - タイヤを許可 - 바퀴 허가 - 允许轮胎 - 允許輪胎 + タイヤ交換の許可 + 바퀴 교체 허용 + Autoriser le remplacement des roues + Permitir Recambio de Rueda Who can remove and replace wheels? @@ -1163,12 +1275,34 @@ Kdo může odstranit a vyměnit kola? ¿Quién puede quitar y cambiar las ruedas? Chi può rimuovere e sostituire le ruote? - Qui peut enlever et remplacer les roues ? + Définit qui peut démonter et remplacer des roues. 誰がタイヤの除去と交換を出来るようにしますか? 누가 바퀴를 제거 및 교체할 수 있습니까? - 谁可维修轮胎? + 谁可维修轮胎? 誰可維修輪胎? + + Allow Wheel Patching + Erlaube Radflicken + Permetti di toppare le ruote + タイヤ補修を許可 + Zezwól na Łatanie Kół + 바퀴 수리 허용 + Autoriser le rafistolage des roues + Разрешить починить колесо + Permitir Parcheo de Rueda + + + Who can patch wheels? + Wer kann Radflicken durchführen? + Chi può rattoppare ruote + 誰がタイヤの補修を出来るようにしますか? + Kto może łatać koła? + 누가 바퀴를 수리할 수 있습니까? + Qui peut rafistoler les roues ? + Кто может починить колеса? + Quién puede parchear ruedas? + Allow Repair Erlaube Reperatur @@ -1178,7 +1312,7 @@ Možnost Opravování Permitir reparación Consenti Riparazioni - Autoriser les réparations + Réparations autorisées pour 修理を許可 수리 허가 允许维修 @@ -1193,10 +1327,10 @@ Kdo může provádět opravy? ¿Quién puede realizar reparaciones? Chi può eseguire riparazioni? - Qui peut réparer ? + Définit qui peut effectuer des réparations. 誰が修理を出来るようににしますか? 누가 수리를 할 수 있습니까? - 谁可以进行维修操作? + 谁可以进行维修操作? 誰可以進行維修操作? @@ -1208,25 +1342,25 @@ Umbral de reparación Práh oprav Limite Riparazioni - Seuil de réparation + Seuil de réparabilité 修理のしきい値 정비 한계치 维修门槛 維修門檻 - What is the maximum damage that can be repaired with a toolkit? + Maximum damage to which a part can be repaired with a toolkit.\n0% means all damage can be repaired. Der maximale Schaden, der von einem Reperatursatz behoben werden kann? Jaki jest maksymalny poziom uszkodzeń jaki może zostać naprawiony przy pomocy narzędzi? Qual é o dano máximo que pode ser reparado com um kit de ferramentas? Какой максимальный урон можно починить с помощью ремкомплекта? ¿Cuál es el daño máximo que puede ser reparado con una caja de herramientas? Jaké maximální poškození může být opraveno pomocí opravárenské sady? - Qual'è il danno massimo che può essere riparato con il Toolkit? - Quel est le maximum de dommages réparable par une trousse à outils ? - ツールキットで修理できる、最大の損傷許容範囲を設定しますか? - 어느정도의 피해까지 툴킷으로 수리가 가능합니까? - 工具包可以修复的最大损坏值? + Qual'è il danno massimo che può essere riparato con il Kit Utensili?\n0% significa che tutti i danni possono essere riparati. + Définit la quantité maximale de dégâts pouvant être réparés avec une trousse à outils. + ツールキットを使用して修復できるパーツの最大ダメージ。\n0% はすべてのダメージを修復できることを意味します。 + 어느정도의 피해까지 도구모음으로 수리가 가능합니까? + 工具包可以修复的最大损坏值? 工具包可以修復的最大損壞值? @@ -1238,25 +1372,25 @@ Umbral de Reparación (Ingeniero) Práh oprav (Inženýr) Limite Riparazioni (Geniere) - Seuil de réparatoin (ingénieur) + Seuil de réparabilité (ingénieurs) 修理のしきい値 (工兵) 정비 한계치 (정비공) - 维修门槛 (工兵) + 维修门槛(工兵) 維修門檻 (工兵) - What is the maximum damage that can be repaired by an engineer? + Maximum damage to which a part can be repaired by an engineer above the minimum level required for the repair.\n0% means all damage can be repaired. Der maximale Schaden, der von einem Pionier behoben werden kann? Jaki jest maksymalny poziom uszkodzeń jaki może zostać naprawiony przez mechanika? Qual é o dano máximo que pode ser reparado com um engenheiro? Какой максимальный урон может починить инженер? ¿Cuál es el daño máximo que puede ser reparado por un ingeniero? Jaké maximální poškození může být opraveno pomoci inženýra? - Qual'è il danno massimo che può essere riparato da un Geniere? - Quel est le maximum de dommages qui peuvent être réparés par un ingénieur ? - 工兵が修理できる、最大の損傷許容範囲を設定しますか? + Qual'è il danno massimo che può essere riparato da un Geniere?\n0% significa che tutti i danni possono essere riparati. + Définit la quantité maximale de dégâts qu'un ingénieur peut réparer. + 修理に必要な最小レベルを超える工兵が修復できるパーツの最大ダメージ。\n0% は、すべてのダメージを修復できることを意味します。 정비공은 어느정도의 피해까지 수리할 수 있습니까? - 工兵可以修复的最大损坏值? + 工兵可以修复的最大损坏值? 工兵可以修復的最大損壞值? @@ -1267,10 +1401,10 @@ Удалять ремкомплект после использования Eliminar conjunto de herramientas al usarlo Odstranit sadu nástrojů po použití - Rimuovi Toolkit dopo l'uso - Enlever la trousse à outils après usage - ツールキットを使うと削除 - 툴킷 사용후 제거 + Consuma Kit Utensili dopo l'uso + Retirer la trousse à outils après usage + ツールキットを使用後に削除 + 도구모음 사용 후 제거 使用后删除工具包 使用後刪除工具包 @@ -1282,11 +1416,11 @@ Следует ли удалять ремкомплект после использования? ¿Deben retirarse las herramientas al usarlas? Má být odstraněna sada nástroju po použití? - Il Toolkit dev'essere rimosso dopo l'uso? - La trousse à outils devrait-elle être enlevée après usage ? - ツールキットを使うと削除しますか? - 툴킷을 사용하면 제거를 합니까? - 要在使用后删除工具包吗? + Il Kit Utensili viene consumato e rimosso dopo l'uso? + Définit si la trousse à outils doit être retirée après usage. + ツールキットを使用時に消費しますか? + 도구모음을 사용하면 제거를 합니까? + 要在使用后删除工具包吗? 要在使用後刪除工具包嗎? @@ -1313,7 +1447,7 @@ Reparar solo en vehículo Pouze opravárenské vozidlo Solo Veicoli Riparazioni - Véhicule de réparation seulement + Véhicules de réparation seulement 修理車両のみ 오직 수리 차량만 维修载具旁 @@ -1328,7 +1462,7 @@ Reparar solo en instalación Pouze opravárenské zařízení Solo Strutture Riparazioni - Installation de réparation seulement + Ateliers de réparation seulement 修理施設のみ 오직 수리 시설만 维修设施旁 @@ -1342,8 +1476,8 @@ Только у ремонтного транспорта или ремонтных сооружений Reparar en instalación o vehículo Opravárenské zařízení nebo vozidlo - Strutture Riparazioni o Veicoli - Installations ou véhicule de réparation + Strutture o Veicoli di Riparazioni + Ateliers ou véhicules de réparation 修理施設または車両のみ 수리 시설혹은 차량 维修设施或载具旁 @@ -1358,7 +1492,7 @@ Přiřadit Inženýra Asignar ingeniero Assegna Geniere - Assigner le rôle d'ingénieur + Assigner ingénieur(s) 工兵にする 정비공 등록 指派工兵 @@ -1387,10 +1521,10 @@ Список имен юнитов, которые будут классифицированы как инженеры, разделенный запятыми. Lista de los nombres de las unidades que serán clasificados como ingeniero, separados por comas. Seznam jmen jednotek, které budou klasifikovány jako inženýr, oddělit čárkami. - Lista di unità che verranno classificate come genieri, separate da virgole. - Liste des noms d'unités qui seront considérées ingénieurs. Séparé par des virgules - 一覧に記載されたユニット名を、工兵として指定します。コンマで複数を指定できます。 - 목록내 보직이름은 정비공으로 분류됩니다. 쉼표로 구분합니다. + Lista di nomi di unità che verranno classificate come genieri, separate da virgole. + Liste d'unités qui seront classées comme ingénieurs, séparées par des virgules. + 工兵に指定されるユニットのリスト。カンマで区切ります。 + 목록 내 보직이름은 정비공으로 분류됩니다. 쉼표로 구분합니다. 工兵名单,把单位名称输入在这边即可定义其为工兵。每个单位使用逗号以做区隔。 工兵名單,把單位名稱輸入在這邊即可定義其為工兵。每個單位使用逗號以做區隔。 @@ -1402,9 +1536,9 @@ Это инженер Es un ingeniero Inženýr - E' Geniere - Est ingénieur - 工兵とする + È Geniere + Qualification technique + 工兵にする 은 정비공이다 是工兵 是工兵 @@ -1413,13 +1547,13 @@ Select the engineering skill level of the unit Wählt die Eignungsstufe zur Ausübung des Pioniers für diese Einheit Wybierz biegłość w dziedzinie naprawy danej jednostki - Selecione o nível de habilidade da unidade em engenhraria + Selecione o nível de habilidade da unidade em engenharia Укажите уровень инженерного мастерства для юнита Selecciona el nivel de conocimientos de ingeniería de la unidad Vyberte úroveň dovednosti inženýra pro jednotku - Seleziona il livello di abilità geniere dell'unità - Sélectionner le niveau d'habilité en réparation de l'unité - ユニットへの工兵スキルを選択 + Seleziona il livello di formazione da geniere dell'unità + Choix du niveau de compétence technique de l'unité. + ユニットの工兵スキルのレベルを定義します。 선택한 인원의 정비 실력을 고르십시요 选择工兵的技术水平 選擇工兵的技術水平 @@ -1433,11 +1567,12 @@ Nikdo Ningún Nessuna - Aucun + Aucune なし 없음 + Hiçbiri Engineer @@ -1453,18 +1588,24 @@ 정비공 工兵 工兵 + Mühendis Adv. Engineer Instandsetzer - Adv. Geniere + Geniere Av. 上級工兵 - 专精 + 高级工兵 專精 Zaaw. mechanik 고급 정비공 Продв. Инженер + Engenheiro Avançado + Ing. avancé + Pokročilý Inženýr + Ingeniero avanzado + Gelişmiş Mühendis Assign one or multiple units as an engineer @@ -1475,8 +1616,8 @@ Asignar una o varias unidades como ingeniero Přiřaďte jednu nebo více osob jako inženýra Assegna una o più unità come genieri - Assigner un ou plusieurs unités comme ingénieur - 修理車両として指定 + Assigne une ou plusieurs unités en tant qu'ingénieur. + 単体、または複数のユニットを工兵として割り当てます 하나 혹은 여러 인원을 정비공으로 등록합니다 指定一个或多个单位为工兵 指定一個或多個單位為工兵 @@ -1490,8 +1631,8 @@ Asignar vehículo de reparación Přiřaďte opraváresnké vozidlo Assegna Veicolo Riparazioni - Assigner en tant que véhicule de réparation - 修理車両として指定 + Affecter véhicule(s) de réparation + 修理車両に割り当て 정비 차량 등록 指定维修载具 指定維修載具 @@ -1515,13 +1656,13 @@ List of vehicles that will be classified as repair vehicle, separated by commas. Eine Aufzählung von Fahrzeugen, die als Reperaturfahrzeug gelten, getrennt durch Kommata Lista nazw pojazdów, które są sklasyfikowane jako pojazdy naprawcze, oddzielone przecinkami. - Lista de veículos que serão classificadas como veículo de reparo. Separado por vígulas. + Lista de veículos que serão classificadas como veículo de reparo. Separado por vírgulas. Список транспортных средств, которые будут классифицированы как ремонтные, разделенный запятыми. Lista de los vehículos que se clasifican como vehículo de reparación, separados por comas. Seznam vozidel, která budou klasifikována jako opravárenská, oddělit čárkami. Lista di Veicoli che verranno considerati veicoli riparazioni, separati da virgole. - Liste de véhicules qui seront considérés comme véhicules de réparation. Séparé par des virgules. - 一覧に記載されたユニット名を、修理車両として指定します。コンマで複数を指定できます。 + Liste de véhicules qui seront classés comme véhicules de réparation, séparés par des virgules. + 修理車両に割り当てる車両のリスト。カンマで区切ります。 목록내 차량은 정비 차량으로 분류됩니다. 쉼표로 구분합니다. 载具名单,把载具名称输入在这边即可定义其为维修载具。每个载具使用逗号以做区隔。 載具名單,把載具名稱輸入在這邊即可定義其為維修載具。每個載具使用逗號以做區隔。 @@ -1534,7 +1675,7 @@ Это ремонтный транспорт Es un vehículo de reparación Opravárenské vozidlo - E' Veicolo Riparazioni + È Veicolo Riparazioni Est un véhicule de réparation 修理車両とする 은 정비 차량이다 @@ -1550,10 +1691,10 @@ ¿Está el vehículo clasificado como un vehículo de reparación? Je vozidlo klasifikováno jako opravárenské? Il veicolo è classificato dome veicolo riparazioni? - Le véhicule est-il considéré comme un véhicule de réparation ? - 車両を修理車両と指定しますか? + Définit s'il s'agit d'un véhicule de réparation. + 車両を修理車両として割り当てます 이 차량을 정비 차량으로 분류합니까? - 此载具是维修载具吗? + 此载具是维修载具吗? 此載具是維修載具嗎? @@ -1565,8 +1706,8 @@ Asignar uno o varios vehículos como vehículo de reparación Přiřaďte jedno nebo více vozidel jako opravárenské vozidlo Assegna uno o più veicoli come veicoli riparazioni - Assigner un ou plusieurs véhicules en tant que véhicule de réparation - 単体、または複数の車両を修理車両とします + Affecte un ou plusieurs véhicules en tant que véhicule de réparation + 単体、または複数の車両を修理車両として割り当てます 하나 혹은 여러 차량을 정비 차량으로 등록합니다 指定一个或多个载具作为维修载具 指定一個或多個載具作為維修載具 @@ -1580,8 +1721,8 @@ Asignar instalación de reparación Přiřaďte opravárenské zařízení Assegna Struttura Riparazioni - Assigner en tant qu'installation de réparation - 修理施設とする + Affecter atelier(s) de réparation + 修理施設に割り当て 정비 시설 등록 指定维修设施 指定維修設施 @@ -1609,9 +1750,9 @@ Список объектов, которые будут классифицированы как ремонтные, разделенный запятыми. Lista de los objetos que se clasifican como instalaciones para la reparación, separados por comas. Seznam objektů, které budou klasifikovány jako opravárenské zařízení, oddělit čárkami. - Lista di oggetti che verranno classificati come strutture riparazioni, separate da virgole. - Liste des objets considérés comme installations de réparation. Séparé par des virgules - 一覧に記載されたユニット名を、修理施設として指定します。コンマで複数を指定できます。 + Lista di oggetti che verranno classificati come strutture riparazioni, separati da virgole. + Liste d'objets qui seront classés comme ateliers de réparation, séparés par des virgules. + 修理施設に割り当てるオブジェクトのリスト。カンマで区切ります。 목록내 시설은 정비 시설으로 분류됩니다. 쉼표로 구분합니다. 设施名单,把设施名称输入在这边即可定义其为维修设施。每个设施使用逗号以做区隔。 設施名單,把設施名稱輸入在這邊即可定義其為維修設施。每個設施使用逗號以做區隔。 @@ -1624,8 +1765,8 @@ Это ремонтное сооружение Es una instalación de reparación Opravárenské zařízení - E' Struttura Riparazioni - Est une installation de réparation + È Struttura Riparazioni + Est un atelier de réparation 修理施設とする 은 정비 시설이다 是维修设施 @@ -1640,10 +1781,10 @@ ¿Está el objeto clasificado como una instalación de reparación? Je objekt klasifikován jako opravárenské zařízení? L'oggetto è classificato come struttura riparazioni? - L'objet est-il considéré comme une installation de réparation ? - オブジェクトを修理施設として指定しますか? + Définit l'objet comme étant un atelier de réparation. + オブジェクトを修理施設として割り当てます 이 시설을 정비 시설로 분류합니까? - 此设施是维修设施吗? + 此设施是维修设施吗? 此設施是維修設施嗎? @@ -1655,10 +1796,10 @@ Asignar uno o varios objetos como una instalación de reparación Přiřaďte jeden nebo více objektů jako opravárenské zařízení Assegna uno o più oggetti come strutture riparazioni - Assigner un ou plusieurs objets en tant que véhicule de réparation - ひとつ、または複数オブジェクトに予備部品を追加 + Assigne un ou plusieurs objets en tant qu'atelier de réparation. + 単体、または複数のオブジェクトを修理施設として割り当てます 하나 혹은 여러 시설을 정비 시설로 등록합니다 - 指定一个或多个对象作为维修设施 + 指定一个或多个物体作为维修设施 指定一個或多個對象作為維修設施 @@ -1685,10 +1826,10 @@ Добавить запасные части в одно или несколько транспортных средств Přidat náhradní díly do jednoho nebo více objektů Aggiungi parti di ricambio ad uno o più oggetti - Ajouter des pièces de rechange à un ou plusieurs objets - 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 + Ajoute des pièces de rechange à un ou plusieurs objets. + 単体、または複数のオブジェクトに予備部品の追加を割り当てます 하나 혹은 여러 물체가 예비 부품을 더합니다 - 添加备件到一个或多个对象上 + 添加备件到一个或多个物体上 添加備件到一個或多個對象上 @@ -1705,18 +1846,19 @@ 목록 名单 名單 + Liste List of objects that will get spare parts added, separated by commas. Eine Aufzählung von Objekten, welche Ersatzteile beherbergen, und durch Kommata getrennt sind. Lista obiektów, które otrzymają części zamienne, oddzielone przecinkiem. - Lista de objetos que ganharão partes sobressalentes, dividos por vírgulas. + Lista de objetos que ganharão partes sobressalentes, divididos por vírgulas. Lista de los objetos que tendrán repuestos añadidos, separados por comas. Список транспортных средств, в которые будут добавляться запчасти, разделенный запятыми. Seznam objektů, které dostanou náhradní díly, oddělit čárkami. - Lista di oggetti a cui verranno aggiunte parti di ricambio, separate da virgole. - Liste des objets qui recevront des pièces de réparation en plus. Séparé par des virgules - 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 + Lista di oggetti a cui verranno aggiunte parti di ricambio, separati da virgole. + Liste d'objets dans lesquels des pièces de rechange seront ajoutées, séparés par des virgules. + 予備部品が追加されるオブジェクトのリスト。カンマで区切ります。 목록내 물체는 예비 부품을 받습니다, 쉼표로 구분합니다. 添加备件到名单的载具上。每个载具使用逗号以做区隔。 添加備件到名單的載具上。每個載具使用逗號以做區隔。 @@ -1761,7 +1903,7 @@ Množství Quantità Quantité - + 数量 수량 数量 數量 @@ -1775,51 +1917,133 @@ Число выбранных запасных частей. Počet vybraných náhradních dílů. Numero di parti di ricambio selezionate. - Nombre de pièces de rechange séléctionnées - 選択された予備部品の数を選択します。 + Nombre de pièces de rechange séléctionnées. + 選択された予備部品の数量を選択します。 선택한 부품의 수 选择的备件数量 選擇的備件數量 - - Wheel repair requirements - Erfordernisse zur Reifenreperatur + + Wheel Change Requirements + Bedingungen für die Reifenreperatur Wym. naprawy kół Requisitos de reparación de ruedas Для ремонта колес требуется Requerimentos para reparo de rodas Vyžaduje opravu kol - Requisiti riparazione ruote - Exigences de réparation de roue - タイヤの修理を必要 + Requisiti sostituzione ruote + Exigences pour réparation des roues + タイヤ修理の要求 바퀴 교체 요구사항 维修轮胎限制 維修輪胎限制 - - Items required to remove/replace wheels + + Items required to remove/replace wheels. Gegenstänge, die zum Entfernen/Austauschen eines Reifens benötigt werden Przedmioty potrzebne do wymiany kół Elementos necesarios para quitar/cambiar ruedas Предметы, которые требуются для снятия/замены колес Itens requeridos para remover/trocar rodas Položka vyžaduje odstraněná/vyměněná kola - Oggetti richiesti per riparare/rimuovere ruote - Items exigés pour enlever/remplacer les roues - タイヤの除去と交換にアイテムを必要としますか? - 바퀴를 제거/교체하는데 필요한 물건 + Oggetti richiesti per rimuovere/sostituire ruote + Outils nécessaires pour le démontage ou le remplacement des roues. + タイヤの除去と交換にアイテムを必要とします。 + 바퀴를 제거/교체하는데 필요한 물건을 정합니다. 需要特定物品来移除/更换车轮 需要特定物品來移除/更換車輪 + + Wheel Patch Requirements + Bedingungen für die Radflicken + Requisiti per rattoppare ruote + タイヤ補修の要求 + Wymagania do Łatania Koła + 바퀴 수리 아이템 필요 + Exigences pour rafistoler une roue + Требования для починки колеса + Requerimientos de Parcheo de Ruedas + + + Items required to patch a wheel. + Gegenstänge, die zum Reifenflicken benötigt werden. + Oggetti richiesti per rattoppare ruote. + タイヤ補修にアイテムを必要とします。 + Przedmioty wymagane do załatania koła + 바퀴를 수리하기 위해 아이템이 필요합니다. + Equipements requis pour rafistoler une roue. + Предметы, необходимые для починки колеса. + Objetos requeridos para parchear una rueda. + + + Misc Repair Requirements + Sonstige Reparaturbedingungen + 部分修理の条件 + 額外修理條件 + 部分全面维修条件 + Exigences pour réparations diverses + Requisiti di riparazione vari + Požadavky pro částečnou opravu + Rózne wymagania do naprawy + Requerimentos para reparos variados + Requisitos de objetos misceláneos de reparación + Требования к разному ремонту + 기타 수리 요구사항 + + + Items required to repair a specific vehicle component or remove/replace tracks. + Gegenstände die benötigt werden, um eine spezifische Fahrzeugkomponente oder eine Kette zu entfernen/auszutauschen. + 車両の特定コンポーネントの修理や履帯の除去/交換にアイテムを必要とします。 + 是否需要物品來修復一些特別載具部位或者移除/替換履帶 + 维修特定车辆部件或拆除/更换轨道所需的物品。 + Outils nécessaires pour la réparation d'un équipement spécifique du véhicule, et pour le démontage ou le remplacement des chenilles. + Předměty potřebné k provedení opravy konkrétní části vozidla nebo sundání/výměny pásů. + Przedmioty wymagane do naprawy określonego elementu pojazdu lub usunięcia/wymiany gąsienicy. + Items necessários para reparar uma peça específica ou remover/substituir lagarta. + Objetos necesarios para reparar un componente específico del vehículo o quitar/reemplazar las orugas. + Oggetti necessari per riparare un componente specifico del veicolo o per rimuovere/sostituire i cingoli + Предметы, необходимые для ремонта отдельных компонентов или снятия/замены гусеницы. + 차량의 궤도나 부품을 제거/교체할 때 필요한 아이템을 정합니다. + + + Full Repair Requirements + Bedingungen für vollständige Reparatur + 完全修理の条件 + 完整修復條件 + 全面维修条件 + Exigences pour réparations complètes + Requisiti per la riparazione completa + Požadavky pro plnou opravu + Wymagania pełnej naprawy + Requerimentos de Reparo Completo + Requisitos para reparación completa + Требования к полному ремонту + 완전 수리 요구사항 + + + Items required to perform a full vehicle repair. + Gegenstände die benötigt werden um ein Fahrzeug vollständig zu reparieren. + 車両の完全修理にアイテムを必要とします。 + 是否需要物品來完整修復載具 + 进行全面车辆维修所需的物品。 + Outils nécessaires pour effectuer une réparation complète des véhicules. + Předměty potřebné k provedení plné opravy vozidla. + Przedmioty wymagane do przeprowadzenia pełnej naprawy pojazdu. + Itens requeridos para realizar um reparo veicular completo. + Objetos requeridos para una reparación completa + Oggetti necessari per eseguire una riparazione completa del veicolo. + Предметы, необходимые для полного ремонта техники. + 차량 완전 수리 시 필요한 아이템을 정합니다. + Engine must be off to repair - Motor muss ausgeschaltet zu reparieren sein + Motor muss ausgeschaltet sein um zu reparieren El motor necesita desactivado para la reparación Pro opravu je zapotřebí vypnout motor O motor deve estar desligado para manutenção - Le moteur doit être éteins pour réparer + Le moteur doit être arrêté pour la réparation. Двигатель должен быть выключен для ремонта - 修理のためにエンジンを停止させる必要があります。 + 修理するにはエンジンを停止する必要があります Silnik musi być wyłączony w celu naprawy 수리를 위해서는 엔진을 꺼야만 합니다 Il motore deve essere spento per poter riparare @@ -1835,16 +2059,26 @@ 备用履带 Zapasowe Gąsienice Запасные траки + Esteiras Reservas + Chenilles de rechange + Náhradní pásy + Orugas de repuesto + 여분 궤도 Number of spare tracks in cargo. Anzahl der Ersatzketten im Laderaum. - カーゴ内にある予備履帯の数を指定します。 - Numero dei cingoli di scorta nel cargo. + 貨物室内の予備履帯の数を指定 + Numero dei cingoli di scorta nel carico. 設定載具在貨艙內攜帶的備用履帶數量 设定载具在货舱内携带的备用履带数量。 Liczba zapasowych gąsienic w ładunku. Количество запасных траков в грузовом отсеке + Número de esteiras reservas na Carga + Nombre de chenilles de rechange dans la cargaison. + Počet náhradních pásů v nákladovém prostoru vozidla. + Número de orugas de repuesto en la carga + 화물칸 안에 여분 궤도 수 Spare Wheels @@ -1855,36 +2089,210 @@ 备用轮胎 Zapasowe Koła Запасные колеса + Pneus Reservas + Roues de secours + Náhradní kola + Ruedas de repuesto + 여분 바퀴 Number of spare wheels in cargo. Anzahl der Ersatzreifen im Laderaum. - カーゴ内にある予備タイヤの数を指定します。 + 貨物室内の予備タイヤの数を指定 Numero delle ruote di scorta nel cargo. 設定載具在貨艙內攜帶的備用輪胎數量 设定载具在货舱内携带的备用轮胎数量。 Liczba zapasowych kół w ładunku. Количество запасных колес в грузовом отсеке + Número de pneus reservas na Carga + Nombre de roues de secours dans la cargaison. + Počet náhradních kol v nákladovém prostoru vozidla. + Número de ruedas de repuesto en la carga + 화물칸 안에 여분 바퀴 수 Auto shut off engine on repair Motor automatisch ausschalten - 修理時にエンジン自動停止 - 维修时自动关闭发动机。 + 修理時にエンジンを自動停止 + 维修时自动关闭发动机 維修時自動關閉引擎 - Motore spento automaticamente durante la riparazione + Spegnimento automatico motore durante riparazioni Automatycznie wyłącz silnik podczas napraw Автоотключение двигателя при ремонте + Desligar motor automaticamente enquanto reparar + Arrêt auto du moteur lors d'une réparation + Automaticky vypnout motor při opravách + Apagar el motor automáticamente al 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. + Coupe automatiquement le moteur lorsque des réparations sont effectuées. + Automaticky vypne motor při zahájení oprav. + Apagar el motor automáticamente al efectuar una reparación + 수리 시 엔진을 자동으로 끕니다. + + + Part Repair Time + 部分修理所要時間 + Czas Naprawy Części + Durata di riparazione componente + Teilreparaturzeit + 부품 수리 시간 + Temps de réparation des pièces + Время ремонта детали + Tiempo de Reparación de Pieza + + + Time in seconds to complete a repair. + 修理完了までの所要時間 (秒単位) + Czas w sekundach do przeprowadzenia naprawy + Tempo in secondi richiesto per completare una riparazione. + Zeit in Sekunden, um eine Reparatur abzuschließen. + 수리를 완료하는 시간(초 단위) + Durée en secondes pour terminer une réparation. + Время завершения ремонта в секундах. + Tiempo en segundos para completar una reparación. + + + Wheel Change Time + タイヤ交換所要時間 + Czas Zmiany Koła + Durata di sostituzione ruote + Radwechselzeit + 바퀴 교체 시간 + Temps de changement d'une roue + Время замены колеса + Tiempo de Cambio de Rueda + + + Time in seconds to remove or change a wheel. + タイヤの取り外しまたは交換に掛かる時間。 (秒単位) + Czas w sekundach do zdjęcia lub zmienienia koła. + Tempo in secondi richiesto per rimuovere o sostituire una ruota. + Zeit in Sekunden, um ein Rad zu entfernen oder zu wechseln. + 바퀴를 제거하거나 교체하는 데 걸리는 시간(초 단위) + Durée en seconde pour enlever ou changer une roue. + Время в секундах на снятие или замену колеса. + Tiempo en segundos para quitar o cambiar una rueda. + + + Patch Wheel + Rad flicken + Rattoppa ruota + タイヤを補修する + Załataj Koło + 바퀴 수리 + Rafistoler la roue + Чинить колесо + Parchear Rueda + + + Patching Wheel... + Rad flicken... + Rattoppando ruota... + タイヤを補修しています・・・ + Łatanie Koła... + 바퀴 수리 중... + Rafistolage de la roue... + Починка колеса... + Parcheando Rueda... + + + Wheel Patch Time + タイヤ補修所要時間 + Czas Łatania Koła + Durata di rattoppamento ruote + Zeit um Räder zu flicken + 바퀴 수리 시간 + Temps de rafistolage d'une roue + Время починки полеса + Tiempo de Parcheo de Rueda + + + Time it takes to patch a wheel by 5%. + タイヤを5%補修するのに掛かる時間。 + Czas potrzebny na załatanie koła o 5%. + Tempo richiesto per ridurre i danni di una ruota del 5%. + Zeit, die benötigt wird, um ein Rad um 5 % zu flicken. + 바퀴를 5% 수리하는 데 걸리는 시간(초 단위) + Durée pour rafistoler une roue de 5%. + Время, необходимое для починки колеса, сокращается на 5%. + Tiempo que lleva parchear una rueda por cada 5%. + + + Patch Wheel Threshold + タイヤ補修しきい値 + Próg Łatania Koła + Limite rattoppamento ruota + Rad flicken Schwellenwert + 바퀴 수리 한계점 + Seuil de rafistolage d'une roue + Порог починки колеса + Umbral de Parcheo de Rueda + + + Maximum damage to which a wheel can be patched.\n0% means all damage can be repaired. + タイヤをのダメージ補修できる最大の度合い。/n 0%は、すべてのダメージが修復可能であることを意味します。 + Maksymalny poziom, do którego koło może zostać załatane.\n0% oznacza że każde uszkodzenia mogą być naprawione. + Livello di integrità massimo di una ruota rattoppata. + Maximales Level, bis zu dem ein Rad geflickt werden kann.\n0% bedeutet, dass das Rad vollständig repariert werden kann. + 바퀴를 수리할 수 있는 최대 레벨입니다. + Niveau maximum de dégâts jusqu'à laquelle une roue peut être réparée.\n0% signifie que la roue peut être reparée entièrement. + Максимальный уровень, до которого колесо может быть починено. + Máximo daño que permite a una rueda ser parcheada.\n0% significa que todo el daño puede ser reparado. + + + Wheel Patch Location + タイヤ補修可能な場所 + Miejsce Łatania Koła + Luoghi rattoppamento ruote + Räder Flick Ort + 바퀴 수리 장소 + Lieu de rafistolage des roues + Место починки колеса + Localización para el Parcheo de Rueda + + + Where the wheel can be patched. + タイヤを補修することが出来る場所。 + Gdzie można załatać koło. + In quali luoghi è possibile rattoppare una ruota? + Wo das Rad geflickt werden kann. + 바퀴를 수리할 수 있는 곳입니다. + Lieu où les roues peuvent être rafistolées. + Где колесо можно починить. + Dónde puede ser parcheada la rueda. + + + On the ground + Auf dem Boden + 地上 + Per terra + Na ziemi + 지면 위 + Sur le terrain + На земле + En el suelo + + + On a vehicle + An einem Fahrzeug + Su un veicolo + 車両上 + Na pojeździe + 차량 + Sur un véhicule + На транспорте + En un vehículo diff --git a/addons/repair/ui/patch_ca.paa b/addons/repair/ui/patch_ca.paa new file mode 100644 index 0000000000..4aadbc2174 Binary files /dev/null and b/addons/repair/ui/patch_ca.paa differ diff --git a/addons/respawn/ACE_Settings.hpp b/addons/respawn/ACE_Settings.hpp index d9dd41134e..4b4c977844 100644 --- a/addons/respawn/ACE_Settings.hpp +++ b/addons/respawn/ACE_Settings.hpp @@ -1,18 +1,10 @@ class ACE_Settings { class GVAR(savePreDeathGear) { - category = CSTRING(DisplayName); - displayName = CSTRING(SavePreDeathGear_DisplayName); - description = CSTRING(SavePreDeathGear_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(removeDeadBodiesDisconnected) { - category = CSTRING(DisplayName); - displayName = CSTRING(RemoveDeadBodiesDisconnected_DisplayName); - description = CSTRING(RemoveDeadBodiesDisconnected_Description); - value = 1; - typeName = "BOOL"; + movedToSQF = 1; }; // Not used anywhere??? // class GVAR(bodyRemoveTimer) { diff --git a/addons/respawn/CfgEventHandlers.hpp b/addons/respawn/CfgEventHandlers.hpp index 481d36cf30..17208865ab 100644 --- a/addons/respawn/CfgEventHandlers.hpp +++ b/addons/respawn/CfgEventHandlers.hpp @@ -1,20 +1,20 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - serverInit = QUOTE(call COMPILE_FILE(XEH_serverPostInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + serverInit = QUOTE(call COMPILE_SCRIPT(XEH_serverPostInit)); }; }; diff --git a/addons/respawn/CfgVehicles.hpp b/addons/respawn/CfgVehicles.hpp index c5e30a3028..bda6c44151 100644 --- a/addons/respawn/CfgVehicles.hpp +++ b/addons/respawn/CfgVehicles.hpp @@ -64,12 +64,12 @@ class CfgVehicles { // team leader class Man; - class CAManBase : Man { + class CAManBase: Man { class ACE_SelfActions { class ACE_MoveRallypoint { displayName = CSTRING(Rallypoint_MoveRallypoint); - condition = QUOTE([ARR_2(_player, side group _player)] call FUNC(canMoveRallypoint)); - statement = QUOTE([ARR_2(_player, side group _player)] call FUNC(moveRallypoint)); + condition = QUOTE([ARR_2(_player,side group _player)] call FUNC(canMoveRallypoint)); + statement = QUOTE([ARR_2(_player,side group _player)] call FUNC(moveRallypoint)); exceptions[] = {"isNotSwimming"}; showDisabled = 0; }; diff --git a/addons/respawn/README.md b/addons/respawn/README.md index 1a9bcfe49f..753114be99 100644 --- a/addons/respawn/README.md +++ b/addons/respawn/README.md @@ -2,11 +2,3 @@ ace_respawn =========== Various module options to help mission makers to quickly set up various respawn configurations. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [bux578](https://github.com/bux578) diff --git a/addons/respawn/XEH_postInit.sqf b/addons/respawn/XEH_postInit.sqf index 6c1b1e9961..502f5f729f 100644 --- a/addons/respawn/XEH_postInit.sqf +++ b/addons/respawn/XEH_postInit.sqf @@ -1,7 +1,7 @@ // by commy2 #include "script_component.hpp" -["ace_rallypointMoved", FUNC(updateRallypoint)] call CBA_fnc_addEventHandler; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; // hide enemy rallypoint markers +["ace_rallypointMoved", LINKFUNC(updateRallypoint)] call CBA_fnc_addEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; // hide enemy rallypoint markers -[QGVAR(showFriendlyFireMessageEvent), FUNC(showFriendlyFireMessage)] call CBA_fnc_addEventHandler; +[QGVAR(showFriendlyFireMessageEvent), LINKFUNC(showFriendlyFireMessage)] call CBA_fnc_addEventHandler; diff --git a/addons/respawn/XEH_preInit.sqf b/addons/respawn/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/respawn/XEH_preInit.sqf +++ b/addons/respawn/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/respawn/XEH_serverPostInit.sqf b/addons/respawn/XEH_serverPostInit.sqf index 727b04d68d..205dc49e0f 100644 --- a/addons/respawn/XEH_serverPostInit.sqf +++ b/addons/respawn/XEH_serverPostInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -["ace_settingsInitialized", { +["CBA_settingsInitialized", { if (GVAR(RemoveDeadBodiesDisconnected)) then { addMissionEventHandler ["HandleDisconnect", { [{ diff --git a/addons/respawn/config.cpp b/addons/respawn/config.cpp index 79fbf69d74..b0a86336a4 100644 --- a/addons/respawn/config.cpp +++ b/addons/respawn/config.cpp @@ -3,8 +3,8 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; - weapons[] = {"ACE_Rallypoint_West", "ACE_Rallypoint_East", "ACE_Rallypoint_Independent", "ACE_Rallypoint_West_Base", "ACE_Rallypoint_East_Base", "ACE_Rallypoint_Independent_Base"}; + units[] = {"ACE_Rallypoint_West", "ACE_Rallypoint_East", "ACE_Rallypoint_Independent", "ACE_Rallypoint_West_Base", "ACE_Rallypoint_East_Base", "ACE_Rallypoint_Independent_Base"}; + weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = { "ace_common" }; author = ECSTRING(common,ACETeam); diff --git a/addons/respawn/functions/fnc_canMoveRallypoint.sqf b/addons/respawn/functions/fnc_canMoveRallypoint.sqf index f37ad34265..1f9a3637bc 100644 --- a/addons/respawn/functions/fnc_canMoveRallypoint.sqf +++ b/addons/respawn/functions/fnc_canMoveRallypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Checks if a unit can move a rally point. diff --git a/addons/respawn/functions/fnc_handleInitPostServer.sqf b/addons/respawn/functions/fnc_handleInitPostServer.sqf index 4de502a9ea..8ac8bd76b6 100644 --- a/addons/respawn/functions/fnc_handleInitPostServer.sqf +++ b/addons/respawn/functions/fnc_handleInitPostServer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle XEH Init Post on Server. diff --git a/addons/respawn/functions/fnc_handleKilled.sqf b/addons/respawn/functions/fnc_handleKilled.sqf index 0a6fcd8ce8..1383561f2c 100644 --- a/addons/respawn/functions/fnc_handleKilled.sqf +++ b/addons/respawn/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Handles the XEH killed event. @@ -20,8 +20,9 @@ params ["_unit"]; // Saves the gear when the player! (and only him) is killed if (ACE_player == _unit && {GVAR(SavePreDeathGear)}) then { - _unit setVariable [QGVAR(unitGear), getUnitLoadout _unit]; + _unit setVariable [QGVAR(unitGear), [_unit] call CBA_fnc_getLoadout]; _unit setVariable [QGVAR(activeWeaponAndMuzzle), [currentWeapon _unit, currentMuzzle _unit, currentWeaponMode _unit]]; + [QGVAR(saveGear), _unit] call CBA_fnc_localEvent; }; if (missionNamespace getVariable [QGVAR(showFriendlyFireMessage), false]) then { diff --git a/addons/respawn/functions/fnc_handlePlayerChanged.sqf b/addons/respawn/functions/fnc_handlePlayerChanged.sqf index 9fc71af9b7..9514966541 100644 --- a/addons/respawn/functions/fnc_handlePlayerChanged.sqf +++ b/addons/respawn/functions/fnc_handlePlayerChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle player changed event. Updates visibility of Rallypoint markers. @@ -19,9 +19,9 @@ params ["_newUnit"]; private _side = side group _newUnit; -((GETMVAR(ACE_Rallypoint_West, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == west)); -((GETMVAR(ACE_Rallypoint_West_Base, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == west)); -((GETMVAR(ACE_Rallypoint_East, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == east)); -((GETMVAR(ACE_Rallypoint_East_Base, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == east)); -((GETMVAR(ACE_Rallypoint_Independent, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == independent)); -((GETMVAR(ACE_Rallypoint_Independent_Base, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == independent)); +((GETMVAR(ACE_Rallypoint_West,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == west)); +((GETMVAR(ACE_Rallypoint_West_Base,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == west)); +((GETMVAR(ACE_Rallypoint_East,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == east)); +((GETMVAR(ACE_Rallypoint_East_Base,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == east)); +((GETMVAR(ACE_Rallypoint_Independent,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == independent)); +((GETMVAR(ACE_Rallypoint_Independent_Base,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == independent)); diff --git a/addons/respawn/functions/fnc_handleRespawn.sqf b/addons/respawn/functions/fnc_handleRespawn.sqf index a8c65056b3..7194d6ee0f 100644 --- a/addons/respawn/functions/fnc_handleRespawn.sqf +++ b/addons/respawn/functions/fnc_handleRespawn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Handles the XEH Respawn event. diff --git a/addons/respawn/functions/fnc_initRallypoint.sqf b/addons/respawn/functions/fnc_initRallypoint.sqf index 0286813cef..7e4651e1e9 100644 --- a/addons/respawn/functions/fnc_initRallypoint.sqf +++ b/addons/respawn/functions/fnc_initRallypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Init code for rallypoints. @@ -53,7 +53,7 @@ if (hasInterface) then { private _type = ["selector_selectedFriendly", "selector_selectedEnemy"] select (_respawnMarker == ""); _marker setMarkerTypeLocal _type; - _marker setMarkerAlphaLocal ([0,1] select (_side == playerSide)); // playerSide to guarantee init + _marker setMarkerAlphaLocal (parseNumber (_side == playerSide)); // playerSide to guarantee init private _date = _rallypoint getVariable [QGVAR(markerDate), ""]; diff --git a/addons/respawn/functions/fnc_module.sqf b/addons/respawn/functions/fnc_module.sqf index 72b4003bbc..acd9ae53e8 100644 --- a/addons/respawn/functions/fnc_module.sqf +++ b/addons/respawn/functions/fnc_module.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, bux578, esteldunedain, commy2 * Initializes the respawn module. diff --git a/addons/respawn/functions/fnc_moduleFriendlyFire.sqf b/addons/respawn/functions/fnc_moduleFriendlyFire.sqf index 2801e26b26..7d9a2eccbd 100644 --- a/addons/respawn/functions/fnc_moduleFriendlyFire.sqf +++ b/addons/respawn/functions/fnc_moduleFriendlyFire.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Initializes the friendly fire module. diff --git a/addons/respawn/functions/fnc_moduleRallypoint.sqf b/addons/respawn/functions/fnc_moduleRallypoint.sqf index a06220fec8..31ba68f1d6 100644 --- a/addons/respawn/functions/fnc_moduleRallypoint.sqf +++ b/addons/respawn/functions/fnc_moduleRallypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Initializes the Rallypoint module. @@ -23,7 +23,6 @@ if !(_activated) exitWith {}; { _x setVariable ["ACE_canMoveRallypoint", true]; - false -} count _units; +} forEach _units; INFO("Rallypoint Module Initialized."); diff --git a/addons/respawn/functions/fnc_moveRallypoint.sqf b/addons/respawn/functions/fnc_moveRallypoint.sqf index d0e191829e..3c4d8b6441 100644 --- a/addons/respawn/functions/fnc_moveRallypoint.sqf +++ b/addons/respawn/functions/fnc_moveRallypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Moves a rallypoint to the players location. diff --git a/addons/respawn/functions/fnc_restoreGear.sqf b/addons/respawn/functions/fnc_restoreGear.sqf index 990fa77ea8..afbc7def86 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578, commy2 * Restores previously saved gear. @@ -17,17 +17,11 @@ */ params ["_unit", "_allGear", "_activeWeaponAndMuzzle"]; -TRACE_3("restoreGear",_unit, count _allGear, _activeWeaponAndMuzzle); +TRACE_3("restoreGear",_unit,count _allGear,_activeWeaponAndMuzzle); // restore all gear if (!isNil "_allGear") then { - _allGear params ["_primaryWeaponArray"]; - if ((_primaryWeaponArray param [0, ""]) == "ACE_FakePrimaryWeapon") then { - TRACE_1("Ignoring fake gun",_primaryWeaponArray); - _allGear set [0, []]; - _activeWeaponAndMuzzle = nil; - }; - _unit setUnitLoadout _allGear; + [_unit, _allGear] call CBA_fnc_setLoadout; }; // restore the last active weapon, muzzle and weaponMode diff --git a/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf b/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf index a20c9926f5..a2a672d3f6 100644 --- a/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf +++ b/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Shows a message in system chat of who killed whom. @@ -11,7 +11,7 @@ * None * * Example: - * [ACE_Player, killer] call ace_module_fnc_functionName + * [ACE_Player, killer] call ace_respawn_fnc_showFriendlyFireMessage * * Public: No */ diff --git a/addons/respawn/functions/fnc_teleportToRallypoint.sqf b/addons/respawn/functions/fnc_teleportToRallypoint.sqf index 6c8a697279..abecc26465 100644 --- a/addons/respawn/functions/fnc_teleportToRallypoint.sqf +++ b/addons/respawn/functions/fnc_teleportToRallypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Teleports a unit to a rallypoint diff --git a/addons/respawn/functions/fnc_updateRallypoint.sqf b/addons/respawn/functions/fnc_updateRallypoint.sqf index 363e12972b..a0e14a4ed2 100644 --- a/addons/respawn/functions/fnc_updateRallypoint.sqf +++ b/addons/respawn/functions/fnc_updateRallypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Updates marker position and texts. @@ -17,7 +17,8 @@ * Public: No */ -params ["_rallypoint", "_side", "_position"]; +params ["_rallypoint", "_side"]; +private _position = param [2, getpos _rallypoint]; if (!hasInterface) exitWith {}; diff --git a/addons/respawn/functions/script_component.hpp b/addons/respawn/functions/script_component.hpp deleted file mode 100644 index eeb32a47bd..0000000000 --- a/addons/respawn/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\respawn\script_component.hpp" \ No newline at end of file diff --git a/addons/respawn/initSettings.inc.sqf b/addons/respawn/initSettings.inc.sqf new file mode 100644 index 0000000000..836ede4811 --- /dev/null +++ b/addons/respawn/initSettings.inc.sqf @@ -0,0 +1,17 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(savePreDeathGear), "CHECKBOX", + [LSTRING(SavePreDeathGear_DisplayName), LSTRING(SavePreDeathGear_Description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(removeDeadBodiesDisconnected), "CHECKBOX", + [LSTRING(RemoveDeadBodiesDisconnected_DisplayName), LSTRING(RemoveDeadBodiesDisconnected_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index 210ccf520d..6db9f12913 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -7,9 +7,15 @@ Riapparizione 重生 重生 - リスポン + リスポーン Odrodzenie Возрождение + Ressurgimento + Réapparition + Znovuzrození + Yeniden Doğma + Reaparición + 재투입 Deploy in 5 seconds... @@ -18,13 +24,13 @@ Despliegue en 5 segundos... Возрождение через 5 секунд... Rozmieszczenie za 5 sekund... - Respawn za 5 sekund... + Znovuzrození za 5 sekund... Kihelyezés 5 másodperc múlva... Dispiegamento in 5 secondi... Será posicionado em 5 segundos... - 設置まであと 5 秒・・・ - 5초 후 재배치... - 5秒后完成布署... + 5秒後に設置します・・・ + 5초 후 재투입... + 5秒后完成部署... 5秒後完成佈署... @@ -40,7 +46,7 @@ Rallypoints posicionado ラリーポイントを設置しました 집결지 배치됨 - 集合点布署完成 + 集合点部署完成 集合點佈署完成 @@ -53,15 +59,16 @@ Téléportation à la base Teletransportar para a Base Bázisra teleportálás - Teleporta alla base + Teleporta in base ベースへ移動 기지로 순간이동 传送至基地 傳送至基地 + Üsse Işınlan Teleport to Rallypoint - Teleport na Rallypoint + Teleport na Bod shromáždění Teletransportar a Punto de reunión Zum Sammelpunkt teleportieren Teleport do punktu zbiórki @@ -90,6 +97,7 @@ 기지로 순간이동함 已传送至基地 已傳送至基地 + Üsse Işınlan Teleported to Rallypoint @@ -98,7 +106,7 @@ Teletransportado al punto de reunión Вы были телепортированы на точку сбора Przeteleportowano do punktu zbiórki - Teleportován na rallypoint + Teleportován na bod shromáždění Gyülekezőpontra teleportálva Teleportato al rallypoint Teletransportado para o Rallypoints @@ -114,12 +122,12 @@ Точка сбора Синих (База) Punkt zbiórki Zachodu (Baza) Point de ralliement OUEST (Base) - Rallypoint West (Base) + Rallypoint Ovest (Base) Gyülekezőpont, Nyugat (Bázis) - Rallypoint Západ (Základna) + Bod shromáždění Západ (Základna) Ponto de encontro Oeste (Base) ラリーポイント 同盟軍 (ベース) - 蓝方集合点 (基地) + 蓝方集合点(基地) 藍方集合點 (基地) 청군 집결지 (기지) @@ -130,12 +138,12 @@ Точка сбора Красных (База) Punkt zbiórki Wschodu (Baza) Point de ralliement EST (Base) - Rallypoint East (Base) + Rallypoint Est (Base) Gyülekezőpont, Kelet (Bázis) - Ralllypoint Východ (Základna) - Ponto de encontro Lest (Base) + Bod shromáždění Východ (Základna) + Ponto de encontro Leste (Base) ラリーポイント OPFOR軍 (ベース) - 红方集合点 (基地) + 红方集合点(基地) 紅方集合點 (基地) 대항군 집결지 (기지) @@ -146,14 +154,14 @@ Точка сбора Независимых (База) Punkt zbiórki Ruchu oporu (Baza) Point de ralliement Indépendant (Base) - Rallypoint Independent (Base) + Rallypoint Indipendenti (Base) Gyülekezőpont, Független (Bázis) - Rallypoint Nezávislý (Základna) + Bod shromáždění Nezávislý (Základna) Ponto de encontro Independente (Base) ラリーポイント 独立軍 (ベース) - 独立方集合点 (基地) + 独立方集合点(基地) 獨立方集合點 (基地) - 독립군 집결지 (기지) + 무소속군 집결지 (기지) Rallypoint West @@ -162,9 +170,9 @@ Точка сбора Синих Punkt zbiórki Zachodu Point de ralliement OUEST - Rallypoint West + Rallypoint Ovest Gyülekezőpont, Nyugat - Rallypoint Západ + Bod shromáždění Západ Ponto de encontro Oeste ラリーポイント 同盟軍 蓝方集合点 @@ -178,9 +186,9 @@ Точка сбора Красных Punkt zbiórki Wschodu Point de ralliement EST - Rallypoint East + Rallypoint Est Gyülekezőpont, Kelet - Rallypoint Východ + Bod shromáždění Východ Ponto de encontro Leste ラリーポイント OPFOR軍 红方集合点 @@ -194,14 +202,14 @@ Точка сбора Независимых Punkt zbiórki Ruchu oporu Point de ralliement Indépendant - Rallypoint Independent + Rallypoint Indipendenti Gyülekezőpont, Független - Rallypoint Nezávislý + Bod shromáždění Nezávislý Ponto de encontro Independente ラリーポイント 独立軍 独立方集合点 獨立方集合點 - 독립군 집결지 + 무소속군 집결지 Respawn System @@ -210,12 +218,12 @@ Wiedereinstiegs-System Systém znovuzrození Sistema de Renascimento - Système de Respawn + Système de réapparition Respawn-rendszer Возрождение Sistema Respawn - リスポン システム - 재배치 시스템 + リスポーン システム + 재투입 시스템 重生系统 重生系統 @@ -226,14 +234,15 @@ Ausrüstung speichern? Uložit výbavu? Salvar equipamento? - Sauver l'équipement? + Sauver l'équipement Felszerelés elmentése? Сохранять снаряжение? Salva Equipaggiamento? - 装備を保存? + 装備保存を有効化 장비를 저장합니까? - 储存装备? + 储存装备? 儲存裝備? + Kıyafetleri Kaydet? Respawn with the gear a soldier had just before his death? @@ -242,13 +251,13 @@ Mit der Ausrüstung, die ein Soldat vor seinem Tod hatte, wiedereinsteigen? Znovuubjevit s výbavou kterou měl voják před smrtí? Renascer com o equipamento que um soldado tinha antes de sua morte? - Conserve l'équipement au Respawn + Le soldat réapparaît avec l'équipement qu'il avait juste avant sa mort. Az egység halála előtti felszerelésével való respawnolása? Возрождать солдата с тем же снаряжением, которое было на нем при смерти? Respawna con l'equipaggiamento che il soldato aveva appena prima di morire? - ユニットが死ぬ前に持っていた装備でリスポンしますか? - 죽기 전에 가지고 있던 장비로 재배치합니까? - 是否在重生时载入死亡前的装备? + ユニットが死ぬ前に持っていた装備でリスポーンできるように設定できます。 + 죽기 전에 가지고 있던 장비로 재투입합니까? + 是否在重生时载入死亡前的装备? 是否在重生時載入死亡前的裝備? @@ -258,14 +267,15 @@ Sollen Leichen automatisch verschwinden? Odstranit těla? Remover corpos? - Enlever les coprs? + Enlever les corps Holttestek eltávolítása? Удалять трупы? Rimuovi corpi? - 死体を削除? + 死体を削除 시체를 제거합니까? - 删除尸体? + 删除尸体? 刪除屍體? + Bedeni Sil ? Remove player bodies after disconnect? @@ -274,13 +284,13 @@ Entferne Spielerkörper nach dem Trennen einer Verbindung? Odstranit hráčova těla po odpojení? Remover corpos dos jogadores depois de desconectar? - Enlève les corps de joueurs après déconnection + Enlève le cadavre des joueurs quand ils se déconnectent. Játékosi testek eltávolítása távozás után? Удалять трупы игроков после дисконнекта? Rimuovi i corpi dei giocatori quando si disconnettono? - 切断後はプレイヤーの死体を削除しますか? + 切断したプレイヤーの死体を削除するかどうかを設定できます。 접속이 끊긴 플레이어의 시체를 제거합니까? - 要删除已离线的玩家尸体吗? + 要删除已离线的玩家尸体吗? 要刪除已離線的玩家屍體嗎? @@ -292,20 +302,26 @@ 死体削除タイマー Czas usunięcia ciała Время удаления трупов + Tempo para remover corpo + Minuterie enlèvement corps + Časovač odstranění mrtvol + Bedenin Silinme Süresi + Temporizador para eliminar cuerpos + 시체 제거 타이머 This module enables you to configure ACE functionality specific to respawns. Moduł ten pozwala dostosować ustawienia odrodzenia (respawnu). Dieses Modul erlaubt es, die Wiedereinstiegs-Einstellungen anzupassen. - Tento modul umožňuje nastavení znovuzrození (spawn). + Tento modul umožňuje nastavení znovuzrození (respawn). Este módulo permite que você personalize as configurações do renascimento (Spawn). Этот модуль позволяет настроить систему возрождения. - Ce module permet de régler les options de Respawn + Ce module vous permet de configurer les fonctionnalités ACE spécifiques à la réapparition des joueurs. Questo modulo ti permette di configurare le funzionalità ACE specifiche dei respawn. Este módulo permite configurar parámetros relacionados con la reaparición - 有効化するとリスポンへ ACE 機能を設定できます。 - 이 모듈은 ACE 재배치의 자세한 설정을 변결할 수 있게 해줍니다. - 该模块使您可以设定ACE的重生功能 + 有効化するとリスポーンへ ACE 機能を設定できます。 + 이 모듈은 ACE 재투입의 자세한 설정을 변경할 수 있게 해줍니다. + 该模块使您可以设定 ACE 的重生功能 該模塊使您可以設定ACE的重生功能 @@ -315,13 +331,13 @@ Nachricht bei Freundbeschuss Upozornění na přátelskou střelbu Mensagens de fogo amigo - Message de tirs fraticides + Messages de tir ami Baráti tűz üzenetek Сообщения об огне по своим Messaggi Fuoco Amico - 友軍誤射の表示 - 아군사격 메세지 - 友军误击讯息 + 友軍誤射の布告 + 아군 오인사격 메시지 + 友军误击信息 友軍誤擊訊息 @@ -331,12 +347,12 @@ Zobrazí zprávu v chatu v případě, když budete střílet na vlastní jednotky. Ve zprávě se zobrazí kdo na koho střílel, popř. kdo koho zabil. Usando este módulo em uma missão para exibir mensagens chat, no caso de quando você faz um fogo amigo - então a mensagem será exibida mostrando quem matou quem. Отображает сообщение в чате, в случае, когда убивают союзных игроков. В докладе указывается, кто стрелял, в кого. Кто кого убил. - Ce module permet l'affiche de message dans le chat lors d'un tir fraticide et indique qui a tué qui. + L'utilisation de ce module fait en sorte qu'à chaque joueur mort par un tir ami, un rapport sera affiché dans le chat, indiquant qui a tué qui. Usando questo modulo nella tua missione farà in modo che ogni uccisione per fuoco amico venga mostrata in forma di messaggio in chat. El usar este módulo, todas las muertes por fuego amigo serán indicadas en el chat. もし友軍誤射による死者が出た場合は、チャットにてその旨を表示します。 - 이 모듈은 미션 중 아군사격으로 인한 사망자 발생시 채팅창에 메세지를 표시해줍니다. - 摆放此模块后,当有发生友军误击致死的事件,会显示提示讯息在聊天视窗中。 + 이 모듈은 미션 중 아군 오인사격으로 인한 사망자 발생 시 채팅창에 메시지를 표시해줍니다. + 摆放此模块后,当有发生友军误击致死的事件,会显示提示信息在聊天视窗中。 擺放此模塊後,當有發生友軍誤擊致死的事件,會顯示提示訊息在聊天視窗中 @@ -346,10 +362,10 @@ Sammelpunktssystem Systém shromáždění Sistema de ponto de encontro - Système de point de ralliement + Système de points de ralliement Gyülekezőpont-rendszer Система точек сбора - Sistema Punto di Raccolta + Sistema Rallypoint ラリーポイント システム 집결지 시스템 集合点系统 @@ -362,12 +378,12 @@ Tento modul umožňuje určit místo shromaždiště, kam se mohou jednokty rychle teleportovat ze "základny". Toto vyžaduje vhodné objekty v mapě - základna a vlajka. Oba dva můžete najít v kategorii Prázdné -> ACE Oživení. Este módulo permite que você aplique em uma missão "pontos de encontro", que pode rapidamente se teletransportar para a "base". Ele requer colocar objetos apropriados no mapa - base e bandeiras. Ambos estão disponíveis na categoria em branco -> ACE Revival. Этот модуль позволяет вам указать место сбора, куда вы можете быстро телепортироваться с "базы". Требуется наличие соответствующих объектов на карте - базы и флага. Они могут быть найдены в категории Пусто -> ACE Возрождения. - Questo modulo ti consente di usare Punti di Raccolta in missione, a cui ti puoi teleportare rapidamente dalla bandiera in base. Richiede il piazzamento di oggetti speciali in mappa - base e bandiera. Entrambi disponibili nella categoria Vuoto -> Respawn ACE + Questo modulo ti consente di usare Rallypoint in missione, a cui ti puoi teleportare rapidamente dalla bandiera in base. Richiede il piazzamento di oggetti speciali in mappa - base e bandiera. Entrambi disponibili nella categoria Vuoto -> ACE Riapparizione Este módulo permite usar puntos de reunión en la misión, a los que pueden teletransportarse las unidades desde la bandera de base. Requiere colocar objetos especiales en el mapa: las banderas de base y de reunión, ambas disponibles en la categoría Vacio-> Reaparición ACE - Ce module vous permet d'utiliser les "rally points" auxquels vous pouvez vous téléporter rapidement depuis un drapeau à la base. Il nécessite le placement d'objets spéciaux sur la carte - base et drapeau, disponibles dans la catégorie Vide -> ACE Respawn. - ミッションでベースから素早く移動できるラリーポイントを使えるようにします。ゲーム内に専用オブジェクトとなるベースとフラッグを設置している必要があります。両オブジェクトは Empty 下の ACE リスポンから設置できます。 - 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역활을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 Empty->ACE Respawn 카테고리에서 찾을 수 있습니다. - 摆放此模块后,你将能在任务中布署集合点,使你可以快速往返基地与前线。要使用本功能,请记得放上空物件->ACE 重生里面的基地与旗帜。 + Ce module vous permet d'utiliser des points de ralliement dans les missions, vers lesquels vous pouvez vous téléporter rapidement depuis le drapeau de la base.\nNécessite de placer des objets spéciaux sur la carte - base et drapeau, tous deux disponibles dans la catégorie "Vide -> ACE Réapparition". + ミッションでベースから素早く移動できるラリーポイントを使えるようにします。ゲーム内に専用オブジェクトとなるベースとフラッグを設置している必要があります。両オブジェクトは Empty 下の ACE リスポーンから設置できます。 + 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역할을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 비어 있음->ACE 재투입 카테고리에서 찾을 수 있습니다. + 摆放此模块后,你将能在任务中部署集合点,使你可以快速往返基地与前线。要使用本功能,请记得放上空物体->ACE 重生里面的基地与旗帜。 擺放此模塊後,你將能在任務中佈署集合點,使你可以快速往返基地與前線。要使用本功能,請記得放上空物件->ACE 重生裡面的基地與旗幟 @@ -377,10 +393,10 @@ Bewege Sammelpunkt Přesun na shromaždiště Mover para ponto de encontro - Bouger le point de ralliement + Déplacer le point de ralliement Gyülekezőpont mozgatása Двигать точку сбора - Sposta Punto di Raccolta + Sposta Rallypoint ラリーポイントを移動 집결지 이동 移动集合点 @@ -393,14 +409,15 @@ ACE-Wiedereinstieg ACE Znovuzrození ACE Respawn - ACE Respawn + ACE Réapparition ACE Respawn ACE Возрождение - Rigenerazione ACE - ACE リスポン - ACE 재배치 + ACE Riapparizione + ACE リスポーン + ACE 재투입 ACE 重生 ACE 重生 + ACE Yeniden Doğma diff --git a/addons/safemode/CfgEventHandlers.hpp b/addons/safemode/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/safemode/CfgEventHandlers.hpp +++ b/addons/safemode/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/safemode/README.md b/addons/safemode/README.md index 9c0632f7be..27a6d7170e 100644 --- a/addons/safemode/README.md +++ b/addons/safemode/README.md @@ -2,11 +2,3 @@ ace_safemode ============ Adds the ability to use the safety on small arms. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) 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..6c617c1898 100644 --- a/addons/safemode/functions/fnc_lockSafety.sqf +++ b/addons/safemode/functions/fnc_lockSafety.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Put weapon on safety, or take it off safety if safety is already put on. @@ -7,6 +7,7 @@ * 0: Unit * 1: Weapon * 2: Muzzle + * 3: Show hint * * Return Value: * None @@ -17,10 +18,7 @@ * Public: No */ -// don't immediately switch back -if (inputAction "nextWeapon" > 0) exitWith {}; - -params ["_unit", "_weapon", "_muzzle"]; +params ["_unit", "_weapon", "_muzzle", ["_hint", true, [true]]]; private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; @@ -78,6 +76,9 @@ if (_muzzle isEqualType "") then { // play fire mode selector sound [_unit, _weapon, _muzzle] call FUNC(playChangeFiremodeSound); -// show info box -private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); -[localize LSTRING(PutOnSafety), _picture] call EFUNC(common,displayTextPicture); +// show info box unless disabled +if (_hint) then { + private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); + [localize LSTRING(PutOnSafety), _picture] call EFUNC(common,displayTextPicture); +}; + diff --git a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf index d013d29696..257e5864f6 100644 --- a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Play weapon firemode change sound. @@ -25,7 +25,7 @@ if (_sound isEqualTo []) exitWith { }; // get position where to play the sound (position of the weapon) -private _position = AGLToASL (_unit modelToWorldVisual (_unit selectionPosition "RightHand")); +private _position = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand"); _sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]]; @@ -34,7 +34,7 @@ if (_filename == "") exitWith { }; // add file extension .wss as default -if !(toLower (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { _filename = format ["%1.wss", _filename]; }; diff --git a/addons/safemode/functions/fnc_setSafeModeVisual.sqf b/addons/safemode/functions/fnc_setSafeModeVisual.sqf index 587ac882d3..d62a542b9d 100644 --- a/addons/safemode/functions/fnc_setSafeModeVisual.sqf +++ b/addons/safemode/functions/fnc_setSafeModeVisual.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Show firemode indicator, representing safety lock diff --git a/addons/safemode/functions/fnc_setWeaponSafety.sqf b/addons/safemode/functions/fnc_setWeaponSafety.sqf new file mode 100644 index 0000000000..d80e1d8c38 --- /dev/null +++ b/addons/safemode/functions/fnc_setWeaponSafety.sqf @@ -0,0 +1,38 @@ +#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 + * 3: Show hint (default: true) + * + * 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]], + ["_hint", true, [true]] +]; + +if (_weapon == "") exitWith {}; + +private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; + +_weapon = configName (configFile >> "CfgWeapons" >> _weapon); + +private _muzzle = currentMuzzle _unit; + +if (_state isNotEqualTo (_weapon in _safedWeapons)) then { + [_unit, _weapon, _muzzle, _hint] call FUNC(lockSafety); +}; diff --git a/addons/safemode/functions/fnc_unlockSafety.sqf b/addons/safemode/functions/fnc_unlockSafety.sqf index 3194de6f14..10372f1a2e 100644 --- a/addons/safemode/functions/fnc_unlockSafety.sqf +++ b/addons/safemode/functions/fnc_unlockSafety.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Take weapon of safety lock. @@ -7,6 +7,7 @@ * 0: Unit * 1: Weapon * 2: Muzzle + * 3: Show hint * * Return Value: * None @@ -17,7 +18,7 @@ * Public: No */ -params ["_unit", "_weapon", "_muzzle"]; +params ["_unit", "_weapon", "_muzzle", ["_hint", true, [true]]]; private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; _safedWeapons deleteAt (_safedWeapons find _weapon); @@ -55,8 +56,7 @@ if (inputAction "nextWeapon" > 0) then { if (_x == "this") then { _modes pushBack _weapon; }; - nil - } count getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); + } forEach getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); // select last mode private _mode = _modes select (count _modes - 1); @@ -77,6 +77,8 @@ if (inputAction "nextWeapon" > 0) then { // player hud [true] call FUNC(setSafeModeVisual); -// show info box -private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); -[localize LSTRING(TookOffSafety), _picture] call EFUNC(common,displayTextPicture); +// show info box unless disabled +if (_hint) then { + private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); + [localize LSTRING(TookOffSafety), _picture] call EFUNC(common,displayTextPicture); +}; diff --git a/addons/safemode/functions/script_component.hpp b/addons/safemode/functions/script_component.hpp deleted file mode 100644 index a25fbfa4c7..0000000000 --- a/addons/safemode/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\safemode\script_component.hpp" \ No newline at end of file diff --git a/addons/safemode/stringtable.xml b/addons/safemode/stringtable.xml index e5eff7255c..ebeb50a63f 100644 --- a/addons/safemode/stringtable.xml +++ b/addons/safemode/stringtable.xml @@ -14,8 +14,9 @@ Modo de segurança 安全装置 안전 모드 - 保险模式 + 保险 保險模式 + Emniyet Modu Take off Safety @@ -25,7 +26,7 @@ Uvolnit pojistku Biztonsági kapcsoló eltolása Снять с предохранителя - Enlever sécurité + Enlever la sécurité Togli la sicura Tirar segurança 安全装置を外す @@ -48,6 +49,7 @@ 안전장치 적용 关保险 關保險 + Emniyete alındı Took off Safety @@ -64,6 +66,7 @@ 안전장치 해제됨 已开保险 已開保險 + Emniyetten çıkartıldı diff --git a/addons/sandbag/CfgEventHandlers.hpp b/addons/sandbag/CfgEventHandlers.hpp index 32d4ac80f4..6770876c89 100644 --- a/addons/sandbag/CfgEventHandlers.hpp +++ b/addons/sandbag/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; @@ -35,6 +35,6 @@ class Extended_Killed_EventHandlers { class Extended_DisplayLoad_EventHandlers { class RscDisplayMission { - ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); }; }; diff --git a/addons/sandbag/README.md b/addons/sandbag/README.md index e1bd40eee5..561a6d2bfc 100644 --- a/addons/sandbag/README.md +++ b/addons/sandbag/README.md @@ -2,10 +2,3 @@ ace_sandbag =============== Adds stackable sandbags. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index a03f6076a1..24122aed8e 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -15,11 +15,11 @@ GVAR(deployDirection) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", {_this call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; -["loadout", {_this call FUNC(handlePlayerInventoryChanged)}] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; //@todo Captivity? diff --git a/addons/sandbag/config.cpp b/addons/sandbag/config.cpp index 80e3f71808..bbd2369659 100644 --- a/addons/sandbag/config.cpp +++ b/addons/sandbag/config.cpp @@ -3,8 +3,8 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_Item_Sandbag", "ACE_Item_Sandbag_empty"}; - weapons[] = {"ACE_Sandbag", "ACE_Sandbag_empty"}; + units[] = {"ACE_Item_Sandbag_empty"}; + weapons[] = {"ACE_Sandbag_empty"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); diff --git a/addons/sandbag/functions/fnc_canDeploy.sqf b/addons/sandbag/functions/fnc_canDeploy.sqf index 88ecd03093..bc0751d6b0 100644 --- a/addons/sandbag/functions/fnc_canDeploy.sqf +++ b/addons/sandbag/functions/fnc_canDeploy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg, commy2 * Checks if the player can deploy a sandbag. diff --git a/addons/sandbag/functions/fnc_deploy.sqf b/addons/sandbag/functions/fnc_deploy.sqf index b336cee0a0..1ef8485112 100644 --- a/addons/sandbag/functions/fnc_deploy.sqf +++ b/addons/sandbag/functions/fnc_deploy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Starts the deploy process for sandbags. diff --git a/addons/sandbag/functions/fnc_deployCancel.sqf b/addons/sandbag/functions/fnc_deployCancel.sqf index 6c5fb1e88a..aa2c2419a3 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Cancels sandbag deployment diff --git a/addons/sandbag/functions/fnc_deployConfirm.sqf b/addons/sandbag/functions/fnc_deployConfirm.sqf index e8abb586ee..20b821b3b5 100644 --- a/addons/sandbag/functions/fnc_deployConfirm.sqf +++ b/addons/sandbag/functions/fnc_deployConfirm.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Confirms sandbag deployment diff --git a/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf b/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf index 7683520c84..cb6cb4ddf1 100644 --- a/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. diff --git a/addons/sandbag/functions/fnc_handleKilled.sqf b/addons/sandbag/functions/fnc_handleKilled.sqf index b778de6cc6..100ed2e930 100644 --- a/addons/sandbag/functions/fnc_handleKilled.sqf +++ b/addons/sandbag/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle death. diff --git a/addons/sandbag/functions/fnc_handlePlayerChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerChanged.sqf index 2ba996f760..6882ed553e 100644 --- a/addons/sandbag/functions/fnc_handlePlayerChanged.sqf +++ b/addons/sandbag/functions/fnc_handlePlayerChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle player changes. diff --git a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf index 53674d8e86..1e557cba1f 100644 --- a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf +++ b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle the InventoryChanged event. diff --git a/addons/sandbag/functions/fnc_handleScrollWheel.sqf b/addons/sandbag/functions/fnc_handleScrollWheel.sqf index 515e40053b..3a4f00a502 100644 --- a/addons/sandbag/functions/fnc_handleScrollWheel.sqf +++ b/addons/sandbag/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg * Handles sandbag rotation diff --git a/addons/sandbag/functions/fnc_handleUnconscious.sqf b/addons/sandbag/functions/fnc_handleUnconscious.sqf index 9b514007fb..3ad90a0cc5 100644 --- a/addons/sandbag/functions/fnc_handleUnconscious.sqf +++ b/addons/sandbag/functions/fnc_handleUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle unconsciousness. diff --git a/addons/sandbag/functions/fnc_pickup.sqf b/addons/sandbag/functions/fnc_pickup.sqf index 7db56cdfbe..2bcc418f4c 100644 --- a/addons/sandbag/functions/fnc_pickup.sqf +++ b/addons/sandbag/functions/fnc_pickup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Pick up sandbag @@ -34,7 +34,7 @@ _unit setVariable [QGVAR(isUsingSandbag), true]; // Force physx update { _x setPosASL (getPosASL _x); - } count (_unit nearObjects ["ACE_SandbagObject", 5]); + } forEach (_unit nearObjects ["ACE_SandbagObject", 5]); [_unit, "ACE_Sandbag_empty"] call EFUNC(common,addToInventory); }, [_unit, _sandbag], 1.5] call CBA_fnc_waitAndExecute; diff --git a/addons/sandbag/functions/script_component.hpp b/addons/sandbag/functions/script_component.hpp deleted file mode 100644 index 1d6f10c806..0000000000 --- a/addons/sandbag/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\sandbag\script_component.hpp" \ No newline at end of file diff --git a/addons/sandbag/stringtable.xml b/addons/sandbag/stringtable.xml index 9284d23468..d6bdab2556 100644 --- a/addons/sandbag/stringtable.xml +++ b/addons/sandbag/stringtable.xml @@ -1,6 +1,6 @@ - + Sandbag Sandsack @@ -16,6 +16,7 @@ 모래주머니 沙包 沙包 + Kum Torbası Sandbag (empty) @@ -30,8 +31,9 @@ Saco de Areia (vazio) 土のう (空) 모래주머니(비어있음) - 沙包 (空) + 沙包(空) 沙包 (空) + Kum Torbası (Boş) Cannot build here @@ -39,15 +41,16 @@ Установка на этом месте невозможна Nie można tu budować No se puede construir aqui - Impossible de construire ici + Impossible de construire ici. Zde nelze postavit Impossibile costruire qui Nem teheted ide - Não pode contruir aqui + Não pode construir aqui ここでは作れません 여기에 지을 수 없습니다 无法放置在此 無法放置在此 + Buraya inşa edilemez Pick up Sandbag @@ -55,7 +58,7 @@ Взять мешок с песком Zabierz worek Coger saco de arena - Prendre sac de sable + Prendre le sac de sable Zvednout pytel Prendi Sacco di Sabbia Homokzsák felvétele @@ -64,6 +67,7 @@ 모래주머니 줍기 捡起沙包 撿起沙包 + Kum torbasını al Carry Sandbag @@ -71,7 +75,7 @@ Нести мешок с песком Przenieś worek Portar saco de arena - Porter sac de sable + Porter le sac de sable Nést pytel Trasporta Sacco di Sabbia Homokzsák cipelése @@ -80,6 +84,7 @@ 모래주머니 옮기기 搬运沙包 搬運沙包 + Kum torbasını taşı End Carrying @@ -87,15 +92,16 @@ Завершить переноску Zostaw worek Dejar de portar - Arreter de porter + Arrêter de porter Položit - Fine Trasporto + Termina Trasporto Cipelés abbahagyása Parar de carregar - 下ろす + 降ろす 그만 옮기기 停止搬运 停止搬運 + Taşımayı bitir Drop Sandbag @@ -103,7 +109,7 @@ Положить мешок Upuść worek Soltar saco de arena - Lacher sac de sable + Lâcher le sac de sable Odložit pytel Lascia Sacco di Sabbia Homokzsák eldobása @@ -112,6 +118,7 @@ 여기에 놓기 放下沙包 放下沙包 + Kum Torbasını Bırak Confirm Deployment @@ -119,15 +126,16 @@ Подтвердить установку Potwierdź rozłożenie Confirmar despliegue - Confirmer Déploiement + Confirmer l'installation Potvrdit Položení Conferma Posizionamento Lerak Confirmar implantação ここで作る 설치 확인 - 确认布署 + 确认部署 確認佈署 + Yerleştirmeyi Onayla Cancel Deployment @@ -135,15 +143,16 @@ Отменить установку Anuluj rozłożenie Cancelar despliegue - Annuler Déploiement + Annuler l'installation Zrušit Položení Cancella Posizionamento Visszavonás Cancelar implantação 作るのを止める 설치 취소 - 取消布署 + 取消部署 取消佈署 + Yerleştirmeyi İptal Et Deploy Sandbag @@ -151,15 +160,16 @@ Установить мешок с песком Rozłóż worek z piaskiem Desplegar saco de arena - Deployer sac de sable + Installer un sac de sable Umístit pytel Posiziona Sacco di Sabbia Homokzsák lerakása Implantar saco de areia 土のうを設置 모래주머니 설치 - 布署沙包 + 部署沙包 佈署沙包 + Kum Torbasını Yerleştir Sandbag Box @@ -169,13 +179,14 @@ Caja de sacos de arena Caisse de sacs de sable Bedna na pytle s pískem - Contenitore Sacchi di Sabbia + Scatola Sacchi di Sabbia Homokzsákos láda Caixa de saco de areia 土のう入れ 모래주머니 상자 沙包箱 沙包箱 + Kum Torbası Kutusu Here is no sand @@ -183,15 +194,16 @@ Здесь нет песка Tu nie ma piasku Aqui no hay arena - Pas de sable ici + Il n'y a pas de sable ici. Tady není písek - Qui non cè Sabbia + Qui non c'è Sabbia Itt nincs homok Aqui não tem areia ここに土はありません 흙이 없습니다 这里没有沙 這裡沒有沙 + Burada Kum Yok Rotate @@ -208,6 +220,7 @@ 돌리기 旋转 旋轉 + Yönlendir diff --git a/addons/scopes/ACE_Arsenal_Stats.hpp b/addons/scopes/ACE_Arsenal_Stats.hpp index 1e2ebd91ea..3e5240bbf5 100644 --- a/addons/scopes/ACE_Arsenal_Stats.hpp +++ b/addons/scopes/ACE_Arsenal_Stats.hpp @@ -6,8 +6,8 @@ class EGVAR(arsenal,stats) { stats[] = {"ACE_ScopeAdjust_Horizontal", "ACE_ScopeAdjust_HorizontalIncrement"}; displayName = CSTRING(statHorizontalLimits); showText = 1; - textStatement = QUOTE(params[ARR_2('_stat','_config')]; private _limits = getArray (_config >> _stat select 0); format [ARR_4('%1 / %2 MIL (∆ %3 MIL)', _limits select 0, _limits select 1, getNumber (_config >> _stat select 1))]); - condition = QUOTE(params[ARR_2('_stat', '_config')]; !((getArray (_config >> _stat select 0)) isEqualTo [])); + textStatement = QUOTE(params[ARR_2('_stat','_config')]; private _limits = getArray (_config >> _stat select 0); format [ARR_4('%1 / %2 MIL (∆ %3 MIL)',_limits select 0,_limits select 1,getNumber (_config >> _stat select 1))]); + condition = QUOTE(params[ARR_2('_stat','_config')]; (getArray (_config >> _stat select 0)) isNotEqualTo []); tabs[] = {{}, {0}}; }; class ACE_scopeVerticalLimits: ACE_scopeHorizontalLimits { diff --git a/addons/scopes/ACE_Settings.hpp b/addons/scopes/ACE_Settings.hpp index 04e0e92ffb..c3aa151de7 100644 --- a/addons/scopes/ACE_Settings.hpp +++ b/addons/scopes/ACE_Settings.hpp @@ -1,93 +1,44 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 1; - displayName = CSTRING(enabled_displayName); - description = CSTRING(enabled_description); + movedToSQF = 1; }; // ACE_ScopeAdjust_Vertical and ACE_ScopeAdjust_Horizontal will be populated with default values instead of [0,0] class GVAR(forceUseOfAdjustmentTurrets) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - displayName = CSTRING(forceUseOfAdjustmentTurrets_displayName); - description = CSTRING(forceUseOfAdjustmentTurrets_description); + movedToSQF = 1; }; - + // Auto corrects the zeroing in both vanilla- and advanced ballistics class GVAR(correctZeroing) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 1; - displayName = CSTRING(correctZeroing_displayName); - description = CSTRING(correctZeroing_description); + movedToSQF = 1; }; // Enables the use of the 'defaultZeroRange' setting to overwrite the discreteDistance[] config class GVAR(overwriteZeroRange) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - displayName = CSTRING(overwriteZeroRange_displayName); - description = CSTRING(overwriteZeroRange_description); + movedToSQF = 1; }; // Only affects scopes with elevation adjustment turrets (ACE_ScopeAdjust_Vertical != [0,0]) class GVAR(defaultZeroRange) { - category = CSTRING(DisplayName); - typeName = "SCALAR"; - value = 100; - displayName = CSTRING(defaultZeroRange_displayName); - description = CSTRING(defaultZeroRange_description); - sliderSettings[] = {0, 1000, 100, 0}; + movedToSQF = 1; }; - + // Only relevant when advanced ballistics is enabled class GVAR(zeroReferenceTemperature) { - category = CSTRING(DisplayName); - typeName = "SCALAR"; - value = 15; - displayName = CSTRING(zeroReferenceTemperature_displayName); - description = CSTRING(zeroReferenceTemperature_description); - sliderSettings[] = {-55, 55, 15, 0}; + movedToSQF = 1; }; class GVAR(zeroReferenceBarometricPressure) { - category = CSTRING(DisplayName); - typeName = "SCALAR"; - value = 1013.25; - displayName = CSTRING(zeroReferenceBarometricPressure_displayName); - description = CSTRING(zeroReferenceBarometricPressure_description); - sliderSettings[] = {0, 1013.25, 1013.25, 2}; + movedToSQF = 1; }; class GVAR(zeroReferenceHumidity) { - category = CSTRING(DisplayName); - typeName = "SCALAR"; - value = 0.0; - displayName = CSTRING(zeroReferenceHumidity_displayName); - description = CSTRING(zeroReferenceHumidity_description); - sliderSettings[] = {0, 1, 0, 2}; + movedToSQF = 1; }; class GVAR(deduceBarometricPressureFromTerrainAltitude) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - displayName = CSTRING(deduceBarometricPressureFromTerrainAltitude_displayName); - description = CSTRING(deduceBarometricPressureFromTerrainAltitude_description); + movedToSQF = 1; }; - + class GVAR(useLegacyUI) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - isClientSettable = 1; - displayName = CSTRING(useLegacyUI_displayName); - description = CSTRING(useLegacyUI_description); + movedToSQF = 1; }; - + class GVAR(simplifiedZeroing) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - displayName = CSTRING(simplifiedZeroing_displayName); - description = CSTRING(simplifiedZeroing_description); + movedToSQF = 1; }; }; diff --git a/addons/scopes/CfgEventHandlers.hpp b/addons/scopes/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/scopes/CfgEventHandlers.hpp +++ b/addons/scopes/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/scopes/CfgWeapons.hpp b/addons/scopes/CfgWeapons.hpp index 86c4820caa..b2d2b14d31 100644 --- a/addons/scopes/CfgWeapons.hpp +++ b/addons/scopes/CfgWeapons.hpp @@ -5,62 +5,66 @@ class Mode_FullAuto; class CfgWeapons { class ItemCore; class InventoryOpticsItem_Base_F; - - class optic_Yorris : ItemCore { + + class optic_Yorris: ItemCore { ACE_ScopeHeightAboveRail = 2.77224; }; - - class optic_MRD : ItemCore { + + class optic_MRD: ItemCore { ACE_ScopeHeightAboveRail = 2.8; }; - - class optic_Aco : ItemCore { + + class optic_Aco: ItemCore { ACE_ScopeHeightAboveRail = 3.69248; }; - - class optic_ACO_grn : ItemCore { + + class optic_ACO_grn: ItemCore { ACE_ScopeHeightAboveRail = 3.69248; }; - - class optic_ACO_grn_smg : ItemCore { + + class optic_ACO_grn_smg: ItemCore { ACE_ScopeHeightAboveRail = 3.69248; }; - - class optic_ACO_smg : ItemCore { + + class optic_ACO_smg: ItemCore { ACE_ScopeHeightAboveRail = 3.69248; }; - - class optic_Holosight : ItemCore { + + class optic_Holosight: ItemCore { ACE_ScopeHeightAboveRail = 4.66933; }; - - class optic_Holosight_smg : ItemCore { + + class optic_Holosight_smg: ItemCore { ACE_ScopeHeightAboveRail = 4.66933; }; - - class optic_Arco : ItemCore { + + class optic_Arco: ItemCore { ACE_ScopeHeightAboveRail = 4.89287; }; - - class optic_ERCO_blk_F : optic_Arco { + + class optic_ERCO_blk_F: optic_Arco { ACE_ScopeHeightAboveRail = 3.48836; }; - - class optic_Hamr : ItemCore { + + class optic_Hamr: ItemCore { ACE_ScopeHeightAboveRail = 4.48584; }; - - class optic_MRCO : ItemCore { + + class optic_MRCO: ItemCore { ACE_ScopeHeightAboveRail = 3.88405; }; - - class optic_Nightstalker : ItemCore { + + class optic_ico_01_base_f: ItemCore { + ACE_ScopeHeightAboveRail = 5.41148; + }; + + class optic_Nightstalker: ItemCore { ACE_ScopeHeightAboveRail = 5.54325; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class NCTALKEP { discreteDistance[] = {200}; @@ -69,14 +73,14 @@ class CfgWeapons { }; }; }; - - class optic_NVS : ItemCore { + + class optic_NVS: ItemCore { ACE_ScopeHeightAboveRail = 5.54325; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class NVS { discreteDistance[] = {300}; @@ -85,14 +89,14 @@ class CfgWeapons { }; }; }; - - class optic_TWS : ItemCore { + + class optic_TWS: ItemCore { ACE_ScopeHeightAboveRail = 5.52874; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class TWS { discreteDistance[] = {300}; @@ -101,14 +105,29 @@ class CfgWeapons { }; }; }; - - class optic_LRPS : ItemCore { + class optic_tws_mg: ItemCore { + ACE_ScopeHeightAboveRail = 5.52874; + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo: InventoryOpticsItem_Base_F { + class OpticsModes { + class TWS { + discreteDistance[] = {300}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class optic_LRPS: ItemCore { ACE_ScopeHeightAboveRail = 4.2098; ACE_ScopeAdjust_Vertical[] = {0, 27}; ACE_ScopeAdjust_Horizontal[] = {-8, 8}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class Snip { opticsZoomMin = 0.011; @@ -122,13 +141,13 @@ class CfgWeapons { }; }; - class optic_SOS : ItemCore { + class optic_SOS: ItemCore { ACE_ScopeHeightAboveRail = 4.41328; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class Snip { discreteDistance[] = {100}; @@ -138,13 +157,13 @@ class CfgWeapons { }; }; - class optic_DMS : ItemCore { + class optic_DMS: ItemCore { ACE_ScopeHeightAboveRail = 3.86253; ACE_ScopeAdjust_Vertical[] = {-4, 20}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class Snip { discreteDistance[] = {100}; @@ -154,13 +173,13 @@ class CfgWeapons { }; }; - class optic_AMS_base : ItemCore { + class optic_AMS_base: ItemCore { ACE_ScopeHeightAboveRail = 3.8933; ACE_ScopeAdjust_Vertical[] = {0, 16}; ACE_ScopeAdjust_Horizontal[] = {-11, 11}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class AMS { opticsZoomMin = 0.0285; @@ -174,13 +193,13 @@ class CfgWeapons { }; }; - class optic_KHS_base : ItemCore { + class optic_KHS_base: ItemCore { ACE_ScopeHeightAboveRail = 4.30723; ACE_ScopeAdjust_Vertical[] = {0, 19}; ACE_ScopeAdjust_Horizontal[] = {-9, 9}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class KHS { opticsZoomMin = 0.026; @@ -194,13 +213,13 @@ class CfgWeapons { }; }; - class optic_KHS_old : ItemCore { + class optic_KHS_old: ItemCore { ACE_ScopeHeightAboveRail = 4.30723; ACE_ScopeAdjust_Vertical[] = {0, 19}; ACE_ScopeAdjust_Horizontal[] = {-9, 9}; ACE_ScopeAdjust_VerticalIncrement = 0.1; ACE_ScopeAdjust_HorizontalIncrement = 0.1; - class ItemInfo : InventoryOpticsItem_Base_F { + class ItemInfo: InventoryOpticsItem_Base_F { class OpticsModes { class KHS { opticsZoomMin = 0.026; @@ -218,161 +237,186 @@ 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.010313; + ACE_RailHeightAboveBore = 3.27488; + }; + class DMR_07_base_F: Rifle_Long_Base_F { ACE_RailHeightAboveBore = 5.07109; - ACE_IronSightBaseAngle = -0.00160721; + ACE_IronSightBaseAngle = 0; }; - + class arifle_MX_Base_F: Rifle_Base_F { class Single: Mode_SemiAuto {}; class FullAuto: Mode_FullAuto {}; }; class arifle_MX_SW_F: arifle_MX_Base_F { ACE_RailHeightAboveBore = 2.40874; - ACE_IronSightBaseAngle = 0.216372; + ACE_IronSightBaseAngle = -0.004011; }; class arifle_MXM_F: arifle_MX_Base_F { ACE_RailHeightAboveBore = 2.40323; - ACE_IronSightBaseAngle = 0.157545; + ACE_IronSightBaseAngle = -0.004011; }; class arifle_SPAR_01_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 3.20768; - ACE_IronSightBaseAngle = -0.166678; + ACE_IronSightBaseAngle = 0.002856; }; class arifle_SPAR_02_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 3.22175; - ACE_IronSightBaseAngle = -0.184641; + ACE_IronSightBaseAngle = -0.018908; }; class arifle_SPAR_03_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 3.71491; - ACE_IronSightBaseAngle = -0.134908; + ACE_IronSightBaseAngle = 0; }; class LMG_Mk200_F: Rifle_Long_Base_F { ACE_RailHeightAboveBore = 2.68925; - ACE_IronSightBaseAngle = 0.0182228; + ACE_IronSightBaseAngle = 0.001719; }; class LMG_Zafir_F: Rifle_Long_Base_F { ACE_RailHeightAboveBore = 0.996651; - ACE_IronSightBaseAngle = 0.19812212; + ACE_IronSightBaseAngle = 0.004584; }; class LMG_03_base_F: Rifle_Long_Base_F { ACE_RailHeightAboveBore = 4.24282; - ACE_IronSightBaseAngle = 0.00181939; + ACE_IronSightBaseAngle = 0.008021; }; class pdw2000_base_F: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 3.08883; ACE_RailBaseAngle = 0.019366; - ACE_IronSightBaseAngle = 0.0399664; + ACE_IronSightBaseAngle = 0.009740; }; class arifle_AKS_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 0; - ACE_IronSightBaseAngle = 0.00574991; + ACE_IronSightBaseAngle = 0; }; class arifle_AKM_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 0; - ACE_IronSightBaseAngle = 0.006273; + ACE_IronSightBaseAngle = 0.014897; }; class arifle_AK12_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 3.82508; - ACE_IronSightBaseAngle = 0.0276926; + ACE_IronSightBaseAngle = 0.025210; + }; + class arifle_AK12_GL_base_F: arifle_AK12_base_F { + ACE_IronSightBaseAngle = 0.017189; + }; + class arifle_AK12U_base_F: arifle_AK12_base_F { + ACE_IronSightBaseAngle = 0.002865; + }; + class arifle_RPK12_base_F: arifle_AK12_base_F { + ACE_IronSightBaseAngle = 0.003438; }; class arifle_CTAR_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 6.07588; - ACE_IronSightBaseAngle = 0.0151815; + ACE_IronSightBaseAngle = 0.004584; }; class arifle_CTARS_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 6.0787; - ACE_IronSightBaseAngle = 0.0125245; + ACE_IronSightBaseAngle = 0.022918; }; class arifle_ARX_base_F: Rifle_Base_F { ACE_RailHeightAboveBore = 2.81635; - ACE_IronSightBaseAngle = 0.113024; + ACE_IronSightBaseAngle = 0.016043; }; class arifle_katiba_Base_F: Rifle_Base_F {}; - + class arifle_Katiba_F: arifle_katiba_Base_F { ACE_RailHeightAboveBore = 5.75468; - ACE_IronSightBaseAngle = 0.0863227; + ACE_IronSightBaseAngle = 0.011459; }; class arifle_Katiba_C_F: arifle_katiba_Base_F { ACE_RailHeightAboveBore = 5.75468; - ACE_IronSightBaseAngle = 0.083419; + ACE_IronSightBaseAngle = 0.011459; }; class arifle_Katiba_GL_F: arifle_katiba_Base_F { ACE_RailHeightAboveBore = 5.75468; - ACE_IronSightBaseAngle = 0.0863227; + ACE_IronSightBaseAngle = 0.011459; }; - + class arifle_MX_F: arifle_MX_Base_F { ACE_RailHeightAboveBore = 2.80201; - ACE_IronSightBaseAngle = 0.19502; + ACE_IronSightBaseAngle = -0.005157; }; class arifle_MX_GL_F: arifle_MX_Base_F { ACE_RailHeightAboveBore = 2.80201; - ACE_IronSightBaseAngle = 0.17142857; + ACE_IronSightBaseAngle = -0.005730; }; class arifle_MXC_F: arifle_MX_Base_F { ACE_RailHeightAboveBore = 2.40874; - ACE_IronSightBaseAngle = 0.0154129; + ACE_IronSightBaseAngle = -0.005157; }; class SDAR_base_F: Rifle_Base_F {}; - + class arifle_SDAR_F: SDAR_base_F { ACE_RailHeightAboveBore = 0; - ACE_IronSightBaseAngle = -0.0237516; + ACE_IronSightBaseAngle = -0.042972; }; class SMG_01_Base: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 4.85355; ACE_RailBaseAngle = 0.0250956; - ACE_IronSightBaseAngle = -0.159239; + ACE_IronSightBaseAngle = 0.018908; }; class SMG_02_base_F: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 4.41831; ACE_RailBaseAngle = 0.0217724; - ACE_IronSightBaseAngle = 0.434847; + ACE_IronSightBaseAngle = 0.022918; + }; + class SMG_03_TR_BASE: Rifle_Base_F { + ACE_IronSightBaseAngle = -0.011459; }; class SMG_05_base_F: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 4.05169; ACE_RailBaseAngle = 0.019366; - ACE_IronSightBaseAngle = -0.122823; + ACE_IronSightBaseAngle = 0.027502; }; class Tavor_base_F: Rifle_Base_F {}; class arifle_TRG20_F: Tavor_base_F { ACE_RailHeightAboveBore = 4.30954; - ACE_IronSightBaseAngle = 0.0338428; + ACE_IronSightBaseAngle = 0.002292; }; class arifle_TRG21_F: Tavor_base_F { ACE_RailHeightAboveBore = 4.30954; - ACE_IronSightBaseAngle = 0.0317759; + ACE_IronSightBaseAngle = 0.002292; }; class arifle_TRG21_GL_F: arifle_TRG21_F { ACE_RailHeightAboveBore = 4.30954; - ACE_IronSightBaseAngle = -0.03428571; + ACE_IronSightBaseAngle = -0.014424; }; class mk20_base_F: Rifle_Base_F {}; class arifle_Mk20_F: mk20_base_F { ACE_RailHeightAboveBore = 4.57255; - ACE_IronSightBaseAngle = -0.153292; + ACE_IronSightBaseAngle = 0.006303; }; class arifle_Mk20C_F: mk20_base_F { ACE_RailHeightAboveBore = 4.41539; - ACE_IronSightBaseAngle = -0.137835; + ACE_IronSightBaseAngle = 0.001146; }; class arifle_Mk20_GL_F: mk20_base_F { ACE_RailHeightAboveBore = 4.41539; - ACE_IronSightBaseAngle = -0.1532926; + ACE_IronSightBaseAngle = 0.005730; + }; + + class arifle_MSBS65_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 5.2; + ACE_IronSightBaseAngle = 0.001719; + }; + class arifle_MSBS65_Mark_base_F: arifle_MSBS65_base_F { + ACE_IronSightBaseAngle = 0.002292; }; class EBR_base_F: Rifle_Long_Base_F {}; @@ -383,43 +427,38 @@ 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; - ACE_IronSightBaseAngle = -0.00601782; + ACE_IronSightBaseAngle = 0.007448; }; class srifle_LRR_F: LRR_base_F { ACE_RailHeightAboveBore = 3.20864; - ACE_IronSightBaseAngle = -0.0302847; + ACE_IronSightBaseAngle = 0.004011; }; class srifle_GM6_F: GM6_base_F { ACE_RailHeightAboveBore = 4.75572; - ACE_IronSightBaseAngle = -0.165062; + ACE_IronSightBaseAngle = 0.001146; }; class srifle_DMR_01_F: DMR_01_base_F { ACE_RailHeightAboveBore = 2.83284; - ACE_IronSightBaseAngle = 0.234393; + ACE_IronSightBaseAngle = 0.005730; }; class srifle_DMR_02_F: DMR_02_base_F { ACE_RailHeightAboveBore = 3.43913; - ACE_IronSightBaseAngle = 0.013878; + ACE_IronSightBaseAngle = 0.015470; }; class srifle_DMR_03_F: DMR_03_base_F { ACE_RailHeightAboveBore = 4.0795; - ACE_IronSightBaseAngle = 0.0138099; + ACE_IronSightBaseAngle = 0.005730; }; class srifle_DMR_04_F: DMR_04_base_F { ACE_RailHeightAboveBore = 2.38022; - ACE_RailBaseAngle = 0.0171842; + ACE_RailBaseAngle = 0.019481; }; class srifle_DMR_05_blk_F: DMR_05_base_F { 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; + ACE_IronSightBaseAngle = 0.012605; }; class MMG_01_base_F; @@ -427,10 +466,10 @@ class CfgWeapons { class MMG_01_hex_F: MMG_01_base_F { ACE_RailHeightAboveBore = 4.73961; - ACE_IronSightBaseAngle = -0.0101613; - }; + ACE_IronSightBaseAngle = -0.003438; + }; class MMG_02_camo_F: MMG_02_base_F { ACE_RailHeightAboveBore = 5.01913; - ACE_IronSightBaseAngle = 0.0136377; + ACE_IronSightBaseAngle = 0.010886; }; }; diff --git a/addons/scopes/README.md b/addons/scopes/README.md index 9ef4c8fa63..d3261e186f 100644 --- a/addons/scopes/README.md +++ b/addons/scopes/README.md @@ -2,12 +2,3 @@ ace_scopes ========== Adds adjustable turrets for long-range optics, allowing zeroing in steps of 0.1 MILs. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) -- [bux578](https://github.com/bux578) diff --git a/addons/scopes/RscTitles.hpp b/addons/scopes/RscTitles.hpp index a15cbbed67..c108caaf4d 100644 --- a/addons/scopes/RscTitles.hpp +++ b/addons/scopes/RscTitles.hpp @@ -14,11 +14,11 @@ class RscTitles { fadeout = 0; name = QGVAR(Zeroing); class controls { - class ACE_Scopes_Zeroing_BG : RscPicture { + class ACE_Scopes_Zeroing_BG: RscPicture { idc = 11; type = 0; text = QPATHTOF(UI\scopes_bg.paa); - style = 48 + 0x800; + style = "48 + 0x800"; scale = 1; sizeEx = 1; font = "RobotoCondensed"; @@ -26,12 +26,12 @@ class RscTitles { colorBackground[] = { 1, 1, 1, 1 }; shadow = 1; - x = (0.5 - 0.4 / 2) * safezoneW + safezoneX; - y = 0 * safezoneH + safezoneY; - w = 0.4 * safezoneW; - h = 0.3 * safezoneH; + x = "(0.5 - 0.4 / 2) * safezoneW + safezoneX"; + y = "0 * safezoneH + safezoneY"; + w = "0.4 * safezoneW"; + h = "0.3 * safezoneH"; }; - class ACE_Scopes_Zeroing_Vertical : RscText { + class ACE_Scopes_Zeroing_Vertical: RscText { idc = 12; type = 0; style = 2; @@ -43,12 +43,12 @@ class RscTitles { colorBackground[] = { 1, 0, 0, 0 }; shadow = 0; - x = (0.5 - 0.4 / 2 + 0.45*0.4) * safezoneW + safezoneX; - y = (0 + 0.19*0.3) * safezoneH + safezoneY; - w = 0.04 * safezoneW; - h = 0.025 * safezoneH; + x = "(0.5 - 0.4 / 2 + 0.45*0.4) * safezoneW + safezoneX"; + y = "(0 + 0.19*0.3) * safezoneH + safezoneY"; + w = "0.04 * safezoneW"; + h = "0.025 * safezoneH"; }; - class ACE_Scopes_Zeroing_Horizontal : RscText { + class ACE_Scopes_Zeroing_Horizontal: RscText { idc = 13; type = 0; style = 2; @@ -60,10 +60,10 @@ class RscTitles { colorBackground[] = { 1, 0, 0, 0 }; shadow = 0; - x = (0.5 - 0.4 / 2 + 0.6*0.4) * safezoneW + safezoneX; - y = (0 + 0.47*0.3) * safezoneH + safezoneY; - w = 0.019 * safezoneW; - h = 0.025 * safezoneH; + x = "(0.5 - 0.4 / 2 + 0.6*0.4) * safezoneW + safezoneX"; + y = "(0 + 0.47*0.3) * safezoneH + safezoneY"; + w = "0.019 * safezoneW"; + h = "0.025 * safezoneH"; }; }; }; diff --git a/addons/scopes/XEH_PREP.hpp b/addons/scopes/XEH_PREP.hpp index 58b4e494f2..70af49a716 100644 --- a/addons/scopes/XEH_PREP.hpp +++ b/addons/scopes/XEH_PREP.hpp @@ -6,7 +6,7 @@ PREP(calculateZeroAngleCorrection); PREP(canAdjustZero); PREP(canResetZero); PREP(firedEH); -PREP(getBaseAngle); +PREP(getBaseAngle); PREP(getBoreHeight); PREP(getCurrentZeroRange); PREP(getOptics); diff --git a/addons/scopes/XEH_postInit.sqf b/addons/scopes/XEH_postInit.sqf index a7720c62f5..997fe8d6dd 100644 --- a/addons/scopes/XEH_postInit.sqf +++ b/addons/scopes/XEH_postInit.sqf @@ -9,22 +9,27 @@ if (!hasInterface) exitWith {}; +// Add keybinds +#include "initKeybinds.inc.sqf" + GVAR(Optics) = ["", "", ""]; GVAR(Guns) = ["", "", ""]; GVAR(canAdjustElevation) = [false, false, false]; GVAR(canAdjustWindage) = [false, false, false]; GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; -["ace_settingsInitialized", { - +["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; - if (GVAR(deduceBarometricPressureFromTerrainAltitude)) then { - GVAR(zeroReferenceBarometricPressure) = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; + // Overwrite setting if automatic pressure deduction is wanted + if (isServer && GVAR(deduceBarometricPressureFromTerrainAltitude)) then { + private _referencePressure = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; + + [QGVAR(zeroReferenceBarometricPressure), _referencePressure, 2, "server"] call CBA_settings_fnc_set; }; // Check inventory when it changes - ["loadout", FUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; + ["loadout", LINKFUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; // Instantly hide knobs when scoping in ["cameraView", { @@ -34,113 +39,14 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; private _layer = [QGVAR(Zeroing)] call BIS_fnc_rscLayer; _layer cutText ["", "PLAIN", 0]; - if !(isNil QGVAR(fadePFH)) then { + if (!isNil QGVAR(fadePFH)) then { [GVAR(fadePFH)] call CBA_fnc_removePerFrameHandler; GVAR(fadePFH) = nil; }; }; }] call CBA_fnc_addPlayerEventHandler; - // Add keybinds - ["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), localize LSTRING(AdjustUpMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), localize LSTRING(AdjustDownMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), localize LSTRING(AdjustLeftMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), localize LSTRING(AdjustRightMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), localize LSTRING(AdjustUpMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), localize LSTRING(AdjustDownMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), localize LSTRING(AdjustLeftMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), localize LSTRING(AdjustRightMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; - - // Register fire event handler - ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - + ["ace_firedPlayer", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/scopes/XEH_preInit.sqf b/addons/scopes/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/scopes/XEH_preInit.sqf +++ b/addons/scopes/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/scopes/dev/checkScopes.sqf b/addons/scopes/dev/checkScopes.sqf new file mode 100644 index 0000000000..f166844ac9 --- /dev/null +++ b/addons/scopes/dev/checkScopes.sqf @@ -0,0 +1,78 @@ +// [] call compileScript ["\z\ace\addons\scopes\dev\checkScopes.sqf"]; + + +private _optics = "getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgWeapons"); +_optics = _optics select {(getNumber (_x >> 'ItemInfo' >> 'type')) == 201}; +diag_log text format ["** Checking %1 scopes **", count _optics]; + +private _fnc_checkConfig = { + params ["_config", ["_diag", false]]; + + private _model = getText (_config >> "model"); + private _weaponObj = createSimpleObject [_model, [0, 0, 0], true]; + private _bestZoom = 1e6; + private _bestOffset = 0; + { + private _xZoom = getNumber (_x >> "opticsZoomMin"); + private _xMem = getText (_x >> "memoryPointCamera"); + private _xOffset = 100 * ((_weaponObj selectionPosition _xMem) select 2); // convert to centimeters + if (_xZoom < _bestZoom) then { // get offset for optic with highest magnification (lowest fov) + _bestZoom = _xZoom; + _bestOffset = _xOffset; + }; + if (_diag) then { + diag_log text format [" %1[%2] = %3 (%4)",configName _x, _xZoom, _xMem, _xOffset]; + }; + } forEach configProperties [_config >> "ItemInfo" >> "OpticsModes", "isClass _x"]; + deleteVehicle _weaponObj; + _bestOffset +}; +{ + private _config = _x; + private _actualOffset = [_config, false] call _fnc_checkConfig; + private _configOffset = getNumber (_config >> "ACE_ScopeHeightAboveRail"); + + if ((abs (_actualOffset - _configOffset)) > 0.1) then { + diag_log text format ["Mismatch %1 - Actual %2 vs Config %3", configName _config, _actualOffset, _configOffset]; + [_config, true] call _fnc_checkConfig; + }; +} forEach _optics; + + + + +private _rifles = "getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgWeapons"); +_rifles = _rifles select {(getNumber (_x >> 'type')) == 1}; +_rifles = _rifles select {(configName _x) == (getText (_x >> 'baseWeapon'))}; +diag_log text format ["** Checking %1 weapons **", count _rifles]; + +private _fnc_checkConfig = { + params ["_config", ["_diag", false]]; + private _model = getText (_config >> "model"); + private _weaponObj = createSimpleObject [_model, [0, 0, 0], true]; + private _lod = (allLODs _weaponObj) # 0 # 2; + private _xMemMuzzle = getText (_config >> "muzzlePos"); + private _xMemOptic = "proxy:\a3\data_f\proxies\weapon_slots\top.001"; + private _xPosMuzzle = _weaponObj selectionPosition _xMemMuzzle; + private _xPosOptic = _weaponObj selectionPosition [_xMemOptic, _lod]; + if (_xPosOptic isEqualTo [0,0,0]) exitWith { -999 }; // e.g. akm has no proxy + + private _xOffset = 100 * ((_xPosOptic vectorDiff _xPosMuzzle) select 2); + if (_diag) then { + diag_log text format [" Muzzle %1 - Top %2", _xPosMuzzle, _xPosOptic]; + }; + deleteVehicle _weaponObj; + _xOffset +}; +{ + private _config = _x; + if ((compatibleItems [configName _config, "CowsSlot"]) isEqualTo []) then { continue }; // e.g. arifle_SDAR_F has no scopes + private _actualOffset = [_config, false] call _fnc_checkConfig; + if (_actualOffset == -999) then { continue }; + private _configOffset = getNumber (_config >> "ACE_RailHeightAboveBore"); + + if ((abs (_actualOffset - _configOffset)) > 0.1) then { + diag_log text format ["Mismatch %1 - Actual %2 vs Config %3", configName _config, _actualOffset, _configOffset]; + [_config, true] call _fnc_checkConfig; + }; +} forEach _rifles; diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index 1d99e3605f..a760065cde 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Changes the adjustment for the current scope @@ -17,12 +17,13 @@ * Public: No */ +if (!GVAR(enabled)) exitWith {false}; + params ["_unit", "_turretAndDirection", "_majorStep"]; TRACE_3("adjustScope",_unit,_turretAndDirection,_majorStep); -if (!(_unit isKindOf "Man")) exitWith {false}; +if !(_unit isKindOf "Man") exitWith {false}; if (currentMuzzle _unit != currentWeapon _unit) exitWith {false}; -if (!GVAR(enabled)) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_adjustZero.sqf b/addons/scopes/functions/fnc_adjustZero.sqf index 56c3404a7c..44e64b7674 100644 --- a/addons/scopes/functions/fnc_adjustZero.sqf +++ b/addons/scopes/functions/fnc_adjustZero.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Updates the zero adjustment of the current scope @@ -17,7 +17,7 @@ params ["_unit"]; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; private _weaponClass = currentWeapon _unit; private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf index e64abb30fc..b813dde9ef 100644 --- a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf +++ b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Applies the adjustment for the current scope diff --git a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf index 017c617ebc..ab84db7cde 100644 --- a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -1,27 +1,31 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the zero angle correction for the new zero range based on current zero range and bore height (distance between bore- and sight axis) * * Arguments: - * 0: Zero range - * 1: Bore height - * 2: Weapon - * 3: Ammo - * 4: Magazine - * 5: Advanced Ballistics enabled? + * 0: Old Zero range + * 1: New Zero range + * 2: Bore height + * 3: Weapon + * 4: Ammo + * 5: Magazine + * 6: Advanced Ballistics enabled? * * Return Value: * zeroAngleCorrection * * Example: - * [5, 6, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection + * [5, 6, 7, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection * * Public: No */ params ["_oldZeroRange", "_newZeroRange", "_boreHeight"/*in cm*/, "_weapon", "_ammo", "_magazine", "_advancedBallistics"]; +// When FFV from vehicles currentZeroing will report 0 so just bail +if (_oldZeroRange <= 0) exitWith { 0 }; + private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index d9c2903cbd..1461d91d20 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Checks if the unit can change the zero adjustment of the current scope @@ -18,9 +18,9 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; if (GVAR(simplifiedZeroing)) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_canResetZero.sqf b/addons/scopes/functions/fnc_canResetZero.sqf index c398294684..92bbda1a4d 100644 --- a/addons/scopes/functions/fnc_canResetZero.sqf +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Checks if the unit can reset the zero adjustment of the current scope @@ -18,8 +18,8 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; -if (vehicle _unit != _unit) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index 8870592885..5ff78a44b7 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, esteldunedain, Ruthberg * Adjusts the flight path of the bullet according to the zeroing. Called from the unified fired EH only for local and non-local players on foot. @@ -16,9 +16,9 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; @@ -30,7 +30,7 @@ TRACE_1("Adjusting With",_zeroing); if (GVAR(correctZeroing) || GVAR(simplifiedZeroing)) then { private _advancedBallistics = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; private _baseAngle = (_unit getVariable [QGVAR(baseAngle), [0,0,0]]) select _weaponIndex; - private _boreHeight = (_unit getVariable [QGVAR(boreHeight), [0,0,0]]) select _weaponIndex; + private _boreHeight = (_unit getVariable [QGVAR(boreHeight), [0,0,0]]) select _weaponIndex; private _oldZeroRange = currentZeroing _unit; private _newZeroRange = [_unit] call FUNC(getCurrentZeroRange); private _zeroCorrection = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5_%6_%7), _oldZeroRange, _newZeroRange, _boreHeight, _weapon, _ammo, _magazine, _advancedBallistics]; diff --git a/addons/scopes/functions/fnc_getBaseAngle.sqf b/addons/scopes/functions/fnc_getBaseAngle.sqf index da5e965938..14da9d252a 100644 --- a/addons/scopes/functions/fnc_getBaseAngle.sqf +++ b/addons/scopes/functions/fnc_getBaseAngle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Gets the base angle of the weapon & optic combination with the given weapon index @@ -18,10 +18,10 @@ params ["_unit", "_weaponIndex"]; -if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; +if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; -private _weaponClass = [primaryWeapon _unit, secondaryWeapon _unit, handgunWeapon _unit] select _weaponIndex; -private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; +private _weaponClass = [primaryWeapon _unit, secondaryWeapon _unit, handgunWeapon _unit] select _weaponIndex; +private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; private _weaponConfig = configFile >> "CfgWeapons" >> _weaponClass; private _baseAngle = getNumber(_weaponConfig >> "ACE_IronSightBaseAngle"); diff --git a/addons/scopes/functions/fnc_getBoreHeight.sqf b/addons/scopes/functions/fnc_getBoreHeight.sqf index 8926585989..37c62d111e 100644 --- a/addons/scopes/functions/fnc_getBoreHeight.sqf +++ b/addons/scopes/functions/fnc_getBoreHeight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Gets the bore height of the weapon & optic combination with the given weapon index @@ -18,10 +18,10 @@ params ["_unit", "_weaponIndex"]; -if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; +if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; -private _weaponClass = [primaryWeapon _unit, secondaryWeapon _unit, handgunWeapon _unit] select _weaponIndex; -private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; +private _weaponClass = [primaryWeapon _unit, secondaryWeapon _unit, handgunWeapon _unit] select _weaponIndex; +private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; if (_opticsClass == "") then { _opticsClass = _weaponClass; }; diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf index 6425fe047a..d1bc3b7790 100644 --- a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Gets the zero range of the currently used optic @@ -17,12 +17,12 @@ params ["_unit"]; -if (!GVAR(enabled)) exitWith { currentZeroing _unit }; +if (!GVAR(enabled)) exitWith {currentZeroing _unit}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith { currentZeroing _unit }; if (GVAR(simplifiedZeroing)) exitWith { - if (!(GVAR(canAdjustElevation) select _weaponIndex)) exitWith { currentZeroing _unit }; + if !(GVAR(canAdjustElevation) select _weaponIndex) exitWith {currentZeroing _unit}; private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; ((_adjustment select _weaponIndex) select 0) }; diff --git a/addons/scopes/functions/fnc_getOptics.sqf b/addons/scopes/functions/fnc_getOptics.sqf index c9c1216d99..d419d8d7f0 100644 --- a/addons/scopes/functions/fnc_getOptics.sqf +++ b/addons/scopes/functions/fnc_getOptics.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Gets the optic classnames of all currently equipped weapons. @@ -21,7 +21,7 @@ params ["_unit"]; private _optics = ["", "", ""]; -if (!(_unit isKindOf "CAManBase")) exitWith {_optics}; +if !(_unit isKindOf "CAManBase") exitWith {_optics}; { if (count _x >= 2) then { diff --git a/addons/scopes/functions/fnc_initModuleSettings.sqf b/addons/scopes/functions/fnc_initModuleSettings.sqf index b0bf38492d..92bf22e87e 100644 --- a/addons/scopes/functions/fnc_initModuleSettings.sqf +++ b/addons/scopes/functions/fnc_initModuleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the scopes settings diff --git a/addons/scopes/functions/fnc_inventoryCheck.sqf b/addons/scopes/functions/fnc_inventoryCheck.sqf index 68a76e6ffe..a3302230cc 100644 --- a/addons/scopes/functions/fnc_inventoryCheck.sqf +++ b/addons/scopes/functions/fnc_inventoryCheck.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Commy2, Ruthberg * Check if weapon optics changed and reset zeroing if needed @@ -74,8 +74,8 @@ private _newOptics = [_player] call FUNC(getOptics); (GVAR(scopeAdjust) select _forEachIndex) set [1, _verticalIncrement]; (GVAR(scopeAdjust) select _forEachIndex) set [2, _maxHorizontal]; (GVAR(scopeAdjust) select _forEachIndex) set [3, _horizontalIncrement]; - GVAR(canAdjustElevation) set [_forEachIndex, (_verticalIncrement > 0) && !(_maxVertical isEqualTo [0, 0])]; - GVAR(canAdjustWindage) set [_forEachIndex, (_horizontalIncrement > 0) && !(_maxHorizontal isEqualTo [0, 0])]; + GVAR(canAdjustElevation) set [_forEachIndex, (_verticalIncrement > 0) && (_maxVertical isNotEqualTo [0, 0])]; + GVAR(canAdjustWindage) set [_forEachIndex, (_horizontalIncrement > 0) && (_maxHorizontal isNotEqualTo [0, 0])]; }; } forEach GVAR(Optics); @@ -112,8 +112,8 @@ private _newGuns = [primaryWeapon _player, secondaryWeapon _player, handgunWeapo (GVAR(scopeAdjust) select _x) set [1, _verticalIncrement]; (GVAR(scopeAdjust) select _x) set [2, _maxHorizontal]; (GVAR(scopeAdjust) select _x) set [3, _horizontalIncrement]; - GVAR(canAdjustElevation) set [_x, (_verticalIncrement > 0) && !(_maxVertical isEqualTo [0, 0])]; - GVAR(canAdjustWindage) set [_x, (_horizontalIncrement > 0) && !(_maxHorizontal isEqualTo [0, 0])]; + GVAR(canAdjustElevation) set [_x, (_verticalIncrement > 0) && (_maxVertical isNotEqualTo [0, 0])]; + GVAR(canAdjustWindage) set [_x, (_horizontalIncrement > 0) && (_maxHorizontal isNotEqualTo [0, 0])]; }; // The optic or the weapon changed, reset the adjustment @@ -123,7 +123,7 @@ private _newGuns = [primaryWeapon _player, secondaryWeapon _player, handgunWeapo _persistentZero = 0; }; private _defaultElevation = [0, 300] select GVAR(simplifiedZeroing); - if (!((_adjustment select _forEachIndex) isEqualTo [_defaultElevation, 0, _persistentZero])) then { + if ((_adjustment select _forEachIndex) isNotEqualTo [_defaultElevation, 0, _persistentZero]) then { _adjustment set [_forEachIndex, [_defaultElevation, 0, _persistentZero]]; _updateAdjustment = true; }; @@ -131,11 +131,11 @@ private _newGuns = [primaryWeapon _player, secondaryWeapon _player, handgunWeapo } forEach [0, 1, 2]; if (GVAR(correctZeroing) || GVAR(simplifiedZeroing)) then { - if (!(_unitBaseAngle isEqualTo (_player getVariable [QGVAR(baseAngle), [0,0,0]]))) then { + if (_unitBaseAngle isNotEqualTo (_player getVariable [QGVAR(baseAngle), [0,0,0]])) then { TRACE_2("syncing",_unitBaseAngle,_player getVariable QGVAR(baseAngle)); _player setVariable [QGVAR(baseAngle), _unitBaseAngle, true]; }; - if (!(_unitBoreHeight isEqualTo (_player getVariable [QGVAR(boreHeight), [0,0,0]]))) then { + if (_unitBoreHeight isNotEqualTo (_player getVariable [QGVAR(boreHeight), [0,0,0]])) then { TRACE_2("syncing",_unitBoreHeight,_player getVariable QGVAR(boreHeight)); _player setVariable [QGVAR(boreHeight), _unitBoreHeight, true]; }; diff --git a/addons/scopes/functions/fnc_resetZero.sqf b/addons/scopes/functions/fnc_resetZero.sqf index 4f4510a55d..c22df8bb0f 100644 --- a/addons/scopes/functions/fnc_resetZero.sqf +++ b/addons/scopes/functions/fnc_resetZero.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Resets the zero adjustment of the current scope @@ -17,7 +17,7 @@ params ["_unit"]; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; private _weaponClass = currentWeapon _unit; private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/functions/fnc_showZeroing.sqf b/addons/scopes/functions/fnc_showZeroing.sqf index ada869b5fd..3deb1c4836 100644 --- a/addons/scopes/functions/fnc_showZeroing.sqf +++ b/addons/scopes/functions/fnc_showZeroing.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: KoffeinFlummi, esteldunedain * Display the adjustment knobs, update their value and fade them out later @@ -67,7 +67,7 @@ if (GVAR(simplifiedZeroing)) then { // Set the time when to hide the knobs GVAR(timeToHide) = diag_tickTime + 3.0; -if !(isNil QGVAR(fadePFH)) exitWith {}; +if (!isNil QGVAR(fadePFH)) exitWith {}; // Launch a PFH to wait and fade out the knobs GVAR(fadePFH) = [{ diff --git a/addons/scopes/functions/script_component.hpp b/addons/scopes/functions/script_component.hpp deleted file mode 100644 index acca51b4b5..0000000000 --- a/addons/scopes/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\scopes\script_component.hpp" diff --git a/addons/scopes/initKeybinds.inc.sqf b/addons/scopes/initKeybinds.inc.sqf new file mode 100644 index 0000000000..0e8db97238 --- /dev/null +++ b/addons/scopes/initKeybinds.inc.sqf @@ -0,0 +1,95 @@ +["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), LLSTRING(AdjustUpMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), LLSTRING(AdjustDownMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), LLSTRING(AdjustLeftMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), LLSTRING(AdjustRightMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), LLSTRING(AdjustUpMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), LLSTRING(AdjustDownMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), LLSTRING(AdjustLeftMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), LLSTRING(AdjustRightMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; diff --git a/addons/scopes/initSettings.inc.sqf b/addons/scopes/initSettings.inc.sqf new file mode 100644 index 0000000000..40ed62cbcc --- /dev/null +++ b/addons/scopes/initSettings.inc.sqf @@ -0,0 +1,93 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_displayName), LSTRING(enabled_description)], + _category, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(forceUseOfAdjustmentTurrets), "CHECKBOX", + [LSTRING(forceUseOfAdjustmentTurrets_displayName), LSTRING(forceUseOfAdjustmentTurrets_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(correctZeroing), "CHECKBOX", + [LSTRING(correctZeroing_displayName), LSTRING(correctZeroing_description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(overwriteZeroRange), "CHECKBOX", + [LSTRING(overwriteZeroRange_displayName), LSTRING(overwriteZeroRange_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(defaultZeroRange), "SLIDER", + [LSTRING(defaultZeroRange_displayName), LSTRING(defaultZeroRange_description)], + _category, + [0, 1000, 100, 0], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(zeroReferenceTemperature), "SLIDER", + [LSTRING(zeroReferenceTemperature_displayName), LSTRING(zeroReferenceTemperature_description)], + _category, + [-55, 55, 15, 0], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(zeroReferenceBarometricPressure), "SLIDER", + [LSTRING(zeroReferenceBarometricPressure_displayName), LSTRING(zeroReferenceBarometricPressure_description)], + _category, + [0, 1013.25, 1013.25, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(zeroReferenceHumidity), "SLIDER", + [LSTRING(zeroReferenceHumidity_displayName), LSTRING(zeroReferenceHumidity_description)], + _category, + [0, 1, 0, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(deduceBarometricPressureFromTerrainAltitude), "CHECKBOX", + [LSTRING(deduceBarometricPressureFromTerrainAltitude_displayName), LSTRING(deduceBarometricPressureFromTerrainAltitude_description)], + _category, + false, + 1, + {[QGVAR(deduceBarometricPressureFromTerrainAltitude), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(useLegacyUI), "CHECKBOX", + [LSTRING(useLegacyUI_displayName), LSTRING(useLegacyUI_description)], + _category, + false, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(simplifiedZeroing), "CHECKBOX", + [LSTRING(simplifiedZeroing_displayName), LSTRING(simplifiedZeroing_description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index b437f82d99..b69d59e3c8 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -7,11 +7,15 @@ スコープ 조준경 Celowniki optyczne - Scopes + Lunettes de visée Mirini 瞄准镜 瞄準鏡 Прицелы + Mira Telescópica + Puškohledy + Dürbünler + Visores Enable ACE Scope adjustment @@ -19,11 +23,14 @@ ACE スコープ調節を有効化 ACE 조준경 영점조작 활성화 Włącz ustawienia celowników optycznych ACE - Active ACE Scope adjustment - Abilita Regolazione mirino ACE - 开启ACE瞄准镜归零调节 + Activer le réglage ACE des lunettes + Abilita Regolazione Mirino ACE + 开启 ACE 瞄准镜归零调节 開啟ACE瞄準鏡歸零調節 - Включить настройку прицелов ACE + Вкл. настройку прицелов ACE + Permitir ajustes de Mira do ACE + Povolit ACE náměr puškohledů + Activar ACE Ajuste de visores Enable adjustment turrets on high powered scopes @@ -31,11 +38,14 @@ 高倍率スコープでACE スコープ調節を有効化 고성능 조준경 조절 나사 활성화 Włącz pokrętła regulacyjne - Permet de régler la hausse et la dérive sur les optiques de visée à fort grossissement - Abilita la regolazione delle torrette nei mirini a lunga gittata + Active les tourelles de réglage des lunettes de visée à fort grossissement. + Abilita la regolazione delle manopole sui mirini a lunga gittata 开启高倍率瞄准镜归零调节 開啟高倍率瞄準鏡歸零調節 Включает регулировочные барабанчики ввода поправок на прицелах с высокой кратностью + Permite que as Miras Telescópicas sejam ajustadas com ACE + Povolí náměr puškohledů pomocí komínků optiky na seřízení zameřovacího kříže u kompatibilních puškohledů. + Activar torretas de ajuste en visores de muchos aumentos Force adjustment turrets @@ -43,23 +53,29 @@ ACE スコープ調節を有効化 조절 나사 강제 Wymuś użycie pokręteł regulacyjnych - Impose le réglage de la hausse/dérive - Forza la regolazione delle torrette + Forcer les tourelles de réglage + Forza la regolazione delle manopole 强制使用归零调节 強制使用歸零調節 - Включить регулировку ненастроенных прицелов + Регулировка ненастроенных прицелов + Força ajustes ACE para Miras + Vynutit použití komínků + Forzar torretas de ajuste - 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 高倍率スコープで調整の使用を強制させます 고성능 조준경의 조절 나사 사용을 강제합니다 Wymuś użycie pokręteł regulacyjnych dla celowników o dużym powiększeniu - Impose le réglage de la hausse/dérive sur les optiques de visée à fort grossissement - Forza l'uso della regolazione nei mirini a lunga gittata + Force l'utilisation des tourelles de réglage sur les lunettes de visée à fort grossissement. + Forza l'uso delle manopole sui mirini a lunga gittata 强制为高倍率瞄准镜开启归零调节 強制為高倍率瞄準鏡開啟歸零調節 Принудительно использовать барабанчики ввода поправок для ненастроенных прицелов с высокой кратностью + Força o uso dos controles de ajuste de Mira do ACE em Miras Telescópicas + Vynutí používání komínků u puškohledů. + Forzar uso de torretas de ajuste en visores de muchos aumentos Correct zeroing @@ -67,11 +83,14 @@ ゼロイン調節 영점 고치기 Poprawka zerowania - Corrige le zérotage + Corriger le zérotage Correggi azzeramento 修正归零 修正歸零 Корректировать пристрелку + Corrigir Zeramento + Opravit náměr + Corregir la homogeneidad Corrects the zeroing of all small arms sights @@ -79,11 +98,14 @@ 全ての小口径用照準器のゼロインを調節します 모든 소화기의 영점을 고칩니다 Poprawia zerowanie wszystkich celowników broni ręcznej - Corrige le zérotage des optiques de visée des petites armes + Corrige le zérotage de tous les viseurs d'armes légères. Corregge l'azzeramento di tutti i mirini di bassa portata 为所有小口径武器修正归零 為所有小口徑武器修正歸零 Позволяет корректировать пристрелку для всех прицелов стрелкового оружия + Corrige o Zeramento de todas as miras de armas pequenas. (Zeroing) + Opravuje náměr mířidel všech ručních zbraní + Corrige la homogeneidad de los visores de armas cortas Overwrite zero distance @@ -91,23 +113,29 @@ ゼロイン距離を上書き 영점거리 덮어쓰기 Nadpisuje ustawienie dla zerowego dystansu - Remplace la distance de zérotage - Sovrascrivi la distanza zero + Écraser la distance de zérotage + Sovrascrivi distanza di azzeramento 覆写归零距离 覆寫歸零距離 Перезаписать дальность пристрелки + Sobrepor distância zero + Přepsat vzdálenost náměru + Sobreescribe la distancia de homogeneizado Uses the 'defaultZeroRange' setting to overwrite the zero range of high power scopes Nutzt die Einstellung 'defaultZeroRange' um Zielfernrohre anzupassen 'defaultZeroRange'設定を使う高倍率スコープのゼロイン距離を上書きします - 기존 고성능 조준경의 영점거리에 '기본설정 영점거리' 를 덮어씌웁니다 + 기존 고성능 조준경의 영점거리에 'defaultZeroRange'를 덮어씌웁니다 Używa 'defaultZeroRange' zamiast ustawionej odległości zerowania dla celowników o duzym przybliżeniu - Utilise le paramètre 'defaultZeroRange' pour remplacer la distance de zérotage sur les optiques de visée à fort grossissement - Usa le impostazioni di "defaultZeroRange" (Portata Zero Predefinita) per sovrascrivere la portata zero dei mirini a lunga gittata + Utilise le paramètre "Distance de zérotage par défaut" pour remplacer la distance de zérotage des lunettes de visée à fort grossissement. + Usa l'impostazione "defaultZeroRange" (Distanza di Azzeramento Predefinita) per sovrascrivere la distanza di azzeramento 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 + Používá nastavení 'defaultZeroRange' na přepsání vzdálenosti náměru pro puškohledy + Utiliza el parámetro 'defaultZeroRange' para sobreescribir la distancia de homogeneizado en los visores de muchos aumentos Default zero distance @@ -116,10 +144,13 @@ 기본설정 영점거리 Domyślne zerowanie Distance de zérotage par défaut - Distanza zero predefinita + Distanza di Azzeramento Predefinita 预设归零距离 預設歸零距離 Дальность пристрелки по умолчанию + Distância Zero Padrão + Standardní vzdálenost náměru + Distancia de homogeneizado por defecto High powered scopes will be zeroed at this distance @@ -127,23 +158,29 @@ 高倍率スコープのゼロイン距離はこの設定になります 고성능 조준경이 정해진 수만큼 영점거리를 맞추게 됩니다. Celowniki o dużym powiększeniu będą zerowane dla tej odległości - Distance de zérotage par défaut des optiques de visée à fort grossissement + Distance de zérotage des lunettes de visée à fort grossissement. I mirini a lunga gittata verranno azzerrati a questa distanza 高倍率瞄准镜将归零在这个距离上 高倍率瞄準鏡將歸零在這個距離上 Дальность, на которую будут пристреляны прицелы с высокой кратностью + Miras Telescópicas serão zeradas nessa distância + Puškohledy budou naměřené na tuto vzdálenost + Visores con muchos aumentos serán homogeneizados por este parámetro Reference temperature Bezugstemperatur - 温度の参照 - 온도 기준 + 参照温度 + 기준 온도 Referencyjna temperatura Température de référence Temperatura di riferimento 参考温度 參考溫度 Референсная температура + Temperatura de Referência + Referenční teplota + Temperatura de referencia Temperature at which the scope was zeroed @@ -151,23 +188,29 @@ スコープがゼロインされる温度 조준경 영점조준시 온도 Temperatura, przy której celownik został wyzerowany - Température de référence pour le zérotage des optiques + Température de référence pour le zérotage des lunettes. Temperatura a cui è stato azzerato il mirino - 武器参考多少温度来进行归零. + 武器参考多少温度来进行归零。 武器參考多少溫度來進行歸零. Температура, при которой выполнена пристрелка прицела + Temperatura na qual a mira foi zerada. + Teplota za které byl puškohled naměřen + Temperatura a la que el visor ha sido homogeneizado Reference barometric pressure Bezugsluftdruck - 気圧の参照 - 기압 기준 + 参照気圧 + 기준 기압 Referencyjne ciśnienie barometryczne Pression barométrique de référence Pressione barometrica di riferimento 参考大气压力 參考大氣壓力 Референсное давление + Pressão Barométrica de Referência + Referenční barometrický tlak + Referencia de presión barométrica Barometric pressure at which the scope was zeroed @@ -175,23 +218,29 @@ スコープがゼロインされる気圧 조준경 영점조준시 기압 Ciśnienie barometryczne, przy którym celownik został wyzerowany - Pression barométrique de référence pour le zérotage des optiques + Pression barométrique de référence pour le zérotage des lunettes. Pressione barometrica a cui è stato azzerato il mirino 武器参考多少大气压力来进行归零。 武器參考多少大氣壓力來進行歸零。 Давление, при котором выполнена пристрелка прицела + Pressão Barométrica de quando a mira foi zerada. + Barometrický tlak za kterého byl puškohled naměřen + Presión barométrica a la que el visor ha sido homogeneizado Reference humidity Bezugsluftfeuchtigkeit - 湿度の参照 - 습도 기준 + 参照湿度 + 기준 습도 Referencyjna wilgotność Humidité de référence Umidità di riferimento 参考湿度 參考濕度 Референсная влажность + Umidade de Referência + Referenční vlhkost vzduchu + Humedad de referencia Humidity at which the scope was zeroed @@ -199,79 +248,104 @@ スコープがゼロインされる湿度 조준경 영점조준시 습도 Wilgotność powietrza, przy której celownik został wyzerowany - Taux d'humidité de référence pour le zérotage des optiques + Taux d'humidité de référence pour le zérotage des lunettes. Umidità a cui è stato azzerato il mirino 武器参考多少湿度来进行归零。 武器參考多少濕度來進行歸零。 Влажность, при которой выполнена пристрелка прицела + Umidade na qual a mira foi zerada. + Vlhkost vzduchu za které byl puškohled naměřen + Humedad a la cual el visor ha sido homogeneizado Deduce pressure from altitude Abgeleiteter Luftdruck von der Höhe - 高度により圧が減少 + 高度で減圧する 고도에 맞춰 기압 설정 Ciśnienie określone na podstawie wysokości - Pression selon l'altitude - Ricava la pressione dall'altitudine + Déterminer la pression selon l'altitude + Stima la pressione dall'altitudine 高度影响大气压力 高度影響大氣壓力 Просчитать давление из высоты + Deduzir pressão pela altitude + Snížit tlak podle nadmořské výšky + Deducir presión de la altitud Deduce the barometric pressure from the terrain altitude Abgeleiteter Luftdruck der Geländeumgebung - 標高により気圧が減少されます + 地形高度の標高から気圧を減圧します 주변 고도에 맞춰 기압을 설정합니다 Określ ciśnienie barometryczne na podstawie wysokości terenu - Détermine la pression barométrique selon l'altitude du terrain - Ricava la pressione barometrica dall'altitudine del terreno + Détermine la pression barométrique en fonction de l'altitude du terrain. + Stima la pressione barometrica dall'altitudine del terreno 在不同高度上会有不同的大气压力 在不同高度上會有不同的大氣壓力 Давление определяется по высоте + Deduz a pressão barométrica pela altitude do terreno. + Snížit barometrický tlak podle současné nadmořské výšky terénu + Deduce la presión barométrica de la altura del terreno Use legacy UI Vorheriges UI verwenden - Usa UI precedente + Usa UI Vecchio 使用舊版介面 - 使用旧版介面 - 昔の UI を使用 + 使用旧版界面 + レガシー UI を使用 기존 UI 사용 Wykorzystaj legacy UI Использовать устаревший интерфейс + Usar Interface Antiga + Utiliser l'ancienne IU + Používat staré UI + Utilizar interfaz antigua Displays elevation and windage with signed numbers Anzeige der Absehenverstellungen mit vorzeichenbehafteten Zahlen - Visualizza l'elevazione e la derivazione con i numeri firmati + Visualizza Alzo e Deriva con numeri firmati 使用帶著標籤的數字顯示歸零遠近與風偏程度 使用带着标签的数字显示归零远近与风偏程度 印付きの数字で仰角と横風を表示 기존의 부호가 있는 숫자로 표고와 폭을 표시합니다. Wyświetla elewację i tarcie powietrza poprzez podpisane liczby Отображает горизонтальные и вертикальные поправки с подписанными числами + Exibir elevação e vento com número sinalizados. + Affiche les valeurs de hausse et de dérive avec des nombres signés. + Zobrazovat elevaci a vítr s znaménky plus a mínus. + Muestra la elevación y el viento con números positivos y negativos Simplified zeroing Vereinfachte Nullung 簡略なゼロイン Azzeramento semplificato - 단순화 된 영점 조정 + 단순화된 영점 조정 簡單歸零 简单归零 Uproszczone zerowanie Упрощенная пристрелка + Zeramento Simplificado + Zérotage simplifié + Zjednodušené naměřování + Homogeneizado simplificado Replicates the vanilla zeroing system for riflescopes. Repliziert das Vanilla-Zeroing-System für Zielfernrohre. - 標準で使われるライフルスコープ用のゼロイン システムを複製します。 + バニラ(ゲーム標準)のライフルスコープ用ゼロイン調整システムを複製します。 Replica il sistema di azzeramento vanilla per le ottiche. - 라이플스코프 용 바닐라 영점조정 시스템을 복제합니다. + 라이플 스코프용 바닐라 영점조정 시스템을 복제합니다. 使用原版的歸零系統來取代ACE複雜的歸零模擬。 - 使用原版的归零系统来取代ACE复杂的归零模拟。 + 使用原版的归零系统来取代 ACE 复杂的归零模拟。 Replikuje system zerowania, dla celowników karabinowych, z domyślnej gry. Использует ванильную систему прицеливания для прицелов + Imita o sistema de zeramento vanilla para miras de rifle. + Reproduit le système de zérotage vanilla pour les lunettes. + Replikuje systém naměřování puškohledů ze základní hry. + Replica en los visores el sistema de homogeneizado de vanilla Minor adjustment up @@ -279,12 +353,12 @@ Zerowanie powoli w górę Малая поправка ВВЕРХ Ajuste menor arriba - Regola leggermente alzata in alto + Regola Alzo leggermente verso l'alto Hausse + Enyhe állítás fel Pequeno ajuste para cima Korekce nahoru (mírně) - 僅かに上へ調節 + 小さく上へ調節 위로 조절 向上微调 向上微調 @@ -295,12 +369,12 @@ Zerowanie powoli w dół Малая поправка ВНИЗ Ajuste menor abajo - Regola leggermente alzata in basso + Regola Alzo leggermente verso il basso Hausse - Enyhe állítás le Pequeno ajuste para baixo Korekce dolů (mírně) - 僅かに下へ調節 + 小さく下へ調節 아래로 조절 向下微调 向下微調 @@ -311,13 +385,13 @@ Zerowanie powoli w prawo Малая поправка ВПРАВО Ajuste menor derecha - Regola leggermente il tiro a destra + Regola Deriva leggermente a destra Dérive + Enyhe állítás jobbra Pequeno ajuste para direita Korekce doprava (mírně) - 僅かに右へ調節 - 오론쪽으로 조절 + 小さく右へ調節 + 오른쪽으로 조절 向右微调 向右微調 @@ -327,12 +401,12 @@ Zerowanie powoli w lewo Малая поправка ВЛЕВО Ajuste menor izquierda - Regola leggermete il tiro a sinistra + Regola Deriva leggermente a sinistra Dérive - Enyhe állítás balra Pequeno ajuste para esquerda Korekce doleva (mírně) - 僅かに左へ調節 + 小さく左へ調節 왼쪽으로 조절 向左微调 向左微調 @@ -359,7 +433,7 @@ Zerowanie w dół Большая поправка ВНИЗ Ajuste mayor abajo - Regola l'alzata in basso + Regola Alzo verso il basso Hausse - - - Nagy állítás le Ajuste grande para baixo @@ -375,7 +449,7 @@ Zerowanie w prawo Большая поправка ВПРАВО Ajuste mayor derecha - Regola il tiro a destra + Regola Deriva a destra Dérive +++ Nagy állítás jobbra Ajuste grande para direita @@ -391,7 +465,7 @@ Zerowanie w lewo Большая поправка ВЛЕВО Ajuste mayor izquierda - Regola il tiro a sinistra + Regola Deriva a sinistra Dérive - - - Nagy állítás balra Ajuste grande para esquerda @@ -407,8 +481,8 @@ Ustaw wyzerowanie Установить дальность пристрелки Establecer ajuste a cero - Imposta i valori dell'azzeramento - RAZ corrections + Imposta l'azzeramento + Réglage du zéro Állítások nullázása Zerar ajuste Vynulovat korekci @@ -421,12 +495,16 @@ Reset zero adjustment Nullung zurücksetzen ゼロイン調節を初期化 - Resetta i valori dell'azzeramento + Resetta l'azzeramento 영점 조정 재설정 重設歸零 重设归零 Zresetuj wyzerowanie Сбросить дальность пристрелки + Restaurar Ajuste Zero + Réinitialiser le réglage du zéro + Reset vynulování + Restaurar ajuste de homogeneizado This module adds windage and elevation adjustment turrets on high power rifle scopes. @@ -434,11 +512,14 @@ このモジュールは高倍率ライフル スコープにおいて横風と仰角の調節ができます。 이 모듈은 고성능 조준경에 조준 나사를 이용한 편차 및 고도 조절 기능을 더해줍니다. Ten moduł włącza pokrętła kalibracyjne poprawki na wiatr oraz poprawki wysokości dla celowników o dużym powiększeniu. - Ce module ajoute les tambours de correction de la hausse et de dérive sur les optiques de visée à fort grossissement. - Questo modulo aggiunge lo spostamento dell'aria e la regolazione dell'elevazione delle torrette in mirini a lunga gittata + Ce module ajoute les tourelles de correction de hausse et de dérive sur les lunettes de visée à fort grossissement. + Questo modulo aggiunge lo spostamento dell'aria e la regolazione dell'elevazione delle manopole in mirini a lunga gittata 此模块可为高倍率瞄准镜新增归零风偏,距离用的调整纽。 此模塊可為高倍率瞄準鏡新增歸零風偏,距離用的調整紐。 Этот модуль добавляет барабанчики ввода горизонтальных и вертикальных поправок для прицелов с высокой кратностью + Esse módulo implementa vento e elevação para os ajustes de miras telescópicas. + Tento modul přidává korekci zaměrovacího kříže puškohledů pro vítr a výšku. + Este módulo añade torretas de ajuste de viento y elevación en visores con muchos aumentos. %1D @@ -448,51 +529,75 @@ %1D %1D %1D - %1D + %1하 %1D %1D + %1D + %1D + %1D + %1D %1L %1L %1G - %1L + %1Sx %1L %1L %1L - %1L + %1좌 %1L %1L + %1L + %1L + %1L + %1L %1R %1R %1D - %1R + %1Dx %1R %1R %1R - %1R + %1우 %1R %1R + %1R + %1R + %1R + %1R Horizontal limits Horizontale Grenzen 水平限制 + 水平限制 水平制限 - Limite orrizontale + Limiti orizzontali Limit poziomy Лимит по горизонтали + Limite Horizontal + Limites horizontales + Horizontální limity + Límites horizontales + 수평 한계 Vertical limits Vertikale Grenzen 垂直限制 + 垂直限制 垂直制限 - Limite verticale + Limiti verticali Limit pionowy Лимит по вертикали + Limite Vertical + Limites verticales + Vertikální limity + Límites verticales + 수직 한계 diff --git a/addons/sitting/$PBOPREFIX$ b/addons/sitting/$PBOPREFIX$ new file mode 100644 index 0000000000..33a846b780 --- /dev/null +++ b/addons/sitting/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\sitting diff --git a/addons/sitting/ACE_Settings.hpp b/addons/sitting/ACE_Settings.hpp new file mode 100644 index 0000000000..0249636f49 --- /dev/null +++ b/addons/sitting/ACE_Settings.hpp @@ -0,0 +1,5 @@ +class ACE_Settings { + class XGVAR(enable) { + movedToSQF = 1; + }; +}; diff --git a/addons/sitting/CfgEventHandlers.hpp b/addons/sitting/CfgEventHandlers.hpp new file mode 100644 index 0000000000..7b93414593 --- /dev/null +++ b/addons/sitting/CfgEventHandlers.hpp @@ -0,0 +1,25 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); + }; +}; + +class Extended_Killed_EventHandlers { + class CAManBase { + class ADDON { + killed = QUOTE(_this call DFUNC(handleInterrupt)); + }; + }; +}; diff --git a/addons/sitting/CfgMoves.hpp b/addons/sitting/CfgMoves.hpp new file mode 100644 index 0000000000..f203203ed0 --- /dev/null +++ b/addons/sitting/CfgMoves.hpp @@ -0,0 +1,108 @@ +// Force free-look, prevent body rotating and leaning +#define MACRO_ANIMATION \ + head = "headDefault"; \ + aimingBody = "aimingNo"; \ + forceAim = 1; \ + static = 1; + +class CfgMovesBasic; +class CfgMovesMaleSdr: CfgMovesBasic { + class States { + class HubSittingChairA_idle1; + class GVAR(HubSittingChairA_idle1): HubSittingChairA_idle1 { + MACRO_ANIMATION + }; + class HubSittingChairA_idle2; + class GVAR(HubSittingChairA_idle2): HubSittingChairA_idle2 { + MACRO_ANIMATION + }; + class HubSittingChairA_idle3; + class GVAR(HubSittingChairA_idle3): HubSittingChairA_idle3 { + MACRO_ANIMATION + }; + class HubSittingChairA_move1; + class GVAR(HubSittingChairA_move1): HubSittingChairA_move1 { + MACRO_ANIMATION + }; + class HubSittingChairB_idle1; + class GVAR(HubSittingChairB_idle1): HubSittingChairB_idle1 { + MACRO_ANIMATION + }; + class HubSittingChairB_idle2; + class GVAR(HubSittingChairB_idle2): HubSittingChairB_idle2 { + MACRO_ANIMATION + }; + class HubSittingChairB_idle3; + class GVAR(HubSittingChairB_idle3): HubSittingChairB_idle3 { + MACRO_ANIMATION + }; + class HubSittingChairB_move1; + class GVAR(HubSittingChairB_move1): HubSittingChairB_move1 { + MACRO_ANIMATION + }; + class HubSittingChairC_idle1; + class GVAR(HubSittingChairC_idle1): HubSittingChairC_idle1 { + MACRO_ANIMATION + }; + class HubSittingChairC_idle2; + class GVAR(HubSittingChairC_idle2): HubSittingChairC_idle2 { + MACRO_ANIMATION + }; + class HubSittingChairC_idle3; + class GVAR(HubSittingChairC_idle3): HubSittingChairC_idle3 { + MACRO_ANIMATION + }; + class HubSittingChairC_move1; + class GVAR(HubSittingChairC_move1): HubSittingChairC_move1 { + MACRO_ANIMATION + }; + class HubSittingChairUA_idle1; + class GVAR(HubSittingChairUA_idle1): HubSittingChairUA_idle1 { + MACRO_ANIMATION + }; + class HubSittingChairUA_idle2; + class GVAR(HubSittingChairUA_idle2): HubSittingChairUA_idle2 { + MACRO_ANIMATION + }; + class HubSittingChairUA_idle3; + class GVAR(HubSittingChairUA_idle3): HubSittingChairUA_idle3 { + MACRO_ANIMATION + }; + class HubSittingChairUA_move1; + class GVAR(HubSittingChairUA_move1): HubSittingChairUA_move1 { + MACRO_ANIMATION + }; + class HubSittingChairUB_idle1; + class GVAR(HubSittingChairUB_idle1): HubSittingChairUB_idle1 { + MACRO_ANIMATION + }; + class HubSittingChairUB_idle2; + class GVAR(HubSittingChairUB_idle2): HubSittingChairUB_idle2 { + MACRO_ANIMATION + }; + class HubSittingChairUB_idle3; + class GVAR(HubSittingChairUB_idle3): HubSittingChairUB_idle3 { + MACRO_ANIMATION + }; + class HubSittingChairUB_move1; + class GVAR(HubSittingChairUB_move1): HubSittingChairUB_move1 { + MACRO_ANIMATION + }; + class HubSittingChairUC_idle1; + class GVAR(HubSittingChairUC_idle1): HubSittingChairUC_idle1 { + MACRO_ANIMATION + }; + class HubSittingChairUC_idle2; + class GVAR(HubSittingChairUC_idle2): HubSittingChairUC_idle2 { + MACRO_ANIMATION + }; + class HubSittingChairUC_idle3; + class GVAR(HubSittingChairUC_idle3): HubSittingChairUC_idle3 { + MACRO_ANIMATION + }; + class HubSittingChairUC_move1; + class GVAR(HubSittingChairUC_move1): HubSittingChairUC_move1 { + MACRO_ANIMATION + }; + }; +}; diff --git a/addons/sitting/CfgVehicles.hpp b/addons/sitting/CfgVehicles.hpp new file mode 100644 index 0000000000..ad2e7db2d2 --- /dev/null +++ b/addons/sitting/CfgVehicles.hpp @@ -0,0 +1,224 @@ +class CfgVehicles { + class ACE_Module; + class ACEX_ModuleSitting: ACE_Module { + author = ECSTRING(common,ACETeam); + category = "ACE"; + displayName = CSTRING(ModuleDisplayName); + function = QFUNC(moduleInit); + scope = 1; + isGlobal = 1; + isSingular = 1; + icon = QUOTE(PATHTOF(UI\Icon_Module_Sitting_ca.paa)); + class Arguments { + class enable { + displayName = CSTRING(Enable); + description = CSTRING(Enable); + typeName = "BOOL"; + defaultValue = 1; + }; + }; + class ModuleDescription { + description = CSTRING(ModuleDescription); + }; + }; + class ACE_ModuleSitting: ACEX_ModuleSitting { + scope = 1; // hidden, backwards compatibility + }; + + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class XGVAR(Stand) { + displayName = CSTRING(Stand); + condition = QUOTE(_player call FUNC(canStand)); + exceptions[] = {"isNotSitting"}; + statement = QUOTE(_player call FUNC(stand)); + priority = 0; + icon = QUOTE(PATHTOF(UI\stand_ca.paa)); + }; + }; + }; + + // Folding Chair + class ThingX; + class Land_CampingChair_V1_F: ThingX { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = {0, -0.1, -0.45}; + XGVAR(interactPosition)[] = {0, 0, 0.3}; + + EGVAR(interaction,replaceTerrainObject) = 1; + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + }; + + // Camping Chair + class Land_CampingChair_V2_F: ThingX { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = {0, -0.1, -0.45}; + XGVAR(interactPosition)[] = {0, 0, 0.3}; + + EGVAR(interaction,replaceTerrainObject) = 1; + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + }; + + // Chair (Plastic) + class Furniture_base_F: ThingX {}; + class Land_ChairPlastic_F: Furniture_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 90; + XGVAR(sitPosition)[] = {0, 0, -0.5}; + XGVAR(interactPosition)[] = {0, 0, 0.3}; + + EGVAR(interaction,replaceTerrainObject) = 1; + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 270; + }; + + // Chair (Wooden) + class Land_ChairWood_F: Furniture_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = {0, -0.05, 0}; + XGVAR(interactPosition)[] = {0, 0, 0.8}; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + }; + + // Office Chair + class Land_OfficeChair_01_F: Furniture_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = {0, 0, -0.6}; + XGVAR(interactPosition)[] = {0, 0, 0.3}; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + }; + + // Wooden Log + class Land_WoodenLog_F: ThingX { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 0; + XGVAR(sitPosition)[] = {0, 0, -1}; + XGVAR(interactPosition)[] = {0, 0, 0.5}; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + }; + + // Rattan Chair + class Land_RattanChair_01_F: Furniture_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = {0, 0, -1}; // Z must be -1 due to chair's geometry (magic floating seat point) + XGVAR(interactPosition)[] = {0, 0, 0.3}; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + }; + + // Arm Chair + class Furniture_Residental_base_F; + class Land_ArmChair_01_F: Furniture_Residental_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 0; + XGVAR(sitPosition)[] = {0, 0, -1}; + XGVAR(interactPosition)[] = {0, 0, 0.3}; + + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; + EGVAR(dragging,carryDirection) = 180; + + }; + + class House_F; + class Land_BusStop_02_shelter_F: House_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = { {-0.5, 0.9, -1.3}, {0.5, 0.9, -1.3} }; + XGVAR(interactPosition)[] = { {-0.5, 0.9, -0.3}, {0.5, 0.9, -0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + }; + + // Benches + class Land_Bench_F: Furniture_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 90; + XGVAR(sitPosition)[] = { {0.1, -0.5, -0.9}, {0.1, 0.5, -0.9} }; + XGVAR(interactPosition)[] = { {0, -0.5, 0.3}, {0, 0.5, 0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryDirection) = 90; + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0, 1, 0}; + EGVAR(dragging,dragDirection) = 90; + }; + + class House_Small_F; + class Land_Bench_01_F: House_Small_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = { {0.5, -0.04, -0.90}, {-0.5, -0.04, -0.90} }; + XGVAR(interactPosition)[] = { {0.5, 0, 0.3}, {-0.5, 0, 0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + }; + + class Land_Bench_02_F: House_Small_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = { {0.5, -0.04, -0.90}, {-0.5, -0.04, -0.90} }; + XGVAR(interactPosition)[] = { {0.5, 0, 0.3}, {-0.5, 0, 0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + }; + + class Land_Bench_03_F: House_Small_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = { {0.5, -0.15, -0.90}, {-0.5, -0.15, -0.90} }; + XGVAR(interactPosition)[] = { {0.5, 0, 0.3}, {-0.5, 0, 0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + }; + + /* Disabled due to a geometry issue with height + class Land_Bench_04_F: House_Small_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = { {0.5, -0.04, -2.00}, {-0.5, -0.04, -2.00} }; + XGVAR(interactPosition)[] = { {0.5, 0, 0.3}, {-0.5, 0, 0.3} }; + };*/ + + class Land_Bench_05_F: House_Small_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 0; + XGVAR(sitPosition)[] = { {0.5, -0.04, -0.90}, {-0.5, -0.04, -0.90} }; + XGVAR(interactPosition)[] = { {0.5, 0, 0.3}, {-0.5, 0, 0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + }; + + class Stall_base_F; + class Land_StallWater_F: Stall_base_F { + XGVAR(canSit) = 1; + XGVAR(sitDirection) = 180; + XGVAR(sitPosition)[] = { {-0.4, -0.8, -0.9}, {0.4, -0.8, -0.9} }; + XGVAR(interactPosition)[] = { {-0.4, -0.75, 0.3}, {0.4, -0.75, 0.3} }; + + EGVAR(interaction,replaceTerrainObject) = 1; + }; +}; diff --git a/addons/sitting/README.md b/addons/sitting/README.md new file mode 100644 index 0000000000..e4d52bfa6d --- /dev/null +++ b/addons/sitting/README.md @@ -0,0 +1,8 @@ +ace_sitting +=============== + +The Sitting module introduces ability to sit on chairs. + +## ACEX Conversion - things still using acex prefix +- All settings +- CfgVehicles Config Entries (e.g. `acex_sitting_canSit`) diff --git a/addons/sitting/UI/Icon_Module_Sitting_ca.paa b/addons/sitting/UI/Icon_Module_Sitting_ca.paa new file mode 100644 index 0000000000..1d4bbccb70 Binary files /dev/null and b/addons/sitting/UI/Icon_Module_Sitting_ca.paa differ diff --git a/addons/sitting/UI/sit_ca.paa b/addons/sitting/UI/sit_ca.paa new file mode 100644 index 0000000000..1191c3b1e0 Binary files /dev/null and b/addons/sitting/UI/sit_ca.paa differ diff --git a/addons/sitting/UI/stand_ca.paa b/addons/sitting/UI/stand_ca.paa new file mode 100644 index 0000000000..08c136f668 Binary files /dev/null and b/addons/sitting/UI/stand_ca.paa differ diff --git a/addons/sitting/XEH_PREP.hpp b/addons/sitting/XEH_PREP.hpp new file mode 100644 index 0000000000..1a01bf8427 --- /dev/null +++ b/addons/sitting/XEH_PREP.hpp @@ -0,0 +1,8 @@ +ACEX_PREP(addSitActions); +ACEX_PREP(canSit); +ACEX_PREP(canStand); +ACEX_PREP(getRandomAnimation); +ACEX_PREP(handleInterrupt); +ACEX_PREP(moduleInit); +ACEX_PREP(sit); +ACEX_PREP(stand); diff --git a/addons/sitting/XEH_clientInit.sqf b/addons/sitting/XEH_clientInit.sqf new file mode 100644 index 0000000000..5495ef0e97 --- /dev/null +++ b/addons/sitting/XEH_clientInit.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +// Exit on Headless +if (!hasInterface) exitWith {}; + +["ace_settingsInitialized", { + TRACE_1("SettingInit",XGVAR(enable)); + + // If not enabled, then do not add CanInteractWith Condition or event handlers + if (!XGVAR(enable)) exitWith {}; + + // Initialize classes as they spawn + ["ThingX", "init", LINKFUNC(addSitActions), nil, nil, true] call CBA_fnc_addClassEventHandler; + + // Initialize statically defined benches (also appear as world objects, no class EH thrown) + { + [_x] call FUNC(addSitActions); + } forEach [BENCHES]; + + // Add interaction menu exception + ["isNotSitting", {isNil {(_this select 0) getVariable QGVAR(sittingStatus)}}] call EFUNC(common,addCanInteractWithCondition); + + // Handle interruptions + ["ace_unconscious", LINKFUNC(handleInterrupt)] call CBA_fnc_addEventHandler; + ["ace_captives_SetHandcuffed", LINKFUNC(handleInterrupt)] call CBA_fnc_addEventHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/sitting/XEH_preInit.sqf b/addons/sitting/XEH_preInit.sqf new file mode 100644 index 0000000000..e626c67e76 --- /dev/null +++ b/addons/sitting/XEH_preInit.sqf @@ -0,0 +1,15 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +if (hasInterface) then { + GVAR(initializedClasses) = []; +}; + +ADDON = true; diff --git a/addons/sitting/XEH_preStart.sqf b/addons/sitting/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/sitting/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/sitting/config.cpp b/addons/sitting/config.cpp new file mode 100644 index 0000000000..ab5c53047d --- /dev/null +++ b/addons/sitting/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Jonpas"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; + + BWC_CONFIG(XADDON); +}; + +#include "ACE_Settings.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMoves.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/sitting/functions/fnc_addSitActions.sqf b/addons/sitting/functions/fnc_addSitActions.sqf new file mode 100644 index 0000000000..a705ca21e6 --- /dev/null +++ b/addons/sitting/functions/fnc_addSitActions.sqf @@ -0,0 +1,71 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Adds sit actions. + * + * Arguments: + * 0: Seat + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_sitting_fnc_addSitActions + * + * Public: No + */ + +params ["_seat"]; + +private _type = _seat; +if (_seat isEqualType objNull) then { + _type = typeOf _seat; +}; + +private _configFile = configFile >> "CfgVehicles" >> _type; + +// Exit if sitting disabled or the object is not specified as a seat +if (!XGVAR(enable) || {getNumber (_configFile >> QXGVAR(canSit)) != 1}) exitWith {}; + +// Exit if class already initialized +if (_type in GVAR(initializedClasses)) exitWith {}; +GVAR(initializedClasses) pushBack _type; + +TRACE_1("Adding Sit Action",_type); + +private _sitPosition = getArray (_configFile >> QXGVAR(sitPosition)); +private _interactPosition = getArray (_configFile >> QXGVAR(interactPosition)); + +if (count _sitPosition != count _interactPosition) exitWith { + WARNING_1("Invalid sitting configuration of %1!",_type); +}; + +if !((_sitPosition select 0) isEqualType []) then { + _sitPosition = [_sitPosition]; + _interactPosition = [_interactPosition]; +}; + +{ + private _menuPosition = [0,0,0]; + private _menuType = ["ACE_MainActions"]; + if (count _interactPosition >= _forEachIndex) then { + _menuPosition = _interactPosition select _forEachIndex; + _menuType = []; + }; + + TRACE_3("Menu Position",_menuPosition,_menuType,_forEachIndex); + + private _sitAction = [ + format [QGVAR(Sit_%1), _forEachIndex], + LLSTRING(Sit), + QUOTE(PATHTOF(UI\sit_ca.paa)), + {_this call FUNC(sit)}, + {_this call FUNC(canSit)}, + {}, + _forEachIndex, + _menuPosition, + 1.5 + ] call EFUNC(interact_menu,createAction); + [_type, 0, _menuType, _sitAction] call EFUNC(interact_menu,addActionToClass); +} forEach _sitPosition; + diff --git a/addons/sitting/functions/fnc_canSit.sqf b/addons/sitting/functions/fnc_canSit.sqf new file mode 100644 index 0000000000..4328234bd9 --- /dev/null +++ b/addons/sitting/functions/fnc_canSit.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, vabene1111 + * Check if the player can sit down. + * + * Arguments: + * 0: Seat + * 1: Player + * 2: Seat Position (default: 0) + * + * Return Value: + * Can Sit Down + * + * Example: + * [cursorObject, player] call ace_sitting_fnc_canSit + * + * Public: No + */ + +params ["_seat", "_player", ["_seatPos", 0]]; + +// Sitting enabled, not occupied and standing up (or not on a big slope) +XGVAR(enable) && +{isNil {_player getVariable QGVAR(sittingStatus)}} && +{ + private _seatsClaimed = _seat getVariable [QGVAR(seatsClaimed), []]; + _seatsClaimed isEqualTo [] || {!(_seatsClaimed select _seatPos)} +} && +{round (vectorUp _seat select 0) == 0 && {round (vectorUp _seat select 1) == 0} && {round (vectorUp _seat select 2) == 1}} diff --git a/addons/sitting/functions/fnc_canStand.sqf b/addons/sitting/functions/fnc_canStand.sqf new file mode 100644 index 0000000000..fafe4f2cd8 --- /dev/null +++ b/addons/sitting/functions/fnc_canStand.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Check if the player can stand up (is in sitting position). + * + * Arguments: + * Player + * + * Return Value: + * Can Stand Up + * + * Example: + * player call ace_sitting_fnc_canStand + * + * Public: No + */ + +params ["_player"]; + +// Sitting +!isNil {_player getVariable QGVAR(sittingStatus)} diff --git a/addons/sitting/functions/fnc_getRandomAnimation.sqf b/addons/sitting/functions/fnc_getRandomAnimation.sqf new file mode 100644 index 0000000000..ac8bd9e68d --- /dev/null +++ b/addons/sitting/functions/fnc_getRandomAnimation.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Gets a random animations from the list. + * + * Arguments: + * None + * + * Return Value: + * Random Animation + * + * Example: + * _animation = call ace_sitting_fnc_getRandomAnimation + * + * Public: No + */ + +// Select random animation from Animations Pool +selectRandom [ + QGVAR(HubSittingChairA_idle1), + QGVAR(HubSittingChairA_idle2), + QGVAR(HubSittingChairA_idle3), + QGVAR(HubSittingChairA_move1), + QGVAR(HubSittingChairB_idle1), + QGVAR(HubSittingChairB_idle2), + QGVAR(HubSittingChairB_idle3), + QGVAR(HubSittingChairB_move1), + QGVAR(HubSittingChairC_idle1), + QGVAR(HubSittingChairC_idle2), + QGVAR(HubSittingChairC_idle3), + QGVAR(HubSittingChairC_move1), + QGVAR(HubSittingChairUA_idle1), + QGVAR(HubSittingChairUA_idle2), + QGVAR(HubSittingChairUA_idle3), + QGVAR(HubSittingChairUA_move1), + QGVAR(HubSittingChairUB_idle1), + QGVAR(HubSittingChairUB_idle2), + QGVAR(HubSittingChairUB_idle3), + QGVAR(HubSittingChairUB_move1), + QGVAR(HubSittingChairUC_idle1), + QGVAR(HubSittingChairUC_idle2), + QGVAR(HubSittingChairUC_idle3), + QGVAR(HubSittingChairUC_move1) +] diff --git a/addons/sitting/functions/fnc_handleInterrupt.sqf b/addons/sitting/functions/fnc_handleInterrupt.sqf new file mode 100644 index 0000000000..ce1ec9fb6a --- /dev/null +++ b/addons/sitting/functions/fnc_handleInterrupt.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Handles interruptions of sitting, like killed or unconsciousness. + * + * Arguments: + * 0: Player + * + * Return Value: + * None + * + * Example: + * player call ace_sitting_fnc_handleInterrupt + * + * Public: No + */ + +params ["_player"]; + +if (!isNil {_player getVariable QGVAR(sittingStatus)}) then { + _player call FUNC(stand); +}; diff --git a/addons/sitting/functions/fnc_moduleInit.sqf b/addons/sitting/functions/fnc_moduleInit.sqf new file mode 100644 index 0000000000..d2b8feefa0 --- /dev/null +++ b/addons/sitting/functions/fnc_moduleInit.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Initializes the Sitting module. + * + * Arguments: + * 0: The module logic + * 1: Units + * 2: Activated + * + * Return Value: + * None + * + * Public: No + */ + +params ["_logic", "_units", "_activated"]; + +if (!_activated) exitWith {}; + +[_logic, QXGVAR(enable), "enable"] call EFUNC(common,readSettingFromModule); + +INFO("Sitting Module Initialized."); diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf new file mode 100644 index 0000000000..70e028719b --- /dev/null +++ b/addons/sitting/functions/fnc_sit.sqf @@ -0,0 +1,108 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, vabene1111 + * Sits down the player. + * + * Arguments: + * 0: Seat + * 1: Player + * 2: Seat Position (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject, player] call ace_sitting_fnc_sit + * [cursorObject, player, 0] call ace_sitting_fnc_sit + * + * Public: No + */ + +params ["_seat", "_player", ["_seatPos", 0]]; +TRACE_3("sit",_seat,_player,_seatPos); + +// Overwrite weird position, because Arma decides to set it differently based on current animation/stance... +_player switchMove "amovpknlmstpsraswrfldnon"; + +// Add scroll-wheel action to release object +private _actionID = _player addAction [ + format ["%1", LLSTRING(Stand)], + QUOTE((_this select 0) call FUNC(stand)), + nil, + 20, + false, + true, + "GetOut", + QUOTE(_this call FUNC(canStand)) +]; + +// Read config +private _configFile = configOf _seat; +private _sitDirection = (getDir _seat) + (_seat getVariable [QXGVAR(sitDirection), getNumber (_configFile >> QXGVAR(sitDirection))]); +private _sitPositionAll = _seat getVariable [QXGVAR(sitPosition), getArray (_configFile >> QXGVAR(sitPosition))]; +private _multiSitting = (_sitPositionAll select 0) isEqualType []; + +private _sitPosition = _sitPositionAll; +if (_multiSitting) then { + _sitPosition = _sitPosition select _seatPos; +}; + +// Get random animation and perform it (before moving player to ensure correct placement) +[_player, call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations +[_player, "", 1] call EFUNC(common,doAnimation); // Correctly applies animation's config values (such as disallow throwing of grenades, intercept keybinds... etc). + +TRACE_2("Sit pos and dir",_sitPosition,_sitDirection); + +// Set direction and position +_player setDir _sitDirection; +//modelToWorld returns AGL +_player setPosASL (AGLtoASL (_seat modelToWorld _sitPosition)); + +// Set variables, save seat object on player +_player setVariable [QGVAR(sittingStatus), [_seat, _actionID, _seatPos]]; + +// Prevent multiple people sitting on one seat +private _seatsClaimed = _seat getVariable [QGVAR(seatsClaimed), []]; +// Initialize claimed seats if first time sitting on it +if (_seatsClaimed isEqualTo []) then { + if (_multiSitting) then { + for "_i" from 0 to ((count _sitPositionAll) - 1) do { + _seatsClaimed pushBack (_i == _seatPos); + }; + } else { + _seatsClaimed = [true]; + }; +} else { + _seatsClaimed set [_seatPos, true]; +}; +_seat setVariable [QGVAR(seatsClaimed), _seatsClaimed, true]; + +// Also prevent dragging/carrying +if !([_seat] call EFUNC(common,owned)) then { + [_player, _seat] call EFUNC(common,claim); +}; + +// Add automatical stand PFH in case of interruptions +private _seatPosOrig = getPosASL _seat; +private _seatDistOrig = (getPosASL _player) distance _seat; +[{ + params ["_args", "_pfhId"]; + _args params ["_player", "_seat", "_seatPosOrig", "_seatDistOrig"]; + + // Remove PFH if not sitting any more + if (isNil {_player getVariable QGVAR(sittingStatus)}) exitWith { + [_pfhId] call CBA_fnc_removePerFrameHandler; + TRACE_1("Remove PFH",_player getVariable [ARR_2(QGVAR(sittingStatus),false)]); + }; + + // Stand up if chair gets deleted or moved + if (isNull _seat || + {getPosASL _player distance _seatPosOrig > _seatDistOrig + 0.5} || + {((getPosASL _seat) vectorDistance _seatPosOrig) > 0.01} + ) exitWith { + _player call FUNC(stand); + TRACE_2("Chair moved",getPosASL _seat,_seatPosOrig); + }; +}, 0, [_player, _seat, _seatPosOrig, _seatDistOrig]] call CBA_fnc_addPerFrameHandler; + +["ace_satDown", [_player, _seat, _seatPos]] call CBA_fnc_localEvent; diff --git a/addons/sitting/functions/fnc_stand.sqf b/addons/sitting/functions/fnc_stand.sqf new file mode 100644 index 0000000000..b25c7a5ee1 --- /dev/null +++ b/addons/sitting/functions/fnc_stand.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Stands up the player. + * + * Arguments: + * Player + * + * Return Value: + * None + * + * Example: + * player call ace_sitting_fnc_stand + * + * Public: No + */ + +params ["_player"]; +TRACE_1("stand",_player); + +(_player getVariable QGVAR(sittingStatus)) params ["_seat", "_actionID", ["_seatPos", 0]]; +TRACE_3("sittingStatus",_seat,_actionID,_seatPos); + +// Remove scroll-wheel action +_player removeAction _actionID; + +// Restore animation +private _animation = switch (currentWeapon _player) do { + case "": {"amovpercmstpsnonwnondnon"}; + case (primaryWeapon _player): {"amovpercmstpslowwrfldnon"}; + case (handgunWeapon _player): {"amovpercmstpslowwpstdnon"}; + default {"amovpercmstpsnonwnondnon"}; +}; + +[_player, _animation, 2] call EFUNC(common,doAnimation); + +// Set sitting status to nil +_player setVariable [QGVAR(sittingStatus), nil]; + +["ace_stoodUp", [_player, _seat, _seatPos]] call CBA_fnc_localEvent; + +if (isNull _seat) exitWith {}; + +// Allow sitting on this seat again +private _seatsClaimed = _seat getVariable [QGVAR(seatsClaimed), []]; +_seatsClaimed set [_seatPos, false]; +_seat setVariable [QGVAR(seatsClaimed), _seatsClaimed, true]; + +// Unclaim if no one else sitting on it +if (_seatsClaimed find true == -1) then { + [objNull, _seat] call EFUNC(common,claim); +}; diff --git a/addons/sitting/initSettings.inc.sqf b/addons/sitting/initSettings.inc.sqf new file mode 100644 index 0000000000..ee1af1ec8e --- /dev/null +++ b/addons/sitting/initSettings.inc.sqf @@ -0,0 +1,10 @@ +[ + QXGVAR(enable), + "CHECKBOX", + [LSTRING(Enable), LSTRING(ModuleDescription)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + true, + true, + {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/sitting/script_component.hpp b/addons/sitting/script_component.hpp new file mode 100644 index 0000000000..50c9bad2de --- /dev/null +++ b/addons/sitting/script_component.hpp @@ -0,0 +1,22 @@ +#define COMPONENT sitting +#define COMPONENT_BEAUTIFIED Sitting +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_SITTING + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_SITTING + #define DEBUG_SETTINGS DEBUG_SETTINGS_SITTING +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + + +#define BENCHES \ + "Land_Bench_01_F", "Land_Bench_02_F", "Land_Bench_03_F", "Land_Bench_04_F", "Land_Bench_05_F", \ + "Land_StallWater_F", "Land_BusStop_02_shelter_F" diff --git a/addons/sitting/stringtable.xml b/addons/sitting/stringtable.xml new file mode 100644 index 0000000000..9ec35ef8b8 --- /dev/null +++ b/addons/sitting/stringtable.xml @@ -0,0 +1,90 @@ + + + + + Sit Down + Hinsetzen + Usiądź + Sentar + Sednout si + Sentarse + S'asseoir + Leülés + Сесть + Siediti + 座る + 앉기 + 坐下 + 坐下 + Otur + + + Stand Up + Aufstehen + Wstań + Levantar + Vstát + Levantarse + Se lever + Felállás + Встать + Alzati + 立つ + 일어서기 + 站起来 + 站起來 + Kalk + + + Enable Sitting + Sitzen ermöglichen + Habilitar opção para sentar + Aktywuj siadanie + Povolit sezení + Activar asiento + Permettre de s'asseoir + Ülés engedélyezése + Разрешить сидение + Abilita seduta + 座るのを有効化 + 앉기 사용 + 开启坐下功能 + 開啟坐下功能 + Oturmayı Aktik Et + + + Sitting + Hinsetzen + Sentado + Siadanie + Sezení + Sentarse + S'asseoir + Ülés + Сидение + Sedersi + 着座 + 앉기 + 坐下功能 + 坐下功能 + Oturma + + + This module allows you to disable the ability to sit on chairs. + Dieses Modul eröffnet die Möglichkeit, sich auf Stühlen hinzusetzen. + Este módulo permite que você desabilite a capacidade de sentar-se em cadeiras e banheiros. + Moduł ten pozwala na włączenie lub wyłączenie możliwości siadania na krzesłach i toaletach. + Tento modul dovoluje zakázat možnost sedět na židlých a toaletách. + Este módulo te permite desactivar la capacidad de sentarse en sillas. + Ce module contrôle la capacité de s'asseoir sur des chaises. + Ez a modul lehetővé teszi a székekre és toalettekre való leülés letiltását. + Этот модуль позволяет вам запретить возможность садиться на стулья и туалеты. + Questo modulo ti permette di disabilitare la possibilità di sederti sulle sedie. + モジュールでは椅子に着席するのを無効化できます。 + 이 모듈을 사용하여 의자에 앉을 수 있는 기능을 비활성화할 수 있습니다. + 此模块可以让你开关在椅子上坐下的能力。 + 此模塊可以讓你開關在椅子上坐下的能力。 + Bu modül, sandalyelere oturma özelliğini devre dışı bırakmanıza izin verir. + + + diff --git a/addons/slideshow/CfgEventHandlers.hpp b/addons/slideshow/CfgEventHandlers.hpp index be284a9d70..8e27a9f14f 100644 --- a/addons/slideshow/CfgEventHandlers.hpp +++ b/addons/slideshow/CfgEventHandlers.hpp @@ -1,12 +1,12 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/slideshow/CfgVehicles.hpp b/addons/slideshow/CfgVehicles.hpp index 6c11ba866c..c7c0687913 100644 --- a/addons/slideshow/CfgVehicles.hpp +++ b/addons/slideshow/CfgVehicles.hpp @@ -47,6 +47,12 @@ class CfgVehicles { typeName = "NUMBER"; defaultValue = 0; }; + class Selection { + displayName = CSTRING(Selection_DisplayName); + description = CSTRING(Selection_Description); + typeName = "NUMBER"; + defaultValue = 0; + }; }; class ModuleDescription { description = CSTRING(Description); diff --git a/addons/slideshow/GUI.hpp b/addons/slideshow/GUI.hpp new file mode 100644 index 0000000000..87b42aa570 --- /dev/null +++ b/addons/slideshow/GUI.hpp @@ -0,0 +1,35 @@ +class GVAR(mapDisplay) { + onLoad = QUOTE(call FUNC(mapImage_init)); + idd = -1; + class Controls {}; +}; + +class ctrlMap; +class GVAR(mapNormal): ctrlMap { + maxSatelliteAlpha = 0; + sizeExLabel = 0; + sizeExUnits = 0; + sizeExInfo = 0; + sizeExLevel = 0; + sizeEx = 0; + scaleMin = 0.005; + scaleMax = 10; + showCountourInterval = 0; + drawShaded = 0.15; + shadedSea = 0.15; + showMarkers = 0; +}; +class GVAR(mapTopo): GVAR(mapNormal) { + drawShaded = 0.35; + shadedSea = 0.35; + sizeExLevel = 0.02; + colorCountlines[] = {0.647059, 0.533333, 0.286275, 0.5}; + colorMainCountlines[] = {0.858824, 0, 0,0.5}; + ptsPerSquareObj = 2000; // don't show buildings +}; +class GVAR(mapSat): GVAR(mapNormal) { + // ref https://feedback.bistudio.com/T170918 - may have problems loading sat textures + maxSatelliteAlpha = 0.95; + colorForest[] = {0, 1, 0, 0}; + colorForestBorder[] = {0, 1, 0, 0}; +}; diff --git a/addons/slideshow/README.md b/addons/slideshow/README.md index 627e1fe660..e2161374a9 100644 --- a/addons/slideshow/README.md +++ b/addons/slideshow/README.md @@ -2,10 +2,3 @@ ace_slideshow =============== Adds ability to have slide-shows on them and control them with a controller (another object). - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Jonpas](https://github.com/jonpas) diff --git a/addons/slideshow/XEH_PREP.hpp b/addons/slideshow/XEH_PREP.hpp index ca31404b53..52c5cb4217 100644 --- a/addons/slideshow/XEH_PREP.hpp +++ b/addons/slideshow/XEH_PREP.hpp @@ -1,5 +1,6 @@ - PREP(addSlideActions); PREP(autoTransition); PREP(createSlideshow); +PREP(mapImage); +PREP(mapImage_init); PREP(moduleInit); diff --git a/addons/slideshow/config.cpp b/addons/slideshow/config.cpp index 6149ad71d7..8b375b7f74 100644 --- a/addons/slideshow/config.cpp +++ b/addons/slideshow/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; + units[] = {QGVAR(module)}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; @@ -16,3 +16,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" +#include "GUI.hpp" diff --git a/addons/slideshow/functions/fnc_addSlideActions.sqf b/addons/slideshow/functions/fnc_addSlideActions.sqf index 6acd304d32..409c724943 100644 --- a/addons/slideshow/functions/fnc_addSlideActions.sqf +++ b/addons/slideshow/functions/fnc_addSlideActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Adds controller slide actions. @@ -9,6 +9,7 @@ * 2: Names * 3: Controller * 4: Current Slideshow + * 5: Texture Selection (default: 0) * * Return Value: * List of actions @@ -19,7 +20,7 @@ * Public: No */ -params ["_objects", "_images", "_names", "_controller", "_currentSlideshow"]; +params ["_objects", "_images", "_names", "_controller", "_currentSlideshow", ["_selection", 0]]; private _actions = []; { @@ -30,14 +31,15 @@ private _actions = []; _names select _forEachIndex, "", { - (_this select 2) params ["_objects", "_image"]; + (_this select 2) params ["_objects", "_image", "_currentSlideshow", "_selection"]; { - _x setObjectTextureGlobal [0, _image] - } count _objects; + _x setObjectTextureGlobal [_selection, _image] + } forEach _objects; + [QGVAR(slideChanged), [_image, _currentSlideshow]] call CBA_fnc_localEvent; }, {true}, {}, - [_objects, _x] + [_objects, _x, _currentSlideshow, _selection] ] call EFUNC(interact_menu,createAction), [], _controller diff --git a/addons/slideshow/functions/fnc_autoTransition.sqf b/addons/slideshow/functions/fnc_autoTransition.sqf index 50e8b1d13d..6a18a041c4 100644 --- a/addons/slideshow/functions/fnc_autoTransition.sqf +++ b/addons/slideshow/functions/fnc_autoTransition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Handles automatic slide transitions using waitAndExecute in a PFH-like manner resulting in no performance loss. @@ -7,18 +7,20 @@ * 0: Objects * 1: Image Paths * 2: State Variable Name - * 3: Duration (0 disables automatic transitions) + * 3: Current Slideshow + * 4: Duration (0 disables automatic transitions) + * 5: Texture Selection * * Return Value: * None * * Example: - * [objects, images, "ace_slideshow_slideshow1", duration] call ace_slideshow_fnc_autoTransition + * [objects, images, "ace_slideshow_slideshow1", duration, selection] call ace_slideshow_fnc_autoTransition * * Public: No */ -params ["_objects", "_images", "_varString", "_duration"]; +params ["_objects", "_images", "_varString", "_currentSlideshow", "_duration", "_selection"]; // Get current slide number of this slideshow private _currentSlide = missionNamespace getVariable [_varString, 0]; @@ -29,11 +31,15 @@ _currentSlide = (_currentSlide + 1) mod (count _images); // Save slide back into global variable (PFH's local variables do not persist through PFH run) missionNamespace setVariable [_varString, _currentSlide]; +private _image = _images select _currentSlide; + // Set slide { - _x setObjectTextureGlobal [0, _images select _currentSlide]; -} count _objects; + _x setObjectTextureGlobal [_selection, _image]; +} forEach _objects; + +[QGVAR(slideChanged), [_image, _currentSlideshow]] call CBA_fnc_localEvent; // Log current slide and execute Next slide -TRACE_4("Auto-transition",_images select _currentSlide,_currentSlide,count _images,_duration); -[FUNC(autoTransition), [_objects, _images, _varString, _duration], _duration] call CBA_fnc_waitAndExecute; +TRACE_4("Auto-transition",_image,_currentSlide,count _images,_duration); +[FUNC(autoTransition), [_objects, _images, _varString, _currentSlideshow, _duration, _selection], _duration] call CBA_fnc_waitAndExecute; diff --git a/addons/slideshow/functions/fnc_createSlideshow.sqf b/addons/slideshow/functions/fnc_createSlideshow.sqf index 965a823941..c24d302346 100644 --- a/addons/slideshow/functions/fnc_createSlideshow.sqf +++ b/addons/slideshow/functions/fnc_createSlideshow.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas, DaC * Prepares necessary variables and default image. @@ -8,11 +8,12 @@ * 1: Controller Objects * 2: Image Paths * 3: Action Names - * 4: Slide Duration (0 disables automatic transitions) + * 4: Slide Duration, 0 disables automatic transitions * 5: Set Name (default: localized "Slides") + * 6: Texture Selection (default: 0) * * Return Value: - * None + * Slideshow ID * * Example: * [[object1, object2, object3], [controller1], ["images\image1.paa", "images\image2.paa"], ["Action1", "Action2"], 5, "My Slides"] call ace_slideshow_fnc_createSlideshow @@ -26,7 +27,8 @@ params [ ["_images", [], [[]] ], ["_names", [], [[]] ], ["_duration", 0, [0]], - ["_setName", localize LSTRING(Interaction), [""]] + ["_setName", localize LSTRING(Interaction), [""]], + ["_selection", 0, [0]] ]; // Verify data @@ -47,8 +49,8 @@ TRACE_5("Information",_objects,_controllers,_images,_names,_setName); if (isServer) then { // Default images on whiteboards (first image) { - _x setObjectTextureGlobal [0, _images select 0]; - } count _objects; + _x setObjectTextureGlobal [_selection, _images select 0]; + } forEach _objects; }; // Number of slideshows (multiple modules support) @@ -59,11 +61,16 @@ private _currentSlideshow = GVAR(slideshows); // Local variable in case GVAR get // If interaction menu module is not present, set default duration value if !(["ace_interact_menu"] call EFUNC(common,isModLoaded)) then { _duration = NOINTERACTMENU_DURATION; - INFO_1("Interaction Menu module not present, defaulting duration value to %1",_duration); + INFO_1("Interaction Menu module not present,defaulting duration value to %1",_duration); }; // Add interactions if automatic transitions are disabled, else setup automatic transitions 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); @@ -77,13 +84,12 @@ if (_duration == 0) then { {}, {true}, {(_this select 2) call FUNC(addSlideActions)}, - [_objects, _images, _names, _x, _currentSlideshow], + [_objects, _images, _names, _x, _currentSlideshow, _selection], [0, 0, 0], 2 ] call EFUNC(interact_menu,createAction); [_x, 0, ["ACE_MainActions"], _slidesAction] call EFUNC(interact_menu,addActionToObject); - nil - } count _controllers; + } forEach _controllers; } else { if !(isServer) exitWith {}; @@ -95,5 +101,7 @@ if (_duration == 0) then { missionNamespace setVariable [_varString, 0]; // Automatic transitions handler - [FUNC(autoTransition), [_objects, _images, _varString, _duration], _duration] call CBA_fnc_waitAndExecute; + [FUNC(autoTransition), [_objects, _images, _varString, _currentSlideshow, _duration, _selection], _duration] call CBA_fnc_waitAndExecute; }; + +_currentSlideshow diff --git a/addons/slideshow/functions/fnc_mapImage.sqf b/addons/slideshow/functions/fnc_mapImage.sqf new file mode 100644 index 0000000000..8703da1256 --- /dev/null +++ b/addons/slideshow/functions/fnc_mapImage.sqf @@ -0,0 +1,67 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Returns a procedural texture that will display a custom map. + * Needs to be run on all machines. + * + * Arguments: + * 0: Position (default: center of map) + * 1: Scale (1.0 fits entire map in x-dimension) (default: 1.25) + * 2: Markers (default: []) + * - 0: Position 2D/3D (default: [0, 0, 0]) + * - 1: Text (default: "") + * - 2: Marker Type or Icon Name (default: "mil_dot") + * - 3: Color (default: [1, 0, 0, 1]) + * 3: Map Type (0: Normal, 1: Topographic, 2: Satellite) or any custom class (even mission config) (default: 0) + * 4: Code to run on init (will be passed [_map, _display, _displayID]) (default: {}) + * 5: Resolution (default: 4096) + * + * Return Value: + * Procedural Texture + * + * Example: + * [] call ace_slideshow_fnc_mapImage + * [getPos player, 0.3, [], 1] call ace_slideshow_fnc_mapImage + * [[5000, 5000], 0.5, [[getpos player, "obj"]], 2, {}] call ace_slideshow_fnc_mapImage + * + * Public: Yes + */ + +params [ + ["_pos", [worldSize / 2, worldSize / 2], [[]]], + ["_scale", 1.25, [0]], + ["_markers", [], [[]]], + ["_mapType", 0, [0, ""]], // 2.14 may allow config type as well + ["_userCode", {}, [{}]], + ["_resolution", 4096, [0]] +]; +TRACE_6("",_pos,_scale,count _markers,_mapType,_userCode isEqualTo {},_resolution); + +_markers = _markers apply { // convert marker array to draw command + _x params [["_xPos", [0,0,0], [[]]], ["_xText", "", [""]], ["_xIcon", "mil_dot", [""]], ["_xColor", [1,0,0,1], [[]]]]; + private _size = 0; + private _config = configFile >> "CfgMarkers" >> _xIcon; + if (isClass _config) then { + _size = 0.5 * getNumber (_config >> "size"); + _xIcon = getText (_config >> "icon"); // don't swap order + } else { + if (_xIcon != "") then { _size = 16 }; // could be a file or a CfgVehicleIcons class + }; + [_xIcon, _xColor, _xPos, _size, _size, 0, _xText, 0, 0.08] +}; + +if (_mapType isEqualType 0) then { + _mapType = [QGVAR(mapNormal), QGVAR(mapTopo), QGVAR(mapSat)] select _mapType; +}; +if ((!isClass (configFile >> _mapType)) && {(!isClass (missionConfigFile >> _mapType))}) then { + ERROR_1("bad map type %1",_mapType); +}; + +// set data in hash +if (isNil QGVAR(mapData)) then { GVAR(mapData) = createHashMap; }; +private _displayID = format ["ace_s_%1", count GVAR(mapData)]; +TRACE_1("setting hash",_displayID); +GVAR(mapData) set [_displayID, [_pos, _scale, _markers, _mapType, _userCode]]; + +// return texture name +format ['#(rgb,%1,%1,1)ui("%2","%3")', _resolution, QGVAR(mapDisplay), _displayID] diff --git a/addons/slideshow/functions/fnc_mapImage_init.sqf b/addons/slideshow/functions/fnc_mapImage_init.sqf new file mode 100644 index 0000000000..3fb6e4c7f8 --- /dev/null +++ b/addons/slideshow/functions/fnc_mapImage_init.sqf @@ -0,0 +1,67 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Initializes the map texture display. + * + * Arguments: + * 0: Display (default: displayNull) + * 1: Disply ID (default: "") + * + * Return Value: + * None + * + * Example: + * [findDisplay "ace_s_0"] call ace_slideshow_fnc_mapImage_init + * + * Public: No + */ + +params [["_display", displayNull], ["_displayID", ""]]; // only one of these will be valid +// On primary call from the display's onload we will only have the actual display +if (_displayID == "") then { _displayID = displayUniqueName _display; }; +// On the delayed call (due to hash missing) we will only have the displayID +if (isNull _display) then { _display = findDisplay _displayID; }; +TRACE_2("mapImage_init",_display,_displayID); + +// seems like display can sometimes not exist even though it does +// it won't be updated correctly, seems to depend on resolution, seems to be fixed mostly by the 2nd update run +if (isNull findDisplay _displayID) then { WARNING_1("possible problem with texture %1",_displayID); }; + +// make sure data exists in hash, there can be a race if server broadcasts texture before client can finish init.sqf +if (isNil QGVAR(mapData) || {!(_displayID in GVAR(mapData))}) exitWith { + WARNING_1("texture %1 has no data in hash",_displayID); + if (!isNull (param [0, displayNull])) then { // not a retry, checking using value from _this + [FUNC(mapImage_init), [displayNull, _displayID], 5] call CBA_fnc_waitAndExecute; + }; +}; + +(GVAR(mapData) get _displayID) params ["_posCenter", "_scale", "_markers", "_mapType", "_userCode"]; +TRACE_4("data",_posCenter,_scale,count _markers,_mapType); + +private _map = _display ctrlCreate [_mapType, -1]; +_map ctrlSetPosition [0, 0, 1, 1]; +_map ctrlCommit 0; +_map ctrlMapSetPosition []; + +_map ctrlMapAnimAdd [0, _scale, _posCenter]; +ctrlMapAnimCommit _map; + +[_map, _display, _displayID] call _userCode; + +// add drawEH to draw markers next update (they will get drawn 3 times total) +_map setVariable ["markers", _markers]; +_map ctrlAddEventHandler ["Draw", { + params ["_map"]; + private _markers = _map getVariable ["markers", []]; + TRACE_2("drawing markers",_map,count _markers); + { _map drawIcon _x } forEach _markers; +}]; + +private _update = { + private _display = findDisplay _this; + if (isNull _display) exitWith {}; + TRACE_2("updating",_display,displayUniqueName _display); + displayUpdate _display; +}; +[_update, _displayID] call CBA_fnc_execNextFrame; // update after a frame so the map anim has time to take effect +[_update, _displayID, 2] call CBA_fnc_waitAndExecute; // update a bit later so textures hopefully have time to load diff --git a/addons/slideshow/functions/fnc_moduleInit.sqf b/addons/slideshow/functions/fnc_moduleInit.sqf index b3cbf8bf43..7e6a78dc95 100644 --- a/addons/slideshow/functions/fnc_moduleInit.sqf +++ b/addons/slideshow/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Initializes the module. @@ -32,14 +32,14 @@ private _images = [_logic getVariable ["Images", ""], false, false] call EFUNC(c private _names = [_logic getVariable ["Names", ""], false, false] call EFUNC(common,parseList); private _setName = _logic getVariable ["SetName", ""]; private _duration = _logic getVariable ["Duration", 0]; +private _selection = _logic getVariable ["Selection", 0]; // Objects synced to the module { _objects pushBack _x; - nil -} count (synchronizedObjects _logic); +} forEach (synchronizedObjects _logic); // Prepare with actions -[_objects, _controllers, _images, _names, _duration, _setName] call FUNC(createSlideshow); +[_objects, _controllers, _images, _names, _duration, _setName, _selection] 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/functions/script_component.hpp b/addons/slideshow/functions/script_component.hpp deleted file mode 100644 index c4c2d6d966..0000000000 --- a/addons/slideshow/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\slideshow\script_component.hpp" diff --git a/addons/slideshow/stringtable.xml b/addons/slideshow/stringtable.xml index 31157155d5..358e3ed3a1 100644 --- a/addons/slideshow/stringtable.xml +++ b/addons/slideshow/stringtable.xml @@ -11,27 +11,28 @@ Слайд-шоу Prezentace Presentación de diapositivas - Mostra Diapositive + Presentazione Diapositive スライドショー 슬라이드 쇼 幻燈片 幻灯片 + Slayt This module allows you to set up slide-shows on different objects. One module per image list. Only objects with hiddenSelection 0 are supported. Dieses Modul erlaubt eine Diavorführung auf unterschiedlichen Objekten. Ein Modul, eine Bilderliste. Nur Objekte mit "hiddenSelection 0" werden unterstützt. - Ce module permet d'afficher des diaporamas sur différents objets. Un module par liste d'image. Seul les objets avec le paramètre "HiddenSelection 0" sont supportés + Ce module permet d'afficher des diaporamas sur différents objets. Un module par liste d'images.\nSeuls les objets avec le paramètre `HiddenSelection 0` sont supportés. Ten moduł pozwala skonfigurować pokaz slajdów na różnych obiektach. Jeden moduł na jedną liste slajdów. Tylko obiekty z hiddenSelection 0 są wspierane. Ez a modul lehetővé teszi a különböző objektumokon való vetítést. Egy modul/képlista. Csak "hiddenSelection 0"-t tartalmazó objektumok felelnek meg. Este módulo permite que você monte apresentações de slides em diferentes objetos. Um módulo por lista de imagem. Somente objetos com hiddenSelection 0 são suportados. Этот модуль позволяет вам устроить слайд-шоу на различных объектах. Один модуль на один список изображений. Поддерживаются только объекты с hiddenSelection 0. Este módulo permite configurar una presentación de diapositivas en diferentes objetos. Un módulo por lista de imágenes. Sólo son soportados objetos con hiddenSelection 0. Tento modul umožňuje nastavit prezentaci na různé objekty. Jeden modul na seznam s obrázky. Podporované jsou pouze objekty s hiddenSelection 0. - Questo modulo ti permette di creare una presentazione con diapositive su vari oggetti. Un modulo per lista immagini. Solo oggetti con hiddenSelection 0 sono supportati. + Questo modulo ti permette di creare una presentazione con diapositive su vari oggetti. Un modulo per ogni lista immagini. Solo oggetti con hiddenSelection 0 sono supportati. さまざまなオブジェクトへスライドショーを設定することができます。1つのモジュールは各画像リストになっています。オブジェクトが hiddenSelection 0へ対応している必要があります。 - 이 모듈은 다른 물체에 대해 슬라이드 쇼를 놓을 수 있게 해줍니다. 한 모듈당 한 이미지목록만 가능합니다. 또한 물체가 hiddenSelection 0 를 지원해야만합니다. + 이 모듈은 다른 물체에 대해 슬라이드 쇼를 놓을 수 있게 해줍니다. 한 모듈 당 한 이미지 목록만 가능합니다. 또한 hiddenSelection 0가 있는 물체만 지원됩니다. 此模塊可讓圖片以幻燈片的形式顯示在物件上,每個模塊都能設定一串幻燈片清單,被設定的物件不能有隱藏部位(hiddenSelection) - 此模块可让图片以幻灯片的形式显示在物件上,每个模块都能设定一串幻灯片清单,被设定的物件不能有隐藏部位(hiddenSelection) + 此模块可让图片以幻灯片的形式显示在物体上,每个模块都能设定一串幻灯片清单,被设定的物件不能有隐藏部位(hiddenSelection) Objects @@ -47,44 +48,46 @@ オブジェクト 물체 物件 - 物件 + 物体 + Objeler Object names (can also be synchronized objects) slide-show will be displayed on, separated by commas if multiple. Objektnamen (können auch synchronisierte Objekte sein) auf denen die Diavorführung abgepielt wird. Werden ggf. durch Kommata getrennt. - Nom d'objets (peuvent aussi être des objets synchronisés) sur lesquels les diaporamas vont être affichées, séparation par virgule si plusieurs. + Noms des objets (pouvant aussi être des objets synchronisés) sur lesquels le diaporama sera affiché, séparés par des virgules s'ils sont plusieurs. Nazwy obiektów (mogą to też być zsynchronizowane obiekty) na których pokaz slajdów zostanie pokazany, oddzielony przecinkiem jeżeli jest ich więcej niż 1. Objektum nevek (szinkronizált is lehet) amik a vetítésen megjelennek, több darab esetén vesszővel elválasztva. Nomes dos objetos (também podem ser objetos sincronizados) em que a apresentação de slides será mostrada, separado por vírgulas se for mais de um. Имена объектов (так же могут использоваться синхронизированные объекты), на которых будет отображаться слайд-шоу, разделенные запятыми. Los nombres de objetos (también pueden ser objetos sincronizados) de diapositivas se mostrarán en, separados por comas. Jména objektů (lze také použít synchronizované objekty) které se budou zobrazovat v prezentaci, oddělit čárkou pokud jich je více. - Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separato da virgole se più di uno. + Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separati da virgole se più di uno. スライドショーを表示するオブジェクト名 (オブジェクトとの同期も可)。複数ある場合はコンマで区切れます 슬라이드 쇼가 보여질 물체(동기화 되는 물체도 가능합니다) 명칭, 다수의 경우 쉼표로 구분합니다. 物件名稱 (也可使用同步線來設定),幻燈片將會顯示在該物件上,如有多個物件,請以逗號作區隔 - 物件名称 (也可使用同步线来设定),幻灯片将会显示在该物件上,如有多个物件,请以逗号作区隔 + 物体名称(也可使用同步线来设定),幻灯片将会显示在该物件上,如有多个物件,请以逗号作区隔 Controllers Steuereinheit - Contrôleurs + Commandes Kontroler Vezérlők Controles Контроллеры Controladores - Kontrolor + Kontrolní objekty Controllori コントローラ 조종 장치 控制器 控制器 + Kontroller Controller object names, separated by commas if multiple. Objekte die als Steuereinheit fungieren. Werden ggf. durch Kommata getrennt. - Noms de contrôleur d'objets, séparation par virgule si plusieurs + Noms des objets servant d'unité de commande, séparés par des virgules s'ils sont plusieurs. Nazwa obiektu - kontrolera, oddzielona przecinkami jeżeli jest ich więcej niż 1. Vezérlő objektum nevek, vesszővel elválasztva több darab esetén. Nome dos objetos de controle, separado por vírgula se mais de um. @@ -94,7 +97,8 @@ コントローラに指定するオブジェクト名を記入し、複数ある場合はコンマで区切れます。 조종 장치 물체 명칭, 다수의 경우 쉼표로 구분됩니다. 指定是控制器的物件名稱,如有多個物件,請以逗號作區隔 - 指定是控制器的物件名称,如有多个物件,请以逗号作区隔 + 指定是控制器的物体名称,如有多个物件,请以逗号作区隔 + Jména kontrolních objektů, v případě více oddělená čárkami. Images @@ -111,22 +115,23 @@ 사진 圖片 图片 + Resimler List of images that will be used for the slide-show, separated by commas, with full path correctly formatted (eg. images\image.paa). Eine Liste von Bildern, die bei der Vorführung verwendet werden. (Durch Kommata getrennt, mit vollem Pfad angegeben (z.B Bilder\bild.paa)). - Liste d'images qui seront utilisées dans des diaporamas, séparation par virgule, avec le chemin d'accès complet et formaté correctement (ie. images\image.paa) + Liste des images qui seront utilisées dans le diaporama, séparées par des virgules, avec le chemin complet correctement formaté (p. ex. images\image.paa). Lista obrazów, które zostaną użyte do pokazu slajdów, oddzielone przecinkiem, z poprawnym pełnym formatem ścieżki do obrazka (np. slajdy\obrazek.paa). A képek listája amit a vetítés használni fog, vesszővel elválasztva, megfelelően formázott teljes útvonallal (pl. képek\kép.paa) Lista das imagens que serão utilizadas na apresentação de slides, separadas por vírgula, com o caminho completo corretamente formatado (ex: imagens\imagem.paa). Список изображений, которые будут использованы для слайд-шоу, разделенные запятыми, с полными путями в правильном формате (например, images\image.paa). Lista de imágenes que se utilizarán para la presentación de diapositivas, separadas por comas, con la ruta completa en formato correcto (ej. imágenes\image.paa). Seznam obrázků které budou použity v prezentaci, oddělené čárkami, s kompletní cestou ve správném formátu (např. image\image.paa). - Lista di immagini che verranno usate durante la presentazione, separati da virgole, con il formato completo del percorso (es. images\image.paa) - 完全なパスでスライドショーに使う画像一覧を入力してください。コンマで区別できます。(例: images\image.paa) + Lista di immagini che verranno usate durante la presentazione, separate da virgole, con percorso completo formattato correttamente (es. images\image.paa) + スライド ショーに使用される画像のリスト。完全パスで入力してください。コンマで区切ります。(例: images\image.paa) 슬라이드 쇼에 쓰일 사진목록입니다, 쉼표로 구분됩니다, 경로설정을 정확히 하십시요. (예: 사진\사진.ppa) 要做為幻燈片的圖片清單,每個圖片請已逗號區隔,並輸入完整路徑位址 (例如:images\image.paa) - 要做为幻灯片的图片清单,每个图片请已逗号区隔,并输入完整路径位址 (例如:images\image.paa) + 要做为幻灯片的图片清单,每个图片请已逗号区隔,并输入完整路径位址(例如:images\image.paa) Interaction Names @@ -146,22 +151,23 @@ List of names that will be used for interaction entries, separated by commas, in order of images. - Liste de noms qui seront utilisés pour des interactions, séparation par virgule, dans l'ordre des images + Liste des noms qui seront utilisés pour les entrées d'interaction, séparés par des virgules, dans l'ordre des images. Lista nazw, które zostaną użyte do nazwania wpisów interakcji, oddzielone przecinkiem, w kolejności obrazów. Olyan nevek listája, melyek interakciós célra kellenek, vesszővel elválasztva, kép szerinti sorrendben. Lista dos nomes que serão usados para entradas de interação, separados por vírgulas, na ordem das imagens. Список имен, которые будут использованы при взаимодействии, разделенные запятыми, в порядке следования изображений. Lista de nombres que se utilizarán para las entradas de interacción, separados por comas, en el orden de las imágenes. - Lista di nomi che verranno usati per per le interazioni, separati da virgole, in ordine per immagini. + Lista di nomi che verranno usati per le interazioni, separati da virgole, nell'ordine delle immagini. Liste aller Namen, die für Interaktionseinträge genutzt werden. Mit Kommata getrennt, in Reihenfolge der Bilder. 画像を操作できるインタラクション エントリ名の一覧を入力してください。コンマで区切り複数を指定できます。 - 상호작용 메세지에 쓰일 명칭입니다, 쉼표로 구분합니다, 이미지의 순서입니다. + 상호작용 메시지에 쓰일 명칭입니다, 쉼표로 구분합니다, 이미지의 순서입니다. 設定互動鍵切換圖片時的按鈕名稱,多個按鈕請以逗號做區隔,有多少圖片就輸入多少個按鈕,以利切換圖片 设定互动键切换图片时的按钮名称,多个按钮请以逗号做区隔,有多少图片就输入多少个按钮,以利切换图片 + Seznam jmen které budou použity pro interakce, oddělené čárkami, v pořadí obrázků. Set Name - Setze Namen + Name der Diavorführung Ustaw nazwę 名前設定 Définir le nom @@ -170,22 +176,28 @@ 设定名称 이름 설정 Установить имя + Definir Nome + Jméno setu + Definir nombre Name that will be used for main interaction entry (to distinguish multiple slideshows). Default: "Slides" Name der für den Hauptinteraktionseintrag benutzt wird (um mehrere Diavorführungen voneinander zu trennen). Nazwa, która będzie użyta w głównym menu interakcji (w celu rozróżnienia różnych slajdów). Domyślnie: "Slides" - メイン インタラクション エントリで使われる名前を設定します。(複数のスライドショーを区別するため)。標準: "Slides" - Un nom qui sera utilisé pour interagir avec plusieurs diaporamas. Par défaut : "Slides" - Nome che sarà utilizzato per le principali interazioni (per distinguere le multiple diapositive). Predefinito: "Slides" + メイン インタラクション エントリで使われる名前を設定します。(複数のスライドショーを区別するため)。 デフォルト: "Slides" + Nom qui sera utilisé pour l'entrée d'interaction principale (pour distinguer plusieurs diaporamas). Valeur par défaut : "Slides". + Nome che verrà utilizzato per le principali interazioni (per distinguere multiple diapositive). Predefinito: "Slides" 設定該幻燈片的標題名稱 (用來區分多個不同標題的幻燈片) 預設名稱: "幻燈片" - 设定该幻灯片的标题名称 (用来区分多个不同标题的幻灯片) 预设名称: "幻灯片" - 상위 상호작용 이름 (여러개의 슬라이드 쇼를 구분하기 위해 사용됨) 기본: "Slides" + 设定该幻灯片的标题名称(用来区分多个不同标题的幻灯片)预设名称:"幻灯片" + 상위 상호작용 이름 (여러 개의 슬라이드 쇼를 구분하기 위해 사용됨) 기본: "Slides" Имя, которое будет использоваться для основных взаимодействий (для различения нескольких слайдов). По умолчанию: «Slides» + Nome que será usado para a entrada principal de interação (para separar vários slideshows). Padrão: "Slides" + Jméno, které bude použito pro hlavní interakci (pro rozlišení více prezentací). Standard: Snímky + Nombre usado para la entrada principal de interacción (para distinguir entre diferentes diapositivas). Por defecto: "Diapositivas" Slide Duration - Durée d'un diaporama + Durée de la diapositive Czas trwania slajdów Dia időtartam Duração do Slide @@ -194,30 +206,56 @@ Doba trvání snímku Durata Diapositiva Länge der Diavorführung pro Bild - スライドの持続時間 - 슬라이드 지속시간 + スライドの継続時間 + 슬라이드 지속 시간 幻燈片顯示時間 幻灯片显示时间 Duration of each slide. Default: 0 (Automatic Transitions Disabled) - Durée de chaque diaporama. Défaut: 0 (transition automatique désactivée) + Temps d'affichage de chaque diapositive. Valeur par défaut : 0 (transition automatique désactivée). Czas trwania poszczególnych slajdów. Domyślnie: 0 (Automatyczne przejścia wyłączone) A diák időtartama. Alapértelmezett: 0 (Automatikus váltás letiltva) Duração de cada slide. Padrão: 0 (Transição automática desabilitada) - Длительность каждого слайда. По-умолчанию: 0 (автоматический переход отключен) + Длительность каждого слайда. По умолчанию: 0 (автоматический переход отключен) Duración de cada diapositiva. Por defecto: 0 (Transiciones automáticas desactivadas) Doba trvání každého snímku. Výchozí: 0 (Automatické posouvání je zakázáno) - Durata di ogni diapositiva. Default: 0 (Transizioni Automatiche Disabilitate) + Durata di ogni diapositiva. Predefinito: 0 (Transizioni Automatiche Disabilitate) Länge der Diavorführung pro Bild. Standard: 0 (Automatischer Wechsel deaktiviert) - 各スライドの持続時間。標準:0 (自動的な切り替えは無効) - 매 슬라이드의 지속시간. 기본설정: 0 (자동 전환 비활성화) + 各スライドの継続時間。 デフォルト: 0 (自動的な切り替えは無効) + 매 슬라이드의 지속 시간. 기본설정: 0 (자동 전환 비활성화) 每張幻燈片顯示的時間。 預設:0 (自動換圖已禁用) - 每张幻灯片显示的时间。 预设:0 (自动换图已禁用) + 每张幻灯片显示的时间。 预设:0(自动换图已禁用) + + + Texture Selection + 纹理选择 + 텍스쳐 선택 + 텍스쳐 선택 + Auswahl der Textur + Selezione della texture + Wybór Tekstury + テクスチャの選択 + Выбор текстуры + Selección de texturas + Sélection de texture + + + Object texture selection. Default: 0 + 物体纹理选择(默认:0) + 개체 텍스처 선택(기본값: 0) + 물체의 텍스쳐를 선택합니다. 기본: 0 + Auswahl der Objekttextur. Standard: 0 + Selezione della texture dell'oggetto. Predefinito: 0 + Wybór tekstury obiektu. Domyślnie: 0 + オブジェクトテクスチャの選択。 デフォルト: 0 + Выбор текстуры объекта. По умолчанию: 0 + Selección de textura de objeto. Defecto: 0 + Sélection de la texture de l'objet. Valeur par défaut : 0 Slides - Diapo + Diapositives Slajdy Diák Slides @@ -230,6 +268,7 @@ 슬라이드 幻燈片 幻灯片 + Slaytlar diff --git a/addons/smallarms/CfgMagazines.hpp b/addons/smallarms/CfgMagazines.hpp index ac55a86f6b..cb3a3fca1f 100644 --- a/addons/smallarms/CfgMagazines.hpp +++ b/addons/smallarms/CfgMagazines.hpp @@ -4,125 +4,76 @@ class CfgMagazines { // Magazine updates: // 1. Update all magazines with tracer mix to use 1 in 5 mix. Full tracer mags should not be changed! // 2. Remove tracers at bottom of magazine. - // 3. Do string updates. // 6.5mm ////////////////////////////////////////// - class 30Rnd_65x39_caseless_mag : CA_Magazine { // MX!! - displayname = "6.5mm 30Rnd Mag"; - displaynameshort = "6.5mm"; - + class 30Rnd_65x39_caseless_mag: CA_Magazine { // MX!! tracersEvery = 0; lastRoundsTracer = 0; }; - class 30Rnd_65x39_caseless_mag_Tracer : 30Rnd_65x39_caseless_mag { // MX!! - displayname = "6.5mm 30Rnd Tracer Mag"; - displaynameshort = "6.5mm Tracer"; - }; - - class 30Rnd_65x39_caseless_green : 30Rnd_65x39_caseless_mag { // Katiba!! - displayname = "6.5mm 30Rnd Mag"; - displaynameshort = "6.5mm"; - + class 30Rnd_65x39_caseless_green: 30Rnd_65x39_caseless_mag { // Katiba!! tracersEvery = 0; lastRoundsTracer = 0; }; - class 30Rnd_65x39_caseless_green_Tracer : 30Rnd_65x39_caseless_green { // Katiba!! - displayname = "6.5mm 30Rnd Tracer Magazine"; - displaynameshort = "6.5mm Tracer"; - }; - - class 100Rnd_65x39_caseless_mag : CA_Magazine { - displayname = "6.5mm 100Rnd Mag"; - displaynameshort = "6.5mm"; - + class 100Rnd_65x39_caseless_mag: CA_Magazine { // Katiba!! tracersEvery = 5; lastRoundsTracer = 3; }; - class 100Rnd_65x39_caseless_mag_Tracer : 100Rnd_65x39_caseless_mag { - displayname = "6.5mm 100Rnd Tracer Mag"; - displaynameshort = "6.5mm Tracer"; - }; - - class 200Rnd_65x39_cased_Box : 100Rnd_65x39_caseless_mag { - displayname = "6.5mm 200Rnd Box"; - displaynameshort = "6.5mm"; - + class 200Rnd_65x39_cased_Box: 100Rnd_65x39_caseless_mag { tracersEvery = 5; lastRoundsTracer = 3; }; - class 200Rnd_65x39_cased_Box_Tracer: 200Rnd_65x39_cased_Box { - displayname = "6.5mm 200Rnd Tracer Box"; - displaynameshort = "6.5mm Tracer"; - }; // 7.62mm ////////////////////////////////////////// - class 20Rnd_762x51_Mag: CA_Magazine { - displayname = "7.62mm 20Rnd Mag"; - displaynameshort = "7.62mm"; - }; - - class 150Rnd_762x51_Box : CA_Magazine { - displayname = "7.62mm 150Rnd Box"; - + class 150Rnd_762x51_Box: CA_Magazine { tracersEvery = 5; lastRoundsTracer = 3; }; - class 150Rnd_762x51_Box_Tracer : 150Rnd_762x51_Box { - displayname = "7.62mm 150Rnd Tracer Box"; - }; - - // Anti-materiel /////////////////////////////// - - class 7Rnd_408_Mag: CA_Magazine { - displayname = ".408 7Rnd Mag"; - }; - - class 5Rnd_127x108_Mag: CA_Magazine { - displayname = "12.7mm 5Rnd Mag"; - }; - // SMG & Pistol //////////////////////////// - class 30Rnd_9x21_Mag : CA_Magazine { - displayname = "9mm 30Rnd Mag"; - displaynameshort = "9mm"; - + class 30Rnd_9x21_Mag: CA_Magazine { lastRoundsTracer = 0; }; class 16Rnd_9x21_Mag: 30Rnd_9x21_Mag { - displayname = "9mm 17Rnd Mag"; - displaynameshort = "9mm"; - + displayname = CSTRING(17Rnd_9x19_Name); count = 17; }; - class 30Rnd_45ACP_Mag_SMG_01 : 30Rnd_9x21_Mag { - displayname = ".45 25Rnd Mag"; + class 30Rnd_45ACP_Mag_SMG_01: 30Rnd_9x21_Mag { + displayname = CSTRING(25Rnd_45_Name); displaynameshort = ".45"; - picture = "\A3\weapons_f\data\ui\M_30Rnd_9x21_CA.paa"; - count = 25; - tracersEvery = 0; lastRoundsTracer = 0; }; - class 9Rnd_45ACP_Mag : 30Rnd_45ACP_Mag_SMG_01 { - displayname = ".45 8Rnd Mag"; - displaynameshort = ".45"; + class 30Rnd_45ACP_Mag_SMG_01_Tracer_Green: 30Rnd_45ACP_Mag_SMG_01 { + displayname = CSTRING(25Rnd_45_Tracer_Green_Name); + }; + class 30Rnd_45ACP_Mag_SMG_01_Tracer_Red: 30Rnd_45ACP_Mag_SMG_01 { + displayname = CSTRING(25Rnd_45_Tracer_Red_Name); + }; + + class 30Rnd_45ACP_Mag_SMG_01_Tracer_Yellow: 30Rnd_45ACP_Mag_SMG_01 { + displayname = CSTRING(25Rnd_45_Tracer_Yellow_Name); + }; + + class 9Rnd_45ACP_Mag: 30Rnd_45ACP_Mag_SMG_01 { + displayname = CSTRING(8Rnd_45_Name); + displaynameshort = ".45"; count = 8; }; - class 30Rnd_45ACP_Mag_SMG_01_Tracer_Green: 30Rnd_45ACP_Mag_SMG_01 { - displayname = ".45 25Rnd Tracer Mag"; + class 11Rnd_45ACP_Mag: CA_Magazine { + displayname = CSTRING(15Rnd_45_Name); + count = 15; }; -}; \ No newline at end of file +}; diff --git a/addons/smallarms/CfgWeapons.hpp b/addons/smallarms/CfgWeapons.hpp index cc7e3cbf2e..7b569d4292 100644 --- a/addons/smallarms/CfgWeapons.hpp +++ b/addons/smallarms/CfgWeapons.hpp @@ -186,21 +186,23 @@ class CfgWeapons { }; }; + class LMG_03_Base_F; + + class LMG_03_F: LMG_03_Base_F { + magazineReloadTime = 0; // Fix for reloading every time weapon is equipped + }; + class LMG_03_Vehicle_F: LMG_03_F { + magazineReloadTime = 5.8; // Should be same as LMG_03_Base_F + }; + // Sniper and anti-materiel rifles ///////////////////////////////// class EBR_base_F: Rifle_Long_Base_F { // EMR/EBR is typically issued semi-auto AFAIK modes[] = {"Single", "single_close_optics1", "single_medium_optics1", "single_far_optics1"}; - cursor = "arifle"; - }; - - class LRR_base_F: Rifle_Long_Base_F { - cursor = "arifle"; }; class GM6_base_F: Rifle_Long_Base_F { - cursor = "arifle"; - // Fuck your balancing, BI. class Single: Mode_SemiAuto { // 250 rpm is probably the limit of the finger on a heavy bullpup trigger like this thing must have. diff --git a/addons/smallarms/README.md b/addons/smallarms/README.md index 0a62e1dbcc..324b8c544a 100644 --- a/addons/smallarms/README.md +++ b/addons/smallarms/README.md @@ -2,11 +2,3 @@ ace_smallarms ============= Tweaks various config values for small arms, improving values like ROF. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/smallarms/stringtable.xml b/addons/smallarms/stringtable.xml new file mode 100644 index 0000000000..0b89a38b0d --- /dev/null +++ b/addons/smallarms/stringtable.xml @@ -0,0 +1,105 @@ + + + + + 9 mm 17Rnd Mag + 9 mm 17 發彈匣 + Mag. 17 balles 9 mm + Cargador de 17 proyectiles de 9 mm + Caricatore 17cp 9mm + 17-nab. mag. 9 mm + Магазин, 17 патр. 9 мм + 17-Schuss-9mm-Magazin + 9 mm, 17ks zásobník + Carregador 17Mun. 9 mm + 9mm 17발 탄창 + 9 mm 17发 弹匣 + 9mm 17Rnd マガジン + 9 mm 17 Merm. Şarjör + + + .45 ACP 25Rnd Mag + 25-nab. mag. .45 ACP + Магазин, 25 патр. .45 ACP + Mag. 25 balles .45 ACP + Cargador de 25 proyectiles de .45 ACP + Caricatore 25cp .45 ACP + 25-Schuss-.45-ACP-Magazin + .45 ACP, 25ks zásobník + .45 ACP 25 Merm. Şarjör + .45 ACP 25Rnd マガジン + .45 ACP 25发 弹匣 + .45 ACP 25발 탄창 + + + .45 ACP 25Rnd Tracers (Green) Mag + 25-nab. mag. .45 ACP (Zielony smugacz) + Магазин, 25 патр. .45 ACP (зелёные трассеры) + Mag. 25 traçantes (Vertes) .45 ACP + Cargador de 25 balas trazadoras (Verde) de .45 ACP + Caricatore 25cp .45 ACP Traccianti (Verdi) + 25-Schuss-.45-ACP-Vermin-Magazin (Leuchtspur Grün) + .45 ACP, 25ks zásobník stopovky (Zelené) + .45 ACP 25 Merm. İzli (Yeşil) Şarjör + .45 ACP 25Rnd トレーサー (緑) マガジン + .45 ACP 25发 弹匣(曳光,绿) + .45 ACP 25발 예광탄 (초록) 탄창 + + + .45 ACP 25Rnd Tracers (Red) Mag + 25-nab. mag. .45 ACP (czerwony smugacz) + Магазин, 25 патр. .45 ACP (красные трассеры) + Mag. 25 traçantes (rouges) .45 ACP + Cargador de 25 balas trazadoras (rojo) de .45 ACP + Caricatore 25cp .45 ACP Traccianti (Rossi) + 25-Schuss-.45-ACP-Vermin-Magazin (Leuchtspur Rot) + .45 ACP, 25ks zásobník stopovky (červené) + .45 ACP 25 Merm. İzli (Kırmızı) Şarjör + .45 ACP 25Rnd トレーサー (赤) マガジン + .45 ACP 25发 弹匣(曳光,红) + .45 ACP 25발 예광탄 (빨강) 탄창 + + + .45 ACP 25Rnd Tracers (Yellow) Mag + 25-nab. mag. .45 ACP (żółty smugacz) + Магазин, 25 патр. .45 ACP (жёлтые трассеры) + Mag. 25 traçantes (jaunes) .45 ACP + Cargador de 25 balas trazadoras (amarillo) de .45 ACP + Caricatore 25cp .45 ACP Traccianti (Gialli) + 25-Schuss-.45-ACP-Vermin-Magazin (Nachlade-Leuchtspur Gelb) + .45 ACP, 25ks zásobník stopovky (žluté) + .45 ACP 25 Merm. İzli (Sarı) Şarjör + .45 ACP 25Rnd トレーサー (黄) マガジン + .45 ACP 25发 弹匣(曳光,黄) + .45 ACP 25발 예광탄 (노랑) 탄창 + + + .45 ACP 8Rnd Mag + 8-nab. mag. .45 ACP + Магазин, 8 патр. .45 ACP + Mag. 8 balles .45 ACP + Cargador de 8 proyectiles de .45 ACP + Caricatore 8cp .45 ACP + 8-Schuss-.45-ACP-Magazin + .45 ACP, 8ks zásobník + .45 ACP 8 Merm. Şarjör + .45 ACP 8Rnd マガジン + .45 ACP 8发 弹匣 + .45 ACP 8발 탄창 + + + .45 ACP 15Rnd Mag + 15-nab. mag. .45 ACP + Магазин, 15 патр. .45 ACP + Mag. 15 balles .45 ACP + Cargador de 15 proyectiles de .45 ACP + Caricatore 15cp .45 ACP + 15-Schuss-.45-ACP-Magazin + .45 ACP, 15ks zásobník + .45 ACP 15 Merm. Şarjör + .45 ACP 15Rnd マガジン + .45 ACP 15发 弹匣 + .45 ACP 15발 탄창 + + + diff --git a/addons/spectator/CfgEventHandlers.hpp b/addons/spectator/CfgEventHandlers.hpp index 7abe7ca4e3..f2b74f1342 100644 --- a/addons/spectator/CfgEventHandlers.hpp +++ b/addons/spectator/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/spectator/README.md b/addons/spectator/README.md index b827bdcc49..18cf2e585d 100644 --- a/addons/spectator/README.md +++ b/addons/spectator/README.md @@ -5,10 +5,5 @@ A flexible spectator framework for mission makers to use. Includes a public API for integration into custom respawn frameworks and a template for use with the vanilla respawn framework. -For more information, see: http://ace3mod.com/wiki/feature/spectator.html +For more information, see: http://ace3.acemod.org/wiki/feature/spectator.html -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [SilentSpike](https://github.com/SilentSpike) diff --git a/addons/spectator/XEH_PREP.hpp b/addons/spectator/XEH_PREP.hpp index ddca0c226c..74e8c8e388 100644 --- a/addons/spectator/XEH_PREP.hpp +++ b/addons/spectator/XEH_PREP.hpp @@ -24,6 +24,7 @@ PREP(ui_handleMouseButtonDblClick); PREP(ui_handleMouseButtonDown); PREP(ui_handleMouseMoving); PREP(ui_handleMouseZChanged); +PREP(ui_handleUnload); PREP(ui_toggleMap); PREP(ui_toggleUI); PREP(ui_updateCamButtons); diff --git a/addons/spectator/XEH_postInit.sqf b/addons/spectator/XEH_postInit.sqf index a02f36ae67..f2a6b64c57 100644 --- a/addons/spectator/XEH_postInit.sqf +++ b/addons/spectator/XEH_postInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -["ace_settingsInitialized", { +["CBA_settingsInitialized", { GVAR(availableModes) = [[0,1,2], [1,2], [0], [1], [2]] select GVAR(restrictModes); GVAR(availableVisions) = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select GVAR(restrictVisions); }] call CBA_fnc_addEventHandler; diff --git a/addons/spectator/XEH_preInit.sqf b/addons/spectator/XEH_preInit.sqf index 1e3d019177..7ef6aadb6f 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // Used by public functions GVAR(availableModes) = [MODE_FREE, MODE_FPS, MODE_FOLLOW]; diff --git a/addons/spectator/config.cpp b/addons/spectator/config.cpp index 359b96135b..a50e3f34ed 100644 --- a/addons/spectator/config.cpp +++ b/addons/spectator/config.cpp @@ -3,12 +3,12 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; + units[] = {QGVAR(virtual)}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"F3 Project","Head","SilentSpike","voiper"}; + authors[] = {"F3 Project","Head","kymckay","voiper"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; diff --git a/addons/spectator/functions/fnc_cam.sqf b/addons/spectator/functions/fnc_cam.sqf index d61fff40c1..d63a3c24a8 100644 --- a/addons/spectator/functions/fnc_cam.sqf +++ b/addons/spectator/functions/fnc_cam.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Handles camera initialisation and destruction * * Arguments: diff --git a/addons/spectator/functions/fnc_cam_prepareTarget.sqf b/addons/spectator/functions/fnc_cam_prepareTarget.sqf index 236924b255..559b7b20db 100644 --- a/addons/spectator/functions/fnc_cam_prepareTarget.sqf +++ b/addons/spectator/functions/fnc_cam_prepareTarget.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Moves the spectator camera to a position relative to the camera focus. * Used for 3PP camera and teleporting, etc. * @@ -40,7 +40,7 @@ if !(isNull _focus) then { private _isMan = _focus isKindOf "Man"; private _height = if !(_isMan) then { (_bbd select 2) / 3 } else { switch (stance _focus) do { case "STAND": {1.4}; case "CROUCH": {0.8}; default {0.4}; }; }; - private _center = if (_isMan) then { AGLToASL (_focus modelToWorldVisual (_focus selectionPosition "Spine3")) } else { AGLToASL (_focus modelToWorldVisual [0,0,_height]) }; + private _center = if (_isMan) then { _focus modelToWorldVisualWorld (_focus selectionPosition "Spine3") } else { _focus modelToWorldVisualWorld [0,0,_height] }; // Set dummy location and rotation private _dummy = GVAR(camDummy); @@ -49,6 +49,6 @@ if !(isNull _focus) then { [_dummy, [GVAR(camYaw), GVAR(camPitch), 0]] call BIS_fnc_setObjectRotation; // Apply location and rotation to camera - GVAR(camera) setPosASL (AGLToASL (_dummy modelToWorldVisual [0, -_distance, 0])); + GVAR(camera) setPosASL (_dummy modelToWorldVisualWorld [0, -_distance, 0]); GVAR(camera) setVectorDirAndUp [vectorDirVisual _dummy, vectorUpVisual _dummy]; }; diff --git a/addons/spectator/functions/fnc_cam_resetTarget.sqf b/addons/spectator/functions/fnc_cam_resetTarget.sqf index 5286d944e3..dd0dd6fc31 100644 --- a/addons/spectator/functions/fnc_cam_resetTarget.sqf +++ b/addons/spectator/functions/fnc_cam_resetTarget.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Removes the current camera interest and detaches dummy target. * * Arguments: diff --git a/addons/spectator/functions/fnc_cam_setCameraMode.sqf b/addons/spectator/functions/fnc_cam_setCameraMode.sqf index 3943823f8a..2b0af6a80b 100644 --- a/addons/spectator/functions/fnc_cam_setCameraMode.sqf +++ b/addons/spectator/functions/fnc_cam_setCameraMode.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to select the camera mode * * Intended to run even if new mode == old mode, as it handles focus diff --git a/addons/spectator/functions/fnc_cam_setTarget.sqf b/addons/spectator/functions/fnc_cam_setTarget.sqf index 4587af8c34..9fbd51a64b 100644 --- a/addons/spectator/functions/fnc_cam_setTarget.sqf +++ b/addons/spectator/functions/fnc_cam_setTarget.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Sets the current camera interest using dummy target. * * Arguments: diff --git a/addons/spectator/functions/fnc_cam_setVisionMode.sqf b/addons/spectator/functions/fnc_cam_setVisionMode.sqf index ccc761934d..5bcf8710b6 100644 --- a/addons/spectator/functions/fnc_cam_setVisionMode.sqf +++ b/addons/spectator/functions/fnc_cam_setVisionMode.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Function used to select the camera vision mode * * Arguments: diff --git a/addons/spectator/functions/fnc_cam_tick.sqf b/addons/spectator/functions/fnc_cam_tick.sqf index 3ec0dbe5e6..1e7e1b9913 100644 --- a/addons/spectator/functions/fnc_cam_tick.sqf +++ b/addons/spectator/functions/fnc_cam_tick.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to perform camera ticks * * Updates camera position in follow mode diff --git a/addons/spectator/functions/fnc_cam_toggleSlow.sqf b/addons/spectator/functions/fnc_cam_toggleSlow.sqf index 47ad2a2106..758598829c 100644 --- a/addons/spectator/functions/fnc_cam_toggleSlow.sqf +++ b/addons/spectator/functions/fnc_cam_toggleSlow.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Function used to set camera slow speed mode * * Arguments: @@ -17,7 +17,7 @@ params ["_slowSpeed"]; -if !(GVAR(camSlow) isEqualTo _slowSpeed) then { +if (GVAR(camSlow) isNotEqualTo _slowSpeed) then { private _camera = GVAR(camera); if (GVAR(camMode) == MODE_FREE) then { diff --git a/addons/spectator/functions/fnc_compat_counter.sqf b/addons/spectator/functions/fnc_compat_counter.sqf index 158bcbd0a5..00bd176732 100644 --- a/addons/spectator/functions/fnc_compat_counter.sqf +++ b/addons/spectator/functions/fnc_compat_counter.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Handles integrating the counter respawn template into the spectator UI * * Should be called from both RscRespawnCounter XEH and spectator init to account for arbitrary order diff --git a/addons/spectator/functions/fnc_compat_spectatorBI.sqf b/addons/spectator/functions/fnc_compat_spectatorBI.sqf index f8817468f1..9bf39ec256 100644 --- a/addons/spectator/functions/fnc_compat_spectatorBI.sqf +++ b/addons/spectator/functions/fnc_compat_spectatorBI.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Handles "compatibility" (i.e. override) for BI spectator respawn types 1, 4 & 5 * * Called from the RscDisplayEGSpectator XEH @@ -18,7 +18,7 @@ */ private _respawn = getMissionConfigValue ["respawn",0]; -if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLower _respawn); }; +if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLowerANSI _respawn); }; if !(_respawn in [1,4,5]) exitWith {}; // Remember to check for side specific templates diff --git a/addons/spectator/functions/fnc_compat_zeus.sqf b/addons/spectator/functions/fnc_compat_zeus.sqf index a8f190bdd4..8cd0b3e464 100644 --- a/addons/spectator/functions/fnc_compat_zeus.sqf +++ b/addons/spectator/functions/fnc_compat_zeus.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Handles compatibility with curator interface (i.e. re-opens spectator if applicable) * * Called from the RscDisplayCurator XEH diff --git a/addons/spectator/functions/fnc_getCameraAttributes.sqf b/addons/spectator/functions/fnc_getCameraAttributes.sqf index d9e53082ed..b4da802276 100644 --- a/addons/spectator/functions/fnc_getCameraAttributes.sqf +++ b/addons/spectator/functions/fnc_getCameraAttributes.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Returns the current spectator camera attributes (see setCameraAttributes for details). * * Arguments: @@ -15,7 +15,7 @@ * Public: Yes */ -if !(isNil QGVAR(camera)) then { +if (!isNil QGVAR(camera)) then { [GVAR(camMode), GVAR(camFocus), GVAR(camVision), getPosATL GVAR(camera), getDirVisual GVAR(camera)] } else { // These values could be pre-set by function diff --git a/addons/spectator/functions/fnc_getGroupIcon.sqf b/addons/spectator/functions/fnc_getGroupIcon.sqf index a408df73dc..64db9e7297 100644 --- a/addons/spectator/functions/fnc_getGroupIcon.sqf +++ b/addons/spectator/functions/fnc_getGroupIcon.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Function used to get an appropriate icon for provided group. Approximate. * * Arguments: diff --git a/addons/spectator/functions/fnc_getTargetEntities.sqf b/addons/spectator/functions/fnc_getTargetEntities.sqf index 162967a1aa..352f3f9c18 100644 --- a/addons/spectator/functions/fnc_getTargetEntities.sqf +++ b/addons/spectator/functions/fnc_getTargetEntities.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Gets the possible entities to spectate based on settings. * Optionally includes dead units for the list and switching. * diff --git a/addons/spectator/functions/fnc_handleFired.sqf b/addons/spectator/functions/fnc_handleFired.sqf index b2efb97a5d..f8683af947 100644 --- a/addons/spectator/functions/fnc_handleFired.sqf +++ b/addons/spectator/functions/fnc_handleFired.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to add projectiles to be drawn when a unit fires * * Arguments: diff --git a/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf b/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf index 267ce5615f..05b780539c 100644 --- a/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf +++ b/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Read spectator settings from module * * Arguments: diff --git a/addons/spectator/functions/fnc_players.sqf b/addons/spectator/functions/fnc_players.sqf index f79c6ce5e9..9dc2fa7d1f 100644 --- a/addons/spectator/functions/fnc_players.sqf +++ b/addons/spectator/functions/fnc_players.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Return all of the player entities who are currently in ace spectator * * Arguments: diff --git a/addons/spectator/functions/fnc_respawnTemplate.sqf b/addons/spectator/functions/fnc_respawnTemplate.sqf index 9cd54ac005..f93ac60ce0 100644 --- a/addons/spectator/functions/fnc_respawnTemplate.sqf +++ b/addons/spectator/functions/fnc_respawnTemplate.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * The ace_spectator respawn template, compatible with types 1,2,3,4 & 5 * * Handles killed and respawned events as per BI's respawn framework: diff --git a/addons/spectator/functions/fnc_setCameraAttributes.sqf b/addons/spectator/functions/fnc_setCameraAttributes.sqf index 2ee5140d80..f33f23c09a 100644 --- a/addons/spectator/functions/fnc_setCameraAttributes.sqf +++ b/addons/spectator/functions/fnc_setCameraAttributes.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Sets the spectator camera attributes as desired. Local effect. * All values are optional and default to no change. * @@ -42,13 +42,13 @@ params [ ]; // Apply if camera exists -if !(isNil QGVAR(camera)) then { +if (!isNil QGVAR(camera)) then { // These functions are smart and handle unavailable inputs - if !(isNil "_focus") then { + if (!isNil "_focus") then { [_focus] call FUNC(setFocus); }; - if !(isNil "_mode") then { + if (!isNil "_mode") then { // If mode not free and no focus, find focus if ((_mode != MODE_FREE) && {isNull GVAR(camFocus)}) then { [true] call FUNC(setFocus); @@ -57,19 +57,19 @@ if !(isNil QGVAR(camera)) then { [_mode] call FUNC(cam_setCameraMode); }; - if !(isNil "_vision") then { + if (!isNil "_vision") then { [_vision] call FUNC(cam_setVisionMode); }; - if !(isNil "_position") then { + if (!isNil "_position") then { GVAR(camera) setPosATL _position; }; - if !(isNil "_direction") then { + if (!isNil "_direction") then { GVAR(camera) setDir _direction; }; } else { - if !(isNil "_focus") then { + if (!isNil "_focus") then { // If there are no entities this becomes nil, handled on camera startup if (_focus isEqualType true) then { _focus = ([] call FUNC(getTargetEntities)) select 0; @@ -78,20 +78,20 @@ if !(isNil QGVAR(camera)) then { GVAR(camFocus) = _focus; }; - if !(isNil "_mode") then { + if (!isNil "_mode") then { GVAR(camMode) = _mode; }; - if !(isNil "_vision") then { + if (!isNil "_vision") then { GVAR(camVision) = _vision; }; // GVARs exits purely for pre-setting of these attributes - if !(isNil "_position") then { + if (!isNil "_position") then { GVAR(camPos) = ATLtoASL _position; }; - if !(isNil "_direction") then { + if (!isNil "_direction") then { GVAR(camDir) = _direction; }; }; diff --git a/addons/spectator/functions/fnc_setFocus.sqf b/addons/spectator/functions/fnc_setFocus.sqf index f524341a1f..6a897506b6 100644 --- a/addons/spectator/functions/fnc_setFocus.sqf +++ b/addons/spectator/functions/fnc_setFocus.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: AACO, SilentSpike + * Author: AACO, kymckay * Function used to set the camera focus * * Arguments: diff --git a/addons/spectator/functions/fnc_setSpectator.sqf b/addons/spectator/functions/fnc_setSpectator.sqf index d9942cc3ab..441baa7ab4 100644 --- a/addons/spectator/functions/fnc_setSpectator.sqf +++ b/addons/spectator/functions/fnc_setSpectator.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Enter/exit spectator mode for the local player * * Client will be able to communicate in ACRE/TFAR as appropriate diff --git a/addons/spectator/functions/fnc_switchFocus.sqf b/addons/spectator/functions/fnc_switchFocus.sqf index 8083a15e0f..c501ac4bb4 100644 --- a/addons/spectator/functions/fnc_switchFocus.sqf +++ b/addons/spectator/functions/fnc_switchFocus.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Function used to switch to next or previous camera focus * * Arguments: diff --git a/addons/spectator/functions/fnc_ui.sqf b/addons/spectator/functions/fnc_ui.sqf index c135c74a69..70e079105a 100644 --- a/addons/spectator/functions/fnc_ui.sqf +++ b/addons/spectator/functions/fnc_ui.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Handles UI initialisation and destruction * * Arguments: @@ -33,7 +33,7 @@ while {dialog} do { BIS_fnc_feedback_allowPP = !_init; // Removes death blur if present -if !(isNil "BIS_DeathBlur") then { +if (!isNil "BIS_DeathBlur") then { BIS_DeathBlur ppEffectAdjust [0]; BIS_DeathBlur ppEffectCommit 0; }; @@ -187,4 +187,7 @@ if (_init) then { // Ensure chat is shown again showChat true; + + // Restore HUD + [] call EFUNC(common,showHud); }; diff --git a/addons/spectator/functions/fnc_ui_draw3D.sqf b/addons/spectator/functions/fnc_ui_draw3D.sqf index 744e1bfe5e..066df4a69f 100644 --- a/addons/spectator/functions/fnc_ui_draw3D.sqf +++ b/addons/spectator/functions/fnc_ui_draw3D.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to draw the 3D icons and track the cursor object * * Arguments: @@ -30,7 +30,7 @@ private _end = AGLToASL screenToWorld getMousePosition; if ((_start distanceSqr _end) <= DISTANCE_NAMES_SQR) then { private _intersections = lineIntersectsSurfaces [_start, _end, _camTarget, _camTargetVeh]; - if !(_intersections isEqualTo []) then { + if (_intersections isNotEqualTo []) then { _cursorObject = effectiveCommander ((_intersections select 0) select 3); }; }; @@ -112,7 +112,7 @@ if !(GVAR(uiMapVisible)) then { private _oldLoc = []; { _x params ["_locNew", "_colorNew"]; - if !(_oldLoc isEqualTo []) then { + if (_oldLoc isNotEqualTo []) then { drawLine3D [_oldLoc, _locNew, _colorNew]; }; _oldLoc = _locNew; diff --git a/addons/spectator/functions/fnc_ui_fadeList.sqf b/addons/spectator/functions/fnc_ui_fadeList.sqf index c365ca4824..59c1728375 100644 --- a/addons/spectator/functions/fnc_ui_fadeList.sqf +++ b/addons/spectator/functions/fnc_ui_fadeList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to fade/unfade the entitiy list diff --git a/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf b/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf index 73d6cf8e89..04c29b5808 100644 --- a/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf +++ b/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to find the tree path of an entity diff --git a/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf b/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf index abebcbc69f..0d878da7e1 100644 --- a/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf +++ b/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte * Function used to handle child destroyed event diff --git a/addons/spectator/functions/fnc_ui_handleKeyDown.sqf b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf index 25a50d140b..c26a06786d 100644 --- a/addons/spectator/functions/fnc_ui_handleKeyDown.sqf +++ b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to handle key down event * * Arguments: diff --git a/addons/spectator/functions/fnc_ui_handleKeyUp.sqf b/addons/spectator/functions/fnc_ui_handleKeyUp.sqf index cf08d4caf6..d43db403c2 100644 --- a/addons/spectator/functions/fnc_ui_handleKeyUp.sqf +++ b/addons/spectator/functions/fnc_ui_handleKeyUp.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Function used to handle key up event * * Arguments: diff --git a/addons/spectator/functions/fnc_ui_handleListClick.sqf b/addons/spectator/functions/fnc_ui_handleListClick.sqf index 225623668d..600b7e711c 100644 --- a/addons/spectator/functions/fnc_ui_handleListClick.sqf +++ b/addons/spectator/functions/fnc_ui_handleListClick.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to handle list single/double clicks * * Expected behaviour: diff --git a/addons/spectator/functions/fnc_ui_handleLoad.sqf b/addons/spectator/functions/fnc_ui_handleLoad.sqf index bcaf90a699..bc1942437d 100644 --- a/addons/spectator/functions/fnc_ui_handleLoad.sqf +++ b/addons/spectator/functions/fnc_ui_handleLoad.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike, Jonpas + * Author: kymckay, Jonpas * Function used to handle load event. * * Arguments: @@ -19,6 +19,13 @@ params ["_display"]; uiNamespace setVariable [QGVAR(display), _display]; +if (["ace_map_gestures"] call EFUNC(common,isModLoaded)) then { + [_display displayCtrl IDC_MAP] call EFUNC(map_gestures,initDisplaySpectator); +}; + +[QGVAR(displayLoaded), _display] call CBA_fnc_localEvent; + + // Handle ACRE2 Toggle Spectator (if present) if (!isNil "acre_api_fnc_addDisplayPassthroughKeys") then { [_display] call acre_api_fnc_addDisplayPassthroughKeys; diff --git a/addons/spectator/functions/fnc_ui_handleMapClick.sqf b/addons/spectator/functions/fnc_ui_handleMapClick.sqf index 6d4e17e401..6dc7719bf3 100644 --- a/addons/spectator/functions/fnc_ui_handleMapClick.sqf +++ b/addons/spectator/functions/fnc_ui_handleMapClick.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to handle map mouse click events diff --git a/addons/spectator/functions/fnc_ui_handleMapDraw.sqf b/addons/spectator/functions/fnc_ui_handleMapDraw.sqf index 0602c7b4d2..eeb7ea22f3 100644 --- a/addons/spectator/functions/fnc_ui_handleMapDraw.sqf +++ b/addons/spectator/functions/fnc_ui_handleMapDraw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to handle map draw @@ -76,7 +76,7 @@ GVAR(uiMapHighlighted) = _nearestEntity; CTRL_MAP_FOOTER ctrlSetText _text; // Draw camera icon -if !(isNil QGVAR(camera)) then { +if (!isNil QGVAR(camera)) then { private _cameraPos = getPosASLVisual GVAR(camera); private _cameraDir = getDirVisual GVAR(camera); _map drawIcon [ICON_CAMERA, [0.5, 1, 0.5, 1], _cameraPos, 32, 48, _cameraDir, "", 1, 0.05, "TahomaB", "right"]; diff --git a/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf b/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf index ec7632e207..b154eb868a 100644 --- a/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf +++ b/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to handle mouse button double clicks * * Expected behaviour: diff --git a/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf b/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf index da74c071ba..eaf1ea3817 100644 --- a/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf +++ b/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to handle mouse down event * * Expected behaviour: diff --git a/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf b/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf index de652f8845..2bc234cd9b 100644 --- a/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf +++ b/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to handle mouse moving event diff --git a/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf index b402d9830e..b58e290cf3 100644 --- a/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf +++ b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to handle mouse scroll event diff --git a/addons/spectator/functions/fnc_ui_handleUnload.sqf b/addons/spectator/functions/fnc_ui_handleUnload.sqf new file mode 100644 index 0000000000..0bf76b86b9 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleUnload.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Function used to handle unload event. + * + * Arguments: + * 0: Spectator display + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleUnload + * + * Public: No + */ + +params ["_display"]; + +[QGVAR(displayUnloaded), _display] call CBA_fnc_localEvent; diff --git a/addons/spectator/functions/fnc_ui_toggleMap.sqf b/addons/spectator/functions/fnc_ui_toggleMap.sqf index c968f39512..d9863663f1 100644 --- a/addons/spectator/functions/fnc_ui_toggleMap.sqf +++ b/addons/spectator/functions/fnc_ui_toggleMap.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Nelson Duarte, AACO * Function used to toggle the map diff --git a/addons/spectator/functions/fnc_ui_toggleUI.sqf b/addons/spectator/functions/fnc_ui_toggleUI.sqf index 7e6716ba5e..ff34798c69 100644 --- a/addons/spectator/functions/fnc_ui_toggleUI.sqf +++ b/addons/spectator/functions/fnc_ui_toggleUI.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to toggle the whole user interface * * Arguments: diff --git a/addons/spectator/functions/fnc_ui_updateCamButtons.sqf b/addons/spectator/functions/fnc_ui_updateCamButtons.sqf index 77a8b3ca17..dc41422c17 100644 --- a/addons/spectator/functions/fnc_ui_updateCamButtons.sqf +++ b/addons/spectator/functions/fnc_ui_updateCamButtons.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Used to update the docked camera buttons * Disables unavailable, highlights current * diff --git a/addons/spectator/functions/fnc_ui_updateHelp.sqf b/addons/spectator/functions/fnc_ui_updateHelp.sqf index d1187ae355..1ddbbacad9 100644 --- a/addons/spectator/functions/fnc_ui_updateHelp.sqf +++ b/addons/spectator/functions/fnc_ui_updateHelp.sqf @@ -1,7 +1,7 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Updates spectator UI help element * * Note that there are some redundant conditions in this file diff --git a/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf index db3065c360..6093467d63 100644 --- a/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf +++ b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used update the things to 3D draw * * Arguments: diff --git a/addons/spectator/functions/fnc_ui_updateListEntities.sqf b/addons/spectator/functions/fnc_ui_updateListEntities.sqf index 640f860ec0..000f9a4b22 100644 --- a/addons/spectator/functions/fnc_ui_updateListEntities.sqf +++ b/addons/spectator/functions/fnc_ui_updateListEntities.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Updates spectator UI list of units/groups * * Arguments: @@ -35,7 +35,7 @@ private _entities = [true] call FUNC(getTargetEntities); // Include the group if it contains valid entities private _entitiesGroup = units _group arrayIntersect _entities; - if !(_entitiesGroup isEqualTo []) then { + if (_entitiesGroup isNotEqualTo []) then { // Cache the info of valid units in the group private _unitsInfo = []; { @@ -81,7 +81,7 @@ private _entities = [true] call FUNC(getTargetEntities); } forEach allGroups; // Whether an update to the list is required (really only if something changed) -if !(GVAR(curList) isEqualTo _newList) then { +if (GVAR(curList) isNotEqualTo _newList) then { private _ctrl = CTRL_LIST; // Remove groups/units that are no longer there diff --git a/addons/spectator/functions/fnc_ui_updateListFocus.sqf b/addons/spectator/functions/fnc_ui_updateListFocus.sqf index 3ac112e2cb..db82787098 100644 --- a/addons/spectator/functions/fnc_ui_updateListFocus.sqf +++ b/addons/spectator/functions/fnc_ui_updateListFocus.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, AACO, SilentSpike + * Author: Nelson Duarte, AACO, kymckay * Function used to update the list current selection * * Arguments: diff --git a/addons/spectator/functions/fnc_ui_updateWidget.sqf b/addons/spectator/functions/fnc_ui_updateWidget.sqf index 32337eae3d..78128d3b00 100644 --- a/addons/spectator/functions/fnc_ui_updateWidget.sqf +++ b/addons/spectator/functions/fnc_ui_updateWidget.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Nelson Duarte, SilentSpike + * Author: Nelson Duarte, kymckay * Updates spectator UI unit info widget * * Arguments: @@ -32,7 +32,7 @@ private _unitTypePicture = ""; private _vehicleTypePicture = ""; private _vehiclePositionPicture = ""; if (_focus != vehicle _focus) then { - _vehicleTypePicture = getText (configFile >> "CfgVehicles" >> typeOf vehicle _focus >> "Picture"); + _vehicleTypePicture = getText (configOf vehicle _focus >> "Picture"); _vehiclePositionPicture = switch (_focus) do { case (commander vehicle _focus): {IMG_COMMANDER}; diff --git a/addons/spectator/functions/fnc_updateCameraModes.sqf b/addons/spectator/functions/fnc_updateCameraModes.sqf index f6408c786d..b188f5d747 100644 --- a/addons/spectator/functions/fnc_updateCameraModes.sqf +++ b/addons/spectator/functions/fnc_updateCameraModes.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Adds or removes spectator camera modes from the selection available to the local player. * Possible camera modes are: * - 0: Free @@ -45,7 +45,7 @@ if (_newModes isEqualTo []) then { }; // Update camera in case of change -if !(isNil QGVAR(camera)) then { +if (!isNil QGVAR(camera)) then { // If mode was free and no longer available, find a focus if (!(MODE_FREE in _newModes) && {GVAR(camMode) == MODE_FREE} && {isNull GVAR(camFocus)}) then { [true] call FUNC(setFocus); diff --git a/addons/spectator/functions/fnc_updateSides.sqf b/addons/spectator/functions/fnc_updateSides.sqf index 1f612a3080..ca6107d0ed 100644 --- a/addons/spectator/functions/fnc_updateSides.sqf +++ b/addons/spectator/functions/fnc_updateSides.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Adds or removes sides from the selection available to spectate. Local effect. * * Default selection is [west,east,resistance,civilian] diff --git a/addons/spectator/functions/fnc_updateUnits.sqf b/addons/spectator/functions/fnc_updateUnits.sqf index a32198c3de..19522e29d8 100644 --- a/addons/spectator/functions/fnc_updateUnits.sqf +++ b/addons/spectator/functions/fnc_updateUnits.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Adds and removed units from the spectator list. Local effect. * * Arguments: diff --git a/addons/spectator/functions/fnc_updateVisionModes.sqf b/addons/spectator/functions/fnc_updateVisionModes.sqf index eb0e07f256..1265ff12fc 100644 --- a/addons/spectator/functions/fnc_updateVisionModes.sqf +++ b/addons/spectator/functions/fnc_updateVisionModes.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Adds or removes spectator vision modes from the selection available to the local player. * * Possible vision modes are: @@ -53,7 +53,7 @@ if (_newModes isEqualTo []) then { }; // Update camera in case of change -if !(isNil QGVAR(camera)) then { +if (!isNil QGVAR(camera)) then { [GVAR(camVision)] call FUNC(cam_setVisionMode); }; diff --git a/addons/spectator/functions/script_component.hpp b/addons/spectator/functions/script_component.hpp deleted file mode 100644 index d5034cb39c..0000000000 --- a/addons/spectator/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\spectator\script_component.hpp" \ No newline at end of file diff --git a/addons/spectator/initSettings.inc.sqf b/addons/spectator/initSettings.inc.sqf new file mode 100644 index 0000000000..6663d5a908 --- /dev/null +++ b/addons/spectator/initSettings.inc.sqf @@ -0,0 +1,39 @@ +[ + QGVAR(enableAI), + "CHECKBOX", + [LSTRING(ai_DisplayName), LSTRING(ai_Description)], + LSTRING(Settings_DisplayName), + false, + true +] call CBA_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + 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_fnc_addSetting; + +[ + QGVAR(maxFollowDistance), + "SLIDER", + [LSTRING(MaxFollowDistance_DisplayName), LSTRING(MaxFollowDistance_Description)], + LSTRING(Settings_DisplayName), + [5, 25, 5, 1], + false +] call CBA_fnc_addSetting; diff --git a/addons/spectator/initSettings.sqf b/addons/spectator/initSettings.sqf deleted file mode 100644 index c970fe77c7..0000000000 --- a/addons/spectator/initSettings.sqf +++ /dev/null @@ -1,39 +0,0 @@ -[ - 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 9bce522433..7f55998d9f 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -7,35 +7,43 @@ Spettatore 旁觀者 旁观者 - スペクテイター + 観戦者 관전자 Spectateur Obserwator Зритель + Espectador + Divák + Izleyici + Espectador ACE Spectator ACE Zuschauer - ACE スペクテイター - Spettatore ACE - Spectateur ACE + ACE 観戦者 + ACE Spettatore + ACE Spectateur ACE 旁观者 ACE 旁觀者 - Obserwator ACE + ACE Obserwator ACE 관전자 ACE Зритель + ACE Espectador + ACE Divák + ACE Izleyici + ACE Espectador Configure how the spectator system will operate by default. Konfiguriert den Zuschauermodus Skonfiguruj domyślne ustawienia obserwatora. Configura como o sistema de espectador operará por padrão. - Определяют, как система спектатора будет функционировать по-умолчанию. + Определяют, как система спектатора будет функционировать по умолчанию. Configurar cómo el sistema de espectador funcionará por defecto. Konfigurovat výchozí nastavení pozorovatele - Configura come il sistema spettatore si comporterà di default. - Configure comment le système de spectateurs opère par défaut. - スペクテイター システムが標準でどのように動作するか設定できます。 + Configura come il sistema spettatore si comporterà di base. + Configure le fonctionnement par défaut du système spectateur. + 観戦者システムが標準でどのように動作するか設定できます。 어떻게 관전자 시스템이 기본적으로 작동되는지 설정합니다 设定旁观者系统相关配置 設定旁觀者系統相關配置 @@ -43,54 +51,62 @@ AI Enabled KI Sichtbarkeit - AI にも有効化 - AI Abilitate + AIにも有効化 + IA Abilitate 可觀察AI - 可观察AI + 可观察 AI AI 활성 - IA Activée + IA visible SI Aktywowane Разрешить для ИИ + IA Ativado + AI povoleno + AI Etkin + IA Activada Make AI viewable in spectator Macht KI-Einheiten den Zuschauern sichtbar - スペクテイターで AI 視点を可能に - Permette la visibilità delle AI in spettatore + 観戦者でAI視点を可能に + Rende le IA visibili come spettatore 開啟此功能後可在觀察者模式下觀察AI單位 - 开启此功能后可在观察者模式下观察AI单位。 - 관전자가 AI를 관전 할 수 있습니다. - Rends les IA visibles en spectateur + 开启此功能后可在观察者模式下观察 AI 单位。 + 관전자가 AI를 관전할 수 있습니다. + Rend les unités IA visibles en spectateur. Spraw, aby SI było widoczne jako obserwator Сделать ИИ видимыми в режиме зрителя + Permite que IA seja visível no espectador + Umožňuje sledovat AI v módu diváka + Permitir ver a la IA en espectador Camera modes Kameramodus Tryby kamery - Modos de camera + Modos de câmera Режимы камеры Módy kamery Modos de cámara - Modalità camera - Mode de caméra + Modalità Videocamera + Modes de caméra カメラ モード 카메라 모드 摄影机模式 攝影機模式 + Kamera Modları Camera modes that can be used Verwendbare Kameramodi Tryby kamery, jakie mogą być używane. - Modos de camera que podem ser utilizados + Modos de câmera que podem ser utilizados Режимы камеры, которые могут быть использованы Modos de la cámara que se pueden utilizar. Módy kamery které mohou být použity. - Modalità che la camera può utilizzare. - Modes de caméra qui peuvent être utilisés + Modalità utilizzabili dalla videocamera spettatore. + Modes de caméra pouvant être utilisés. カメラ モードを設定できます。 - 사용할 수 있는 카메라 모드들 입니다 + 사용할 수 있는 카메라 모드들입니다 设定可使用的摄影机模式 設定可使用的攝影機模式 @@ -108,10 +124,11 @@ 모두 所有 所有 + Hepsi 1PP and 3PP - 1ère et 3e personne + 1ère et 3ème personne 1.ª y 3.ª persona 1° e 3° pers 1 i 3 os. @@ -119,10 +136,11 @@ 1PP und 3PP 1. a 3. osoby 1ª e 3ª pessoa - 1PP 과 3PP 카메라 + 1인칭과 3인칭 카메라 一人称と三人称 第一人稱與第三人稱 第一人称与第三人称 + 1PP ve 3PP Vision modes @@ -133,11 +151,12 @@ Modos de visión Módy zobrazení Modalità visuali - Modes de vision + Modes de visualisation ビジョン モード 시야 모드 视觉模式 視覺模式 + Görüş Modları Vision modes that can be used @@ -148,9 +167,9 @@ Modos de visión que pueden ser utilizados. Módy zobrazení které mohou být použity. Modalità visuali che possono essere usate. - Modes de visions qui peuvent être utilisés + Modes de visualisation pouvant être utilisés. ビジョン モードを設定できます。 - 사용할 수 있는 시야 모드들 입니다 + 사용할 수 있는 시야 모드들입니다 设定可使用的视觉模式 設定可使用的視覺模式 @@ -168,6 +187,7 @@ 야간투시경 夜视 夜視 + Geçe Görüşü Thermal imaging @@ -183,16 +203,37 @@ 열화상 热成像 熱成像 + Termal Görüş Max Follow Distance + Maximale Beobachtungsdistance Макс. дистанция следования 最大追随距離 + Distância Máxima de Acompanhamento + 最大跟隨距離 + 最大跟随距离 + Distance maximale de suivi + Distanza massima per seguire + Maximální vzdálenost sledování objektu + Maksymalna odległość śledzenia + Distancia máxima de seguimiento + 최대 추적 거리 Maximum distance the follow camera can be from the target + Maximale Distanz in welcher die Kamera dem Ziel folgen kann. Максимальная дистанция от камеры слежения до цели - カメラが目標へ追随できる最大距離を決定できます。 + カメラが目標へ追随できる最大距離 + A distância máxima que a câmera de acompanhamento pode estar do alvo. + 攝影機能追隨目標的最大距離 + 摄影机能追随目标的最大距离 + Distanza massima che la telecamera seguente può allontanarsi dall'obiettivo + Distance maximale à laquelle la caméra de suivi peut se trouver par rapport à la cible. + Maximální vzdálenost při které může kamera sledovat cíl + Maksymalna odległość na jakiej kamera może podążać od celu + Distancia máxima que la cámara de seguimiento puede estar del objetivo + 카메라가 목표를 따라갈 수 있는 최대 거리를 설정합니다. @@ -209,6 +250,7 @@ 정비공 工兵 工兵 + Mühendis Free @@ -221,9 +263,10 @@ Libera Libre 自由視点 - 자유 + 자유시점 自由模式 自由模式 + Serbest Normal @@ -236,39 +279,42 @@ Normale Normale 通常 - 정상 + 일반 正常 正常 + Normal Night Nacht Noc - Visão Norturna + Visão Noturna Ночное Noční Nocturna Notturno - Nuit + Nocturne 暗視装置 야간 夜视 夜視 + Gece Thermal - Wärme + Wärmebild Termo Térmica Тепловизор Termální Térmica - Termico + Termica Thermique 熱源画像 열상 热成像 熱成像 + Termal @@ -282,6 +328,10 @@ Icônes Ikony Иконки + Ícones + Ikony + Ikonlar + Iconos Projectiles @@ -294,6 +344,10 @@ Projectiles Pociski Осколки + Projéteis + Projektily + Mermiler + Proyectiles Next Unit @@ -309,6 +363,7 @@ 다음 인원 下个单位 下個單位 + Sonraki Takım Previous Unit @@ -324,6 +379,7 @@ 이전 인원 上个单位 上個單位 + Önceki Takım Vision Mode @@ -336,11 +392,15 @@ Mode de vision Tryb Wizji Режим видения + Modo de Visão + Režim sledování + Görüş Modu + Modo de visión Slow Speed Langsam - 速度低下 + 速度を下げる Bassa Velocità 慢速度 慢速度 @@ -348,6 +408,10 @@ Vitesse lente Wolna Prędkość Замедление + Velocidade Lenta + Pomalá rychlost + Yavaş Hız + Velocidad lenta diff --git a/addons/spectator/ui.hpp b/addons/spectator/ui.hpp index 7a49c72a86..f61e7749ee 100644 --- a/addons/spectator/ui.hpp +++ b/addons/spectator/ui.hpp @@ -20,6 +20,7 @@ class GVAR(display) { closeOnMissionEnd = 1; onLoad = QUOTE(_this call FUNC(ui_handleLoad)); + onUnload = QUOTE(_this call FUNC(ui_handleUnload)); onKeyDown = QUOTE(_this call FUNC(ui_handleKeyDown)); onKeyUp = QUOTE(_this call FUNC(ui_handleKeyUp)); @@ -54,9 +55,9 @@ class GVAR(display) { onTreeDblClick = QUOTE([ARR_2(true,_this)] call FUNC(ui_handleListClick)); x = "safeZoneX"; - y = safeZoneY + H_PART(1.5); - w = W_PART(13.5); - h = safeZoneH - H_PART(1.5); + y = QUOTE(safeZoneY + H_PART(1.5)); + w = QUOTE(W_PART(13.5)); + h = QUOTE(safeZoneH - H_PART(1.5)); disableKeyboardSearch = 1; multiselectEnabled = 0; @@ -82,30 +83,30 @@ class GVAR(display) { x = "safeZoneX"; y = "safezoneY"; - w = W_PART(13.5); - h = H_PART(1.5); + w = QUOTE(W_PART(13.5)); + h = QUOTE(H_PART(1.5)); fade = 0.5; rows = 1; columns = 1; strings[] = {"$STR_A3_Spectator_Entities"}; values[] = {0}; - sizeEx = H_PART(1); + sizeEx = QUOTE(H_PART(1)); colorBackground[] = {0,0,0,0.75}; colorSelectedBg[] = {0,0,0,0.65}; }; class CameraTypesGroup: RscControlsGroupNoScrollbars { idc = IDC_CAM_TYPES; - x = X_PART(15.5); - y = safezoneY + safezoneH - H_PART(2.38); - w = W_PART(8.6); + x = QUOTE(X_PART(15.5)); + y = QUOTE(safezoneY + safezoneH - H_PART(2.38)); + w = QUOTE(W_PART(8.6)); h = 2.6; class controls { class CameraTypesBackground: RscText { - x = W_PART(0.6); - y = H_PART(0.4); - w = W_PART(7.5); - h = H_PART(2); + x = QUOTE(W_PART(0.6)); + y = QUOTE(H_PART(0.4)); + w = QUOTE(W_PART(7.5)); + h = QUOTE(H_PART(2)); colorBackground[] = {0,0,0,0.75}; }; class Free: RscButton { @@ -114,10 +115,10 @@ class GVAR(display) { onButtonClick = QUOTE([MODE_FREE] call FUNC(cam_setCameraMode)); - x = W_PART(1.3); - y = H_PART(0.8); - w = W_PART(1.63); - h = H_PART(1.37); + x = QUOTE(W_PART(1.3)); + y = QUOTE(H_PART(0.8)); + w = QUOTE(W_PART(1.63)); + h = QUOTE(H_PART(1.37)); colorBackground[] = {0,0,0,0}; colorBackgroundDisabled[] = {0,0,0,0}; @@ -132,10 +133,10 @@ class GVAR(display) { onButtonClick = QUOTE([MODE_FOLLOW] call FUNC(cam_setCameraMode)); - x = W_PART(3.6); - y = H_PART(0.8); - w = W_PART(1.63); - h = H_PART(1.37); + x = QUOTE(W_PART(3.6)); + y = QUOTE(H_PART(0.8)); + w = QUOTE(W_PART(1.63)); + h = QUOTE(H_PART(1.37)); colorBackground[] = {0,0,0,0}; colorBackgroundDisabled[] = {0,0,0,0}; @@ -150,10 +151,10 @@ class GVAR(display) { onButtonClick = QUOTE([MODE_FPS] call FUNC(cam_setCameraMode)); - x = W_PART(5.8); - y = H_PART(0.8); - w = W_PART(1.63); - h = H_PART(1.37); + x = QUOTE(W_PART(5.8)); + y = QUOTE(H_PART(0.8)); + w = QUOTE(W_PART(1.63)); + h = QUOTE(H_PART(1.37)); colorBackground[] = {0,0,0,0}; colorBackgroundDisabled[] = {0,0,0,0}; @@ -188,7 +189,7 @@ class GVAR(display) { text = ""; style = 2; colorBackground[] = {0,0,0,0.75}; - sizeEx = H_PART(1); + sizeEx = QUOTE(H_PART(1)); }; class GameTimeText: RscText { idc = IDC_TIME; @@ -197,7 +198,7 @@ class GVAR(display) { w = 0.29; h = 0.03; text = "00:00:00"; - sizeEx = H_PART(1); + sizeEx = QUOTE(H_PART(1)); }; class MapTitle: RscText { idc = IDC_MAP_TITLE; @@ -207,7 +208,7 @@ class GVAR(display) { h = 0.03; text = ""; colorText[] = {1,1,1,1}; - sizeEx = H_PART(1); + sizeEx = QUOTE(H_PART(1)); }; class SpectatorsCount: RscText { idc = IDC_MAP_SPEC_NUM; @@ -217,7 +218,7 @@ class GVAR(display) { h = 0.03; text = ""; colorText[] = {1,1,1,1}; - sizeEx = H_PART(1); + sizeEx = QUOTE(H_PART(1)); }; class SpectatorsIcon: RscPictureKeepAspect { x = 0.94; @@ -244,214 +245,214 @@ class GVAR(display) { }; class HelpBackground: RscText { idc = IDC_HELP_BACK; - x = safezoneX + safezoneW - W_PART(12); - y = safezoneY + safezoneH - H_PART(8); - w = W_PART(12); - h = H_PART(8); + x = QUOTE(safezoneX + safezoneW - W_PART(12)); + y = QUOTE(safezoneY + safezoneH - H_PART(8)); + w = QUOTE(W_PART(12)); + h = QUOTE(H_PART(8)); colorBackground[] = {0,0,0,0.75}; }; class Help: RscListNBox { class ListScrollBar: ScrollBar {}; disableOverflow = 0; - rowHeight = H_PART(1); + rowHeight = QUOTE(H_PART(1)); idc = IDC_HELP; - x = safezoneX + safezoneW - W_PART(12); - y = safezoneY + safezoneH - H_PART(12); - w = W_PART(12); - h = H_PART(12); + x = QUOTE(safezoneX + safezoneW - W_PART(12)); + y = QUOTE(safezoneY + safezoneH - H_PART(12)); + w = QUOTE(W_PART(12)); + h = QUOTE(H_PART(12)); }; class FocusInfo: RscControlsGroupNoScrollbars { idc = IDC_WIDGET; - x = X_PART(12.9); - y = Y_PART(24); - w = W_PART(14.2); - h = H_PART(3.5); + x = QUOTE(X_PART(12.9)); + y = QUOTE(Y_PART(24)); + w = QUOTE(W_PART(14.2)); + h = QUOTE(H_PART(3.5)); class controls { class UpperBackground: RscText { x = 0; y = 0; - w = W_PART(14.2); - h = H_PART(1.4); + w = QUOTE(W_PART(14.2)); + h = QUOTE(H_PART(1.4)); colorBackground[] = {0,0,0,0.75}; }; class StatsBackground: RscText { x = 0; - y = H_PART(1.5); - w = W_PART(6); - h = H_PART(2); + y = QUOTE(H_PART(1.5)); + w = QUOTE(W_PART(6)); + h = QUOTE(H_PART(2)); colorBackground[] = {0,0,0,0.75}; }; class WeaponBackground: RscText { - x = W_PART(6.1); - y = H_PART(1.5); - w = W_PART(6); - h = H_PART(2); + x = QUOTE(W_PART(6.1)); + y = QUOTE(H_PART(1.5)); + w = QUOTE(W_PART(6)); + h = QUOTE(H_PART(2)); colorBackground[] = {1,1,1,0.4}; }; class ThrowableBackground: RscText { - x = W_PART(12.2); - y = H_PART(1.5); - w = W_PART(2); - h = H_PART(2); + x = QUOTE(W_PART(12.2)); + y = QUOTE(H_PART(1.5)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); colorBackground[] = {1,1,1,0.4}; }; class Name: RscText { shadow = 0; idc = IDC_WIDGET_NAME; text = ""; - x = W_PART(0.1); - y = H_PART(0.1); - w = W_PART(10.8); - h = H_PART(1.2); - sizeEx = H_PART(1); + x = QUOTE(W_PART(0.1)); + y = QUOTE(H_PART(0.1)); + w = QUOTE(W_PART(10.8)); + h = QUOTE(H_PART(1.2)); + sizeEx = QUOTE(H_PART(1)); }; class VehiclePos: RscPictureKeepAspect { idc = IDC_WIDGET_VEHICLE_POS; text = ""; - x = W_PART(11); - y = H_PART(0.2); - w = W_PART(1); - h = H_PART(1); + x = QUOTE(W_PART(11)); + y = QUOTE(H_PART(0.2)); + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); }; class VehicleType: RscPicture { idc = IDC_WIDGET_VEHICLE; text = ""; - x = W_PART(12.1); - y = H_PART(0.2); - w = W_PART(2); - h = H_PART(1); + x = QUOTE(W_PART(12.1)); + y = QUOTE(H_PART(0.2)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(1)); }; class UnitType: RscPictureKeepAspect { idc = IDC_WIDGET_UNIT; text = ""; - x = W_PART(13.1); - y = H_PART(0.2); - w = W_PART(1); - h = H_PART(1); + x = QUOTE(W_PART(13.1)); + y = QUOTE(H_PART(0.2)); + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); }; class Kills: RscPictureKeepAspect { text = "a3\Ui_f\data\IGUI\Cfg\MPTable\infantry_ca.paa"; - x = W_PART(0.1); - y = H_PART(1.6); - w = W_PART(0.8); - h = H_PART(0.8); + x = QUOTE(W_PART(0.1)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.8)); }; class LandKills: RscPictureKeepAspect { text = "a3\Ui_f\data\IGUI\Cfg\MPTable\soft_ca.paa"; - x = W_PART(1.1); - y = H_PART(1.6); - w = W_PART(0.8); - h = H_PART(0.8); + x = QUOTE(W_PART(1.1)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.8)); }; class ArmoredKills: RscPictureKeepAspect { text = "a3\Ui_f\data\IGUI\Cfg\MPTable\armored_ca.paa"; - x = W_PART(2.1); - y = H_PART(1.6); - w = W_PART(0.8); - h = H_PART(0.8); + x = QUOTE(W_PART(2.1)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.8)); }; class AirKills: RscPictureKeepAspect { text = "a3\Ui_f\data\IGUI\Cfg\MPTable\air_ca.paa"; - x = W_PART(3.1); - y = H_PART(1.6); - w = W_PART(0.8); - h = H_PART(0.8); + x = QUOTE(W_PART(3.1)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.8)); }; class Deaths: RscPictureKeepAspect { text = "a3\Ui_f\data\IGUI\Cfg\MPTable\killed_ca.paa"; - x = W_PART(4.1); - y = H_PART(1.6); - w = W_PART(0.8); - h = H_PART(0.8); + x = QUOTE(W_PART(4.1)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.8)); }; class Total: RscPictureKeepAspect { text = "a3\Ui_f\data\IGUI\Cfg\MPTable\total_ca.paa"; - x = W_PART(5.1); - y = H_PART(1.6); - w = W_PART(0.8); - h = H_PART(0.8); + x = QUOTE(W_PART(5.1)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.8)); }; class Kills_Count: RscText { style = 2; shadow = 0; idc = IDC_WIDGET_KILLS; text = ""; - x = W_PART(0.1); - y = H_PART(2.5); - w = W_PART(0.8); - h = H_PART(0.9); - sizeEx = H_PART(0.7); + x = QUOTE(W_PART(0.1)); + y = QUOTE(H_PART(2.5)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.9)); + sizeEx = QUOTE(H_PART(0.7)); }; class LandKills_Count: RscText { style = 2; shadow = 0; idc = IDC_WIDGET_LAND; text = ""; - x = W_PART(1.1); - y = H_PART(2.5); - w = W_PART(0.8); - h = H_PART(0.9); - sizeEx = H_PART(0.7); + x = QUOTE(W_PART(1.1)); + y = QUOTE(H_PART(2.5)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.9)); + sizeEx = QUOTE(H_PART(0.7)); }; class ArmoredKills_Count: RscText { style = 2; shadow = 0; idc = IDC_WIDGET_ARMORED; text = ""; - x = W_PART(2.1); - y = H_PART(2.5); - w = W_PART(0.8); - h = H_PART(0.9); - sizeEx = H_PART(0.7); + x = QUOTE(W_PART(2.1)); + y = QUOTE(H_PART(2.5)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.9)); + sizeEx = QUOTE(H_PART(0.7)); }; class AirKills_Count: RscText { style = 2; shadow = 0; idc = IDC_WIDGET_AIR; text = ""; - x = W_PART(3.1); - y = H_PART(2.5); - w = W_PART(0.8); - h = H_PART(0.9); - sizeEx = H_PART(0.7); + x = QUOTE(W_PART(3.1)); + y = QUOTE(H_PART(2.5)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.9)); + sizeEx = QUOTE(H_PART(0.7)); }; class Deaths_Count: RscText { style = 2; shadow = 0; idc = IDC_WIDGET_DEATHS; text = ""; - x = W_PART(4.1); - y = H_PART(2.5); - w = W_PART(0.8); - h = H_PART(0.9); - sizeEx = H_PART(0.7); + x = QUOTE(W_PART(4.1)); + y = QUOTE(H_PART(2.5)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.9)); + sizeEx = QUOTE(H_PART(0.7)); }; class Total_Count: RscText { style = 2; shadow = 0; idc = IDC_WIDGET_TOTAL; text = ""; - x = W_PART(5.1); - y = H_PART(2.5); - w = W_PART(0.8); - h = H_PART(0.9); - sizeEx = H_PART(0.7); + x = QUOTE(W_PART(5.1)); + y = QUOTE(H_PART(2.5)); + w = QUOTE(W_PART(0.8)); + h = QUOTE(H_PART(0.9)); + sizeEx = QUOTE(H_PART(0.7)); }; class WeaponPicture: RscPictureKeepAspect { idc = IDC_WIDGET_WEAPON; text = ""; - x = W_PART(6.2); - y = H_PART(1.6); - w = W_PART(5.8); - h = H_PART(1.8); + x = QUOTE(W_PART(6.2)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(5.8)); + h = QUOTE(H_PART(1.8)); }; class ThrowablePicture: RscPictureKeepAspect { idc = IDC_WIDGET_THROWABLE; text = ""; - x = W_PART(12.3); - y = H_PART(1.6); - w = W_PART(1.8); - h = H_PART(1.8); + x = QUOTE(W_PART(12.3)); + y = QUOTE(H_PART(1.6)); + w = QUOTE(W_PART(1.8)); + h = QUOTE(H_PART(1.8)); }; }; }; diff --git a/addons/spottingscope/CfgEventHandlers.hpp b/addons/spottingscope/CfgEventHandlers.hpp index b34b3ac099..4e0965ea82 100644 --- a/addons/spottingscope/CfgEventHandlers.hpp +++ b/addons/spottingscope/CfgEventHandlers.hpp @@ -1,22 +1,16 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; -class Extended_PostInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - }; -}; - class Extended_Init_EventHandlers { class ACE_SpottingScopeObject { class ADDON { diff --git a/addons/spottingscope/CfgVehicles.hpp b/addons/spottingscope/CfgVehicles.hpp index 660a3d6749..93fa00a7bc 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -41,14 +41,14 @@ class CfgVehicles { EGVAR(dragging,dragPosition)[] = {0,1,0}; EGVAR(dragging,dragDirection) = 0; - class ACE_Actions: ACE_Actions{ + class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { selection = "main_turret_axis"; class ACE_Pickup { selection = ""; displayName = CSTRING(PickUp); distance = 5; - condition = QUOTE((alive _target) && (count (crew _target) == 0)); + condition = QUOTE((alive _target) && {(crew _target) isEqualTo []}); statement = QUOTE([ARR_2(_target,_player)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; diff --git a/addons/spottingscope/CfgWeapons.hpp b/addons/spottingscope/CfgWeapons.hpp index 2949920602..73af3b9cde 100644 --- a/addons/spottingscope/CfgWeapons.hpp +++ b/addons/spottingscope/CfgWeapons.hpp @@ -9,6 +9,7 @@ class CfgWeapons { descriptionShort = ""; picture = QPATHTOF(UI\w_spottingscope_ca.paa); model = QPATHTOF(data\ace_spottingscope.p3d); + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 40; @@ -25,11 +26,11 @@ class CfgWeapons { 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)} + {0, QPATHTOF(data\ace_spottingscope_reticle_b1_ca.paa), 1, QPATHTOF(data\ace_spottingscope_reticle_b1_ca.paa)}, + {9, QPATHTOF(data\ace_spottingscope_reticle_b2_ca.paa), "1/2", QPATHTOF(data\ace_spottingscope_reticle_b2_ca.paa)}, + {14, QPATHTOF(data\ace_spottingscope_reticle_b3_ca.paa), "1/3", QPATHTOF(data\ace_spottingscope_reticle_b3_ca.paa)}, + {19, QPATHTOF(data\ace_spottingscope_reticle_b4_ca.paa), "1/4", QPATHTOF(data\ace_spottingscope_reticle_b4_ca.paa)}, + {24, QPATHTOF(data\ace_spottingscope_reticle_b5_ca.paa), "1/5", QPATHTOF(data\ace_spottingscope_reticle_b5_ca.paa)} }; fadeReticleInterval[] = {10.5,9.5}; diff --git a/addons/spottingscope/README.md b/addons/spottingscope/README.md index a07b9c6c85..8cd42e45ac 100644 --- a/addons/spottingscope/README.md +++ b/addons/spottingscope/README.md @@ -2,10 +2,3 @@ ace_spottingscope =============== Adds a spotting scope. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/spottingscope/XEH_postInit.sqf b/addons/spottingscope/XEH_postInit.sqf deleted file mode 100644 index 421c54b49f..0000000000 --- a/addons/spottingscope/XEH_postInit.sqf +++ /dev/null @@ -1 +0,0 @@ -#include "script_component.hpp" diff --git a/addons/spottingscope/XEH_preInit.sqf b/addons/spottingscope/XEH_preInit.sqf index 13d220d959..568b6c2e4a 100644 --- a/addons/spottingscope/XEH_preInit.sqf +++ b/addons/spottingscope/XEH_preInit.sqf @@ -11,7 +11,7 @@ PREP_RECOMPILE_END; private _tube = "ACE_SpottingScope_tube" createVehicle [0,0,0]; _tube setDir (getDir _wreck - 180); - _tube setPosASL AGLToASL (_wreck modelToWorld (_wreck selectionPosition "destructionEffect")); + _tube setPosASL (_wreck modelToWorldWorld (_wreck selectionPosition "destructionEffect")); _tube setVelocity [1 - random 2, 1 - random 2, 4]; _tube addTorque (vectorNormalized [1 - random 2, 1 - random 2, 1 - random 2] vectorMultiply 4); }] call CBA_fnc_addClassEventHandler; diff --git a/addons/spottingscope/functions/fnc_pickup.sqf b/addons/spottingscope/functions/fnc_pickup.sqf index 2e8a5cc9e2..1b0e6b1a05 100644 --- a/addons/spottingscope/functions/fnc_pickup.sqf +++ b/addons/spottingscope/functions/fnc_pickup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Pick up spotting scope diff --git a/addons/spottingscope/functions/fnc_place.sqf b/addons/spottingscope/functions/fnc_place.sqf index ddf02d7e1e..b15656aca3 100644 --- a/addons/spottingscope/functions/fnc_place.sqf +++ b/addons/spottingscope/functions/fnc_place.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Place down spotting scope diff --git a/addons/spottingscope/functions/script_component.hpp b/addons/spottingscope/functions/script_component.hpp deleted file mode 100644 index 504cde2ca6..0000000000 --- a/addons/spottingscope/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\spottingscope\script_component.hpp" \ No newline at end of file diff --git a/addons/spottingscope/stringtable.xml b/addons/spottingscope/stringtable.xml index b11bff24ac..e6afd17003 100644 --- a/addons/spottingscope/stringtable.xml +++ b/addons/spottingscope/stringtable.xml @@ -1,13 +1,13 @@ - + Spotting Scope Teleskop Зрительная труба Teleskop Telescopio - Téléscope de visée + Longue-vue Zaměřovací dalekohled Cannocchiale Megfigyelő távcső @@ -16,6 +16,7 @@ 감적 망원경 观测镜 觀測鏡 + Gözcü Dürbünü Pick up Spotting Scope @@ -23,7 +24,7 @@ Поднять зрительная трубу Zabierz teleskop Coger telescopio - Prendre téléscope de visée + Récupérer la longue-vue Zvednout zaměřovací dalekohled Raccogli Cannocchiale Mefgigy. távcső felvétele @@ -32,6 +33,7 @@ 감적 망원경 줍기 捡起观测镜 撿起觀測鏡 + Gözcü Dürbününü al Place Spotting Scope @@ -39,15 +41,16 @@ Установить зрительная трубу Ustaw teleskop Colocar telescopio - Placer téléscope de visée + Placer la longue-vue Položit zaměřovací dalekohled Posiziona Cannocchiale Megfigy. távcső elhelyezése Colocar luneta de observador 観測用スコープを置く - 감적 망원경 배치 + 감적 망원경 놓기 放置观测镜 放置觀測鏡 + Gözcü Dürbününü Yerleştir diff --git a/addons/switchunits/ACE_Settings.hpp b/addons/switchunits/ACE_Settings.hpp index 31c74f2889..9f02068f1f 100644 --- a/addons/switchunits/ACE_Settings.hpp +++ b/addons/switchunits/ACE_Settings.hpp @@ -1,50 +1,23 @@ class ACE_Settings { class GVAR(enableSwitchUnits) { - category = CSTRING(DisplayName); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(switchToWest) { - category = CSTRING(DisplayName); - displayName = CSTRING(SwitchToWest_DisplayName); - description = CSTRING(SwitchToWest_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(switchToEast) { - category = CSTRING(DisplayName); - displayName = CSTRING(SwitchToEast_DisplayName); - description = CSTRING(SwitchToEast_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(switchToIndependent) { - category = CSTRING(DisplayName); - displayName = CSTRING(SwitchToIndependent_DisplayName); - description = CSTRING(SwitchToIndependent_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(switchToCivilian) { - category = CSTRING(DisplayName); - displayName = CSTRING(SwitchToCivilian_DisplayName); - description = CSTRING(SwitchToCivilian_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(enableSafeZone) { - category = CSTRING(DisplayName); - displayName = CSTRING(EnableSafeZone_DisplayName); - description = CSTRING(EnableSafeZone_Description); - value = 1; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(safeZoneRadius) { - category = CSTRING(DisplayName); - displayName = CSTRING(SafeZoneRadius_DisplayName); - description = CSTRING(SafeZoneRadius_Description); - value = 100; - typeName = "SCALAR"; - sliderSettings[] = {0, 1000, 100, 0}; + movedToSQF = 1; }; }; diff --git a/addons/switchunits/CfgEventHandlers.hpp b/addons/switchunits/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/switchunits/CfgEventHandlers.hpp +++ b/addons/switchunits/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/switchunits/CfgVehicles.hpp b/addons/switchunits/CfgVehicles.hpp index bb07eb541c..74d51db44e 100644 --- a/addons/switchunits/CfgVehicles.hpp +++ b/addons/switchunits/CfgVehicles.hpp @@ -4,7 +4,7 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); category = "ACE"; displayName = CSTRING(DisplayName); - function = FUNC(module); + function = QFUNC(module); scope = 1; isGlobal = 1; icon = QPATHTOF(UI\Icon_Module_SwitchUnits_ca.paa); diff --git a/addons/switchunits/README.md b/addons/switchunits/README.md index 029dfc7cf9..07a29a8665 100644 --- a/addons/switchunits/README.md +++ b/addons/switchunits/README.md @@ -2,11 +2,3 @@ ace_switchunits =============== Adds insurgency-style unit switching. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [bux578](https://github.com/bux578) -- [commy2](https://github.com/commy2) diff --git a/addons/switchunits/XEH_postInit.sqf b/addons/switchunits/XEH_postInit.sqf index cffac8b57f..b3937b597a 100644 --- a/addons/switchunits/XEH_postInit.sqf +++ b/addons/switchunits/XEH_postInit.sqf @@ -19,7 +19,7 @@ if (missionNamespace getVariable [QGVAR(EnableSwitchUnits), false]) then { [player] call FUNC(startSwitchUnits); } else { - ["ace_settingChanged", { + ["CBA_SettingChanged", { params ["_name", "_value"]; if ((_name == QGVAR(EnableSwitchUnits)) && {_value}) then { [player] call FUNC(startSwitchUnits); diff --git a/addons/switchunits/XEH_preInit.sqf b/addons/switchunits/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/switchunits/XEH_preInit.sqf +++ b/addons/switchunits/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/switchunits/functions/fnc_addMapFunction.sqf b/addons/switchunits/functions/fnc_addMapFunction.sqf index 28d9f05b78..46d4ce9e8f 100644 --- a/addons/switchunits/functions/fnc_addMapFunction.sqf +++ b/addons/switchunits/functions/fnc_addMapFunction.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Adds a mapClick Eventhandler @@ -16,12 +16,9 @@ * Public: No */ -params ["_unit", "_sides"]; - -["theMapClick", "onMapSingleClick", { - // IGNORE_PRIVATE_WARNING(_pos,_shift,_alt) +addMissionEventHandler ["MapSingleClick", { + params ["", "_pos"]; if (alive ACE_player && {GVAR(OriginalUnit) getVariable ["ACE_CanSwitchUnits", false]}) then { - [_this, _pos, _shift, _alt] call FUNC(handleMapClick); + [GVAR(switchableSides), _pos] call FUNC(handleMapClick); }; - -}, [_unit, _sides]] call BIS_fnc_addStackedEventHandler; +}]; diff --git a/addons/switchunits/functions/fnc_handleMapClick.sqf b/addons/switchunits/functions/fnc_handleMapClick.sqf index 73f48c1fc0..fbb1e3d349 100644 --- a/addons/switchunits/functions/fnc_handleMapClick.sqf +++ b/addons/switchunits/functions/fnc_handleMapClick.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Switches to a unit close to a clicked map position @@ -18,8 +18,7 @@ * Public: No */ -params ["_faction", "_pos"]; -_faction params ["", "_sides"]; +params ["_sides", "_pos"]; private _nearestObjects = nearestObjects [_pos, ["Man"], 15]; diff --git a/addons/switchunits/functions/fnc_initPlayer.sqf b/addons/switchunits/functions/fnc_initPlayer.sqf index 5fe6d5be6e..ffc0f7ad63 100644 --- a/addons/switchunits/functions/fnc_initPlayer.sqf +++ b/addons/switchunits/functions/fnc_initPlayer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Initializes the player @@ -16,10 +16,10 @@ * Public: No */ -params ["_playerUnit", "_sides"]; +params ["_playerUnit"]; if (vehicle _playerUnit == _playerUnit) then { - [_sides] call FUNC(markAiOnMap); + [GVAR(switchableSides)] call FUNC(markAiOnMap); _playerUnit setVariable [QGVAR(IsPlayerUnit), true, true]; _playerUnit allowDamage false; @@ -38,5 +38,5 @@ if (vehicle _playerUnit == _playerUnit) then { [_playerUnit, "forceWalk", "ACE_SwitchUnits", true] call EFUNC(common,statusEffect_set); - [_playerUnit, _sides] call FUNC(addMapFunction); + [] call FUNC(addMapFunction); }; diff --git a/addons/switchunits/functions/fnc_isValidAi.sqf b/addons/switchunits/functions/fnc_isValidAi.sqf index 39fd0db94d..53ebcdaac2 100644 --- a/addons/switchunits/functions/fnc_isValidAi.sqf +++ b/addons/switchunits/functions/fnc_isValidAi.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Checks if AI is a valid target for switching. @@ -19,6 +19,6 @@ params ["_unit"]; !([_unit] call EFUNC(common,isPlayer) || {_unit in playableUnits} -|| {vehicle _unit != _unit} +|| {!isNull objectParent _unit} || {_unit getVariable [QGVAR(IsPlayerUnit), false]} || {_unit getVariable [QGVAR(IsPlayerControlled), false]}) // return diff --git a/addons/switchunits/functions/fnc_markAiOnMap.sqf b/addons/switchunits/functions/fnc_markAiOnMap.sqf index 6c2eb0b0d9..203ba426ff 100644 --- a/addons/switchunits/functions/fnc_markAiOnMap.sqf +++ b/addons/switchunits/functions/fnc_markAiOnMap.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Creates markers for AI units for given sides. @@ -27,7 +27,7 @@ GVAR(AllMarkerNames) = []; // delete markers { deleteMarkerLocal _x; - } count GVAR(AllMarkerNames); + } forEach GVAR(AllMarkerNames); // reset the array GVAR(AllMarkerNames) = []; @@ -54,12 +54,11 @@ GVAR(AllMarkerNames) = []; _markerName setMarkerTextLocal (_x getVariable [QGVAR(PlayerControlledName), ""]); } else { _markerName setMarkerColorLocal _markerColor; - _markerName setMarkerTextLocal (getText (configFile >> "CfgVehicles" >> typeOf _x >> "displayName")); + _markerName setMarkerTextLocal (getText (configOf _x >> "displayName")); }; GVAR(AllMarkerNames) pushBack _markerName; - nil }; - } count allUnits; + } forEach allUnits; }; }, 1.5, [_sidesToShow]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/switchunits/functions/fnc_module.sqf b/addons/switchunits/functions/fnc_module.sqf index a2346ff2f4..d243715875 100644 --- a/addons/switchunits/functions/fnc_module.sqf +++ b/addons/switchunits/functions/fnc_module.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Initializes the SwitchUnits module diff --git a/addons/switchunits/functions/fnc_nearestPlayers.sqf b/addons/switchunits/functions/fnc_nearestPlayers.sqf index 1d649d0843..de1fda7e08 100644 --- a/addons/switchunits/functions/fnc_nearestPlayers.sqf +++ b/addons/switchunits/functions/fnc_nearestPlayers.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Returns an array of alive players in a given radius around a given location diff --git a/addons/switchunits/functions/fnc_startSwitchUnits.sqf b/addons/switchunits/functions/fnc_startSwitchUnits.sqf index f5cc4c1330..46fbb7e476 100644 --- a/addons/switchunits/functions/fnc_startSwitchUnits.sqf +++ b/addons/switchunits/functions/fnc_startSwitchUnits.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Starts the SwitchUnits functionality @@ -18,14 +18,14 @@ params ["_player"]; if (GVAR(EnableSwitchUnits)) then { - private _sides = []; + GVAR(switchableSides) = []; - if (GVAR(SwitchToWest)) then {_sides pushBack west;}; - if (GVAR(SwitchToEast)) then {_sides pushBack east;}; - if (GVAR(SwitchToIndependent)) then {_sides pushBack independent;}; - if (GVAR(SwitchToCivilian)) then {_sides pushBack civilian;}; + if (GVAR(SwitchToWest)) then {GVAR(switchableSides) pushBack west;}; + if (GVAR(SwitchToEast)) then {GVAR(switchableSides) pushBack east;}; + if (GVAR(SwitchToIndependent)) then {GVAR(switchableSides) pushBack independent;}; + if (GVAR(SwitchToCivilian)) then {GVAR(switchableSides) pushBack civilian;}; if (_player getVariable ["ACE_CanSwitchUnits", false]) then { - [_player, _sides] call FUNC(initPlayer); + [_player] call FUNC(initPlayer); }; }; diff --git a/addons/switchunits/functions/fnc_switchBack.sqf b/addons/switchunits/functions/fnc_switchBack.sqf index 9762547545..454d9001b1 100644 --- a/addons/switchunits/functions/fnc_switchBack.sqf +++ b/addons/switchunits/functions/fnc_switchBack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Switches back to the original player unit diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf index ab2867c3ef..9ce074eecb 100644 --- a/addons/switchunits/functions/fnc_switchUnit.sqf +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux578 * Switches to the new given player unit @@ -18,7 +18,7 @@ params ["_unit"]; // don't switch to original player units -if (!([_unit] call FUNC(isValidAi))) exitWith {}; +if !([_unit] call FUNC(isValidAi)) exitWith {}; // exit var private _leave = false; @@ -27,7 +27,7 @@ if (GVAR(EnableSafeZone)) then { private _allNearestPlayers = [position _unit, GVAR(SafeZoneRadius)] call FUNC(nearestPlayers); private _nearestEnemyPlayers = _allNearestPlayers select {((side GVAR(OriginalGroup)) getFriend side _x < 0.6) && !(_x getVariable [QGVAR(IsPlayerControlled), false])}; - if (count _nearestEnemyPlayers > 0) exitWith { + if (_nearestEnemyPlayers isNotEqualTo []) exitWith { _leave = true; }; }; diff --git a/addons/switchunits/functions/script_component.hpp b/addons/switchunits/functions/script_component.hpp deleted file mode 100644 index d03116f2f8..0000000000 --- a/addons/switchunits/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\switchunits\script_component.hpp" diff --git a/addons/switchunits/initSettings.inc.sqf b/addons/switchunits/initSettings.inc.sqf new file mode 100644 index 0000000000..173cb9112c --- /dev/null +++ b/addons/switchunits/initSettings.inc.sqf @@ -0,0 +1,57 @@ +private _category = format ["ACE %1", localize LSTRING(DisplayName)]; + +[ + QGVAR(enableSwitchUnits), "CHECKBOX", + LSTRING(EnableSwitchUnits_DisplayName), + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(switchToWest), "CHECKBOX", + [LSTRING(SwitchToWest_DisplayName), LSTRING(SwitchToWest_Description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(switchToEast), "CHECKBOX", + [LSTRING(SwitchToEast_DisplayName), LSTRING(SwitchToEast_Description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(switchToIndependent), "CHECKBOX", + [LSTRING(SwitchToIndependent_DisplayName), LSTRING(SwitchToIndependent_Description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(switchToCivilian), "CHECKBOX", + [LSTRING(SwitchToCivilian_DisplayName), LSTRING(SwitchToCivilian_Description)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableSafeZone), "CHECKBOX", + [LSTRING(EnableSafeZone_DisplayName), LSTRING(EnableSafeZone_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(safeZoneRadius), "SLIDER", + [LSTRING(SafeZoneRadius_DisplayName), LSTRING(SafeZoneRadius_Description)], + _category, + [0, 1000, 100, 0], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index 2eff66308e..c772b40867 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -5,12 +5,17 @@ Switch Units Cambia Unità 切換單位 - 切换单位 - ユニット切り替え - 병력 전환 + 单位切换 + ユニットを切り替え + 유닛 변경 Einheitenwechsel Przełącz Jednostki Переключение юнитов + Trocar Unidades + Přepnout jednotky + Changement de camp + Birlik Değiştir + Cambiar unidades Switched unit @@ -19,14 +24,15 @@ Prohozená jednotka Przełączona jednostka Cambiado de unidad - Unité changée + Camp changé Egység átváltva Unità cambiata Trocado de unidade - ユニットを切り替え + 切り替えたユニット 切换单位 切換單位 - 인원 전환 + 유닛 변경됨 + Birlik Değiştirildi Trying to switch @@ -35,13 +41,14 @@ Próba zmiany Provando a cambiare Intentando cambiar - Essaye de basculer + Essaie de changer Tentando trocar Попытка переключения 切り替えを試す 전환 시도중 - 尝试切换中 + 正在尝试切换 嘗試切換中 + Birlik değiştirilme deneniyor This unit is too close to the enemy. @@ -50,7 +57,7 @@ Tato jednotka je moc blízko k nepříteli. Ta jednostka jest zbyt blisko przeciwnika. Esta unidad está demasiado cerca del enemigo. - Cette unité est trop proche des ennemis + Cette unité est trop proche de l'ennemi. Ez az egység túl közel van az ellenséghez. Questa unità è troppo vicina al nemico. Essa unidade está muito perto do inimigo. @@ -59,6 +66,21 @@ 这单位太接近敌人了 這單位太接近敵人了 + + Enable switch side + Ermögliche Seitenwechsel + Permetti cambio fazione + Permettre le changement de camp + 啟用陣營切換 + 启用阵营切换 + Povolit změnu strany + Włącz zmiane strony + Habilita troca de time + 陣営切り替えを有効化 + Включить смену стороны + Habilitar cambio de bando + 진영 변경 활성화 + Switch to West? Zmiana na Zachód? @@ -66,14 +88,15 @@ Nach BLUFOR wechseln? Přesunout k BLUFOR? Trocar para Oeste? - Changer en OUEST? + Passage en BLUFOR Átváltás BLUFOR-ra? На синих? Cambia per BLUFOR? - 同盟軍へ切り替えますか? - 切换至蓝方? + 同盟軍へ切り替える? + 切换至蓝方? 切換至藍方? - 청군으로 전환합니까? + 청군으로 변경합니까? + Batıya Geç? Allow switching to west units? @@ -82,14 +105,14 @@ Erlaube das Wechseln zu BLUFOR-Einheiten? Povolit přesun k BLUFOR? Permitir troca de unidades para o Oeste? - Permettre le changement en unité OUEST? + Autorise le passage en unité BLUFOR. Nyugat-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на синих юнитов? Consenti passaggio ad unità BLUFOR? - 同盟軍側ユニットへ切り替えられるようにしますか? - 允许切换至蓝方? + 同盟軍ユニットへの切り替えを許可しますか? + 允许切换至蓝方? 允許切換至藍方? - 청군 인원으로 전환합니까? + 청군 인원으로 변경하는 것을 허락합니까? Switch to East? @@ -98,14 +121,15 @@ Nach OPFOR wechseln? Přesunout k OPFOR? Trocar para Leste? - Changer en EST? + Passage en OPFOR Átváltás OPFOR-ra? На красных? Cambia per OPFOR? - OPFOR軍側へ切り替えますか? - 切换至红方? + OPFOR軍へ切り替える? + 切换至红方? 切換至紅方? - 대항군으로 전환합니까? + 대항군으로 변경합니까? + Doğuya Geç ? Allow switching to east units? @@ -114,14 +138,14 @@ Erlaube das Wechseln zu OPFOR-Einheiten? Povolit přesun k OPFOR? Permitir troca de unidades para o Leste? - Permettre le changement en unité EST? + Autorise le passage en unité OPFOR. Kelet-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на красных юнитов? Consenti passaggio ad unità OPFOR? - OPFOR軍側ユニットへ切り替えられるようにしますか? - 允许切换至红方? + OPFOR軍ユニットへの切り替えを許可しますか? + 允许切换至红方? 允許切換至紅方? - 대항군 인원으로 전환합니까? + 대항군 인원으로 변경하는 것을 허락합니까? Switch to Independent? @@ -129,15 +153,16 @@ ¿Cambiar a Independiente? Nach INDFOR wechseln? Přesunout k INDFOR? - Trocar para Indenpendente - Changer en INDE? + Trocar para Independente + Passage en Indépendant Átváltás INDFOR-ra? На независимых? Cambia per INDFOR? - 独立軍へ切り替えますか? - 切换至独立方? + 独立軍へ切り替える? + 切换至独立方? 切換至獨立方? - 독립군 으로 전환합니까? + 무소속군으로 전환합니까? + Bağımsıza Geç? Allow switching to independent units? @@ -145,15 +170,15 @@ ¿Permitir cambios a unidades Independientes? Erlaube das Wechseln zu INDFOR-Einheiten? Povolit přesun k INDFOR? - Permitir troca de unidades para o Indenpendente? - Permettre le changement en unité INDE? + Permitir troca de unidades para o Independente? + Autorise le passage en unité Indépendante. Független egységekre való váltás engedélyezése? Разрешить переключаться на независимых юнитов? Consenti passaggio ad unità INDFOR? - 独立軍側ユニットへ切り替えられるようにしますか? - 允许切换至独立方? + 独立軍ユニットへの切り替えを許可しますか? + 允许切换至独立方? 允許切換至獨立方? - 독립군 인원으로 전환합니까? + 무소속군 인원으로 변경하는 것을 허락합니까? Switch to Civilian? @@ -162,14 +187,15 @@ Nach CIVILIAN wechseln? Přesunout k CIVILISTŮM? Trocar para Civis? - Changer en CIV? + Passage en Civil Átváltás civilre? На гражданских? Cambia per Civili? - 市民へ切り替えますか? + 市民へ切り替える? 민간인으로 전환합니까? - 切换至平民方? + 切换至平民方? 切換至平民方? + Sivillere Geç? Allow switching to civilian units? @@ -178,13 +204,13 @@ Erlaube das Wechseln zu CIVILIAN-Einheiten? Povolit přesun k CIVILISTŮM? Permitir troca de unidades para o Civil? - Permettre le changement en unité CIV? + Autorise le passage en unité Civile. Civil egységekre való váltás engedélyezése? Разрешить переключаться на гражданских юнитов? Consenti passaggio ad unità civili? - 市民側ユニットへ切り替えられるようにしますか? - 민간인으로 전환하는걸 허가합니까? - 允许切换至平民方? + 市民ユニットへの切り替えを許可しますか? + 민간인으로 변경하는걸 허가합니까? + 允许切换至平民方? 允許切換至平民方? @@ -194,13 +220,13 @@ Aktiviere Sicherheitszone? Povolit bezpečné oblasti? Habilitar zona segura? - Activer la zone sécurisée? + Créer une zone sécurisée Biztonságos zóna engedélyezése? Безопасная зона Abilita Zona Sicura? - 安全地帯を有効にしますか? - 안전 지대 활성화? - 启用安全区? + 安全地帯を有効化 + 안전지대 활성화 + 启用安全区? 啟用安全區? @@ -208,15 +234,15 @@ Aktywuje bezpieczną strefę wokół jednostek przeciwnika. Gracze nie mogą zmieniać strony wewnątrz tej strefy. Habilita una zona segura alrededor de las unidades enemigas. Los jugadores no pueden cambiar de unidad dentro de la zona segura. Aktiviere eine Sicherheitszone um feindliche Einheiten? Spieler können nicht zu Einheiten in der Sicherheitszone wechseln. - Povolit bezpečnou zónu kolem nepřátelských jednotek? Hráči se nemohou změnit strany/jednotky uvnitř bezpečné zóny. - Habilitar uma zona segur ao redor das unidades inimigas? Jogadores não conseguirão trocar para unidades dentro dessa zona segura. - Activer une zone sécurisée autour des enemis ? Les joueurs ne peuvent changer d'unité dand la zone sécurisée + Povolit bezpečnou zónu kolem nepřátelských jednotek? Hráči nemohou změnit strany/jednotky uvnitř bezpečné zóny. + Habilitar uma zona segura ao redor das unidades inimigas? Jogadores não conseguirão trocar para unidades dentro dessa zona segura. + Active une zone de sécurité autour des unités ennemies. Les joueurs ne peuvent pas changer de camp à l'intérieur de cette zone. Engedélyezve legyen-e egy biztonságos zóna az ellenségek körül? A játékosok nem tudnak a biztonságos zónán belüli egységekre váltani. Включить безопасную зону вокруг вражеских юнитов? Игроки не могут переключаться на юнитов, находящихся в безопасной зоне. Abilita una zona sicura attorno ad unità nemiche? I giocatori non possono cambiare ad unità dentro la zona sicura. - 敵ユニットから逃れる安全地帯を有効にしますか?プレイヤーは安全地帯内のユニットへ切り替えできません。 - 적 주위로 안전 지대를 활성화합니까? 안전 지대 내에서는 플레이어가 인원 전환을 할 수 없습니다. - 启用敌方周围安全地带? 玩家不能切换到安全区内的单位 + 敵ユニットの周囲に安全地帯を確保しますか? プレイヤーは安全地帯内のユニットに切り替えることはできません。 + 적 주위로 안전지대를 활성화합니까? 안전지대 내에서는 플레이어가 인원 전환을 할 수 없습니다. + 启用敌方周围安全地带? 玩家不能切换到安全区内的单位 啟用敵方周圍安全地帶? 玩家不能切換到安全區內的單位 @@ -231,7 +257,7 @@ Радиус безопасной зоны Raggio Zona Sicura 安全地帯の半径 - 안전 지대 반경 + 안전지대 반경 安全区半径 安全區半徑 @@ -242,11 +268,11 @@ Die Sicherheitszone um Spieler von einem anderen Team. Standard: 100 Bezpečná zóna kolem hráče z jiných týmu. Výchozí: 100 A zona segura ao redor dos jogadores de diferentes equipes. Padrão: 100 - Rayon de la zone sécurisée autour de joueurs d'équipe différentes. Défaut: 100 + Rayon de la zone de sécurité autour des joueurs d'équipes différentes. Valeur par défaut : 100 mètres. A biztonságos zóna más csapatból lévő játékosok körül. Alapértelmezett: 100 - Радиус безопасной зоны вокруг ироков из противоположной команды. По-умолчанию: 100 + Радиус безопасной зоны вокруг ироков из противоположной команды. По умолчанию: 100 La zona sicura attorno ai giocatori di un team diverso. Default: 100 - 別のチームへのプレイヤーの周囲にある安全地帯の範囲。標準: 100 + 別のチームのプレイヤーの周囲にある安全地帯の範囲。 デフォルト: 100 다른 진영으로 부터의 플레이어 안전 지대. 기본설정: 100 安全区的范围。预设值:100 安全區的範圍。預設值:100 @@ -258,10 +284,10 @@ Tento modul umožňuje přepínání mazi dostupnými stranami. Este módulo permite mudar o lado à disposição dos jogadores. Этот модуль позволяет игрокам переключаться между доступными юнитами. - Ce module permet le changement de faction des joueurs + Ce module vous permet de changer de camp en cours de partie. Questo modulo ti permette di cambiare lato durante la partita. El módulo permite a las unidades cambiar de bando durante el juego. - モジュールはゲームにおいて、陣営の切り替えを有効にします。 + モジュールを使用すると、ゲーム中に陣営を切り替えることが出来るようになります。 이 모듈은 당신을 게임 중에 진영을 바꿀 수 있게 해줍니다. 此模块允许你在游戏中切换至另一方 此模塊允許你在遊戲中切換至另一方 diff --git a/addons/tacticalladder/CfgEventHandlers.hpp b/addons/tacticalladder/CfgEventHandlers.hpp index 5b2eb3a053..48780d7241 100644 --- a/addons/tacticalladder/CfgEventHandlers.hpp +++ b/addons/tacticalladder/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; @@ -27,6 +27,6 @@ class Extended_Killed_EventHandlers { class Extended_DisplayLoad_EventHandlers { class RscDisplayMission { - ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); }; }; diff --git a/addons/tacticalladder/README.md b/addons/tacticalladder/README.md index c4b84b1613..8dab8141c1 100644 --- a/addons/tacticalladder/README.md +++ b/addons/tacticalladder/README.md @@ -2,10 +2,3 @@ ace_tacticalladder =============== Adds a packable tactical ladder. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/tacticalladder/XEH_postInit.sqf b/addons/tacticalladder/XEH_postInit.sqf index 1a6f356fb0..c4b25a77ab 100644 --- a/addons/tacticalladder/XEH_postInit.sqf +++ b/addons/tacticalladder/XEH_postInit.sqf @@ -17,10 +17,10 @@ GVAR(currentAngle) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel adjusting on player change. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle falling unconscious -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; // @todo captivity? diff --git a/addons/tacticalladder/config.cpp b/addons/tacticalladder/config.cpp index def7b0ce96..1060300de5 100644 --- a/addons/tacticalladder/config.cpp +++ b/addons/tacticalladder/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {}; + units[] = {"ACE_TacticalLadder_Pack"}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_apl", "ace_interaction"}; diff --git a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf index f8e2ce9f3a..7c05cbbe63 100644 --- a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg, commy2 * Cancel tactical ladder deployment diff --git a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf index 755d13d132..9fe13e4e65 100644 --- a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg, commy2 * Confirm tactical ladder deployment @@ -23,7 +23,7 @@ params ["_unit", "_ladder"]; [_unit, "blockThrow", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); private _pos1 = getPosASL _ladder; -private _pos2 = AGLToASL (_ladder modelToWorld (_ladder selectionPosition "check2")); +private _pos2 = _ladder modelToWorldWorld (_ladder selectionPosition "check2"); if (lineIntersects [_pos1, _pos2, _ladder]) exitWith {false}; diff --git a/addons/tacticalladder/functions/fnc_deployTL.sqf b/addons/tacticalladder/functions/fnc_deployTL.sqf index 1005cf5100..0f399536f4 100644 --- a/addons/tacticalladder/functions/fnc_deployTL.sqf +++ b/addons/tacticalladder/functions/fnc_deployTL.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Deploy tactical ladder @@ -23,7 +23,7 @@ removeBackpack _unit; private _pos = _unit modelToWorld [0,0,0]; -private _offset = if ((_unit call CBA_fnc_getUnitAnim select 0) == "prone") then { 1 } else {0.8}; +private _offset = [0.8, 1] select (_unit call CBA_fnc_getUnitAnim select 0 == "prone"); _pos set [0, (_pos select 0) + (sin getDir _unit) * _offset]; _pos set [1, (_pos select 1) + (cos getDir _unit) * _offset]; diff --git a/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf b/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf index 54963d00ae..ef3c35be86 100644 --- a/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. diff --git a/addons/tacticalladder/functions/fnc_handleKilled.sqf b/addons/tacticalladder/functions/fnc_handleKilled.sqf index a67b41368e..f5b87bfaaf 100644 --- a/addons/tacticalladder/functions/fnc_handleKilled.sqf +++ b/addons/tacticalladder/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle death. diff --git a/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf b/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf index 25be5fe7bf..be8a74c456 100644 --- a/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf +++ b/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle player changes. diff --git a/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf b/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf index 4e46b61d4e..821f62d708 100644 --- a/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf +++ b/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Handles lengthening and tilting of the ladder diff --git a/addons/tacticalladder/functions/fnc_handleUnconscious.sqf b/addons/tacticalladder/functions/fnc_handleUnconscious.sqf index ed966a9f72..b555b069ac 100644 --- a/addons/tacticalladder/functions/fnc_handleUnconscious.sqf +++ b/addons/tacticalladder/functions/fnc_handleUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle unconsciousness. diff --git a/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf b/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf index 5af9ecaafd..13ab990f39 100644 --- a/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf +++ b/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Checks if Tactical Ladder is empty (no one climbing it). diff --git a/addons/tacticalladder/functions/fnc_pickupTL.sqf b/addons/tacticalladder/functions/fnc_pickupTL.sqf index 76cbea27d6..4c0890eb4b 100644 --- a/addons/tacticalladder/functions/fnc_pickupTL.sqf +++ b/addons/tacticalladder/functions/fnc_pickupTL.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg, commy2 * Pick up tactical ladder diff --git a/addons/tacticalladder/functions/fnc_positionTL.sqf b/addons/tacticalladder/functions/fnc_positionTL.sqf index bbfd877c2f..6d6f78f1a3 100644 --- a/addons/tacticalladder/functions/fnc_positionTL.sqf +++ b/addons/tacticalladder/functions/fnc_positionTL.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Position tactical ladder @@ -26,7 +26,7 @@ params ["_unit", "_ladder"]; { _ladder animate [_x, 0]; -} count __ANIMS; +} forEach __ANIMS; [_unit, "amovpercmstpslowwrfldnon_player_idlesteady03", 2] call EFUNC(common,doAnimation); @@ -35,7 +35,7 @@ _ladder attachTo [_unit, [0, 0.75, 0], ""]; // Position ladder in front of playe _ladder animate ["rotate", 0]; { _ladder animate [_x, 1]; -} count ["extract_1", "extract_2", "extract_3"]; // Extract ladder at head height (extract_3) +} forEach ["extract_1", "extract_2", "extract_3"]; // Extract ladder at head height (extract_3) GVAR(ladder) = _ladder; GVAR(cancelTime) = CBA_missionTime + 1; // Workaround to prevent accidental canceling diff --git a/addons/tacticalladder/functions/script_component.hpp b/addons/tacticalladder/functions/script_component.hpp deleted file mode 100644 index 53bdb8be62..0000000000 --- a/addons/tacticalladder/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\tacticalladder\script_component.hpp" \ No newline at end of file diff --git a/addons/tacticalladder/stringtable.xml b/addons/tacticalladder/stringtable.xml index bec5b05e64..a7d33865f9 100644 --- a/addons/tacticalladder/stringtable.xml +++ b/addons/tacticalladder/stringtable.xml @@ -1,21 +1,22 @@ - + Telescopic Ladder Teleskopleiter Телескопическая лестница Drabina teleskopowa Escalera telescópica - Echelle téléscopique + Echelle télescopique Teleskopický žebřík Scala Telescopica Teleszkopikus létra Escada telescópica - タクティカル ラダー - 로프 사다리 + 伸縮はしご + 접이식 사다리 伸缩梯子 伸縮梯子 + Katlanabilir Merdiven Deploy ladder @@ -28,10 +29,11 @@ Piazza scala Létra lerakása Implantar escada - ラダーを設置 + はしごを設置 사다리 배치 - 布署梯子 + 部署梯子 佈署梯子 + Merdiveni Konuşlandır Drop ladder @@ -39,43 +41,45 @@ Положить лестницу Zostaw drabinę Soltar escalera - Lacher l'échelle + Lâcher l'échelle Položit žebřík Lascia scala Létra eldobása Derrubar escada - ラダーを落とす - 사다리 놓기 + はしごを落とす + 사다리 내려놓기 降下梯子 降下梯子 + Merdiveni Bırak Extend Ausfahren Rozłóż - Extender + Estender Разложить Prodloužit Estendi Extender - Déployer + Ajuster 伸ばす 늘리기 伸长梯子 伸長梯子 + Uzat +Ctrl tilt +Strg kippen +Ctrl nachyl - +Ctrl tilt + +Ctrl inclinar +Ctrl наклонить +Ctrl naklonit +Ctrl inclinar +Ctrl incliner +Ctrl per inclinare +Ctrl で傾ける - +컨트롤키 기울이기 + +컨트롤 키 기울이기 +Ctrl 倾斜 +Ctrl 傾斜 @@ -90,10 +94,11 @@ Posiziona scala Létra elhelyezése Posicionar escada - ラダーの位置 - 사다리 위치 + はしごの位置 + 사다리 설치 梯子位置 梯子位置 + Merdiveni Taşı Pickup ladder @@ -101,15 +106,16 @@ Взять лестницу Zabierz drabinę Recoger escalera - Prendre l'échelle + Récupérer l'échelle Vzít žebřík Prendi scala Létra felvétele Pegar escada - ラダーを拾う + はしごを拾う 사다리 줍기 捡起梯子 撿起梯子 + Merdiveni Al diff --git a/addons/tagging/ACE_Settings.hpp b/addons/tagging/ACE_Settings.hpp index a536718795..af9bca12d1 100644 --- a/addons/tagging/ACE_Settings.hpp +++ b/addons/tagging/ACE_Settings.hpp @@ -1,11 +1,5 @@ class ACE_Settings { class GVAR(quickTag) { - category = CSTRING(Tagging); - displayName = CSTRING(QuickTag); - description = CSTRING(QuickTagDesc); - typeName = "SCALAR"; - value = 1; - values[] = {ECSTRING(Common,Disabled), CSTRING(LastUsed), CSTRING(RandomX), CSTRING(Random)}; - isClientSettable = 1; + movedToSQF = 1; }; }; diff --git a/addons/tagging/ACE_Tags.hpp b/addons/tagging/ACE_Tags.hpp index 78762cf888..806dfdf5dd 100644 --- a/addons/tagging/ACE_Tags.hpp +++ b/addons/tagging/ACE_Tags.hpp @@ -1,26 +1,118 @@ +#define GLUE(g1,g2) g1##g2 +#define TAG(name,col) class TRIPLES(ACE,name,col) { \ + displayName = CSTRING(name); \ + requiredItem = QUOTE(GLUE(ACE_Spraypaint,col)); \ + textures[] = {QPATHTOF(UI\tags\col\name.paa)}; \ + icon = QPATHTOF(UI\tags\col\name.paa); \ + } + class ACE_Tags { class ACE_XBlack { - displayName = CSTRING(XBlack); + displayName = CSTRING(x); requiredItem = "ACE_SpraypaintBlack"; textures[] = {QPATHTOF(UI\tags\black\0.paa), QPATHTOF(UI\tags\black\1.paa), QPATHTOF(UI\tags\black\2.paa)}; - icon = QPATHTOF(UI\icons\iconTaggingBlack.paa); + icon = QPATHTOF(UI\tags\black\0.paa); }; class ACE_XRed { - displayName = CSTRING(XRed); + displayName = CSTRING(x); requiredItem = "ACE_SpraypaintRed"; textures[] = {QPATHTOF(UI\tags\red\0.paa), QPATHTOF(UI\tags\red\1.paa), QPATHTOF(UI\tags\red\2.paa)}; - icon = QPATHTOF(UI\icons\iconTaggingRed.paa); + icon = QPATHTOF(UI\tags\red\0.paa); }; class ACE_XGreen { - displayName = CSTRING(XGreen); + displayName = CSTRING(x); requiredItem = "ACE_SpraypaintGreen"; textures[] = {QPATHTOF(UI\tags\green\0.paa), QPATHTOF(UI\tags\green\1.paa), QPATHTOF(UI\tags\green\2.paa)}; - icon = QPATHTOF(UI\icons\iconTaggingGreen.paa); + icon = QPATHTOF(UI\tags\green\0.paa); }; class ACE_XBlue { - displayName = CSTRING(XBlue); + displayName = CSTRING(x); requiredItem = "ACE_SpraypaintBlue"; textures[] = {QPATHTOF(UI\tags\blue\0.paa), QPATHTOF(UI\tags\blue\1.paa), QPATHTOF(UI\tags\blue\2.paa)}; - icon = QPATHTOF(UI\icons\iconTaggingBlue.paa); + icon = QPATHTOF(UI\tags\blue\0.paa); }; + class ACE_XYellow { + displayName = CSTRING(x); + requiredItem = "ACE_SpraypaintYellow"; + textures[] = {QPATHTOF(UI\tags\yellow\0.paa), QPATHTOF(UI\tags\yellow\1.paa), QPATHTOF(UI\tags\yellow\2.paa)}; + icon = QPATHTOF(UI\tags\yellow\0.paa); + }; + class ACE_XWhite { + displayName = CSTRING(x); + requiredItem = "ACE_SpraypaintWhite"; + textures[] = {QPATHTOF(UI\tags\white\0.paa), QPATHTOF(UI\tags\white\1.paa), QPATHTOF(UI\tags\white\2.paa)}; + icon = QPATHTOF(UI\tags\white\0.paa); + }; + + TAG(arrow_up,Black); + TAG(arrow_down,Black); + TAG(arrow_left,Black); + TAG(arrow_right,Black); + TAG(circle,Black); + TAG(cross,Black); + TAG(diamond,Black); + TAG(square,Black); + TAG(square_filled,Black); + TAG(triangle,Black); + TAG(triangle_inverted,Black); + + TAG(arrow_up,Blue); + TAG(arrow_down,Blue); + TAG(arrow_left,Blue); + TAG(arrow_right,Blue); + TAG(circle,Blue); + TAG(cross,Blue); + TAG(diamond,Blue); + TAG(square,Blue); + TAG(square_filled,Blue); + TAG(triangle,Blue); + TAG(triangle_inverted,Blue); + + TAG(arrow_up,Green); + TAG(arrow_down,Green); + TAG(arrow_left,Green); + TAG(arrow_right,Green); + TAG(circle,Green); + TAG(cross,Green); + TAG(diamond,Green); + TAG(square,Green); + TAG(square_filled,Green); + TAG(triangle,Green); + TAG(triangle_inverted,Green); + + TAG(arrow_up,Red); + TAG(arrow_down,Red); + TAG(arrow_left,Red); + TAG(arrow_right,Red); + TAG(circle,Red); + TAG(cross,Red); + TAG(diamond,Red); + TAG(square,Red); + TAG(square_filled,Red); + TAG(triangle,Red); + TAG(triangle_inverted,Red); + + TAG(arrow_up,Yellow); + TAG(arrow_down,Yellow); + TAG(arrow_left,Yellow); + TAG(arrow_right,Yellow); + TAG(circle,Yellow); + TAG(cross,Yellow); + TAG(diamond,Yellow); + TAG(square,Yellow); + TAG(square_filled,Yellow); + TAG(triangle,Yellow); + TAG(triangle_inverted,Yellow); + + TAG(arrow_up,White); + TAG(arrow_down,White); + TAG(arrow_left,White); + TAG(arrow_right,White); + TAG(circle,White); + TAG(cross,White); + TAG(diamond,White); + TAG(square,White); + TAG(square_filled,White); + TAG(triangle,White); + TAG(triangle_inverted,White); }; diff --git a/addons/tagging/CfgEden.hpp b/addons/tagging/CfgEden.hpp new file mode 100644 index 0000000000..ac9f5e25da --- /dev/null +++ b/addons/tagging/CfgEden.hpp @@ -0,0 +1,20 @@ +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class GVAR(stencilVehicle) { + property = QGVAR(stencilVehicle); + control = "Edit"; + displayName = CSTRING(stencilVehicle); + tooltip = CSTRING(stencilVehicle_tooltip); + expression = QUOTE([ARR_2(_this,_value)] call FUNC(stencilVehicle)); + condition = "objectVehicle"; + defaultValue = "''"; + typeName = "STRING"; + }; + }; + }; + }; + }; +}; diff --git a/addons/tagging/CfgEventHandlers.hpp b/addons/tagging/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/tagging/CfgEventHandlers.hpp +++ b/addons/tagging/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/tagging/CfgVehicles.hpp b/addons/tagging/CfgVehicles.hpp index 204e902641..9263573425 100644 --- a/addons/tagging/CfgVehicles.hpp +++ b/addons/tagging/CfgVehicles.hpp @@ -53,6 +53,17 @@ class CfgVehicles { }; }; + class LandVehicle; + class Car: LandVehicle { + GVAR(canTag) = 1; + }; + class Tank: LandVehicle { + GVAR(canTag) = 1; + }; + class Air; + class Helicopter: Air { + GVAR(canTag) = 1; + }; class Item_Base_F; class ACE_Item_SpraypaintBlack: Item_Base_F { @@ -83,6 +94,18 @@ class CfgVehicles { MACRO_ADDITEM(ACE_SpraypaintBlue,1); }; }; + class ACE_Item_SpraypaintYellow: ACE_Item_SpraypaintBlack { + displayName = CSTRING(SpraypaintYellow); + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintYellow,1); + }; + }; + class ACE_Item_SpraypaintWhite: ACE_Item_SpraypaintBlack { + displayName = CSTRING(SpraypaintWhite); + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintWhite,1); + }; + }; class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { @@ -91,6 +114,8 @@ class CfgVehicles { MACRO_ADDITEM(ACE_SpraypaintRed,5); MACRO_ADDITEM(ACE_SpraypaintBlue,5); MACRO_ADDITEM(ACE_SpraypaintGreen,5); + MACRO_ADDITEM(ACE_SpraypaintYellow,5); + MACRO_ADDITEM(ACE_SpraypaintWhite,5); }; }; }; diff --git a/addons/tagging/CfgWeapons.hpp b/addons/tagging/CfgWeapons.hpp index 4405696a08..906b990f81 100644 --- a/addons/tagging/CfgWeapons.hpp +++ b/addons/tagging/CfgWeapons.hpp @@ -2,7 +2,7 @@ class CfgWeapons { class ACE_ItemCore; class CBA_MiscItem_ItemInfo; - class ACE_SpraypaintBlack : ACE_ItemCore { + class ACE_SpraypaintBlack: ACE_ItemCore { author = "jokoho48"; displayname = CSTRING(spraypaintBlack); descriptionShort = CSTRING(descSpraypaint); @@ -14,20 +14,36 @@ class CfgWeapons { class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; + GVAR(textColor) = "000000FE"; }; - class ACE_SpraypaintRed : ACE_SpraypaintBlack { + class ACE_SpraypaintRed: ACE_SpraypaintBlack { displayname = CSTRING(spraypaintRed); picture = QPATHTOF(UI\items\itemSpraypaintRed.paa); hiddenSelectionsTextures[] = {QPATHTOF(data\spraycanRed_co.paa)}; + GVAR(textColor) = "FF0000FE"; }; - class ACE_SpraypaintGreen : ACE_SpraypaintBlack { + class ACE_SpraypaintGreen: ACE_SpraypaintBlack { displayname = CSTRING(spraypaintGreen); picture = QPATHTOF(UI\items\itemSpraypaintGreen.paa); hiddenSelectionsTextures[] = {QPATHTOF(data\spraycanGreen_co.paa)}; + GVAR(textColor) = "00FF00FE"; }; - class ACE_SpraypaintBlue : ACE_SpraypaintBlack { + class ACE_SpraypaintBlue: ACE_SpraypaintBlack { displayname = CSTRING(spraypaintBlue); picture = QPATHTOF(UI\items\itemSpraypaintBlue.paa); hiddenSelectionsTextures[] = {QPATHTOF(data\spraycanBlue_co.paa)}; + GVAR(textColor) = "0000FFFE"; + }; + class ACE_SpraypaintYellow: ACE_SpraypaintBlack { + displayname = CSTRING(spraypaintYellow); + picture = QPATHTOF(UI\items\itemSpraypaintYellow.paa); + hiddenSelectionsTextures[] = {QPATHTOF(data\spraycanYellow_co.paa)}; + GVAR(textColor) = "FFFF00FE"; + }; + class ACE_SpraypaintWhite: ACE_SpraypaintBlack { + displayname = CSTRING(spraypaintWhite); + picture = QPATHTOF(UI\items\itemSpraypaintWhite.paa); + hiddenSelectionsTextures[] = {QPATHTOF(data\spraycanWhite_co.paa)}; + GVAR(textColor) = "FFFFFFFE"; }; }; diff --git a/addons/tagging/README.md b/addons/tagging/README.md index 1e41cb0c2d..675da9d755 100644 --- a/addons/tagging/README.md +++ b/addons/tagging/README.md @@ -2,11 +2,3 @@ ace_tagging =============== Adds a can of spray paint which allows you to tag buildings, walls and other static objects. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [BaerMitUmlaut](https://github.com/BaerMitUmlaut) -- [Jonpas](https://github.com/jonpas) diff --git a/addons/tagging/UI/icons/iconTaggingWhite.paa b/addons/tagging/UI/icons/iconTaggingWhite.paa new file mode 100644 index 0000000000..8d97ddca06 Binary files /dev/null and b/addons/tagging/UI/icons/iconTaggingWhite.paa differ diff --git a/addons/tagging/UI/icons/iconTaggingYellow.paa b/addons/tagging/UI/icons/iconTaggingYellow.paa new file mode 100644 index 0000000000..46a0624da8 Binary files /dev/null and b/addons/tagging/UI/icons/iconTaggingYellow.paa differ diff --git a/addons/tagging/UI/items/itemSpraypaintWhite.paa b/addons/tagging/UI/items/itemSpraypaintWhite.paa new file mode 100644 index 0000000000..0e7e16af78 Binary files /dev/null and b/addons/tagging/UI/items/itemSpraypaintWhite.paa differ diff --git a/addons/tagging/UI/items/itemSpraypaintYellow.paa b/addons/tagging/UI/items/itemSpraypaintYellow.paa new file mode 100644 index 0000000000..59d9fb2ba2 Binary files /dev/null and b/addons/tagging/UI/items/itemSpraypaintYellow.paa differ diff --git a/addons/tagging/UI/tags/black/arrow_down.paa b/addons/tagging/UI/tags/black/arrow_down.paa new file mode 100644 index 0000000000..cdaabc04ee Binary files /dev/null and b/addons/tagging/UI/tags/black/arrow_down.paa differ diff --git a/addons/tagging/UI/tags/black/arrow_left.paa b/addons/tagging/UI/tags/black/arrow_left.paa new file mode 100644 index 0000000000..caa40c3c51 Binary files /dev/null and b/addons/tagging/UI/tags/black/arrow_left.paa differ diff --git a/addons/tagging/UI/tags/black/arrow_right.paa b/addons/tagging/UI/tags/black/arrow_right.paa new file mode 100644 index 0000000000..da015c37cf Binary files /dev/null and b/addons/tagging/UI/tags/black/arrow_right.paa differ diff --git a/addons/tagging/UI/tags/black/arrow_up.paa b/addons/tagging/UI/tags/black/arrow_up.paa new file mode 100644 index 0000000000..575aeaea92 Binary files /dev/null and b/addons/tagging/UI/tags/black/arrow_up.paa differ diff --git a/addons/tagging/UI/tags/black/circle.paa b/addons/tagging/UI/tags/black/circle.paa new file mode 100644 index 0000000000..c89cf93306 Binary files /dev/null and b/addons/tagging/UI/tags/black/circle.paa differ diff --git a/addons/tagging/UI/tags/black/cross.paa b/addons/tagging/UI/tags/black/cross.paa new file mode 100644 index 0000000000..a784b63211 Binary files /dev/null and b/addons/tagging/UI/tags/black/cross.paa differ diff --git a/addons/tagging/UI/tags/black/diamond.paa b/addons/tagging/UI/tags/black/diamond.paa new file mode 100644 index 0000000000..8d158348f9 Binary files /dev/null and b/addons/tagging/UI/tags/black/diamond.paa differ diff --git a/addons/tagging/UI/tags/black/square.paa b/addons/tagging/UI/tags/black/square.paa new file mode 100644 index 0000000000..0d288a3002 Binary files /dev/null and b/addons/tagging/UI/tags/black/square.paa differ diff --git a/addons/tagging/UI/tags/black/square_filled.paa b/addons/tagging/UI/tags/black/square_filled.paa new file mode 100644 index 0000000000..a4d2c37bab Binary files /dev/null and b/addons/tagging/UI/tags/black/square_filled.paa differ diff --git a/addons/tagging/UI/tags/black/triangle.paa b/addons/tagging/UI/tags/black/triangle.paa new file mode 100644 index 0000000000..5a29bcdfb3 Binary files /dev/null and b/addons/tagging/UI/tags/black/triangle.paa differ diff --git a/addons/tagging/UI/tags/black/triangle_inverted.paa b/addons/tagging/UI/tags/black/triangle_inverted.paa new file mode 100644 index 0000000000..46eaf69487 Binary files /dev/null and b/addons/tagging/UI/tags/black/triangle_inverted.paa differ diff --git a/addons/tagging/UI/tags/blue/arrow_down.paa b/addons/tagging/UI/tags/blue/arrow_down.paa new file mode 100644 index 0000000000..bbd6eb63ac Binary files /dev/null and b/addons/tagging/UI/tags/blue/arrow_down.paa differ diff --git a/addons/tagging/UI/tags/blue/arrow_left.paa b/addons/tagging/UI/tags/blue/arrow_left.paa new file mode 100644 index 0000000000..9b70ebfb00 Binary files /dev/null and b/addons/tagging/UI/tags/blue/arrow_left.paa differ diff --git a/addons/tagging/UI/tags/blue/arrow_right.paa b/addons/tagging/UI/tags/blue/arrow_right.paa new file mode 100644 index 0000000000..7c7ac2af6b Binary files /dev/null and b/addons/tagging/UI/tags/blue/arrow_right.paa differ diff --git a/addons/tagging/UI/tags/blue/arrow_up.paa b/addons/tagging/UI/tags/blue/arrow_up.paa new file mode 100644 index 0000000000..976151c245 Binary files /dev/null and b/addons/tagging/UI/tags/blue/arrow_up.paa differ diff --git a/addons/tagging/UI/tags/blue/circle.paa b/addons/tagging/UI/tags/blue/circle.paa new file mode 100644 index 0000000000..f841ac9caa Binary files /dev/null and b/addons/tagging/UI/tags/blue/circle.paa differ diff --git a/addons/tagging/UI/tags/blue/cross.paa b/addons/tagging/UI/tags/blue/cross.paa new file mode 100644 index 0000000000..0235a9361a Binary files /dev/null and b/addons/tagging/UI/tags/blue/cross.paa differ diff --git a/addons/tagging/UI/tags/blue/diamond.paa b/addons/tagging/UI/tags/blue/diamond.paa new file mode 100644 index 0000000000..d66fc599ee Binary files /dev/null and b/addons/tagging/UI/tags/blue/diamond.paa differ diff --git a/addons/tagging/UI/tags/blue/square.paa b/addons/tagging/UI/tags/blue/square.paa new file mode 100644 index 0000000000..6eec9cd3ed Binary files /dev/null and b/addons/tagging/UI/tags/blue/square.paa differ diff --git a/addons/tagging/UI/tags/blue/square_filled.paa b/addons/tagging/UI/tags/blue/square_filled.paa new file mode 100644 index 0000000000..81af837a01 Binary files /dev/null and b/addons/tagging/UI/tags/blue/square_filled.paa differ diff --git a/addons/tagging/UI/tags/blue/triangle.paa b/addons/tagging/UI/tags/blue/triangle.paa new file mode 100644 index 0000000000..80674f1495 Binary files /dev/null and b/addons/tagging/UI/tags/blue/triangle.paa differ diff --git a/addons/tagging/UI/tags/blue/triangle_inverted.paa b/addons/tagging/UI/tags/blue/triangle_inverted.paa new file mode 100644 index 0000000000..161404bc1a Binary files /dev/null and b/addons/tagging/UI/tags/blue/triangle_inverted.paa differ diff --git a/addons/tagging/UI/tags/green/arrow_down.paa b/addons/tagging/UI/tags/green/arrow_down.paa new file mode 100644 index 0000000000..c3c256beb2 Binary files /dev/null and b/addons/tagging/UI/tags/green/arrow_down.paa differ diff --git a/addons/tagging/UI/tags/green/arrow_left.paa b/addons/tagging/UI/tags/green/arrow_left.paa new file mode 100644 index 0000000000..b5c3f1cdaa Binary files /dev/null and b/addons/tagging/UI/tags/green/arrow_left.paa differ diff --git a/addons/tagging/UI/tags/green/arrow_right.paa b/addons/tagging/UI/tags/green/arrow_right.paa new file mode 100644 index 0000000000..4cd445cad9 Binary files /dev/null and b/addons/tagging/UI/tags/green/arrow_right.paa differ diff --git a/addons/tagging/UI/tags/green/arrow_up.paa b/addons/tagging/UI/tags/green/arrow_up.paa new file mode 100644 index 0000000000..949378dafc Binary files /dev/null and b/addons/tagging/UI/tags/green/arrow_up.paa differ diff --git a/addons/tagging/UI/tags/green/circle.paa b/addons/tagging/UI/tags/green/circle.paa new file mode 100644 index 0000000000..74e79b1d45 Binary files /dev/null and b/addons/tagging/UI/tags/green/circle.paa differ diff --git a/addons/tagging/UI/tags/green/cross.paa b/addons/tagging/UI/tags/green/cross.paa new file mode 100644 index 0000000000..db4a57222d Binary files /dev/null and b/addons/tagging/UI/tags/green/cross.paa differ diff --git a/addons/tagging/UI/tags/green/diamond.paa b/addons/tagging/UI/tags/green/diamond.paa new file mode 100644 index 0000000000..4ab45168d2 Binary files /dev/null and b/addons/tagging/UI/tags/green/diamond.paa differ diff --git a/addons/tagging/UI/tags/green/square.paa b/addons/tagging/UI/tags/green/square.paa new file mode 100644 index 0000000000..8cb639ed85 Binary files /dev/null and b/addons/tagging/UI/tags/green/square.paa differ diff --git a/addons/tagging/UI/tags/green/square_filled.paa b/addons/tagging/UI/tags/green/square_filled.paa new file mode 100644 index 0000000000..d08edea5d5 Binary files /dev/null and b/addons/tagging/UI/tags/green/square_filled.paa differ diff --git a/addons/tagging/UI/tags/green/triangle.paa b/addons/tagging/UI/tags/green/triangle.paa new file mode 100644 index 0000000000..bc570882fe Binary files /dev/null and b/addons/tagging/UI/tags/green/triangle.paa differ diff --git a/addons/tagging/UI/tags/green/triangle_inverted.paa b/addons/tagging/UI/tags/green/triangle_inverted.paa new file mode 100644 index 0000000000..ce6d43b692 Binary files /dev/null and b/addons/tagging/UI/tags/green/triangle_inverted.paa differ diff --git a/addons/tagging/UI/tags/red/arrow_down.paa b/addons/tagging/UI/tags/red/arrow_down.paa new file mode 100644 index 0000000000..7929adf188 Binary files /dev/null and b/addons/tagging/UI/tags/red/arrow_down.paa differ diff --git a/addons/tagging/UI/tags/red/arrow_left.paa b/addons/tagging/UI/tags/red/arrow_left.paa new file mode 100644 index 0000000000..6788c48858 Binary files /dev/null and b/addons/tagging/UI/tags/red/arrow_left.paa differ diff --git a/addons/tagging/UI/tags/red/arrow_right.paa b/addons/tagging/UI/tags/red/arrow_right.paa new file mode 100644 index 0000000000..afd12bff4f Binary files /dev/null and b/addons/tagging/UI/tags/red/arrow_right.paa differ diff --git a/addons/tagging/UI/tags/red/arrow_up.paa b/addons/tagging/UI/tags/red/arrow_up.paa new file mode 100644 index 0000000000..81e15bdf1b Binary files /dev/null and b/addons/tagging/UI/tags/red/arrow_up.paa differ diff --git a/addons/tagging/UI/tags/red/circle.paa b/addons/tagging/UI/tags/red/circle.paa new file mode 100644 index 0000000000..fb76c8f01f Binary files /dev/null and b/addons/tagging/UI/tags/red/circle.paa differ diff --git a/addons/tagging/UI/tags/red/cross.paa b/addons/tagging/UI/tags/red/cross.paa new file mode 100644 index 0000000000..882e79a57a Binary files /dev/null and b/addons/tagging/UI/tags/red/cross.paa differ diff --git a/addons/tagging/UI/tags/red/diamond.paa b/addons/tagging/UI/tags/red/diamond.paa new file mode 100644 index 0000000000..4f9b583af4 Binary files /dev/null and b/addons/tagging/UI/tags/red/diamond.paa differ diff --git a/addons/tagging/UI/tags/red/square.paa b/addons/tagging/UI/tags/red/square.paa new file mode 100644 index 0000000000..ec83e52244 Binary files /dev/null and b/addons/tagging/UI/tags/red/square.paa differ diff --git a/addons/tagging/UI/tags/red/square_filled.paa b/addons/tagging/UI/tags/red/square_filled.paa new file mode 100644 index 0000000000..815f6a2df9 Binary files /dev/null and b/addons/tagging/UI/tags/red/square_filled.paa differ diff --git a/addons/tagging/UI/tags/red/triangle.paa b/addons/tagging/UI/tags/red/triangle.paa new file mode 100644 index 0000000000..7f2b431201 Binary files /dev/null and b/addons/tagging/UI/tags/red/triangle.paa differ diff --git a/addons/tagging/UI/tags/red/triangle_inverted.paa b/addons/tagging/UI/tags/red/triangle_inverted.paa new file mode 100644 index 0000000000..8d2f818fd0 Binary files /dev/null and b/addons/tagging/UI/tags/red/triangle_inverted.paa differ diff --git a/addons/tagging/UI/tags/white/0.paa b/addons/tagging/UI/tags/white/0.paa new file mode 100644 index 0000000000..2a710e60f5 Binary files /dev/null and b/addons/tagging/UI/tags/white/0.paa differ diff --git a/addons/tagging/UI/tags/white/1.paa b/addons/tagging/UI/tags/white/1.paa new file mode 100644 index 0000000000..efa7d12c17 Binary files /dev/null and b/addons/tagging/UI/tags/white/1.paa differ diff --git a/addons/tagging/UI/tags/white/2.paa b/addons/tagging/UI/tags/white/2.paa new file mode 100644 index 0000000000..569cb118bc Binary files /dev/null and b/addons/tagging/UI/tags/white/2.paa differ diff --git a/addons/tagging/UI/tags/white/arrow_down.paa b/addons/tagging/UI/tags/white/arrow_down.paa new file mode 100644 index 0000000000..1b9f47390e Binary files /dev/null and b/addons/tagging/UI/tags/white/arrow_down.paa differ diff --git a/addons/tagging/UI/tags/white/arrow_left.paa b/addons/tagging/UI/tags/white/arrow_left.paa new file mode 100644 index 0000000000..7934c9caa1 Binary files /dev/null and b/addons/tagging/UI/tags/white/arrow_left.paa differ diff --git a/addons/tagging/UI/tags/white/arrow_right.paa b/addons/tagging/UI/tags/white/arrow_right.paa new file mode 100644 index 0000000000..9873324716 Binary files /dev/null and b/addons/tagging/UI/tags/white/arrow_right.paa differ diff --git a/addons/tagging/UI/tags/white/arrow_up.paa b/addons/tagging/UI/tags/white/arrow_up.paa new file mode 100644 index 0000000000..f388f29c30 Binary files /dev/null and b/addons/tagging/UI/tags/white/arrow_up.paa differ diff --git a/addons/tagging/UI/tags/white/circle.paa b/addons/tagging/UI/tags/white/circle.paa new file mode 100644 index 0000000000..769b96e15a Binary files /dev/null and b/addons/tagging/UI/tags/white/circle.paa differ diff --git a/addons/tagging/UI/tags/white/cross.paa b/addons/tagging/UI/tags/white/cross.paa new file mode 100644 index 0000000000..bbc2e44240 Binary files /dev/null and b/addons/tagging/UI/tags/white/cross.paa differ diff --git a/addons/tagging/UI/tags/white/diamond.paa b/addons/tagging/UI/tags/white/diamond.paa new file mode 100644 index 0000000000..3b2b17b424 Binary files /dev/null and b/addons/tagging/UI/tags/white/diamond.paa differ diff --git a/addons/tagging/UI/tags/white/square.paa b/addons/tagging/UI/tags/white/square.paa new file mode 100644 index 0000000000..680603d6d3 Binary files /dev/null and b/addons/tagging/UI/tags/white/square.paa differ diff --git a/addons/tagging/UI/tags/white/square_filled.paa b/addons/tagging/UI/tags/white/square_filled.paa new file mode 100644 index 0000000000..ffbe7eee81 Binary files /dev/null and b/addons/tagging/UI/tags/white/square_filled.paa differ diff --git a/addons/tagging/UI/tags/white/triangle.paa b/addons/tagging/UI/tags/white/triangle.paa new file mode 100644 index 0000000000..5d4bb9c6a9 Binary files /dev/null and b/addons/tagging/UI/tags/white/triangle.paa differ diff --git a/addons/tagging/UI/tags/white/triangle_inverted.paa b/addons/tagging/UI/tags/white/triangle_inverted.paa new file mode 100644 index 0000000000..ed543ec29b Binary files /dev/null and b/addons/tagging/UI/tags/white/triangle_inverted.paa differ diff --git a/addons/tagging/UI/tags/yellow/0.paa b/addons/tagging/UI/tags/yellow/0.paa new file mode 100644 index 0000000000..6b441ab22d Binary files /dev/null and b/addons/tagging/UI/tags/yellow/0.paa differ diff --git a/addons/tagging/UI/tags/yellow/1.paa b/addons/tagging/UI/tags/yellow/1.paa new file mode 100644 index 0000000000..5e4d2da5ef Binary files /dev/null and b/addons/tagging/UI/tags/yellow/1.paa differ diff --git a/addons/tagging/UI/tags/yellow/2.paa b/addons/tagging/UI/tags/yellow/2.paa new file mode 100644 index 0000000000..0e03b827f0 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/2.paa differ diff --git a/addons/tagging/UI/tags/yellow/arrow_down.paa b/addons/tagging/UI/tags/yellow/arrow_down.paa new file mode 100644 index 0000000000..d547bba0f2 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/arrow_down.paa differ diff --git a/addons/tagging/UI/tags/yellow/arrow_left.paa b/addons/tagging/UI/tags/yellow/arrow_left.paa new file mode 100644 index 0000000000..4a3e05bd2b Binary files /dev/null and b/addons/tagging/UI/tags/yellow/arrow_left.paa differ diff --git a/addons/tagging/UI/tags/yellow/arrow_right.paa b/addons/tagging/UI/tags/yellow/arrow_right.paa new file mode 100644 index 0000000000..aad867960b Binary files /dev/null and b/addons/tagging/UI/tags/yellow/arrow_right.paa differ diff --git a/addons/tagging/UI/tags/yellow/arrow_up.paa b/addons/tagging/UI/tags/yellow/arrow_up.paa new file mode 100644 index 0000000000..df2b2c505d Binary files /dev/null and b/addons/tagging/UI/tags/yellow/arrow_up.paa differ diff --git a/addons/tagging/UI/tags/yellow/circle.paa b/addons/tagging/UI/tags/yellow/circle.paa new file mode 100644 index 0000000000..d7d67b4b15 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/circle.paa differ diff --git a/addons/tagging/UI/tags/yellow/cross.paa b/addons/tagging/UI/tags/yellow/cross.paa new file mode 100644 index 0000000000..1cfcfef9b4 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/cross.paa differ diff --git a/addons/tagging/UI/tags/yellow/diamond.paa b/addons/tagging/UI/tags/yellow/diamond.paa new file mode 100644 index 0000000000..d2448d5f62 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/diamond.paa differ diff --git a/addons/tagging/UI/tags/yellow/square.paa b/addons/tagging/UI/tags/yellow/square.paa new file mode 100644 index 0000000000..fea44ea538 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/square.paa differ diff --git a/addons/tagging/UI/tags/yellow/square_filled.paa b/addons/tagging/UI/tags/yellow/square_filled.paa new file mode 100644 index 0000000000..f16e270fa4 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/square_filled.paa differ diff --git a/addons/tagging/UI/tags/yellow/triangle.paa b/addons/tagging/UI/tags/yellow/triangle.paa new file mode 100644 index 0000000000..0fc6917962 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/triangle.paa differ diff --git a/addons/tagging/UI/tags/yellow/triangle_inverted.paa b/addons/tagging/UI/tags/yellow/triangle_inverted.paa new file mode 100644 index 0000000000..ad6a3726f4 Binary files /dev/null and b/addons/tagging/UI/tags/yellow/triangle_inverted.paa differ diff --git a/addons/tagging/XEH_PREP.hpp b/addons/tagging/XEH_PREP.hpp index 44bd74b992..37898f31e9 100644 --- a/addons/tagging/XEH_PREP.hpp +++ b/addons/tagging/XEH_PREP.hpp @@ -1,10 +1,15 @@ PREP(addCustomTag); +PREP(addStencilTag); PREP(addTagActions); PREP(applyCustomTag); PREP(checkTaggable); PREP(compileConfigTags); +PREP(compileTagAction); PREP(createTag); +PREP(generateStencilTexture); PREP(moduleInit); +PREP(parseConfigTag); PREP(quickTag); +PREP(stencilVehicle); PREP(tag); PREP(tagTestingThread); diff --git a/addons/tagging/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf index 7fefa5757e..02e082648a 100644 --- a/addons/tagging/XEH_postInit.sqf +++ b/addons/tagging/XEH_postInit.sqf @@ -1,20 +1,12 @@ // by esteldunedain #include "script_component.hpp" - -// Cache for static objects -GVAR(cacheStaticModels) = [false] call CBA_fnc_createNamespace; -private _cacheStaticModels = call (uiNamespace getVariable [QGVAR(cacheStaticModels), {[]}]); -{ - GVAR(cacheStaticModels) setVariable [_x, true]; -} forEach _cacheStaticModels; - if (hasInterface) then { // Compile and cache config tags call FUNC(compileConfigTags); // Scripted tag adding EH - [QGVAR(applyCustomTag), FUNC(applyCustomTag)] call CBA_fnc_addEventHandler; + [QGVAR(applyCustomTag), LINKFUNC(applyCustomTag)] call CBA_fnc_addEventHandler; // Keybind ["ACE3 Equipment", QGVAR(quickTag), localize LSTRING(QuickTag), { @@ -32,4 +24,4 @@ if (!isServer) exitWith {}; GVAR(testingThread) = false; GVAR(tagsToTest) = []; -[QGVAR(createTag), DFUNC(createTag)] call CBA_fnc_addEventHandler; +[QGVAR(createTag), LINKFUNC(createTag)] call CBA_fnc_addEventHandler; diff --git a/addons/tagging/XEH_preInit.sqf b/addons/tagging/XEH_preInit.sqf index e1487c671f..d368b7c1c6 100644 --- a/addons/tagging/XEH_preInit.sqf +++ b/addons/tagging/XEH_preInit.sqf @@ -7,6 +7,8 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; GVAR(cachedTags) = []; -GVAR(cachedRequiredItems) = []; +GVAR(itemActions) = createHashMap; + +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/tagging/XEH_preStart.sqf b/addons/tagging/XEH_preStart.sqf index 342b4b6407..eb8f7ab767 100644 --- a/addons/tagging/XEH_preStart.sqf +++ b/addons/tagging/XEH_preStart.sqf @@ -4,7 +4,7 @@ private _cacheStaticModels = []; -private _vehicleClasses = "isClass _x && (configName _x) isKindOf 'Static'" configClasses (configFile >> "CfgVehicles"); +private _vehicleClasses = "(configName _x) isKindOf 'Static'" configClasses (configFile >> "CfgVehicles"); // Consider static everything vehicle that inherit from Static // This include houses (which we don't need), but also walls, that we do @@ -12,11 +12,11 @@ private _vehicleClasses = "isClass _x && (configName _x) isKindOf 'Static'" conf private _model = getText (_x >> "model"); if (_model != "") then { private _array = _model splitString "\"; - _cacheStaticModels pushBackUnique toLower (_array select ((count _array) - 1)); + _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; } forEach _vehicleClasses; -private _nonAIVehicleClasses = "isClass _x" configClasses (configFile >> "CfgNonAIVehicles"); +private _nonAIVehicleClasses = "true" configClasses (configFile >> "CfgNonAIVehicles"); // Also consider static all object inheriting from bridges private _cfgBase = configFile >> "CfgNonAIVehicles"; @@ -24,9 +24,13 @@ private _cfgBase = configFile >> "CfgNonAIVehicles"; private _model = getText (_x >> "model"); if (_model != "") then { private _array = _model splitString "\"; - _cacheStaticModels pushBackUnique toLower (_array select ((count _array) - 1)); + _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; -} forEach (_nonaivehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); +} forEach (_nonAIVehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); -uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal str _cacheStaticModels]; +uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal (_cacheStaticModels createHashMapFromArray [])]; TRACE_1("compiled",count _cacheStaticModels); + +// force preload of stencil texture to avoid error popup +// Warning Message: Cannot load mipmap z\ace\addons\fonts\sairastencilone\ace_stencil64-01.paa +"Test" getTextWidth ["ACE_Stencil", 0.3]; diff --git a/addons/tagging/config.cpp b/addons/tagging/config.cpp index 6ec32da0a6..ef24a9d2d3 100644 --- a/addons/tagging/config.cpp +++ b/addons/tagging/config.cpp @@ -19,3 +19,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" +#include "CfgEden.hpp" diff --git a/addons/tagging/data/spraycanWhite_co.paa b/addons/tagging/data/spraycanWhite_co.paa new file mode 100644 index 0000000000..85b86532a7 Binary files /dev/null and b/addons/tagging/data/spraycanWhite_co.paa differ diff --git a/addons/tagging/data/spraycanYellow_co.paa b/addons/tagging/data/spraycanYellow_co.paa new file mode 100644 index 0000000000..adff701bb8 Binary files /dev/null and b/addons/tagging/data/spraycanYellow_co.paa differ diff --git a/addons/tagging/functions/fnc_addCustomTag.sqf b/addons/tagging/functions/fnc_addCustomTag.sqf index 6dccf3bfb2..c99d1f4409 100644 --- a/addons/tagging/functions/fnc_addCustomTag.sqf +++ b/addons/tagging/functions/fnc_addCustomTag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Adds custom tag. Has to be executed on one machine only. @@ -9,10 +9,11 @@ * 2: Required Item * 3: Textures Paths * 4: Icon Path (default: "") - * 5: Material Paths (optional) + * 5: Material Paths (default: []) + * 6: Tag Model (default: "UserTexture1m_F") * * Return Value: - * Sucessfully Added Tag + * Successfully Added Tag * * Example: * ["ace_victoryRed", "Victory Red", "ACE_SpraypaintRed", ["path\to\texture1.paa", "path\to\texture2.paa"], "path\to\icon.paa"] call ace_tagging_fnc_addCustomTag @@ -26,30 +27,33 @@ params [ ["_requiredItem", "", [""]], ["_textures", [], [[]]], ["_icon", "", [""]], - ["_materials", [], [[]]] + ["_materials", [], [[]]], + ["_tagModel", "UserTexture1m_F", [""]] ]; // Verify if (_identifier == "") exitWith { - ERROR("Failed adding custom tag - missing identifier"); + ERROR("Failed adding custom tag - missing identifier"); false }; if (_displayName == "") exitWith { - ERROR_1("Failed adding custom tag: %1 - missing displayName",_identifier); + ERROR_1("Failed adding custom tag: %1 - missing displayName",_identifier); false }; if (_requiredItem == "") exitWith { - ERROR_1("Failed adding custom tag: %1 - missing requiredItem",_identifier); + ERROR_1("Failed adding custom tag: %1 - missing requiredItem",_identifier); false }; if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) exitWith { - ERROR_2("Failed adding custom tag: %1 - requiredItem %2 does not exist",_identifier,_requiredItem); + ERROR_2("Failed adding custom tag: %1 - requiredItem %2 does not exist",_identifier,_requiredItem); false }; if (_textures isEqualTo []) exitWith { - ERROR_1("Failed adding custom tag: %1 - missing textures",_identifier); + ERROR_1("Failed adding custom tag: %1 - missing textures",_identifier); false }; _identifier = [_identifier] call CBA_fnc_removeWhitespace; // Add -[QGVAR(applyCustomTag), [_identifier, _displayName, _requiredItem, _textures, _icon, _materials]] call CBA_fnc_globalEventJIP; +[QGVAR(applyCustomTag), [_identifier, _displayName, _requiredItem, _textures, _icon, _materials, _tagModel]] call CBA_fnc_globalEventJIP; + +true diff --git a/addons/tagging/functions/fnc_addStencilTag.sqf b/addons/tagging/functions/fnc_addStencilTag.sqf new file mode 100644 index 0000000000..f6613856a9 --- /dev/null +++ b/addons/tagging/functions/fnc_addStencilTag.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds custom text tag. Has to be executed on one machine only. + * + * Arguments: + * 0: Display Text + * 1: Text Size (default: 0.3) + * 2: Required Item (default: "ACE_SpraypaintBlack") + * 3: Text Color (in HEX 6 or 8) (default: based on spray item) + * 4: Background Color (in HEX 6 or 8) (default: "00000000" - transparent) + * 5: Auto newlines (default: true) + * + * Return Value: + * Sucessfully Added Tag + * + * Example: + * ["Orcs Go Home", 0.22] call ace_tagging_fnc_addStencilTag + * ["LOGI-2", 0.3, "ACE_SpraypaintBlack", "f7e9e1"] call ace_tagging_fnc_addStencilTag + * + * Public: Yes + */ + +params [ + ["_text", "", [""]], + ["_textSize", 0.3, [0]], + ["_requiredItem", "ACE_SpraypaintBlack", [""]], + ["_textColor", "", [""]], + ["_backgroundColor", "00000000", [""]], + ["_autoMultiline", true, [false]] +]; +TRACE_6("",_text,_textSize,_requiredItem,_textColor,_backgroundColor,_autoMultiline); + +if (_text == "") exitWith { ERROR_1("bad text %1",_text); false }; +// Check required item exists +if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) exitWith { ERROR_1("bad item %1",_requiredItem); false }; +// Get color from spray item used +if (_textColor == "") then { + _textColor = getText (configFile >> "CfgWeapons" >> _requiredItem >> QGVAR(textColor)); + if (_textColor == "") then { _textColor = "000000" }; +}; + + +private _identifier = format ["%1_%2_%3",_text,_textColor,_backgroundColor]; +private _interactionText = _text regexReplace ["\\n", " "]; +private _texture = [_text, _textSize, _textColor, _backgroundColor, _autoMultiline] call FUNC(generateStencilTexture); +TRACE_2("",_identifier,_texture); +if (_texture == "") exitWith { ERROR_1("bad texture params %1",_this); false }; + +[_identifier, _interactionText, _requiredItem, [_texture]] call FUNC(addCustomTag) // return diff --git a/addons/tagging/functions/fnc_addTagActions.sqf b/addons/tagging/functions/fnc_addTagActions.sqf index f9add50829..9c720e1f6c 100644 --- a/addons/tagging/functions/fnc_addTagActions.sqf +++ b/addons/tagging/functions/fnc_addTagActions.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Compiles tags from ACE_Tags and returns children actions. @@ -19,38 +19,18 @@ params ["_unit"]; private _actions = []; { - _x params ["_class", "_displayName", "_requiredItem", "_textures", "_icon", "_materials"]; - _actions pushBack [ [ - format ["ACE_ConfigTag_%1", _class], - _displayName, - _icon, - { - (_this select 2) params ["_unit", "_class", "_textures", "", "_materials"]; - - ( - if (count _textures == count _materials) then { - private _textureIndex = floor random count _textures; - [_textures select _textureIndex, _materials select _textureIndex] - } else { - [selectRandom _textures, selectRandom _materials] - } - ) params ["_randomTexture", "_randomMaterial"]; - - [_unit, _randomTexture, _randomMaterial] call FUNC(tag); - _unit setVariable [QGVAR(lastUsedTag), _class]; - }, - { - (_this select 2) params ["_unit", "", "", "_requiredItem"]; - _requiredItem in (_unit call EFUNC(common,uniqueItems)) - }, + format ["ACE_TagItem_%1", _x], + getText (configFile >> "CfgWeapons" >> _x >> "displayName"), + getText (configFile >> "CfgWeapons" >> _x >> "picture"), {}, - [_unit, _class, _textures, _requiredItem, _materials] + {(_this select 2) in (_player call EFUNC(common,uniqueItems))}, + {}, + _x ] call EFUNC(interact_menu,createAction), - [], + _y apply { [_x, [], _unit] }, //sub-actions for each individual tag _unit - ]; -} forEach GVAR(cachedTags); - + ] +} forEach GVAR(itemActions); _actions diff --git a/addons/tagging/functions/fnc_applyCustomTag.sqf b/addons/tagging/functions/fnc_applyCustomTag.sqf index d7a14820a8..5aaf4c4b8f 100644 --- a/addons/tagging/functions/fnc_applyCustomTag.sqf +++ b/addons/tagging/functions/fnc_applyCustomTag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Applies custom tag to the cache. @@ -10,6 +10,7 @@ * 3: Textures Paths * 4: Icon Path (default: "") * 5: Material Paths + * 6: Tag Model (optional) * * Return Value: * None @@ -23,12 +24,17 @@ params ["_identifier", "_displayName", "_requiredItem"]; // Add only if tag not already added (compare identifiers) -if !(GVAR(cachedTags) select {_x select 0 == _identifier} isEqualTo []) exitWith { +if ((GVAR(cachedTags) select {_x select 0 == _identifier}) isNotEqualTo []) exitWith { INFO_2("Tag with selected identifier already exists: %1 (%2)",_identifier,_displayName) }; + +if (isLocalized _displayName) then { + _this set [1, localize _displayName]; +}; + _requiredItem = configName (configFile >> "CfgWeapons" >> _requiredItem); // Convert To config case _this set [2, _requiredItem]; GVAR(cachedTags) pushBack _this; -GVAR(cachedRequiredItems) pushBackUnique _requiredItem; +_this call FUNC(compileTagAction); TRACE_1("Added custom script tag",_this); diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf index 3a022ca2b7..ef20062a32 100644 --- a/addons/tagging/functions/fnc_checkTaggable.sqf +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, esteldunedain * Checks if there is a taggable surface within 2.5m in front of the player. @@ -20,7 +20,7 @@ // Exit if no required item in inventory if ([_unit, { - GVAR(cachedRequiredItems) arrayIntersect (_unit call EFUNC(common,uniqueItems)) isEqualTo [] + (keys GVAR(itemActions)) arrayIntersect (_unit call EFUNC(common,uniqueItems)) isEqualTo [] }, _unit, QGVAR(checkRequiredItemsCache), 9999, "cba_events_loadoutEvent"] call EFUNC(common,cachedCall)) exitWith {false}; private _startPosASL = eyePos _unit; @@ -42,9 +42,15 @@ // If the class is alright, do not exit if (_object isKindOf "Static") exitWith {false}; + // Taggable vehicle, do not exit + if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) + && {getText (configOf _object >> "selectionClan") in selectionNames _object}) exitWith { + false + }; + // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/functions/fnc_compileConfigTags.sqf b/addons/tagging/functions/fnc_compileConfigTags.sqf index df9f01ac45..d2f096d067 100644 --- a/addons/tagging/functions/fnc_compileConfigTags.sqf +++ b/addons/tagging/functions/fnc_compileConfigTags.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Compiles and caches tags from ACE_Tags config. @@ -16,40 +16,25 @@ */ { - private _failure = false; private _class = configName _x; + private _result = [_x, false] call FUNC(parseConfigTag); - private _displayName = getText (_x >> "displayName"); - if (_displayName == "") then { - ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing displayName",_class); - _failure = true; - }; + if (_result isNotEqualTo []) then { + _result params ["_tagInfo", "_requiredItem"]; - private _requiredItem = getText (_x >> "requiredItem"); - if (_requiredItem == "") then { - ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing requiredItem",_class); - _failure = true; - } else { - if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) then { - ERROR_2("Failed compiling ACE_Tags for tag: %1 - requiredItem %2 does not exist",_class,_requiredItem); - _failure = true; - } else { - _requiredItem = configName (configFile >> "CfgWeapons" >> _requiredItem); // convert to config case - }; - }; - - private _textures = getArray (_x >> "textures"); - if (_textures isEqualTo []) then { - ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing textures",_class); - _failure = true; - }; - - private _materials = getArray (_x >> "materials"); - - private _icon = getText (_x >> "icon"); - - if (!_failure) then { - GVAR(cachedTags) pushBack [_class, _displayName, _requiredItem, _textures, _icon, _materials]; - GVAR(cachedRequiredItems) pushBackUnique _requiredItem; + GVAR(cachedTags) pushBack _tagInfo; + _tagInfo call FUNC(compileTagAction); }; } forEach ("true" configClasses (configFile >> "ACE_Tags")); + +{ + private _class = configName _x; + private _result = [_x, true] call FUNC(parseConfigTag); + + if (_result isNotEqualTo []) then { + _result params ["_tagInfo", "_requiredItem"]; + + GVAR(cachedTags) pushBack _tagInfo; + _tagInfo call FUNC(compileTagAction); + }; +} forEach ("true" configClasses (missionConfigFile >> "ACE_Tags")); diff --git a/addons/tagging/functions/fnc_compileTagAction.sqf b/addons/tagging/functions/fnc_compileTagAction.sqf new file mode 100644 index 0000000000..a49de10f47 --- /dev/null +++ b/addons/tagging/functions/fnc_compileTagAction.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Compiles tags from ACE_Tags and returns children actions. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [unit] call ace_tagging_fnc_compileTagAction + * + * Public: No + */ + +params ["_class", "_displayName", "_requiredItem", "_textures", "_icon", "_materials", "_tagModel"]; + +private _actions = GVAR(itemActions) getOrDefault [_requiredItem, []]; + +_actions pushBack ([ + _class, + _displayName, + _icon, + { + (_this select 2) params ["_class", "_textures", "_materials", "_tagModel"]; + + ( + if (count _textures == count _materials) then { + private _textureIndex = floor random count _textures; + [_textures select _textureIndex, _materials select _textureIndex] + } else { + [selectRandom _textures, selectRandom _materials] + } + ) params ["_randomTexture", "_randomMaterial"]; + + [_player, _randomTexture, _randomMaterial, _tagModel] call FUNC(tag); + _player setVariable [QGVAR(lastUsedTag), _class]; + }, + {true}, // required item is checked at an upper level + {}, + [_class, _textures, _materials, _tagModel] +] call EFUNC(interact_menu,createAction)); + +GVAR(itemActions) set [_requiredItem, _actions]; diff --git a/addons/tagging/functions/fnc_createTag.sqf b/addons/tagging/functions/fnc_createTag.sqf index 5f2a60cf86..90923cc803 100644 --- a/addons/tagging/functions/fnc_createTag.sqf +++ b/addons/tagging/functions/fnc_createTag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, esteldunedain * Creates a tag and handle its destruction. Only execute on the server. @@ -10,6 +10,7 @@ * 3: Object it should be tied to * 4: Unit that created the tag * 5: Material of the tag (Optional) + * 6: Vehicle Tag (Optional) * * Return Value: * Tag created @@ -20,7 +21,7 @@ * Public: No */ -params ["_tagPosASL", "_vectorDirAndUp", "_texture", "_object", "_unit", ["_material","",[""]]]; +params ["_tagPosASL", "_vectorDirAndUp", "_texture", "_object", "_unit", ["_material","",[""]], ["_tagModel", "UserTexture1m_F", [""]], ["_isVehicleTag", false, [false]]]; TRACE_5("createTag:",_tagPosASL,_vectorDirAndUp,_texture,_object,_unit); if (_texture == "") exitWith { @@ -28,7 +29,15 @@ if (_texture == "") exitWith { false }; -private _tag = createSimpleObject ["UserTexture1m_F", _tagPosASL]; +if (_isVehicleTag) exitWith { + TRACE_3("tagging vehicle",_object,typeOf _object,_texture); + _object setObjectTextureGlobal [getText (configOf _object >> "selectionClan"), _texture]; + _object setVariable [QGVAR(hasTag), true, true]; + // if (_material != "") then { _object setObjectMaterialGlobal ["clan", _material] }; // ?? + ["ace_tagCreated", [objNull, _texture, _object, _unit]] call CBA_fnc_globalEvent; +}; + +private _tag = createSimpleObject [_tagModel, _tagPosASL]; _tag setObjectTextureGlobal [0, _texture]; if (_material != "") then { _tag setObjectMaterialGlobal [0, _material] }; _tag setVectorDirAndUp _vectorDirAndUp; @@ -46,7 +55,7 @@ if (_object getVariable [QGVAR(testVar), false]) then { // If the object already has tags attached, just add the new one to the list private _attachedTags = _object getVariable QGVAR(attachedTags); - if !(isNil "_attachedTags ") exitWith { + if (!isNil "_attachedTags") exitWith { _attachedTags pushBack _tag; }; diff --git a/addons/tagging/functions/fnc_generateStencilTexture.sqf b/addons/tagging/functions/fnc_generateStencilTexture.sqf new file mode 100644 index 0000000000..6d8dffdc55 --- /dev/null +++ b/addons/tagging/functions/fnc_generateStencilTexture.sqf @@ -0,0 +1,55 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Generate a "Text to Texture" + * + * Arguments: + * 0: Display Text + * 1: Text Size (default: 0.3) + * 2: Text Color (in HEX 6 or 8) (default: "000000" - black) + * 3: Background Color (in HEX 6 or 8) (default: "00000000" - transparent) + * 4: Auto newlines (default: true) + * 4: Texture Dimensions (default: 512) + * + * Return Value: + * Texture + * + * Example: + * ["your text"] call ace_tagging_fnc_generateStencilTexture + * + * Public: No + */ + +params [ + ["_text", "", [""]], + ["_textSize", 0.3, [0]], + ["_textColor", "000000", [""]], + ["_backgroundColor", "00000000", [""]], + ["_autoMultiline", true, [false]], + ["_dimension", 512, [0]] +]; + +if (_textColor select [0, 1] == "#") then {_textColor = _textColor select [1];}; +if (_backgroundColor select [0, 1] == "#") then {_backgroundColor = _backgroundColor select [1];}; +if !((count _textColor) in [6,8]) exitWith {ERROR_1("bad Tcolor %1",_textColor); ""}; +if !((count _backgroundColor) in [6,8]) exitWith {ERROR_1("bad Bcolor %1",_textColor); ""}; + +if (_autoMultiline) then { + private _magicWidth = 0.75; + private _words = _text splitString " "; + private _lines = []; + while {_words isNotEqualTo []} do { + private _size = count _words; + while {_size > 1} do { + private _testLine = (_words select [0, _size]) joinString " "; + if ((_testLine getTextWidth ["ACE_Stencil", _textSize]) < _magicWidth) exitWith {}; + _size = _size - 1; + }; + _lines pushBack ((_words select [0, _size]) joinString " "); + _words = _words select [_size, (count _words) - _size]; + }; + _text = _lines joinString "\n"; +}; + +// return +format ['#(rgb,%1,%1,3)text(1,1,"ACE_Stencil",%2,"#%3","#%4","%5")', _dimension, _textSize, _backgroundColor, _textColor, _text] diff --git a/addons/tagging/functions/fnc_moduleInit.sqf b/addons/tagging/functions/fnc_moduleInit.sqf index 3f1048e1e5..d7c42ea8b9 100644 --- a/addons/tagging/functions/fnc_moduleInit.sqf +++ b/addons/tagging/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Initializes the Tagging module. diff --git a/addons/tagging/functions/fnc_parseConfigTag.sqf b/addons/tagging/functions/fnc_parseConfigTag.sqf new file mode 100644 index 0000000000..5526b2fed0 --- /dev/null +++ b/addons/tagging/functions/fnc_parseConfigTag.sqf @@ -0,0 +1,91 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, Dedmen + * Parses tags from ACE_Tags config. + * + * Arguments: + * 0: The config class + * 1: Is Mission + * + * Return Value: + * Tag Information + * + * Example: + * [_x, false] call ace_tagging_fnc_parseConfigTag + * + * Public: No + */ + +#define GET_MOD_OR_MISSION_PATH(thing) \ + if (thing select [0,1] != "@") then { \ + getMissionPath thing; \ + } else { \ + thing select [1]; \ + } + +params ["_cfg", ["_isMission", false, [false]]]; + + +private _failure = false; +private _class = configName _cfg; + +private _displayName = getText (_cfg >> "displayName"); +if (_displayName == "") then { + ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing displayName",_class); + _failure = true; +}; + +private _requiredItem = getText (_cfg >> "requiredItem"); +if (_requiredItem == "") then { + ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing requiredItem",_class); + _failure = true; +} else { + if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) then { + ERROR_2("Failed compiling ACE_Tags for tag: %1 - requiredItem %2 does not exist",_class,_requiredItem); + _failure = true; + } else { + _requiredItem = configName (configFile >> "CfgWeapons" >> _requiredItem); // convert to config case + }; +}; + +private _textures = getArray (_cfg >> "textures"); +if (_textures isEqualTo []) then { + ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing textures",_class); + _failure = true; +}; + +private _materials = getArray (_cfg >> "materials"); + +private _icon = getText (_cfg >> "icon"); + +private _tagModel = getText (_cfg >> "tagModel"); +if (_tagModel == "") then { + _tagModel = "UserTexture1m_F"; +}; + +// Need to parse mission vs mod path for mission config +if (_isMission) then { + _materials = _materials apply { + GET_MOD_OR_MISSION_PATH(_x); + }; + + _textures = _textures apply { + GET_MOD_OR_MISSION_PATH(_x); + }; + + // Only if path to model, either has subfolders or atleast a .p3d + if ("\" in _tagModel || {"." in _tagModel}) then { + _tagModel = GET_MOD_OR_MISSION_PATH(_tagModel); + }; +}; + + + +if (_failure) then { + [] +} else { + [ + [_class, _displayName, _requiredItem, _textures, _icon, _materials, _tagModel], + _requiredItem + ] +} diff --git a/addons/tagging/functions/fnc_quickTag.sqf b/addons/tagging/functions/fnc_quickTag.sqf index 1939ce1679..3e8c51218d 100644 --- a/addons/tagging/functions/fnc_quickTag.sqf +++ b/addons/tagging/functions/fnc_quickTag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Selects random tag and applies it. @@ -47,9 +47,9 @@ if (GVAR(quickTag) == 3) then { }; // Tag -if !(_possibleTags isEqualTo []) then { +if (_possibleTags isNotEqualTo []) then { private _availableTags = _possibleTags select {(_x select 2) in (_unit call EFUNC(common,uniqueItems))}; - (selectRandom _availableTags) params ["", "", "", "_textures", "", "_materials"]; + (selectRandom _availableTags) params ["", "", "", "_textures", "", "_materials", "_tagModel"]; ( if (count _textures == count _materials) then { @@ -60,5 +60,5 @@ if !(_possibleTags isEqualTo []) then { } ) params ["_randomTexture", "_randomMaterial"]; - [_unit, _randomTexture, _randomMaterial] call FUNC(tag); + [_unit, _randomTexture, _randomMaterial, _tagModel] call FUNC(tag); }; diff --git a/addons/tagging/functions/fnc_stencilVehicle.sqf b/addons/tagging/functions/fnc_stencilVehicle.sqf new file mode 100644 index 0000000000..1dfd86a2f9 --- /dev/null +++ b/addons/tagging/functions/fnc_stencilVehicle.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Handles 3den attribute for vehicle ID markings + * + * Arguments: + * 0: Vehicle + * 1: Display Text + * 2: Text Size (Optional) + * 3: Text Color (Optional) + * + * Return Value: + * None + * + * Example: + * [truck, "BARVO-1 Bastards"] call ace_tagging_fnc_stencilVehicle + * + * Public: No + */ + +params [ + ["_vehicle", objNull, [objNull]], + ["_text", "", [""]], + ["_textSize", 0.3, [0]], // Fits about 7-8 chars in width + ["_textcolor", "f7e9e1f8", [""]] // making text color slightly transparent (f8) fixes a "shimmering" problem (possibly related to HBAO) +]; +TRACE_2("",_vehicle,_text); + +if (!isServer) exitWith {}; +if (_text == "") exitWith {}; +private _clanSel = getText (configOf _vehicle >> "selectionClan"); +if !(_clanSel in selectionNames _vehicle) exitWith {TRACE_1("no tag",_clanSel);}; + +private _texture = [_text, _textSize, _textColor, "00000000", true] call FUNC(generateStencilTexture); +TRACE_1("",_texture); +if (_texture == "") exitWith { ERROR_1("bad texture params %1",_this); }; +[[], [], _texture, _vehicle, objNull, "", "", true] call FUNC(createTag); // apply texture and send event diff --git a/addons/tagging/functions/fnc_tag.sqf b/addons/tagging/functions/fnc_tag.sqf index 1a0fe20e64..f130e1322b 100644 --- a/addons/tagging/functions/fnc_tag.sqf +++ b/addons/tagging/functions/fnc_tag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: BaerMitUmlaut, esteldunedain * Creates a tag on a wall that is on the closest surface within 2m on front of the unit. @@ -6,10 +6,11 @@ * Arguments: * 0: Unit * 1: The colour of the tag (valid colours are black, red, green and blue or full path to custom texture) - * 2: Material of the tag (Optional) + * 2: Material of the tag (default: "") + * 3: Tag Model (default: "UserTexture1m_F") * * Return Value: - * Sucess + * Success * * Example: * success = [player, "z\ace\addons\tagging\UI\tags\black\0.paa"] call ace_tagging_fnc_tag @@ -20,13 +21,15 @@ params [ ["_unit", objNull, [objNull]], ["_texture", "", [""]], - ["_material", "", [""]] + ["_material", "", [""]], + ["_tagModel", "UserTexture1m_F", [""]] ]; if (isNull _unit || {_texture == ""}) exitWith { ERROR_2("Tag parameters invalid. Unit: %1, Texture: %2",_unit,_texture); }; +private _isVehicleTag = false; private _startPosASL = eyePos _unit; private _cameraPosASL = AGLToASL positionCameraToWorld [0, 0, 0]; private _cameraDir = (AGLToASL positionCameraToWorld [0, 0, 1]) vectorDiff _cameraPosASL; @@ -42,16 +45,23 @@ if (_intersections isEqualTo []) exitWith { }; (_intersections select 0) params ["_touchingPoint", "_surfaceNormal", "", "_object"]; -TRACE_3("",_touchingPoint, _surfaceNormal, _object); +TRACE_3("",_touchingPoint,_surfaceNormal,_object); // Exit if trying to tag a non static object if ((!isNull _object) && { // If the class is alright, do not exit if (_object isKindOf "Static") exitWith {false}; + // Taggable vehicle, do not exit and tell server to change "clan" tag + if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) + && {getText (configOf _object >> "selectionClan") in selectionNames _object}) exitWith { + _isVehicleTag = true; + false + }; + // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) @@ -68,15 +78,22 @@ if (_surfaceNormal vectorDotProduct (_endPosASL vectorDiff _startPosASL) > 0) t // Check if its a valid surface: big enough, reasonably plane private _v1 = vectorNormalized (_surfaceNormal vectorMultiply -1); -private _v2 = vectorNormalized (_v1 vectorCrossProduct (_endPosASL vectorDiff _startPosASL)); +private _v2 = []; +private _v3 = []; // If the surface is not horizontal (>20º), create vup _v2 pointing upward instead of away -if (abs (_v1 select 2) < 0.94) then { - private _v3Temp = _v1 vectorCrossProduct [0, 0, 1]; - _v2 = _v3Temp vectorCrossProduct _v1; +private _vectorDirAndUp = if (abs (_v1 select 2) < 0.94) then { + _v3 = _v1 vectorCrossProduct [0, 0, 1]; + _v2 = _v3 vectorCrossProduct _v1; + TRACE_2("Wall Placement",_v1,_v2); + [_v1, _v2] +} else { + _v2 = vectorNormalized (_v1 vectorCrossProduct (_endPosASL vectorDiff _startPosASL)); + _v3 = _v2 vectorCrossProduct _v1; + TRACE_2("Ground Placement",_v1,_v3); + [_v1, _v3] }; -private _v3 = _v2 vectorCrossProduct _v1; -TRACE_3("Reference:", _v1, _v2, _v3); +TRACE_3("Reference:",_v1,_v2,_v3); private _fnc_isOk = { params ["_rx", "_ry"]; @@ -86,20 +103,20 @@ private _fnc_isOk = { // If there's no intersections if (_intersections isEqualTo []) exitWith {false;}; - if !(((_intersections select 0) select 3) isEqualTo _object) exitWith {false;}; + if (((_intersections select 0) select 3) isNotEqualTo _object) exitWith {false;}; true }; -if ( !([ 0.5 * TAG_SIZE, 0.5 * TAG_SIZE] call _fnc_isOk) || +if ( (!_isVehicleTag) && { + !([ 0.5 * TAG_SIZE, 0.5 * TAG_SIZE] call _fnc_isOk) || {!([ 0.5 * TAG_SIZE,-0.5 * TAG_SIZE] call _fnc_isOk) || {!([-0.5 * TAG_SIZE, 0.5 * TAG_SIZE] call _fnc_isOk) || - {!([-0.5 * TAG_SIZE,-0.5 * TAG_SIZE] call _fnc_isOk)}}}) exitWith { + {!([-0.5 * TAG_SIZE,-0.5 * TAG_SIZE] call _fnc_isOk)}}}}) exitWith { TRACE_1("Unsuitable location:",_touchingPoint); false }; -private _vectorDirAndUp = [_surfaceNormal vectorMultiply -1, _v3]; // Everything ok, make the unit create the tag [_unit, "PutDown"] call EFUNC(common,doGesture); @@ -108,10 +125,10 @@ private _vectorDirAndUp = [_surfaceNormal vectorMultiply -1, _v3]; params ["", "", "", "", "_unit"]; TRACE_2("Unit:",_unit,_this); - playSound3D [QUOTE(PATHTO_R(sounds\spray.ogg)), _unit, false, (eyePos _unit), 10, 1, 15]; + playSound3D [QUOTE(PATHTO_R(sounds\spray.ogg)), _unit, false, (eyePos _unit), 5, 1, 15]; // Tell the server to create the tag and handle its destruction [QGVAR(createTag), _this] call CBA_fnc_serverEvent; -}, [_touchingPoint vectorAdd (_surfaceNormal vectorMultiply 0.06), _vectorDirAndUp, _texture, _object, _unit, _material], 0.6] call CBA_fnc_waitAndExecute; +}, [_touchingPoint vectorAdd (_surfaceNormal vectorMultiply 0.06), _vectorDirAndUp, _texture, _object, _unit, _material, _tagModel, _isVehicleTag], 0.6] call CBA_fnc_waitAndExecute; true diff --git a/addons/tagging/functions/fnc_tagTestingThread.sqf b/addons/tagging/functions/fnc_tagTestingThread.sqf index dcfb5e0bac..f6d5209e3c 100644 --- a/addons/tagging/functions/fnc_tagTestingThread.sqf +++ b/addons/tagging/functions/fnc_tagTestingThread.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain * Checks if tags are still leaning on an object periodically. diff --git a/addons/tagging/functions/script_component.hpp b/addons/tagging/functions/script_component.hpp deleted file mode 100644 index bc860f2283..0000000000 --- a/addons/tagging/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\tagging\script_component.hpp" \ No newline at end of file diff --git a/addons/tagging/initSettings.inc.sqf b/addons/tagging/initSettings.inc.sqf new file mode 100644 index 0000000000..e05146c081 --- /dev/null +++ b/addons/tagging/initSettings.inc.sqf @@ -0,0 +1,8 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(Tagging)]; + +[ + QGVAR(quickTag), "LIST", + [LLSTRING(QuickTag), LLSTRING(QuickTagDesc)], + _category, + [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1] // [values, titles, defaultIndex] +] call CBA_fnc_addSetting; diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 75de55efcc..fa54b56b54 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -6,53 +6,67 @@ Маркировка タグ付け Tagowanie - Markierungssystem (Spraydose) - 뿌리기 + Markieren (Spraydose) + 태그하기 Marquage Marcamento 喷漆 噴漆 + Marcação + Označování + Işaretleme + Marcado Configure how the tagging system will operate by default. - Настройка работы системы спрей-маркеров по-умолчанию. - 標準で開くタグ付けシステムの設定を行います。 + Настройка работы системы спрей-маркеров по умолчанию. + タグ付けシステムの標準動作を設定します。 Skonfiguruj zachowanie systemu tagowania. - Konfiguriert, wie das Markierungssystem standardmäßig funktioniert. - 뿌리기 시스템의 기본사항을 설정합니다. + Konfiguriert, wie das Markieren standardmäßig funktioniert. + 태그 시스템의 기본사항을 설정합니다. Configure le fonctionnement par défaut du système de marquage. - Configura quanto il sistema di marcamento agirà da se. + Configura come il sistema di marcamento agirà in maniera predefinita. 定义喷漆系统预设设定 定義噴漆系統預設設定 + Configura como o sistema de Marcação funcionará como padrão. (Tagging) + Nakonfigurujte, jak bude systém značkování ve výchozím nastavení fungovat. + Configura cómo funciona el sistema de marcado por defecto. Spray Paint - Quick Tag Быстрый маркер - クイック タグ + スプレーペイント - クイックタグ Szybkie tagowanie Schnelle Markierung (Spraydose) - 빠른 뿌리기 - Marquage rapide - Marcamento Rapido + 스프레이 페인트 - 빠른 태그 + Peinture en spray - Marquage rapide + Marcamento Spray - Rapido 快速喷漆 快速噴漆 + Lata de Tinta - Marcação Rápida + Stříkací barva - Rychlá značka + Sprey Boya- Hızlı Işaretleme + Pintada con spray - Marcado rápido Action performed on main tag interaction point. Действие, выполняемое при выборе главного пункта меню маркировки. - インタラクション ポイントにむけてタグ付けをします。 + メインのインタラクションポイント(タグ)を選択した際に行われるアクション。 Akcja wykonywana na głównym punkcie interakcji tagu. Aktion, die am Haupt-Interaktionspunkt ausgeführt werden soll. - 이 동작은 상호작용에서 뿌리기를 할 수 있게 해준다 - Action réalisé au point de marquage principal. - Azione eseguita sul punto di interazione dei tag principali. - 直接喷漆在互动选单瞄准的点上。 + 상호작용 시 표시할 낙서를 고릅니다. + Type de marquage à appliquer sur le point visé. + Azione eseguita sul punto di interazione del tag principale. + 直接喷漆在互动菜单瞄准的点上。 直接噴漆在互動選單瞄準的點上。 + Ação executada no ponto principal de marcação + Akce prováděná v hlavním bodě značky interakce. + Acción realizada en el punto de interacción de marcado principal. Last Used Повторить последний - 前回と同じ + 最後に使用したタグ Ostatnio użyte Zuletzt benutzt 최근 사용 @@ -60,6 +74,10 @@ Ultimo Usato 上次最后使用 上次最後使用 + Último usado + Naposledy použitý + Son Kullanan + Último usado Random X @@ -68,10 +86,14 @@ Losowy X Zufällig X 무작위 X - Aléatoire X - Random X + X aléatoire + Randomico X 随机X标记 隨機X標記 + Aleatório X + Náhodné X + Rasgele X + Aleatorio X Random @@ -81,9 +103,13 @@ Zufällig 무작위 Aléatoire - Random + Randomico 随机 隨機 + Aleatório + Náhodný + Rasgele + Aleatorio Tag @@ -94,146 +120,282 @@ Označit Marcar Маркер - タグ - 뿌리기 + タグ (スプレーペイント) + 태그 Tag 喷漆 噴漆 + Işaretle - - X black - Schwarz X - X en negro - X na czarno - X noir - X nero - X černě - X em preto - Черный Х - 黒のX印 - 검정 X - 黑色X标记 - 黑色X標記 + + X + X + X + X + X + X + X + X + Х + X印 + X + X标记 + X標記 + X - - X red - Rot X - X en rojo - X na czerwono - X rouge - X rosso - X červeně - X em vermelho - Красный Х - 赤のX印 - 빨간 X - 红色X标记 - 紅色X標記 + + Up Arrow + 矢印 (上) + Strzałka w górę + 화살표(위) + Стрелка вверх + Flecha Arriba + Pfeil Hoch + Freccia in alto + Flèche du haut - - X green - Grün X - X en verde - X na zielono - X vert - X verde - X zeleně - X em verde - Зеленый Х - 緑のX印 - 초록 X - 绿色X标记 - 綠色X標記 + + Down Arrow + 矢印 (下) + Strzałka w dół + 화살표(아래) + Стрелка вниз + Flecha Abajo + Pfeil Runter + Freccia in basso + Flèche du bas - - X blue - Blau X - X en azul - X na niebiesko - X bleu - X blu - X modře - X em azul - Синий Х - 青のX印 - 파랑 X - 蓝色X标记 - 藍色X標記 + + Left Arrow + 矢印 (左) + Strzałka w lewo + 화살표(왼쪽) + Стрелка влево + Flecha Izquierda + Pfeil Links + Freccia a sinistra + Flèche gauche + + + Right Arrow + 矢印 (右) + Strzałka w prawo + 화살표(오른쪽) + Стрелка вправо + Flecha Derecha + Pfeil Rechts + Freccia a destra + Flèche droite + + + Circle + + Okrąg + + Круг + Círculo + Kreis + Cerchio + Cercle + + + Cross + 十字 + Krzyż + 십자 + Перекрестие + Cruz + Kreuz + Croce + Croix + + + Diamond + 菱形 + Diament + 마름모 + Алмаз + Diamante + Diamant + Diamante + Losange + + + Square + 四角 + Kwadrat + 사각형 + Квадрат + Cuadrado + Quadrat + Quadrato + Carré + + + Filled Square + 四角 (塗りつぶし) + Wypełniony Kwadrat + 채워진 사각형 + Заполненный Квадрат + Cuadrado Lleno + Gefülltes Quadrat + Quadrato pieno + Carré rempli + + + Triangle + 三角 + Trójkąt + 삼각형 + Треугольник + Triángulo + Dreieck + Triangolo + Triangle + + + Triangle Inverted + 三角 (反転) + Odwrócony trójkąt + 역삼각형 + Обратный треугольник + Triángulo invertido + Invertiertes Dreieck + Triangolo capovolto + Triangle inversé - Black spray paint - Schwarze Sprühfarbe + Spray Paint (Black) + Sprühfarbe (Schwarz) Pintura negra - Czarna farba w sprayu - Peinture pulvérisée noire + Farba w Sprayu (Czarna) + Peinture en spray (Noire) Bomboletta spray nera Černý sprej Spray de tinta preta Черный спрей - 黒のスプレー缶 + スプレーペイント缶 (黒色) 검정 스프레이 黑色喷漆 黑色噴漆 + Sprey Boya (Siyah) - Red spray paint - Rote Sprühfarbe + Spray Paint (Red) + Sprühfarbe (Rot) Pintura roja - Czerwona farba w sprayu - Peinture pulvérisée rouge + Farba w Sprayu (Czerwona) + Peinture en spray (Rouge) Bomboletta spray rossa Červený sprej Spray de tinta vermelha Красный спрей - 赤のスプレー缶 + スプレーペイント缶 (赤色) 빨강 스프레이 红色喷漆 紅色噴漆 + Sprey Boya (Kırmızı) - Green spray paint - Grüne Sprühfarbe + Spray Paint (Green) + Sprühfarbe (Grün) Pintura verde - Zielona farba w sprayu - Peinture pulvérisée verte + Farba w Sprayu (Zielona) + Peinture en spray (Verte) Bomboletta spray verde Zelený sprej Spray de tinta verde - Зеленый спрей - 緑のスプレー缶 + Зелёный спрей + スプレーペイント缶 (緑色) 초록 스프레이 绿色喷漆 綠色噴漆 + Sprey Boya (Yeşil) - Blue spray paint - Blaue Sprühfarbe + Spray Paint (Blue) + Sprühfarbe (Blau) Pintura azul - Niebieska farba w sprayu - Peinture pulvérisée bleue + Farba w Sprayu (Niebieska) + Peinture en spray (Bleue) Bomboletta spray blu Modrý sprej Spray de tinta azul Синий спрей - 青のスプレー缶 + スプレーペイント缶 (青色) 파랑 스프레이 蓝色喷漆 藍色噴漆 + Sprey Boya (Mavi) + + + Spray Paint (Yellow) + Sprühfarbe (Gelb) + Pintura amarilla + Farba w Sprayu (Żółta) + Peinture en spray (Jaune) + Bomboletta spray gialla + Žlutý sprej + Spray de tinta amarela + Желтый спрей + スプレーペイント缶 (黄色) + 노랑 스프레이 + 黄色喷漆 + 黃色噴漆 + Sprey Boya (Sarı) + + + Spray Paint (White) + Sprühfarbe (Weiß) + Pintura blanca + Farba w Sprayu (Biała) + Peinture en spray (Blanc) + Bomboletta spray bianca + Bílý sprej + Spray de tinta branca + Белый спрей + スプレーペイント缶 (白色) + 하양 스프레이 + 白色喷漆 + 白色噴漆 + Sprey Boya (Beyaz) A can of spray paint for tagging walls. Eine Farbsprühdose um Wände zu markieren. Lata de pintura en aerosol para marcar. Farba w sprayu, służy do oznakowywania terenu. - Un spray de peinture pour marquer les murs. - Una bomboletta di spay per contrassegnare i muri. + Une bombe de peinture en spray pour tagger les murs. + Una bomboletta spay per applicare marker sui muri. Plechovka se sprejem k vytváření značek. Uma lata de tinta spray para marcar paredes. Балончик спрея для рисования маркеров на стенах. - スプレー缶は壁にタグ付できます。 - 벽에 뿌릴 수 있는 스프레이캔 입니다. + 壁にタグを描くためのスプレーペイント缶。 + 벽에 낙서할 수 있는 스프레이캔 입니다. 喷漆可喷涂在墙壁上 噴漆可噴塗在牆壁上 + + Vehicle ID Marking + 車両IDマーキング + Oznaczenie identyfikacyjne pojazdu + Fahrzeug ID Markierung + Marcatore identificativo sui veicoli + 차량 ID 마킹 + Marquage ID des véhicules + Идентификационная маркировка транспортного средства + Marcado Identificativo de Vehículo + + + Replaces clan tag with stenciled text + 部隊タグをステンシルテキストに置き換える + Zastępuje tag klanu tekstem z szablonu + Ersetzt das Clan-Tag durch Schablonentext + Sostituisce l'icona del clan con testo in stampatello + 클랜 태그를 스텐실 텍스트로 바꿉니다. + Remplace le tag du clan par un texte au pochoir + Заменяет тег клана трафаретным текстом + Reemplaza marca del clan con un texto serigrafiado + diff --git a/addons/thermals/README.md b/addons/thermals/README.md index edec645164..7fc50b3e26 100644 --- a/addons/thermals/README.md +++ b/addons/thermals/README.md @@ -2,11 +2,3 @@ ace_thermals ============ Improves the thermal properties of humans. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/towing/$PBOPREFIX$ b/addons/towing/$PBOPREFIX$ new file mode 100644 index 0000000000..6755fcc3bf --- /dev/null +++ b/addons/towing/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\towing \ No newline at end of file diff --git a/addons/towing/CfgEventHandlers.hpp b/addons/towing/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/towing/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/towing/CfgVehicles.hpp b/addons/towing/CfgVehicles.hpp new file mode 100644 index 0000000000..6775a8c9e2 --- /dev/null +++ b/addons/towing/CfgVehicles.hpp @@ -0,0 +1,62 @@ +#define CONCAT(a,b) a##b +#define TOW_ACTION(length) \ + class GVAR(CONCAT(startTow,length)) {\ + displayName = CSTRING(CONCAT(start,length));\ + condition = QUOTE([ARR_2(_player,'CONCAT(ACE_rope,length)')] call DEFUNC(common,hasItem));\ + statement = QUOTE([ARR_3(_player,_target,'CONCAT(ACE_rope,length)')] call DFUNC(startTow));\ + exceptions[] = { INTERACTION_EXCEPTIONS };\ + } +#define TOW_ACTIONS \ + class ACE_Actions {\ + class ACE_MainActions {\ + class ADDON {\ + displayName = CSTRING(displayName);\ + distance = TOW_ACTION_DISTANCE;\ + condition = QUOTE(alive _target && {_target call DFUNC(isSuitableSimulation)});\ + exceptions[] = { INTERACTION_EXCEPTIONS };\ + insertChildren = QUOTE(_target call DFUNC(getDetachActions));\ + TOW_ACTION(3);\ + TOW_ACTION(6);\ + TOW_ACTION(12);\ + TOW_ACTION(15);\ + TOW_ACTION(18);\ + TOW_ACTION(27);\ + TOW_ACTION(36);\ + };\ + };\ + } + +class CfgVehicles { + class LandVehicle; + class Car: LandVehicle { + TOW_ACTIONS; + }; + + class Tank: LandVehicle { + TOW_ACTIONS; + }; + + class Ship; + class Ship_F: Ship { + TOW_ACTIONS; + }; + + class ThingX; + class GVAR(helper): ThingX { + displayName = "helper"; // not publicly visible, no stringtable needed + scope = 1; + scopeCurator = 1; + model = "\A3\Weapons_f\empty"; + destrType = "DestructNo"; + }; + class GVAR(hook): GVAR(helper) { + displayName = "hook"; + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(detach); + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(detachRope)); + distance = TOW_ACTION_DISTANCE; + }; + }; + }; +}; diff --git a/addons/towing/README.md b/addons/towing/README.md new file mode 100644 index 0000000000..ad6bfd14cc --- /dev/null +++ b/addons/towing/README.md @@ -0,0 +1,4 @@ +ace_towing +=================== + +Adds the ability to tow vehicles. diff --git a/addons/towing/XEH_PREP.hpp b/addons/towing/XEH_PREP.hpp new file mode 100644 index 0000000000..b72f70c55b --- /dev/null +++ b/addons/towing/XEH_PREP.hpp @@ -0,0 +1,11 @@ +PREP(addRopeToVehicle); +PREP(attachRopePFH); +PREP(attachVehicles); +PREP(detachChild); +PREP(detachRope); +PREP(getDetachActions); +PREP(isSuitableSimulation); +PREP(onMouseButtonDown); +PREP(onMouseButtonUp); +PREP(startTow); +PREP(towStateMachinePFH); diff --git a/addons/towing/XEH_postInit.sqf b/addons/towing/XEH_postInit.sqf new file mode 100644 index 0000000000..01c7d6e48e --- /dev/null +++ b/addons/towing/XEH_postInit.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" + +["MouseButtonUp", LINKFUNC(onMouseButtonUp)] call CBA_fnc_addDisplayHandler; +GVAR(mouseLeft) = false; +GVAR(mouseRight) = false; +GVAR(blockFireEHID) = -1; + +[QGVAR(ropeAttachTo), { + params ["_child", "_relativeAttachPos", "_rope", "_helper"]; + TRACE_4("ropeAttachTo",_child,_relativeAttachPos,_rope,_helper); + _helper ropeDetach _rope; + [_child, _relativeAttachPos] ropeAttachTo _rope; + deleteVehicle _helper; +}] call CBA_fnc_addEventHandler; + +[QGVAR(attachVehicles), LINKFUNC(attachVehicles)] call CBA_fnc_addEventHandler; +[QGVAR(detachChild), LINKFUNC(detachChild)] call CBA_fnc_addEventHandler; + +if (!isServer) exitWith {}; + +[QGVAR(cleanupParent), { + params ["_parent"]; + TRACE_1("cleanupParent",_parent); + _parent removeEventHandler ["RopeBreak", _parent getVariable [QGVAR(RopeBreakEHID), -1]]; + _parent setVariable [QGVAR(RopeBreakEHID), -1]; + private _parentParentHooks = _parent getVariable [QGVAR(parentHooks), []]; + if (_parentParentHooks isEqualTo []) then { + TRACE_1("remove Deleted EH",_parent); + _parent removeEventHandler ["Deleted", _parent getVariable [QGVAR(DeletedEHID), -1]]; + _parent setVariable [QGVAR(DeletedEHID), -1]; + }; +}] call CBA_fnc_addEventHandler; + +addMissionEventHandler ["PlayerConnected", { + if (GVAR(allChildren) isEqualTo []) exitWith {}; + params ["", "", "", "_jip", "_owner"]; + if (!_jip) exitWith {}; + TRACE_2("pushing children",_owner,GVAR(allChildren)); + [QGVAR(setTowParentAllChildren), [GVAR(allChildren)], _owner] call CBA_fnc_ownerEvent; +}]; diff --git a/addons/towing/XEH_preInit.sqf b/addons/towing/XEH_preInit.sqf new file mode 100644 index 0000000000..6a85ba442f --- /dev/null +++ b/addons/towing/XEH_preInit.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +// handle JIP +if (isServer) then { + GVAR(allChildren) = []; +} else { + // can't use CBA EH in postInit because too late for server PlayerConnected EH + [QGVAR(setTowParentAllChildren), { + params ["_children"]; + TRACE_1("setTowParentAllChildren",_children); + { + private _parent = _x getVariable QGVAR(parent); + TRACE_2("setTowParent",_x,_parent); + _x setTowParent _parent; + } forEach _children; + }] call CBA_fnc_addEventHandler; +}; + +ADDON = true; diff --git a/addons/towing/XEH_preStart.sqf b/addons/towing/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/towing/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/towing/config.cpp b/addons/towing/config.cpp new file mode 100644 index 0000000000..d4d1b5e854 --- /dev/null +++ b/addons/towing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "ace_logistics_rope"}; + author = ECSTRING(common,ACETeam); + authors[] = {"tcvm"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" + diff --git a/addons/towing/functions/fnc_addRopeToVehicle.sqf b/addons/towing/functions/fnc_addRopeToVehicle.sqf new file mode 100644 index 0000000000..9dec1257d0 --- /dev/null +++ b/addons/towing/functions/fnc_addRopeToVehicle.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Adds rope to vehicle inventory. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_towing_fnc_addRopeToVehicle + * + * Public: No + */ + +if (!GVAR(addRopeToVehicleInventory)) exitWith {}; +params ["_vehicle"]; + +if (0 == getNumber (configOf _vehicle >> QEGVAR(cargo,hasCargo))) exitWith {}; + +private _ropeType = ["ACE_rope6", "ACE_rope12"] select ( + -1 < ["Tank", "Wheeled_APC_F", "Truck_F"] findIf {_vehicle isKindOf _x} +); + +_vehicle addItemCargoGlobal [_ropeType, 1]; diff --git a/addons/towing/functions/fnc_attachRopePFH.sqf b/addons/towing/functions/fnc_attachRopePFH.sqf new file mode 100644 index 0000000000..37f626e0a9 --- /dev/null +++ b/addons/towing/functions/fnc_attachRopePFH.sqf @@ -0,0 +1,97 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * PFH which allows the user to attach a rope to the given target vehicle + * + * Arguments: + * 0: Unit wanting to attach rope + * 1: Vehicle to attach rope + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_towing_fnc_attachRopePFH + * + * Public: No + */ +params ["_unit", "_target", "_ignoreParent", "_ignoreRope", "_source", "_maxRange"]; + +private _viewDirection = getCameraViewDirection _unit; +GVAR(attachHelper) setPosASL (_unit modelToWorldVisualWorld [0, 1, 1.5]); + +private _hintLMB = ""; +private _hintRMB = localize ELSTRING(dragging,Drop); + +private _startPos = eyePos _unit; +private _endPos = _startPos vectorAdd (_viewDirection vectorMultiply TOW_ACTION_DISTANCE); +private _intersections = lineIntersectsSurfaces [_startPos, _endPos, _unit, GVAR(attachHelper), true, 2]; +GVAR(canAttach) = false; +if (_intersections isNotEqualTo []) then { + private _intersectionToUse = []; + { + _x params ["", "", "_object"]; + if (_object isKindOf "AllVehicles" && { _object isNotEqualTo _ignoreRope && { _object isNotEqualTo _ignoreParent } }) exitWith { + _intersectionToUse = _x; + }; + } forEach _intersections; + + if (_intersectionToUse isEqualTo []) exitWith {}; + + _intersectionToUse params ["_intersectPosition", "", "_intersectObject"]; + + GVAR(canAttach) = + _intersectObject isNotEqualTo _ignoreParent + && { + // if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child + if (!isNull _target) then { + _intersectObject isEqualTo _target + } else { + [_intersectObject] call FUNC(isSuitableSimulation) + && { // ignore _intersectObject which has parent != _ignoreParent + private _intersectObjectParent = _intersectObject getVariable [QGVAR(parent), objNull]; + isNull _intersectObjectParent || {_intersectObjectParent == _ignoreParent} + } && { // arma prevents making rings (ropeAttachTo silently fails) + private _ancestor = _ignoreParent getVariable [QGVAR(parent), objNull]; + while {!isNull _ancestor && {_ancestor != _intersectObject}} do { + _ancestor = _ancestor getVariable [QGVAR(parent), objNull]; + }; + isNull _ancestor + } + } + } + ; + + if (GVAR(canAttach)) then { + // TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope); + GVAR(attachHelper) setPosASL _intersectPosition; + _hintLMB = LLSTRING(attach); + + GVAR(attachHelper) setVariable [QGVAR(object), _intersectObject]; + }; + +}; + +if (_source isNotEqualTo [0, 0, 0]) then { + private _distanceFromSource = _source vectorDistance getPosASLVisual GVAR(attachHelper); + if (_distanceFromSource > _maxRange) then { + GVAR(canAttach) = false; + + private _direction = _source vectorFromTo getPosASLVisual GVAR(attachHelper); + GVAR(attachHelper) setPosASL (_source vectorAdd (_direction vectorMultiply _maxRange)); + + _hintLMB = ""; + + if (_distanceFromSource > _maxRange + 2) then { + GVAR(cancel) = true; + } else { + GVAR(cancel) = false; + }; + }; +}; + +private _hint = [_hintLMB, _hintRMB]; +if (_hint isNotEqualTo (_unit getVariable [QGVAR(hint), []])) then { + _unit setVariable [QGVAR(hint), _hint]; + _hint call EFUNC(interaction,showMouseHint); +}; diff --git a/addons/towing/functions/fnc_attachVehicles.sqf b/addons/towing/functions/fnc_attachVehicles.sqf new file mode 100644 index 0000000000..9fd95f3742 --- /dev/null +++ b/addons/towing/functions/fnc_attachVehicles.sqf @@ -0,0 +1,65 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Attaches child to parent vehicle. + * Run globally. + * + * Arguments: + * 0: Vehicle to tow from + * 1: Vehicle to tow + * 2: Rope End Position + * 3: Rope + * 4: Attached Helper Object + * + * Return Value: + * None + * + * Example: + * [parent, cursorObject, [0,0,0], ropes parent select 0] call ace_towing_fnc_attachVehicles + * + * Public: No + */ +params ["_parent", "_child", "_relativeAttachPos", "_rope", "_helper"]; +TRACE_5("attachVehicles",_parent,_child,_relativeAttachPos,_rope,_helper); + +if (local _parent) then { + _helper ropeDetach _rope; + [_child, _relativeAttachPos] ropeAttachTo _rope; + deleteVehicle _helper; +}; + +_child setTowParent _parent; +if (!isServer) exitWith {}; + +_child setVariable [QGVAR(parent), _parent, true]; +GVAR(allChildren) pushBack _child; + +{ + if (-1 == _x getVariable [QGVAR(DeletedEHID), -1]) then { + _x setVariable [QGVAR(DeletedEHID), _x addEventHandler ["Deleted", { + params ["_entity"]; + private _childHooks = _entity getVariable [QGVAR(childHooks), []]; + private _parentHooks = _entity getVariable [QGVAR(parentHooks), []]; + TRACE_3("Deleted EH",_entity,_childHooks,_parentHooks); + { + [objNull, _x, _entity] call FUNC(detachRope); + } forEach (_childHooks + _parentHooks); + if (_childHooks isNotEqualTo []) then { // only for parent + // because deleting lasts for several frames we have to delete RB EH to fix double cleanup + _entity removeEventHandler ["RopeBreak", _entity getVariable QGVAR(RopeBreakEHID)]; + }; + }]]; + }; +} forEach [_parent, _child]; + +if (-1 == _parent getVariable [QGVAR(RopeBreakEHID), -1]) then { + _parent setVariable [QGVAR(RopeBreakEHID), _parent addEventHandler ["RopeBreak", { + params ["_parent", "_rope", "_child"]; + if (isNull _rope) exitWith {}; // happens + private _hook = _rope getVariable [QGVAR(hook), objNull]; + private _hookChild = _hook getVariable [QGVAR(vars), []] param [1, objNull]; + if (isNull _hook || {_child != _hookChild}) exitWith {}; // handle helper detach + TRACE_4("RopeBreak EH",_parent,_rope,_child,_hook); + [objNull, _hook] call FUNC(detachRope); + }]]; +}; diff --git a/addons/towing/functions/fnc_detachChild.sqf b/addons/towing/functions/fnc_detachChild.sqf new file mode 100644 index 0000000000..a30f90d8c6 --- /dev/null +++ b/addons/towing/functions/fnc_detachChild.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Detaches child. + * Run globally. + * + * Arguments: + * 0: Child + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_towing_fnc_detachChild + * + * Public: No + */ +params ["_child"]; +TRACE_1("detachChild",_child); + +_child setTowParent objNull; + +if (!isServer) exitWith {}; + +_child setVariable [QGVAR(parent), objNull, true]; +GVAR(allChildren) = GVAR(allChildren) - [_child]; + +private _childChildHooks = _child getVariable [QGVAR(childHooks), []]; +if (_childChildHooks isEqualTo []) then { + TRACE_1("remove Deleted EH",_child); + _child removeEventHandler ["Deleted", _child getVariable [QGVAR(DeletedEHID), -1]]; + _child setVariable [QGVAR(DeletedEHID), -1]; +}; diff --git a/addons/towing/functions/fnc_detachRope.sqf b/addons/towing/functions/fnc_detachRope.sqf new file mode 100644 index 0000000000..8baed5532d --- /dev/null +++ b/addons/towing/functions/fnc_detachRope.sqf @@ -0,0 +1,60 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Detaches rope of given hook and gives rope item back. + * + * Arguments: + * 0: Player + * 1: Rope Hook + * 2: Deleted object (default: objNull) + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_towing_fnc_detachRope + * + * Public: No + */ +params ["_unit", "_hook", ["_deletedObject", objNull]]; + +private _hookVars = _hook getVariable QGVAR(vars); +if (isNil "_hookVars") then { // this is hookParent + _hook = _hook getVariable QGVAR(hook); + _hookVars = _hook getVariable QGVAR(vars); +}; + +_hookVars params ["_parent", "_child", "_rope", "_ropeClass", "_hookParent"]; + +TRACE_8("detachRope",_unit,_parent,_child,_hook,_hookParent,_rope,_ropeClass,_deletedObject); + +ropeDestroy _rope; // can run on client + +if (!isNull _unit && {_ropeClass isNotEqualTo ""}) then { + [_unit, _ropeClass, true] call CBA_fnc_addItem; +}; + +{ + detach _x; + deleteVehicle _x; +} forEach [_hook, _hookParent]; + +// cleanup object variables and EHs only if function isn't called from Deleted EH +if (isNull _deletedObject || {_parent isNotEqualTo _deletedObject}) then { + private _parentChildHooks = _parent getVariable [QGVAR(childHooks), []]; + _parentChildHooks = _parentChildHooks - [_hook]; + _parent setVariable [QGVAR(childHooks), _parentChildHooks, true]; + + if (_parentChildHooks isEqualTo []) then { + [QGVAR(cleanupParent), _parent] call CBA_fnc_serverEvent; + }; +}; +if (isNull _deletedObject || {_child isNotEqualTo _deletedObject}) then { + private _childParentHooks = _child getVariable [QGVAR(parentHooks), []]; + _childParentHooks = _childParentHooks - [_hook]; + _child setVariable [QGVAR(parentHooks), _childParentHooks, true]; + + if (_childParentHooks isEqualTo []) then { + [QGVAR(detachChild), _child] call CBA_fnc_globalEvent; + }; +}; diff --git a/addons/towing/functions/fnc_getDetachActions.sqf b/addons/towing/functions/fnc_getDetachActions.sqf new file mode 100644 index 0000000000..4f86220797 --- /dev/null +++ b/addons/towing/functions/fnc_getDetachActions.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Creates vehicle detach actions for attached ropes. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Detach actions + * + * Example: + * cursorObject call ace_towing_fnc_getDetachActions + * + * Public: No + */ +params ["_vehicle"]; + +private _statement = { + params ["", "_player", "_hook"]; + [_player, _hook] call FUNC(detachRope); +}; + +private _parentHooks = _vehicle getVariable [QGVAR(parentHooks), []]; +private _childHooks = _vehicle getVariable [QGVAR(childHooks), []]; + +(_parentHooks + _childHooks) apply { + private _hook = _x; + _hook getVariable QGVAR(vars) params ["_hookParent", "_hookChild"]; + private _partner = [_hookParent, _hookChild] select (_vehicle == _hookParent); + private _partnerName = getText (configOf _partner >> "displayName"); + private _partnerOwnerName = [_partner, true] call EFUNC(common,getName); + if (_partnerOwnerName != "") then { + _partnerName = format ["%1, %2", _partnerName, _partnerOwnerName]; + }; + private _name = format ["%1 (%2)", LLSTRING(detach), _partnerName]; + private _icon = [_partner] call EFUNC(common,getVehicleIcon); + private _action = [format ["%1", _hook], _name, _icon, _statement, {true}, {}, _hook] call EFUNC(interact_menu,createAction); + [_action, [], _vehicle] +} diff --git a/addons/towing/functions/fnc_isSuitableSimulation.sqf b/addons/towing/functions/fnc_isSuitableSimulation.sqf new file mode 100644 index 0000000000..a4131e6a91 --- /dev/null +++ b/addons/towing/functions/fnc_isSuitableSimulation.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Condition for whether or not this object is a simulation type which can be a tow parent (TankX or CarX) + * + * Arguments: + * 0: Vehicle to tow from + * 1: Check type - Parent or Child + * + * Return Value: + * Whether or not this vehicle can tow + * + * Example: + * [cursorObject] call ace_towing_fnc_isSuitableSimulation + * + * Public: No + */ +params ["_target"]; + +// need toLower since apparently this isn't case sensitive +private _simulationType = getText ((configOf _target) >> "simulation"); +// TRACE_1("sim type",_simulationType); + +// Biki lies, you can both tow and tow as either TankX or CarX +(toLowerANSI _simulationType) in ["tankx", "carx", "shipx"] diff --git a/addons/towing/functions/fnc_onMouseButtonDown.sqf b/addons/towing/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..401cf8c8a1 --- /dev/null +++ b/addons/towing/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Handles mouse interaction for attaching rope + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_towing_fnc_onMouseButtonDown + * + * Public: No + */ +params ["", "_button"]; + +if (_button > 1) exitWith {}; + +if (_button == 1) then { + GVAR(mouseRight) = true; +} else { + GVAR(mouseLeft) = true; +} + diff --git a/addons/towing/functions/fnc_onMouseButtonUp.sqf b/addons/towing/functions/fnc_onMouseButtonUp.sqf new file mode 100644 index 0000000000..04a406e9f2 --- /dev/null +++ b/addons/towing/functions/fnc_onMouseButtonUp.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Handles mouse interaction for attaching rope + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_towing_fnc_onMouseButtonUp + * + * Public: No + */ +params ["", "_button"]; + +if (_button > 1) exitWith {}; + +if (_button == 1) then { + GVAR(mouseRight) = false; +} else { + GVAR(mouseLeft) = false; +} + diff --git a/addons/towing/functions/fnc_startTow.sqf b/addons/towing/functions/fnc_startTow.sqf new file mode 100644 index 0000000000..33cee1cb7b --- /dev/null +++ b/addons/towing/functions/fnc_startTow.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Start rope attach PFH + * + * Arguments: + * 0: Unit wanting to start towing + * 1: Vehicle to tow from + * 2: Rope Classname + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "ACE_rope3"] call ace_towing_fnc_startTow + * + * Public: No + */ +params ["_unit", "_target", "_ropeClass"]; + +GVAR(attachHelper) = "Sign_Sphere10cm_F" createVehicleLocal [0, 0, 0]; +[_unit] call EFUNC(weaponselect,putWeaponAway); + +private _ropeLength = getNumber (configFile >> "CfgWeapons" >> _ropeClass >> QEGVAR(logistics_rope,length)); +if (_ropeLength == 0) then { + _ropeLength = 3; +}; + +_unit removeItem _ropeClass; + +GVAR(isSwimming) = _unit call EFUNC(common,isSwimming); +GVAR(putWeaponAwayNextFrame) = false; +GVAR(cancel) = false; +GVAR(canAttach) = false; +GVAR(onMouseButtonDownEHID) = ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; +[LINKFUNC(towStateMachinePFH), 0, [TOW_STATE_ATTACH_PARENT, _unit, _target, objNull, _ropeLength, _ropeClass]] call CBA_fnc_addPerFrameHandler; +[QGVAR(ropeDeployed), [_unit, _target, _ropeClass]] call CBA_fnc_localEvent; diff --git a/addons/towing/functions/fnc_towStateMachinePFH.sqf b/addons/towing/functions/fnc_towStateMachinePFH.sqf new file mode 100644 index 0000000000..50afdeb153 --- /dev/null +++ b/addons/towing/functions/fnc_towStateMachinePFH.sqf @@ -0,0 +1,169 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Called per frame. Handles current unit state for attaching a rope to two vehicles. + * + * Arguments: + * 0: PFEH Args + * 1: PFID + * + * Return Value: + * None + * + * Example: + * [[],0]] call ace_towing_fnc_towStateMachinePFH + * + * Public: No + */ +params ["_args", "_handle"]; +_args params ["_state", "_unit", "_parent", "_rope", "_length", "_ropeClass"]; + +private _wasSwimming = GVAR(isSwimming); +GVAR(isSwimming) = _unit call EFUNC(common,isSwimming); + +// skip this frame to wait for weapon in hands +if (_wasSwimming && {!GVAR(isSwimming)}) exitWith {GVAR(putWeaponAwayNextFrame) = true;}; +// move weapon to back in next frame +if (GVAR(putWeaponAwayNextFrame)) then { + if (currentWeapon _unit isNotEqualTo "") then {[_unit] call EFUNC(weaponselect,putWeaponAway)}; + GVAR(putWeaponAwayNextFrame) = false; +}; + +// block fire when swimming in wetsuit with weapon +if (GVAR(isSwimming) && {currentWeapon _unit isNotEqualTo ""}) then { + if (GVAR(blockFireEHID) == -1) then { + GVAR(blockFireEHID) = [_unit, "DefaultAction", {true}, {}] call EFUNC(common,addActionEventHandler); + }; +} else { + if (GVAR(blockFireEHID) != -1) then { + [_unit, "DefaultAction", GVAR(blockFireEHID)] call EFUNC(common,removeActionEventHandler); + GVAR(blockFireEHID) = -1; + }; +}; + +private _exitCondition = !( + (alive GVAR(attachHelper)) && + { alive _parent } && + { alive _unit } && + { + currentWeapon _unit isEqualTo "" + || {_unit call EFUNC(common,isSwimming)} // swimming in wetsuit forces weapon in hands + || {getPosASLW _unit select 2 < -1.5} // walking-to-swimming animation in wetsuit lasts for 3 seconds + } && + { [_unit, objNull, [INTERACTION_EXCEPTIONS]] call EFUNC(common,canInteractWith) } && + { "unconscious" isNotEqualTo toLowerANSI animationState _unit } && + { !(_unit getVariable ["ACE_isUnconscious", false]) } && + { ACE_player == _unit } +); + +if (_exitCondition && {_state < TOW_STATE_CANCEL}) then { + _state = TOW_STATE_CANCEL; +}; + +switch (_state) do { + case TOW_STATE_ATTACH_PARENT: { + // TRACE_2("state attach parent",_unit,_parent); + [_unit, _parent, objNull, objNull, [0, 0, 0], _length] call FUNC(attachRopePFH); + + if (GVAR(canAttach) && { GVAR(mouseLeft) }) then { + _args set [0, TOW_STATE_ATTACH_CHILD]; + // can't use unit hand because rope doesn't change position when hand moving + // can't use createVehicleLocal because rope can be non-local (like parent) and it must be attached to global vehicle + GVAR(helper) = createVehicle [QGVAR(helper), [0, 0, 0], [], 0, "CAN_COLLIDE"]; + GVAR(helper) attachTo [_unit, [0, 0, 0], "LeftHand", true]; + _rope = ropeCreate [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual GVAR(attachHelper), GVAR(helper), [0, 0, 0], _length]; + _args set [3, _rope]; + }; + + if (GVAR(mouseRight) || GVAR(cancel)) then { + _args set [0, TOW_STATE_CANCEL]; + GVAR(cancel) = false; + }; + }; + case TOW_STATE_ATTACH_CHILD: { + // TRACE_3("state attach child",_unit,_parent,_rope); + [_unit, objNull, _parent, _rope, getPosASLVisual _rope, _length] call FUNC(attachRopePFH); + + if (GVAR(canAttach) && { GVAR(mouseLeft) }) then { + _args set [0, TOW_STATE_ATTACH]; + }; + + if (GVAR(mouseRight) || GVAR(cancel)) then { + _args set [0, TOW_STATE_CANCEL]; + GVAR(cancel) = false; + }; + }; + case TOW_STATE_ATTACH: { + TRACE_3("state attach",GVAR(attachHelper),_parent,_rope); + private _child = GVAR(attachHelper) getVariable [QGVAR(object), objNull]; + private _relativeAttachPos = _child worldToModelVisual ASLtoAGL getPosASLVisual GVAR(attachHelper); + + TRACE_3("child&pos",_parent,_child,_relativeAttachPos); + + if (_child isEqualTo _parent) exitWith { + _args set [0, TOW_STATE_CANCEL]; + ERROR_MSG("_child isEqualTo _parent"); + }; + + if (GVAR(cancel)) exitWith { + _args set [0, TOW_STATE_CANCEL]; + GVAR(cancel) = false; + }; + + detach GVAR(helper); + // can't delete GVAR(helper) without ropeDetach which requires local rope (==parent), so pass it to owner + if (isNull (_child getVariable [QGVAR(parent), objNull])) then { + [QGVAR(attachVehicles), [_parent, _child, _relativeAttachPos, _rope, GVAR(helper)]] call CBA_fnc_globalEvent; + } else { + [QGVAR(ropeAttachTo), [_child, _relativeAttachPos, _rope, GVAR(helper)], _parent] call CBA_fnc_targetEvent; + }; + + private _hookParent = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _hookParent attachTo [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual _rope]; + + private _hook = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _hook attachTo [_child, _relativeAttachPos]; + + // use array to decrease public setVar count + private _hookVars = [_parent, _child, _rope, _ropeClass, _hookParent]; + _hook setVariable [QGVAR(vars), _hookVars, true]; + + _hookParent setVariable [QGVAR(hook), _hook, true]; + _rope setVariable [QGVAR(hook), _hook, true]; + + private _childParentHooks = _child getVariable [QGVAR(parentHooks), []]; + _childParentHooks pushBack _hook; + _child setVariable [QGVAR(parentHooks), _childParentHooks, true]; + + private _parentChildHooks = _parent getVariable [QGVAR(childHooks), []]; + _parentChildHooks pushBack _hook; + _parent setVariable [QGVAR(childHooks), _parentChildHooks, true]; + + _args set [0, TOW_STATE_CLEANUP]; + }; + case TOW_STATE_CANCEL: { + TRACE_1("state cancel",_rope); + if !(isNull _rope) then { + detach GVAR(helper); + deleteVehicle GVAR(helper); + ropeDestroy _rope; + }; + [_unit, _ropeClass, true] call CBA_fnc_addItem; + _args set [0, TOW_STATE_CLEANUP]; + GVAR(cancel) = false; + [QGVAR(ropeDeployCanceled), [_unit, _ropeClass]] call CBA_fnc_localEvent; + (localize LSTRING(canceled)) call CBA_fnc_notify; + }; + case TOW_STATE_CLEANUP: { + TRACE_2("state cleanup",GVAR(attachHelper),_handle); + deleteVehicle GVAR(attachHelper); + [_handle] call CBA_fnc_removePerFrameHandler; + ["MouseButtonDown", GVAR(onMouseButtonDownEHID)] call CBA_fnc_removeDisplayHandler; + _unit setVariable [QGVAR(hint), []]; + call EFUNC(interaction,hideMouseHint); + if (GVAR(blockFireEHID) != -1) then { + [_unit, "DefaultAction", GVAR(blockFireEHID)] call EFUNC(common,removeActionEventHandler); + GVAR(blockFireEHID) = -1; + }; + }; +}; diff --git a/addons/towing/initSettings.inc.sqf b/addons/towing/initSettings.inc.sqf new file mode 100644 index 0000000000..dbfe326d4c --- /dev/null +++ b/addons/towing/initSettings.inc.sqf @@ -0,0 +1,14 @@ +[ + QGVAR(addRopeToVehicleInventory), "CHECKBOX", + LSTRING(Setting_addRopeToVehicleInventory_DisplayName), + ELSTRING(main,Category_Logistics), + true, + true, + { + if !(_this && {isServer} && {isNil QGVAR(addRopeToVehicleInventory_initialized)}) exitWith {}; + GVAR(addRopeToVehicleInventory_initialized) = true; + { + [_x, "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler; + } forEach ["Car", "Ship", "Tank"]; + } +] call CBA_fnc_addSetting; diff --git a/addons/towing/script_component.hpp b/addons/towing/script_component.hpp new file mode 100644 index 0000000000..c52e84046e --- /dev/null +++ b/addons/towing/script_component.hpp @@ -0,0 +1,26 @@ +#define COMPONENT towing +#define COMPONENT_BEAUTIFIED Towing +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_TOWING + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_TOWING + #define DEBUG_SETTINGS DEBUG_SETTINGS_TOWING +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define TOW_ACTION_DISTANCE 3 +#define INTERACTION_EXCEPTIONS "isNotOnLadder", "isNotSwimming" + +#define TOW_STATE_ATTACH_PARENT 0 +#define TOW_STATE_ATTACH_CHILD 1 +#define TOW_STATE_ATTACH 2 +#define TOW_STATE_CANCEL 3 +#define TOW_STATE_CLEANUP 4 diff --git a/addons/towing/stringtable.xml b/addons/towing/stringtable.xml new file mode 100644 index 0000000000..949d36dd48 --- /dev/null +++ b/addons/towing/stringtable.xml @@ -0,0 +1,148 @@ + + + + + Towing + けん引 + Remorquage + Traino + Буксирование + Abschleppen + Holowanie + 牵引 + 견인 + Remolcado + + + Attach Tow Rope + けん引ロープを取り付け + Attacher la corde de remorquage + Attacca la corda di traino + Прикрепить буксировочный канат + Abschleppseil befestigen + Przypnij linkę holowniczą + 系上牵引绳 + 견인줄 부착 + Sujetar cuerda de remolcado + + + Attaching Cancelled + 取り付けを中止しました + Attachage annulé + Attaccamento interrotto + Прикрепление отменено + Befestigen Abgebrochen + Przyczepianie anulowane + 取消系上绳索 + 견인 취소됨 + Sujección cancelada + + + Attach Tow Rope (3.2m) + けん引ロープ (3.2m) を取り付け + Attacher la corde (3,2 m) + Attacca corda di traino (3,2m) + Прикрепить буксировочный канат (3.2м) + Befestige Seil (3.2m) + Przypnij linkę holowniczą (3,2m) + 系上牵引绳(3.2米) + 견인줄 부착(3.2M) + Sujetar cuerda de remolcado (3.2m) + + + Attach Tow Rope (6.2m) + けん引ロープ (6.2m) を取り付け + Attacher la corde (6,2 m) + Attacca corda di traino (6,2m) + Прикрепить буксировочный канат (6.2м) + Befestige Seil (6.2m) + Przypnij linkę holowniczą (6,2m) + 系上牵引绳(6.2米) + 견인줄 부착(6.2M) + Sujetar cuerda de remolcado (6.2m) + + + Attach Tow Rope (12.2m) + けん引ロープ (12.2m) を取り付け + Attacher la corde (12,2 m) + Attacca corda di traino (12,2m) + Прикрепить буксировочный канат (12.2м) + Befestige Seil (12.2m) + Przypnij linkę holowniczą (12,2m) + 系上牵引绳(12.2米) + 견인줄 부착(12.2M) + Sujetar cuerda de remolcado (12.2m) + + + Attach Tow Rope (15.2m) + けん引ロープ (15.2m) を取り付け + Attacher la corde (15,2 m) + Attacca corda di traino (15,2m) + Прикрепить буксировочный канат (15.2м) + Befestige Seil (15.2m) + Przypnij linkę holowniczą (15,2m) + 系上牵引绳(15.2米) + 견인줄 부착(15.2M) + Sujetar cuerda de remolcado (15.2m) + + + Attach Tow Rope (18.3m) + けん引ロープ (18.3m) を取り付け + Attacher la corde (18,3 m) + Attacca corda di traino (18,3m) + Прикрепить буксировочный канат (18.3м) + Befestige Seil (18.3m) + Przypnij linkę holowniczą (18,3m) + 系上牵引绳(18.3米) + 견인줄 부착(18.2M) + Sujetar cuerda de remolcado (18.3m) + + + Attach Tow Rope (27.4m) + けん引ロープ (27.4m) を取り付け + Attacher la corde (27,4 m) + Attacca corda di traino (27,4m) + Прикрепить буксировочный канат (27.4м) + Befestige Seil (27.4m) + Przypnij linkę holowniczą (27,4m) + 系上牵引绳(27.4米) + 견인줄 부착(27.4M) + Sujetar cuerda de remolcado (27.4m) + + + Attach Tow Rope (36.6m) + けん引ロープ (36.6m) を取り付け + Attacher la corde (36,6 m) + Attacca corda di traino (36,6m) + Прикрепить буксировочный канат (36.6м) + Befestige Seil (36.6m) + Przypnij linkę holowniczą (36,6m) + 系上牵引绳(36.6米) + 견인줄 부착(36.6M) + Sujetar cuerda de remolcado (36.6m) + + + Detach Tow Rope + けん引ロープを外す + Détacher la corde + Stacca corda di traino + Отцепить буксировочный канат + Entferne Abschleppseil + Odepnij linkę holowniczą + 解开牵引绳 + 견인줄 분리 + Desmontar cuerda de remolcado + + + Add Tow Rope to Vehicle Inventory + Добавить буксировочный трос в инвентарь машин + Dodaj linkę holowniczą do ekwipunku pojazdów + Aggiungi corde di traino all'inventario dei veicoli + 차량 소지품에 견인줄 추가 + Añadir cuerda de remolcado al inventario del vehículo + 車両のインベントリに牽引ロープを追加する + Abschleppseil zum Fahrzeuginventar hinzufügen + Ajouter une corde à l'inventaire des véhicules + + + diff --git a/addons/trenches/ACE_Arsenal_Stats.hpp b/addons/trenches/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..d8f79f3e5c --- /dev/null +++ b/addons/trenches/ACE_Arsenal_Stats.hpp @@ -0,0 +1,13 @@ +class EGVAR(arsenal,stats) { + class statBase; + class GVAR(entrenchingTool): statBase { + scope = 2; + priority = -1; + stats[] = {QGVAR(entrenchingTool)}; + displayName = CSTRING(EntrenchingToolName); + showText = 1; + textStatement = QUOTE(localize QUOTE(ELSTRING(common,yes))); + condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); + tabs[] = {{0,1,5}, {7}}; + }; +}; diff --git a/addons/trenches/CfgEventHandlers.hpp b/addons/trenches/CfgEventHandlers.hpp index 5b2eb3a053..48780d7241 100644 --- a/addons/trenches/CfgEventHandlers.hpp +++ b/addons/trenches/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; @@ -27,6 +27,6 @@ class Extended_Killed_EventHandlers { class Extended_DisplayLoad_EventHandlers { class RscDisplayMission { - ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); }; }; diff --git a/addons/trenches/CfgVehicles.hpp b/addons/trenches/CfgVehicles.hpp index 3b13be21a8..bec66e2e64 100644 --- a/addons/trenches/CfgVehicles.hpp +++ b/addons/trenches/CfgVehicles.hpp @@ -9,12 +9,17 @@ class CBA_Extended_EventHandlers; class ACE_ContinueDiggingTrench { \ displayName = CSTRING(ContinueDiggingTrench); \ condition = QUOTE([ARR_2(_target,_player)] call FUNC(canContinueDiggingTrench)); \ - statement = QUOTE([ARR_2(_target,_player)] call FUNC(continueDiggingTrench);); \ + statement = QUOTE([ARR_2(_target,_player)] call FUNC(continueDiggingTrench)); \ }; \ class ACE_RemoveTrench { \ displayName = CSTRING(RemoveEnvelope); \ condition = QUOTE([ARR_2(_target,_player)] call FUNC(canRemoveTrench)); \ - statement = QUOTE([ARR_2(_target,_player)] call FUNC(removeTrench);); \ + statement = QUOTE([ARR_2(_target,_player)] call FUNC(removeTrench)); \ + }; \ + class ACE_CamouflageTrench { \ + displayName = CSTRING(CamouflageTrench); \ + condition = QUOTE([ARR_2(_target,_player)] call FUNC(canCamouflageTrench)); \ + statement = QUOTE([ARR_2(_target,_player)] call FUNC(camouflageTrench)); \ }; \ }; \ } @@ -53,8 +58,8 @@ class CfgVehicles { descriptionShort = CSTRING(EnevlopeSmallDescription); model = QPATHTOEF(apl,ace_envelope_small4.p3d); scope = 2; - GVAR(diggingDuration) = 20; - GVAR(removalDuration) = 12; + GVAR(diggingDuration) = QGVAR(smallEnvelopeDigDuration); + GVAR(removalDuration) = QGVAR(smallEnvelopeRemoveDuration); GVAR(noGeoClass) = "ACE_envelope_small_NoGeo"; GVAR(placementData)[] = {2,3,0.35}; GVAR(grassCuttingPoints)[] = {{0,-0.5,0}}; @@ -62,6 +67,8 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + hiddenSelections[] = {"velka"}; + hiddenSelectionsTextures[] = {"a3\map_data\gdt_mud_co.paa"}; }; class ACE_envelope_big: BagFence_base_F { author = ECSTRING(common,ACETeam); @@ -69,8 +76,8 @@ class CfgVehicles { descriptionShort = CSTRING(EnevlopeBigDescription); model = QPATHTOEF(apl,ace_envelope_big4.p3d); scope = 2; - GVAR(diggingDuration) = 25; - GVAR(removalDuration) = 15; + GVAR(diggingDuration) = QGVAR(bigEnvelopeDigDuration); + GVAR(removalDuration) = QGVAR(bigEnvelopeRemoveDuration); GVAR(noGeoClass) = "ACE_envelope_big_NoGeo"; GVAR(placementData)[] = {6,1.1,0.20}; GVAR(grassCuttingPoints)[] = {{-1.5,-1,0},{1.5,-1,0}}; @@ -78,6 +85,8 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + hiddenSelections[] = {"velka"}; + hiddenSelectionsTextures[] = {"a3\map_data\gdt_mud_co.paa"}; }; class ACE_envelope_small_NoGeo: ACE_envelope_small { diff --git a/addons/trenches/CfgWeapons.hpp b/addons/trenches/CfgWeapons.hpp index de79bc277f..c4548606db 100644 --- a/addons/trenches/CfgWeapons.hpp +++ b/addons/trenches/CfgWeapons.hpp @@ -9,8 +9,11 @@ class CfgWeapons { model = QPATHTOEF(apl,ace_entrchtool.p3d); picture = QPATHTOF(ui\w_entrchtool_ca.paa); scope = 2; + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; + + GVAR(entrenchingTool) = 1; }; }; diff --git a/addons/trenches/README.md b/addons/trenches/README.md index 8b4a0d7a36..cd19758221 100644 --- a/addons/trenches/README.md +++ b/addons/trenches/README.md @@ -1,22 +1,7 @@ ace_trenches ================= -Adds item 'ACE_entrenchingtool' +Provides players with the capability of digging trenches. + +Adds item 'ACE_EntrenchingTool' Adds 2 trenches; Envelope - Small & Envelop - Big - -### Whitelist surfaces for digging -Single surfaces can be whitelisted by adding `ACE_canDig = 1` into `CfgSurfaces`. -Example: -```cpp -class CfgSurfaces { - class myAwesomeSurface { - ACE_canDig = 1; - }; -}; -``` - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Grey](https://github.com/Grey-Soldierman) diff --git a/addons/trenches/XEH_PREP.hpp b/addons/trenches/XEH_PREP.hpp index 2e671acb85..340cfe482d 100644 --- a/addons/trenches/XEH_PREP.hpp +++ b/addons/trenches/XEH_PREP.hpp @@ -1,4 +1,7 @@ +PREP(blockTrench_place); +PREP(camouflageTrench); +PREP(canCamouflageTrench); PREP(canContinueDiggingTrench); PREP(canDigTrench); PREP(canRemoveTrench); @@ -9,6 +12,7 @@ PREP(handlePlayerChanged); PREP(handlePlayerInventoryChanged); PREP(handleScrollWheel); PREP(handleUnconscious); +PREP(hasEntrenchingTool); PREP(placeCancel); PREP(placeConfirm); PREP(placeTrench); diff --git a/addons/trenches/XEH_postInit.sqf b/addons/trenches/XEH_postInit.sqf index 1fbfa24116..59a6fb8a08 100644 --- a/addons/trenches/XEH_postInit.sqf +++ b/addons/trenches/XEH_postInit.sqf @@ -3,6 +3,17 @@ if (isServer) then { // Cancel dig on hard disconnection. Function is identical to killed addMissionEventHandler ["HandleDisconnect", {_this call FUNC(handleKilled)}]; + + // Wrapper for blockTrench_place, on failure send hint back to source + [QGVAR(layTrenchline), { + params [["_source", objNull, [objNull]], ["_args", [], [[]]]]; + private _return = _args call FUNC(blockTrench_place); + TRACE_3("layTrenchline EH",_source,_args,_return); + _return params ["_success", "_reason", ["_info", ""]]; + if ((!_success) && {!isNull _source}) then { + [QEGVAR(common,displayTextStructured), [["%1:
%2
%3", "str_mis_state_failed", _reason, _info], 3], [_source]] call CBA_fnc_targetEvent; + }; + }] call CBA_fnc_addEventHandler; }; if (!hasInterface) exitWith {}; @@ -16,11 +27,11 @@ GVAR(digDirection) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel dig on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -["loadout", FUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; //@todo Captivity? diff --git a/addons/trenches/XEH_preInit.sqf b/addons/trenches/XEH_preInit.sqf index b47cf6628d..94decd550a 100644 --- a/addons/trenches/XEH_preInit.sqf +++ b/addons/trenches/XEH_preInit.sqf @@ -6,4 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +GVAR(entrenchingTools) = call (uiNamespace getVariable QGVAR(entrenchingTools)); + ADDON = true; diff --git a/addons/trenches/XEH_preStart.sqf b/addons/trenches/XEH_preStart.sqf index 022888575e..c966b2c9b6 100644 --- a/addons/trenches/XEH_preStart.sqf +++ b/addons/trenches/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +private _entrenchingTools = (QUOTE(getNumber (_x >> QQGVAR(entrenchingTool)) > 0) configClasses (configFile >> "CfgWeapons") apply {configName _x}); +_entrenchingTools append (QUOTE(getNumber (_x >> QQGVAR(entrenchingTool)) > 0) configClasses (configFile >> "CfgVehicles") apply {configName _x}); +TRACE_1("",_entrenchingTools); + +uiNamespace setVariable [QGVAR(entrenchingTools), compileFinal str _entrenchingTools]; diff --git a/addons/trenches/config.cpp b/addons/trenches/config.cpp index 3f76f012ed..18d5e4a3d6 100644 --- a/addons/trenches/config.cpp +++ b/addons/trenches/config.cpp @@ -14,6 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Arsenal_Stats.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/trenches/functions/fnc_blockTrench_place.sqf b/addons/trenches/functions/fnc_blockTrench_place.sqf new file mode 100644 index 0000000000..4c0a218307 --- /dev/null +++ b/addons/trenches/functions/fnc_blockTrench_place.sqf @@ -0,0 +1,173 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Dig trenchline + * + * Arguments: + * 0: Position + * 1: Position + * 2: Force - ignoring saftey checks (optional: false) + * 3: Cut Grass (optional: false) + * 4: Dry Run - Just test if possible (can run on clients) + * + * Return Value: + * + * 0: Success + * 1: Failure reason + * 2: Extra info + * + * Example: + * [a, b] call ace_trenches_fnc_blockTrench_place + * + * Public: No + */ + +params [["_start2d", [], [[]]], ["_end2d", [], [[]]], ["_force", false, [false]], ["_cutGrass", false, [false]], ["_dryRun", false, [false]]]; +TRACE_4("blockTrench_place",_start2d,_end2d,_force,_dryRun); + +if ((!isServer) && {!_dryRun}) exitWith { ERROR("function must be called on server"); [false, "server-only"]; }; + +scopeName "main"; + +// get maths +getTerrainInfo params ["", "", "_cellsize"]; +if ((_cellsize < 1) || {_cellsize > 10}) exitWith { [false, "world cellsize"] breakOut "main" }; // malden is 12.5 + +// for Land_Trench_01_forest_F +private _modelX = 2.1; +private _modelZ = 1.1; +private _modelSize = 3.75; + +private _landAdjust = -1.7; // how deep we dig into the terrain +private _trenchDepth = -1; // how deep the floor is +private _trenchWidth = 1; // offset for each side from center +private _blockAdjust = -0.45; // get block to sit flush +private _blockScale = _cellsize / _modelSize; // scale up block to fit cellsize + +private _xOffset = _trenchWidth + _blockScale * _modelX; +private _zOffset = _blockAdjust - (_blockScale - 1) * _modelZ; +private _testRadius = 1 * _blockScale * _modelSize; + +// convert to terrain grid +_start2d = (_start2d select [0,2]) apply {_cellsize * round (_x / _cellsize)}; +_end2d = (_end2d select [0,2]) apply {_cellsize * round (_x / _cellsize)}; +_start2d params ["_ax", "_ay"]; +_end2d params ["_bx", "_by"]; +{ // make sure points aren't outside terrain + if (_x < _cellsize || {_x > (worldSize - _cellsize)}) exitWith { [false, "outside map boundry"] breakOut "main" }; +} forEach [_ax, _ay, _bx, _by]; +TRACE_3("adjusted",_cellsize,_start2d,_end2d); + +// get direction and start/end +private _east = (abs (_ax - _bx)) >= (abs (_ay - _by)); +private _origin2D = []; +private _length = 0; +if (_east) then { + _origin2D = [_end2d, _start2d] select (_ax < _bx); + _length = (abs (_ax - _bx)) / _cellsize; +} else { + _origin2D = [_end2d, _start2d] select (_ay < _by); + _length = (abs (_ay - _by)) / _cellsize; +}; +TRACE_3("",_east,_origin2D,_length); +if (_length < 2) exitWith { [false, "too short"] breakOut "main" }; + +if (_dryRun) exitWith { // return an array of block positions + private _positions = []; + for "_i" from 0 to _length do { // intentionally inclusive + _positions pushBack (_origin2D vectorAdd (if (_east) then {[(_i + 0.5) * _cellsize, 0]} else {[0, (_i + 0.5) * _cellsize]})); + }; + [true, "dry run", _positions] +}; + + +// Test and get block data +private _blockData = []; +for "_i" from 0 to _length do { // intentionally inclusive + private _posCenter = _origin2D; + private _posLeft = _origin2D; + private _posRight = _origin2D; + private _direction = []; + if (_east) then { + _posCenter = _posCenter vectorAdd [(_i + 0.5) * _cellsize, 0]; + _posLeft = _posCenter vectorAdd [0, _xOffset]; + _posRight = _posCenter vectorAdd [0, -_xOffset]; + _direction = [0,-1,0]; + } else { + _posCenter = _posCenter vectorAdd [0, (_i + 0.5) * _cellsize]; + _posLeft = _posCenter vectorAdd [_xOffset, 0]; + _posRight = _posCenter vectorAdd [-_xOffset, 0]; + _direction = [-1,0,0]; + }; + + { // Test if each point is valid + private _pos2d = _x; + // check water + if ((!_force) && {(getTerrainHeightASL _pos2D) < 0}) then { [false, "water"] breakOut "main" }; + // check canDig (surface type) + if ((!_force) && {!([_pos2d] call EFUNC(common,canDig))}) then { [false, "canDig surface"] breakOut "main" }; + // check canDig (surface type) + if ((!_force) && {isOnRoad _pos2D}) then { [false, "road"] breakOut "main" }; + // check terrain objects + private _terrainObjects = nearestTerrainObjects [_pos2d, [], _testRadius, false, true]; + // todo: want to avoid touching trees and large rocks but could allow some small shrubs to be overlapped + if (_terrainObjects isNotEqualTo []) then { + if (_force) then { + WARNING_1("overlapping terrainObjects %1",_terrainObjects); + } else { + [false, "terrain object", _terrainObjects] breakOut "main"; + }; + }; + // check mission objects + private _missionObjects = nearestObjects [_origin2D, ["All"], _testRadius, true]; + _missionObjects = _missionObjects select { !(_x isKindOf "Logic") }; + if (_missionObjects isNotEqualTo []) then { + _missionObjects = _missionObjects apply {typeOf _x}; + if (_force) then { + WARNING_1("blocking missionObjects %1",_missionObjects); + } else { + [false, "mission object", _missionObjects] breakOut "main"; + }; + }; + } forEach [_posCenter, _posLeft, _posRight]; + + _posCenter set [2, (getTerrainHeightASL _posCenter) + _zOffset + _trenchDepth]; + _posLeft set [2, (getTerrainHeightASL _posLeft) + _zOffset]; + _posRight set [2, (getTerrainHeightASL _posRight) + _zOffset]; + + if (_cutGrass && {_i != 0} && {_i != _length}) then { + _blockData pushBack ["Land_ClutterCutter_medium_F", _blockScale, _posCenter, [0,1,0], surfaceNormal _posCenter]; + }; + // todo: there also is a snow textured block or do it right and make our own re-texturable model + _blockData pushBack ["Land_Trench_01_forest_F", _blockScale, _posCenter, _direction, surfaceNormal _posCenter]; + _blockData pushBack ["Land_Trench_01_forest_F", _blockScale, _posLeft, _direction, surfaceNormal _posLeft]; + _blockData pushBack ["Land_Trench_01_forest_F", _blockScale, _posRight, _direction vectorMultiply -1, surfaceNormal _posRight]; +}; + + +// Adjust terrain heights +private _terrainData = []; +for "_i" from 1 to (_length - 1) do { // skip first and last + private _posCenter = _origin2D; + if (_east) then { + _posCenter = _posCenter vectorAdd [_i * _cellsize, 0]; + } else { + _posCenter = _posCenter vectorAdd [0, _i * _cellsize]; + }; + + _posCenter set [2, (getTerrainHeight _posCenter) + _landAdjust]; + _terrainData pushBack _posCenter +}; +TRACE_1("setTerrainHeight",count _terrainData); +setTerrainHeight [_terrainData, true]; + + +// Place blocks +{ + _x params ["_xClass", "_xScale", "_xPosASL", "_xDir", "_xUp"]; + private _block = createSimpleObject [_xClass, _xPosASL]; + _block setVectorDirAndUp [_xDir, _xUp]; + if (_xScale != 1) then { _block setObjectScale _xScale; }; +} forEach _blockData; + +[true, "", _length] diff --git a/addons/trenches/functions/fnc_camouflageTrench.sqf b/addons/trenches/functions/fnc_camouflageTrench.sqf new file mode 100644 index 0000000000..efdfe82d5f --- /dev/null +++ b/addons/trenches/functions/fnc_camouflageTrench.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Cyruz + * Apply surfaceTexture to a completed trench. + * + * Arguments: + * 0: Trench + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [TrenchObj, ACE_player] call ace_trenches_fnc_camouflageTrench + * + * Public: No + */ + +params ["_trench", "_unit"]; + +_unit playActionNow "PutDown"; + +[{ + _this setObjectTextureGlobal [0, surfaceTexture getPosATL _this]; + _this setVariable [QGVAR(camouflaged), true, true]; +}, _trench, 2] call CBA_fnc_waitAndExecute; diff --git a/addons/trenches/functions/fnc_canCamouflageTrench.sqf b/addons/trenches/functions/fnc_canCamouflageTrench.sqf new file mode 100644 index 0000000000..074fd910a7 --- /dev/null +++ b/addons/trenches/functions/fnc_canCamouflageTrench.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Cyruz + * Checks if a unit can camouflage a trench. + * + * Arguments: + * 0: Trench + * 1: Unit + * + * Return Value: + * Can camouflage + * + * Example: + * [TrenchObj, ACE_player] call ace_trenches_fnc_canCamouflageTrench + * + * Public: No + */ + +params ["_trench", "_unit"]; + +if !(_unit call FUNC(hasEntrenchingTool)) exitWith {false}; + +// Prevent camouflage if not fully dug +if ((_trench getVariable [QGVAR(progress), 0]) != 1) exitWith {false}; + +// Prevent camouflage being applied once already camouflaged +if (_trench getVariable [QGVAR(camouflaged), false]) exitWith {false}; + +true diff --git a/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf b/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf index 97fee957b0..0074c21082 100644 --- a/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Checks if a unit can continue digging a trench @@ -18,8 +18,8 @@ params ["_trench", "_unit"]; -if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; -if ((_trench getVariable [QGVAR(progress), 0]) >= 1) exitWith {false}; +if !(_unit call FUNC(hasEntrenchingTool)) exitWith {false}; +if ((_trench getVariable [QGVAR(progress), 1]) >= 1) exitWith {false}; // Prevent removing/digging trench by more than one person if (_trench getVariable [QGVAR(digging), false]) exitWith {false}; diff --git a/addons/trenches/functions/fnc_canDigTrench.sqf b/addons/trenches/functions/fnc_canDigTrench.sqf index d6bf05993d..3ef8e2ee74 100644 --- a/addons/trenches/functions/fnc_canDigTrench.sqf +++ b/addons/trenches/functions/fnc_canDigTrench.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg, commy2, esteldunedain * Checks if a unit can dig a trench. @@ -17,6 +17,6 @@ params ["_unit"]; -if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; +if !(_unit call FUNC(hasEntrenchingTool)) exitWith {false}; _unit call EFUNC(common,canDig) diff --git a/addons/trenches/functions/fnc_canRemoveTrench.sqf b/addons/trenches/functions/fnc_canRemoveTrench.sqf index 23347fc310..8d1ec7578f 100644 --- a/addons/trenches/functions/fnc_canRemoveTrench.sqf +++ b/addons/trenches/functions/fnc_canRemoveTrench.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: SzwedzikPL * Checks if a unit can remove a trench @@ -18,7 +18,7 @@ params ["_trench", "_unit"]; -if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; +if !(_unit call FUNC(hasEntrenchingTool)) exitWith {false}; // Prevent removing/digging trench by more than one person if (_trench getVariable [QGVAR(digging), false]) exitWith {false}; diff --git a/addons/trenches/functions/fnc_continueDiggingTrench.sqf b/addons/trenches/functions/fnc_continueDiggingTrench.sqf index efedfa031b..78047c189e 100644 --- a/addons/trenches/functions/fnc_continueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_continueDiggingTrench.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support, esteldunedain * Continue process of digging trench. @@ -19,13 +19,13 @@ params ["_trench", "_unit"]; TRACE_2("continueDiggingTrench",_trench,_unit); -private _actualProgress = _trench getVariable [QGVAR(progress), 0]; +private _actualProgress = _trench getVariable [QGVAR(progress), 1]; if(_actualProgress == 1) exitWith {}; // Mark trench as being worked on _trench setVariable [QGVAR(digging), true, true]; -private _digTime = getNumber (configFile >> "CfgVehicles" >> (typeof _trench) >> QGVAR(diggingDuration)); +private _digTime = missionNamespace getVariable [getText (configOf _trench >> QGVAR(diggingDuration)), 20]; private _digTimeLeft = _digTime * (1 - _actualProgress); private _placeData = _trench getVariable [QGVAR(placeData), [[], []]]; @@ -48,6 +48,8 @@ private _fnc_onFinish = { private _progress = _trench getVariable [QGVAR(progress), 0]; _trench setVariable [QGVAR(progress), _progress, true]; + [QGVAR(finished), [_unit, _trench]] call CBA_fnc_globalEvent; + // Reset animation [_unit, "", 1] call EFUNC(common,doAnimation); }; @@ -63,7 +65,11 @@ private _fnc_onFailure = { // Reset animation [_unit, "", 1] call EFUNC(common,doAnimation); }; -[(_digTimeLeft + 0.5), [_unit, _trench], _fnc_onFinish, _fnc_onFailure, localize LSTRING(DiggingTrench)] call EFUNC(common,progressBar); +private _fnc_condition = { + (_this select 0) params ["_unit"]; + _unit call FUNC(hasEntrenchingTool) +}; +[(_digTimeLeft + 0.5), [_unit, _trench], _fnc_onFinish, _fnc_onFailure, localize LSTRING(DiggingTrench), _fnc_condition] call EFUNC(common,progressBar); if(_actualProgress == 0) then { [_unit, _trench, _trenchId, _basePos vectorDiff [0, 0, 1.0], _vecDirAndUp, _actualProgress] call FUNC(setTrenchPlacement); @@ -71,11 +77,11 @@ if(_actualProgress == 0) then { //Remove grass { private _trenchGrassCutter = createVehicle ["Land_ClutterCutter_medium_F", [0, 0, 0], [], 0, "NONE"]; - private _cutterPos = AGLToASL (_trench modelToWorld _x); + private _cutterPos = _trench modelToWorldWorld _x; _cutterPos set [2, getTerrainHeightASL _cutterPos]; _trenchGrassCutter setPosASL _cutterPos; deleteVehicle _trenchGrassCutter; - } foreach getArray (configFile >> "CfgVehicles" >> (typeof _trench) >> QGVAR(grassCuttingPoints)); + } foreach getArray (configOf _trench >> QGVAR(grassCuttingPoints)); }; private _progressLeft = (_actualProgress * 10) + 1; diff --git a/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf b/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf index 1a27e28d60..6b242c7918 100644 --- a/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. diff --git a/addons/trenches/functions/fnc_handleKilled.sqf b/addons/trenches/functions/fnc_handleKilled.sqf index 1142ad0f3b..bcdbd48580 100644 --- a/addons/trenches/functions/fnc_handleKilled.sqf +++ b/addons/trenches/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle death. diff --git a/addons/trenches/functions/fnc_handlePlayerChanged.sqf b/addons/trenches/functions/fnc_handlePlayerChanged.sqf index 77a152e421..28f1dea5e9 100644 --- a/addons/trenches/functions/fnc_handlePlayerChanged.sqf +++ b/addons/trenches/functions/fnc_handlePlayerChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle player changes. diff --git a/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf index 682cbae81e..2f341a0b86 100644 --- a/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf +++ b/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle the InventoryChanged event. @@ -11,7 +11,7 @@ * None * * Example: - * [bob, "weapon"] call ace_trenches_fnc_handlePlayerInverntoryChanged + * [bob, "weapon"] call ace_trenches_fnc_handlePlayerInventoryChanged * * Public: No */ @@ -19,7 +19,7 @@ params ["_unit"]; if (_unit getVariable [QGVAR(isPlacing), false]) then { - if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) then { + if !(_unit call FUNC(hasEntrenchingTool)) then { [_unit] call FUNC(placeCancel); }; }; diff --git a/addons/trenches/functions/fnc_handleScrollWheel.sqf b/addons/trenches/functions/fnc_handleScrollWheel.sqf index 242b79f1f0..29a35b3674 100644 --- a/addons/trenches/functions/fnc_handleScrollWheel.sqf +++ b/addons/trenches/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg * Handles sandbag rotation @@ -10,7 +10,7 @@ * handled * * Example: - * [1.2] call ace_sandbag_fnc_handleScrollWheel + * [1.2] call ace_trenches_fnc_handleScrollWheel * * Public: No */ diff --git a/addons/trenches/functions/fnc_handleUnconscious.sqf b/addons/trenches/functions/fnc_handleUnconscious.sqf index 6f600cecdf..ba808625ce 100644 --- a/addons/trenches/functions/fnc_handleUnconscious.sqf +++ b/addons/trenches/functions/fnc_handleUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle unconsciousness. diff --git a/addons/trenches/functions/fnc_hasEntrenchingTool.sqf b/addons/trenches/functions/fnc_hasEntrenchingTool.sqf new file mode 100644 index 0000000000..5a1127d007 --- /dev/null +++ b/addons/trenches/functions/fnc_hasEntrenchingTool.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Checks if unit has entrenching tool. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Has entrenching tool + * + * Example: + * [bob] call ace_trenches_fnc_hasEntrenchingTool + * + * Public: Yes +*/ + +params [ + ["_unit", objNull, [objNull]] +]; + +private _uniqueItems = _unit call EFUNC(common,uniqueItems); +_uniqueItems append weapons _unit; +_uniqueItems pushBack backpack _unit; + +GVAR(entrenchingTools) findIf {_x in _uniqueItems} != -1 // return diff --git a/addons/trenches/functions/fnc_placeCancel.sqf b/addons/trenches/functions/fnc_placeCancel.sqf index 36bf5c8023..a06ecff459 100644 --- a/addons/trenches/functions/fnc_placeCancel.sqf +++ b/addons/trenches/functions/fnc_placeCancel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Cancels trench dig @@ -11,7 +11,7 @@ * None * * Example: - * [ACE_player] call ace_sandbag_fnc_placeCancel + * [ACE_player] call ace_trenches_fnc_placeCancel * * Public: No */ diff --git a/addons/trenches/functions/fnc_placeConfirm.sqf b/addons/trenches/functions/fnc_placeConfirm.sqf index 25d675d09b..03d4791e02 100644 --- a/addons/trenches/functions/fnc_placeConfirm.sqf +++ b/addons/trenches/functions/fnc_placeConfirm.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support and esteldunedain * Confirms trench dig @@ -38,11 +38,14 @@ if (isNull GVAR(trench)) exitWith {}; deleteVehicle GVAR(trench); private _trench = createVehicle [GVAR(trenchClass), [0, 0, 0], [], 0, "NONE"]; +_trench setVariable [QGVAR(progress), 0, true]; GVAR(trenchPlacementData) params ["_dx", "_dy", "_offset"]; private _basePos = GVAR(trenchPos); private _angle = (GVAR(digDirection) + getDir _unit); +[QGVAR(placed), [_unit, _trench]] call CBA_fnc_globalEvent; + // _v1 forward from the player, _v2 to the right, _v3 points away from the ground private _v3 = surfaceNormal _basePos; private _v2 = [sin _angle, +cos _angle, 0] vectorCrossProduct _v3; diff --git a/addons/trenches/functions/fnc_placeTrench.sqf b/addons/trenches/functions/fnc_placeTrench.sqf index 0f52786561..f49aef4a38 100644 --- a/addons/trenches/functions/fnc_placeTrench.sqf +++ b/addons/trenches/functions/fnc_placeTrench.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support, esteldunedain * Starts the place process for trench. diff --git a/addons/trenches/functions/fnc_removeTrench.sqf b/addons/trenches/functions/fnc_removeTrench.sqf index 3a549eb16f..0e9870eb8b 100644 --- a/addons/trenches/functions/fnc_removeTrench.sqf +++ b/addons/trenches/functions/fnc_removeTrench.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support and esteldunedain * Removes trench @@ -19,15 +19,18 @@ params ["_trench", "_unit"]; TRACE_2("removeTrench",_trench,_unit); -private _actualProgress = _trench getVariable [QGVAR(progress), 0]; +private _actualProgress = _trench getVariable [QGVAR(progress), 1]; if(_actualProgress == 0) exitWith {}; // Mark trench as being worked on _trench setVariable [QGVAR(digging), true, true]; -private _removeTime = getNumber (configFile >> "CfgVehicles" >> (typeof _trench) >> QGVAR(removalDuration)); +private _removeTime = missionNamespace getVariable [getText (configOf _trench >> QGVAR(removalDuration)), 12]; private _removeTimeLeft = _removeTime * _actualProgress; +if (isNil {_trench getVariable QGVAR(placeData)}) then { + _trench setVariable [QGVAR(placeData), [getPosASL _trench, [vectorDir _trench, vectorUp _trench]], true]; +}; private _placeData = _trench getVariable [QGVAR(placeData), [[], []]]; _placeData params ["_basePos", "_vecDirAndUp"]; @@ -61,7 +64,11 @@ private _fnc_onFailure = { // Reset animation [_unit, "", 1] call EFUNC(common,doAnimation); }; -[(_removeTimeLeft + 0.5), [_unit, _trench], _fnc_onFinish, _fnc_onFailure, localize LSTRING(RemovingTrench)] call EFUNC(common,progressBar); +private _fnc_condition = { + (_this select 0) params ["_unit"]; + _unit call FUNC(hasEntrenchingTool) +}; +[(_removeTimeLeft + 0.5), [_unit, _trench], _fnc_onFinish, _fnc_onFailure, localize LSTRING(RemovingTrench), _fnc_condition] call EFUNC(common,progressBar); private _progressLeft = ((1 - _actualProgress) * 10) + 1; diff --git a/addons/trenches/functions/fnc_setTrenchPlacement.sqf b/addons/trenches/functions/fnc_setTrenchPlacement.sqf index c314914efe..d222de1326 100644 --- a/addons/trenches/functions/fnc_setTrenchPlacement.sqf +++ b/addons/trenches/functions/fnc_setTrenchPlacement.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support and esteldunedain * Sets trench placement diff --git a/addons/trenches/functions/script_component.hpp b/addons/trenches/functions/script_component.hpp deleted file mode 100644 index 3747e01219..0000000000 --- a/addons/trenches/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\trenches\script_component.hpp" \ No newline at end of file diff --git a/addons/trenches/initSettings.inc.sqf b/addons/trenches/initSettings.inc.sqf new file mode 100644 index 0000000000..13e373d25d --- /dev/null +++ b/addons/trenches/initSettings.inc.sqf @@ -0,0 +1,36 @@ +// Trenches dig/remove durations +[ + QGVAR(smallEnvelopeDigDuration), + "TIME", + [LSTRING(SmallEnvelopeDigDuration_DisplayName), LSTRING(SmallEnvelopeDigDuration_Description)], + LSTRING(Category), + [5, 600, 20], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(smallEnvelopeRemoveDuration), + "TIME", + [LSTRING(SmallEnvelopeRemoveDuration_DisplayName), LSTRING(SmallEnvelopeRemoveDuration_Description)], + LSTRING(Category), + [5, 600, 12], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(bigEnvelopeDigDuration), + "TIME", + [LSTRING(BigEnvelopeDigDuration_DisplayName), LSTRING(BigEnvelopeDigDuration_Description)], + LSTRING(Category), + [5, 600, 25], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(bigEnvelopeRemoveDuration), + "TIME", + [LSTRING(BigEnvelopeRemoveDuration_DisplayName), LSTRING(BigEnvelopeRemoveDuration_Description)], + LSTRING(Category), + [5, 600, 15], + true +] call CBA_fnc_addSetting; diff --git a/addons/trenches/stringtable.xml b/addons/trenches/stringtable.xml index 9e0c1364da..4b47ee6a14 100644 --- a/addons/trenches/stringtable.xml +++ b/addons/trenches/stringtable.xml @@ -1,57 +1,61 @@ - + Entrenching Tool Klappspaten Saperka Pala da Trincea Pala para trincheras - Outil de tranchée + Pelle tactique Polní lopatka Ferramenta de trincheira Саперная лопата - シャベル + 塹壕ツール 야전삽 战备锹 戰備鍬 + Kürek Entrenching Tool - Saperka, używana do budowy wnęk - Mit dem Klappspaten können Erdwälle oder Gräben ausgehoben werden. - Pala da Trincea + Saperka, używana do budowy okopów + Mit dem Klappspaten können Erdwälle oder Gräben ausgehoben werden. + Usata per costruire barriere o scavare trincee. Pala para trincheras - Outil de tranchée + Outil permettant de creuser des tranchées. Polní lopatky se používají k zákopovým a jiným pracem. Ferramenta de trincheira Саперная лопата - シャベル - 야전용 삽. 군인들의 영원한 친구 + 塹壕ツール + 야전삽 战备锹 戰備鍬 + Kürek Envelope - Small Rund - Klein - Wnęka - mała - Fascia - Piccola + Okop - mały + Trincea - Piccola Trinchera pequeña - Envelope - petite + Tranchée individuelle Trincheira - Pequena Окоп - Малый 塹壕 - 小型 참호 - 소형 - 掩体 - 小 + 掩体—小 掩體 - 小 + Obálka - Malá + Zarf - Küçük Small Personal Trench Kleiner Schützengraben - Mała jednoosobowa wnęka + Mały jednoosobowy okop Piccola Trincea Personale Trinchera personal pequeña - Petite tranchée personelle + Petite tranchée personnelle Malý zákop pro jednoho Trincheira pessoal pequena Малый персональный окоп @@ -59,11 +63,12 @@ 소형 개인참호 小型个人掩体 小型個人掩體 + Küçük Kişisel Siper Dig Small Trench Grabe kleinen Schützengraben - Kop małą wnękę + Kop mały okop Scava Trincea Piccola Cavar trinchera pequeña Creuser une petite tranchée @@ -72,42 +77,46 @@ Вырыть малый окоп 小型塹壕を掘る 소형참호 파기 - 盖小掩体 + 挖掘小掩体 蓋小掩體 + Küçük Siper Envelope - Big Rund - Groß - Wnęka - duża - Fascia - Grande + Okop - duży + Trincea - Grande Trinchera grande - Enveloppe - grande + Grande tranchée Trincheira - Grande Окоп - Большой 塹壕 - 大型 참호 - 대형 - 掩体 - 大 + 掩体—大 掩體 - 大 + Obálka - Velká + Zarf - Büyük Large Personal Trench Großer Schützengraben - Duża jednoosobowa wnęka + Duży jednoosobowy okop Grande Trincea Personale Trinchera personal grande - Grande tranchée personelle + Grande tranchée personnelle Velký zákop pro jednoho Trincheira pessoal grande Большой персональный окоп - 大型の塹壕を掘る + 大型の個人用塹壕 대형 참호 大型个人掩体 大型個人掩體 + Geniş Kişisel Siper Dig Big Trench Grabe großen Schützengraben - Kop dużą wnękę + Kop duży okop Scava Trincea Grande Cavar trinchera grande Creuser une grande tranchée @@ -116,8 +125,9 @@ Вырыть большой окоп 大型の塹壕を掘る 대형참호 파기 - 盖大掩体 + 挖掘大掩体 蓋大掩體 + Büyük Siper Confirm Dig @@ -125,14 +135,15 @@ Potwierdź kopanie Conferma Scavo Confirmar cavado - Confirmer la creusée + Confirmer l'excavation Potvrdit kopání - Confirmar excavação + Confirmar escavação Копать ここに掘る 여기에 파기 确认开工 確認開工 + Kazmayı Onayla Cancel Dig @@ -140,20 +151,21 @@ Anuluj kopanie Annulla Scavo Cancelar cavado - Annuler la creusée + Annuler l'excavation Zrušit kopání - Cancelar excavação + Cancelar escavação Отменить копание 掘るのを中止 취소하기 取消动作 取消動作 + Kazmayı Iptal Et Rotate Drehen Girar - Tourner + Rotation Rotazione Otočit Forgatás @@ -164,35 +176,39 @@ 돌리기 旋转 旋轉 + Yönlendir Digging Trench Grabe Schützengraben - Kopanie wnęki + Kopanie okopu Scavando la Trincea Cavando trinchera - Creuse la tranchée + Excavation de la tranchée Vykopat zákop Cavando trincheira Копание окопа 塹壕を掘っている - 참호 파는중 - 正在盖掩体中 + 참호 파는 중 + 正在挖掘掩体 正在蓋掩體中 + Siper Kazılıyor Continue Digging Trench - Wzów kopanie wnęki + Wzów kopanie okopu Continuar cavando trincheira - Continuer à creuser la tranchée + Poursuivre l'excavation de la tranchée Продолжить копание окопа Pokračovat v kopání 塹壕を掘りつづける Graben fortsetzen 계속해서 참호파기 - Continuando a Scavare la Trincea - 继续盖掩体 + Continua a Scavare la Trincea + 继续挖掘掩体 繼續蓋掩體 + Kazmaya Devam Et + Continuar cavando trinchera Remove Trench @@ -201,26 +217,150 @@ Retirer la tranchée Убрать окоп Odstranit zákop - 塹壕を消す + 塹壕を撤去 Schützengraben entfernen 참호 제거 Rimuovi Trincea 移除掩体 移除掩體 + Siperi Kaldır + Eliminar trinchera + + + Camouflage Trench + Zakamufluj okop + Camoufler la tranchée + 伪装掩体 + 참호 위장시키기 + Камуфлировать окоп + Camuflar trinchera + Camuffa la trincea + 塹壕を偽装 + Graben tarnen Removing Trench - Usuwanie wnęki - Removendo tricnheira - Retirement de la tranchée + Usuwanie okopu + Removendo trincheira + Retrait de la tranchée Убирание окопа Odstraňuji zákop - 塹壕を消しています + 塹壕を撤去しています Entferne Schützengraben - 참호 제거중... + 참호 제거 중 Rimuovendo la Trincea - 移除掩体中 + 正在移除掩体 移除掩體中 + Siper Kaldırılıyor + Eliminando trinchera + + + ACE Trenches + ACE Окопы + ACE Tranchées + ACE 塹壕 + ACETrincheras + ACE Okopy + ACE Gräben + ACE Trincee + ACE 战壕 + ACE 참호 + + + Small Trench Dig Duration + Время копания малого окопа + Petites tranchées - durée d'excavation + 小型塹壕造成の所要時間 + Tiempo de cavar trinchera pequeña + Czas kopania małego okopu + Kleiner Graben - Aushebungsdauer + Trincea piccola - Durata di scavo + 小型战壕挖掘时间 + 소형참호 건설 시간 + + + Time, in seconds, required to dig a small trench. + Время в секундах, необходимое для рытья малого окопа + Définit le temps nécessaire au déploiement des petites tranchées (en secondes). + 小型塹壕の造成が完了するまで掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para cavar una trinchera pequeña. + Czas, w sekundach wymagany do wykopania małego okopu + Zeit in Sekunden, um einen kleinen Graben auszuheben. + Tempo in secondi per scavare una trincea piccola. + 挖一条小型战壕所需的时间(秒)。 + 소형 참호를 팔 때 필요한 시간을 설정합니다. (초 단위) + + + Small Trench Remove Duration + Время удаления малого окопа + Petites tranchées - durée de retrait + 小型塹壕撤去の所要時間 + Tiempo de eliminar trinchera pequeña + Czas usuwania małego okopu + Kleiner Graben - Aufschüttdauer + Trincea piccola - Durata di rimozione + 小型战壕回填时间 + 소형참호 제거 시간 + + + Time, in seconds, required to remove a small trench. + Время в секундах, необходимое для удаления малого окопа + Définit le temps nécessaire pour le retrait des petites tranchées (en secondes). + 小型塹壕の撤去が完了するまで掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para eliminar una trinchera pequeña. + Czas, w sekundach wymagany do usunięcia małego okopu + Zeit in Sekunden, um einen kleinen Graben aufzuschütten. + Tempo in secondi per rimuovere una trincea piccola. + 回填一条小型战壕所需的时间(秒)。 + 소형 참호를 제거할때 필요한 시간을 설정합니다. (초 단위) + + + Big Trench Dig Duration + Время рытья большого окопа + Grandes tranchées - durée d'excavation + 大型塹壕造成の所要時間 + Tiempo de cavar trinchera grande + Czas kopania dużego okopu + Große Graben - Aushebungsdauer + Trincea grande - Durata di scavo + 大型战壕挖掘时间 + 대형참호 건설 시간 + + + Time, in seconds, required to dig a big trench. + Время в секундах, необходимое для рытья большого окопа + Définit le temps nécessaire au déploiement des grandes tranchées (en secondes). + 大型塹壕の造成が完了するまで掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para cavar una trinchera grande + Czas, w sekundach wymagany do wykopania dużego okopu + Zeit in Sekunden, um einen großen Graben auszuheben. + Tempo in secondi per scavare una trincea grande. + 挖一条大型战壕所需的时间(秒)。 + 대형 참호를 팔때 필요한 시간을 설정합니다. (초 단위) + + + Big Trench Remove Duration + Время удаления большого окопа + Grandes tranchées - durée de retrait + 大型塹壕撤去の所要時間 + Tiempo de eliminar trinchera grande + Czas usuwania dużego okopu + Kleiner Graben - Aufschüttdauer + Trincea grande - Durata di rimozione + 大型战壕回填时间 + 대형참호 제거 시간 + + + Time, in seconds, required to remove a big trench. + Время в секундах, необходимое для удаления большого окопа + Définit le temps nécessaire pour le retrait des grandes tranchées (en secondes). + 大型塹壕の撤去が完了するまで掛かる時間。 (秒単位) + Tiempo, en segundos, requerido para eliminar una trinchera grande + Czas, w sekundach wymagany do usunięcia dużego okopu + Zeit in Sekunden, um einen großen Graben aufzuschütten. + Tempo in secondi per rimuovere una trincea grande. + 回填一条大型战壕所需的时间(秒)。 + 대형 참호를 제거할때 필요한 시간을 설정합니다. (초 단위) diff --git a/addons/tripod/CfgEventHandlers.hpp b/addons/tripod/CfgEventHandlers.hpp index 3a79000a3c..f7a5fa3747 100644 --- a/addons/tripod/CfgEventHandlers.hpp +++ b/addons/tripod/CfgEventHandlers.hpp @@ -1,19 +1,19 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/tripod/CfgVehicles.hpp b/addons/tripod/CfgVehicles.hpp index 31888ab5dd..3e07574cb7 100644 --- a/addons/tripod/CfgVehicles.hpp +++ b/addons/tripod/CfgVehicles.hpp @@ -86,7 +86,7 @@ class CfgVehicles { distance = 5; condition = "(true)"; //wait a frame to handle "Do When releasing action menu key" option: - statement = QUOTE([ARR_2({_this call FUNC(adjust)}, [ARR_2(_player,_target)])] call CBA_fnc_execNextFrame); + statement = QUOTE([ARR_2({_this call FUNC(adjust)},[ARR_2(_player,_target)])] call CBA_fnc_execNextFrame); showDisabled = 0; exceptions[] = {}; icon = QPATHTOF(UI\w_sniper_tripod_ca.paa); diff --git a/addons/tripod/CfgWeapons.hpp b/addons/tripod/CfgWeapons.hpp index 4e609f4f3d..27c6ea8525 100644 --- a/addons/tripod/CfgWeapons.hpp +++ b/addons/tripod/CfgWeapons.hpp @@ -9,6 +9,7 @@ class CfgWeapons { descriptionShort = ""; model = QPATHTOF(data\w_sniper_tripod.p3d); picture = QPATHTOF(UI\w_sniper_tripod_ca.paa); + ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 40; diff --git a/addons/tripod/README.md b/addons/tripod/README.md index beb6791b6d..a0483c863e 100644 --- a/addons/tripod/README.md +++ b/addons/tripod/README.md @@ -2,10 +2,3 @@ ace_tripod =============== Adds a packable tripod. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/tripod/XEH_postInit.sqf b/addons/tripod/XEH_postInit.sqf index 9fbfaa6c8d..febd71390b 100644 --- a/addons/tripod/XEH_postInit.sqf +++ b/addons/tripod/XEH_postInit.sqf @@ -10,10 +10,10 @@ GVAR(height) = 0.5; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel adjusting on player change. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle falling unconscious -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; // @todo captivity? diff --git a/addons/tripod/functions/fnc_adjust.sqf b/addons/tripod/functions/fnc_adjust.sqf index 42af65be74..b7cdc842e9 100644 --- a/addons/tripod/functions/fnc_adjust.sqf +++ b/addons/tripod/functions/fnc_adjust.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Adjust tripod height @@ -30,17 +30,17 @@ GVAR(adjustPFH) = [{ [_unit, "DefaultAction", _unit getVariable [QGVAR(Adjust), -1]] call EFUNC(common,removeActionEventHandler); [_this select 1] call CBA_fnc_removePerFrameHandler; + GVAR(adjustPFH) = -1; }; { _tripod animate [_x, 1 - GVAR(height)]; - } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; - + } forEach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; }, 0, [_unit, _tripod]] call CBA_fnc_addPerFrameHandler; [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); // add mouse button action and hint -[localize "STR_ACE_Tripod_Done", "", localize "STR_ACE_Tripod_ScrollAction"] call EFUNC(interaction,showMouseHint); +[LLSTRING(Done), "", LLSTRING(ScrollAction)] call EFUNC(interaction,showMouseHint); _unit setVariable [QGVAR(Adjust), [ _unit, "DefaultAction", diff --git a/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf b/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf index 0103c0a590..abb9efe304 100644 --- a/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. diff --git a/addons/tripod/functions/fnc_handleKilled.sqf b/addons/tripod/functions/fnc_handleKilled.sqf index 1ce7ce5e0b..01fb5ddd67 100644 --- a/addons/tripod/functions/fnc_handleKilled.sqf +++ b/addons/tripod/functions/fnc_handleKilled.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle death. diff --git a/addons/tripod/functions/fnc_handlePlayerChanged.sqf b/addons/tripod/functions/fnc_handlePlayerChanged.sqf index 506699c293..0d01a138af 100644 --- a/addons/tripod/functions/fnc_handlePlayerChanged.sqf +++ b/addons/tripod/functions/fnc_handlePlayerChanged.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle player changes. diff --git a/addons/tripod/functions/fnc_handleScrollWheel.sqf b/addons/tripod/functions/fnc_handleScrollWheel.sqf index d1cc67272c..67b4e00946 100644 --- a/addons/tripod/functions/fnc_handleScrollWheel.sqf +++ b/addons/tripod/functions/fnc_handleScrollWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg * Handles sandbag rotation diff --git a/addons/tripod/functions/fnc_handleUnconscious.sqf b/addons/tripod/functions/fnc_handleUnconscious.sqf index 632be51e0d..96ed5bdce0 100644 --- a/addons/tripod/functions/fnc_handleUnconscious.sqf +++ b/addons/tripod/functions/fnc_handleUnconscious.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handle unconsciousness. diff --git a/addons/tripod/functions/fnc_pickup.sqf b/addons/tripod/functions/fnc_pickup.sqf index 931efaddfa..0ff72a2b98 100644 --- a/addons/tripod/functions/fnc_pickup.sqf +++ b/addons/tripod/functions/fnc_pickup.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Pick up tripod diff --git a/addons/tripod/functions/fnc_place.sqf b/addons/tripod/functions/fnc_place.sqf index c903c0148d..0109990ded 100644 --- a/addons/tripod/functions/fnc_place.sqf +++ b/addons/tripod/functions/fnc_place.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Rocko, Ruthberg * Place down tripod @@ -34,7 +34,7 @@ if (stance _unit == "STAND") then { { _tripod animate [_x, 0.5]; - } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; + } forEach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; [{ (_this select 0) params ["_tripod", "_direction", "_position"]; diff --git a/addons/tripod/functions/script_component.hpp b/addons/tripod/functions/script_component.hpp deleted file mode 100644 index 4fa165afc7..0000000000 --- a/addons/tripod/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\tripod\script_component.hpp" \ No newline at end of file diff --git a/addons/tripod/stringtable.xml b/addons/tripod/stringtable.xml index daea7e95fd..8b1c1f6eb8 100644 --- a/addons/tripod/stringtable.xml +++ b/addons/tripod/stringtable.xml @@ -1,6 +1,6 @@ - + SSWT Kit Scharfschützendreibein @@ -9,13 +9,14 @@ Equipo SSWT Kit SSWT SSWT souprava - SSWT Kit + Kit SSWT SSWT Készlet Kit SSWT SSWT キット SSWT 키트 狙击手专用三脚架 狙擊手專用三腳架 + SSWT Kiti Place SSWT Kit @@ -25,13 +26,14 @@ Colocar equipo SSWT Placer le kit SSWT Rozlož souprava SSWT - Place SSWT Kit + Piazza Kit SSWT SSWT készlet elhelyezése Colocar kit SSWT SSWT キットを置く SSWT 키트 배치 放置狙击手专用三脚架 放置狙擊手專用三腳架 + Yerleştir SSWT Kit Pick up SSWT Kit @@ -48,6 +50,7 @@ SSWT 키트 줍기 捡起狙击手专用三脚架 撿起狙擊手專用三腳架 + Al SSWT Kit Adjust SSWT Kit @@ -59,11 +62,12 @@ Régler le kit SSWT SSWT készlet állítása Выровнять снайперский штатив - Aggiusta Kit SSWT + Regola Kit SSWT SSWT キットを調節 SSWT 키트 조절 调整狙击手专用三脚架 調整狙擊手專用三腳架 + Ayarla SSWT Kit Done @@ -80,6 +84,7 @@ 완료 完成 完成 + Bitti adjust @@ -88,7 +93,7 @@ regulace anpassen ajuste - régler + Régler szabályzás подстройка regola @@ -96,6 +101,7 @@ 조절 调整 調整 + Ayarlamak diff --git a/addons/ui/ACE_Settings.hpp b/addons/ui/ACE_Settings.hpp index c02d5be2b6..5e747baee9 100644 --- a/addons/ui/ACE_Settings.hpp +++ b/addons/ui/ACE_Settings.hpp @@ -1,285 +1,116 @@ class ACE_Settings { class GVAR(allowSelectiveUI) { - category = CSTRING(Category); - displayName = CSTRING(AllowSelectiveUI); - description = CSTRING(AllowSelectiveUI_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; // BASIC class GVAR(soldierVehicleWeaponInfo) { - category = CSTRING(Category); - displayName = CSTRING(SoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleRadar) { - category = CSTRING(Category); - displayName = CSTRING(VehicleRadar); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleCompass) { - category = CSTRING(Category); - displayName = CSTRING(VehicleCompass); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(commandMenu) { - category = CSTRING(Category); - displayName = CSTRING(CommandMenu); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(groupBar) { - category = CSTRING(Category); - displayName = CSTRING(GroupBar); - typeName = "BOOL"; - value = 0; - isClientSettable = 1; + movedToSQF = 1; }; // ADVANCED // Soldier class GVAR(weaponName) { - category = CSTRING(Category); - displayName = CSTRING(WeaponName); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(weaponNameBackground) { - category = CSTRING(Category); - displayName = CSTRING(WeaponNameBackground); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(firingMode) { - category = CSTRING(Category); - displayName = CSTRING(FiringMode); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(ammoType) { - category = CSTRING(Category); - displayName = CSTRING(AmmoType); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(ammoCount) { - category = CSTRING(Category); - displayName = CSTRING(AmmoCount); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 0; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(magCount) { - category = CSTRING(Category); - displayName = CSTRING(MagCount); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(throwableName) { - category = CSTRING(Category); - displayName = CSTRING(throwableName); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(throwableCount) { - category = CSTRING(Category); - displayName = CSTRING(throwableCount); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(zeroing) { - category = CSTRING(Category); - displayName = CSTRING(Zeroing); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(weaponLowerInfoBackground) { - category = CSTRING(Category); - displayName = CSTRING(WeaponLowerInfoBackground); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(stance) { - category = CSTRING(Category); - displayName = CSTRING(Stance); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(staminaBar) { - category = CSTRING(Category); - displayName = CSTRING(StaminaBar); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; // Gunner class GVAR(gunnerWeaponName) { - category = CSTRING(Category); - displayName = CSTRING(GunnerWeaponName); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerWeaponNameBackground) { - category = CSTRING(Category); - displayName = CSTRING(GunnerWeaponNameBackground); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerFiringMode) { - category = CSTRING(Category); - displayName = CSTRING(GunnerFiringMode); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerAmmoType) { - category = CSTRING(Category); - displayName = CSTRING(GunnerAmmoType); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerAmmoCount) { - category = CSTRING(Category); - displayName = CSTRING(GunnerAmmoCount); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerMagCount) { - category = CSTRING(Category); - displayName = CSTRING(GunnerMagCount); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerLaunchableName) { - category = CSTRING(Category); - displayName = CSTRING(gunnerLaunchableName); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerLaunchableCount) { - category = CSTRING(Category); - displayName = CSTRING(gunnerLaunchableCount); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerZeroing) { - category = CSTRING(Category); - displayName = CSTRING(GunnerZeroing); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(gunnerWeaponLowerInfoBackground) { - category = CSTRING(Category); - displayName = CSTRING(GunnerWeaponLowerInfoBackground); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; // Vehicle class GVAR(vehicleName) { - category = CSTRING(Category); - displayName = CSTRING(VehicleName); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleNameBackground) { - category = CSTRING(Category); - displayName = CSTRING(VehicleNameBackground); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleFuelBar) { - category = CSTRING(Category); - displayName = CSTRING(VehicleFuelBar); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleSpeed) { - category = CSTRING(Category); - displayName = CSTRING(VehicleSpeed); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleAltitude) { - category = CSTRING(Category); - displayName = CSTRING(VehicleAltitude); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleDamage) { - category = CSTRING(Category); - displayName = CSTRING(VehicleDamage); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(vehicleInfoBackground) { - category = CSTRING(Category); - displayName = CSTRING(VehicleInfoBackground); - description = CSTRING(RequiresSoldierVehicleWeaponInfo); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; }; diff --git a/addons/ui/ACE_UI.hpp b/addons/ui/ACE_UI.hpp index 7bf395da57..4fbf7038ef 100644 --- a/addons/ui/ACE_UI.hpp +++ b/addons/ui/ACE_UI.hpp @@ -1,174 +1,182 @@ class ACE_UI { + class devWatermark { + idd = IDD_MISSION; + elements[] = {11400}; + location = ANYWHERE; + class conditions { + isDevelopmentBranch = QUOTE(productVersion select 4 == 'Development'); + }; + }; class weaponName { - idd = 300; - elements[] = {118}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON}; location = GROUND_ONLY; class conditions {}; }; class weaponNameBackground { - idd = 300; + idd = IDD_UNITINFO; elements[] = {1001, 1008}; location = GROUND_ONLY; class conditions {}; }; class firingMode { - idd = 300; - elements[] = {187, 1203}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON_MODE_TEXTURE, 1203}; location = GROUND_ONLY; class conditions {}; }; class ammoType { - idd = 300; - elements[] = {155}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON_AMMO}; location = GROUND_ONLY; class conditions {}; }; class ammoCount { - idd = 300; - elements[] = {184}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_AMMOCOUNT}; location = GROUND_ONLY; class conditions {}; }; class magCount { - idd = 300; - elements[] = {185}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_MAGCOUNT}; location = GROUND_ONLY; class conditions {}; }; class throwableName { - idd = 300; + idd = IDD_UNITINFO; elements[] = {152}; location = GROUND_ONLY; class conditions {}; }; class throwableCount { - idd = 300; + idd = IDD_UNITINFO; elements[] = {151}; location = GROUND_ONLY; class conditions {}; }; class zeroing { - idd = 300; - elements[] = {168}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON_ELEVATION}; location = GROUND_ONLY; class conditions {}; }; class weaponLowerInfoBackground { - idd = 300; + idd = IDD_UNITINFO; elements[] = {1202}; location = GROUND_ONLY; class conditions {}; }; class staminaBar { - idd = 305; - elements[] = {193}; + idd = IDD_STAMINA_BAR; + elements[] = {IDC_IGUI_STAMINA_BAR}; location = GROUND_ONLY; class conditions {}; }; class stance { - idd = 303; - elements[] = {188, 1201}; + idd = IDD_STANCEINFO; + elements[] = {IDC_IGUI_STANCE_INDICATOR, 1201}; location = GROUND_ONLY; class conditions {}; }; class gunnerWeaponName { - idd = 300; - elements[] = {118}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerWeaponNameBackground { - idd = 300; + idd = IDD_UNITINFO; elements[] = {1001, 1008}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerFiringMode { - idd = 300; - elements[] = {187, 1203}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON_MODE_TEXTURE, 1203}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerAmmoType { - idd = 300; - elements[] = {155}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON_AMMO}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerAmmoCount { - idd = 300; - elements[] = {184}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_AMMOCOUNT}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerMagCount { - idd = 300; - elements[] = {185}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_MAGCOUNT}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerLaunchableName { - idd = 300; + idd = IDD_UNITINFO; elements[] = {152}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerLaunchableCount { - idd = 300; + idd = IDD_UNITINFO; elements[] = {151}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerZeroing { - idd = 300; - elements[] = {168}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_WEAPON_ELEVATION}; location = VEHICLE_ONLY; class conditions {}; }; class gunnerWeaponLowerInfoBackground { - idd = 300; + idd = IDD_UNITINFO; elements[] = {1202}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleName { - idd = 300; - elements[] = {120}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_VEHICLE}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleNameBackground { - idd = 300; + idd = IDD_UNITINFO; elements[] = {1000, 1013}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleFuelBar { - idd = 300; - elements[] = {113, 1202}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_VALUE_FUEL, 1202}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleSpeed { - idd = 300; - elements[] = {121, 1004, 1006}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_SPEED, 1004, 1006}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleAltitude { - idd = 300; - elements[] = {122, 1005, 1014}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_ALT, 1005, 1014}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleDamage { - idd = 300; - elements[] = {111}; + idd = IDD_UNITINFO; + elements[] = {IDC_IGUI_HITZONES}; location = VEHICLE_ONLY; class conditions {}; }; class vehicleInfoBackground { - idd = 300; + idd = IDD_UNITINFO; elements[] = {1200}; location = VEHICLE_ONLY; class conditions {}; diff --git a/addons/ui/CfgEventHandlers.hpp b/addons/ui/CfgEventHandlers.hpp index 89c91283ed..534a8f81f6 100644 --- a/addons/ui/CfgEventHandlers.hpp +++ b/addons/ui/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); }; }; diff --git a/addons/ui/CfgInGameUI.hpp b/addons/ui/CfgInGameUI.hpp new file mode 100644 index 0000000000..8f39984b03 --- /dev/null +++ b/addons/ui/CfgInGameUI.hpp @@ -0,0 +1,5 @@ +class CfgInGameUI { + class DefaultAction { + size = QUOTE(profileNamespace getVariable [ARR_2('GVAR(hideDefaultActionIcon)',(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8))]); + }; +}; diff --git a/addons/ui/README.md b/addons/ui/README.md index c55ffbc5c7..8e0c610778 100644 --- a/addons/ui/README.md +++ b/addons/ui/README.md @@ -2,11 +2,3 @@ ace_ui ======= Removes vignette, changes the chat contrast on the map to allow easier reading and provides settings to hide or show different UI elements. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [VKing](https://github.com/VKing6) -- [Jonpas](https://github.com/jonpas) diff --git a/addons/ui/RscInGameUI.hpp b/addons/ui/RscInGameUI.hpp new file mode 100644 index 0000000000..404eaba7f7 --- /dev/null +++ b/addons/ui/RscInGameUI.hpp @@ -0,0 +1,22 @@ +#define SPEED_INDICATOR_W (IGUI_GRID_STANCE_WAbs / 2) +#define SPEED_INDICATOR_H (IGUI_GRID_STANCE_HAbs / 3.5) +#define SPEED_INDICATOR_Y_OFFSET (IGUI_GRID_STANCE_HAbs / 4.25) + +#undef IGUI_GRID_STANCE_X +#undef IGUI_GRID_STANCE_Y +#define ace_IGUI_GRID_STANCE_X (profilenamespace getvariable ['IGUI_GRID_STANCE_X',IGUI_GRID_STANCE_XDef]) +#define ace_IGUI_GRID_STANCE_Y (profilenamespace getvariable ['IGUI_GRID_STANCE_Y',IGUI_GRID_STANCE_YDef]) + +class RscPictureKeepAspect; +class RscInGameUI { + class RscStanceInfo { + controls[] += {QGVAR(speedIndicator)}; + class GVAR(speedIndicator): RscPictureKeepAspect { + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(speedIndicator),_this select 0)]); + x = QUOTE(ace_IGUI_GRID_STANCE_X + IGUI_GRID_STANCE_WAbs / 2 - SPEED_INDICATOR_W / 2); + y = QUOTE(ace_IGUI_GRID_STANCE_Y + IGUI_GRID_STANCE_HAbs - SPEED_INDICATOR_Y_OFFSET); + w = QUOTE(SPEED_INDICATOR_W); + h = QUOTE(SPEED_INDICATOR_H); + }; + }; +}; diff --git a/addons/ui/UI/speed_indicator/1_ca.paa b/addons/ui/UI/speed_indicator/1_ca.paa new file mode 100644 index 0000000000..bcafc6d09e Binary files /dev/null and b/addons/ui/UI/speed_indicator/1_ca.paa differ diff --git a/addons/ui/UI/speed_indicator/2_ca.paa b/addons/ui/UI/speed_indicator/2_ca.paa new file mode 100644 index 0000000000..6ba5b7f215 Binary files /dev/null and b/addons/ui/UI/speed_indicator/2_ca.paa differ diff --git a/addons/ui/UI/speed_indicator/3_ca.paa b/addons/ui/UI/speed_indicator/3_ca.paa new file mode 100644 index 0000000000..3e190e8858 Binary files /dev/null and b/addons/ui/UI/speed_indicator/3_ca.paa differ diff --git a/addons/ui/UI/speed_indicator/4_ca.paa b/addons/ui/UI/speed_indicator/4_ca.paa new file mode 100644 index 0000000000..fc53c16bb5 Binary files /dev/null and b/addons/ui/UI/speed_indicator/4_ca.paa differ diff --git a/addons/ui/XEH_PREP.hpp b/addons/ui/XEH_PREP.hpp index a927a8ad2d..436e59361c 100644 --- a/addons/ui/XEH_PREP.hpp +++ b/addons/ui/XEH_PREP.hpp @@ -1,5 +1,7 @@ PREP(compileConfigUI); +PREP(handleSpeedIndicator); PREP(moduleInit); +PREP(onAnimChanged); PREP(setAdvancedElement); PREP(setElements); PREP(setElementVisibility); diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index 5cfa322b0d..d9d3fa5717 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -4,14 +4,14 @@ if (!hasInterface) exitWith {}; // Compile and cache config UI -GVAR(configCache) = call CBA_fnc_createNamespace; +GVAR(configCache) = createHashMap; call FUNC(compileConfigUI); // Scripted API namespace -GVAR(elementsSet) = call CBA_fnc_createNamespace; +GVAR(elementsSet) = createHashMap; // Attach all event handlers where UI has to be updated -["ace_settingsInitialized", { +["CBA_settingsInitialized", { // Initial settings [false] call FUNC(setElements); @@ -19,10 +19,9 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; ["ace_infoDisplayChanged", { // Selective UI Advanced // Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified - private _force = [true, false] select (GVAR(allowSelectiveUI)); { - [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, _force] call FUNC(setAdvancedElement); - } forEach (allVariables GVAR(configCache)); + [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, !GVAR(allowSelectiveUI)] call FUNC(setAdvancedElement); + } forEach (keys GVAR(configCache)); // Execute local event for when it's safe to modify UI through this API // infoDisplayChanged can execute multiple times, make sure it only happens once @@ -33,17 +32,19 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; }] call CBA_fnc_addEventHandler; // On changing settings - ["ace_settingChanged", { - params ["_name"]; + ["CBA_SettingChanged", { + params ["_name", "_value"]; + if (_name select [0, 7] != "ace_ui_") exitWith {}; if (_name in ELEMENTS_BASIC) then { [true] call FUNC(setElements); } else { - private _nameNoPrefix = toLower (_name select [7]); - private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix; - if (!isNil "_cachedElement") then { - [_nameNoPrefix, missionNamespace getVariable _name, true] call FUNC(setAdvancedElement); + private _nameNoPrefix = toLowerANSI (_name select [7]); + if (_nameNoPrefix in GVAR(configCache)) then { + [_nameNoPrefix, _value, true] call FUNC(setAdvancedElement); }; }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; + +[QUOTE(ADDON), "AnimChanged", LINKFUNC(onAnimChanged), true] call EFUNC(common,addPlayerEH); diff --git a/addons/ui/XEH_preInit.sqf b/addons/ui/XEH_preInit.sqf index b937d5d81c..b85b7329b0 100644 --- a/addons/ui/XEH_preInit.sqf +++ b/addons/ui/XEH_preInit.sqf @@ -6,6 +6,21 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + GVAR(interfaceInitialized) = false; +GVAR(speedIndicatorIconHash) = createHashMapFromArray [ + // Standing/Crouched + [["wlk", false], QPATHTOF(ui\speed_indicator\1_ca.paa)], + [["tac", false], QPATHTOF(ui\speed_indicator\2_ca.paa)], + [["run", false], QPATHTOF(ui\speed_indicator\3_ca.paa)], + [["eva", false], QPATHTOF(ui\speed_indicator\4_ca.paa)], + // Prone + [["wlk", true], QPATHTOF(ui\speed_indicator\1_ca.paa)], + [["run", true], QPATHTOF(ui\speed_indicator\2_ca.paa)], + [["spr", true], QPATHTOF(ui\speed_indicator\3_ca.paa)], + [["eva", true], QPATHTOF(ui\speed_indicator\4_ca.paa)] +]; + ADDON = true; diff --git a/addons/ui/config.cpp b/addons/ui/config.cpp index d480a5f33b..0a04e1fccb 100644 --- a/addons/ui/config.cpp +++ b/addons/ui/config.cpp @@ -8,16 +8,18 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"VKing", "Jonpas"}; + authors[] = {"VKing", "Jonpas", "veteran29"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; #include "CfgEventHandlers.hpp" +#include "CfgInGameUI.hpp" #include "CfgVehicles.hpp" #include "ACE_Settings.hpp" #include "ACE_UI.hpp" #include "RscChat.hpp" +#include "RscInGameUI.hpp" #include "RscVignette.hpp" diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index 0baaa8ca5c..960db9aed4 100644 --- a/addons/ui/functions/fnc_compileConfigUI.sqf +++ b/addons/ui/functions/fnc_compileConfigUI.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Compiles and caches UI from ACE_UI config. @@ -17,7 +17,7 @@ { private _failure = false; - private _class = toLower (configName _x); + private _class = toLowerANSI (configName _x); private _idd = getNumber (_x >> "idd"); @@ -40,6 +40,6 @@ TRACE_1("Caching Condition",_x); } forEach (configProperties [_x >> "conditions"]); - GVAR(configCache) setVariable [_class, [_idd, _elements, _location, _conditions]]; + GVAR(configCache) set [_class, [_idd, _elements, _location, _conditions]]; }; } forEach ("true" configClasses (configFile >> "ACE_UI")); diff --git a/addons/ui/functions/fnc_handleSpeedIndicator.sqf b/addons/ui/functions/fnc_handleSpeedIndicator.sqf new file mode 100644 index 0000000000..5f8c360322 --- /dev/null +++ b/addons/ui/functions/fnc_handleSpeedIndicator.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Handles visual changes of the speed indicator. + * + * Arguments: + * Current animation state + * + * Return Value: + * None + * + * Example: + * ["amovpercmtacslowwrfldf_ver2"] call ace_ui_fnc_handleSpeedIndicator + * + * Public: No + */ + +params ["_animState"]; + +if (!GVAR(enableSpeedIndicator)) exitWith {}; + +private _animSpeed = _animState select [9, 3]; +private _isProne = _animState select [5, 3] isEqualTo "pne"; + +private _icon = GVAR(speedIndicatorIconHash) getOrDefault [[_animSpeed, _isProne], ""]; + +private _speedIndicator = uiNamespace getVariable [QGVAR(speedIndicator), controlNull]; +_speedIndicator ctrlSetText _icon; diff --git a/addons/ui/functions/fnc_moduleInit.sqf b/addons/ui/functions/fnc_moduleInit.sqf index b1295a6c10..82c63d4e00 100644 --- a/addons/ui/functions/fnc_moduleInit.sqf +++ b/addons/ui/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Initializes the UI module. diff --git a/addons/ui/functions/fnc_onAnimChanged.sqf b/addons/ui/functions/fnc_onAnimChanged.sqf new file mode 100644 index 0000000000..d7a647e9ca --- /dev/null +++ b/addons/ui/functions/fnc_onAnimChanged.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: veteran29 + * Handle player unit animation changes. + * + * Arguments: + * 0: Unit + * 1: Current animation + * + * Return Value: + * None + * + * Example: + * [newbob, "amovpercmtacslowwrfldf_ver2"] call ace_ui_fnc_onAnimChanged + * + * Public: No + */ + +(_this select 1) call FUNC(handleSpeedIndicator); diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf index 4e2ececf6c..86a1134802 100644 --- a/addons/ui/functions/fnc_setAdvancedElement.sqf +++ b/addons/ui/functions/fnc_setAdvancedElement.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Sets advanced visible element of the UI using displays and controls. @@ -20,7 +20,9 @@ params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]]]; -private _cachedElement = GVAR(configCache) getVariable _element; +_element = toLowerANSI _element; + +private _cachedElement = GVAR(configCache) get _element; if (isNil "_cachedElement") exitWith {TRACE_1("nil element",_this)}; if (!_force && {!GVAR(allowSelectiveUI)}) exitWith { @@ -33,9 +35,10 @@ _cachedElement params ["_idd", "_elements", "_location", "_conditions"]; // Exit if main vehicle type condition not fitting private _canUseWeaponOrInCargo = ACE_player call CBA_fnc_canUseWeapon || {-1 < vehicle ACE_player getCargoIndex ACE_player}; +private _inUAVCamera = !isNull getConnectedUAVUnit player; // explictly using player if ( - (_canUseWeaponOrInCargo && {_location == VEHICLE_ONLY}) - || {!_canUseWeaponOrInCargo && {_location == GROUND_ONLY}} + (_canUseWeaponOrInCargo && {!_inUAVCamera} && {_location == VEHICLE_ONLY}) + || {(!_canUseWeaponOrInCargo || {_inUAVCamera}) && {_location == GROUND_ONLY}} ) exitWith { TRACE_3("skip location",_this,_canUseWeaponOrInCargo,_location); false @@ -51,11 +54,11 @@ if ( }; _show = false; }; -} count _conditions; +} forEach _conditions; // Get setting from scripted API if (!_force) then { - private _setElement = GVAR(elementsSet) getVariable _element; + private _setElement = GVAR(elementsSet) get _element; if (!isNil "_setElement") then { _setElement params ["_sourceSet", "_showSet"]; if (_showHint) then { @@ -66,7 +69,8 @@ if (!_force) then { }; }; -private _fade = [1, 0] select _show; +private _displays = ((uiNamespace getVariable "IGUI_displays") + [findDisplay IDD_MISSION]) select {_idd == ctrlIDD _x}; +private _fade = parseNumber !_show; // Disable/Enable elements private _success = false; @@ -75,16 +79,16 @@ private _success = false; // Loop through IGUI displays as they can be present several times for some reason { - if (_idd == ctrlIDD _x) then { - TRACE_4("Setting Element Visibility",_element,_fade,_idd,_idc); + _success = true; - (_x displayCtrl _idc) ctrlSetFade _fade; - (_x displayCtrl _idc) ctrlCommit 0; + private _control = _x displayCtrl _idc; + if (ctrlFade _control == _fade) then {continue}; - _success = true; - }; - } count (uiNamespace getVariable "IGUI_displays"); - nil -} count _elements; + TRACE_4("Setting Element Visibility",_element,_fade,_idd,_idc); + + _control ctrlSetFade _fade; + _control ctrlCommit 0; + } forEach _displays; +} forEach _elements; _success diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index f6c4525828..938fb2da7d 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Setter for toggling advanced element visibility. @@ -29,15 +29,14 @@ if (_source == "" || {_element == ""}) exitWith { WARNING("Source or Element may not be empty strings!"); }; -_element = toLower _element; +_element = toLowerANSI _element; // Verify element is bound -private _cachedElement = GVAR(configCache) getVariable _element; -if (isNil "_cachedElement") exitWith { +if !(_element in GVAR(configCache)) exitWith { WARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); }; -private _setElement = GVAR(elementsSet) getVariable _element; +private _setElement = GVAR(elementsSet) get _element; private _return = false; if (isNil "_setElement") then { @@ -45,7 +44,7 @@ if (isNil "_setElement") then { private _success = [_element, _show, false, true] call FUNC(setAdvancedElement); if (_success) then { - GVAR(elementsSet) setVariable [_element, [_source, _show]]; + GVAR(elementsSet) set [_element, [_source, _show]]; _return = true; }; } else { @@ -57,7 +56,7 @@ if (isNil "_setElement") then { }; } else { TRACE_3("Unsetting element",_sourceSet,_element,_show); - GVAR(elementsSet) setVariable [_element, nil]; + GVAR(elementsSet) set [_element, nil]; [_element, _show, false, true] call FUNC(setAdvancedElement); _return = true; diff --git a/addons/ui/functions/fnc_setElements.sqf b/addons/ui/functions/fnc_setElements.sqf index 8e7da0eb3d..1181957c38 100644 --- a/addons/ui/functions/fnc_setElements.sqf +++ b/addons/ui/functions/fnc_setElements.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Sets basic visible elements of the UI using showHUD setter. diff --git a/addons/ui/functions/script_component.hpp b/addons/ui/functions/script_component.hpp deleted file mode 100644 index 656228f742..0000000000 --- a/addons/ui/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\ui\script_component.hpp" diff --git a/addons/ui/initSettings.inc.sqf b/addons/ui/initSettings.inc.sqf new file mode 100644 index 0000000000..dc701b91d5 --- /dev/null +++ b/addons/ui/initSettings.inc.sqf @@ -0,0 +1,318 @@ +private _category = format ["ACE %1", localize LSTRING(Category)]; + +[ + QGVAR(allowSelectiveUI), "CHECKBOX", + [LSTRING(AllowSelectiveUI), LSTRING(AllowSelectiveUI_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(soldierVehicleWeaponInfo), "CHECKBOX", + LSTRING(SoldierVehicleWeaponInfo), + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleRadar), "CHECKBOX", + LSTRING(VehicleRadar), + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleCompass), "CHECKBOX", + LSTRING(VehicleCompass), + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(commandMenu), "CHECKBOX", + LSTRING(CommandMenu), + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(groupBar), "CHECKBOX", + LSTRING(GroupBar), + _category, + false, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponName), "CHECKBOX", + [LSTRING(WeaponName), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponNameBackground), "CHECKBOX", + [LSTRING(WeaponNameBackground), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(firingMode), "CHECKBOX", + [LSTRING(FiringMode), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(ammoType), "CHECKBOX", + [LSTRING(AmmoType), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(ammoCount), "CHECKBOX", + [LSTRING(AmmoCount), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + false, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(magCount), "CHECKBOX", + [LSTRING(MagCount), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(throwableName), "CHECKBOX", + [LSTRING(ThrowableName), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(throwableCount), "CHECKBOX", + [LSTRING(ThrowableCount), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(zeroing), "CHECKBOX", + [LSTRING(Zeroing), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponLowerInfoBackground), "CHECKBOX", + [LSTRING(WeaponLowerInfoBackground), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(stance), "CHECKBOX", + [LSTRING(Stance), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(staminaBar), "CHECKBOX", + [LSTRING(StaminaBar), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerWeaponName), "CHECKBOX", + [LSTRING(GunnerWeaponName), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerWeaponNameBackground), "CHECKBOX", + [LSTRING(GunnerWeaponNameBackground), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerFiringMode), "CHECKBOX", + [LSTRING(GunnerFiringMode), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerAmmoType), "CHECKBOX", + [LSTRING(GunnerAmmoType), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerAmmoCount), "CHECKBOX", + [LSTRING(GunnerAmmoCount), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerMagCount), "CHECKBOX", + [LSTRING(GunnerMagCount), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerLaunchableName), "CHECKBOX", + [LSTRING(GunnerLaunchableName), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerLaunchableCount), "CHECKBOX", + [LSTRING(GunnerLaunchableCount), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerZeroing), "CHECKBOX", + [LSTRING(GunnerZeroing), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(gunnerWeaponLowerInfoBackground), "CHECKBOX", + [LSTRING(GunnerWeaponLowerInfoBackground), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleName), "CHECKBOX", + [LSTRING(VehicleName), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleNameBackground), "CHECKBOX", + [LSTRING(VehicleNameBackground), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleFuelBar), "CHECKBOX", + [LSTRING(VehicleFuelBar), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleSpeed), "CHECKBOX", + [LSTRING(VehicleSpeed), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleAltitude), "CHECKBOX", + [LSTRING(VehicleAltitude), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleDamage), "CHECKBOX", + [LSTRING(VehicleDamage), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleInfoBackground), "CHECKBOX", + [LSTRING(VehicleInfoBackground), LSTRING(RequiresSoldierVehicleWeaponInfo)], + _category, + true, + 0 +] call CBA_fnc_addSetting; + +if (productVersion select 4 == 'Development') then { + [ + QGVAR(devWatermark), + "CHECKBOX", + LSTRING(devWatermark), + _category, + true + ] call CBA_fnc_addSetting; +}; + +[ + QGVAR(enableSpeedIndicator), + "CHECKBOX", + [LSTRING(EnableSpeedIndicator), LSTRING(EnableSpeedIndicator_Description)], + _category, + true, + true, { + if (!_this) then { + private _speedIndicator = uiNamespace getVariable [QGVAR(speedIndicator), controlNull]; + _speedIndicator ctrlSetText ""; + }; + } +] call CBA_fnc_addSetting; + +[ + QGVAR(hideDefaultActionIcon), + "CHECKBOX", + [LSTRING(HideDefaultActionIcon), LSTRING(HideDefaultActionIcon_Description)], + _category, + false, + 2, { + profileNamespace setVariable [QGVAR(hideDefaultActionIcon), [nil, 0] select _this]; + saveProfileNamespace; + }, + true // needs restart +] call CBA_fnc_addSetting; diff --git a/addons/ui/script_component.hpp b/addons/ui/script_component.hpp index 11b0d08715..a9899945c7 100644 --- a/addons/ui/script_component.hpp +++ b/addons/ui/script_component.hpp @@ -16,6 +16,8 @@ #include "\z\ace\addons\main\script_macros.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" +#include "\a3\ui_f\hpp\defineCommonGrids.inc" // Basic Elements #define ELEMENTS_BASIC [QGVAR(soldierVehicleWeaponInfo), QGVAR(vehicleRadar), QGVAR(vehicleCompass), QGVAR(commandMenu), QGVAR(groupBar)] diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 06b253238b..562abe2765 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -5,84 +5,93 @@ User Interface Uživatelské rozhraní Interface do usuário - Interface utilisateur + Interface Utilisateur Интерфейс - ユーザ インタフェイス + ユーザ インタフェース Interfejs użytkownika Benutzeroberfläche 사용자 인터페이스 Interfaccia Utente - 使用者介面 + 用户界面 使用者介面 + Interfaz de usuario + Kullanıcı Arayüzü User Interface Uživatelské rozhraní Interface do usuário - Interface utilisateur + Interface Utilisateur Пользовательский интерфейс - ユーザ インタフェイス + ユーザ インタフェース Interfejs użytkownika Benutzeroberfläche 사용자 인터페이스 Interfaccia Utente - 使用者介面 + 用户界面 使用者介面 + Interfaz de usuario + Kullanıcı Arayüzü This module allows toggling visible user interface parts. Este módulo permite ligar ou desligar partes da interface do usuário - Ce module permet le basculement de parties visibles de l'interface utlisateur + Ce module permet d'activer ou de désactiver certains éléments de l'Interface Utilisateur (IU). Этот модуль позволяет переключать видимость элементов пользовательского интерфейса. - モジュールではユーザ インタフェイスの一部表示を切り替えできます。 + このモジュールではユーザ インタフェースの表示部位の表示状態を切り替えることができます。 Moduł ten pozwala zmienić stan widoczności poszczególnych elementów UI. Dieses Modul erlaubt es, Teile der Benutzeroberfläche (UI) an- oder auszuschalten. - 이 모듈은 사용자 인터페이스의 부분을 토글하는것을 가능케 해줍니다. - Questo modulo consente di commutare parti di interfaccia utente visibili. - 此模块允许你调整使用者介面的任何一个元件 + 이 모듈은 사용자 인터페이스의 부분을 토글하는 것을 가능케 해줍니다. + Questo modulo consente di selezionare quali parti dell'interfaccia utente sono visibili. + 此模块允许你调整用户界面的任何一个控件 此模塊允許你調整使用者介面的任何一個元件 + Tento modul umožňuje přepínání viditelných částí uživatelského rozhraní. + Este módulo permite activar la visibilidad de apartados de la interfaz Allow Selective UI Povolit selektivní UI Permitir IU Selecionável - Permettre l'IU selective - Включить настраиваемый интерфейс - UI 選択性を許可 + Autoriser la personnalisation de l'IU + Вкл. настраиваемый интерфейс + 選択性UIを許可 Zezwól na selektywne UI Erlaube selektives UI 선택적 사용자 인터페이스 허가 Permette l'UI Selettiva - 允许调整使用者介面 + 允许调整用户界面 允許調整使用者介面 + Permitir IU selectiva Allow client to modify their UI. Povolit klientovi měnit jeho UI Permite o cliente modificar sua IU. - Permet aux clients de modifier leur IU + Permet aux clients de modifier leur Interface Utilisateur. Позволить клиентам изменять их пользовательский интерфейс. - クライアントがユーザ インタフェイスを編集できるようにします。 + クライアントがユーザ インタフェースを編集できるようにします。 Zezwól klientowi na modyfikację UI. Erlaube Clients, ihr UI zu modifizieren. - 클라이언트가 선택적 사용자 인터페이스 사용하는것을 허가합니다 + 클라이언트가 자신의 사용자 인터페이스를 사용하는 것을 허가합니다 Permette al client di modificare la propria UI. - 允许客户端自行调整使用者介面 + 允许客户端自行调整用户界面 允許客戶端自行調整使用者介面 + Permitir al cliente modificar su interfaz. Soldier/Vehicle/Weapon Information Informace o Vojákovi/Vozidlu/Zbrani Informação de Soldado/Veículo/Armamento - Soldat/Véhicule/Arme/Informations - Информация о Солдате/Технике/Оружии + Information soldat/véhicule/arme + Информация о солдате/технике/оружии 兵士/車両/武器の情報 Informacje o żołnierzu/pojeździe/broni Soldat/Fahrzeug/Waffe Information 병사/차량/무기 정보 Informazioni Soldato/Veicolo/Arma - 士兵/载具/武器资讯栏 + 士兵/载具/武器信息栏 士兵/載具/武器資訊欄 + Información de soldado / vehículo / arma Vehicle Radar @@ -90,27 +99,31 @@ Radar de Veículo Radar de véhicule Радар в технике - 車両のレーダ + 車両のレーダー Radar w pojeździe Fahrzeugradar 차량 레이더 - Rada Veicolo + Radar Veicolo 载具雷达 載具雷達 + Radar de vehículos + Araç Radarı Vehicle Compass Kompas vozidla Bússola de Veículo - Compas de véhicule + Boussole de véhicule Компас в технике - 車両のレーダ + 車両のコンパス Kompas w pojeździe Fahrzeugkompass 차량 나침반 Bussola Veicolo - 载具指北针 + 载具指南针 載具指北針 + Brújula del vehículo + Araç Pusulası Command Menu @@ -123,8 +136,10 @@ Kommandomenü 지휘 메뉴 Menù di Comando - 指挥选单 + 指挥菜单 指揮選單 + Menú de Comando + Komut Menüsü Group Bar @@ -132,19 +147,33 @@ Barra de Grupo Barre de groupe Панель командира - 指揮メニュー + グループ バー Pasek grupy Gruppenleiste 그룹 막대 Barra del Gruppo 小队状态栏 小隊狀態欄 + Barra de grupo + Grup Göstergesi + + + Development Build Watermark + Водяной знак Development Build + Marca de agua para compilación de desarrollo + Filigrane version de développement + Znak wodny wersji deweloperskiej + 開発ビルドでの透かしマーク + Wasserzeichen für Entwicklungsversion + Filigrana per versione in fase di sviluppo + 开发建设水印 + 개발용 빌드 워터마크 Weapon Name Název zbraně Nome do Armamento - Nom de l''arme + Nom de l'arme Название оружия 武器名 Nazwa broni @@ -153,20 +182,23 @@ Nome Arma 武器名称 武器名稱 + Nombre del arma + Silah Ismi Weapon Name Background Název zbraně v pozadí Fundo do Nome do Armamento - Arrière-plan du nom de l'arme + Fond pour le nom de l'arme Фон названия оружия - 武器名の背景表示 + 武器名の背景 Tło nazwy broni Waffenname Hintergrund 무기 이름 배경 - Nome Sfondo Arma + Sfondo Nome Arma 武器名称背景 武器名稱背景 + Fondo de nombre de arma Firing Mode @@ -181,6 +213,8 @@ Modalità di Fuoco 射击模式 射擊模式 + Modo de disparo + Ateşleme Modu Ammo Type @@ -195,6 +229,8 @@ Tipo Munizioni 弹药类型 彈藥類型 + Tipo de munición + Mermi Türü Ammo Count @@ -202,13 +238,15 @@ Quantidade de Munição Nombre de munitions Количество боеприпасов - 弾薬数 + 弾数 Ilość amunicji Munitionsanzahl 탄약수 Contatore Munizioni 弹药数量 彈藥數量 + Cantidad de munición + Mermi Sayısı Magazine Count @@ -216,47 +254,53 @@ Quantidade de Carregadores Nombre de chargeurs Количество магазинов - 弾倉装填数 + 弾倉数 Ilość magazynków Magazinanzahl 탄창수 - Contatore Caricatore + Contatore Caricatori 弹匣数量 彈匣數量 + Recuento de cargadores + Şarjör Sayısı Throwable Type Typ granátů apod. Tipo de Arremessável - Type d'objets de lancer + Type d'objet lançable Тип гранаты - 投げる種類 + 投擲物の種類 Typ granatu Wurfobjekt-Typ 투척물 종류 - Tipo Lanciabile + Tipo di Lanciabile 投掷物类型 投擲物類型 + Tipo arrojable + Fırlatılabilir Türü Throwable Count Počet granátů apod. Quantidade de Arremessável - Nombre d'objets de lancer + Nombre d'objets lançables Количество гранат - 投げられる数 + 投擲物の残数 Ilość granatów Wurfobjekt-Anzahl 투척물 개수 Contatore Lanciabili 投掷物数量 投擲物數量 + Cantidad arrojable + Fırlatılabilir Sayısı Zeroing Náměr Zerar a mira - Mise à zéro + Zérotage Дальность стрельбы ゼロイン Wyzerowanie broni @@ -265,19 +309,23 @@ Azzeramento 归零距离 歸零距離 + Reducción a cero + Sıfırlama Weapon Lower Info Background Informações na parte de baixo do fundo do Armamento - Arrière-plan des informations inférieures de l'arme - Фон ниформации об оружии снизу - 武器名の背景表示 (下側) + Fond pour la barre d'informations inférieure de l'arme + Фон информации об оружии снизу + 武器名下部の情報表示の背景 Tło dolnej części informacji o broni Hintergrund der unteren Waffen-Info-Leiste 무기 상세 정보 배경 - Informazioni Sfondo Arma Bassa - 武器底部资讯栏背景 + Sfondo Informazioni Arma Bassa + 武器底部信息栏背景 武器底部資訊欄背景 + Fondo de información inferior de arma + Nižší pozadí panulu s informacemi o zbrani Stance @@ -292,6 +340,8 @@ Postura 姿态 姿態 + Postura + Duruş Stamina Bar @@ -299,18 +349,20 @@ Barra de Energia Barre d'endurance Полоса выносливости - 体力バー + スタミナバー Pasek staminy Ausdaueranzeige - 체력 막대 + 지구력 막대 Barra Stamina 体力栏 體力欄 + Barra de resistencia + Yorulma Çubuğu Gunner Weapon Name Nome da arma do fuzileiro - Nom de l'arme du tireur + Nom de l'arme (tireur) Название орудия наводчика 射手用の武器名 Nazwa broni strzelca @@ -319,19 +371,24 @@ Nome Arma Artigliere 炮手武器名称 砲手武器名稱 + Jméno zbraně vozidla + Nişancı Silah Ismi + Nombre de arma de artillero Gunner Weapon Name Background Fundo do nome da arma do fuzileiro - Arrière-plan du nom de l'arme (tireur) + Fond pour le nom de l'arme (tireur) Фон названия орудия наводчика - 射手用の武器名の背景表示 + 射手用の武器名の背景 Tło nazwy broni strzelca Richtschütze Waffenname Hintergrund 사수 무기 명칭 배경 - Nome Sfondo Arma Artigliere + Sfondo Nome Arma Artigliere 炮手武器名称背景 砲手武器名稱背景 + Pozadí jména zbraně vozidla + Fondo de nombre de arma de artillero Gunner Firing Mode @@ -345,6 +402,9 @@ Modalità di Fuoco Artigliere 炮手射击模式 砲手射擊模式 + Režim palby zbraně vozidla + Nişancı Ateşleme Modu + Modo de fuego de artillero Gunner Ammo Type @@ -358,6 +418,9 @@ Tipo Munizioni Artigliere 炮手弹药类型 砲手彈藥類型 + Typ munice zbraně vozidla + Nişancı Mermi Türü + Tipo de munición de artillero Gunner Ammo Count @@ -371,6 +434,9 @@ Contatore Munizioni Artigliere 炮手弹药数量 砲手彈藥數量 + Počet zásobníků zbraně vozidla + Nişancı Mermi Sayısı + Cantidad de munición de artillero Gunner Magazine Count @@ -381,40 +447,47 @@ Ilość magazynków strzelca Richtschütze Magazinanzahl 사수 탄창 수량 - Contatore Caricatore Artigliere + Contatore Caricatori Artigliere 炮手弹匣数量 砲手彈匣數量 + Počet munice zbraně vozidla + Nişancı Şarjör Sayısı + Cantidad de cargadores de artillero Gunner Launchable Type Tipo de Arremessável do fuzileiro - Type d'objets jetable ( tireur) + Type d'objet lançable (tireur) Тип пусковой установки наводчика - 射手用のランチャーの種類 + 射手用ランチャーの種類 Typ rakiet strzelca Richtschütze Raketentyp 사수 발사체 종류 Tipo Lanciabile Artigliere 炮手发射物类型 砲手發射物類型 + Typ odpalitelných granátů vozidla + Tipo de lanzador de artillero Gunner Launchable Count Quantidade de Arremessável do fuzileiro - Nombre d'objets jetable (tireur) - Количество снарядов пусковой установки наводчика - 射手用のランチャー弾薬数 + Nombre d'objets lançables (tireur) + Кол-во снарядов ПУ наводчика + 射手用ランチャーの弾数 Ilość rakiet strzelca Richtschütze Raketenanzahl 사수 발사체 수량 - Contatore Lanciabili Artigliere + Contatore Missili Artigliere 炮手发射物数量 砲手發射物數量 + Počet odpalitelných granátů vozidla + Cantidad de lanzadores de artillero Gunner Zeroing Zerar a mira do fuzileiro - Mise à zéro ( tireur) + Zérotage (tireur) Дальность стрельбы наводчика 射手用ゼロイン Wyzerowanie broni strzelca @@ -423,19 +496,23 @@ Azzeramento Artigliere 炮手归零距离 砲手歸零距離 + Náměr zbraně vozidla + Calibracion de mira de artillero Gunner Weapon Lower Info Background Informações na parte de baixo do fundo do Armamento do fuzileiro - Arrière-plan des informations inférieures (tireur) - Фон ниформации об орудии наводчика снизу - 射手用の武器名の背景表示 (下側) + Fond pour la barre d'informations inférieure (tireur) + Фон информации об орудии наводчика снизу + 射手用武器名下部の情報表示の背景 Tło dolnej części informacji o broni strzelca Hintergrund der unteren Waffen-Info-Leiste (Richtschütze) 사수 무기 상세 정보 배경 - Informazioni Sfondo Arma Artigliere Bassa - 炮手武器底部资讯栏背景 + Sfondo Informazioni Arma Artigliere Bassa + 炮手武器底部信息栏背景 砲手武器底部資訊欄背景 + Nižší pozadí panelu s informacemi o zbrani vozidla + Fondo de información inferior de armamento de artillero Vehicle Name @@ -450,26 +527,29 @@ Nome Veicolo 载具名称 載具名稱 + Nombre del vehiculo + Araç Ismi Vehicle Name Background Název vozidla v pozadí Fundo do Nome do Veículo - Arrière-plan du nom du véhicule + Fond pour le nom du véhicule Фон названия техники 車両名の背景 Tło nazwy pojazdu Fahrzeugname Hintergrund 차량 명칭 배경 - Nome Sfondo Veicolo + Sfondo Nome Veicolo 载具名称背景 載具名稱背景 + Fondo del nombre del vehículo Vehicle Fuel Bar Ukazatel paliva Barra de Combustível do Veículo - Barre d'éssence du véhicule + Barre d'essence du véhicule Полоса топлива 車両の燃料計 Pasek paliwa @@ -478,6 +558,8 @@ Barra Carburante Veicolo 载具燃料栏 載具燃料欄 + Barra de combustible del vehículo + Araç Yakıt Göstergesi Vehicle Speed @@ -492,6 +574,8 @@ Velocità Veicolo 载具速度 載具速度 + Velocidad del vehículo + Araç Hızı Vehicle Altitude @@ -506,75 +590,132 @@ Altitudine Veicolo 载具高度 載具高度 + Altitud del vehículo + Araç Yüksekliği Vehicle Damage Poškození vozidla Dano do Veículo - Dégats du véhicule + Dégâts du véhicule Повреждение техники - 車両の損傷表示 + 車両の損傷状態 Uszkodzenia pojazdu Fahrzeugschaden 차량 피해 - Danno Veicolo + Danni Veicolo 载具伤害 載具傷害 + Daño vehicular + Araç Hasarı Vehicle Info Background Info o vozidle v pozadí Fundo das informações do veículo - Arrière-plan des informations du véhicule + Fond pour les informations du véhicule Фон информации о технике 車両状態の背景 Tło informacji o pojeździe Fahrzeug Info Hintergrund 차량 정보 배경 - Informazioni Sfondo Veicolo - 载具资讯栏背景 + Sfondo Informazioni Veicolo + 载具信息栏背景 載具資訊欄背景 + Fondo de información del vehículo Requires Soldier/Vehicle/Weapon Information. Vyžaduje informace o Vojákovi/Vozidlu/Zbrani Requer informações de Soldado/Veículo/Armamento - Requiert les informations de soldat/Vehicule/Arme. - Требуется Информация о Солдате/Технике/Оружии. - 兵士/車両/武器の情報を必要とします。 + Requiert l'option "Information soldat/véhicule/arme". + Требуется информация о солдате/технике/оружии. + 兵士/車両/武器の情報 の表示が必要です。 Wymaga informacji o żołnierzu/pojeździe/broni. Benötigt Soldat/Fahrzeug/Waffe Information. 병사/차량/무기의 정보가 필요합니다. - Richiede informazione Soldato/Veicolo/Arma. - 需要士兵/载具/武器的资讯. + Richiede informazioni Soldato/Veicolo/Arma. + 需要士兵/载具/武器的信息。 需要士兵/載具/武器的資訊. + Requiere información de Soldado/Vehículo. Modifying User Interface is disabled. Změna uživatelského rozhraní je zakázána. A modificação da interface do usuário está desabilitada. - Modifications de l'interface utilisateur désactivé. + La personnalisation de l'Interface Utilisateur est désactivée. Изменение пользовательского интерфейса запрещено. - ユーザ インタフェイスの変更は無効化されています。 + ユーザ インターフェースの変更は無効化されています。 Modyfikacja interfejsu użytkownika jest wyłączona. Die Modifizierung des UI ist deaktiviert. - 사용자 인터페이스 변경이 비활성화 되어있습니다. + 사용자 인터페이스 변경이 비활성화 되어 있습니다. La modifica dell'Interfaccia Utente è disabilitata. - 自定使用者介面功能已关闭 + 自定用户界面功能已关闭 自定使用者介面功能已關閉 + La modificación de la interfaz de usuario está desactivada. Cannot modify a forced User Interface element. Não é possível modificar um elemento forçado da interface do usuário. - Impossible de modifier un élément de l'interface utilisateur forcé. + Impossible de modifier un élément forcé de l'Interface Utilisateur. Невозможно изменить зафиксированный элемент пользовательского интерфейса. - ユーザー インタフェイス要素の強制はできません。 + ユーザ インターフェース要素の強制はできません。 Nie można modyfikować wymuszonego elementu interfejsu użytkownika. Gesperrte UI-Elemente können nicht modifiziert werden. 강제 사용자 인터페이스는 변경하실 수 없습니다. - Impossibile modificare un elemento forzato d' Interfaccia Utente. - 无法编辑已被锁定的使用者介面元件 + Impossibile modificare un elemento forzato dell'Interfaccia Utente. + 无法编辑已被锁定的用户界面控件 無法編輯已被鎖定的使用者介面元件 + Nelze upravit prvek vynuceného uživatelského rozhraní. + No se puede modificar un elemento forzado de la Interfaz del Usuario + + + Enable movement speed indicator + Włącz wskaźnik prędkości poruszania + 移動速度インジケータを有効化 + Indicateur de vitesse de déplacement + Вкл. индикатор скорости передвижения + Aktiviere Bewegungsgeschwindigkeits-Indikator + Attiva Indicatore di Velocità + 启用移动速度指示器 + 이동 속도 표시기 활성화 + Habilitar indicador de velocidad de movimiento + + + Enables movement speed indicator for player character. + Włącza wskaźnik prędkości poruszania się dla postaci gracza. + プレイヤー キャラの移動速度を表示します。 + Affiche un indicateur permettant de visualiser la vitesse de déplacement du personnage. + Включает индикатор скорости передвижения персонажа игрока. + Aktiviere den Bewegungsgeschwindigkeits-Indikator des Spielers. + Attiva Indicatore di Velocità del Giocatore + 为玩家角色启用移动速度指示器。 + 플레이어 캐릭터를 위한 이동속도 표시기를 활성화합니다. + Habilita el indicador de velocidad de movimiento para el personaje del jugador. + + + Hide Default Action Icon + デフォルトのアクションアイコンを非表示 + Ukryj domyślną ikonę akcji + 기본 행동 아이콘 숨기기 + 隐藏默认动作标识 + Спрятать иконку действия по умолчанию + Ocultar el icono de acción por defecto + Standardaktionssymbol ausblenden + Masquer l'icône d'action par défaut + Nascondi Icona dell'Interazione Standard + + + Hides the icon shown automatically when something is in front of the cursor. Requires a game restart.\nWarning: Does not remove the action itself! It is advisable to unbind 'Use default action' key to prevent unwanted interactions. + カーソルの前に何かがあるときに自動的に表示されるアイコンを非表示にします。 ゲームを再起動する必要があります。\n警告:アクション自体は削除されません! 誤って実行することを防ぐために、'標準アクション'キーのバインドを解除することをお勧めします。 + Ukrywa ikonę wyświetlaną automatycznie, gdy coś znajduje się przed kursorem. Wymaga ponownego uruchomienia gry.\nOstrzeżenie: Nie usuwa samej akcji! Zaleca się usunięcia przypisania klawisza „Użyj domyślnej akcji”, aby zapobiec niechcianym interakcjom. + 커서 앞에 무언가가 있을 때 자동으로 표시되는 아이콘을 숨깁니다. 게임을 재시작해야 합니다\n경고: 작업 자체를 제거하지 않습니다! 원하지 않는 상호작용을 방지하려면 '기본 행동' 키를 삭제하는 것이 좋습니다. + 隐藏屏幕面前有物体时自动显示的动作标识。需要重新启动游戏。\n警告:不会删除动作本身!建议同时取消对“使用默认动作”键的绑定,以防止不必要的互动。 + Прячет иконку, которая показывается автоматически когда что-то находиться перед курсором. Требует рестарта игры.\nВнимание: не убирает само действие! Рекомендуется убрать комбинацию клавиш с настройки "Выполнить действие по умолчанию" чтобы предостеречься от нежеланных действий. + Oculta el icono que se muestra automáticamente cuando algo se sitúa enfrente del cursor. Requiere reinicio del juego.\nAdvertencia: No elimina la propia acción! Es recomendable desactivar la tecla "Usar acción por defecto" para prevenir interacciones no deseadas. + Blendet das Symbol aus, das automatisch angezeigt wird, wenn sich etwas vor dem Cursor befindet. Erfordert einen Neustart des Spiels.\nWarnung: Die Aktion selbst wird nicht entfernt! Es empfiehlt sich, die Belegung der Taste 'Standardaktion verwenden' aufzuheben, um unerwünschte Interaktionen zu verhindern. + Cache l'icône qui s'affiche automatiquement lorsque quelque chose est devant le curseur. Nécessite un redémarrage du jeu.\nAvertissement : l'action n'est pas supprimée ! Il est recommandé d'annuler l'affectation du bouton 'Utiliser l'action par défaut' afin d'éviter des interactions indésirables. + Nasconde l'icona mostrata in automatico quando qualcosa è davanti al cursore. La modifica richiede un riavvio del gioco.\nAttenzione: Non rimuovere l'azione stessa! È consigliato rimuovere solo il tasto dall'assegnazione 'Usa Azione Standard' per impedire interazioni non volute. diff --git a/addons/vector/CfgEventHandlers.hpp b/addons/vector/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/vector/CfgEventHandlers.hpp +++ b/addons/vector/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/vector/CfgWeapons.hpp b/addons/vector/CfgWeapons.hpp index 5ffe99eea9..f1a8db5482 100644 --- a/addons/vector/CfgWeapons.hpp +++ b/addons/vector/CfgWeapons.hpp @@ -7,8 +7,8 @@ class CfgWeapons { model = QPATHTOF(ace_vector.p3d); picture = QPATHTOF(UI\ace_vector_x_ca.paa); visionMode[] = {"Normal","NVG"}; - opticsZoomMax = 0.25/7; - opticsZoomMin = 0.25/7; + opticsZoomMax = "0.25/7"; + opticsZoomMin = "0.25/7"; modelOptics = "\A3\Weapons_F\empty.p3d"; class CBA_ScriptedOptic { @@ -19,6 +19,7 @@ class CfgWeapons { reticleSafezoneSize = 1; hidePeripheralVision = 1; opticsPPEffects[] = {QGVAR(OpticsRadBlur1)}; + disableTilt = 1; }; weaponInfoType = "ACE_RscOptics_vector"; }; diff --git a/addons/vector/README.md b/addons/vector/README.md index 8907a78e49..9281e9ee34 100644 --- a/addons/vector/README.md +++ b/addons/vector/README.md @@ -2,11 +2,3 @@ ace_vector ========== Adds the Vector rangefinder including all modes found in its real counterpart. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/vector/XEH_postInit.sqf b/addons/vector/XEH_postInit.sqf index 12f643ece3..fb76dc5136 100644 --- a/addons/vector/XEH_postInit.sqf +++ b/addons/vector/XEH_postInit.sqf @@ -13,4 +13,4 @@ GVAR(useFeet) = false; GVAR(modeReticle) = 0; GVAR(illuminate) = false; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" diff --git a/addons/vector/functions/fnc_adjustBrightness.sqf b/addons/vector/functions/fnc_adjustBrightness.sqf index cfe7f119a8..e8ece20637 100644 --- a/addons/vector/functions/fnc_adjustBrightness.sqf +++ b/addons/vector/functions/fnc_adjustBrightness.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * @@ -10,7 +10,7 @@ * None * * Example: - * [5] call ace_vector_fnc_adjustBrigthness + * [5] call ace_vector_fnc_adjustBrightness * * Public: No */ diff --git a/addons/vector/functions/fnc_clearDisplay.sqf b/addons/vector/functions/fnc_clearDisplay.sqf index 1f723dd2f8..8b27b17ab6 100644 --- a/addons/vector/functions/fnc_clearDisplay.sqf +++ b/addons/vector/functions/fnc_clearDisplay.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Clears the vectors control items. diff --git a/addons/vector/functions/fnc_convertToTexturesDegree.sqf b/addons/vector/functions/fnc_convertToTexturesDegree.sqf index 17754244f1..559c79d5bd 100644 --- a/addons/vector/functions/fnc_convertToTexturesDegree.sqf +++ b/addons/vector/functions/fnc_convertToTexturesDegree.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * converts azimuth into array of textures for the vectors scripted info control diff --git a/addons/vector/functions/fnc_convertToTexturesDistance.sqf b/addons/vector/functions/fnc_convertToTexturesDistance.sqf index cb2f1ba990..91bbcfd606 100644 --- a/addons/vector/functions/fnc_convertToTexturesDistance.sqf +++ b/addons/vector/functions/fnc_convertToTexturesDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * converts rangefinder distance into array of textures for the vectors scripted info control diff --git a/addons/vector/functions/fnc_convertToTexturesFOS.sqf b/addons/vector/functions/fnc_convertToTexturesFOS.sqf index eb9e6f840c..5b831f080e 100644 --- a/addons/vector/functions/fnc_convertToTexturesFOS.sqf +++ b/addons/vector/functions/fnc_convertToTexturesFOS.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * converts rangefinder distance into array of textures for the vectors scripted info control diff --git a/addons/vector/functions/fnc_dataTransfer.sqf b/addons/vector/functions/fnc_dataTransfer.sqf index b50a823be9..5dbdf5c2ff 100644 --- a/addons/vector/functions/fnc_dataTransfer.sqf +++ b/addons/vector/functions/fnc_dataTransfer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Data transfer over a connected cable. Based on page 14 of pdf. diff --git a/addons/vector/functions/fnc_getDirection.sqf b/addons/vector/functions/fnc_getDirection.sqf index 1103a55458..554b8954ba 100644 --- a/addons/vector/functions/fnc_getDirection.sqf +++ b/addons/vector/functions/fnc_getDirection.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_getDistance.sqf b/addons/vector/functions/fnc_getDistance.sqf index 8c38cc619f..dbe8f70818 100644 --- a/addons/vector/functions/fnc_getDistance.sqf +++ b/addons/vector/functions/fnc_getDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_getFallOfShot.sqf b/addons/vector/functions/fnc_getFallOfShot.sqf index 7fbaa6ad98..5de2db1ef4 100644 --- a/addons/vector/functions/fnc_getFallOfShot.sqf +++ b/addons/vector/functions/fnc_getFallOfShot.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_getHeightDistance.sqf b/addons/vector/functions/fnc_getHeightDistance.sqf index 00bd888cdf..89c7bc36ef 100644 --- a/addons/vector/functions/fnc_getHeightDistance.sqf +++ b/addons/vector/functions/fnc_getHeightDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf b/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf index 33d9a07dc0..e572ad1056 100644 --- a/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf +++ b/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_getRelativeDistance.sqf b/addons/vector/functions/fnc_getRelativeDistance.sqf index bbe9ca1672..b5751bfd1f 100644 --- a/addons/vector/functions/fnc_getRelativeDistance.sqf +++ b/addons/vector/functions/fnc_getRelativeDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_getRelativeHeightLength.sqf b/addons/vector/functions/fnc_getRelativeHeightLength.sqf index 1049ba84b6..a9f7a2e363 100644 --- a/addons/vector/functions/fnc_getRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_getRelativeHeightLength.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_illuminate.sqf b/addons/vector/functions/fnc_illuminate.sqf index 0c91da0ac0..10811b3e79 100644 --- a/addons/vector/functions/fnc_illuminate.sqf +++ b/addons/vector/functions/fnc_illuminate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_nextMode.sqf b/addons/vector/functions/fnc_nextMode.sqf index cd00b4977d..f55bbe765b 100644 --- a/addons/vector/functions/fnc_nextMode.sqf +++ b/addons/vector/functions/fnc_nextMode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_onKeyDown.sqf b/addons/vector/functions/fnc_onKeyDown.sqf index a9c6b90b2d..082f22e483 100644 --- a/addons/vector/functions/fnc_onKeyDown.sqf +++ b/addons/vector/functions/fnc_onKeyDown.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles pressing the special vector keys. @@ -38,7 +38,7 @@ private _fnc_setPFH = { }; GVAR(currentMode) = _this; - GVAR(holdKeyHandler) = [FUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; + GVAR(holdKeyHandler) = [LINKFUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; }; switch (_this select 0) do { diff --git a/addons/vector/functions/fnc_onKeyHold.sqf b/addons/vector/functions/fnc_onKeyHold.sqf index cefdc3236b..f19039851b 100644 --- a/addons/vector/functions/fnc_onKeyHold.sqf +++ b/addons/vector/functions/fnc_onKeyHold.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * PFH executed while holding a vector key down. @@ -16,7 +16,7 @@ * Public: No */ -if (!((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"])) exitWith { +if !((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; GVAR(currentMode) = ""; diff --git a/addons/vector/functions/fnc_onKeyUp.sqf b/addons/vector/functions/fnc_onKeyUp.sqf index 2e315d7c0e..b660331e65 100644 --- a/addons/vector/functions/fnc_onKeyUp.sqf +++ b/addons/vector/functions/fnc_onKeyUp.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Handles releasing the special vector keys. @@ -22,7 +22,7 @@ private _fnc_setPFH = { }; GVAR(currentMode) = _this;// - GVAR(holdKeyHandler) = [FUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; + GVAR(holdKeyHandler) = [LINKFUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; }; switch (_this select 0) do { diff --git a/addons/vector/functions/fnc_showAzimuth.sqf b/addons/vector/functions/fnc_showAzimuth.sqf index e07f093b5d..4b84d5d1e4 100644 --- a/addons/vector/functions/fnc_showAzimuth.sqf +++ b/addons/vector/functions/fnc_showAzimuth.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showAzimuthInclination.sqf b/addons/vector/functions/fnc_showAzimuthInclination.sqf index e7769a3e7b..fdff0ef44a 100644 --- a/addons/vector/functions/fnc_showAzimuthInclination.sqf +++ b/addons/vector/functions/fnc_showAzimuthInclination.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showCenter.sqf b/addons/vector/functions/fnc_showCenter.sqf index d9e3542fac..78c7db3c5f 100644 --- a/addons/vector/functions/fnc_showCenter.sqf +++ b/addons/vector/functions/fnc_showCenter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Shows or hides the vectors center square thingy. diff --git a/addons/vector/functions/fnc_showDistance.sqf b/addons/vector/functions/fnc_showDistance.sqf index 3009d5ea5d..33fc583f46 100644 --- a/addons/vector/functions/fnc_showDistance.sqf +++ b/addons/vector/functions/fnc_showDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showFallOfShot.sqf b/addons/vector/functions/fnc_showFallOfShot.sqf index ac03fc6bbf..46963052f8 100644 --- a/addons/vector/functions/fnc_showFallOfShot.sqf +++ b/addons/vector/functions/fnc_showFallOfShot.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showHeightDistance.sqf b/addons/vector/functions/fnc_showHeightDistance.sqf index ce4e3011a9..0439a77ed0 100644 --- a/addons/vector/functions/fnc_showHeightDistance.sqf +++ b/addons/vector/functions/fnc_showHeightDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showP1.sqf b/addons/vector/functions/fnc_showP1.sqf index 4cb25adfaa..e592e02488 100644 --- a/addons/vector/functions/fnc_showP1.sqf +++ b/addons/vector/functions/fnc_showP1.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Shows or hides the 1-P text line. diff --git a/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf b/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf index 74365cc6c7..adefac8d71 100644 --- a/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf +++ b/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showRelativeDistance.sqf b/addons/vector/functions/fnc_showRelativeDistance.sqf index b8ddd9f04f..02bca2e480 100644 --- a/addons/vector/functions/fnc_showRelativeDistance.sqf +++ b/addons/vector/functions/fnc_showRelativeDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showRelativeHeightLength.sqf b/addons/vector/functions/fnc_showRelativeHeightLength.sqf index 1fb9ddcb2f..95e9d4f6bb 100644 --- a/addons/vector/functions/fnc_showRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_showRelativeHeightLength.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/fnc_showReticle.sqf b/addons/vector/functions/fnc_showReticle.sqf index fabf3cad15..6f5bd4c551 100644 --- a/addons/vector/functions/fnc_showReticle.sqf +++ b/addons/vector/functions/fnc_showReticle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Shows or hides the electronic reticle. diff --git a/addons/vector/functions/fnc_showText.sqf b/addons/vector/functions/fnc_showText.sqf index 23f4481082..21c12e8475 100644 --- a/addons/vector/functions/fnc_showText.sqf +++ b/addons/vector/functions/fnc_showText.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * diff --git a/addons/vector/functions/script_component.hpp b/addons/vector/functions/script_component.hpp deleted file mode 100644 index d4007d8aa4..0000000000 --- a/addons/vector/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\vector\script_component.hpp" \ No newline at end of file diff --git a/addons/vector/initKeybinds.sqf b/addons/vector/initKeybinds.inc.sqf similarity index 100% rename from addons/vector/initKeybinds.sqf rename to addons/vector/initKeybinds.inc.sqf diff --git a/addons/vector/stringtable.xml b/addons/vector/stringtable.xml index 76feaa2b5c..c28e7078bf 100644 --- a/addons/vector/stringtable.xml +++ b/addons/vector/stringtable.xml @@ -13,9 +13,10 @@ Vector 21 Nite Vector 21 Nite ベクター 21 ナイト - Vector 21 Nite + 벡터 21 야간투시 Vector 21 Nite Vector 21 Nite + Vector 21 Nite Vector 21 @@ -29,9 +30,10 @@ Vector 21 Vector 21 ベクター 21 - Vector 21 + 벡터 21 Vector 21 Vector 21 + Vector 21 Rangefinder @@ -44,16 +46,17 @@ Távolságmérő Medidor de Distância Дальномер - 測距機器 + 測距儀 거리측정기 测距仪 測距儀 + Menzil Bulucu Vector - Azimuth Key Vector - Azimuth-Taste Vector - Tecla de acimut - Vector - Touche Azimuth + Vector - Touche azimuth Vector - Azymut Vector - Zobrazit azimut Vector - Tasto Azimuth @@ -61,15 +64,16 @@ Vector - Irányszög gomb Vector – Азимут ベクター - 方位角キー - Vector - 방위각 키 - Vector - 方位按键 + 벡터 - 방위각 키 + Vector—方位按键 Vector - 方位按鍵 + Vector - Azimuth Tuşu Vector - Distance Key Vector - Entfernungs-Taste Vector - Tecla de distancia - Vector - Touche Distance + Vector - Touche distance Vector - Odległość Vector - Zobrazit vzdálenost Vector - Tasto Distanza @@ -77,9 +81,10 @@ Vector - Távolság gomb Vector – Расстояние ベクター - 距離キー - Vector - 거리 키 - Vector - 距离按键 + 벡터 - 거리 키 + Vector—距离按键 Vector - 距離按鍵 + Vector - Mesafe Tuşu diff --git a/addons/vehicle_damage/$PBOPREFIX$ b/addons/vehicle_damage/$PBOPREFIX$ new file mode 100644 index 0000000000..ec06bcd644 --- /dev/null +++ b/addons/vehicle_damage/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\vehicle_damage \ No newline at end of file diff --git a/addons/vehicle_damage/CfgAmmo.hpp b/addons/vehicle_damage/CfgAmmo.hpp new file mode 100644 index 0000000000..408c3e7b15 --- /dev/null +++ b/addons/vehicle_damage/CfgAmmo.hpp @@ -0,0 +1,113 @@ +#pragma hemtt suppress pw3_padded_arg file + +class CfgAmmo { + class Default; + class BulletCore; + class ShellCore; + class MissileCore; + class GrenadeCore; + class LaserBombCore; + class RocketCore; + class MineCore; + class BombCore; + class DirectionalBombCore; + class PipeBombCore; + + class B_30mm_HE; + class GrenadeHand; + class R_PG32V_F; + class SubmunitionBase; + class Sh_125mm_HE; + class M_Vorona_HEAT; + class M_SPG9_HEAT; + class R_MRAAWS_HEAT_F; + class B_338_Ball; + + class ACE_G_40mm_HE; + + CREATE_INCENDIARY_AMMO(BulletBase, BulletCore, 0.1); + CREATE_INCENDIARY_AMMO(ShellBase, ShellCore, 1.0); + CREATE_INCENDIARY_AMMO(ammo_Penetrator_Base, ShellBase, 1.0); + CREATE_INCENDIARY_AMMO(MissileBase, MissileCore, 1.0); + CREATE_INCENDIARY_AMMO(ammo_Missile_CruiseBase, MissileBase, 0.5); + CREATE_INCENDIARY_AMMO(GrenadeBase, GrenadeCore, 0.1); + CREATE_INCENDIARY_AMMO(Grenade, Default, 0.0); + CREATE_INCENDIARY_AMMO(ammo_bomb_LaserGuidedBase, LaserBombCore, 0.6); + CREATE_INCENDIARY_AMMO(RocketBase, RocketCore, 1.0); + CREATE_INCENDIARY_AMMO(MineBase, MineCore, 0.5); + CREATE_INCENDIARY_AMMO(DirectionalBombBase, DirectionalBombCore, 1.0); + CREATE_INCENDIARY_AMMO(PipeBombBase, PipeBombCore, 0.7); + CREATE_INCENDIARY_AMMO(ammo_Missile_AntiRadiationBase, MissileBase, 1.0); + CREATE_INCENDIARY_AMMO(ammo_Gun20mmAABase, BulletBase, 0.7); + CREATE_INCENDIARY_AMMO(ammo_Gun30mmAABase, BulletBase, 0.7); + CREATE_INCENDIARY_AMMO(ammo_Gun35mmAABase, BulletBase, 0.7); + CREATE_INCENDIARY_AMMO(ammo_Missile_CannonLaunchedBase, MissileBase, 1.0); + + CREATE_INCENDIARY_AMMO(B_127x99_Ball, BulletBase, 0.2); + CREATE_INCENDIARY_AMMO(B_127x99_SLAP, B_127x99_Ball, 0.8); + CREATE_INCENDIARY_AMMO(B_127x108_Ball, BulletBase, 0.3); + CREATE_INCENDIARY_AMMO(B_127x108_APDS, B_127x108_Ball, 0.1); + + CREATE_INCENDIARY_AMMO(B_30mm_MP, B_30mm_HE, 0.6); + CREATE_INCENDIARY_AMMO(B_40mm_GPR, B_30mm_HE, 0.6); + CREATE_INCENDIARY_AMMO(B_20mm, BulletBase, 0.2); + CREATE_INCENDIARY_AMMO(B_25mm, BulletBase, 0.4); + CREATE_INCENDIARY_AMMO(B_30mm_AP, BulletBase, 0.4); + CREATE_INCENDIARY_AMMO(B_30mm_APFSDS, B_30mm_AP, 0.1); + CREATE_INCENDIARY_AMMO(B_35mm_AA, BulletBase, 0.7); + CREATE_INCENDIARY_AMMO(SmokeShell, GrenadeHand, 0.0); + + + CREATE_INCENDIARY_AMMO(ammo_Penetrator_30mm, ammo_Penetrator_Base, 0.8); + CREATE_INCENDIARY_AMMO(ammo_Penetrator_grenade_40mm, ammo_Penetrator_Base, 1.0); + CREATE_INCENDIARY_AMMO(ammo_Penetrator_105mm, ammo_Penetrator_Base, 1.0); + CREATE_INCENDIARY_AMMO(ammo_Penetrator_120mm, ammo_Penetrator_Base, 1.0); + CREATE_INCENDIARY_AMMO(ammo_Penetrator_Rocket_03_AP, ammo_Penetrator_Base, 0.7); + CREATE_INCENDIARY_AMMO(ammo_Penetrator_Rocket_04_AP, ammo_Penetrator_Base, 0.7); + + CREATE_INCENDIARY_AMMO(Sh_120mm_HE, ShellBase, 0.4); + CREATE_INCENDIARY_AMMO(Sh_120mm_APFSDS, ShellBase, 0.1); + CREATE_INCENDIARY_AMMO(Sh_120mm_HEAT_MP, ShellBase, 0.8); + CREATE_INCENDIARY_AMMO(Sh_155mm_AMOS, ShellBase, 0.4); + CREATE_INCENDIARY_AMMO(Sh_82mm_AMOS, Sh_155mm_AMOS, 0.1); + + CREATE_INCENDIARY_AMMO(Bo_Mk82, BombCore, 0.8); + CREATE_INCENDIARY_AMMO(R_TBG32V_F, R_PG32V_F, 0.2); + + CREATE_INCENDIARY_AMMO(R_80mm_HE, RocketBase, 0.2); + CREATE_INCENDIARY_AMMO(R_60mm_HE, R_80mm_HE, 0.1); + + CREATE_INCENDIARY_AMMO(R_230mm_HE, SubmunitionBase, 0.9); + CREATE_INCENDIARY_AMMO(R_230mm_fly, ShellBase, 0.9); + + CREATE_INCENDIARY_AMMO(G_40mm_HE, GrenadeBase, 0.1); + CREATE_INCENDIARY_AMMO(G_20mm_HE, G_40mm_HE, 0.3); + CREATE_INCENDIARY_AMMO(G_40mm_HEDP, G_40mm_HE, 0.8); + + CREATE_INCENDIARY_AMMO(Mo_cluster_AP, ShellBase, 0.9); + CREATE_INCENDIARY_AMMO(M_Titan_AT, MissileBase, 1.0); + CREATE_INCENDIARY_AMMO(M_Titan_AP, M_Titan_AT, 0.3); + + CREATE_INCENDIARY_AMMO(Sh_125mm_APFSDS, Sh_120mm_APFSDS, 0.15); + CREATE_INCENDIARY_AMMO(Sh_125mm_HEAT, Sh_125mm_HE, 1.0); + + CREATE_INCENDIARY_AMMO(Gatling_30mm_HE_Plane_CAS_01_F, BulletBase, 0.6); + + CREATE_INCENDIARY_AMMO(Missile_AGM_02_F, MissileBase, 1.0); + CREATE_INCENDIARY_AMMO(M_Mo_82mm_AT, MissileBase, 1.0); + CREATE_INCENDIARY_AMMO(Rocket_04_HE_F, MissileBase, 0.4); + CREATE_INCENDIARY_AMMO(Rocket_04_AP_F, Rocket_04_HE_F, 0.1); + + CREATE_INCENDIARY_AMMO(Sh_105mm_HEAT_MP, Sh_125mm_HEAT, 0.8); + + CREATE_INCENDIARY_AMMO(APERSTripMine_Wire_Ammo, DirectionalBombBase, 0.0); + + CREATE_INCENDIARY_AMMO(B_127x54_Ball, BulletBase, 0.8); + CREATE_INCENDIARY_AMMO(B_93x64_Ball, BulletBase, 0.5); + + CREATE_INCENDIARY_AMMO(M_Vorona_HE, M_Vorona_HEAT, 0.2); + CREATE_INCENDIARY_AMMO(M_SPG9_HE, M_SPG9_HEAT, 0.2); + CREATE_INCENDIARY_AMMO(R_MRAAWS_HE_F, R_MRAAWS_HEAT_F, 0.4); + + CREATE_INCENDIARY_AMMO(B_20mm_AP, BulletBase, 0.2); +}; diff --git a/addons/vehicle_damage/CfgEventHandlers.hpp b/addons/vehicle_damage/CfgEventHandlers.hpp new file mode 100644 index 0000000000..74ffec132e --- /dev/null +++ b/addons/vehicle_damage/CfgEventHandlers.hpp @@ -0,0 +1,19 @@ + +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + diff --git a/addons/vehicle_damage/CfgVehicles.hpp b/addons/vehicle_damage/CfgVehicles.hpp new file mode 100644 index 0000000000..9ea47711ea --- /dev/null +++ b/addons/vehicle_damage/CfgVehicles.hpp @@ -0,0 +1,291 @@ +class CfgVehicles { + class ThingX; + class GVAR(Turret_MBT_01): ThingX { + author = ECSTRING(common,ACETeam); + _generalMacro = QGVAR(Turret_MBT_01); + scope = 1; + displayName = CSTRING(generic_turret_wreck); + model = "\A3\Structures_F\Wrecks\Wreck_Slammer_turret_F.p3d"; + icon = "\A3\armor_f_gamma\MBT_01\Data\ui\map_slammer_mk4_ca.paa"; + }; + class GVAR(Turret_MBT_02): ThingX { + author = ECSTRING(common,ACETeam); + _generalMacro = QGVAR(Turret_MBT_02); + scope = 1; + displayName = CSTRING(generic_turret_wreck); + model = "\A3\Structures_F\Wrecks\Wreck_T72_turret_F.p3d"; + icon = "\A3\armor_f_gamma\MBT_02\Data\UI\map_MBT_02_ca.paa"; + }; + + class Tank; + class Car_F; + class Tank_F: Tank { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0.2; + GVAR(engineDetonationProb) = 0.2; + GVAR(hullFireProb) = 0.5; + GVAR(turretFireProb) = 0.2; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0.2; + GVAR(canHaveFireRing) = 0; + }; + class Wheeled_APC_F: Car_F { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0.2; + GVAR(engineDetonationProb) = 0.2; + GVAR(hullFireProb) = 0.5; + GVAR(turretFireProb) = 0.2; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0.2; + GVAR(canHaveFireRing) = 0; + }; + class APC_Tracked_01_base_F: Tank_F {}; + class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; + class B_APC_Tracked_01_AA_F: B_APC_Tracked_01_base_F { + GVAR(hullDetonationProb) = 0.4; + GVAR(turretDetonationProb) = 0.4; + GVAR(engineDetonationProb) = 0.4; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0.7; + GVAR(engineFireProb) = 0.8; + GVAR(detonationDuringFireProb) = 0.8; + GVAR(canHaveFireRing) = 1; + }; + class B_APC_Tracked_01_rcws_F: B_APC_Tracked_01_base_F { + GVAR(hullDetonationProb) = 0.3; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0.1; + GVAR(hullFireProb) = 0.8; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.8; + GVAR(detonationDuringFireProb) = 0.5; + }; + class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { + GVAR(hullDetonationProb) = 0.3; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0.1; + GVAR(hullFireProb) = 0.8; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.8; + GVAR(detonationDuringFireProb) = 0.5; + }; + class APC_Wheeled_01_base_F: Wheeled_APC_F { + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_top_back", "HitSLAT_top_left", "HitSLAT_top_right", + "HitSLAT_back", + "HitSLAT_front" + }; + }; + class B_APC_Wheeled_01_base_F: APC_Wheeled_01_base_F {}; + class B_APC_Wheeled_01_cannon_F: B_APC_Wheeled_01_base_F { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0.2; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0.7; + GVAR(engineFireProb) = 0.7; + GVAR(detonationDuringFireProb) = 0.5; + GVAR(canHaveFireRing) = 1; + }; + class APC_Wheeled_02_base_F: Wheeled_APC_F { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.7; + GVAR(detonationDuringFireProb) = 0.5; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_back", + "HitSLAT_front" + }; + }; + class AFV_Wheeled_01_base_F: Wheeled_APC_F { + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_back", + "HitSLAT_front" + }; + }; + class B_AFV_Wheeled_01_cannon_F: AFV_Wheeled_01_base_F { + GVAR(hullDetonationProb) = 0.5; + GVAR(turretDetonationProb) = 0.5; + GVAR(engineDetonationProb) = 0.2; + GVAR(hullFireProb) = 0.2; + GVAR(turretFireProb) = 0.2; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0.5; + }; + class AFV_Wheeled_01_up_base_F: AFV_Wheeled_01_base_F { + GVAR(eraHitpoints)[] = { + "HitERA_Front", "HitERA_Left", "HitERA_Right", "HitERA_Top", "HitERA_Back" + }; + }; + class MBT_01_base_F: Tank_F { + GVAR(hullDetonationProb) = 0.6; + GVAR(turretDetonationProb) = 0.3; + GVAR(engineDetonationProb) = 0.1; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0.4; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0.3; + GVAR(canHaveFireRing) = 1; + }; + class B_MBT_01_base_F: MBT_01_base_F {}; + class B_MBT_01_cannon_F: B_MBT_01_base_F { + GVAR(turret)[] = { QGVAR(Turret_MBT_01), {0, -1, 0.5} }; + }; + class B_MBT_01_TUSK_F: B_MBT_01_cannon_F { + GVAR(eraHitpoints)[] = { + "HitERA_Front", + "HitERA_Left_1", "HitERA_Left_2", "HitERA_Left_3", "HitERA_Left_4", + "HitERA_Right_1", "HitERA_Right_2", "HitERA_Right_3", "HitERA_Right_4", + "HitERA_Top_Front", "HitERA_Top_Left", "HitERA_Top_Right" + }; + }; + + class O_MBT_02_base_F; + class O_MBT_02_cannon_F: O_MBT_02_base_F { + GVAR(turret)[] = { QGVAR(Turret_MBT_02), {0, -1, 0} }; + GVAR(canHaveFireRing) = 1; + }; + + class APC_Tracked_02_base_F: Tank_F { + GVAR(hullDetonationProb) = 0; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.8; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.8; + GVAR(detonationDuringFireProb) = 0.5; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_back", + "HitSLAT_front" + }; + GVAR(canHaveFireRing) = 1; + }; + class O_APC_Tracked_02_base_F: APC_Tracked_02_base_F {}; + class O_APC_Tracked_02_AA_F: O_APC_Tracked_02_base_F { + GVAR(hullDetonationProb) = 0.4; + GVAR(turretDetonationProb) = 0.4; + GVAR(engineDetonationProb) = 0.4; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0.7; + GVAR(engineFireProb) = 0.8; + GVAR(detonationDuringFireProb) = 0.8; + GVAR(canHaveFireRing) = 1; + }; + class MBT_04_base_F: Tank_F { + GVAR(hullDetonationProb) = 0; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.2; + GVAR(turretFireProb) = 0.2; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0; + GVAR(eraHitpoints)[] = { + "HitERA_Front", + "HitERA_Left_1", "HitERA_Left_2", + "HitERA_Right_1", "HitERA_Right_2", + "HitERA_Top" + }; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left", "HitSLAT_Right" + }; + GVAR(canHaveFireRing) = 1; + }; + class MBT_02_base_F: Tank_F { + GVAR(hullDetonationProb) = 0; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.2; + GVAR(turretFireProb) = 0.2; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0; + GVAR(eraHitpoints)[] = { + "HitERA_Front", + "HitERA_Left_1", "HitERA_Left_2", + "HitERA_Right_1", "HitERA_Right_2", + "HitERA_Top_Left_1", "HitERA_Top_Left_2", + "HitERA_Top_Right_1", "HitERA_Top_Right_2" + }; + GVAR(canHaveFireRing) = 1; + }; + class LT_01_base_F: Tank_F { + GVAR(hullDetonationProb) = 0.8; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0.3; + GVAR(hullFireProb) = 0.5; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.7; + GVAR(detonationDuringFireProb) = 0.9; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_back", + "HitSLAT_front" + }; + }; + class LT_01_scout_base_F: LT_01_base_F { + GVAR(hullDetonationProb) = 0; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.8; + GVAR(detonationDuringFireProb) = 0; + }; + class APC_Tracked_03_base_F: Tank_F { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0.2; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0.7; + GVAR(engineFireProb) = 0.7; + GVAR(detonationDuringFireProb) = 0.5; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_top_back", "HitSLAT_top_left", "HitSLAT_top_right", + "HitSLAT_back", "HitSLAT_front" + }; + GVAR(canHaveFireRing) = 1; + }; + class APC_Wheeled_03_base_F: Wheeled_APC_F { + GVAR(hullDetonationProb) = 0.2; + GVAR(turretDetonationProb) = 0; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.7; + GVAR(turretFireProb) = 0; + GVAR(engineFireProb) = 0.7; + GVAR(detonationDuringFireProb) = 0.5; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left_1", "HitSLAT_Left_2", "HitSLAT_Left_3", + "HitSLAT_Right_1", "HitSLAT_Right_2", "HitSLAT_Right_3", + "HitSLAT_back", + "HitSLAT_front" + }; + }; + class MBT_03_base_F: Tank_F { + GVAR(hullDetonationProb) = 0.3; + GVAR(turretDetonationProb) = 0.5; + GVAR(engineDetonationProb) = 0; + GVAR(hullFireProb) = 0.3; + GVAR(turretFireProb) = 0.2; + GVAR(engineFireProb) = 0.5; + GVAR(detonationDuringFireProb) = 0.7; + GVAR(slatHitpoints)[] = { + "HitSLAT_Left", "HitSLAT_Right", "HitSLAT_back", + "HitSLAT_top_left", "HitSLAT_top_right", "HitSLAT_top_back" + }; + GVAR(canHaveFireRing) = 1; + }; +}; + diff --git a/addons/vehicle_damage/README.md b/addons/vehicle_damage/README.md new file mode 100644 index 0000000000..8560222ff2 --- /dev/null +++ b/addons/vehicle_damage/README.md @@ -0,0 +1,4 @@ +ace_vehicle_damage +=================== + +Adds enhanced vehicle damage. Primary goal is to remove global vehicle health and instead opt for a "component based" health system. diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp new file mode 100644 index 0000000000..a7eb519881 --- /dev/null +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -0,0 +1,14 @@ +PREP(abandon); +PREP(addEventHandler); +PREP(handleBail); +PREP(handleVehicleDamage); +PREP(handleCookoff); +PREP(detonate); +PREP(processHit); +PREP(handleDetonation); +PREP(handleDamage); +PREP(knockOut); +PREP(addDamage); +PREP(handleDamageEjectIfDestroyed); +PREP(blowOffTurret); +PREP(medicalDamage); diff --git a/addons/vehicle_damage/XEH_postInit.sqf b/addons/vehicle_damage/XEH_postInit.sqf new file mode 100644 index 0000000000..9784d335ed --- /dev/null +++ b/addons/vehicle_damage/XEH_postInit.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" + +["ace_settingsInitialized", { + TRACE_1("settings init",GVAR(enabled)); + if (GVAR(enabled)) then { + [QGVAR(medicalDamage), LINKFUNC(medicalDamage)] call CBA_fnc_addEventHandler; + + [QGVAR(bailOut), { + params ["_center", "_crewman", "_vehicle"]; + TRACE_3("bailOut",_center,_crewman,_vehicle); + + if (isPlayer _crewman) exitWith {}; + if (!alive _crewman || {!([_crewman] call EFUNC(common,isAwake))}) exitWith {}; + + unassignVehicle _crewman; + _crewman leaveVehicle _vehicle; + doGetOut _crewman; + + private _angle = floor (random 360); + private _dist = (30 + (random 10)); + private _escape = _center getPos [_dist, _angle]; + + _crewman doMove _escape; + _crewman setSpeedMode "FULL"; + }] call CBA_fnc_addEventHandler; + + ["Tank", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + ["Wheeled_APC_F", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + + if (GVAR(enableCarDamage)) then { + ["Car", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + }; + + // Blow off turret effect + // TODO: Add blowing-off-turret effect to vehicles that cook-off but aren't destroyed (no catastrophic explosion) + // The problem is that vehicles are repairable if they haven't been destroyed. So if the turret is gone and vehicle is repaired, how do we handle that? + ["Tank", "Killed", { + if (_this select 3 && random 1 < 0.15) then { + (_this select 0) call FUNC(blowOffTurret); + }; + }, true, [], true] call CBA_fnc_addClassEventHandler; + }; + + // init eject from destroyed vehicle + { + [_x, "init", { + params ["_vehicle"]; + if (!alive _vehicle) exitWith {}; + TRACE_2("ejectIfDestroyed init",_vehicle,typeOf _vehicle); + _vehicle addEventHandler ["HandleDamage", {call FUNC(handleDamageEjectIfDestroyed)}]; + }, true, [], true] call CBA_fnc_addClassEventHandler; + } forEach EJECT_IF_DESTROYED_VEHICLES; +}] call CBA_fnc_addEventHandler; diff --git a/addons/vehicle_damage/XEH_preInit.sqf b/addons/vehicle_damage/XEH_preInit.sqf new file mode 100644 index 0000000000..894773534a --- /dev/null +++ b/addons/vehicle_damage/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/vehicle_damage/XEH_preStart.sqf b/addons/vehicle_damage/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/vehicle_damage/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/vehicle_damage/config.cpp b/addons/vehicle_damage/config.cpp new file mode 100644 index 0000000000..6b4f7cf685 --- /dev/null +++ b/addons/vehicle_damage/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + // ammo/vehicle config defines touch all of these + requiredAddons[] = { "ace_common", "ace_cookoff" }; + author = ECSTRING(common,ACETeam); + authors[] = {"tcvm"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgAmmo.hpp" diff --git a/addons/vehicle_damage/functions/fnc_abandon.sqf b/addons/vehicle_damage/functions/fnc_abandon.sqf new file mode 100644 index 0000000000..83b06a80df --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_abandon.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Forces the AI currently in a vehicle to bail out. + * + * Arguments: + * 0: The vehicle in which to bail out + * + * Return Value: + * None + * + * Example: + * [tank2] call ace_vehicle_damage_fnc_abandon; + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_2("abandon",_vehicle,(crew _vehicle) select {alive _x}); + +if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith {}; // check for API + +[{ + params ["_vehicle"]; + _vehicle allowCrewInImmobile false; + + private _center = getPosASL _vehicle; + TRACE_2("bailing out crew after delay",_vehicle,_center); + { + [QGVAR(bailOut), [_center, _x, _vehicle], _x] call CBA_fnc_targetEvent; + } forEach crew _vehicle; +}, _this, random MAX_CREW_BAILOUT_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/vehicle_damage/functions/fnc_addDamage.sqf b/addons/vehicle_damage/functions/fnc_addDamage.sqf new file mode 100644 index 0000000000..35475bd36c --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_addDamage.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets vehicle damage based on HitIndex. Failing that it falls back to HitPoint name. + * + * Arguments: + * 0: The vehicle + * 1: Hit Index + * 2: Hit Point + * 3: Damage + * 4: Whether or not to cap the damage to maximum part damage (default: True) + * + * Return Value: + * None + * + * Example: + * [vehicle player, 234, "HitHull"] call ace_vehicle_damage_fnc_addDamage + * + * Public: No + */ + +params ["_vehicle", "_hitIndex", "_hitPoint", "_damage", ["_capDamageAtCurret", true]]; + +private _currentDamage = _vehicle getHitPointDamage _hitPoint; +if (_capDamageAtCurret && { _damage < _currentDamage }) exitWith { + TRACE_4("capping damage at current",_capDamageAtCurret,_damage,_currentDamage,_hitPoint); +}; + +TRACE_4("adding damage to vehicle",_vehicle,_hitIndex,_hitPoint,_damage); +if (_hitPoint isEqualTo "#structural") then { + _hitPoint = "hithull"; + _hitIndex = -1; +}; +if (_hitIndex >= 0) then { + _vehicle setHitIndex [_hitIndex, _damage, true]; +} else { + _vehicle setHitPointDamage [_hitPoint, _damage, true]; +}; + +if (_hitPoint == "hitengine" && {_damage > 0.9}) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; +}; diff --git a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf new file mode 100644 index 0000000000..a7e59c75a1 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf @@ -0,0 +1,110 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Adds the event handler to a vehicle. + * + * Arguments: + * 0: The vehicle in which to add the event handler to + * + * Return Value: + * None + * + * Example: + * [tank2] call ace_vehicle_damage_fnc_addEventHandler; + * + * Public: No + */ + +params["_vehicle"]; +TRACE_2("addEventHandler",_vehicle,GVAR(enabled)); + +if !(GVAR(enabled)) exitWith { + #ifdef DEBUG_MODE_FULL + [{ ["Warning: Vehicle Damage not enabled...", 2] call CBA_fnc_notify; }, [], 5] call CBA_fnc_waitAndExecute; + #endif +}; + +private _hitpointHash = [[], nil] call CBA_fnc_hashCreate; +private _vehicleConfig = configOf _vehicle; +private _hitpointsConfig = _vehicleConfig >> "HitPoints"; +private _turretConfig = _vehicleConfig >> "Turrets"; +private _eraHitpoints = [_vehicleConfig >> QGVAR(eraHitpoints), "ARRAY", []] call CBA_fnc_getConfigEntry; +private _slatHitpoints = [_vehicleConfig >> QGVAR(slatHitpoints), "ARRAY", []] call CBA_fnc_getConfigEntry; + +// Add hitpoint names to config for quick lookup +{ + _x params ["_hitpoints", "_type"]; + { + [_hitpointHash, toLowerANSI _x, [_type, _hitpointsConfig >> _x, toLowerANSI _x]] call CBA_fnc_hashSet; + } forEach _hitpoints; +} forEach ALL_HITPOINTS; + +_vehicle setVariable [QGVAR(hitpointHash), _hitpointHash]; + +// gun and turret hitpoints arent hardcoded anymore - dig through config to find correct names +private _iterateThroughConfig = { + params ["_vehicle", "_config", "_iterateThroughConfig", "_hitpointAliases"]; + TRACE_1("checking config",_config); + private _configName = toLowerANSI configName _config; + private _isGun = ([_config >> "isGun", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; + private _isTurret = ([_config >> "isTurret", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; + private _isEra = _configName in _eraHitpoints; + private _isSlat = _configName in _slatHitpoints; + private _isMisc = false; + + // prevent incompatibilites with old mods + if (_configName isEqualTo "hitturret") then { + _isTurret = true; + }; + if (_configName isEqualTo "hitgun") then { + _isGun = true; + }; + + private _hash = _vehicle getVariable QGVAR(hitpointHash); + { + _x params ["_hitType", "_hitPoints"]; + if (_configName in _hitPoints) then { + [_hash, _configName, [_hitType, _config, _configName]] call CBA_fnc_hashSet; + _isMisc = true; + }; + } forEach _hitpointAliases; + + if (_isGun || _isTurret || _isEra || _isSlat || _isMisc) then { + TRACE_6("found gun/turret/era/slat/misc",_isGun,_isTurret,_isEra,_isSlat,_isMisc,_hash); + if (_isGun) then { + [_hash, _configName, ["gun", _config, _configName]] call CBA_fnc_hashSet; + }; + if (_isTurret) then { + [_hash, _configName, ["turret", _config, _configName]] call CBA_fnc_hashSet; + }; + if (_isEra) then { + [_hash, _configName, ["era", _config, _configName]] call CBA_fnc_hashSet; + }; + if (_isSlat) then { + [_hash, _configName, ["slat", _config, _configName]] call CBA_fnc_hashSet; + }; + _vehicle setVariable [QGVAR(hitpointHash), _hash]; + } else { + { + [_vehicle, _x, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; + } forEach configProperties [_config, "isClass _x", true]; + }; +}; + +private _hitpointAliases = [_vehicleConfig >> QGVAR(hitpointAlias), "ARRAY", []] call CBA_fnc_getConfigEntry; +TRACE_1("hitpoint alias",_hitpointAliases); +[_vehicle, _hitpointsConfig, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; +[_vehicle, _turretConfig, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; + +_vehicle allowCrewInImmobile true; +private _eh = _vehicle getVariable [QGVAR(handleDamage), nil]; +if (isNil "_eh") then { + // no clue why, but for some reason this needs to exec'd next frame or else it isnt the last event handler in the system. + // Maybe its overridden somewhere else, but this makes sure it is the last one + [{ + params ["_vehicle"]; + TRACE_1("EH not added yet - added eh now",_vehicle); + private _hd = _vehicle addEventHandler ["HandleDamage", { _this call FUNC(handleDamage) }]; + _vehicle setVariable [QGVAR(handleDamage), _hd]; + }, [_vehicle]] call CBA_fnc_execNextFrame; +}; diff --git a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf new file mode 100644 index 0000000000..818fe6f6ef --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: commy2 + * Blow off turret effect. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * (vehicle player) call ace_vehicle_damage_fnc_blowOffTurret + * + * Public: No + */ + +// Delayed so the object is spawned after the model changes to a wreck +// The sudden change in the model would cause nearby PhysX objects to get stuck +[{ + params ["_vehicle"]; + + (getArray (configOf _vehicle >> QGVAR(turret))) params [["_model", "", [""]], ["_offset", [0, 0, 0], [[]], 3]]; + + if (_model isEqualTo "") exitWith {}; + + private _position = _vehicle modelToWorld _offset; + private _turret = createVehicle [_model, _position, [], 0, "CAN_COLLIDE"]; + + _turret setVectorUp [random 1, random 1, 1]; + _turret setVelocity [random 7, random 7, 8 + random 5]; + + // Add turret to all curators that already own the wreck + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(zeus,addObjects), [[_turret], objectCurators _vehicle]] call CBA_fnc_serverEvent; + }; +}, _this, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf b/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf new file mode 100644 index 0000000000..4e847c2d36 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf @@ -0,0 +1,118 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Calculates whether or not hit penetrated given armour or not. Only enabled with advanced penetration simulation turned on. + * + * Arguments: + * 0: Source of damage + * 1: The vehicle + * 2: Projectile that hit + * 3: Hitpoint damaged + * + * Return Value: + * None + * + * Example: + * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_calculatePenetrationInfo; + * + * Public: No + */ + +params ["_source", "_vehicle", "_projectileData", "_hitpointConfig"]; +_projectileData params ["_projectileType", "_projectileConfig"]; +/* + http://www.longrods.ch/peneq.php + https://www.scribd.com/doc/267210898/57-mm-APFSDS-2-000-m#download + Perforation Calculation of APFSDS: + Tungsten/Depleted Uranium: Rods + P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) * cos^m (theta) * sqrt (Pp / Pt) * e^((-(c0 + c1 * BHNT) * BHNT) / (Pp * Vt^2)) + + Steel Rods + P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) * cos^m (theta) * sqrt (Pp / Pt) * e^((-c * BHNT^k * BHNP^n) / (Pp * Vt^2)) + + Penetration Calculation of Tungsten APFSDS (Used for all penetrators): + P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) sqrt (Pp / Pt) * e^((-(c0 + c1 * BHNT) * BHNT) / (Pp * Vt^2)) + + where: + Penetrator: + D = Diameter of penetrator rod (always 22mm) + L = Total length of penetrator in millimeters (always 950mm) + Lw = Working length of rod in millimeters + Vt = impact velocity in Kilometers/Second + theta = NATO Obliquity angle of Penetration + Pp = Penetrator Density in kg/m^3 + BHNP = Brinell hardness number of penetrator + + Target: + Pt = target density in kg/m^3 (always 7840kg/m^3) + d = plate thickness in millimeters + BHNT = Brinell hardness number of target (always 350) + + Material Data: + Tungsten: + Pp = 19300 + BHNP = N/A + + a = 0.994 + c0 = 134.5 + c1 = -0.148 + + Depleted Uranium: + Pp = 18600 + BHNP = N/A + + a = 0.825 + c0 = 90.0 + c1 = -0.0849 + + Steel: + Pp = 7850 + BHNP = 500 + + a = 1.104 + c = 9874 + k = 0.3598 + n = -0.2342 + + Cofficients: + m = -0.224 + b0 = 0.283 + b1 = 0.0656 +*/ + +private _enabled = ([_hitpointConfig >> QGVAR(enabled), "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; +#define MATERIAL_ARRAY ([[0, 0, 0, 0, 0, 0], "steel", [7850, 500, 1.104, 9874, 0.3598, -0.2342], "tungsten", [19300, 0, 0.994, 134.5, -0.148], "depleted_uranium", [18600, 0, 0.825, 90, -0.0849]]) +private _rodMaterialStr = [_projectileConfig >> QGVAR(material), "STRING", "tungsten"] call CBA_fnc_getConfigEntry; +private _rodMaterialParams = MATERIAL_ARRAY select (1 + MATERIAL_ARRAY find toLowerANSI _rodMaterial); + +if !(_enabled) exitWith { [false, 0, 0, 0, 0] }; +if (_rodMaterialParams isEqualTo [0, 0, 0, 0, 0, 0]) exitWith { [] }; + +private _tanX = 2 * (0.283 * 0.0656 * (1)); +private _tanh = 1 / (((exp _tanX) - 1) / ((exp _tanX) + 1)); +private _cosm = (cos 0) ^ -0.224; +private _lw = 950; // technically this would be something else depending on armour slant but this is a good enough aproximation + +private _aproximateVelocity = 0; + +private _perf_pLw = 0; +private _pen_pLw = 0; +if (_rodMaterialStr isEqualTo "steel") then { + _rodMaterialParams params ["_Pp", "_BHNP", "_a", "_c", "_k", "_n"]; + private _exp = (-_c * 350^_k * _BHNP^_n) / (_Pp * _aproximateVelocity * _aproximateVelocity); + _pen_pLw = _a * _tanh * sqrt (_Pp / 7840) * exp _exp; + _perf_pLw = _pen_pLw * _cosm; +} else { + _rodMaterialParams params ["_Pp", "_BHNP", "_a", "_c0", "_c1"]; + private _exp = (-(_c0 + _c1 * 350) * 350) / (_Pp * _aproximateVelocity * _aproximateVelocity); + _pen_pLw = _a * _tanh * _cosm * sqrt (_Pp / 7840) * exp _exp; + _perf_pLw = _pen_pLw * _cosm; +}; + +private _perforationDistance = _lw * _perf_pLw; +private _penetrationDistance = _lw * _pen_pLw; +private _hitpointEffectiveArmour = [_hitpointConfig >> QGVAR(thickness), "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _hitpointEffectiveSlope = [_hitpointConfig >> QGVAR(slope), "NUMBER", 0] call CBA_fnc_getConfigEntry; +_penetrationDistance = _penetrationDistance * cos (_hitpointEffectiveSlope); + +[_penetrationDistance > _hitpointEffectiveArmour, _penetrationDistance - _hitpointEffectiveArmour, _penetrationDistance, _perforationDistance, _hitpointEffectiveArmour] diff --git a/addons/vehicle_damage/functions/fnc_detonate.sqf b/addons/vehicle_damage/functions/fnc_detonate.sqf new file mode 100644 index 0000000000..7f0dce28c9 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_detonate.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Detonates vehicle ammo and heavily wounds all inside. + * + * Arguments: + * 0: The vehicle + * 1: Person who caused detonation (default: objNull) + * + * Return Value: + * None + * + * Example: + * [tank2] call ace_vehicle_damage_fnc_detonate; + * + * Public: No + */ + +params ["_vehicle", ["_injurer", objNull]]; + +if (((_vehicle call EFUNC(cookoff,getVehicleAmmo)) select 1) > 0) then { + { + [QGVAR(medicalDamage), [_x, _injurer, _injurer], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); +}; + +[QEGVAR(cookoff,detonateAmmunitionServer), [_vehicle, false, _injurer, _injurer]] call CBA_fnc_serverEvent; diff --git a/addons/vehicle_damage/functions/fnc_handleBail.sqf b/addons/vehicle_damage/functions/fnc_handleBail.sqf new file mode 100644 index 0000000000..97aad2cd32 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_handleBail.sqf @@ -0,0 +1,67 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Handles whether or not the crew should bail. + * + * Arguments: + * 0: The vehicle + * 1: Can the vehicle move? + * 2: Can the vehicle shoot? + * + * Return Value: + * None + * + * Example: + * [tank1, false, true] call ace_vehicle_damage_fnc_handleBail + * + * Public: No + */ + +params ["_vehicle", "_canMove", "_canShoot"]; +private _isCar = (_vehicle isKindOf "Car" && { !(_vehicle isKindOf "Wheeled_APC_F") }); + +if (_canMove) then { + _canMove = alive driver _vehicle; +}; + +if (_canShoot) then { + _canShoot = alive gunner _vehicle; +}; + +_vehicle setVariable[QGVAR(canMove), _canMove]; +_vehicle setVariable[QGVAR(canShoot), _canShoot]; + +private _rand = random 1; + +if (_isCar) then { + if !(_canMove) then { + [_vehicle] spawn FUNC(abandon); + LOG_3("[%1] can't move and is bailing and is a car [%2 | %3]",_vehicle,_canMove,_isCar); + }; +} else { + if (!_canMove && !_canShoot ) exitWith { // If you can't move and you can't shoot, you better GTFO + [_vehicle] spawn FUNC(abandon); + LOG_3("[%1] is a sitting duck and is bailing [%2 | %3]",_vehicle,_canMove,_canShoot); + }; + + if (!_canShoot && !_isCar) then { + if (BAILOUT_CHANCE_SHOOT > _rand) then { // 50% chance of bailing out if turret/gun is destroyed + [_vehicle] spawn FUNC(abandon); + LOG_4("[%1] Cannot shoot and is bailing with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + } else { + _vehicle allowFleeing 1; + LOG_4("[%1] Cannot shoot and is fleeing with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + }; + }; + + if !(_canMove) then { + if (BAILOUT_CHANCE_MOVE > _rand) then { // 80% Chance of bailing out if engine is destroyed + [_vehicle] spawn FUNC(abandon); + LOG_4("[%1] Cannot move and is bailing with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + } else { + LOG_4("[%1] Cannot move and is bunkering with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + }; + }; +}; + + diff --git a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf new file mode 100644 index 0000000000..3e7b83ebb6 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -0,0 +1,59 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks hitpoint damage and determines if a vehicle should cookoff. + * + * Arguments: + * 0: The vehicle + * 1: Chance of fire + * 2: Intensity of cookoff + * 3: Person who instigated cookoff (default: objNull) + * 4: Part of vehicle which got hit (default: "") + * 5: Whether or not the vehicle can spawn ring-fire effect (default: false) + * 6: Can Jet (default: true) + * + * Return Value: + * If cooked off + * + * Example: + * [tank2, 0.1, 5] call ace_vehicle_damage_fnc_handleCookoff; + * + * Public: No + */ + +params ["_vehicle", "_chanceOfFire", "_intensity", ["_injurer", objNull], ["_hitPart", ""], ["_canRing", false], ["_canJet", true]]; + +// Ignore if the vehicle is already cooking off +if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith {true}; + +_chanceOfFire = _chanceOfFire * EGVAR(cookoff,probabilityCoef); + +if (_chanceOfFire >= random 1) exitWith { + private _configOf = configOf _vehicle; + private _fireDetonateChance = [_configOf >> QGVAR(detonationDuringFireProb), "number", 0] call CBA_fnc_getConfigEntry; + if (_canRing) then { + _canRing = ([_configOf >> QGVAR(canHaveFireRing), "number", 0] call CBA_fnc_getConfigEntry) == 1; + }; + + if (_canJet) then { + _canJet = ([_configOf >> QEGVAR(cookoff,canHaveFireJet), "number", 1] call CBA_fnc_getConfigEntry) == 1; + }; + + private _delayWithSmoke = _chanceOfFire < random 1; + private _detonateAfterCookoff = (_fireDetonateChance / 4) > random 1; + + private _source = ""; + if (_hitPart == "engine") then { + _source = ["hit_engine_point", "HitPoints"]; + }; + + [QEGVAR(cookOff,cookOffServer), [_vehicle, _intensity, _injurer, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, _canJet]] call CBA_fnc_serverEvent; + LOG_4("Cooking-off [%1] with a chance-of-fire [%2] - Delayed Smoke | Detonate after cookoff [%3 | %4]",_vehicle,_chanceOfFire,_delayWithSmoke,_detonateAfterCookoff); + [_vehicle] spawn FUNC(abandon); + LOG_1("[%1] is on fire is bailing",_vehicle); + + true +}; + +LOG_2("[%1] No Cook-off - Chance of fire [%2]",_vehicle,_chanceOfFire); +false diff --git a/addons/vehicle_damage/functions/fnc_handleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleDamage.sqf new file mode 100644 index 0000000000..51bf1be97d --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_handleDamage.sqf @@ -0,0 +1,94 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Called by "HandleDamage" event handler. Sets up hit array for this frame's damage. + * + * Arguments: + * 0: The vehicle + * 1: Name of selection where unit was damaged (unused) + * 2: Damage taken + * 3: Source unit of damage (unused) + * 4: Projectile that caused damage + * 5: Hit part index of hit point + * 6: Instigator of damage (unused) + * 7: Hit point config name + * + * Return Value: + * Current or maximum damage of part + * + * Example: + * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_handleDamage; + * + * Public: No + */ + +params ["_vehicle", "_hitSelection", "_damage", "", "_projectile", "_hitIndex", "", "_hitPoint"]; +TRACE_6("HandleDamage event inputs",_vehicle,_hitSelection,_damage,_projectile,_hitIndex,_hitPoint); + +private _returnHit = if (_hitSelection isNotEqualTo "") then { + _vehicle getHitIndex _hitIndex +} else { + damage _vehicle +}; + +if !(_projectile in ["ace_ammoExplosion", "ACE_ammoExplosionLarge"]) then { + if (local _vehicle) then { + // set up hit array so we can execute all damage next frame. Always in order of hit done. + private _hitHash = _vehicle getVariable [QGVAR(hitHash), nil]; + if (isNil "_hitHash") then { + _hitHash = [[], nil] call CBA_fnc_hashCreate; + }; + private _currentFrameArray = [_hitHash, diag_frameNo] call CBA_fnc_hashGet; + if (isNil "_currentFrameArray") then { + _currentFrameArray = []; + }; + // if a valid hit, process it + if !((_hitPoint find "#light") >= 0 || { _damage <= 0 }) then { + if (_currentFrameArray isEqualTo []) then { + [{ + params ["_vehicle", "_processingFrame"]; + private _frameHash = _vehicle getVariable [QGVAR(hitHash), nil]; + private _hitArray = [_frameHash, _processingFrame] call CBA_fnc_hashGet; + if (_hitArray isEqualTo []) exitWith {}; + + reverse _hitArray; + TRACE_3("processing data from old frame",diag_frameNo,_processingFrame,_hitArray); + { + _x params ["_vehicle", "_selection", "_damage", "_injurer", "_projectile", "_hitIndex", "", "_hitPoint"]; + + private _returnHit = if (_selection isNotEqualTo "") then { + _vehicle getHitIndex _hitIndex + } else { + damage _vehicle + }; + + private _newDamage = _damage - _returnHit; + if !([_vehicle, _hitPoint, _hitIndex, _injurer, _returnHit, _newDamage, _projectile, _selection] call FUNC(handleVehicleDamage)) exitWith { + LOG_2("cancelling rest of vehicle damage queue ( [%1] items left out of [%2] )",(count (_hitArray#1)) - _forEachIndex,count (_hitArray#1)) + }; + } forEach _hitArray; + + [_frameHash, _processingFrame] call CBA_fnc_hashRem; + + }, [_vehicle, diag_frameNo]] call CBA_fnc_execNextFrame; + }; + _currentFrameArray pushBack _this; + }; + + [_hitHash, diag_frameNo, _currentFrameArray] call CBA_fnc_hashSet; + _vehicle setVariable [QGVAR(hitHash), _hitHash]; + }; +}; + +// damage is never to be handled in-engine. Always handle out of engine with this event handler +// don't return 0 or else old parts will be reset in damage +private _criticalDamageIndex = (CRITICAL_HITPOINTS findIf { _x isEqualTo _hitPoint }) + 1; +if (_criticalDamageIndex > 0) then { + _returnHit = (_returnHit min (CRITICAL_HITPOINTS select _criticalDamageIndex)); +}; + +if (_hitPoint isEqualTo "" && _hitIndex < 0) then { + _returnHit = _returnHit min 0.89; +}; + +_returnHit diff --git a/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf b/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf new file mode 100644 index 0000000000..fdf6f9c6d3 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Ejects crew from destroyed vehicle. + * Should be called from HandleDamage EH. + * + * Arguments: + * HandleDamage EH + * + * Return Value: + * None + * + * Example: + * _this call ace_vehicle_damage_fnc_handleDamageEjectIfDestroyed + * + * Public: No + */ + +params ["_vehicle", "", "", "", "_ammo"]; + +if (alive _vehicle) exitWith {}; + +TRACE_2("ejectIfDestroyed HDEH",typeOf _vehicle,_this); + +if (!IS_EXPLOSIVE_AMMO(_ammo)) then { + { + if (alive _x) then { + moveOut _x; + }; + } forEach crew _vehicle; +}; + +_vehicle removeEventHandler ["HandleDamage", _thisEventHandler]; diff --git a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf new file mode 100644 index 0000000000..8f317323fa --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks hitpoint damage and determines if a vehicle should cookoff. + * + * Arguments: + * 0: The vehicle + * 1: Chance of detonation + * 2: Vehicle ammo array + * 3: How much explosive ammo is inside vehicle + * 4: How much non-explosive ammo inside vehicle + * 5: Person who instigated damage (default: objNull) + * + * Return Value: + * Detonated + * + * Example: + * [tank2, 0.5] call ace_vehicle_damage_fnc_handleDetonation; + * + * Public: No + */ + +params ["_vehicle", "_chanceOfDetonate", "_vehicleAmmo", "_explosiveAmmoCount", "_nonExplosiveAmmoCount", ["_injurer", objNull]]; + +private _isKnockedOut = _explosiveAmmoCount > 0; + +// Ignore if the vehicle is already detonating ammo +if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith {_isKnockedOut}; + +if (_chanceOfDetonate >= random 1) exitWith { + [_vehicle, _injurer, _vehicleAmmo] call FUNC(detonate); + LOG_2("Detonating [%1] with a chance-to-detonate [%2]",_vehicle,_chanceOfDetonate); + _isKnockedOut +}; + +LOG_2("[%1] No Detonation - Chance of detonation [%2]",_vehicle,_chanceOfDetonate); +false diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf new file mode 100644 index 0000000000..02033b83be --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -0,0 +1,99 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Process vehicle hit. + * + * Arguments: + * 0: The vehicle + * 1: The hitpoint which got hit + * 2: The index of what got hit + * 3: The damage that the new part took + * 4: Person who hit vehicle + * 5: Damage before hit + * 6: Damage after hit + * 7: Projectile + * 8: Selection that got hit + * + * Return Value: + * Whether or not to continue handling last frame's damage + * + * Example: + * [ace_vehicle_damage_fnc_handleVehicleDamage, tank1, "Hit_Engine", 12]] call CBA_fnc_execNextFrame + * + * Public: No + */ + +params["_vehicle", "_hitPoint", "_hitIndex", "_injurer", "_oldDamage", "_newDamage", "_projectile", "_selection"]; +TRACE_6("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_injurer,_oldDamage,_newDamage); +if !(alive _vehicle) exitWith { + private _eventHandler = _vehicle getVariable[QGVAR(handleDamage), nil]; + if !(isNil "_eventHandler") then { + _vehicle removeEventHandler ["HandleDamage", _eventHandler]; + }; + LOG_1("Vehicle [%1] no longer alive",_vehicle); + true +}; + +_hitPoint = toLowerANSI _hitPoint; +private _hitpointHash = _vehicle getVariable [QGVAR(hitpointHash), []]; +private _type = if (_hitpointHash isEqualTo []) then { + "exit" +} else { + ([_hitpointHash, _hitPoint] call CBA_fnc_hashGet) select 0 +}; + +if (isNil "_type") then { + _type = "exit"; +}; + +// generic structural damage will be transfered into hull damage for simulation's sake +private _structural = false; +if (_selection isEqualTo "") then { + _type = "hull"; + _hitPoint = "hithull"; + _structural = true; + TRACE_1("structural damage",_selection); + _newDamage = abs _newDamage; +}; + +if (_type isEqualTo "exit") exitWith { LOG_1("No relevant hitpoints hit [%1]. Exiting",_hitPoint); true }; + +// Ignore multiple hits at the same time +private _ignoreHit = false; +private _ignoreBailCheck = false; +private _multHit = _vehicle getVariable [QGVAR(hitTime), nil]; +if (isNil "_multHit") then { + _vehicle setVariable[QGVAR(hitTime), [CBA_missionTime, _injurer, [_hitPoint]]]; +} else { + private _hitPointInOldArray = _hitPoint in (_multHit select 2); + private _withinTime = (CBA_missionTime <= (_multHit select 0) + CONST_TIME) && { _injurer == (_multHit select 1) }; + if (_hitPointInOldArray && _withinTime) then { + _ignoreHit = true; + } else { + // If the hitpoint isnt in the old array then that means that the time expired and a new array should be generated + if !(_hitPointInOldArray) then { + private _oldHitPoints = _multHit select 2; + _oldHitPoints pushBack _hitPoint; + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _injurer, _oldHitPoints]]; + _ignoreBailCheck = true; + } else { + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _injurer, [_hitPoint]]]; + }; + }; +}; +if (_ignoreHit && !_structural) exitWith { + LOG_3("Ignoring multiple hits done to vehicle [%1] by [%2] -- hitpoint [%3].",_vehicle,_injurer,_hitPoint); + true +}; +LOG_3("Processing hit done to vehicle [%1] by [%2] at time [%3].",_vehicle,_injurer,CBA_missionTime); + +if !([_vehicle, _projectile, _hitIndex, _newDamage, [_hitpointHash, _hitPoint] call CBA_fnc_hashGet, _injurer] call FUNC(processHit)) exitWith { false }; + +private _canMove = _vehicle getVariable[QGVAR(canMove), true]; +private _canShoot = _vehicle getVariable[QGVAR(canShoot), true]; + +if !(_ignoreBailCheck) then { + [_vehicle, _canMove, _canShoot] call FUNC(handleBail); +}; + +true diff --git a/addons/vehicle_damage/functions/fnc_knockOut.sqf b/addons/vehicle_damage/functions/fnc_knockOut.sqf new file mode 100644 index 0000000000..5c8d1697a6 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_knockOut.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Knock out vehicle from battle. Destroy all internal hitpoints. + * + * Arguments: + * 0: The vehicle + * + * Return Value: + * None + * + * Example: + * [vehicle player] call ace_vehicle_damage_fnc_knockOut + * + * Public: No + */ + +params ["_vehicle"]; +private _hash = _vehicle getVariable [QGVAR(hitpointHash), nil]; +if (isNil "_hash") exitWith {}; + +[_hash, { + private _hitpointAlias = _value#0; + if (_hitpointAlias isEqualTo "hull") then { + [_vehicle, -1, _key, 0.89] call FUNC(addDamage); + } else { + if (_hitpointAlias in ["fuel", "turret", "gun", "engine"]) then { + if ((0.3 > random 1) || { _hitpointAlias isEqualTo "engine" }) then { + [_vehicle, -1, _key, 1] call FUNC(addDamage); + } else { + private _currentDamage = _vehicle getHitpointDamage _key; + [_vehicle, -1, _key, (_currentDamage + (0.3 max random 1)) min 1] call FUNC(addDamage); + }; + }; + }; +}] call CBA_fnc_hashEachPair; + diff --git a/addons/vehicle_damage/functions/fnc_medicalDamage.sqf b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf new file mode 100644 index 0000000000..c5234cf1c1 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Applies medical damage to a unit. + * + * Arguments: + * 0: Target + * 1: Source + * 2: Instigator + * 3: Guarantee death? (default: false) + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player] call ace_vehicle_damage_fnc_medicalDamage; + * + * Public: No + */ + +params ["_unit", "_source", "_instigator", ["_guaranteeDeath", false]]; + +// Check if unit is invulnerable +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {}; + +if (GETEGVAR(medical,enabled,false)) then { + for "_i" from 0 to floor (4 + random 3) do { + [_unit, random [0, 0.66, 1], selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _instigator] call EFUNC(medical,addDamageToUnit); + }; +} else { + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + random [0, 0.66, 1], true, _source, _instigator]; + } forEach ["HitFace", "HitNeck", "HitHead", "HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody", "HitArms", "HitHands", "HitLegs"]; +}; + +// If guaranteed death is wished +if (_guaranteeDeath && {alive _unit}) then { + [_unit, QGVAR(medicalDamage), _source, _instigator] call EFUNC(common,setDead); +}; diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf new file mode 100644 index 0000000000..2402df7fc2 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -0,0 +1,349 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Process hit by projectile against vehicle and apply appropiate damage to part. + * + * Arguments: + * 0: The vehicle + * 1: Projectile that hit + * 2: Hit index of potentially damaged part + * 3: New damage done to part + * 4: Information about hitpoint + * 5: Person who caused damage + * + * Return Value: + * None + * + * Example: + * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_processHit; + * + * Public: No + */ + +params ["_vehicle", "_projectile", "_hitIndex", "_newDamage", "_hitpointData", "_injurer"]; +_hitpointData params ["_hitArea", "_hitpointConfig", "_hitpointName"]; + +private _return = true; + +if (_newDamage < 0) then { + _newDamage = -_newDamage; +}; + +private _currentPartDamage = _vehicle getHitIndex _hitIndex; +private _nextPartDamage = _currentPartDamage + _newDamage; + +// damage is high enough for immediate destruction +if (_newDamage >= 15) exitWith { + TRACE_2("immediate destruction - high damage",_newDamage,_currentPartDamage); + [_vehicle] call FUNC(knockOut); + [_vehicle, 1] call FUNC(handleDetonation); + // Kill everyone inside for very insane damage + { + [QGVAR(medicalDamage), [_x, _injurer, _injurer, true], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); + _vehicle setDamage 1; + _return = false; + _return +}; + +private _projectileConfig = _projectile call CBA_fnc_getObjectConfig; + +private _warheadTypeStr = getText (_projectileConfig >> "warheadName"); +private _incendiary = [_projectileConfig >> QGVAR(incendiary), "NUMBER", -1] call CBA_fnc_getConfigEntry; +private _warheadType = ["HE", "AP", "HEAT", "TandemHEAT"] find _warheadTypeStr; // numerical index for warhead type for quicker checks. Numbers defined in script_macros.hpp +if (_warheadType < 0) then { + _warheadType = WARHEAD_TYPE_NONE; +}; +if (_incendiary < 0) then { + _incendiary = [0.3, 0.1, 1, 1, 0] select _warheadType; +}; + +private _minDamage = [_hitpointConfig >> "minimalHit", "NUMBER", 0] call CBA_fnc_getConfigEntry; +if (_minDamage < 0) then { + _minDamage = -_minDamage; +}; + +private _ammoEffectiveness = 0; +private _projectileExplosive = [_projectileConfig >> "explosive", "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _indirectHit = [_projectileConfig >> "indirectHit", "NUMBER", 0] call CBA_fnc_getConfigEntry; + +if (_warheadType isEqualTo WARHEAD_TYPE_AP) then { + // change damage based on projectile speed (doesn't do this in vanilla ARMA believe it or not) + if !(isNull _injurer) then { + private _airFriction = [_projectileConfig >> "airFriction", "NUMBER", 0] call CBA_fnc_getConfigEntry; + private _distance = _injurer distance _vehicle; + _newDamage = (1 - _projectileExplosive) * _newDamage * exp(_airFriction * _distance); + }; +}; + +private _penChance = 1; +if (_newDamage < _minDamage) then { + _penChance = _newDamage / _minDamage; + TRACE_5("minimum damage modifying hit",_newDamage,_penChance,abs _minDamage,_warheadTypeStr,_hitArea); +}; + +if (_penChance < random 1) exitWith { + TRACE_1("didn't penetrate",_penChance); + _return +}; + +if (_minDamage == 0) then { + _minDamage = 1; +}; + +if (_warheadType isEqualTo WARHEAD_TYPE_HE) then { + private _modifiedIndirectHit = _indirectHit / 100; + if (_newDamage > _modifiedIndirectHit) then { + _newDamage = _newDamage / 2; + }; + _newDamage = (_newDamage * (_newDamage / _modifiedIndirectHit)) min _newDamage; +}; + +_ammoEffectiveness = if (_warheadType isEqualTo WARHEAD_TYPE_AP) then { + 0.15 max _newDamage +} else { + if (_warheadType isEqualTo WARHEAD_TYPE_HE) then { + (_newDamage / (_minDamage + (_indirectHit / 100)) * 0.2) + } else { + ((_newDamage / _minDamage) * 0.4) min 1 + }; +}; +TRACE_4("ammo effectiveness",_ammoEffectiveness,_newDamage,_minDamage,_warheadTypeStr); + +_incendiary = _incendiary * _ammoEffectiveness; + +private _isCar = (_vehicle isKindOf "Car" && { !(_vehicle isKindOf "Wheeled_APC_F") }); +if (_isCar) then { + _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; +}; + +private _currentVehicleAmmo = _vehicle call EFUNC(cookoff,getVehicleAmmo); +private _chanceOfDetonation = 0; +private _explosiveAmmoCount = 0; +private _nonExplosiveAmmoCount = 0; + +if ((_currentVehicleAmmo select 0) isNotEqualTo []) then { + private _magConfig = configFile >> "CfgMagazines"; + private _ammoConfig = configFile >> "CfgAmmo"; + private _countOfExplodableAmmo = 0; + { + _x params ["_magazineClassname", "_currentAmmoCount"]; + private _initialAmmoCount = getNumber (_magConfig >> _magazineClassname >> "count"); + _chanceOfDetonation = _chanceOfDetonation + (_currentAmmoCount / _initialAmmoCount); + _countOfExplodableAmmo = _countOfExplodableAmmo + 1; + + private _ammoClassname = getText (_magConfig >> _magazineClassname >> "ammo"); + private _explosive = getNumber (_ammoConfig >> _ammoClassname >> "explosive"); + private _hit = getNumber (_ammoConfig >> _ammoClassname >> "hit"); + if (_explosive > 0.5 || _hit > 50) then { + _explosiveAmmoCount = _explosiveAmmoCount + 1; + } else { + _nonExplosiveAmmoCount = _nonExplosiveAmmoCount + 1; + }; + } forEach (_currentVehicleAmmo select 0); + if (_countOfExplodableAmmo != 0) then { + _chanceOfDetonation = _chanceOfDetonation / _countOfExplodableAmmo; + }; +}; +private _chanceToDetonate = 0; +private _chanceOfFire = 0; +private _currentFuel = fuel _vehicle; +private _vehicleConfig = _vehicle call CBA_fnc_getObjectConfig; +switch (_hitArea) do { + case "engine": { + _chanceToDetonate = ([_vehicleConfig >> QGVAR(engineDetonationProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _currentFuel * _penChance; + _chanceOfFire = ([_vehicleConfig >> QGVAR(engineFireProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _currentFuel * _penChance; + + private _cookoffIntensity = 4 * _currentFuel; + TRACE_6("hit engine",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + + if (_isCar) then { + _chanceOfFire = 0; // no cookoff for cars + }; + + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + [_vehicle] call FUNC(knockOut); + }; + + // cap damage at 0.9 to avoid hard coded blow up + _nextPartDamage = (0.9 min _nextPartDamage); + + // fatal engine/drive system damage + if (_nextPartDamage == 0.9 || { 0.8 * _ammoEffectiveness > random 1 }) then { + [_vehicle, _hitIndex, _hitpointName, 0.9 * _penChance] call FUNC(addDamage); + _vehicle setVariable [QGVAR(canMove), false]; + } else { + [_vehicle, _hitIndex, _hitpointName, _nextPartDamage * _penChance] call FUNC(addDamage); + }; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, _hitArea, false] call FUNC(handleCookoff); + }; + case "hull": { + _chanceToDetonate = ([_vehicleConfig >> QGVAR(hullDetonationProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; + _chanceOfFire = ([_vehicleConfig >> QGVAR(hullFireProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; + + private _cookoffIntensity = 1.5 + (_explosiveAmmoCount * _chanceOfFire); + TRACE_6("hit hull",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + + if (_isCar) then { + _chanceOfFire = 0; // no cookoff for cars + }; + + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); + [_vehicle] call FUNC(knockOut); + }; + + private _hash = _vehicle getVariable [QGVAR(hitpointHash), []]; + private _hashKeys = [_hash] call CBA_fnc_hashKeys; + + // 25% chance of jamming turret - 25% of mobility kill - 25% of both - 75% chance of critical hull damage + private _rand = random 1; + TRACE_2("rolling hull damage",_ammoEffectiveness,_rand); + private _partKill = []; + if (_ammoEffectiveness > _rand) then { + _rand = random 1; + TRACE_2("damaged hull part",_ammoEffectiveness,_rand); + switch (true) do { + case (_rand < 0.25): { + [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); + // iterate through all keys and find appropriate turret + [_hash, { + if (_value#0 isEqualTo "turret") then { + _partKill pushBack _key; + }; + }] call CBA_fnc_hashEachPair; + _vehicle setVariable [QGVAR(canShoot), false]; + }; + case (_rand < 0.5): { + [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); + _partKill = _partKill + ENGINE_HITPOINTS#0; + if !(_vehicle isKindOf "Wheeled_APC_F") then { + _partKill = _partKill + TRACK_HITPOINTS#0; + }; + + _vehicle setVariable [QGVAR(canMove), false]; + }; + case (_rand < 0.75): { + [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); + _partKill = _partKill + ENGINE_HITPOINTS#0; + if !(_vehicle isKindOf "Wheeled_APC_F") then { + _partKill = _partKill + TRACK_HITPOINTS#0; + }; + + // iterate through all keys and find appropriate turret + [_hash, { + if (_value#0 isEqualTo "turret") then { + _partKill pushBack _key; + }; + }] call CBA_fnc_hashEachPair; + + _vehicle setVariable [QGVAR(canMove), false]; + _vehicle setVariable [QGVAR(canShoot), false]; + }; + default{}; + }; + }; + + { + TRACE_1("doing damage to hitpoint",_x); + [_vehicle, -1, _x, 1 * _penChance] call FUNC(addDamage); + } forEach _partKill; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", true] call FUNC(handleCookoff); + }; + case "turret": { + _chanceToDetonate = ([_vehicleConfig >> QGVAR(turretDetonationProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _chanceOfDetonation * _penChance; + _chanceOfFire = ([_vehicleConfig >> QGVAR(turretFireProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _chanceOfDetonation * _penChance; + + private _cookoffIntensity = _explosiveAmmoCount * _chanceOfFire; + TRACE_6("hit turret",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + + if (_isCar) then { + _chanceOfFire = 0; // no cookoff for cars + }; + + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + [_vehicle] call FUNC(knockOut); + }; + + if (0.8 * _ammoEffectiveness > random 1) then { + TRACE_1("damaged turret",_ammoEffectiveness * 0.8); + [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); + _vehicle setVariable [QGVAR(canShoot), false]; + }; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", true] call FUNC(handleCookoff); + }; + case "gun": { + TRACE_5("hit gun",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel); + if (0.8 * _ammoEffectiveness > random 1) then { + TRACE_1("damaged gun",_ammoEffectiveness * 0.8); + [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); + _vehicle setVariable [QGVAR(canShoot), false]; + }; + }; + case "track": { + private _damage = (0.1 max (0.1 * _newDamage / _minDamage)) min 1; + [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _damage) * _penChance] call FUNC(addDamage); + TRACE_3("damaged track",_damage,_newDamage,_minDamage); + + if ((_vehicle getHitIndex _hitIndex) >= 1) then { + _vehicle setVariable [QGVAR(canMove), false]; + }; + }; + case "wheel": { + [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _newDamage) * _penChance] call FUNC(addDamage); + TRACE_1("damaged wheel",_newDamage); + }; + case "fuel": { + _chanceOfFire = (_incendiary * _currentFuel * _penChance) / 2; + private _cookoffIntensity = _currentFuel * 5; + TRACE_2("damaged fuel",_chanceOfFire,_cookoffIntensity); + + if (_isCar) then { + _chanceOfFire = 0; // no cookoff for cars + }; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", false] call FUNC(handleCookoff); + + private _damage = (0.1 max (0.1 * _newDamage / _minDamage)) min 1; + [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _damage) * _penChance] call FUNC(addDamage); + }; + case "slat": { + TRACE_2("hit slat",_warheadType,_warheadTypeStr); + // incredibly small chance of AP destroying SLAT + if (_warheadType isEqualTo WARHEAD_TYPE_HEAT || { _warheadType isEqualTo WARHEAD_TYPE_TANDEM } || { _warheadType isEqualTo WARHEAD_TYPE_HE } || { 0.01 > random 1 }) then { + private _currentDamage = _vehicle getHitIndex _hitIndex; + TRACE_3("damaged slat",_warheadType,_warheadTypeStr,_currentDamage); + + if (_warheadType isEqualTo WARHEAD_TYPE_HEAT || { _warheadType isEqualTo WARHEAD_TYPE_TANDEM }) then { + [_vehicle, _hitIndex, _hitpointName, 1] call FUNC(addDamage); + } else { + [_vehicle, _hitIndex, _hitpointName, _currentDamage + (0.5 max random 1)] call FUNC(addDamage); + }; + + if (_currentDamage < 1 && _warheadType isEqualTo WARHEAD_TYPE_HEAT) then { + _return = false; + }; + }; + }; + case "era": { + TRACE_2("hit era",_warheadType,_warheadTypeStr); + if (_warheadType isEqualTo WARHEAD_TYPE_HEAT || { _warheadType isEqualTo WARHEAD_TYPE_TANDEM } || { 0.05 > random 1 }) then { + private _currentDamage = _vehicle getHitIndex _hitIndex; + TRACE_3("damaged era",_warheadType,_warheadTypeStr,_currentDamage); + [_vehicle, _hitIndex, _hitpointName, 1] call FUNC(addDamage); + + // dont process anymore damage if this is HEAT - shouldnt happen anyway but ARMA says it does so you know + if (_currentDamage < 1 && _warheadType isEqualTo WARHEAD_TYPE_HEAT) then { + _return = false; + }; + }; + }; + default { + TRACE_1("hit unknown hitpoint??",_hitArea); + } +}; + +_return diff --git a/addons/vehicle_damage/initSettings.inc.sqf b/addons/vehicle_damage/initSettings.inc.sqf new file mode 100644 index 0000000000..0d3f324af2 --- /dev/null +++ b/addons/vehicle_damage/initSettings.inc.sqf @@ -0,0 +1,19 @@ +[ + QGVAR(enabled), "CHECKBOX", + [ELSTRING(common,Enabled), LSTRING(setting_description)], + LSTRING(category_displayName), + false, // default value + true, // isGlobal + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; + +[ + QGVAR(enableCarDamage), "CHECKBOX", + [LSTRING(carDamage_setting_enable), LSTRING(carDamage_setting_description)], + LSTRING(category_displayName), + false, // default value + true, // isGlobal + {[QGVAR(enableCarDamage), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; diff --git a/addons/vehicle_damage/script_component.hpp b/addons/vehicle_damage/script_component.hpp new file mode 100644 index 0000000000..2cd8e6f36a --- /dev/null +++ b/addons/vehicle_damage/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT vehicle_damage +#define COMPONENT_BEAUTIFIED Vehicle Damage +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_VEHICLE_DAMAGE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_VEHICLE_DAMAGE + #define DEBUG_SETTINGS DEBUG_SETTINGS_VEHICLE_DAMAGE +#endif + +#include "\z\ace\addons\main\script_macros.hpp" +#include "script_macros.hpp" diff --git a/addons/vehicle_damage/script_macros.hpp b/addons/vehicle_damage/script_macros.hpp new file mode 100644 index 0000000000..84f3120ac1 --- /dev/null +++ b/addons/vehicle_damage/script_macros.hpp @@ -0,0 +1,27 @@ +#define CONST_TIME 0.03 +#define MAX_CREW_BAILOUT_TIME 12 + +#define BAILOUT_CHANCE_SHOOT 0.5 +#define BAILOUT_CHANCE_MOVE 0.8 + +#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) + +#define ENGINE_HITPOINTS [["hitengine"], "engine"] +#define HULL_HITPOINTS [["hithull", "hitbody", "#structural"],"hull"] +#define TRACK_HITPOINTS [["hitltrack", "hitrtrack"], "track"] +#define WHEEL_HITPOINTS [["hitlbwheel", "hitlmwheel", "hitlfwheel", "hitlf2wheel", "hitrbwheel", "hitrmwheel", "hitrlwheel", "hitrfwheel", "hitrf2wheel"], "wheel"] +#define FUEL_HITPOINTS [["hitfuel"], "fuel"] +#define ALL_HITPOINTS [ENGINE_HITPOINTS, HULL_HITPOINTS, TRACK_HITPOINTS, WHEEL_HITPOINTS, FUEL_HITPOINTS] + +#define CRITICAL_HITPOINTS ["hithull", 0.89, "hitbody", 0.89, "#structural", 0.89, "hitengine", 0.9] + +#define WARHEAD_TYPE_HE 0 +#define WARHEAD_TYPE_AP 1 +#define WARHEAD_TYPE_HEAT 2 +#define WARHEAD_TYPE_TANDEM 3 +#define WARHEAD_TYPE_NONE 4 + +#define EJECT_IF_DESTROYED_VEHICLES ["Boat_Transport_02_base_F", "Rubber_duck_base_F"] + + +#define CREATE_INCENDIARY_AMMO(ammo,base,inc) class ammo: base { GVAR(incendiary) = inc; } diff --git a/addons/vehicle_damage/stringtable.xml b/addons/vehicle_damage/stringtable.xml new file mode 100644 index 0000000000..4a8fdb4264 --- /dev/null +++ b/addons/vehicle_damage/stringtable.xml @@ -0,0 +1,68 @@ + + + + + ACE Advanced Vehicle Damage + ACE アドバンスドビークルダメージ + ACE Dégâts de véhicule avancés + ACE Erweiterter Fahrzeugsschaden + ACE Danni Veicolo Avanzati + ACE Zaawansowany system uszkodzeń pojazdów + ACE 高级载具损坏 + ACE 고급 차량 피해 + ACE Продвинутое повреждение техники + ACE Daño avanzado de vehículos + + + Enable/Disable advanced vehicle damage + アドバンスドビークルダメージを有効/無効にする + Active les dégâts de véhicule avancés. + Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden + Abilità danni avanzati ai veicoli + Włącz/Wyłącz zaawansowane uszkodzenia pojazdów + 启用/禁用高级载具损坏 + 고급 차량 피해 활성화/비활성화 + Включить/выключить продвинутое повреждение техники + Habilitar/Deshabilitar el daño avanzado de vehículos + + + Enable/Disable advanced car damage (Experimental) + アドバンスド車ダメージを有効/無効にする (試験的) + Active les dégâts avancés sur les voitures (expérimental). + Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden (Experimentell) + Abilita danni avanzati ai veicoli (sperimentale) + Włącz/Wyłącz zaawansowane uszkodzenia w samochodach (eksperymentalne) + 启用/禁用高级车辆损坏(实验性) + 고급 차량 피해(실험용) 활성화/비활성화 + Включить/выключить продвинутое повреждение машин (экспериментальное) + Habilita/Deshabilita el daño avanzado de coche (Experimental) + + + Enable/Disable advanced car damage + アドバンスド車ダメージを有効/無効にする + Dégâts de voiture avancés + Aktiviert/Deaktiviert erweiterten Autoschaden + Abilita danni avanzati alle macchine + Włącz/Wyłącz zaawansowane uszkodzenia w samochodach + 启用/禁用高级车辆损坏 + 고급 차량 피해 활성화/비활성화 + Продвинутое повреждение машин + Habilitar/Deshabilitar daño avanzado de coche (Experimental) + + + Wreck (Turret) + Épave (tourelle) + Restos (torreta) + Rottame (Torretta) + Wrak (wieżyczka) + Обломки (башня) + Wrack (Geschützturm) + Vrak (věž) + Ruínas (torre) + 잔해(포탑) + 残骸 (砲塔) + 殘骸 (砲塔) + 残骸(炮塔) + + + diff --git a/addons/vehiclelock/CfgEventHandlers.hpp b/addons/vehiclelock/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/vehiclelock/CfgEventHandlers.hpp +++ b/addons/vehiclelock/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/vehiclelock/CfgVehicles.hpp b/addons/vehiclelock/CfgVehicles.hpp index 62a6a525fe..3209cf7205 100644 --- a/addons/vehiclelock/CfgVehicles.hpp +++ b/addons/vehiclelock/CfgVehicles.hpp @@ -2,20 +2,20 @@ class ACE_SelfActions { \ class ACE_unlockVehicle { \ displayName = CSTRING(Action_UnLock); \ - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ - statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)), [ARR_2(_target,false)], [_target])] call CBA_fnc_targetEvent); \ + condition = QUOTE(([ARR_2(_player,_target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ + statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)),[ARR_2(_target,false)],[_target])] call CBA_fnc_targetEvent); \ icon = QPATHTOF(ui\key_menuIcon_ca.paa); \ }; \ class ACE_lockVehicle { \ displayName = CSTRING(Action_Lock); \ - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ - statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)), [ARR_2(_target,true)], [_target])] call CBA_fnc_targetEvent); \ + condition = QUOTE(([ARR_2(_player,_target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ + statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)),[ARR_2(_target,true)],[_target])] call CBA_fnc_targetEvent); \ icon = QPATHTOF(ui\key_menuIcon_ca.paa); \ }; \ class ACE_lockpickVehicle { \ displayName = CSTRING(Action_Lockpick); \ - condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ - statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ + condition = QUOTE([ARR_3(_player,_target,'canLockpick')] call FUNC(lockpick)); \ + statement = QUOTE([ARR_3(_player,_target,'startLockpick')] call FUNC(lockpick)); \ }; \ }; \ class ACE_Actions { \ @@ -23,24 +23,24 @@ class ACE_unlockVehicle { \ displayName = CSTRING(Action_UnLock); \ distance = 4; \ - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ - statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)), [ARR_2(_target,false)], [_target])] call CBA_fnc_targetEvent); \ + condition = QUOTE(([ARR_2(_player,_target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ + statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)),[ARR_2(_target,false)],[_target])] call CBA_fnc_targetEvent); \ exceptions[] = {"isNotSwimming"}; \ icon = QPATHTOF(ui\key_menuIcon_ca.paa); \ }; \ class ACE_lockVehicle { \ displayName = CSTRING(Action_Lock); \ distance = 4; \ - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ - statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)), [ARR_2(_target,true)], [_target])] call CBA_fnc_targetEvent); \ + condition = QUOTE(([ARR_2(_player,_target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ + statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)),[ARR_2(_target,true)],[_target])] call CBA_fnc_targetEvent); \ exceptions[] = {"isNotSwimming"}; \ icon = QPATHTOF(ui\key_menuIcon_ca.paa); \ }; \ class ACE_lockpickVehicle { \ displayName = CSTRING(Action_Lockpick); \ distance = 4; \ - condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ - statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ + condition = QUOTE([ARR_3(_player,_target,'canLockpick')] call FUNC(lockpick)); \ + statement = QUOTE([ARR_3(_player,_target,'startLockpick')] call FUNC(lockpick)); \ exceptions[] = {"isNotSwimming"}; \ }; \ }; \ diff --git a/addons/vehiclelock/CfgWeapons.hpp b/addons/vehiclelock/CfgWeapons.hpp index 8c7f7b137a..b2cbdc5848 100644 --- a/addons/vehiclelock/CfgWeapons.hpp +++ b/addons/vehiclelock/CfgWeapons.hpp @@ -11,7 +11,7 @@ class CfgWeapons { picture = QPATHTOF(ui\keyBlack.paa); scope = 2; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 0; + mass = 0.1; }; }; class ACE_key_lockpick: ACE_key_master { diff --git a/addons/vehiclelock/XEH_postInit.sqf b/addons/vehiclelock/XEH_postInit.sqf index 64bd4fd642..d16b47aef5 100644 --- a/addons/vehiclelock/XEH_postInit.sqf +++ b/addons/vehiclelock/XEH_postInit.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" //Add Event Handlers -[QGVAR(setupCustomKey), {_this call FUNC(serverSetupCustomKeyEH)}] call CBA_fnc_addEventHandler; -[QGVAR(setVehicleLock), {_this call FUNC(setVehicleLockEH)}] call CBA_fnc_addEventHandler; +[QGVAR(setupCustomKey), LINKFUNC(serverSetupCustomKeyEH)] call CBA_fnc_addEventHandler; +[QGVAR(setVehicleLock), LINKFUNC(setVehicleLockEH)] call CBA_fnc_addEventHandler; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { TRACE_2("SettingsInitialized eh",GVAR(LockVehicleInventory),GVAR(VehicleStartingLockState)); if (hasInterface && {GVAR(LockVehicleInventory)}) then { - ["CAManBase", "InventoryOpened", {_this call FUNC(onOpenInventory)}] call CBA_fnc_addClassEventHandler; + ["CAManBase", "InventoryOpened", LINKFUNC(onOpenInventory)] call CBA_fnc_addClassEventHandler; }; if (isServer && {GVAR(VehicleStartingLockState) != -1}) then { [{ diff --git a/addons/vehiclelock/XEH_preInit.sqf b/addons/vehiclelock/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/vehiclelock/XEH_preInit.sqf +++ b/addons/vehiclelock/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index e88105e398..4d0f065c06 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Adds a key to a unit that will open a vehicle @@ -23,14 +23,18 @@ if (!params [["_unit", objNull, [objNull]], ["_veh", objNull, [objNull]], ["_use }; TRACE_3("params",_unit,_veh,_useCustom); -if (isNull _unit) exitWith {ERROR("null unit");}; -if (isNull _veh) exitWith {ERROR("null vehicle");}; +if (isNull _unit) exitWith { + ERROR("null unit"); +}; +if (isNull _veh) exitWith { + ERROR("null vehicle"); +}; if (_useCustom) then { private _previousMags = magazinesDetail _unit; _unit addMagazine ["ACE_key_customKeyMagazine", 1]; //addMagazine array has global effects private _newMags = (magazinesDetail _unit) - _previousMags; - if ((count _newMags) == 0) exitWith {ERROR("failed to add magazine (inventory full?)");}; + if (_newMags isEqualTo []) exitWith {ERROR("failed to add magazine (inventory full?)");}; private _keyMagazine = _newMags select 0; TRACE_2("setting up key on server",_veh,_keyMagazine); //Have the server run add the key to the vehicle's key array: diff --git a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf index 5e78e55edb..adf3b2f6ec 100644 --- a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf +++ b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Returns the side specifc key for a vehicle diff --git a/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf b/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf index eb0ecb21a7..08cc150a3c 100644 --- a/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf +++ b/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * For every lockable vehicle, sets the starting lock state to a sane value. diff --git a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf index bda8f67b65..c5f7e0e35a 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Returns if user has a valid key for the vehicle diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index f106216c89..7bb29395f0 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles lockpick functionality. Three different functions: @@ -33,7 +33,10 @@ if ((locked _veh) == 0) exitWith {false}; if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; private _vehLockpickStrength = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; -if (!(_vehLockpickStrength isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; +if !(_vehLockpickStrength isEqualType 0) exitWith { + ERROR("ACE_vehicleLock_LockpickStrength invalid"); + false +}; //-1 indicates unpickable lock if (_vehLockpickStrength < 0) exitWith {false}; @@ -45,7 +48,7 @@ private _condition = { ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} }; -if (!([[_unit, _veh]] call _condition)) exitWith {false}; +if !([[_unit, _veh]] call _condition) exitWith {false}; private _returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; switch (_funcType) do { @@ -53,10 +56,12 @@ switch (_funcType) do { _returnValue = !([_unit, _veh] call FUNC(hasKeyForVehicle)) && {(locked _veh) in [2, 3]}; }; case "startLockpick": { + [QGVAR(startedLockpick), [_veh]] call CBA_fnc_localEvent; [_vehLockpickStrength, [_unit, _veh, "finishLockpick"], {(_this select 0) call FUNC(lockpick)}, {}, (localize LSTRING(Action_LockpickInUse)), _condition, ["isNotInside", "isNotSwimming"]] call EFUNC(common,progressBar); }; case "finishLockpick": { [QGVAR(setVehicleLock), [_veh, false], [_veh]] call CBA_fnc_targetEvent; + [QGVAR(finishedLockpick), [_veh]] call CBA_fnc_localEvent; }; default { ERROR("bad function type"); diff --git a/addons/vehiclelock/functions/fnc_moduleInit.sqf b/addons/vehiclelock/functions/fnc_moduleInit.sqf index 16e81e85ea..4f6fdf118c 100644 --- a/addons/vehiclelock/functions/fnc_moduleInit.sqf +++ b/addons/vehiclelock/functions/fnc_moduleInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Function for setup module. Sets default lockpick strength and default lock state. @@ -12,7 +12,7 @@ * None * * Example: - * [fromModule] call ACE_VehicleLock_fnc_hasKeyForVehicle; + * [fromModule] call ace_vehiclelock_fnc_moduleInit; * * Public: No */ diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index 5aede3f620..a269fbd6e5 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Function for sync module. Assigns keys for all synced vehicles to any players that are synced. @@ -22,7 +22,7 @@ if (!isServer) exitWith {}; params ["_logic", "_syncedObjects", "_activated"]; TRACE_3("params",_logic,_syncedObjects,_activated); -if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; +if (!_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; [{ params ["_syncedObjects"]; diff --git a/addons/vehiclelock/functions/fnc_onOpenInventory.sqf b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf index 92cbe0144d..f8ccc59a0f 100644 --- a/addons/vehiclelock/functions/fnc_onOpenInventory.sqf +++ b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the inventory opening. @@ -37,10 +37,10 @@ if (GVAR(LockVehicleInventory) && //if setting not enabled !isNull (findDisplay 602) }, { - TRACE_1("car display open: closing", _this); + TRACE_1("car display open: closing",_this); (findDisplay 602) closeDisplay 0; [{ - TRACE_1("Opening Player Inventory", _this); + TRACE_1("Opening Player Inventory",_this); ACE_player action ["Gear", objNull]; }, []] call CBA_fnc_execNextFrame; }, []] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf b/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf index 7018e67bcb..7b259adc0d 100644 --- a/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf +++ b/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * On the server: Adds a key (magazineDetail name) to approved keys for a vehicle. diff --git a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf index 8f38d48f37..7b99f093a7 100644 --- a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf +++ b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Sets a vehicle lock state because of a "ace_vehiclelock_setVehicleLock" event @@ -20,5 +20,5 @@ params ["_veh", "_isLocked"]; TRACE_2("params",_veh,_isLocked); private _lockNumber = [0, 2] select _isLocked; -TRACE_2("Setting Lock State", _veh, _lockNumber); +TRACE_2("Setting Lock State",_veh,_lockNumber); _veh lock _lockNumber; diff --git a/addons/vehiclelock/functions/script_component.hpp b/addons/vehiclelock/functions/script_component.hpp deleted file mode 100644 index 0e05142c6e..0000000000 --- a/addons/vehiclelock/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\vehiclelock\script_component.hpp" \ No newline at end of file diff --git a/addons/vehiclelock/initSettings.inc.sqf b/addons/vehiclelock/initSettings.inc.sqf new file mode 100644 index 0000000000..dcb520e7e2 --- /dev/null +++ b/addons/vehiclelock/initSettings.inc.sqf @@ -0,0 +1,27 @@ +[ + QGVAR(defaultLockpickStrength), "SLIDER", + [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], + LSTRING(DisplayName), + [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(lockVehicleInventory), "CHECKBOX", + [LSTRING(LockVehicleInventory_DisplayName), LSTRING(LockVehicleInventory_Description)], + LSTRING(DisplayName), + false, // default value + true, // isGlobal + {[QGVAR(lockVehicleInventory), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleStartingLockState), "LIST", + [LSTRING(VehicleStartingLockState_DisplayName), LSTRING(VehicleStartingLockState_Description)], + LSTRING(DisplayName), + [[-1,0,1,2],[LSTRING(VehicleStartingLockState_AsIs), LSTRING(VehicleStartingLockState_RemoveAmbiguousLockState), LSTRING(VehicleStartingLockState_Locked), LSTRING(VehicleStartingLockState_Unlocked)], 0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(vehicleStartingLockState), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/vehiclelock/initSettings.sqf b/addons/vehiclelock/initSettings.sqf deleted file mode 100644 index 30de8a692c..0000000000 --- a/addons/vehiclelock/initSettings.sqf +++ /dev/null @@ -1,30 +0,0 @@ -// CBA Settings [ADDON: ace_vehicleLock]: - -[ - QGVAR(defaultLockpickStrength), "SLIDER", - [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], - LSTRING(DisplayName), - [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(defaultLockpickStrength), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_settings_fnc_init; - -[ - QGVAR(lockVehicleInventory), "CHECKBOX", - [LSTRING(LockVehicleInventory_DisplayName), LSTRING(LockVehicleInventory_Description)], - LSTRING(DisplayName), - false, // default value - true, // isGlobal - {[QGVAR(lockVehicleInventory), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[ - QGVAR(vehicleStartingLockState), "LIST", - [LSTRING(VehicleStartingLockState_DisplayName), LSTRING(VehicleStartingLockState_Description)], - LSTRING(DisplayName), - [[-1,0,1,2],["str_cfg_envsounds_default", LSTRING(VehicleStartingLockState_AsIs), LSTRING(VehicleStartingLockState_Locked), LSTRING(VehicleStartingLockState_Unlocked)], 0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(vehicleStartingLockState), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; diff --git a/addons/vehiclelock/readme.md b/addons/vehiclelock/readme.md index 64ae01a99c..85923203cb 100644 --- a/addons/vehiclelock/readme.md +++ b/addons/vehiclelock/readme.md @@ -33,8 +33,3 @@ Two key modes (can be used together): #### Public Functions: `[bob, car1, true] call ACE_VehicleLock_fnc_addKeyForVehicle;` - will add a `ACE_key_customKeyMagazine` to bob and program it to work on car1 -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/vehiclelock/stringtable.xml b/addons/vehiclelock/stringtable.xml index 1f34586851..7cfa58d07a 100644 --- a/addons/vehiclelock/stringtable.xml +++ b/addons/vehiclelock/stringtable.xml @@ -11,6 +11,11 @@ ACE Fahrzeugsperre ACE Zamknięcie Pojazdu ACE Блокировка транспорта + ACE Trancar Veículos + ACE Verrouillage véhicule + ACE Zamykání Vozidel + ACE Araç Kilidi + ACE Bloqueo de vehículo Unlock Vehicle @@ -23,10 +28,11 @@ Открыть машину Sblocca il Veicolo Destravar veículo - 車両の鍵を開ける - 차량 잠금열기 + 車両を解錠 + 차량 잠금해제 载具解锁 載具解鎖 + Araç Kilidini Aç Lock Vehicle @@ -43,12 +49,13 @@ 차량 잠그기 载具上锁 載具上鎖 + Aracı Kilitle Lockpick Vehicle Fahrzeug knacken Forzar vehículo - Crocheter le véhicule + Crocheter la serrure Otwórz zamek Vypáčit vozidlo Jármű feltörése @@ -59,28 +66,30 @@ 차량 문따기 解锁载具 解鎖載具 + Aracı Maymuncukla Picking Lock... Schloss knacken... Forzando cerradura... - Crochetage... + Crochetage de la serrure... Otwieranie zamka... Páčim vozidlo... Zár feltörése... Взламываем замок... - Scassino il veicolo... + Scassinando il veicolo... Usando Mixa... 鍵をこじ開けている・・・ - 문따는중... - 解锁中... + 문따는 중... + 正在开锁... 解鎖中... + Maymuncuklanıyor... A custom key that will open a specific vehicle. Ein Schlüssel der ein bestimmtes Fahrzeug aufschließt. Una llave concreta abrirá un vehículo concreto. - Une clé propre à un seul véhicule. + Une clé personnalisée qui ouvrira un véhicule spécifique. Unikatowy klucz, który otworzy konkretny pojazd. Vlastní klíč, který otevře konkrétní vozidlo. Egy egyedi kulcs, ami egy meghatározott járművet nyit ki. @@ -112,23 +121,23 @@ A lockpick set that can pick the locks of most vehicles. Ein Dietrich der die meisten Fahrzeugschlösser knacken kann. Un set de ganzúas que puede abrir las cerraduras de la mayoría vehículos. - Un crochet qui ouvrira la plupart des véhicules. + Un set de crochetage permettant de forcer la plupart des serrures de véhicules. Zestaw wytrychów, dzięki któremu można otworzyć zamki w większości pojazdów. Sada paklíčů, která dokáže odemknout zámky u většiny vozidel. Egy tolvajkulcs-készlet, mely a legtöbb jármű zárjait fel tudja törni. Набор отмычек, которым можно взломать почти любую машину. - Un grimardello per forzare la maggior parte dei veicoli + Un grimardello per forzare la maggior parte dei veicoli. Um set de chave mixas que pode abrir a maioria dos veículos. ピッキング ツールでは多くの車両をこじ開けられます。 거의 모든 차량을 열 수 있게 해주는 해정도구 모음입니다. - 一组解锁钥匙 (可解锁大部份载具) + 一组解锁钥匙(可解锁大部份载具) 一組解鎖鑰匙 (可解鎖大部份載具) A key that should open most WEST vehicles. Ein Schlüssel der die meisten westlichen Fahrzeuge öffnen sollte. Una llave que abrirá la mayoría de vehículos occidentales. - Une clé qui ouvrira la plupart des véhicules OUEST. + Une clé qui devrait ouvrir la plupart des véhicules OUEST. Klucz, który powinien otworzyć większość pojazdów ZACHODU. Klíč který by měl otevřít většinou Západních vozidel. Egy kulcs, ami a NYUGAT egységeinek legtöbb járművét ki tudja nyitni. @@ -136,56 +145,56 @@ Una chiave che apre la maggior parte dei veicoli occidentali Uma chave que abre a maioria dos veículos ocidentais このキーは多くの同盟軍車両を開けられます。 - 거의 모든 서방진영 차량을 여는 열쇠입니다. - 一组解锁钥匙 (可解锁大部份蓝方载具) + 거의 모든 청군 진영 차량을 여는 열쇠입니다. + 一组解锁钥匙(可解锁大部份蓝方载具) 一組解鎖鑰匙 (可解鎖大部份藍方載具) A key that should open most EAST vehicle. Ein Schlüssel der die meisten östlichen Fahrzeuge öffnen sollte. Una llave que abrirá la mayoría de vehículos orientales. - Une clé qui ouvrira la plupart des véhicules EST. + Une clé qui devrait ouvrir la plupart des véhicules EST. Klucz, który powinien otworzyć większość pojazdów WSCHODU. Egy kulcs, ami a KELET egységeinek legtöbb járművét ki tudja nyitni. Klíč který by měl otevřít vetšinu Východních vozidel. Ключ для открытия большинства машин Синих. - Una chaive che apre la maggior parte dei veicoli orientali + Una chiave che apre la maggior parte dei veicoli orientali Uma chave que abre a maioria dos veículos orientais このキーは多くのOPFOR軍車両を開けられます。 - 거의 모든 동방진영 차량을 여는 열쇠입니다. - 一组解锁钥匙 (可解锁大部份红方载具) + 거의 모든 대항군 진영 차량을 여는 열쇠입니다. + 一组解锁钥匙(可解锁大部份红方载具) 一組解鎖鑰匙 (可解鎖大部份紅方載具) A key that should open most INDEP vehicle. Ein Schlüssel der die meisten Fahrzeuge der Aufständischen öffnen sollte. Una llave que abrirá la mayoría de vehículos independientes. - Une clé qui ouvrira la plupart des véhicules INDEP. + Une clé qui devrait ouvrir la plupart des véhicules INDEP. Klucz, który powinien otworzyć większość pojazdów INDFOR. Egy kulcs, ami a FÜGGETLEN egységek legtöbb járművét ki tudja nyitni. Klíč který by měl otevřít většinu Nezávislých vozidel. Ключ для открытия большинства машин Независимых. - Una chaive che apre la maggior parte dei veicoli degli indipendenti + Una chiave che apre la maggior parte dei veicoli degli indipendenti. Uma chave que abre a maioria dos veículos independentes このキーは多くの独立軍車両を開けられます。 - 거의 모든 중립진영 차량을 여는 열쇠입니다. - 一组解锁钥匙 (可解锁大部份独立方载具) + 거의 모든 무소속군 진영 차량을 여는 열쇠입니다. + 一组解锁钥匙(可解锁大部份独立方载具) 一組解鎖鑰匙 (可解鎖大部份獨立方載具) A key that should open most CIV vehicle. Ein Schlüssel der die meisten zivilen Fahrzeuge öffnen sollte. Una llave que abrirá la mayoría de vehículos civiles. - Une clé qui ouvrira la plupart des véhicules CIV. + Une clé qui devrait ouvrir la plupart des véhicules CIV. Klucz, który powinien otworzyć większość pojazdów CYWILNYCH. Klíč který by měl otevřít většinu Civilních vozidel. Egy kulcs, ami a CIVIL járművek többségét ki tudja nyitni. Ключ для открытия большинства машин Гражданских. - Una chaive che apr ela maggior parte dei veicoli civili + Una chiave che apre la maggior parte dei veicoli civili. Uma chave que abre a maioria dos veículos civis. このキーは多くの市民車両を開けられます。 거의 모든 민간인 차량을 여는 열쇠입니다 - 一组解锁钥匙 (可解锁大部份平民载具) + 一组解锁钥匙(可解锁大部份平民载具) 一組解鎖鑰匙 (可解鎖大部份平民載具) @@ -215,7 +224,7 @@ Jármű rakodótér zárás Закрывать инвентарь транспорта Blocca Inventario Veicolo - 施錠されている車両のインベントリ + 車両インベントリをロックする 차량 소지품 잠금 上锁载具的车箱 上鎖載具的車箱 @@ -227,12 +236,12 @@ Sperrt das Inventar von gesperrten Fahrzeugen Zamknout inventář u zamčených vozidel Bloqueia o inventário de veículos fechados - Verrouille l'inventaire de véhicule fermés à clé + Verrouille l'inventaire des véhicules fermés à clé. Bezárja a zárt járművek rakterét is Закрывать инвентарь транспорта, если транспорт закрыт - Blocca l'inventario di un veicolo bloccato - 施錠されている車両の開けないインベントリ - 잠긴 차량의 소지품을 뒤지지못하게 합니다. + Blocca l'inventario di un veicolo bloccato. + 施錠された車両のインベントリをロックします + 잠긴 차량의 소지품을 뒤지지 못하게 합니다. 上锁载具的车箱,使玩家不能拿取/查看载具内的装备 上鎖載具的車箱,使玩家不能拿取/查看載具內的裝備 @@ -243,31 +252,43 @@ Fahrzeuge spawnen gesperrt Počáteční stav zámku vozidla Estado inicial da fechadura dos veículos - Etat du verrouillage du véhicule au démarrage + État initial du verrouillage Jármű kezdő zár-állapot Начальное состояние замков Stato Iniziale del Blocco per Veicoli - 開始時における車両の鍵の状態 - 시작시 차량 잠금 상태 + 開始時の車両の鍵の状態 + 시작 시 차량 잠금 상태 载具初始上锁状态 載具初始上鎖狀態 Set lock state for all vehicles (removes ambiguous lock states) - Ustawia początkowy stan blokady dla wszystkich pojazdów (usuwa dwuznaczne stany blokady) + Ustawia początkowy stan blokady dla wszystkich pojazdów (usuwa niejednoznaczny stan blokady) Establece el estado de cierre para todos los vehículos (elimina estados de cierre ambiguos) Setze Sperrstatus für alle Fahrzeuge (entfernt unklare Sperrzustände) Nastavit stav zámku u všech vozidel (odstraňuje nejednoznačné stavy zámků) Definir estados de fechadura para todos os veículos (remove estados de fechadura ambíguos) - Défini l'état de vérrouillage pour tous les véhicules (supprime les vérrouillage ambigue) + Définit l'état de verrouillage pour tous les véhicules (supprime les états de verrouillage ambigus). Beállítja a zár-állapotot az összes járműhöz (eltávolítja az azonosíthatatlan zárállapotokat) Устанавливает начальное состояние замков всех транспортных средств (устраняет неоднозначные состояния) Imposta lo stato di blocco per tutti i veicoli (rimuove stati di blocco ambigui) 全車両へ鍵の状態を設定します。(あいまいな鍵の状態を削除) - 모든 차량의 잠금 상태를 정합니다. (애매한 잠금 상태는 모두 없앱니다.) - 设定所有载具的初始上锁状态 (移除不明确的锁定状态) + 모든 차량의 잠금 상태를 정합니다. (불분명한 잠금 상태는 모두 없앱니다.) + 设定所有载具的初始上锁状态(移除不明确的锁定状态) 設定所有載具的初始上鎖狀態 (移除不明確的鎖定狀態) + + Remove Ambiguous Lock State + Eliminar estado de bloqueo ambiguo + Rimuovi stati di blocco ambigui + Supprimer les états de verrouillage ambigus + Устранить неоднозначные состояния замков + Usuń niejednoznaczny stan blokady + あいまいな鍵の状態を削除 + Unklaren Sperrzustand entfernen + 移除不明确的上锁状态 + 불분명한 잠금상태 제거 + As Is Jak jest @@ -275,7 +296,7 @@ Unverändert Jak je Como está - Pas de changement + Tel quel Úgy-ahogy Как есть Com'è @@ -295,7 +316,7 @@ Zárva Закрыт Bloccato - 施錠ずみ + 施錠済 잠김 上锁 上鎖 @@ -311,7 +332,7 @@ Nyitva Открыт Sbloccato - 開錠ずみ + 解錠済 열림 解锁 解鎖 @@ -323,14 +344,15 @@ Standard-Pick-Stärke Výchozí síla páčidla Durabilidade padrão da chave micha - Force de crochetage par défaut + Difficulté par défaut du crochetage Alapértelmezett zártörő-erősség - Сила отмычки по-умолчанию - Durabilità Default del Grimaldello - ピッキング ツールの能力設定 + Сила отмычки по умолчанию + Durabilità Predefinita del Grimaldello + Lockpickの能力設定 기본 해정도구 설정 预设开锁能力 預設開鎖能力 + Varsayılan Maymuncuk Gücü Default Time to lockpick (in seconds). Default: 10 @@ -339,13 +361,13 @@ Standardzeit um ein Schloss zu knacken (in Sekunden). Standard: 10 Čas k vypáčení zámku (v sekundách). Výchozí: 10 Tempo padrão para forçar a fechadura (em segundos). Padrão: 10 - Temps par défaut pour le crochetage + Temps par défaut requis pour crocheter une serrure. Valeur par défaut : 10 secondes. Alapértelmezett idő a zárfeltöréshez (másodpercben). Alapértelmezett: 10 - Время для взлома замка отмычкой (в секундах). По-умолчанию: 10 - Tempo Default richiesto per forzare serrature (in secondi). Default: 10 - ピッキング ツールを使った作業時間の標準設定。(秒) 標準: 10 + Время для взлома замка отмычкой (в секундах). По умолчанию: 10 + Tempo Default richiesto per forzare serrature (in secondi). Predefinito: 10 + Lockpickを使った作業の所要時間の標準設定。 (秒単位) デフォルト: 10 해정을 위해 들이는 기본시간입니다(초 단위). 기본설정: 10 - 开锁时间(秒)。预设:10 + 开锁时间(秒)。预设:10 開鎖時間(秒)。預設:10 @@ -355,11 +377,11 @@ Einstellungen für Pick-Stärke und anfänglichen Fahrzeugsperrzustand. Entfernt unklare Sperrzustände. Nastavení síly vypáčení a počáteční stav zámku vozidla. Odstraňuje nejednoznačné stavy zámků. Definições para a durabilidade da chave micha e estado inicial da fechadura do veículo. Remove estados de fechadura ambíguas - Paramètres pour le crochetage et état inital des véhicules. Supprime les états de verrouillage ambigue. + Réglage de la difficulté du crochetage et de l'état de verrouillage initial des véhicules. Supprime les états de verrouillage ambigus. Beállítások a zártörő erősségére és alapértelmezett zár-állapotra a járműveken. Eltávolítja az azonosíthatatlan zár-állapotokat. Настройки силы отмычек и начальное состояние замков транспорта. Устраняет неоднозначные состояния замков. Impostazioni per resistenza iniziale delle serrature e stato di blocco dei veicoli. Rimuove stati di blocco ambigui. - ピッキング ツールの能力と車両の鍵の初期状態を設定できます。あいまいな鍵の状態を削除します。 + Lockpickの能力と車両の鍵の初期状態を設定できます。あいまいな鍵の状態を削除します。 해정도구 설정과 시작시 차량의 잠금 상태 그리고 애매한 잠금 상태를 지우는 설정입니다. 设定开锁能力和初始载具上锁状态。移除不明确的锁定状态 設定開鎖能力和初始載具上鎖狀態。移除不明確的鎖定狀態 @@ -381,18 +403,18 @@ 指定載具鑰匙 - Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Only valid for objects present at mission start. + Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Only valid for objects present at mission start. Zsynchronizuj z pojazdami i graczami. Rozda klucze dla graczy dla każdego zsynchronizowanego pojazdu. Działa tylko na pojazdy obecne na misji od samego początku (postawione w edytorze). Sincronizar con vehiculos y jugadores. Distribuirá llaves personalizadas a los jugadores para todos los vehículos sincronizados. Solo valido para objetos presentes al inicio de la mision. Synchronisiere mit Fahrzeugen und Spielern. Wird eigene Schlüssel an Spieler für jedes synchronisierte Fahrzeuge aushändigen. Nur gültig für am Missionsstart existierende Fahrzeuge. Synchronizuj s vozidly a hráči. Hráč dostane klíč ke každému synchonizovanému vozidlu. Platné pouze pro objekty přítomné na začátku mise. Sincronizar com veículos e jogadores. Irá distribuir chaves personalizadas para os jogadores para cada veículo sincronizado. Só é válido para objetos presentes no início da missão. - Synchronise avec les véhicules et les joueurs. Distribue les clés aux joueurs pour chaque véhicule synchronisé. Uniquement valide pour les objects présent au démarrage. + Synchroniser avec les véhicules et les joueurs. Remettra des clés personnalisées aux joueurs pour chaque véhicule synchronisé.\nValable uniquement pour les objets présents dès le début de la mission. Szinkronizál a járművekkel és játékosokkal. Egyedi kulcsokat oszt ki a játékosoknak minden szinkronizált járműhöz. Csak a küldetés indításakor jelenlévő járművekhez érvényes. Синхронизируйте с транспортом и игроком. Это выдаст игроку ключи от всех синхронизированных транспортных средств. Работает только для объектов, присутствующих на старте миссии Sincronizza con veicoli e giocatori. Distribuirà chiavi ai giocatori per ogni veicolo sincronizzato. Valido solo per oggetti presenti ad inizio missione. - 車両とプレイヤへ同期します。プレイヤへ同期された車両のカスタム キーを作ります。これはミッション開始時に作成されたオブジェクトでのみ有効です。 - 차량과 플레이어에게 동기화됩니다. 동기화된 차량은 플레이어에게 열쇠를 지급합니다. 오직 미션 시작시에 생긴 물체들만 유효합니다. + 車両とプレイヤーへ同期します。プレイヤーへ同期された車両のカスタム キーを作ります。これはミッション開始時に作成されたオブジェクトでのみ有効です。 + 차량과 플레이어에게 동기화됩니다. 동기화된 차량은 플레이어에게 열쇠를 지급합니다. 오직 미션 시작 시에 생긴 물체들만 유효합니다. 可同步在载具与玩家身上。将使被同步的玩家掌握其他被同步载具的钥匙。此模块只会在任务刚开始时触发。 可同步在載具與玩家身上。將使被同步的玩家掌握其他被同步載具的鑰匙。此模塊只會在任務剛開始時觸發 diff --git a/addons/vehicles/CfgEventHandlers.hpp b/addons/vehicles/CfgEventHandlers.hpp index fb16727899..99633dc28d 100644 --- a/addons/vehicles/CfgEventHandlers.hpp +++ b/addons/vehicles/CfgEventHandlers.hpp @@ -1,24 +1,24 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_Engine_EventHandlers { - class Car { + class AllVehicles { class ACE_EngineStartDelay { clientEngine = QUOTE(if (local driver (_this select 0)) then {_this call FUNC(startEngine)};); }; diff --git a/addons/vehicles/CfgVehicles.hpp b/addons/vehicles/CfgVehicles.hpp index ff79ed26f4..3dcb8ed490 100644 --- a/addons/vehicles/CfgVehicles.hpp +++ b/addons/vehicles/CfgVehicles.hpp @@ -16,7 +16,9 @@ class CfgVehicles { class CommanderOptics;//: NewTurret {}; }; - class Car: LandVehicle {}; + class Car: LandVehicle { + GVAR(engineStartDelay) = 1.3; + }; class Tank: LandVehicle { class Turrets { @@ -67,15 +69,15 @@ class CfgVehicles { }; class APC_Tracked_01_base_F: Tank_F { - fuelCapacity = 500 * FUEL_FACTOR; + fuelCapacity = QUOTE(500 * FUEL_FACTOR); }; class APC_Tracked_02_base_F: Tank_F { - fuelCapacity = 600 * FUEL_FACTOR; // NO FUCKING DATA + fuelCapacity = QUOTE(600 * FUEL_FACTOR); // NO FUCKING DATA }; class APC_Tracked_03_base_F: Tank_F { - fuelCapacity = 660 * FUEL_FACTOR; + fuelCapacity = QUOTE(660 * FUEL_FACTOR); class Turrets: Turrets { class MainTurret: MainTurret { weapons[] = {"autocannon_30mm","ACE_LMG_coax_L94A1_mem3"}; // Base 1.82: "autocannon_30mm","LMG_coax" @@ -84,7 +86,7 @@ class CfgVehicles { }; class MBT_03_base_F: Tank_F { - fuelCapacity = 550 * FUEL_FACTOR; + fuelCapacity = QUOTE(550 * FUEL_FACTOR); class Turrets: Turrets { class MainTurret: MainTurret { weapons[] = {"cannon_120mm_long","ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm_long","LMG_coax" @@ -93,7 +95,7 @@ class CfgVehicles { }; class MBT_01_base_F: Tank_F { - fuelCapacity = 500 * FUEL_FACTOR; + fuelCapacity = QUOTE(500 * FUEL_FACTOR); class Turrets: Turrets { class MainTurret: MainTurret { weapons[] = {"cannon_120mm", "ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm","LMG_coax" @@ -110,14 +112,14 @@ class CfgVehicles { }; }; }; - - - + + + class MBT_02_base_F: Tank_F { - fuelCapacity = 600 * FUEL_FACTOR; // again, couldn't find proper data + fuelCapacity = QUOTE(600 * FUEL_FACTOR); // again, couldn't find proper data }; - + // Change boat minigun ammo to 7.62 class Ship_F: Ship {}; @@ -146,15 +148,15 @@ class CfgVehicles { class Truck_F: Car_F {}; class MRAP_01_base_F: Car_F { - fuelCapacity = 510 * FUEL_FACTOR; + fuelCapacity = QUOTE(510 * FUEL_FACTOR); }; class MRAP_02_base_F: Car_F { - fuelCapacity = 500 * FUEL_FACTOR; // couldn't find any data for the punisher + fuelCapacity = QUOTE(500 * FUEL_FACTOR); // couldn't find any data for the punisher }; - + class MRAP_03_base_F: Car_F { - fuelCapacity = 860 * FUEL_FACTOR; + fuelCapacity = QUOTE(860 * FUEL_FACTOR); smokeLauncherGrenadeCount = 3; smokeLauncherAngle = 80; class Turrets: Turrets { @@ -185,19 +187,19 @@ class CfgVehicles { }; class Truck_01_base_F: Truck_F { - fuelCapacity = 644 * FUEL_FACTOR; + fuelCapacity = QUOTE(644 * FUEL_FACTOR); }; class Truck_02_base_F: Truck_F { - fuelCapacity = 1100 * FUEL_FACTOR; + fuelCapacity = QUOTE(1100 * FUEL_FACTOR); }; class Truck_03_base_F: Truck_F { - fuelCapacity = 900 * FUEL_FACTOR; // NO. FUCKING. DATA. + fuelCapacity = QUOTE(900 * FUEL_FACTOR); // NO. FUCKING. DATA. }; class APC_Wheeled_01_base_F: Wheeled_APC_F { - fuelCapacity = 800 * FUEL_FACTOR; + fuelCapacity = QUOTE(800 * FUEL_FACTOR); class Turrets: Turrets { class MainTurret: MainTurret {}; }; @@ -212,11 +214,11 @@ class CfgVehicles { }; class APC_Wheeled_02_base_F: Wheeled_APC_F { - fuelCapacity = 700 * FUEL_FACTOR; + fuelCapacity = QUOTE(700 * FUEL_FACTOR); }; class APC_Wheeled_03_base_F: Wheeled_APC_F { - fuelCapacity = 700 * FUEL_FACTOR; + fuelCapacity = QUOTE(700 * FUEL_FACTOR); class Turrets: Turrets { class MainTurret: MainTurret {}; }; @@ -231,14 +233,14 @@ class CfgVehicles { }; // Tanks DLC Wiesel 2 - class LT_01_base_F : Tank_F { - class Turrets : Turrets { - class MainTurret : MainTurret {}; + class LT_01_base_F: Tank_F { + class Turrets: Turrets { + class MainTurret: MainTurret {}; }; }; - class LT_01_cannon_base_F : LT_01_base_F { - class Turrets : Turrets { - class MainTurret : MainTurret { + class LT_01_cannon_base_F: LT_01_base_F { + class Turrets: Turrets { + class MainTurret: MainTurret { weapons[] = { "SmokeLauncher", "ACE_LMG_coax_ext_MG3", @@ -249,8 +251,8 @@ class CfgVehicles { }; // Tanks DLC Rooikat 120 - class AFV_Wheeled_01_base_F : wheeled_APC_F { - class Turrets : Turrets { + class AFV_Wheeled_01_base_F: Wheeled_APC_F { + class Turrets: Turrets { class MainTurret: MainTurret { weapons[] = {"ACE_cannon_120mm_GT12","ACE_LMG_coax_DenelMG4"}; magazines[] = {"12Rnd_120mm_APFSDS_shells_Tracer_Red","8Rnd_120mm_HE_shells_Tracer_Red","8Rnd_120mm_HEAT_MP_T_Red","4Rnd_120mm_LG_cannon_missiles","200Rnd_762x51_Belt_T_Red","200Rnd_762x51_Belt_T_Red","200Rnd_762x51_Belt_T_Red","200Rnd_762x51_Belt_T_Red"}; @@ -259,19 +261,19 @@ class CfgVehicles { }; // Tanks DLC Armata - class MBT_04_base_F : Tank_F { - class Turrets : Turrets { - class MainTurret : MainTurret { - class Turrets : Turrets { + class MBT_04_base_F: Tank_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + class Turrets: Turrets { class CommanderOptics: CommanderOptics {}; }; }; }; }; - class MBT_04_cannon_base_F : MBT_04_base_F { - class Turrets : Turrets { - class MainTurret : MainTurret { - class Turrets : Turrets { + class MBT_04_cannon_base_F: MBT_04_base_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + class Turrets: Turrets { class CommanderOptics: CommanderOptics { weapons[] = {"ACE_HMG_127_KORD","SmokeLauncher"}; }; diff --git a/addons/vehicles/CfgWeapons.hpp b/addons/vehicles/CfgWeapons.hpp index 4c1c4575b9..2fbe4e5246 100644 --- a/addons/vehicles/CfgWeapons.hpp +++ b/addons/vehicles/CfgWeapons.hpp @@ -10,7 +10,7 @@ class CfgWeapons { class ACE_LMG_coax_MAG58_mem3: LMG_coax {}; class ACE_LMG_coax_ext_MAG58: LMG_coax_ext {}; class ACE_LMG_coax_ext_MG3: LMG_coax_ext {}; - class ACE_LMG_coax_DenelMG4 : LMG_coax {}; + class ACE_LMG_coax_DenelMG4: LMG_coax {}; class LMG_Minigun: LMG_RCWS { // Add the following: "2000Rnd_762x51_Belt_T_Green","2000Rnd_762x51_Belt_T_Red","2000Rnd_762x51_Belt_T_Yellow","5000Rnd_762x51_Belt","5000Rnd_762x51_Yellow_Belt" @@ -28,16 +28,16 @@ class CfgWeapons { }; }; - class HMG_127_APC : HMG_127 {}; - class ACE_HMG_127_KORD : HMG_127_APC {}; + class HMG_127_APC: HMG_127 {}; + class ACE_HMG_127_KORD: HMG_127_APC {}; // Tanks DLC: weapons for Wiesel and Rooikat class CannonCore; - class autocannon_Base_F : CannonCore {}; - class cannon_20mm : autocannon_Base_F {}; - class ACE_cannon_20mm_Rh202 : cannon_20mm {}; + class autocannon_Base_F: CannonCore {}; + class cannon_20mm: autocannon_Base_F {}; + class ACE_cannon_20mm_Rh202: cannon_20mm {}; - class cannon_120mm : CannonCore {}; - class ACE_cannon_120mm_GT12 : cannon_120mm {}; + class cannon_120mm: CannonCore {}; + class ACE_cannon_120mm_GT12: cannon_120mm {}; }; diff --git a/addons/vehicles/README.md b/addons/vehicles/README.md index fe26f297df..a84b558a67 100644 --- a/addons/vehicles/README.md +++ b/addons/vehicles/README.md @@ -2,11 +2,3 @@ ace_vehicles ============ Various tweaks to vehicle and vehicle weapon configs. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [KoffeinFlummi](https://github.com/KoffeinFlummi) -- [commy2](https://github.com/commy2) diff --git a/addons/vehicles/XEH_PREP.hpp b/addons/vehicles/XEH_PREP.hpp index ec2e27a94e..3b446300f7 100644 --- a/addons/vehicles/XEH_PREP.hpp +++ b/addons/vehicles/XEH_PREP.hpp @@ -1,3 +1,5 @@ - +PREP(autoThrottle); PREP(speedLimiter); PREP(startEngine); +PREP(setVehicleStartDelay); +PREP(toggleSpeedControl); diff --git a/addons/vehicles/XEH_postInit.sqf b/addons/vehicles/XEH_postInit.sqf index 3afea03187..d89aff2b25 100644 --- a/addons/vehicles/XEH_postInit.sqf +++ b/addons/vehicles/XEH_postInit.sqf @@ -3,46 +3,36 @@ if (!hasInterface) exitWith {}; GVAR(isSpeedLimiter) = false; + // Add keybinds -["ACE3 Vehicles", QGVAR(speedLimiter), localize LSTRING(SpeedLimiter), -{ - private _connectedUAV = getConnectedUAV ACE_player; - private _uavControll = UAVControl _connectedUAV; - if ((_uavControll select 1) == "DRIVER") then { - if !(_connectedUAV isKindOf "UGV_01_base_F") exitWith {false}; - GVAR(isUAV) = true; - [_uavControll select 0, _connectedUAV] call FUNC(speedLimiter); - true - } else { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if !(ACE_player == driver vehicle ACE_player && - {vehicle ACE_player isKindOf 'Car' || - {vehicle ACE_player isKindOf 'Tank'}}) exitWith {false}; +["ACE3 Vehicles", QGVAR(speedLimiter), localize LSTRING(SpeedLimiter), { + false call FUNC(toggleSpeedControl) +}, {false}, [DIK_DELETE, [false, false, false]], false] call CBA_fnc_addKeybind; - GVAR(isUAV) = false; - // Statement - [ACE_player, vehicle ACE_player] call FUNC(speedLimiter); - true - }; - -}, -{false}, -[211, [false, false, false]], false] call CBA_fnc_addKeybind; //DELETE Key +["ACE3 Vehicles", QGVAR(cruiseControl), localize LSTRING(CruiseControl), { + true call FUNC(toggleSpeedControl) +}, {false}, [DIK_INSERT, [false, false, false]], false] call CBA_fnc_addKeybind; ["ACE3 Vehicles", QGVAR(scrollUp), localize LSTRING(IncreaseSpeedLimit), { if (GVAR(isSpeedLimiter)) then { - GVAR(speedLimit) = round (GVAR(speedLimit) + 1) max 5; + GVAR(speedLimit) = round (GVAR(speedLimit) + GVAR(speedLimiterStep)) max (5 max GVAR(speedLimiterStep)); + GVAR(speedLimit) = 5 max GVAR(speedLimiterStep) * floor (GVAR(speedLimit) / GVAR(speedLimiterStep)); [["%1: %2", LSTRING(SpeedLimit), GVAR(speedLimit)]] call EFUNC(common,displayTextStructured); true + } else { + !isNil QGVAR(speedLimit) + && {[GVAR(isCruiseControl), true] call FUNC(toggleSpeedControl)} // RESUME }; }, {false}, [MOUSE_SCROLL_UP, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + Mouse Wheel Scroll Up ["ACE3 Vehicles", QGVAR(scrollDown), localize LSTRING(DecreaseSpeedLimit), { if (GVAR(isSpeedLimiter)) then { - GVAR(speedLimit) = round (GVAR(speedLimit) - 1) max 5; + GVAR(speedLimit) = round (GVAR(speedLimit) - GVAR(speedLimiterStep)) max (5 max GVAR(speedLimiterStep)); + GVAR(speedLimit) = 5 max GVAR(speedLimiterStep) * ceil (GVAR(speedLimit) / GVAR(speedLimiterStep)); [["%1: %2", LSTRING(SpeedLimit), GVAR(speedLimit)]] call EFUNC(common,displayTextStructured); true + } else { + !isNil QGVAR(isCruiseControl) + && {GVAR(isCruiseControl) call FUNC(toggleSpeedControl)} // SET }; }, {false}, [MOUSE_SCROLL_DOWN, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + Mouse Wheel Scroll Down diff --git a/addons/vehicles/XEH_preInit.sqf b/addons/vehicles/XEH_preInit.sqf index 028a8aec1c..70cd66e1cc 100644 --- a/addons/vehicles/XEH_preInit.sqf +++ b/addons/vehicles/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" [ "AllVehicles", diff --git a/addons/vehicles/functions/fnc_autoThrottle.sqf b/addons/vehicles/functions/fnc_autoThrottle.sqf new file mode 100644 index 0000000000..63b4f53642 --- /dev/null +++ b/addons/vehicles/functions/fnc_autoThrottle.sqf @@ -0,0 +1,113 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Toggle speed limiter for Driver in Plane. Uses a simple PID controller to manage thrust + * + * Arguments: + * 0: Driver + * 1: Vehicle + * 2: Preserve Speed Limit + * + * Return Value: + * None + * + * Example: + * [player, car] call ace_vehicles_fnc_autoThrottle + * + * Public: No + */ +#define PID_P 1 +#define PID_I 0.3 +#define PID_D 0 +#define EPSILON 0.001 + +params ["_driver", "_vehicle", ["_preserveSpeedLimit", false]]; + +if (GVAR(isSpeedLimiter)) exitWith { + [localize LSTRING(Off)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + GVAR(isSpeedLimiter) = false; +}; + +[localize LSTRING(On)] call EFUNC(common,displayTextStructured); +playSound "ACE_Sound_Click"; +GVAR(isSpeedLimiter) = true; +GVAR(isCruiseControl) = true; // enables SET/RESUME + +if (!_preserveSpeedLimit) then { + // Convert forward speed to KM/H. `speed _vehicle` isnt accurate enough for this controller to work well, so its easier to use M/S. The system assumes it is KM/H so we need the conversion + GVAR(speedLimit) = (((velocityModelSpace _vehicle) select 1) * 3.6) max 5; +}; + +[{ + params ["_args", "_idPFH"]; + _args params ["_driver", "_vehicle", "_autothrottleParameters"]; + _autothrottleParameters params ["_lastVelocity", "_integralValue", "_lastTime", "_lastThrottleValue", "_throttleLogValue"]; + + // this will take into account game being pausesd + private _deltaTime = CBA_missionTime - _lastTime; + + private _role = _driver call EFUNC(common,getUavControlPosition); + if (GVAR(isUAV)) then { + if (_role != "DRIVER") then { + GVAR(isSpeedLimiter) = false; + }; + } else { + if (_driver != currentPilot _vehicle || {_role != ""}) then { + GVAR(isSpeedLimiter) = false; + }; + }; + + if (_throttleLogValue == 0) then { + _throttleLogValue = 1; + }; + + private _currentThrottle = (airplaneThrottle _vehicle) ^ _throttleLogValue; + if (_lastThrottleValue != -1 && { EPSILON < abs (_currentThrottle - _lastThrottleValue) }) then { + // player/script has moved throttle, stop limiting speed + // ARMA will allow an increment of one throttle unit per frame, so if there is a difference between our known throttle value and actual throttle value, the player must of changed it + [localize LSTRING(Off)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + GVAR(isSpeedLimiter) = false; + }; + + if (call CBA_fnc_getActiveFeatureCamera != "") then { + GVAR(isSpeedLimiter) = false; + }; + + if (!GVAR(isSpeedLimiter)) exitWith { + [_idPFH] call CBA_fnc_removePerFrameHandler; + }; + + if (_deltaTime == 0) exitWith {}; + + private _forwardVelocity = (velocityModelSpace _vehicle) select 1; + // convert from KM/H to M/S + private _velocityError = (GVAR(speedLimit) / 3.6) - _forwardVelocity; + + // strictly speaking this would work better if this error was time to zero acceleration. I can't find the acceleration values in config, however, so this works instead + private _errorDiff = _velocityError - _lastVelocity; + + private _p = PID_P * _velocityError; + private _i = _integralValue + (PID_I * _errorDiff * _deltaTime); + private _d = PID_D * _errorDiff / _deltaTime; + + private _outputBeforeSaturation = _p + _i + _d; + private _throttle = 0 max (_outputBeforeSaturation min 1); + + // if we are saturated, we clamp the integral value to avoid integral windup + if (_outputBeforeSaturation != _throttle) then { + // saturated + _i = _integralValue; + _throttle = 0 max ((_p + _d) min 1); + }; + + _vehicle setAirplaneThrottle _throttle; + + _autothrottleParameters set [0, _d]; + _autothrottleParameters set [1, _i]; + _autothrottleParameters set [2, CBA_missionTime]; + _autothrottleParameters set [3, _throttle]; + +}, 0, [_driver, _vehicle, [0, 0, CBA_missionTime, -1, getNumber (configOf _vehicle >> "throttleToThrustLogFactor")]]] call CBA_fnc_addPerFrameHandler; + diff --git a/addons/vehicles/functions/fnc_setVehicleStartDelay.sqf b/addons/vehicles/functions/fnc_setVehicleStartDelay.sqf new file mode 100644 index 0000000000..6539eec7ef --- /dev/null +++ b/addons/vehicles/functions/fnc_setVehicleStartDelay.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: severgun + * Set engine startup delay to specific vehicle. + * + * Arguments: + * 0: Vehicle + * 1: Delay (seconds) + * + * Return Value: + * None + * + * Example: + * [hemmt, 3.2] call ace_vehicles_fnc_setVehicleStartDelay + * + * Public: Yes + */ + +params [["_veh", objNull, [objNull]], ["_delay", 0, [99]]]; + +if (isNull _veh || {!(_veh isKindOf "AllVehicles")}) exitWith {}; + +_veh setVariable [QGVAR(engineStartDelay), _delay max 0, true]; diff --git a/addons/vehicles/functions/fnc_speedLimiter.sqf b/addons/vehicles/functions/fnc_speedLimiter.sqf index da2f7bf19a..a2ad474174 100644 --- a/addons/vehicles/functions/fnc_speedLimiter.sqf +++ b/addons/vehicles/functions/fnc_speedLimiter.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Toggle speed limiter for Driver in Vehicle. @@ -6,53 +6,100 @@ * Arguments: * 0: Driver * 1: Vehicle + * 2: Cruise Control + * 3: Preserve Speed Limit * * Return Value: * None * * Example: - * [player, car] call ace_vehicles_fnc_speedLimiter + * [player, car, true] call ace_vehicles_fnc_speedLimiter * * Public: No */ -params ["_driver", "_vehicle"]; +params ["_driver", "_vehicle", ["_cruiseControl", false], ["_preserveSpeedLimit", false]]; if (GVAR(isSpeedLimiter)) exitWith { - [localize LSTRING(Off)] call EFUNC(common,displayTextStructured); - playSound "ACE_Sound_Click"; - GVAR(isSpeedLimiter) = false; + switch ([GVAR(isCruiseControl), _cruiseControl]) do { + case [true, true]: { + [localize LSTRING(OffCruise)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + _vehicle setCruiseControl [0, false]; + GVAR(isSpeedLimiter) = false; + }; + case [true, false]: { + [localize LSTRING(On)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + _vehicle setCruiseControl [GVAR(speedLimit), false]; + GVAR(isCruiseControl) = false; + }; + case [false, true]: { + [localize LSTRING(OnCruise)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + _vehicle setCruiseControl [GVAR(speedLimit), true]; + GVAR(isCruiseControl) = true; + }; + case [false, false]: { + [localize LSTRING(Off)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + _vehicle setCruiseControl [0, false]; + GVAR(isSpeedLimiter) = false; + }; + }; }; -[localize LSTRING(On)] call EFUNC(common,displayTextStructured); +(getCruiseControl _vehicle) params ["_speedLimit"]; +if (_speedLimit != 0) exitWith { TRACE_1("speed limit set by external source",_speedLimit); }; + +[localize ( + [LSTRING(On), LSTRING(OnCruise)] select _cruiseControl +)] call EFUNC(common,displayTextStructured); playSound "ACE_Sound_Click"; GVAR(isSpeedLimiter) = true; +GVAR(isCruiseControl) = _cruiseControl; -GVAR(speedLimit) = speed _vehicle max 5; +if (!_preserveSpeedLimit) then { + GVAR(speedLimit) = round (speed _vehicle max 5); +}; +GVAR(speedLimitInit) = true; [{ params ["_args", "_idPFH"]; _args params ["_driver", "_vehicle"]; + private _role = _driver call EFUNC(common,getUavControlPosition); if (GVAR(isUAV)) then { - private _uavControll = UAVControl _vehicle; - if ((_uavControll select 0) != _driver || _uavControll select 1 != "DRIVER") then { + if (_role == "") then { GVAR(isSpeedLimiter) = false; + TRACE_1("UAV controller changed, disabling speedlimit",_vehicle); }; } else { - if (_driver != driver _vehicle) then { + if (_driver != driver _vehicle || {_role != ""}) then { GVAR(isSpeedLimiter) = false; + TRACE_3("Vehicle driver changed, disabling speedlimit",_driver,driver _vehicle,_vehicle); }; }; + if (call CBA_fnc_getActiveFeatureCamera != "") then { + GVAR(isSpeedLimiter) = false; + }; + if (!GVAR(isSpeedLimiter)) exitWith { + _vehicle setCruiseControl [0, false]; [_idPFH] call CBA_fnc_removePerFrameHandler; }; - private _speed = speed _vehicle; - - if (_speed > GVAR(speedLimit)) then { - _vehicle setVelocity ((velocity _vehicle) vectorMultiply ((GVAR(speedLimit) / _speed) - 0.00001)); // fix 1.42-hotfix PhysX libraries applying force in previous direction when turning + getCruiseControl _vehicle params ["_currentSpeedLimit", "_cruiseControlActive"]; + if (GVAR(isCruiseControl) && {!GVAR(speedLimitInit) && {!_cruiseControlActive}}) exitWith { + [_idPFH] call CBA_fnc_removePerFrameHandler; + GVAR(isSpeedLimiter) = false; + [localize LSTRING(OffCruise)] call EFUNC(common,displayTextStructured); + playSound "ACE_Sound_Click"; + }; + if (round _currentSpeedLimit != GVAR(speedLimit)) then { + TRACE_2("Updating speed limit",GVAR(speedLimit),_vehicle); + _vehicle setCruiseControl [GVAR(speedLimit), GVAR(isCruiseControl)]; + GVAR(speedLimitInit) = false; }; - }, 0, [_driver, _vehicle]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/vehicles/functions/fnc_startEngine.sqf b/addons/vehicles/functions/fnc_startEngine.sqf index 507036b0cb..8823ae4018 100644 --- a/addons/vehicles/functions/fnc_startEngine.sqf +++ b/addons/vehicles/functions/fnc_startEngine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Delays engine start of vehicle. @@ -11,7 +11,7 @@ * None * * Example: - * [vehicle player, false] call ace_vehicle_fnc_startEngine + * [vehicle player, false] call ace_vehicles_fnc_startEngine * * Public: No */ @@ -20,6 +20,9 @@ params ["_vehicle", "_isEngineOn"]; if (!_isEngineOn || {floor abs speed _vehicle > 0 || {!isNull isVehicleCargo _vehicle}}) exitWith {}; +private _startupDelay = _vehicle getVariable [QGVAR(engineStartDelay), getNumber (configOf _vehicle >> QGVAR(engineStartDelay))]; +if (_startupDelay <= 0) exitWith {}; + [{ params ["_args", "_idPFH"]; _args params ["_vehicle", "_time", "_direction"]; @@ -29,4 +32,4 @@ if (!_isEngineOn || {floor abs speed _vehicle > 0 || {!isNull isVehicleCargo _ve _vehicle setVelocity [0, 0, 0]; _vehicle setVectorDirAndUp _direction; -} , 0, [_vehicle, CBA_missionTime + STARTUP_DELAY, [vectorDir _vehicle, vectorUp _vehicle]]] call CBA_fnc_addPerFrameHandler; +} , 0, [_vehicle, CBA_missionTime + _startupDelay, [vectorDir _vehicle, vectorUp _vehicle]]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/vehicles/functions/fnc_toggleSpeedControl.sqf b/addons/vehicles/functions/fnc_toggleSpeedControl.sqf new file mode 100644 index 0000000000..bbbaa08876 --- /dev/null +++ b/addons/vehicles/functions/fnc_toggleSpeedControl.sqf @@ -0,0 +1,59 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Checks if player can toggle speed control and runs proper speed control mode. + * Should run as key handler. + * + * Arguments: + * 0: Cruise Control + * 1: Preserve Speed Limit + * + * Return Value: + * Key handled + * + * Example: + * true call ace_vehicles_fnc_toggleSpeedControl + * + * Public: No + */ + +params [["_cruiseControl", false], ["_preserveSpeedLimit", false]]; + +private _role = ACE_player call EFUNC(common,getUavControlPosition); + +private _vehicle = objNull; +private _continue = true; +if (_role != "") then { + GVAR(isUAV) = true; + _vehicle = getConnectedUAV ACE_player; + _continue = ( + !visibleMap + && {_role == "DRIVER" || {!(_vehicle isKindOf "Plane")}} + ); +} else { + GVAR(isUAV) = false; + _vehicle = vehicle ACE_player; + _continue = ( + ACE_player == currentPilot _vehicle + && {[ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)} + ); +}; +if ( + !_continue + || {!(isEngineOn _vehicle)} + || {!GVAR(isSpeedLimiter) && _cruiseControl && {speed _vehicle < 1}} // don't enable CC when stop or move backward +) exitWith {false}; + +private _allowedVehicleClasses = ["Car", "Tank", "Ship"]; +if (_cruiseControl) then { + _allowedVehicleClasses pushBack "Plane"; +}; +if (-1 == _allowedVehicleClasses findIf {_vehicle isKindOf _x}) exitWith {false}; + +if (_vehicle isKindOf "Plane") then { + [ACE_player, _vehicle, _preserveSpeedLimit] call FUNC(autoThrottle); +} else { + [ACE_player, _vehicle, _cruiseControl, _preserveSpeedLimit] call FUNC(speedLimiter); +}; + +true diff --git a/addons/vehicles/functions/script_component.hpp b/addons/vehicles/functions/script_component.hpp deleted file mode 100644 index f84b06d718..0000000000 --- a/addons/vehicles/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\vehicles\script_component.hpp" \ No newline at end of file diff --git a/addons/vehicles/initSettings.inc.sqf b/addons/vehicles/initSettings.inc.sqf new file mode 100644 index 0000000000..eb15ea346f --- /dev/null +++ b/addons/vehicles/initSettings.inc.sqf @@ -0,0 +1,29 @@ +[ + QGVAR(keepEngineRunning), + "CHECKBOX", + [LSTRING(SettingKeepEngineRunningName), LSTRING(SettingKeepEngineRunningDesc)], + ELSTRING(common,ACEKeybindCategoryVehicles), + false, // default value + true // isGlobal +] call CBA_fnc_addSetting; + +[ + QGVAR(hideEjectAction), + "CHECKBOX", + [LSTRING(HideEjectAction), LSTRING(HideEjectActionTooltip)], + ELSTRING(common,ACEKeybindCategoryVehicles), + true, + 2, { + profileNamespace setVariable [QGVAR(showEjectAction), parseNumber !_this]; + saveProfileNamespace; + }, + true // needs restart +] call CBA_fnc_addSetting; + +[ + QGVAR(speedLimiterStep), + "SLIDER", + LSTRING(SpeedLimiterStep), + ELSTRING(common,ACEKeybindCategoryVehicles), + [1, 10, 5, -1] // whole numbers only +] call CBA_fnc_addSetting; diff --git a/addons/vehicles/initSettings.sqf b/addons/vehicles/initSettings.sqf deleted file mode 100644 index 926a95ea4c..0000000000 --- a/addons/vehicles/initSettings.sqf +++ /dev/null @@ -1,21 +0,0 @@ -[ - QGVAR(keepEngineRunning), - "CHECKBOX", - [LSTRING(SettingKeepEngineRunningName), LSTRING(SettingKeepEngineRunningDesc)], - ELSTRING(common,ACEKeybindCategoryVehicles), - false, // default value - true // isGlobal -] call CBA_fnc_addSetting; - -[ - QGVAR(hideEjectAction), - "CHECKBOX", - [LSTRING(HideEjectAction), LSTRING(HideEjectActionTooltip)], - ELSTRING(common,ACEKeybindCategoryVehicles), - true, - 2, { - profileNamespace setVariable [QGVAR(showEjectAction), parseNumber !_this]; - saveProfileNamespace; - }, - true // needs restart -] call CBA_fnc_addSetting; diff --git a/addons/vehicles/script_component.hpp b/addons/vehicles/script_component.hpp index b985da6632..a23967a4d5 100644 --- a/addons/vehicles/script_component.hpp +++ b/addons/vehicles/script_component.hpp @@ -6,6 +6,8 @@ // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + #ifdef DEBUG_ENABLED_VEHICLES #define DEBUG_MODE_FULL #endif @@ -19,5 +21,5 @@ #define MOUSE_SCROLL_UP 0xF8 #define MOUSE_SCROLL_DOWN 0xF9 -#define FUEL_FACTOR 0.165 // fuel capacity = range in km * FUEL_FACTOR -#define STARTUP_DELAY 1.3 +// fuel capacity = range in km * FUEL_FACTOR +#define FUEL_FACTOR 0.165 diff --git a/addons/vehicles/stringtable.xml b/addons/vehicles/stringtable.xml index ffca34b7ec..741901d75c 100644 --- a/addons/vehicles/stringtable.xml +++ b/addons/vehicles/stringtable.xml @@ -3,11 +3,11 @@ Speed Limiter on - Begrenzer an + Geschwindigkeitsbegrenzer an Limitador de velocidad activado Ogranicznik prędkości włączony Omezovač rychlosti zapnut - Limiteur de vitesse Activé + Limiteur de vitesse activé Ограничение скорости включено Sebességkorlátozó bekapcsolva Limitador de Velocidade Ativo @@ -16,14 +16,27 @@ 속도 제한기 켜짐 启用速度限制 啟用速度限制 + Hız Sabitleyeciı Açık + + + Cruise control on + Tempomat an + 자동운전 켜짐 + Tempomat włączony + クルーズコントロールを有効化 + 开启巡航模式 + Controllo di Velocità Attivo + Круиз-контроль включён + Control de crucero encendido + Régulateur de vitesse activé Speed Limiter off - Begrenzer aus + Geschwindigkeitsbegrenzer aus Limitador de velocidad desactivado Ogranicznik prędkości wyłączony Omezovač rychlosti vypnut - Limiteur de vitesse Désactivé + Limiteur de vitesse désactivé Ограничение скорости выключено Sebességkorlátozó kikapcsolva Limitador de Velocidade Desativado @@ -32,18 +45,39 @@ 속도 제한기 꺼짐 停用速度限制 停用速度限制 + Hız Sabitleyeci Kapalı + + + Cruise control off + Tempomat aus + 자동운전 꺼짐 + Tempomat wyłączony + クルーズコントロールを無効化 + 关闭巡航模式 + Controllo di Velocità Non Attivo + Круиз-контроль выключен + Control de crucero apagado + Régulateur de vitesse désactivé Speed Limit Geschwindigkeitsbegrenzung Limite di velocità - 速度制限 + 制限速度 Ograniczenie prędkości Ограничение скорости + Limite de Velocidade + Límite de velocidad + Rychlostní omezení + 速限 + 限速 + Vitesse limite + Hız Limiti + 속도 제한 Speed Limiter - Begrenzer + Geschwindigkeitsbegrenzer Limitador de velocidad Ogranicznik prędkości Omezovač rychlosti @@ -56,34 +90,83 @@ 속도 제한기 速度限制器 速度限制器 + Hız Sabitleyici + + + Cruise Control + Tempomat + 자동운전 + Tempomat + クルーズコントロール + 巡航模式 + Controllo di Velocità + Круиз-контроль + Contro de crucero + Régulateur de vitesse Increase Speed Limit Maximale Geschwindigkeit erhöhen Aumenta limite di velocità - 速度制限を増やす + 制限速度を増やす Zwiększ ograniczenie prędkości Увеличить ограничение скорости + Aumentar Limite de Velocidade + Aumentar límite de velocidad + Zvyš rychlostní limit + 增加速限 + 提高限速 + Augmenter la vitesse limite + Hız Limitini Arttır + 속도 제한 증가 Decrease Speed Limit Maximale Geschwindigkeit verringern Diminuisce limite di velocità - 速度制限を減らす + 制限速度を減らす Zmniejsz ograniczenie prędkości Уменьшить ограничение скорости + Diminuir Limite de Velocidade + Disminuir límite de velocidad + Sniž rychlostní limit + 降低速限 + 降低限速 + Diminuer la vitesse limite + Hız Limitini Azalt + 속도 제한 감소 Disable automatic engine shut-off Motor nach Verlassen laufen lassen エンジン自動停止を無効化 Убрать автовыключение двигателя + Desativar desligamento automático do motor + Desactivar apagado automático del motor + Vypni automatické vypnutí motoru + 關閉引擎自動熄火 + 关闭引擎自动熄火 + Désactiver l'arrêt automatique du moteur + Wyłącz automatyczne wyłączanie silnika + Disattiva lo spegnimento automatico del motore + Otomatik motor durdurmayı devre dışı bırak + 자동으로 엔진 끄기 비활성화 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. + Desactivar el apagado automático del motor al salir de los vehículos. + Zabraň automatickému vypnutí motoru při opuštění vozidla. + 避免離開載具時自動熄火。 + 避免离开载具时自动熄火。 + Impedisce lo spegnimento automatico del motore quando si esce dai veicoli. + Empêche l'arrêt automatique du moteur à la sortie des véhicules. + Araçtan inerken motorun otomatik kapatılmasını engelleyin. + Zapobiegaj automatycznemu wyłączaniu silnika podczas wychodzenia z pojazdu. + 차량에서 내릴 때 자동으로 엔진을 끄는 것을 비활성화 합니다. Hide Eject Action @@ -91,13 +174,42 @@ Ukryj akcję Wyskocz Убрать действие 'Выпрыгнуть' 脱出アクションを非表示 + Ocultar opção de Ejetar + Ocultar acción de expulsión + 隱藏逃脫動作 + 隐藏下车选项 + Masquer l'action d'éjection + Nascondi azione di espulsione + Schovat vyskočení z vozidla + 탈출 액션 숨기기 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. + Oculta la entrada Expulsar del menú de acciones. Requiere un reinicio del juego. + 隱藏在動作選單中逃脫動作的選項。要求遊戲重新啟動。 + 隐藏鼠标滚轮菜单中的下车选项。需要重新启动游戏。 + Masque l'entrée "Éjection" du menu Action. Nécessite un redémarrage du jeu. + Nasconde la voce Espelli dal menu azione. Richiede il riavvio del gioco. + Schová akci vyskošení z vozidla z akčního menu. Vyžaduje restart hry. + 휠액션에서 탈출을 숨깁니다. 게임 재시작을 필요로 합니다. + + + Speed Limiter Step + Schrittgröße des Geschwindigkeitsbegrenzers + Przeskok limitera prędkości + Pas du limiteur de vitesse + Intervalli del Limitatore di Velocità + 制限速度の増減量 + Krokování omezovače rychlosti + Шаг ограничителя скорости + Salto de limitador de vehículo + 限速器步长 + 속도 제한기 단위 diff --git a/addons/viewdistance/ACE_Settings.hpp b/addons/viewdistance/ACE_Settings.hpp index 63c2a5d19a..e99752c891 100644 --- a/addons/viewdistance/ACE_Settings.hpp +++ b/addons/viewdistance/ACE_Settings.hpp @@ -1,53 +1,20 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(Module_DisplayName); - typeName = "BOOL"; - value = 1; - displayName = CSTRING(enabled_DisplayName); - description = CSTRING(enabled_Description); + movedToSQF = 1; }; class GVAR(viewDistanceOnFoot) { - category = CSTRING(Module_DisplayName); - typeName = "SCALAR"; - isClientSettable = 1; - value = 0; // index, NOT value // Can set it to client's actual viewdistance in the init function once ACE_Settings supports numbers (if ever). - values[] = {CSTRING(videosettings), "500", "1000", "1500", "2000", "2500", "3000", "3500", "4000", "5000", "6000", "7000", "8000", "9000", "10000"}; // Values also need to be changed in functions/fnc_returnValue.sqf - displayName = CSTRING(onFoot_DisplayName); - description = CSTRING(onFoot_Description); + movedToSQF = 1; }; class GVAR(viewDistanceLandVehicle) { - category = CSTRING(Module_DisplayName); - typeName = "SCALAR"; - isClientSettable = 1; - value = 0; // index, NOT value - values[] = {CSTRING(videosettings), "500", "1000", "1500", "2000", "2500", "3000", "3500", "4000", "5000", "6000", "7000", "8000", "9000", "10000"}; // Values also need to be changed in functions/fnc_returnValue.sqf - displayName = CSTRING(landVehicle_DisplayName); - description = CSTRING(landVehicle_Description); + movedToSQF = 1; }; class GVAR(viewDistanceAirVehicle) { - category = CSTRING(Module_DisplayName); - typeName = "SCALAR"; - isClientSettable = 1; - value = 0; // index, NOT value - values[] = {CSTRING(videosettings), "500", "1000", "1500", "2000", "2500", "3000", "3500", "4000", "5000", "6000", "7000", "8000", "9000", "10000"}; // Values also need to be changed in functions/fnc_returnValue.sqf - displayName = CSTRING(airVehicle_DisplayName); - description = CSTRING(airVehicle_Description); + movedToSQF = 1; }; class GVAR(limitViewDistance) { - category = CSTRING(Module_DisplayName); - typeName = "SCALAR"; - value = 10000; // Value, NOT index. 10000 is the maximum in A3 - displayName = CSTRING(limit_DisplayName); - description = CSTRING(limit_setting); - sliderSettings[] = {500, 12000, 10000, 0}; + movedToSQF = 1; }; class GVAR(objectViewDistanceCoeff) { - category = CSTRING(Module_DisplayName); - typeName = "SCALAR"; - isClientSettable = 1; - value = 0; // index. Actual coefficient is given by functions/fnc_returnObjectCoeff.sqf - values[] = {CSTRING(object_off), CSTRING(object_verylow), CSTRING(object_low), CSTRING(object_medium),CSTRING(object_high), CSTRING(object_veryhigh), CSTRING(object_fovBased)}; - displayName = CSTRING(object_DisplayName); - description = CSTRING(object_Description); + movedToSQF = 1; }; }; diff --git a/addons/viewdistance/CfgEventHandlers.hpp b/addons/viewdistance/CfgEventHandlers.hpp index 789cfeb05c..505e215d29 100644 --- a/addons/viewdistance/CfgEventHandlers.hpp +++ b/addons/viewdistance/CfgEventHandlers.hpp @@ -1,18 +1,24 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); + }; +}; + +class Extended_DisplayUnload_EventHandlers { + class RscDisplayOptionsVideo { + ADDON = QUOTE([false] call FUNC(adaptViewDistance)); }; }; diff --git a/addons/viewdistance/README.md b/addons/viewdistance/README.md index 2f0b14dbeb..f76d5c4e50 100644 --- a/addons/viewdistance/README.md +++ b/addons/viewdistance/README.md @@ -2,11 +2,3 @@ ace_viewdistance =========== Adds various View Distance settings, including Field of View based Object View Distance, and allows limiting maximum view distance that can be set by players. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Winter](https://github.com/Winter259) -- [Jonpas](https://github.com/jonpas) diff --git a/addons/viewdistance/XEH_PREP.hpp b/addons/viewdistance/XEH_PREP.hpp index c040baf334..f766232a4d 100644 --- a/addons/viewdistance/XEH_PREP.hpp +++ b/addons/viewdistance/XEH_PREP.hpp @@ -2,5 +2,4 @@ PREP(adaptViewDistance); PREP(changeViewDistance); PREP(initModule); PREP(returnObjectCoeff); -PREP(returnValue); PREP(setFovBasedOvdPFH); diff --git a/addons/viewdistance/XEH_clientInit.sqf b/addons/viewdistance/XEH_clientInit.sqf index eb609a40f9..c60137939f 100644 --- a/addons/viewdistance/XEH_clientInit.sqf +++ b/addons/viewdistance/XEH_clientInit.sqf @@ -2,25 +2,13 @@ if (!hasInterface) exitWith {}; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { // if not enabled, then bugger off. if !(GVAR(enabled)) exitWith {}; // Limit on load [false] call FUNC(adaptViewDistance); - // Set the EH which waits for any of the view distance settings to be changed, so that the effect is show immediately - ["ace_settingChanged",{ - params ["_name"]; - if ((_name == QGVAR(viewDistanceOnFoot)) || - (_name == QGVAR(viewDistanceLandVehicle)) || - (_name == QGVAR(viewDistanceAirVehicle)) || - (_name == QGVAR(objectViewDistanceCoeff))) then { - - [true] call FUNC(adaptViewDistance); - }; - }] call CBA_fnc_addEventHandler; - // Set the EH which waits for a vehicle change to automatically swap between On Foot/In Land Vehicle/In Air Vehicle // Also run when SettingsInitialized runs (not guaranteed) ["vehicle",{ @@ -29,5 +17,5 @@ if (!hasInterface) exitWith {}; ["ACE_controlledUAV", { [false] call FUNC(adaptViewDistance); }] call CBA_fnc_addEventHandler; - + }] call CBA_fnc_addEventHandler; diff --git a/addons/viewdistance/XEH_preInit.sqf b/addons/viewdistance/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/viewdistance/XEH_preInit.sqf +++ b/addons/viewdistance/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/viewdistance/functions/fnc_adaptViewDistance.sqf b/addons/viewdistance/functions/fnc_adaptViewDistance.sqf index d83b8ae746..9878d17336 100644 --- a/addons/viewdistance/functions/fnc_adaptViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_adaptViewDistance.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Winter * Sets the player's current view distance according to whether s/he is on foot, in a land vehicle or in an air vehicle. diff --git a/addons/viewdistance/functions/fnc_changeViewDistance.sqf b/addons/viewdistance/functions/fnc_changeViewDistance.sqf index 40d07cf100..b7fb192db2 100644 --- a/addons/viewdistance/functions/fnc_changeViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_changeViewDistance.sqf @@ -1,10 +1,10 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Winter * Sets the player's current view distance according to allowed values. * * Arguments: - * 0: View Distance setting INDEX + * 0: View Distance setting * 1: Show Prompt * * Return Value: @@ -16,27 +16,32 @@ * Public: No */ -params ["_indexRequested", "_showPrompt"]; +params ["_viewDistance", "_showPrompt"]; + +if (_viewDistance == 0) then { // Video Settings + _viewDistance = (getVideoOptions get "overallVisibility"); +}; -private _newViewDistance = [_indexRequested] call FUNC(returnValue); // changes the setting index into an actual view distance value private _objectViewDistanceCoeff = [GVAR(objectViewDistanceCoeff)] call FUNC(returnObjectCoeff); // changes the setting index into a coefficient. private _viewDistanceLimit = GVAR(limitViewDistance); // Grab the limit -TRACE_3("Limit",_newViewDistance,_viewDistanceLimit,_showPrompt); -setViewDistance (_newViewDistance min _viewDistanceLimit); +TRACE_3("Limit",_viewDistance,_viewDistanceLimit,_showPrompt); +setViewDistance (_viewDistance min _viewDistanceLimit); 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 { GVAR(fovBasedPFHminimalViewDistance) = getObjectViewDistance select 0; // Minimal view distance holder and PFH isRunning variable - [FUNC(setFovBasedOvdPFH), 0, []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(setFovBasedOvdPFH), 0, []] call CBA_fnc_addPerFrameHandler; }; }; @@ -50,7 +55,7 @@ if (_showPrompt) then { _text = [ format ["%1 %2m", localize LSTRING(invalid), viewDistance], format ["%1 %2m", localize LSTRING(infotext), viewDistance] - ] select (_newViewDistance <= _viewDistanceLimit); + ] select (_viewDistance <= _viewDistanceLimit); _text = _text + format ["
%1 %2%3", localize LSTRING(objectinfotext), _objectViewDistanceCoeff * 100, "%"]; }; [parseText _text, 2] call EFUNC(common,displayTextStructured); diff --git a/addons/viewdistance/functions/fnc_initModule.sqf b/addons/viewdistance/functions/fnc_initModule.sqf index b33b6b532c..fe8781f035 100644 --- a/addons/viewdistance/functions/fnc_initModule.sqf +++ b/addons/viewdistance/functions/fnc_initModule.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Winter * Initializes the view distance limiter module. diff --git a/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf b/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf index 5cc17be8bb..54ce388f5c 100644 --- a/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf +++ b/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Winter * Returns the object view distance coefficient according to the given index diff --git a/addons/viewdistance/functions/fnc_returnValue.sqf b/addons/viewdistance/functions/fnc_returnValue.sqf deleted file mode 100644 index 480a9ce7ae..0000000000 --- a/addons/viewdistance/functions/fnc_returnValue.sqf +++ /dev/null @@ -1,37 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Winter - * Returns the view distance value according to the given index. - * - * Arguments: - * 0: View Distance Index - * - * Return Value: - * View Distance - * - * Example: - * [2] call ace_viewdistance_fnc_returnViewDistanceValue - * - * Public: No - */ - -params ["_index"]; - -switch (_index) do { - case 0: {viewDistance}; // Video Settings option - case 1: {500}; - case 2: {1000}; - case 3: {1500}; - case 4: {2000}; - case 5: {2500}; - case 6: {3000}; - case 7: {3500}; - case 8: {4000}; - case 9: {5000}; - case 10: {6000}; - case 11: {7000}; - case 12: {8000}; - case 13: {9000}; - case 14: {10000}; - default {1000}; -}; diff --git a/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf b/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf index e419687ac6..c08545ca7c 100644 --- a/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf +++ b/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Sets Object View Distance dynamically based on current Field of View, between Object View Distance (minimal value) and View Distance (maximum value) set before this PFH starts. diff --git a/addons/viewdistance/functions/script_component.hpp b/addons/viewdistance/functions/script_component.hpp deleted file mode 100644 index f6c83ec54d..0000000000 --- a/addons/viewdistance/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\viewdistance\script_component.hpp" diff --git a/addons/viewdistance/initSettings.inc.sqf b/addons/viewdistance/initSettings.inc.sqf new file mode 100644 index 0000000000..26f0f25017 --- /dev/null +++ b/addons/viewdistance/initSettings.inc.sqf @@ -0,0 +1,54 @@ +private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_DisplayName), LSTRING(enabled_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(viewDistanceOnFoot), "SLIDER", + [LSTRING(onFoot_DisplayName), format ["%1\n%2", LLSTRING(onFoot_Description), LLSTRING(sliderExtraDescription)]], + _category, + [0, 10000, 0, -1], + 0, + {[true] call FUNC(adaptViewDistance)} +] call CBA_fnc_addSetting; + +[ + QGVAR(viewDistanceLandVehicle), "SLIDER", + [LSTRING(landVehicle_DisplayName), format ["%1\n%2", LLSTRING(landVehicle_Description), LLSTRING(sliderExtraDescription)]], + _category, + [0, 10000, 0, -1], + 0, + {[true] call FUNC(adaptViewDistance)} +] call CBA_fnc_addSetting; + +[ + QGVAR(viewDistanceAirVehicle), "SLIDER", + [LSTRING(airVehicle_DisplayName), format ["%1\n%2", LLSTRING(airVehicle_Description), LLSTRING(sliderExtraDescription)]], + _category, + [0, 10000, 0, -1], + 0, + {[true] call FUNC(adaptViewDistance)} +] call CBA_fnc_addSetting; + +[ + QGVAR(limitViewDistance), "SLIDER", + [LSTRING(limit_DisplayName), LSTRING(limit_setting)], + _category, + [500, 12000, 10000, -1], + 1, + {[true] call FUNC(adaptViewDistance)} +] call CBA_fnc_addSetting; + +[ + QGVAR(objectViewDistanceCoeff), "LIST", + [LSTRING(object_DisplayName), LSTRING(object_Description)], + _category, + [[0, 1, 2, 3, 4, 5, 6], [LSTRING(object_off), LSTRING(object_verylow), LSTRING(object_low), LSTRING(object_medium),LSTRING(object_high), LSTRING(object_veryhigh), LSTRING(object_fovBased)], 0], + 0, + {[true] call FUNC(adaptViewDistance)} +] call CBA_fnc_addSetting; diff --git a/addons/viewdistance/stringtable.xml b/addons/viewdistance/stringtable.xml index 5c2d2ec287..eb7ed94838 100644 --- a/addons/viewdistance/stringtable.xml +++ b/addons/viewdistance/stringtable.xml @@ -8,14 +8,15 @@ Omezovač dohlednosti Sichtweitenbegrenzung Limitador de distância de visão - Limiteur de distance de vue + Limiteur de visibilité Látótáv-korlátozó Ограничитель дальности видимости Limitatore Distanza Visiva - 視界距離の制限 + 視界距離を制限 시야 제한기 - 视野距离限制器 + 视距限制器 視野距離限制器 + Görüş Uzaklığı Sınırlayıcısı Allows limiting maximum view distance that can be set by players. @@ -24,11 +25,11 @@ Umožňuje určit maximální dohlednost, kterou si může hráč nastavit Erlaubt das Einschränken der maximalen Sichtweite, welche von Spielern eingestellt werden kann. Permite limitar a distância máxima de visão que pode ser definida pelos jogadores. - Permet de limiter la distance de vue que les joueurs peuvent choisir + Permet de restreindre la distance maximale de visibilité pouvant être définie par les joueurs. Lehetővé teszi a játékosok által a látótávolság maximumának korlátozását. Позволяет ограничить максимальную дальность видимости, которая может быть установлена игроками. Consente di limitare la distanza visiva massima che può essere impostata dai giocatori. - プレイヤーへ最大の視界距離を制限できます。 + プレイヤーが設定できる最大視界距離を制限できます。 플레이어가 볼 수 있는 최대 시야를 제한합니다. 允许玩家最大的可视距离 允許玩家最大的可視距離 @@ -40,14 +41,15 @@ Povolit ACE dohlednost Aktiviere ACE-Sichtweite Habilitar distância de visão ACE - Activer la distance de vue ACE + Activer la visibilité ACE ACE látótávolság engedélyezése Ограничить дальность видимости Abilita distanza visiva ACE ACE 視界距離を有効化 ACE 시야 활성화 - 启用ACE视距 + 启用 ACE 视距 啟用ACE視距 + ACE Görüş Uzaklığını Aktif Et Enables ACE viewdistance @@ -56,14 +58,15 @@ Povolit ACE dohlednost Aktiviert ACE-Sichtweite Habilita a distância de visão ACE - Activer la distance de vue ACE + Active la visibilité ACE. Engedélyezi az ACE látótávolságot Включает ограничитель дальности видимости ACE Abilita distanza visiva ACE ACE 視界距離を有効化 - ACE 시야 활성화 - 启用ACE视距 + ACE 시야를 활성화 합니다. + 启用 ACE 视距 啟用ACE視距 + ACE Görüş Uzaklığını Aktif Et View Distance Limit @@ -72,14 +75,15 @@ Limit dohlednosti Sichtweitengrenze Limite da distância de visão - Limite de distance de vue + Limite de visibilité Látótáv-korlát Дальность видимости Limite Distanza Visiva 視界距離の制限 시야 제한기 - 视野距离限制 + 视距限制 視野距離限制 + Görüş Uzaklığı Limiti Sets the limit for how high clients can raise their view distance (up to 10000) @@ -88,14 +92,15 @@ Stanoví limit jak daleko si může client zvýšit dohlednost (do 10000) Setze die Grenze fest, wie weit Spieler ihre Sichtweite erhöhen können (bis 10000) Estabelecer um limite de quão alto os clientes podem aumentar sua distância de visão (até 10000) - Défini pour les clients la limite de distance de vue maximale (jusqu'à 10000) + Définit la limite maximale à laquelle les clients peuvent augmenter leur distance de visibilité (jusqu'à 10000). Korlátozza, mekkora látótávolságot állíthatnak be a kliensek (maximum 10000-ig) Устанавливает предел дальности, насколько клиенты могут увеличить свою дальность видимости (до 10000) Imposta il limite massimo a cui i client possono alzare la propria distanza visiva (massimo 10000) - 各クライアントが最大まで設定できる視界距離を設定します。(最大 10000) + 各クライアントが設定できる視界距離の上限 (最大 10000) 클라이언트가 최대 얼마나 멀리 볼 수 있는지 제한을 둡니다 (10000 까지 가능) - 设定客户端最高可显示的视野距离 (最高至10000) + 设定客户端最高可显示的视距(最高至10000) 設定客戶端最高可顯示的視野距離 (最高至10000) + Kişilerin görüş mesafelerini ne kadar yükseltebileceğine ilişkin sınırı belirler (En Fazla 10000) Limit for client's view distance set here and can overridden by module @@ -104,15 +109,27 @@ Limit dohlednoti pro klienty se nastavuje zde a může být potlačeno pomocí modulu. Stellt die Grenze für die Sichtweite des Spielers ein. Das kann von einem Modul überschrieben werden. Permite limitar a distância de visão máxima que pode ser definida por jogadores. Pode ser substituído por módulo. - Limite de la distance de vue pour les clients et peut être forcé par ce module + La limite de portée visuelle du joueur est définie ici, pouvant être écrasée par un autre module. A kliens látótávolsága itt állítható be, és felülbírálható modulok által Предел дальности видимости клиентов устанавливается здесь и может быть переопределен модулем Limite per la distanza visiva del client impostato qui e può essere scavalcato dal modulo - クライアントへの視界距離の設定や、それをモジュールにより上書きできます - 클라이언트의 시야를 이 모듈로 치환할 수 있습니다. + クライアントの表示距離の制限はここで設定され、モジュールによって上書きできます + 클라이언트의 시야를 이 모듈로 덮어씌울 수 있습니다. 玩家的视距限制可在此设定,也可透过模块改写 玩家的視距限制可在此設定,也可透過模塊改寫 + + Setting to 0 will use default video settings + 设置为0将使用默认的视频设置 + 0으로 설정시 기존 비디오 설정을 사용합니다. + Bei Einstellung auf 0 werden die Standard-Videoeinstellungen verwendet. + Se impostato su 0 verranno usate le impostazioni video predefinite. + Ustawienie na 0, spowoduje użycie domyślnych ustawień wideo. + 0に設定すると、デフォルトのビデオ設定が使用されます + Значение 0 будет использовать настройки видео по умолчанию + Establecer a 0 utiliza las opciones de video por defecto + La valeur 0 permet d'utiliser les paramètres vidéo par défaut + Client View Distance (On Foot) Zasięg widzenia (piechota) @@ -120,14 +137,15 @@ Dohlednost (Pěšák) Spielersichtweite (zu Fuß) Distância de visão do cliente (A pé) - Distance de vue (à pied) + Visibilité (à pied) Kliens látótáv (gyalog) Дальность видимости (Пешком) Distanza Visiva Client (a Piedi) クライアント側視界距離 (地上) 클라이언트 시야 (보병) - 客户端视野距离 (步行) + 客户端视距(步行) 客戶端視野距離 (步行) + Kişilerin Görüş Uzaklığı Mesafesi (Yerde) Changes in game view distance when the player is on foot. @@ -136,14 +154,15 @@ Změna dohlednosti pro hráče pokud jde po svých. Verändert die Sichtweite, wenn ein Spieler zu Fuß unterwegs ist. Muda a distância de visão do jogador dentro do jogo quando ele está a pé. - Change la distance de vue quand le joueur est à pied + Change la distance d'affichage du jeu quand le joueur est à pied. Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos gyalogosan van. Изменяет дальность видимости в игре, когда игрок перемещается пешком. Cambia la distanza visiva in gioco quando il giocatore è a piedi. プレイヤーが地上にいる時の視界距離を変更します。 플레이어가 보병일 경우의 시야를 바꿀 수 있습니다. - 改变玩家步行时的视野距离. + 改变玩家步行时的视距。 改變玩家步行時的視野距離. + Oyuncular ayakta iken görebileceği uzaklığı değiştir. Client View Distance (Land Vehicle) @@ -152,14 +171,15 @@ Dohlednost (Pozemní technika) Spielersichtweite (Landfahrzeuge) Distância de visão do cliente (Veículo terrestre) - Distance de vue (à pied) + Visibilité (véhicule terrestre) Kliens látótáv (szárazföldi jármű) Дальность видимости (В наземном трансп.) Distanza Visiva Client (Veicolo Terrestre) クライアント側視界距離 (車両) 클라이언트 시야 (차량) - 客户端视野距离 (地面载具) + 客户端视距(地面载具) 客戶端視野距離 (地面載具) + Kişilerin Görüş Uzaklığı Mesafesi (Kara Araçların da) Changes in game view distance when the player is in a land vehicle. @@ -168,14 +188,15 @@ Změna dohlednosti pro hráče pokud je v pozemní technice. Verändert die Sichtweite, wenn ein Spieler in einem Landfahrzeug ist. Muda a distância de visão do jogador dentro do jogo quando ele está dentro de um veículo terrestre. - Change la distance de vue quand le joueur est dans un véhicule + Change la distance d'affichage du jeu quand le joueur se trouve dans un véhicule terrestre. Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos szárazföldi járműben van. Изменяет дальность видимости в игре, когда игрок перемещается в наземном транспорте. Cambia la distanza visiva in gioco quando il giocatore è in un veicolo terrestre. - プレイヤーが車両の時の視界距離を変更します。 + プレイヤーが車両に乗っている時の視界距離を変更します。 플레이어가 차량 내부일 경우의 시야를 바꿀 수 있습니다. - 改变玩家于地面载具内时的视野距离 + 改变玩家于地面载具内时的视距 改變玩家於地面載具內時的視野距離 + Oyuncular kara araçlarında iken görebileceği uzaklığı değiştir. Client View Distance (Air Vehicle) @@ -184,14 +205,15 @@ Dohlednost (Vzdušná technika) Spielersichtweite (Luftfahrzeuge) Distância de visão do cliente (Veículo aéreo) - Distance de vue (véhicule aérien) + Visibilité (véhicule aérien) Kliens látótáv (légi jármű) Дальность видимости (В воздушном трансп.) Distanza Visiva Client (Veicoli d'Aria) クライアント側視界距離 (航空機) 클라이언트 시야 (항공기) - 客户端视野距离 (空中载具) + 客户端视距(空中载具) 客戶端視野距離 (空中載具) + Kişilerin Görüş Uzaklığı Mesafesi (Hava Araçların da) Changes in game view distance when the player is in an air vehicle. @@ -200,14 +222,15 @@ Změna dohlednosti pro hráče pokud je ve vzdušné technice. Verändert die Sichtweite wenn ein Spieler in einem Luftfahrzeug ist. Muda a distância de visão do jogador dentro do jogo quando ele está dentro de um veículo aéreo. - Change la distance de vue quand le joueur est dans un véhicule aérien + Change la distance d'affichage du jeu quand le joueur se trouve dans un véhicule aérien. Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos légi járműben van. Изменяет дальность видимости в игре, когда игрок перемещается в воздушном транспорте. Cambia la distanza visiva in gioco quando il giocatore è in un mezzo aereo. プレイヤーが航空機に乗っている時の視界距離を変更します。 플레이어가 항공기 내부일 경우의 시야를 바꿀 수 있습니다. - 改变玩家于空中载具内时的视野距离 + 改变玩家于空中载具内时的视距 改變玩家於空中載具內時的視野距離 + Oyuncular hava araçların da iken görebileceği uzaklığı değiştir. Dynamic Object View Distance @@ -216,13 +239,13 @@ Dynamická dohlednost objektů Dynamische Objektsichtweite Distância de visão dinâmica dos objetos - Distance de vue pour les objet dynamique + Distance d'affichage dynamique des objets Dinamikus objektum-látótáv Динамич. дальность отрисовки объектов Distanza Visiva Oggetti Dinamica - 動的なオブジェクトの描画距離 + 動的なオブジェクト描画距離 동적 물체 시야 - 动态物件的视野距离 + 动态物体的视距 動態物件的視野距離 @@ -232,13 +255,13 @@ Nastaví objekt dohlednosti jako koeficient dohlednosti. Passt die Objektsichtweite dynamisch der Sichtweite an. Estabelece a distância de visão dos objetos com um coeficiente da distância de visão. - Défini la distance d'affichage des objets comme un coefficient de la distance de vue + Définit la distance d'affichage des objets en fonction de la distance de visibilité, ou selon le champ de vision (FoV).\nLorsque l'affichage basé sur le FoV est choisi, les valeurs minimales et maximales varient en fonction de l'angle de vue. Beállítja az objektum-látótávot a megadott látótáv koefficienseként. Устанавливает дальность отрисовки объектов как коэффициент от общей дальности видимости. Imposta la distanza visiva degli oggetti come un coefficiente basato sulla distanza visiva oppure basato sul campo visivo. - 視野角を元にするか、視界距離によるオブジェクト描画距離を決定します。視野角を元にするオプションを有効化した場合、視野角により最低と最高値が変動します。 - 설정된 시야 혹은 시계(FoV)에 계수를 적용해 물체 시야를 적용합니다. 시계를 바탕으로 하는 옵션을 활성화할 경우 시계에 의한 최저와 최고치가 변동됩니다. - 设定物件可被观察的距离,透过视野距离或是视野角度来决定。 + オブジェクト描画距離を視界距離の係数として、または視野角に基づいて設定します。視野角を元にするオプションを有効化した場合、視野角により最低と最高値が変動します。 + 설정된 시야 혹은 시야각(FoV)에 계수를 적용해 물체 시야를 적용합니다. 시야각를 바탕으로 하는 옵션을 활성화할 경우 시야각에 의한 최저와 최고치가 변동됩니다. + 设定物体可被观察的距离,透过视距或是视野角度来决定。 設定物件可被觀察的距離,透過視野距離或是視野角度來決定。 @@ -248,7 +271,7 @@ Vypnout Aus Desligado - Eteint + Désactivée Kikapcsolva Выкл. Disabilitato @@ -256,6 +279,7 @@ 끄기 关闭 關閉 + Kapalı Very Low @@ -264,14 +288,15 @@ Velmi málo Sehr niedrig Muito baixo - Très bas + Très basse Minimális Очень низкая Molto Basso - 最低 + 非常に低い 매우 낮음 非常低 非常低 + Çok Düşük Low @@ -280,14 +305,15 @@ Málo Niedrig Baixo - Bas + Basse Alacsony Низкая Basso - + 低い 낮음 + Düşük Medium @@ -296,14 +322,15 @@ Středně Mittel Médio - Moyen + Moyenne Közepes Средняя Medio - 通常 + 중간 + Orta High @@ -312,14 +339,15 @@ Hodně Hoch Alto - Haut + Haute Magas Высокая Alto - + 高い 높음 + Yüksek Very High @@ -328,14 +356,15 @@ Velmi hodně Sehr hoch Muito alto - Très haut + Très haute Maximális Очень высокая Molto Alto - 最高 + 非常に高い 매우 높음 非常高 非常高 + Çok Yüksek FoV Based @@ -346,9 +375,9 @@ Oparty na FoV Basato su Campo Visivo (FoV) Basada en campo de visión - Champ de vision basé + Basée sur le champ de vision 視野角を元にする - 시계(FoV) + 시야각(FoV) 由视野角度决定 由視野角度決定 @@ -359,14 +388,15 @@ Dohlednost: Sichtweite: Distância de visão: - Distance de vue + Distance de vue : Látótávolság: Дальность видимости: Distanza Visiva: - 視界距離: + 視界距離: 시야: - 视野距离: + 视距: 視野距離: + Görüş Uzaklığı: Object View Distance is @@ -375,13 +405,13 @@ Dohlednost objektů je Objektsichtweite ist Distância de visão do objeto é - La distance d'affichage des objets est: + La distance d'affichage des objets est de Az objektum-látótávolság: Дальность видимости объектов: Distanza Visiva Oggetti è オブジェクト描画距離は - 동적 물체 시야는 - 物件视野距离为 + 물체 시야는 + 物体视距为 物件視野距離為 @@ -390,15 +420,16 @@ Esta opción no es valida! El limite es Tato volba je neplatná! Limit je Diese Option ist ungültig! Die Grenze ist - Essa opção é inválida. O limte é - Cette option est non valide! La limite est + Essa opção é inválida. O limite é + Cette option est non valide ! La limite est de Ez a beállítás érvénytelen! A maximum mennyiség Настройка не верна! Текущий предел Questa opzione è invalida! Il limite è - このオプションは無効です!制限は + このオプションは無効です! 制限は 이 옵션은 불가능합니다! 제한은 - 该选项是无效的! 限制是 + 该选项是无效的! 限制是 該選項是無效的! 限制是 + Bu seçenek geçersiz! Limit Video Settings @@ -411,10 +442,11 @@ Videobeállítások Видео настройки Impostazioni Video - 映像設定 + 描画設定 영상 설정 影像设定 影像設定 + Grafik Ayarları diff --git a/addons/viewports/$PBOPREFIX$ b/addons/viewports/$PBOPREFIX$ new file mode 100644 index 0000000000..0ed652c6e7 --- /dev/null +++ b/addons/viewports/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\viewports diff --git a/addons/viewports/CfgEventHandlers.hpp b/addons/viewports/CfgEventHandlers.hpp new file mode 100644 index 0000000000..2a3f71f852 --- /dev/null +++ b/addons/viewports/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/viewports/CfgVehicles.hpp b/addons/viewports/CfgVehicles.hpp new file mode 100644 index 0000000000..9b6427ff2c --- /dev/null +++ b/addons/viewports/CfgVehicles.hpp @@ -0,0 +1,22 @@ +class CfgVehicles { + class B_MBT_01_base_F; + class B_MBT_01_cannon_F: B_MBT_01_base_F { // Merkava + class ace_viewports { + class SLD_backLeftUpper { + type = "screen"; + camLocation[] = {0,0,0.05}; + maxDistance = 5; + camAttach[] = {0,0}; + screenLocation[] = {-0.925,-3.43459,-1.07}; + roles[]={"cargo"}; + }; + }; + }; + class B_MBT_01_TUSK_F: B_MBT_01_cannon_F { // Merkava TUSK (slightly different model-space because different p3d model) + class ace_viewports: ace_viewports { + class SLD_backLeftUpper: SLD_backLeftUpper { + screenLocation[] = {-0.925,-4.65511,-1.07}; + }; + }; + }; +}; diff --git a/addons/viewports/README.md b/addons/viewports/README.md new file mode 100644 index 0000000000..c4faabaada --- /dev/null +++ b/addons/viewports/README.md @@ -0,0 +1,4 @@ +ace_viewports +========== + +Allows crew to look through periscopes diff --git a/addons/viewports/XEH_PREP.hpp b/addons/viewports/XEH_PREP.hpp new file mode 100644 index 0000000000..ddf32fb5d9 --- /dev/null +++ b/addons/viewports/XEH_PREP.hpp @@ -0,0 +1,8 @@ +LOG("prep"); + +PREP(eachFrame); +PREP(enterVehicle); +PREP(getSeatInfo); +PREP(getViewports); +PREP(viewCleanup); +PREP(viewCreate); diff --git a/addons/viewports/XEH_postInit.sqf b/addons/viewports/XEH_postInit.sqf new file mode 100644 index 0000000000..06984eabf0 --- /dev/null +++ b/addons/viewports/XEH_postInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +GVAR(pfeh) = -1; +["CBA_settingsInitialized", { + TRACE_1("CBA_settingsInitialized",GVAR(enabled)); + ["vehicle", LINKFUNC(enterVehicle), true] call CBA_fnc_addPlayerEventHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/viewports/XEH_preInit.sqf b/addons/viewports/XEH_preInit.sqf new file mode 100644 index 0000000000..ec82c949b1 --- /dev/null +++ b/addons/viewports/XEH_preInit.sqf @@ -0,0 +1,15 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +#ifdef POINT_CONFIG_DEBUG +call compileScript [QPATHTOF(dev\debugPoints.sqf)]; +#endif + +ADDON = true; diff --git a/addons/viewports/XEH_preStart.sqf b/addons/viewports/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/viewports/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/viewports/config.cpp b/addons/viewports/config.cpp new file mode 100644 index 0000000000..7d303de1b7 --- /dev/null +++ b/addons/viewports/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "gui.hpp" diff --git a/addons/viewports/data/optic_window_ca.paa b/addons/viewports/data/optic_window_ca.paa new file mode 100644 index 0000000000..18e1aa9ea7 Binary files /dev/null and b/addons/viewports/data/optic_window_ca.paa differ diff --git a/addons/viewports/dev/debugPoints.sqf b/addons/viewports/dev/debugPoints.sqf new file mode 100644 index 0000000000..53fe016b62 --- /dev/null +++ b/addons/viewports/dev/debugPoints.sqf @@ -0,0 +1,173 @@ +#include "..\script_component.hpp" +/* + [] call compileScript ["\z\ace\addons\viewports\dev\debugPoints.sqf"]; + + This is mostly just for placing the mem points in threeden + left-click to place and adjust current point + alt+left-click to place next point + alt+right-click to output + shift+right-click to reset + + // Tweak: + z = (vehicle player) getVariable "ace_viewports_viewports"; + p = z # 0 # 4; z # 0 set [4, p vectorAdd [0,0.1,0]]; + + // Place by view: + v = (positionCameraToWorld [0,0,0.4]); + m = (vehicle player) worldToModel v; + z = (vehicle player) getVariable "ace_viewports_viewports"; + z # 0 set [4, m]; +*/ + +#define IDD_3DEN 313 + +[] spawn { + INFO_2("Pre-Init [is3den %1][3den display: %2]",is3den,!isNull findDisplay IDD_3DEN); + if (!is3den) exitWith {}; + + GVAR(3denIndex) = 0; + GVAR(3denViewports) = []; + + disableSerialization; + private _3den = findDisplay IDD_3DEN; + if (_3den getVariable [QGVAR(setup), false]) exitWith {}; + _3den setVariable [QGVAR(setup), true]; + + _3den displayAddEventHandler ["MouseButtonDown", { + params ["", "_button", "_mouseX", "_mouseY", "_shift", "_ctrl", "_alt"]; + + if (_shift && _button == 1) exitWith { + systemChat "Reset/Reload"; + if ((supportInfo "u:diag_mergeConfigFile") isNotEqualTo []) then { + call compile 'diag_mergeConfigFile ["P:\z\ace\addons\viewports\config.cpp"]'; + }; + { _x setVariable [QGVAR(viewports), nil] } forEach vehicles; + GVAR(3denIndex) = 0; + GVAR(3denViewports) = []; + true + }; + + if (_alt) then { + if (count GVAR(3denViewports) > GVAR(3denIndex)) then { + systemChat "Advance to next index"; + GVAR(3denIndex) = GVAR(3denIndex) + 1; + }; + }; + if (_alt && _button == 1) exitWith { + private _vehicle = (get3DENSelected "object") param [0, objNull]; + private _config = configOf _vehicle; + private _model = getText (_config >> "model"); + while {true} do { + private _parent = inheritsFrom _config; + if ((getText (_parent >> "model")) != _model) exitWith {}; + _config = _parent; + }; + + private _out = []; + _out pushBack format [" class %1: %2 {", configName _config, configName inheritsFrom _config]; + _out pushBack format [" class ace_viewports {"]; + { + _x params ["_name", "", "_camLocation", "_camAttach"]; + _out pushBack format [' class %1 {', _name]; + _out pushBack format [' camLocation[] = {%1, %2, %3};', _camLocation # 0, _camLocation # 1, _camLocation # 2]; + _out pushBack format [' camAttach = %1;', _camAttach]; + // _out pushBack format [' type = "%1";', _type]; + // _out pushBack format [' screenLocation[] = {};']; + // _out pushBack format [' maxDistance = 99;']; + // _out pushBack format [' compartments[]={};']; + // _out pushBack format [' roles[]={};']; + _out pushBack format [' };']; + } forEach GVAR(3denViewports); + + _out pushBack format [' };']; + _out pushBack format [' };']; + + // Some inherited configs might use a different model which uses a different offset - yuck + private _inherited = '((configName _x) isKindOf (configName _config)) && {_model != getText (_x >> "model")}' configClasses (configFile >> "CfgVehicles"); + _out pushBack format ["// Watch out for %1", _inherited apply {configName _x}]; + + copyToClipboard (_out joinString endl); + systemChat format ["copied %1 lines", count _out]; + }; + if (_button == 0) exitWith { + private _vehicle = (get3DENSelected "object") param [0, objNull]; + if (isNull _vehicle) exitWith {}; + + private _start = AGLToASL positionCameraToWorld [0,0,0]; + private _end = AGLToASL screenToWorld [_mouseX, _mouseY]; + private _intersections = lineIntersectsSurfaces [_start, _end]; + private _pointASL = _intersections # 0 # 0; + if (isNil "_pointASL") exitWith {}; + _pointASL = _pointASL vectorAdd [0,0,0.09]; // Add a little bit up because it always sinks into the model + private _pointMS = _vehicle worldToModel ASLtoAGL _pointASL; + + private _name = format ["view_%1",GVAR(3denIndex)]; + // [_name, _type, _camLocation, _camAttach, _screenLocation, _maxDistance, _compartments, _roles] + GVAR(3denViewports) set [GVAR(3denIndex), [_name, "", _pointMS, 0, _pointMS, 99, [], []]]; + true + }; + }]; +}; + +// this runs in both threeden and in-game +addMissionEventHandler ["Draw3D", { + private _vehicle = vehicle player; + private _viewports = _vehicle getVariable [QGVAR(viewports), []]; + + if (is3den) then { + _vehicle = (get3DENSelected "object") param [0, objNull]; + if (isNull _vehicle) exitWith {}; + _viewports = [_vehicle] call FUNC(getViewports); + if (GVAR(3denViewports) isNotEqualTo []) then { + _viewports = GVAR(3denViewports); + }; + }; + if (isNull _vehicle) exitWith {}; + + + drawIcon3D ["#(argb,8,8,3)color(1,1,1,1)", [1,1,0,1], _vehicle modelToWorldVisual [0,0,0], 0.1, 0.1, 0, "", 1, 0.02, "TahomaB"]; + if (alive player) then { // not using ace_player so this works in 3den + drawIcon3D ["#(argb,8,8,3)color(1,1,1,1)", [0,1,0,1], aslToAGL eyepos player, 0.1, 0.1, 0, "eye", 1, 0.02, "TahomaB"]; + drawIcon3D ["#(argb,8,8,3)color(1,1,1,1)", [0,1,0,1], player modelToWorldVisual (player selectionPosition "pilot"), 0.1, 0.1, 0, "pilot", 1, 0.02, "TahomaB"]; + }; + // { + // private _pos = _vehicle modelToWorldVisual (_vehicle selectionPosition [_x, "Memory"]); + // drawIcon3D ["#(argb,8,8,3)color(1,1,1,1)", [0,0,1,0.2], _pos, 0.05, 0.05, 0, _x, 1, 0.02, "TahomaB"]; + // } forEach (_vehicle selectionNames "Memory"); + + + { + _x params ["_name", "_type", "_camLocation", "_camAttach", "_screenLocation", "_maxDistance", "_compartments", "_roles"]; + + if (_camLocation isEqualType "") then { + _camLocation = _vehicle selectionPosition [_camLocation, "Memory"]; + }; + + private _screenAGL = _vehicle modelToWorldVisual _screenLocation; + drawIcon3D ["#(argb,8,8,3)color(0,0,1,1)", [1,0.5,1,1], _screenAGL, 0.05, 0.05, 0, format ["%1:%2",_forEachIndex,_compartments], 1, 0.03, "TahomaB"]; + + private _camAGL = if (_camAttach isEqualType 0) then { + _vehicle modelToWorldVisual _camLocation + } else { + private _turretConfig = [_vehicle, _camAttach] call CBA_fnc_getTurret; + private _memoryPointGunnerOptics = getText(_turretConfig >> "memoryPointGunnerOptics"); + _vehicle modelToWorldVisual (_camLocation vectorAdd (_vehicle selectionPosition _memoryPointGunnerOptics)) + }; + drawIcon3D ["#(argb,8,8,3)color(1,0,0,1)", [0.5,1,1,1], _camAGL, 0.1, 0.1, 0, format ["%1:%2",_forEachIndex,_name], 1, 0.03, "TahomaB"]; + + if (_camAttach isEqualType 0) then { + private _camAGL = _vehicle modelToWorldVisual _camLocation; + drawIcon3D ["#(argb,8,8,3)color(1,0,0,1)", [1,1,1,1], _camAGL, 0.1, 0.1, 0, _name, 1, 0.05, "TahomaB"]; + private _target = _vehicle modelToWorldVisual (_camLocation vectorAdd ([1, _camAttach, 0] call CBA_fnc_polar2vect)); + drawLine3D [_camAGL, _target, [0,1,0,1]]; + private _target = _vehicle modelToWorldVisual (_camLocation vectorAdd ([1, _camAttach, 1] call CBA_fnc_polar2vect)); + drawLine3D [_camAGL, _target, [0,1,0,1]]; + private _target = _vehicle modelToWorldVisual (_camLocation vectorAdd ([1, _camAttach, -1] call CBA_fnc_polar2vect)); + drawLine3D [_camAGL, _target, [0,1,0,1]]; + private _target = _vehicle modelToWorldVisual (_camLocation vectorAdd ([0.2, _camAttach+90, 0] call CBA_fnc_polar2vect)); + drawLine3D [_camAGL, _target, [1,0,1,1]]; + private _target = _vehicle modelToWorldVisual (_camLocation vectorAdd ([0.2, _camAttach-90, 0] call CBA_fnc_polar2vect)); + drawLine3D [_camAGL, _target, [1,0,1.2,1]]; + }; + } forEach _viewports; +}]; diff --git a/addons/viewports/functions/fnc_eachFrame.sqf b/addons/viewports/functions/fnc_eachFrame.sqf new file mode 100644 index 0000000000..21f2f09dc8 --- /dev/null +++ b/addons/viewports/functions/fnc_eachFrame.sqf @@ -0,0 +1,77 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Runs each frame while inside of a vehicle with viewports + * + * Arguments: + * 0: PFEH Args + * 0: Player + * 1: Vehicle + * 2: Viewport configuration + * 3: Viewport index shown (-1 for none) + * 4: Last visionmode + * + * Return Value: + * None + * + * Example: + * [] call ace_viewports_fnc_eachFrame + * + * Public: No + */ + +params ["_args", "_pfID"]; +_args params ["_player", "_vehicle", "_viewports", "_shownIndex", "_lastVisionMode"]; + +private _newIndex = -1; +if (cba_events_control) then { + if (cameraView != "INTERNAL") exitWith {}; + if (isTurnedOut _player) exitWith {}; + if !([_player, _vehicle, []] call EFUNC(common,canInteractWith)) exitWith {}; + + BEGIN_COUNTER(newIndex); + if ((_shownIndex > -1) && {currentVisionMode _player != _lastVisionMode}) then { + // Vision Mode Changed - Force stop cam and restart + call FUNC(viewCleanup); + _shownIndex = -1; + }; + + ([_player] call FUNC(getSeatInfo)) params ["_role", "", "", "_compartment"]; + + private _newIndexAngle = 45; // Controls the max angle + private _eyesPosASL = AGLtoASL (positionCameraToWorld [0, 0, 0]); + private _eyesDir = (AGLtoASL (positionCameraToWorld [0, 0, 1])) vectorDiff _eyesPosASL; + { + _x params ["", "", "_camLocation", "", "_screenLocation", "_maxDistance", "_compartments", "_roles"]; + + private _viewASL = AGLtoASL (_vehicle modelToWorldVisual _screenLocation); + private _viewDiff = _viewASL vectorDiff _eyesPosASL; + private _viewAngle = acos (_viewDiff vectorCos _eyesDir); + #ifdef DEBUG_MODE_FULL + systemChat format ["%1: %2 @ %3",_forEachIndex,round _viewAngle, vectorMagnitude _viewDiff]; + #endif + if ( + (_viewAngle < _newIndexAngle) + && {(_compartments isEqualTo []) || {(toLowerANSI _compartment) in _compartments}} + && {(_roles isEqualTo []) || {(toLowerANSI _role) in _roles}} + && {(vectorMagnitude _viewDiff) < _maxDistance} + ) then { + _newIndex = _forEachIndex; + _newIndexAngle = _viewAngle; + }; + } forEach _viewports; + END_COUNTER(newIndex); +}; + +if (_shownIndex == _newIndex) exitWith {}; // No-change - fast exit + +if (_shownIndex > -1) then { + call FUNC(viewCleanup); +}; + +if (_newIndex > -1) then { + [_vehicle, _viewports # _newIndex, currentVisionMode _player] call FUNC(viewCreate); + _args set [4, currentVisionMode _player]; +}; + +_args set [3, _newIndex]; diff --git a/addons/viewports/functions/fnc_enterVehicle.sqf b/addons/viewports/functions/fnc_enterVehicle.sqf new file mode 100644 index 0000000000..ccec954060 --- /dev/null +++ b/addons/viewports/functions/fnc_enterVehicle.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Handle playerEH for new changing vehicle, check if it has any viewports and start PFEH + * + * Arguments: + * 0: player + * 1: vehicle + * + * Return Value: + * None + * + * Example: + * [player, vehicle player] call ace_viewports_fnc_enterVehicle + * + * Public: No + */ + +params ["_player", "_vehicle"]; +TRACE_2("enterVehicle",_player,_vehicle); + +if (GVAR(pfeh) != -1) then { + TRACE_1("cleaning up",GVAR(pfeh)); + [GVAR(pfeh)] call CBA_fnc_removePerFrameHandler; + GVAR(pfeh) = -1; + call FUNC(viewCleanup); +}; + +if (!GVAR(enabled)) exitWith {}; +if (_player == _vehicle) exitWith {}; + +private _viewports = [_vehicle] call FUNC(getViewports); +if (_viewports isEqualTo []) exitWith {}; + +GVAR(pfeh) = [LINKFUNC(eachFrame), 0, [_player, _vehicle, _viewports, -1, -1]] call CBA_fnc_addPerFrameHandler; +TRACE_3("start pfeh",GVAR(pfeh),typeOf _vehicle,count _viewports); diff --git a/addons/viewports/functions/fnc_getSeatInfo.sqf b/addons/viewports/functions/fnc_getSeatInfo.sqf new file mode 100644 index 0000000000..01c71c3cfe --- /dev/null +++ b/addons/viewports/functions/fnc_getSeatInfo.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian, PabstMirror + * Adapted from quickmount's addFreeSeatsActions + * + * Arguments: + * 0: Unit + * + * Return Value: + * ARRAY + * + * Example: + * [player] call ace_viewports_fnc_getSeatInfo + * + * Public: No + */ + +params ["_unit"]; + +private _vehicle = vehicle _unit; +if (_vehicle == _unit) exitWith { [] }; +private _vehicleConfig = configOf _vehicle; + +private _fullCrew = fullCrew [_vehicle, "", false]; +(_fullCrew select (_fullCrew findIf {_unit == _x select 0})) params ["", "_role", "_cargoIndex", "_turretPath"]; + +private _compartment = switch (_role) do { + case "driver": { + (_vehicleConfig >> "driverCompartments") call BIS_fnc_getCfgData + }; + case "cargo": { + // note: cargoNumber is different from the cargoIndex from fullCrew... + private _cargoNumber = fullCrew [_vehicle, "cargo", true] findIf {_unit == _x select 0}; + private _cargoCompartments = getArray (_vehicleConfig >> "cargoCompartments"); + private _cargoCompartmentsLast = count _cargoCompartments - 1; + _cargoCompartments select (_cargoNumber min _cargoCompartmentsLast) + }; + default { + private _turretConfig = [_vehicleConfig, _turretPath] call CBA_fnc_getTurret; + (_turretConfig >> "gunnerCompartments") call BIS_fnc_getCfgData + }; +}; + +if !(_compartment isEqualType "") then {_compartment = format ["Compartment%1",_compartment]}; + +[_role, _cargoIndex, _turretPath, _compartment] diff --git a/addons/viewports/functions/fnc_getViewports.sqf b/addons/viewports/functions/fnc_getViewports.sqf new file mode 100644 index 0000000000..744b973151 --- /dev/null +++ b/addons/viewports/functions/fnc_getViewports.sqf @@ -0,0 +1,74 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gets viewports for a vehicle from config. Caches results to a setVar on the vic. + * + * Arguments: + * 0: vehicle + * + * Return Value: + * ARRAY + * + * Example: + * [vehicle player] call ace_viewports_fnc_getViewports + * + * Public: No + */ + +params ["_vehicle"]; + +private _viewports = _vehicle getVariable [QGVAR(viewports), nil]; + +if (isNil "_viewports") then { + _viewports = (configProperties [(configOf _vehicle) >> "ace_viewports", "isClass _x", true]) apply { + // name [STRING] is just used for debug + private _name = configName _x; + // type [STRING] - Optional + private _type = getText (_x >> "type"); + // camLocation [ARRAY or STRING] - Required + private _camLocation = if (isArray (_x >> "camLocation")) then { + getArray (_x >> "camLocation") // modelOffset + } else { + getText (_x >> "camLocation") // memPoint + }; + // camAttach [ARRAY or NUMBER] - Required + private _camAttach = if (isArray (_x >> "camAttach")) then { + getArray (_x >> "camAttach") // turret + } else { + getNumber (_x >> "camAttach") // angle + }; + // screenLocation [ARRAY or STRING] - Optional (will be converted to ARRAY here!) + private _screenLocation = if (isArray (_x >> "screenLocation")) then { + getArray (_x >> "screenLocation") // modelOffset + } else { + getText (_x >> "screenLocation") // memPoint + }; + if (_screenLocation isEqualType "") then { + // screens should be on the hull (IE non-animated) so we can do all the mem-point calculations here + if (_screenLocation == "") exitWith { // use generic periscope drop height from cam + private _camLocArray = if (_camLocation isEqualType []) then { + _camLocation + } else { + _vehicle selectionPosition [_camLocation, "Memory"]; + }; + _screenLocation =_camLocArray vectorAdd [0,0,-0.175] + }; + _screenLocation = _vehicle selectionPosition [_screenLocation, "Memory"]; + }; + // maxDistance [NUMBER] - Optional + private _maxDistance = getNumber (_x >> "maxDistance"); + if (_maxDistance == 0) then { + _maxDistance = 0.8; + }; + // compartments [ARRAY] - Optional + private _compartments = (getArray (_x >> "compartments")) apply {toLowerANSI _x}; + // roles [ARRAY] - Optional + private _roles = (getArray (_x >> "roles")) apply {toLowerANSI _x}; + + [_name, _type, _camLocation, _camAttach, _screenLocation, _maxDistance, _compartments, _roles] + }; + TRACE_3("getViewports",_vehicle,typeOf _vehicle,count _viewports); + _vehicle setVariable [QGVAR(viewports), _viewports]; +}; + +_viewports diff --git a/addons/viewports/functions/fnc_viewCleanup.sqf b/addons/viewports/functions/fnc_viewCleanup.sqf new file mode 100644 index 0000000000..4759439a7e --- /dev/null +++ b/addons/viewports/functions/fnc_viewCleanup.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Cleans up existing viewport display and camera + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_viewports_fnc_viewCleanup + * + * Public: No + */ + +TRACE_1("camCleanup",_this); + +if (!isNull (missionNamespace getVariable [QGVAR(camera), objNull])) then { + GVAR(camera) cameraEffect ["terminate", "back", QGVAR(pip0)]; + camDestroy GVAR(camera); +}; + +private _display = uiNamespace getVariable [QGVAR(display), displayNull]; +if (!isNull _display) then { + QGVAR(display) cutText ["", "PLAIN"]; +}; diff --git a/addons/viewports/functions/fnc_viewCreate.sqf b/addons/viewports/functions/fnc_viewCreate.sqf new file mode 100644 index 0000000000..8b08da9575 --- /dev/null +++ b/addons/viewports/functions/fnc_viewCreate.sqf @@ -0,0 +1,129 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Creates a viewport display and camera + * + * Arguments: + * 0: Vehicle + * 1: Viewport + * 2: Player's vision mode + * + * Return Value: + * None + * + * Example: + * [...] call ace_viewports_fnc_viewCreate + * + * Public: No + */ + +params ["_vehicle", "_viewport", "_visionMode"]; +_viewport params ["_name", "_type", "_camLocation", "_camAttach"]; +TRACE_5("camCreate",_vehicle,_name,_type,_camLocation,_camAttach); + +private _usingGoggles = _visionMode > 0; + +if (_camLocation isEqualType "") then { + _camLocation = _vehicle selectionPosition [_camLocation, "Memory"]; + if (_camLocation isEqualTo [0,0,0]) then { WARNING_2("probably bad cam location %1:%2",typeOf _vehicle,_viewport); } +}; + +// Create Cam and attach it to vic +GVAR(camera) = "camera" camCreate getPos _vehicle; +if (_camAttach isEqualType 0) then { + // number - Static attach and set const direction + GVAR(camera) attachTo [_vehicle, _camLocation]; + GVAR(camera) setDir _camAttach; // could do pitch as well, but probably not needed +} else { + // array - Turret path, get gunner optic mem and bone-attach to it + private _turretConfig = [_vehicle, _camAttach] call CBA_fnc_getTurret; + private _memoryPointGunnerOptics = getText(_turretConfig >> "memoryPointGunnerOptics"); + GVAR(camera) attachTo [_vehicle, _camLocation, _memoryPointGunnerOptics, true]; +}; + +// Setup r2texture +GVAR(camera) cameraEffect ["INTERNAL", "BACK", QGVAR(pip0)]; +private _renderTexture = format ["#(argb,512,512,1)r2t(%1,1)", QGVAR(pip0)]; + +// Create blank display +QGVAR(display) cutRsc [QGVAR(display), "PLAIN", 0, false]; +private _display = uiNamespace getVariable [QGVAR(display), displayNull]; + + +// R2T aspect ratio parameter has no effect - it will match main video AR +// better to have ui elements squashed than to squash the R2T +private _screenAR = getResolution select 4; +private _camEffect = [0]; +private _camFov = 0.75; + + +switch (true) do { + case (_type == "screen"): { + // Generic "Squad Leader's Display" monitor showing turret cam + private _desiredAR = 1.25; + private _stretch = (_desiredAR / _screenAR) max 0.8 min 1.25; // define max stretch factor of pip texture (don't stretch more or less than this) + + private _viewHeight = 0.3 * safeZoneH; + private _viewWidth = _stretch * _viewHeight * _screenAR / 1.3333333333333; + + private _ctrlRender = _display ctrlCreate ["RscPicture", -1]; + _ctrlRender ctrlSetText _renderTexture; + _ctrlRender ctrlSetPosition [safezoneX + 0.5 * safezoneW - 0.5 * _viewWidth, safezoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; + _ctrlRender ctrlCommit 0; + + private _ctrlOverlay = _display ctrlCreate ["RscPicture", -1]; + _ctrlOverlay ctrlSetText "\a3\weapons_f\reticle\data\optika_tv_ca.paa"; + _ctrlOverlay ctrlSetPosition [safezoneX + 0.5 * safezoneW - 0.5 * _viewWidth, safezoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; + _ctrlOverlay ctrlCommit 0; + + if (_usingGoggles) then { + // Screen will be out of focus, too bright and not in IR; should be almost impossible to see anything useful + _camEffect = [3,1,1,0.1,0,[0,0,0,0],[1,1,1,0],[1,1,1,1]]; + + private _ctrlNVG = _display ctrlCreate ["RscPicture", -1]; + _ctrlNVG ctrlSetText "#(argb,8,8,3)color(1,1,0.6,0.9)"; + _ctrlNVG ctrlSetPosition [safezoneX + 0.5 * safezoneW - 0.5 * _viewWidth, safezoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; + _ctrlNVG ctrlCommit 0; + } else { + _camEffect = [0]; // 2.08's currentVisionMode change could allow matching real turret's vision mode + }; + _camFov = 0.25; + }; + default { + // Generic periscope viewport + private _desiredAR = 3; + private _stretch = (_desiredAR / _screenAR) max 0.8 min 1.25; // define max stretch factor of pip texture + private _viewHeight = 0.3 * safeZoneH; + + if (_usingGoggles) then { + _camEffect = [_visionMode]; // pass-thru + // _camEffect = [3, true, 0.747773,0.791092,0,[0,0,0,0],[1.3,1.2,0,0.9],[6,1,1,0]]; + // Some periscope glass is IR Laser Safe (~1064nm) which is close to same wavelength as NVGs + // And cannot apply nvg and ace_nightvision effects to pip at same time, so just make it small and shitty... + _viewHeight = 0.45 * _viewHeight; + }; + private _viewWidth = _stretch * _viewHeight * _screenAR / 1.3333333333333; + + private _ctrlRender = _display ctrlCreate ["RscPicture", -1]; + _ctrlRender ctrlSetText _renderTexture; + _ctrlRender ctrlSetPosition [safezoneX + 0.5 * safezoneW - 0.5 * _viewWidth, safezoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; + _ctrlRender ctrlCommit 0; + + if (_usingGoggles) then { + // Roughly try to color match ace_nvg, and make it semi-opaque + private _ctrlNVG = _display ctrlCreate ["RscPicture", -1]; + _ctrlNVG ctrlSetText "#(argb,8,8,3)color(0.25,0.2,0.05,0.75)"; + _ctrlNVG ctrlSetPosition [safezoneX + 0.5 * safezoneW - 0.5 * _viewWidth, safezoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; + _ctrlNVG ctrlCommit 0; + }; + + private _ctrlOverlay = _display ctrlCreate ["RscPicture", -1]; + _ctrlOverlay ctrlSetText QPATHTOF(data\optic_window_ca.paa); + _ctrlOverlay ctrlSetPosition [safezoneX + 0.5 * safezoneW - 0.5 * _viewWidth, safezoneY + 0.5 * safeZoneH - 0.5 * _viewHeight, _viewWidth, _viewHeight]; + _ctrlOverlay ctrlCommit 0; + }; +}; + +GVAR(camera) camSetFov _camFov; +QGVAR(pip0) setPiPEffect _camEffect; +GVAR(camera) camCommit 0; diff --git a/addons/viewports/gui.hpp b/addons/viewports/gui.hpp new file mode 100644 index 0000000000..6cf3d16823 --- /dev/null +++ b/addons/viewports/gui.hpp @@ -0,0 +1,11 @@ +class RscTitles { + class GVAR(display) { + idd = -1; + onLoad = QUOTE(with uiNameSpace do { GVAR(display) = _this select 0 };); + movingEnable = 0; + duration = 9999999; + fadeIn = 0; + fadeOut = 0; + class controls {}; + }; +}; diff --git a/addons/viewports/initSettings.inc.sqf b/addons/viewports/initSettings.inc.sqf new file mode 100644 index 0000000000..506d3c78a3 --- /dev/null +++ b/addons/viewports/initSettings.inc.sqf @@ -0,0 +1,9 @@ +[ + QGVAR(enabled), "CHECKBOX", + [LELSTRING(common,Enabled), LLSTRING(setting_enabled_description)], + [ELSTRING(common,ACEKeybindCategoryVehicles), LSTRING(addon_displayname)], + true, + true, + {}, + false // Doesn't need full mission restart, but you have to exit and re-enter vic +] call CBA_fnc_addSetting; diff --git a/addons/viewports/script_component.hpp b/addons/viewports/script_component.hpp new file mode 100644 index 0000000000..587a3d3e4e --- /dev/null +++ b/addons/viewports/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT viewports +#define COMPONENT_BEAUTIFIED Viewports +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS +// #define POINT_CONFIG_DEBUG + +#ifdef DEBUG_ENABLED_VIEWPORTS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_VIEWPORTS + #define DEBUG_SETTINGS DEBUG_SETTINGS_VIEWPORTS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/viewports/stringtable.xml b/addons/viewports/stringtable.xml new file mode 100644 index 0000000000..be78cdc995 --- /dev/null +++ b/addons/viewports/stringtable.xml @@ -0,0 +1,29 @@ + + + + + Viewports + ビューポート + 뷰포트 + 观察口 + Periscopi + Wizjery + Триплексы + Periscopios + Sichtfenster + Périscopes + + + Allows crew to look through periscopes + Pozwala załodze patrzeć przez peryskop + 乗組員がペリスコープを通して外を見ることができるようにします + 승무원이 잠망경을 통해 볼 수 있도록 허용합니다 + 允许乘员通过观察口观察 + Permetti all'equipaggio di guardare attraverso periscopi + Разрешить экипажу смотреть сквозь перископ + Permite a la tripulación asomarse a través de los periscopios + Ermöglicht der Besatzung den Blick durch Periskope + Permet à l'équipage de regarder à travers des périscopes. + + + diff --git a/addons/viewrestriction/$PBOPREFIX$ b/addons/viewrestriction/$PBOPREFIX$ new file mode 100644 index 0000000000..046d7e0d08 --- /dev/null +++ b/addons/viewrestriction/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\viewrestriction diff --git a/addons/viewrestriction/ACE_Settings.hpp b/addons/viewrestriction/ACE_Settings.hpp new file mode 100644 index 0000000000..d526e3a3e3 --- /dev/null +++ b/addons/viewrestriction/ACE_Settings.hpp @@ -0,0 +1,29 @@ +#define MACRO_VALUES \ + CSTRING(Disabled), CSTRING(FirstPerson), CSTRING(ThirdPerson) + +class ACE_Settings { + class XGVAR(mode) { + movedToSQF = 1; + }; + class XGVAR(modeSelectiveFoot) { + movedToSQF = 1; + }; + class XGVAR(modeSelectiveLand) { + movedToSQF = 1; + }; + class XGVAR(modeSelectiveAir) { + movedToSQF = 1; + }; + class XGVAR(modeSelectiveSea) { + movedToSQF = 1; + }; + // Disabled - Reference comment in FUNC(canChangeCamera) + /*class GVAR(modeSelectiveUAV) { + category = CSTRING(ModuleDisplayName); + value = 0; + typeName = "SCALAR"; + displayName = CSTRING(ModeSelectiveUAV); + description = CSTRING(ModeSelectiveUAVDesc); + values[] = {MACRO_VALUES}; + };*/ +}; diff --git a/addons/viewrestriction/CfgEventHandlers.hpp b/addons/viewrestriction/CfgEventHandlers.hpp new file mode 100644 index 0000000000..7636444f39 --- /dev/null +++ b/addons/viewrestriction/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_clientInit)); + }; +}; diff --git a/addons/viewrestriction/CfgVehicles.hpp b/addons/viewrestriction/CfgVehicles.hpp new file mode 100644 index 0000000000..4b80829913 --- /dev/null +++ b/addons/viewrestriction/CfgVehicles.hpp @@ -0,0 +1,85 @@ +#define MACRO_OPTIONS \ + class Disabled { \ + default = 1; \ + name = CSTRING(Disabled); \ + value = 0; \ + }; \ + class FirstPerson { \ + name = CSTRING(FirstPerson); \ + value = 1; \ + }; \ + class ThirdPerson { \ + name = CSTRING(ThirdPerson); \ + value = 2; \ + }; + +class CfgVehicles { + class ACE_Module; + class XGVAR(Module): ACE_Module { + author = ECSTRING(common,ACETeam); + category = "ACE"; + function = QFUNC(moduleInit); + displayName = CSTRING(ModuleDisplayName); + scope = 1; + isGlobal = 1; + icon = QUOTE(PATHTOF(UI\Icon_Module_ViewRestriction_ca.paa)); + class Arguments { + class mode { + displayName = CSTRING(Mode); + description = CSTRING(ModeDesc); + typeName = "NUMBER"; + class values { + MACRO_OPTIONS + class Selective { + name = CSTRING(Selective); + value = 3; + }; + }; + }; + class modeSelectiveFoot { + displayName = CSTRING(ModeSelectiveFoot); + description = CSTRING(ModeSelectiveFootDesc); + typeName = "NUMBER"; + class values { + MACRO_OPTIONS + }; + }; + class modeSelectiveLand { + displayName = CSTRING(ModeSelectiveLand); + description = CSTRING(ModeSelectiveLandDesc); + typeName = "NUMBER"; + class values { + MACRO_OPTIONS + }; + }; + class modeSelectiveAir { + displayName = CSTRING(ModeSelectiveAir); + description = CSTRING(ModeSelectiveAirDesc); + typeName = "NUMBER"; + class values { + MACRO_OPTIONS + }; + }; + class modeSelectiveSea { + displayName = CSTRING(ModeSelectiveSea); + description = CSTRING(ModeSelectiveSeaDesc); + typeName = "NUMBER"; + class values { + MACRO_OPTIONS + }; + }; + // Disabled - Reference comment in FUNC(canChangeCamera) + /*class modeSelectiveUAV { + displayName = CSTRING(ModeSelectiveUAV); + description = CSTRING(ModeSelectiveUAVDesc); + typeName = "NUMBER"; + class values { + MACRO_OPTIONS + }; + };*/ + }; + class ModuleDescription { + description = CSTRING(ModuleDescription); + }; + }; +}; diff --git a/addons/viewrestriction/README.md b/addons/viewrestriction/README.md new file mode 100644 index 0000000000..883014f3cd --- /dev/null +++ b/addons/viewrestriction/README.md @@ -0,0 +1,8 @@ +ace_viewrestriction +=============== + +The View Restriction module introduces restricting of first and third person views overall or configured per type. + +## ACEX Conversion - things still using acex prefix +- All settings +- CfgVehicles Module Classname diff --git a/addons/viewrestriction/UI/Icon_Module_ViewRestriction_ca.paa b/addons/viewrestriction/UI/Icon_Module_ViewRestriction_ca.paa new file mode 100644 index 0000000000..3d8f57759d Binary files /dev/null and b/addons/viewrestriction/UI/Icon_Module_ViewRestriction_ca.paa differ diff --git a/addons/viewrestriction/XEH_PREP.hpp b/addons/viewrestriction/XEH_PREP.hpp new file mode 100644 index 0000000000..c9933f04b5 --- /dev/null +++ b/addons/viewrestriction/XEH_PREP.hpp @@ -0,0 +1,5 @@ +ACEX_PREP(canChangeCamera); +ACEX_PREP(changeCamera); +ACEX_PREP(moduleInit); +ACEX_PREP(selectiveChangeCamera); +ACEX_PREP(switchPreserveView); diff --git a/addons/viewrestriction/XEH_clientInit.sqf b/addons/viewrestriction/XEH_clientInit.sqf new file mode 100644 index 0000000000..1ed4f008da --- /dev/null +++ b/addons/viewrestriction/XEH_clientInit.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" + +// Exit on Headless Client +if !(hasInterface) exitWith {}; + +["ace_settingsInitialized", { + // Exit if module is disabled + if (XGVAR(mode) == 0) exitWith {}; + + // Exit if all Selective Modes are Disabled + if (XGVAR(mode) == 3 && + {XGVAR(modeSelectiveFoot) == 0} && + {XGVAR(modeSelectiveLand) == 0} && + {XGVAR(modeSelectiveAir) == 0} && + {XGVAR(modeSelectiveSea) == 0}/* && + {GVAR(modeSelectiveUAV) == 0}*/ + ) exitWith { + WARNING("Selective mode enabled, but all sub-modes are disabled.") + }; + + // Exit if third person view is not available + if (difficultyOption "thirdPersonView" != 1) exitWith { + WARNING("View Restriction is enabled, but 3rd person is disabled with server difficulty."); + }; + + // Add Event Handler for changing camera - also happens on spawn + ["cameraView", { + [_this select 1, cameraOn] call FUNC(changeCamera); + }] call CBA_fnc_addPlayerEventHandler; + + // Add Event Hander for exiting and entering a vehicle when on Selective mode - cameraView does not fire on simple enter/exit + if (XGVAR(mode) == 3) then { + ["vehicle", { + [cameraView, _this select 1] call FUNC(changeCamera); + }] call CBA_fnc_addPlayerEventHandler; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/viewrestriction/XEH_preInit.sqf b/addons/viewrestriction/XEH_preInit.sqf new file mode 100644 index 0000000000..894773534a --- /dev/null +++ b/addons/viewrestriction/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/viewrestriction/XEH_preStart.sqf b/addons/viewrestriction/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/viewrestriction/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/viewrestriction/config.cpp b/addons/viewrestriction/config.cpp new file mode 100644 index 0000000000..40158953cf --- /dev/null +++ b/addons/viewrestriction/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Jonpas", "esteldunedain"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; + + BWC_CONFIG(XADDON); +}; + +#include "CfgEventHandlers.hpp" +#include "ACE_Settings.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/viewrestriction/functions/fnc_canChangeCamera.sqf b/addons/viewrestriction/functions/fnc_canChangeCamera.sqf new file mode 100644 index 0000000000..dc68825da7 --- /dev/null +++ b/addons/viewrestriction/functions/fnc_canChangeCamera.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Checks if camera can be changed. + * + * Arguments: + * 0: New Camera View + * 1: Vehicle + * 2: Check gunner view (default: true) + * + * Return Value: + * Can Change Camera + * + * Example: + * ["INTERNAL", vehicle] call ace_viewrestriction_fnc_canChangeCamera + * + * Public: No + */ + +params ["_newCameraView", "_cameraOn", ["_checkGunnerView", true]]; + +// Remote control hates switchCamera (control returns to player, camera is left on remotely controlled object/unit), make sure remote controlled units are not impacted + +!(_newCameraView isEqualTo "GUNNER" && {_checkGunnerView}) && +{_newCameraView isNotEqualTo "GROUP"} && +{!isNull ACE_player} && +{player == ACE_player} && +{alive ACE_player} && +{ACE_player == _cameraOn || vehicle ACE_player == _cameraOn} && +{"" isEqualTo call CBA_fnc_getActiveFeatureCamera} && +{!(_cameraOn isKindOf "UAV" || _cameraOn isKindOf "UAV_01_base_F")} // UAVs are remote controlled diff --git a/addons/viewrestriction/functions/fnc_changeCamera.sqf b/addons/viewrestriction/functions/fnc_changeCamera.sqf new file mode 100644 index 0000000000..eb6907386a --- /dev/null +++ b/addons/viewrestriction/functions/fnc_changeCamera.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Change camera based on setting. + * + * Arguments: + * 0: New Camera View + * 1: Vehicle + * + * Return Value: + * None + * + * Example: + * ["INTERNAL", vehicle] call ace_viewrestriction_fnc_changeCamera + * + * Public: No + */ + +params ["_newCameraView", "_cameraOn"]; + +if !([_newCameraView, _cameraOn] call FUNC(canChangeCamera)) exitWith {}; + +TRACE_1("View Restricted",XGVAR(mode)); + +// FirstPerson +if (XGVAR(mode) == 1) exitWith { + _cameraOn switchCamera "INTERNAL"; +}; + +// ThirdPerson +if (XGVAR(mode) == 2) exitWith { + _cameraOn switchCamera "EXTERNAL"; +}; + +// Selective +if (XGVAR(mode) == 3) exitWith { + [_cameraOn] call FUNC(selectiveChangeCamera); +}; diff --git a/addons/viewrestriction/functions/fnc_moduleInit.sqf b/addons/viewrestriction/functions/fnc_moduleInit.sqf new file mode 100644 index 0000000000..12f7a36493 --- /dev/null +++ b/addons/viewrestriction/functions/fnc_moduleInit.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Initializes the View Restriction module. + * + * Arguments: + * 0: logic + * 1: Synchronised Units + * 2: Module Activated + * + * Return Value: + * None + * + * Public: No + */ + +params ["_logic", "_units", "_activated"]; + +if (!_activated) exitWith {}; + +[_logic, QXGVAR(mode), "mode"] call EFUNC(common,readSettingFromModule); + +// Read selective options only if selective mode selected +if (XGVAR(mode) == 3) then { + [_logic, QXGVAR(modeSelectiveFoot), "modeSelectiveFoot"] call EFUNC(common,readSettingFromModule); + [_logic, QXGVAR(modeSelectiveLand), "modeSelectiveLand"] call EFUNC(common,readSettingFromModule); + [_logic, QXGVAR(modeSelectiveAir), "modeSelectiveAir"] call EFUNC(common,readSettingFromModule); + [_logic, QXGVAR(modeSelectiveSea), "modeSelectiveSea"] call EFUNC(common,readSettingFromModule); + //[_logic, QGVAR(modeSelectiveUAV), "modeSelectiveUAV"] call EFUNC(common,readSettingFromModule); // Disabled - Reference comment in FUNC(canChangeCamera) + + INFO_5("View Restriction Module Initialized. Mode: %1 (Foot: %2, Land: %3, Air: %4, Sea: %5)",XGVAR(mode),XGVAR(modeSelectiveFoot),XGVAR(modeSelectiveLand),XGVAR(modeSelectiveAir),XGVAR(modeSelectiveSea)); +} else { + INFO_1("View Restriction Module Initialized. Mode: %1",XGVAR(mode)); +}; diff --git a/addons/viewrestriction/functions/fnc_selectiveChangeCamera.sqf b/addons/viewrestriction/functions/fnc_selectiveChangeCamera.sqf new file mode 100644 index 0000000000..ee26739ae4 --- /dev/null +++ b/addons/viewrestriction/functions/fnc_selectiveChangeCamera.sqf @@ -0,0 +1,69 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas + * Changes camera mode based on vehicle type the player is currently occupying. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [vehicle] call ace_viewrestriction_fnc_selectiveChangeCamera + * + * Public: No + */ + +params ["_cameraOn"]; + +// Foot +if (_cameraOn isKindOf "CAManBase") exitWith { + if (XGVAR(modeSelectiveFoot) == 1) exitWith { + _cameraOn switchCamera "INTERNAL"; + }; + if (XGVAR(modeSelectiveFoot) == 2) exitWith { + _cameraOn switchCamera "EXTERNAL"; + }; +}; + +// Land Vehicles +if (_cameraOn isKindOf "LandVehicle") exitWith { + if (XGVAR(modeSelectiveLand) == 1) exitWith { + _cameraOn switchCamera "INTERNAL"; + }; + if (XGVAR(modeSelectiveLand) == 2) exitWith { + _cameraOn switchCamera "EXTERNAL"; + }; +}; + +// UAVs (must be evaluated before Air Vehicles due to inheritance tree) +// Disabled - Reference comment in FUNC(canChangeCamera) +/*if (_cameraOn isKindOf "UAV" || {_cameraOn isKindOf "UAV_01_base_F"}) exitWith { + if (GVAR(modeSelectiveUAV) == 1) exitWith { + _cameraOn switchCamera "INTERNAL"; + }; + if (GVAR(modeSelectiveUAV) == 2) exitWith { + _cameraOn switchCamera "EXTERNAL"; + }; +};*/ + +// Air Vehicles (must be evaluated after UAVs due to inheritance tree) +if (_cameraOn isKindOf "Air") exitWith { + if (XGVAR(modeSelectiveAir) == 1) exitWith { + _cameraOn switchCamera "INTERNAL"; + }; + if (XGVAR(modeSelectiveAir) == 2) exitWith { + _cameraOn switchCamera "EXTERNAL"; + }; +}; + +// Sea Vehicles +if (_cameraOn isKindOf "Ship") exitWith { + if (XGVAR(modeSelectiveSea) == 1) exitWith { + _cameraOn switchCamera "INTERNAL"; + }; + if (XGVAR(modeSelectiveSea) == 2) exitWith { + _cameraOn switchCamera "EXTERNAL"; + }; +}; diff --git a/addons/viewrestriction/functions/fnc_switchPreserveView.sqf b/addons/viewrestriction/functions/fnc_switchPreserveView.sqf new file mode 100644 index 0000000000..63cf8ba8b6 --- /dev/null +++ b/addons/viewrestriction/functions/fnc_switchPreserveView.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Controls View Preserving state. + * + * Arguments: + * 0: Enabled + * + * Return Value: + * None + * + * Example: + * true call ace_viewrestriction_fnc_switchPreserveView + * + * Public: No + */ + +params ["_enabled"]; + +if (!_enabled || {XGVAR(mode) > 0}) exitWith { + if (isNil QGVAR(preserveViewCameraViewEH)) exitWith {}; + ["cameraView", GVAR(preserveViewCameraViewEH)] call CBA_fnc_removePlayerEventHandler; + ["vehicle", GVAR(preserveViewVehicleEH)] call CBA_fnc_removePlayerEventHandler; + GVAR(preserveViewCameraViewEH) = nil; + GVAR(preserveViewVehicleEH) = nil; +}; + +GVAR(preserveViewCameraViewEH) = ["cameraView", { + params ["_player", "_cameraView"]; + if !([_cameraView, cameraOn] call FUNC(canChangeCamera)) exitWith {}; + + private _vehicle = vehicle _player; + private _vehicleClass = {if (_vehicle isKindOf _x) exitWith {_x}} forEach ["CAManBase", "LandVehicle", "Air", "Ship", "All"]; + private _varName = QXGVAR(preserveView) + _vehicleClass; + if (_cameraView isNotEqualTo (profileNamespace getVariable [_varName, ""])) then { + profileNamespace setVariable [_varName, _cameraView]; + }; +}] call CBA_fnc_addPlayerEventHandler; + +GVAR(preserveViewVehicleEH) = ["vehicle", { + params ["_player", "_vehicle"]; + private _cameraView = cameraView; + if !([_cameraView, cameraOn, false] call FUNC(canChangeCamera)) exitWith {}; + + private _vehicleClass = {if (_vehicle isKindOf _x) exitWith {_x}} forEach ["CAManBase", "LandVehicle", "Air", "Ship", "All"]; + private _savedView = profileNamespace getVariable (QXGVAR(preserveView) + _vehicleClass); + if (!isNil "_savedView" && {_cameraView isNotEqualTo _savedView}) then { + _vehicle switchCamera _savedView; + }; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/viewrestriction/initSettings.inc.sqf b/addons/viewrestriction/initSettings.inc.sqf new file mode 100644 index 0000000000..80382f5b19 --- /dev/null +++ b/addons/viewrestriction/initSettings.inc.sqf @@ -0,0 +1,64 @@ +[ + QXGVAR(mode), + "LIST", + [LSTRING(Mode), LSTRING(ModeDesc)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + [[0, 1, 2, 3], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson), LSTRING(Selective)], 0], + true, + {[QGVAR(mode), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(modeSelectiveFoot), + "LIST", + [LSTRING(ModeSelectiveFoot), LSTRING(ModeSelectiveFootDesc)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], + true, + {[QGVAR(modeSelectiveFoot), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(modeSelectiveLand), + "LIST", + [LSTRING(ModeSelectiveLand), LSTRING(ModeSelectiveLandDesc)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], + true, + {[QGVAR(modeSelectiveLand), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(modeSelectiveAir), + "LIST", + [LSTRING(ModeSelectiveAir), LSTRING(ModeSelectiveAirDesc)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], + true, + {[QGVAR(modeSelectiveAir), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(modeSelectiveSea), + "LIST", + [LSTRING(ModeSelectiveSea), LSTRING(ModeSelectiveSeaDesc)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], + true, + {[QGVAR(modeSelectiveSea), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QXGVAR(preserveView), + "CHECKBOX", + [LSTRING(SettingPreserveViewName), LSTRING(SettingPreserveViewDesc)], + format ["ACE %1", LLSTRING(ModuleDisplayName)], + false, + false, + LINKFUNC(switchPreserveView) +] call CBA_fnc_addSetting; diff --git a/addons/viewrestriction/script_component.hpp b/addons/viewrestriction/script_component.hpp new file mode 100644 index 0000000000..a86b4df577 --- /dev/null +++ b/addons/viewrestriction/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT viewrestriction +#define COMPONENT_BEAUTIFIED View Restriction +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_VIEWRESTRICTION + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_VIEWRESTRICTION + #define DEBUG_SETTINGS DEBUG_SETTINGS_VIEWRESTRICTION +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/viewrestriction/stringtable.xml b/addons/viewrestriction/stringtable.xml new file mode 100644 index 0000000000..fee4a9bf33 --- /dev/null +++ b/addons/viewrestriction/stringtable.xml @@ -0,0 +1,300 @@ + + + + + View Restriction + Ograniczenie widoczności + Sichteinschränkungen + Korlátozások + 視点制限 + 시점 제한 + Restriction Vue + 人称限制 + 視野限制 + Restrizione di Visuale + Ограничение обзора + Görüntüyü Kısıtla + Reestricción de Vista + + + View restriction settings to limit the usage of 1st or 3rd person views globally or per vehicle type. + Ograniczenie widoczności ze względu na użycie 1. lub 3. os. globalnie, lub z uwzględnieniem typu pojazdu. + Einstellungen um Egoperspektive und Third-Person-Perspektive global oder pro Fahrzeugtyp zu limitieren. + 全体や車両ごとで使える視点を1人称か3人称視点のどちらかに制限します。 + 차량 유형별, 혹은 전체적으로 1,3인칭 시점 사용 제한 설정 + La restriction de la vue limite l'usage de la vue à la 1ère/3ème personne globalement ou par type de véhicule. + 人称限制可以设定在全局或是局部状况下能用的人称模式。 + 視野限制可以設定在全局或是局部狀況下能用的視野模式。 + Impostazioni di restrizione visuale per limitare l'utilizzo di prima e terza persona a livello globale o per tipologia di veicolo. + Настройки ограничения обзора при виде от 1-го или 3-го лица. Общие для всех, или Выборочные, в зависимости от техники. + 1. veya 3. kişi görünümlerinin kullanımını genel olarak veya araç türüne göre sınırlamak için kısıtlama ayarlarını görüntüleyin. + Opciones de Reestricción de Vista para limitar el uso de 1º o 3º persona globalmente o según el tipo de vehículo. + + + Mode + Tryb + Modus + Mód + モード + 모드 + Mode + 模式 + 模式 + Modalità + Режим установок + Mod + Modo + + + Sets global mode. Default: Disabled + Zmienia tryb globalny. (Domyślnie: Wyłączony) + Globaler Modus. (Standard: Deaktiviert) + Globális mód beállítása. Alapértelmeyett: Kikapcsolva + グローバル モードの設定。 (デフォルト: 無効) + 전체 모드를 사용합니다. 기본값: 사용 안 함 + Mode global. Défaut: Désactivé + 设定全局的人称模式。预设:关闭 + 設定全局的視野模式。預設:關閉 + Imposta modalità globale. Default: Disabilitato + Общие установки для всех. По умолчанию: Отключено. + Global modu ayarlar. Varsayılan: Devre Dışı + Establece el modo global. Defecto: Deshabilitado + + + (Selective) Foot + (Tryb selektywny) Piechota + (Selektiv) zu Fuß + (Szelektív) Gyalogos + (選択性) 地上 + (선택) 보병 + (Sélectif) A pied + (可选)步行 + (可選) 步行 + (Selettiva) Piedi + (Выборочные) Пешком + (Seçilebilir) Ayakta + (Selectivo) Pie + + + Selective mode on Foot. Default: Disabled (Requires Mode: Selective) + Tryb selektywny piechoty. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) + Selektiver Modus zu Fuß. (Standard: Deaktiviert, Benötigt Modus: Selektiv) + Szelektív mód Gyalogosan. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) + 地上でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) + 보병 시점. 기본값: 사용 안 함 (모드-선택 필요) + Mode sélectif hors des véhicules. Défaut: Désactivé (Nécessite Mode: Sélectif) + 设定在步行的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') + 設定在步行的狀況下能使用的視野模式。預設:關閉(需在全局設定中先選擇'使用可選設定') + Modalità selettiva su Piedi. Default: Disabilitato (Necessita della Modalità: Selettiva) + Выборочные установки без техники. По умолчанию: Отключено (требуется режим: Выборочные) + Ayakta iken seçilen görüş modu. Varsayılan: Etkin Değil + Modo selectivo a pie. Defecto: Deshabilitado (Requiere Modo: Selectivo) + + + (Selective) Land Vehicles + (Tryb selektywny) Pojazdy + (Selektiv) Landfahrzeuge + (Szelektív) Szárazföldi Járművek + (選択性) 地上車両 + (선택) 지상 차량 + (Sélectif) Véhicules terrestres + (可选)陆上载具 + (可選) 陸上載具 + (Selettiva) Veicoli Terrestri + (Выборочные) Наземная техника + (Seçilebilir) Kara Araçları + (Selectivo) Vehículos de tierra + + + Selective mode in Land Vehicles. Default: Disabled (Requires Mode: Selective) + Tryb selektywny pojazdów. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) + Selektiver Modus in Landfahrzeugen. (Standard: Deaktiviert, Benötigt Modus: Selektiv) + Szelektív mód a Szárazföldi Járművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) + 地上車両でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) + 차량 시점. 기본값: 사용 안 함 (모드-선택 필요) + Mode sélectif dans les véhicules terrestres. Défaut: Désactivé (Nécessite Mode: Sélectif) + 设定在搭乘陆上载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') + 設定在搭乘陸上載具的狀況下能使用的視野模式。預設:關閉(需在全局設定中先選擇'使用可選設定') + Modalità selettiva su Veicoli Terrestri. Default: Disabilitato (Necessita della Modalità: Selettiva) + Выборочные установки для наземной техники. По умолчанию: Отключено (требуется режим: Выборочные) + Kara araçlarında iken seçilen görüş modu. Varsayılan: Etkin Değil + Modo selectivo en vehículos de tierra.Defecto: Deshabilitado (Requiere Modo: Selectivo) + + + (Selective) Air Vehicles + (Tryb selektywny) Lotnictwo + (Selektiv) Luftfahrzeuge + (Szelektív) Légijárművek + (選択性) 航空機 + (선택) 항공기 + (Sélectif) Véhicules aériens + (可选)空中载具 + (可選) 空中載具 + (Selettiva) Veicolo Aerei + (Выборочные) Авиатехника + (Seçilebilir) Hava Araçları + (Selectivo) Vehículos aéreos + + + Selective mode in Air Vehicles. Default: Disabled (Requires Mode: Selective) + Tryb selektywny lotnictwa. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) + Selektiver Modus in Luftfahrzeugen. (Standard: Deaktiviert, Benötigt Modus: Selektiv) + Szelektív mód a Légijárművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) + 航空機でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) + 항공기 시점. 기본값: 사용 안 함 (모드-선택 필요) + Mode sélectif dans les véhicules aériens. Défaut: Désactivé (Nécessite Mode: Sélectif) + 设定在搭乘空中载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') + 設定在搭乘空中載具的狀況下能使用的視野模式。預設:關閉(需在全局設定中先選擇'使用可選設定') + Modalità selettiva su Veicoli Aerei. Default: Disabilitato (Necessita della Modalità: Selettiva) + Выборочные установки для авиатехники. По умолчанию: Отключено (требуется режим: Выборочные) + Hava araçlarında iken seçilen görüş modu. Varsayılan: Etkin Değil + Modo selectivo en vehículos aéreos. Defecto: Deshabilitado (Requiere Modo: Selectivo) + + + (Selective) Sea Vehicles + (Tryb selektywny) Jednostki pływające + (Selektiv) Wasserfahrzeuge + (Szelektív) Vízi Járművek + (選択性) 船舶 + (선택) 함선 + (Sélectif) Véhicules marins + (可选)水上载具 + (可選) 水上載具 + (Selettiva) Veicoli Marittimi + (Выборочные) Водный транспорт + (Seçilebilir) Deniz Araçları + (Selectivo) Vehículos marítimos + + + Selective mode in Sea Vehicles. Default: Disabled (Requires Mode: Selective) + Tryb selektywny jednostek pływających. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) + Selektiver Modus zu Fuß. (Standard: Deaktiviert, Benötigt Modus: Selektiv) + Szelektív mód a Vízi Járművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) + 船舶でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) + 함선 시점. 기본값: 사용 안 함 (모드-선택 필요) + Mode sélectif dans les véhicules marins. Défaut: Désactivé (Nécessite Mode: Sélectif) + 设定在搭乘水上载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') + 設定在搭乘水上載具的狀況下能使用的視野模式。預設:關閉(需在全局設定中先選擇'使用可選設定') + Modalità selettiva su Veicoli Marittimi. Default: Disabilitato (Necessita della Modalità: Selettiva) + Выборочные установки для водного транспорта. По умолчанию: Отключено (требуется режим: Выборочные) + Deniz araçlarında iken seçilen görüş modu. Varsayılan: Etkin Değil + Modo selectivo en vehículos marítimos. Defecto: Deshabilitado (Requiere Modo: Selectivo) + + + (Selective) UAVs + (Tryb selektywny) UAV + (Selektiv) Unbemannte Luftfahrzeuge + (Szelektív) Pilóta Nélüli Légijárművek + (選択性) 無人機 + (선택) 무인기 + (Sélectif) Drones + (可选)无人机 + (可選) 無人載具 + (Selettiva) UAV + (Выборочные) Беспиплотники + (Seçilebilir) IHA'lar + (Selectivo) VANTs + + + Selective mode in UAVs. Default: Disabled (Requires Mode: Selective) + Tryb selektywny UAV. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) + Selektiver Modus in unbemannten Luftfahrzeugen. (Standard: Deaktiviert, Benötigt Modus: Selektiv + Szelektív mód a Pilóta Nélküli Légijárművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) + 無人機でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) + 무인기 시점. 기본값: 사용 안 함 (모드-선택 필요) + Mode sélectif dans les drones. Défaut: Désactivé (Nécessite Mode: Sélectif) + 设定在搭乘无人载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') + 設定在搭乘無人載具的狀況下能使用的視野模式。預設:關閉(需在全局設定中先選擇'使用可選設定') + Modalità selettiva su UAV. Default: Disabilitato (Necessita della Modalità: Selettiva) + Выборочные установки для беспилотников. По умолчанию: Отключено (требуется режим: Выборочные) + IHA araçlarında iken seçilen görüş modu. Varsayılan: Etkin Değil + Modo selectivo en VANTs. Defecto: Deshabilitado (Requiere Modo: Selectivo) + + + Disabled + Wyłączony + Deaktiviert + Kikapcsolva + 無効 + Disabilitata + 사용 안 함 + Désactivé + 关闭 + 關閉 + Отключено + Devre Dışı + Deshabilitado + + + Forced 1st Person + Wymuś 1. osobę + Erzwungene Egoperspektive + Prima persona forzata + 1人称視点に強制 + 강제 1인칭 + Impose la 1ère personne + 强制使用第一人称 + 強制使用第一人稱 + От 1-го лица (принудительно) + 1. Kişi Görüşüne Zorla + Forzada 1º persona + + + Forced 3rd Person + Wymuś 3. osobę + Erzwungene Third-Person-Perspektive + Terza persona forzata + 3人称視点に強制 + 강제 3인칭 + Impose la 3ème personne + 强制使用第三人称 + 強制使用第三人稱 + От 3-го лица (принудительно) + 3. Kişi Görüşüne Zorla + Forzada 3º persona + + + Selective + Selektywny + Selektiv + Selettiva + Szelektív + 選択性 + 선택 + Sélectif + 使用可选设定 + 使用可選設定 + Выборочный + Seçilebilinir + Selectivo + + + Preserve view for vehicle types + Behalte die Ansicht bei Fahrzeugtypen bei + Mantieni visuale per tipo di veicolo + Запоминать вид для типов техники + 車両の種別により視点を変更 + 保留載具的視野模式 + 保留载具的人称模式 + Zachowaj ustawienie widoku dla pojazdów + Araç türleri için görünümü koru + 차량 타입에 따른 시야 정보 저장 + Preservar vista para los tipos de vehículos + Conserver la vue pour les types de véhicules + + + Switch view on vehicle change to last used in this vehicle type (Requires Mode: Disabled) + Wechsel die Ansicht bei Fahrzeugwechsel zu der zuletzt genutzen in diesen Fahrzeugtyp. (Benötigt Modus: Ausgeschaltet) + Cambia la visuale quando si cambia veicolo a quella usata la volta precedente su un veicolo dello stesso tipo (Richiede modalità: Disattivata) + Переключать вид при смене техники на последний использованный в данном типе техники (требуется режим: Отключено) + 車両変更時の視点をその車両種別で最後に使用したものに切り替えます (要求モード: 無効) + 切換到載具時自動切換到上次最後使用的視野模式(需求模式:關閉) + 切换到载具时自动切换到上次最后使用的人称模式(需求模式:关闭) + Zmień widok podczas zmiany pojazdu na ustawienie widoku z ostatniego używanego pojazdu tego typu (Wymaga Tryb: Wyłączony + Araçlar için en son kullanılan bakış türünü kaydet. + 해당 차량 타입에서 마지막으로 사용했던 시야로 설정하여 봅니다 (모드 - 사용 안함 필요) + Cambiar vista en el cambio de vehículo hacia la última usada en ese tipo de vehículo (Requiere Modo: Deshabilitado) + Lors d'un changement de véhicule, change la vue pour la dernière utilisée dans ce type de véhicule (Mod requis : désactivé). + + + diff --git a/addons/volume/$PBOPREFIX$ b/addons/volume/$PBOPREFIX$ new file mode 100644 index 0000000000..0207eb5918 --- /dev/null +++ b/addons/volume/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\volume diff --git a/addons/volume/ACE_Settings.hpp b/addons/volume/ACE_Settings.hpp new file mode 100644 index 0000000000..6b3a527235 --- /dev/null +++ b/addons/volume/ACE_Settings.hpp @@ -0,0 +1,20 @@ +class ACE_Settings { + class XGVAR(enabled) { + movedToSQF = 1; + }; + class XGVAR(reduction) { + movedToSQF = 1; + }; + class XGVAR(fadeDelay) { + movedToSQF = 1; + }; + class XGVAR(lowerInVehicles) { + movedToSQF = 1; + }; + class XGVAR(showNotification) { + movedToSQF = 1; + }; + class XGVAR(remindIfLowered) { + movedToSQF = 1; + }; +}; diff --git a/addons/volume/CfgEventHandlers.hpp b/addons/volume/CfgEventHandlers.hpp new file mode 100644 index 0000000000..bff1c64e94 --- /dev/null +++ b/addons/volume/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient)); + }; +}; diff --git a/addons/volume/README.md b/addons/volume/README.md new file mode 100644 index 0000000000..88dcd37c6e --- /dev/null +++ b/addons/volume/README.md @@ -0,0 +1,8 @@ +ace_volume +========== + +Volume module reduces volume in vehicles or on keypress. + +## ACEX Conversion - things still using acex prefix +- All settings +- CBA Keybind ID diff --git a/addons/volume/XEH_PREP.hpp b/addons/volume/XEH_PREP.hpp new file mode 100644 index 0000000000..e90c8d6929 --- /dev/null +++ b/addons/volume/XEH_PREP.hpp @@ -0,0 +1,3 @@ +ACEX_PREP(lowerVolume); +ACEX_PREP(remind); +ACEX_PREP(restoreVolume); diff --git a/addons/volume/XEH_postInitClient.sqf b/addons/volume/XEH_postInitClient.sqf new file mode 100644 index 0000000000..896bb718f8 --- /dev/null +++ b/addons/volume/XEH_postInitClient.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +["ACE3 Common", QXGVAR(toggle), [LLSTRING(KeybindName), LLSTRING(KeybindDescription)], "", { + if (!XGVAR(enabled)) exitWith { + if (GVAR(isLowered)) then { + call FUNC(restoreVolume); + }; + }; + + if (GVAR(isLowered)) then { + call FUNC(restoreVolume); + } else { + call FUNC(lowerVolume); + }; + + false +}] call CBA_fnc_addKeybind; + +["vehicle", { + params ["_unit"]; + + if (!XGVAR(lowerInVehicles)) exitWith {}; + + if (!isNull objectParent _unit) then { + call FUNC(lowerVolume); + } else { + call FUNC(restoreVolume); + }; +}] call CBA_fnc_addPlayerEventHandler; + +// Self-calling reminder +[FUNC(remind), [], REMINDER_DELAY] call CBA_fnc_waitAndExecute; + +// Restore volume on respawn +ace_player addEventHandler ["Respawn", FUNC(restoreVolume)]; diff --git a/addons/volume/XEH_preInit.sqf b/addons/volume/XEH_preInit.sqf new file mode 100644 index 0000000000..775f4d71d5 --- /dev/null +++ b/addons/volume/XEH_preInit.sqf @@ -0,0 +1,15 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.inc.sqf" + +GVAR(isLowered) = false; +GVAR(initialGameVolume) = soundVolume; +GVAR(initialMusicVolume) = musicVolume; + +ADDON = true; diff --git a/addons/volume/XEH_preStart.sqf b/addons/volume/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/volume/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/volume/config.cpp b/addons/volume/config.cpp new file mode 100644 index 0000000000..e6802311ea --- /dev/null +++ b/addons/volume/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Kingsley"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "ACE_Settings.hpp" diff --git a/addons/volume/functions/fnc_lowerVolume.sqf b/addons/volume/functions/fnc_lowerVolume.sqf new file mode 100644 index 0000000000..5e8658fb95 --- /dev/null +++ b/addons/volume/functions/fnc_lowerVolume.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Lowers the game and music volume with values from ACE settings. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_volume_fnc_lowerVolume + * + * Public: No + */ + +EGVAR(hearing,disableVolumeUpdate) = true; + +private _coef = XGVAR(reduction) / 10; +private _reductionGame = _coef * GVAR(initialGameVolume); +private _reductionMusic = _coef * GVAR(initialMusicVolume); + +XGVAR(fadeDelay) fadeSound (GVAR(initialGameVolume) - _reductionGame); +XGVAR(fadeDelay) fadeMusic (GVAR(initialMusicVolume) - _reductionMusic); + +GVAR(isLowered) = true; + +if (XGVAR(showNotification)) then { + [LLSTRING(Lowered)] call EFUNC(common,displayTextStructured); +}; diff --git a/addons/volume/functions/fnc_remind.sqf b/addons/volume/functions/fnc_remind.sqf new file mode 100644 index 0000000000..ec9b26b064 --- /dev/null +++ b/addons/volume/functions/fnc_remind.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Reminds about lowered volume. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_volume_fnc_remind + * + * Public: No + */ + +// Exit if reminder not enabled or not lowered +if (!XGVAR(remindIfLowered) || {!GVAR(isLowered)}) exitWith {}; + +[LLSTRING(LoweredReminder)] call EFUNC(common,displayTextStructured); + +// Fire another reminder in 60s +[FUNC(remind), [], REMINDER_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/volume/functions/fnc_restoreVolume.sqf b/addons/volume/functions/fnc_restoreVolume.sqf new file mode 100644 index 0000000000..6ebe2fc7db --- /dev/null +++ b/addons/volume/functions/fnc_restoreVolume.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Kingsley + * Restores the game and music volume to what it was when the mission first started, + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_volume_fnc_restoreVolume + * + * Public: No + */ + +EGVAR(hearing,disableVolumeUpdate) = false; + +XGVAR(fadeDelay) fadeSound GVAR(initialGameVolume); +XGVAR(fadeDelay) fadeMusic GVAR(initialMusicVolume); + +GVAR(isLowered) = false; + +if (XGVAR(showNotification)) then { + [LLSTRING(Restored)] call EFUNC(common,displayTextStructured); +}; diff --git a/addons/volume/initSettings.inc.sqf b/addons/volume/initSettings.inc.sqf new file mode 100644 index 0000000000..44bb464a1e --- /dev/null +++ b/addons/volume/initSettings.inc.sqf @@ -0,0 +1,47 @@ +[ + QXGVAR(enabled), + "CHECKBOX", + [ELSTRING(common,Enabled), LSTRING(KeybindDescription)], + format ["ACE %1", LLSTRING(Name)], + false +] call CBA_fnc_addSetting; + +[ + QXGVAR(reduction), + "LIST", + [LSTRING(Reduction), LSTRING(ReductionDescription)], + format ["ACE %1", LLSTRING(Name)], + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5] +] call CBA_fnc_addSetting; + +[ + QXGVAR(fadeDelay), + "LIST", + [LSTRING(FadeDelay), LSTRING(FadeDelayDescription)], + format ["ACE %1", LLSTRING(Name)], + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1] +] call CBA_fnc_addSetting; + +[ + QXGVAR(lowerInVehicles), + "CHECKBOX", + [LSTRING(LowerInVehicles), LSTRING(LowerInVehiclesDescription)], + format ["ACE %1", LLSTRING(Name)], + false +] call CBA_fnc_addSetting; + +[ + QXGVAR(showNotification), + "CHECKBOX", + [LSTRING(ShowNotification), LSTRING(ShowNotificationDescription)], + format ["ACE %1", LLSTRING(Name)], + true +] call CBA_fnc_addSetting; + +[ + QXGVAR(remindIfLowered), + "CHECKBOX", + [LSTRING(RemindIfLowered), LSTRING(RemindIfLoweredDescription)], + format ["ACE %1", LLSTRING(Name)], + false +] call CBA_fnc_addSetting; diff --git a/addons/volume/script_component.hpp b/addons/volume/script_component.hpp new file mode 100644 index 0000000000..0c31011458 --- /dev/null +++ b/addons/volume/script_component.hpp @@ -0,0 +1,20 @@ +#define COMPONENT volume +#define COMPONENT_BEAUTIFIED Volume +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_VOLUME + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_VOLUME + #define DEBUG_SETTINGS DEBUG_SETTINGS_VOLUME +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + + +#define REMINDER_DELAY 60 diff --git a/addons/volume/stringtable.xml b/addons/volume/stringtable.xml new file mode 100644 index 0000000000..feecb28b10 --- /dev/null +++ b/addons/volume/stringtable.xml @@ -0,0 +1,224 @@ + + + + + Volume + Lautstärke + Volume + 音量 + 음량 + 音量 + 音量 + Volume + Громкость + Głosność + Ses + Volumen + + + Toggle Volume + Lautstärke umschalten + 音量を切り替え + Bascule Volume + 음량 토글 + 切换音量 + 切換音量 + Cambia Volume + Переключить громкость + Przełącz Głosność + Sesi Aç/Kapat + Activar control de volumen + + + Toggle volume reduction. + Lautstärkeverringerung umschalten. + 音量を一時的に低減します。 + Active la réduction du volume. + 토글하여 음량 감소합니다. + 切换降低音量。 + 切換降低音量。 + Cambia Riduzione del Volume. + Переключает уменьшение громкости + Przełącz redukcje głosności + Ses azaltmayı aç / kapat. + Activar reducción de volumen. + + + Lowered volume + Lautstärke veringert + 音量を下げました + Volume réduit + 음량 감소됨 + 降低音量 + 降低音量 + Volume Abbassato + Громкость снижена + Zmniejszona głosność + Azaltılmış ses + Volumen reducido + + + Restored volume + Lautstärke wiederhergestellt + 音量を戻しました + Volume rétabli + 음량 복구됨 + 恢复音量 + 回復音量 + Volume Ripristinato + Громкость восстановлена + Przywrócona głosność + Volumen restaurado + + + Reduction + Reduzierung + 低減 + Réduction + 감소 + 降低 + 降低 + Riduzione + Уменьшение + Redukcja + Reducción + + + Reduce volume by this percentage. + Reduziere Lautstärke um diesen Prozentsatz. + この割合で音量を低減します。 + Réduit le volume de ce pourcentage. + 다음의 비율로 음량을 감소합니다. + 使用此百分比来调整音量降低大小。 + 使用此百分比來調整音量降低大小。 + Riduci il volume di questa percentuale. + Уменьшает громкость + Zmniejsz głosność o tyle procent + Reducir el volumen este porcentaje. + + + Lower in vehicles + Verringere in Fahrzeugen + 車両内で低減 + Réduit dans les véhicules + 차량에서 감소함 + 在载具中降低音量 + 在載具中降低音量 + Più basso nei veicoli + Уменьшать в технике + Zmniejsz w pojazdach + Araçlarda Daha Düşük + Reducir en vehículos + + + Automatically lower volume when inside vehicles. + Verringere die Lautstärke innerhalb von Fahrzeugen automatisch. + 車両内では自動的に音量を低減させます。 + Réduit automatiquement le volume à l'intérieur des véhicules. + 차량 내에 있으면 자동으로 음량을 감소시킵니다. + 当搭乘载具时自动降低音量。 + 當搭乘載具時自動降低音量。 + Riduce automaticamente il volume quando dentro i veicoli. + Автоматически уменьшать громкость в технике + Automatycznie zmniejsz głosność będąc w pojeździe + Araçlara binince sesi azalt. + Reduce automáticamente el volumen dentro de vehículos. + + + Show notification + Zeige Benachrichtigung + 通知を表示 + Afficher notification + 설정 보기 + 显示提示 + 顯示提示 + Mostra notifica + Показывать уведомление + Pokaż powiadomienie + Bildirim Göster + Mostrar notificación + + + Show notification when lowering/restoring volume. + Zeige Benachrichtigung, wenn Lautstärke verringert/wiederhergestellt wurde. + 音量を低減、復元時に通知を表示します。 + Affiche une notification lorsque le volume est réduit/rétabli. + 음량이 감소/복구될 때 메시지를 표시합니다. + 当正在降低/恢复音量时显示提示。 + 當正在降低/回復音量時顯示提示。 + Mostra notifiche quando si abbassa/ripristina il volume. + Показывать уведомление при уменьшении/восстановлении громкости + Pokaż powiadomienie zmniejszając/odnawiając głosność + Ses azaltıldığın da bildirim göster. + Mostrar notificación cuando se disminuye/restaura el volumen. + + + Fade delay + Ausblendzeit + フェードの遅延 + Retard fondu + 페이드 지연 + 淡出/入延迟 + 淡出/入延遲 + Latenza del cambio volume + Задержка затухания + Opoznienie wyciszenia + Retardo en disminución gradual + + + Time it takes (in seconds) for the sound to fade in/out. + Zeit, die es benötigt (in Sekunden), für das Geräusch, ein- bzw. auszublenden. + 音がフェードイン/アウトするまでの時間。 (秒単位) + Temps nécessaire (en secondes) aux sons pour être réduits/rétablis. + 페이드 인/아웃 되는데 걸리는 시간(초) + 设定音量淡出/入时所需的秒数。 + 設定音量淡出/入時所需的秒數。 + Il tempo che impiega (in secondi) il suono a cambiare volume. + Время (сек.) для затухания/восстановления звука. + Ilość czasu (w sekundach) ile zajmuje wyciszenie/zgłośnienie dźwięku + Tiempo que tarda (en segundos) para que se active o desactive la disminuación gradual del volumen + + + Reminder if lowered + Erinnere wenn verringert + 低減時に通知 + Rappel si réduit + 감소 시 알림 + 降低音量时是否提醒 + 降低音量時是否提醒 + Notifica se diminuito + Напоминать о снижении громкости + Przypomnij o zmniejszonej głosności dźwięku + Eğer Düşükse Hatırlat + Recordatorio s reducido + + + Reminds you every minute if your volume is lowered. + Erinnert dich jede Minute, wenn deine Lautstärke verringert wurde. + 音量を低減時は毎分ごとに通知します。 + Rappelle chaque minute que le volume est réduit. + 음량이 감소되면 매 분 마다 알려줍니다 + 开启后会每分钟警告一次你的音量已被降低。 + 開啟後會每分鐘警告一次你的音量已被降低。 + Ti notifica ogni minuto se il tuo volume è abbassato. + Ежеминутное напоминание о сниженной громкости + Przypomina co minuten o zmniejszonej głosności dźwięku + Eğer ses düşükse her dakika hatırlatır. + Te recuerda cada minuto si el volumen está siendo reducido. + + + Volume still lowered + Lautstärke noch immer verringert. + 音量を低減中です + Volume réduit + 음량 감소 중 + 降低音量中 + 降低音量中 + Il volume è ancora abbassato + Громкость все еще снижена + Dźwięk jest nadal zmniejszony + Ses hala düşük + Volumen todavía reducido + + + diff --git a/addons/weaponselect/CfgEventHandlers.hpp b/addons/weaponselect/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/weaponselect/CfgEventHandlers.hpp +++ b/addons/weaponselect/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/weaponselect/README.md b/addons/weaponselect/README.md index 2292140816..417fc3c3fa 100644 --- a/addons/weaponselect/README.md +++ b/addons/weaponselect/README.md @@ -2,11 +2,3 @@ ace_weaponselect ================ Adds the ability to quickly select weapons using the number keys. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index 4706363271..e9f05de8bb 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -183,25 +183,25 @@ if (!hasInterface) exitWith {}; {false}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; //Unbound (was 5 Key) -["ACE3 Vehicles", QGVAR(FireSmokeLauncher), localize LSTRING(FireSmokeLauncher), { - // Conditions: canInteract - if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if !(ACE_player != vehicle ACE_player && {ACE_player == commander vehicle ACE_player}) exitWith {false}; +// ["ACE3 Vehicles", QGVAR(FireSmokeLauncher), localize LSTRING(FireSmokeLauncher), { +// // Conditions: canInteract +// if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; +// // Conditions: specific +// if !(ACE_player != vehicle ACE_player && {ACE_player == commander vehicle ACE_player}) exitWith {false}; - // Statement - [vehicle ACE_player] call FUNC(fireSmokeLauncher); - true -}, -{false}, -[10, [false, false, false]], false] call CBA_fnc_addKeybind; //9 Key +// // Statement +// [vehicle ACE_player] call FUNC(fireSmokeLauncher); +// true +// }, +// {false}, +// [10, [false, false, false]], false] call CBA_fnc_addKeybind; //9 Key ["ACE3 Vehicles", QGVAR(CollisionLights), localize LSTRING(CollisionLights), { // Conditions: canInteract - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((ACE_player isEqualTo (vehicle ACE_player)) || {ACE_player != (driver (vehicle ACE_player))}) exitWith {false}; - + // Statement (vehicle ACE_player) setCollisionLight !(isCollisionLightOn (vehicle ACE_player)); true @@ -210,4 +210,4 @@ if (!hasInterface) exitWith {}; [0, [false, false, false]]] call CBA_fnc_addKeybind; // Register fire event handler -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; diff --git a/addons/weaponselect/XEH_preInit.sqf b/addons/weaponselect/XEH_preInit.sqf index 01c9f2484f..e699f3d2f3 100644 --- a/addons/weaponselect/XEH_preInit.sqf +++ b/addons/weaponselect/XEH_preInit.sqf @@ -11,21 +11,23 @@ GVAR(GrenadesAll) = []; GVAR(GrenadesFrag) = []; GVAR(GrenadesNonFrag) = []; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + { - private _magazines = getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); + private _magazines = getArray (_cfgThrow >> _x >> "magazines"); GVAR(GrenadesAll) append _magazines; { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + private _explosive = getNumber (_cfgAmmo >> _ammo >> "explosive"); ([GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select (_explosive == 0)) pushBack _x; - false - } count _magazines; - false -} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); + } forEach _magazines; +} forEach getArray (_cfgThrow >> "muzzles"); -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf b/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf index c87047a787..f43a8f00da 100644 --- a/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf +++ b/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: esteldunedain, commy2 * Display a grenade type and quantity. diff --git a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf index f1bd108926..8b9fcf94b7 100644 --- a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf +++ b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Fire Vehicle Smoke Launcher. @@ -22,7 +22,7 @@ private _weapons = _vehicle weaponsTurret _turret; if ( count _weapons > 1 - || {count _weapons > 0 && {!(_weapons select 0 in ["SmokeLauncher", "BWA3_SmokeLauncher"])}} // @todo somebody might use custom smoke launcher weapons aswell, maybe ... + || {_weapons isNotEqualTo [] && {!(_weapons select 0 in ["SmokeLauncher", "BWA3_SmokeLauncher"])}} // @todo somebody might use custom smoke launcher weapons aswell, maybe ... ) then { //This doesn't work reliably for vehilces with additional weapons for the commander. Select smoke launcher instead. diff --git a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf index 86945dbaac..fc55b54b5f 100644 --- a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Play weapon firemode change sound. @@ -23,14 +23,14 @@ private _sound = getArray (configFile >> "CfgWeapons" >> _weapon >> "changeFirem if (_sound isEqualTo []) exitWith {}; // get position where to play the sound (position of the weapon) -private _position = AGLToASL (_unit modelToWorldVisual (_unit selectionPosition "RightHand")); +private _position = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand"); _sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]]; if (_filename == "") exitWith {}; // add file extension .wss as default -if !(toLower (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { _filename = format ["%1.wss", _filename]; }; diff --git a/addons/weaponselect/functions/fnc_putWeaponAway.sqf b/addons/weaponselect/functions/fnc_putWeaponAway.sqf index 0622d62ae0..6f3f2c51af 100644 --- a/addons/weaponselect/functions/fnc_putWeaponAway.sqf +++ b/addons/weaponselect/functions/fnc_putWeaponAway.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * The unit will put its current weapon away. diff --git a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf index 21f07639f4..ad17c7f18d 100644 --- a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf +++ b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Select the next grenade. @@ -37,8 +37,7 @@ private _grenades = []; if (_x in _magazines) then { _grenades pushBack _x; }; - false -} count ([GVAR(GrenadesAll), GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select _type); +} forEach ([GVAR(GrenadesAll), GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select _type); // abort if no grenades are available if (_grenades isEqualTo []) exitWith {false}; @@ -62,14 +61,14 @@ private _vestGrenades = vestItems _unit select {_x in GVAR(GrenadesAll) private _backpackGrenades = backpackItems _unit select {_x in GVAR(GrenadesAll) && {_x != _nextGrenade}}; // remove all grenades except those we are switching to --> this breaks the selector -{_unit removeItemFromUniform _x; false} count _uniformGrenades; -{_unit removeItemFromVest _x; false} count _vestGrenades; -{_unit removeItemFromBackpack _x; false} count _backpackGrenades; +{_unit removeItemFromUniform _x} forEach _uniformGrenades; +{_unit removeItemFromVest _x} forEach _vestGrenades; +{_unit removeItemFromBackpack _x} forEach _backpackGrenades; // readd grenades -{_unit addItemToUniform _x; false} count _uniformGrenades; -{_unit addItemToVest _x; false} count _vestGrenades; -{_unit addItemToBackpack _x; false} count _backpackGrenades; +{_unit addItemToUniform _x} forEach _uniformGrenades; +{_unit addItemToVest _x} forEach _vestGrenades; +{_unit addItemToBackpack _x} forEach _backpackGrenades; [_nextGrenade, {_x == _nextGrenade} count _magazines] call FUNC(displayGrenadeTypeAndNumber); diff --git a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf index 8812a63525..f2810bb512 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * The player will select the specified weapon or will change to the next firing mode if the weapon was already selected. diff --git a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf index ff2d48baf4..9a27a515ad 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * The player will select the specified weapon and change to the first additional muzzle. E.g. the grenade launcher of a assault rifle. diff --git a/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf b/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf index b3fa528532..d332afdcdc 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Select weapon for unit in vehicle. diff --git a/addons/weaponselect/functions/fnc_throwGrenade.sqf b/addons/weaponselect/functions/fnc_throwGrenade.sqf index 1214bdc84b..ffe289a589 100644 --- a/addons/weaponselect/functions/fnc_throwGrenade.sqf +++ b/addons/weaponselect/functions/fnc_throwGrenade.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: commy2 * Display Grenade information on grenade throw. Called from the unified fired EH only for the local player. @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); if (_weapon != "Throw") exitWith {}; diff --git a/addons/weaponselect/functions/script_component.hpp b/addons/weaponselect/functions/script_component.hpp deleted file mode 100644 index b7e33ed562..0000000000 --- a/addons/weaponselect/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\weaponselect\script_component.hpp" \ No newline at end of file diff --git a/addons/weaponselect/initSettings.inc.sqf b/addons/weaponselect/initSettings.inc.sqf new file mode 100644 index 0000000000..f5695748b4 --- /dev/null +++ b/addons/weaponselect/initSettings.inc.sqf @@ -0,0 +1,6 @@ +[ + QGVAR(displayText), "CHECKBOX", + [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], + ELSTRING(common,ACEKeybindCategoryWeapons), + true // default value +] call CBA_fnc_addSetting; diff --git a/addons/weaponselect/initSettings.sqf b/addons/weaponselect/initSettings.sqf deleted file mode 100644 index d4fc725783..0000000000 --- a/addons/weaponselect/initSettings.sqf +++ /dev/null @@ -1,8 +0,0 @@ -// CBA Settings [ADDON: ace_weaponselect]: - -[QGVAR(displayText), "CHECKBOX", -[LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], -localize ELSTRING(common,ACEKeybindCategoryWeapons), -true, // default value -false, // isGlobal -{[QGVAR(displayText), _this] call EFUNC(common,cbaSettings_settingChanged)}] call CBA_settings_fnc_init; diff --git a/addons/weaponselect/stringtable.xml b/addons/weaponselect/stringtable.xml index d1f3ce670f..4369c3b5f9 100644 --- a/addons/weaponselect/stringtable.xml +++ b/addons/weaponselect/stringtable.xml @@ -8,13 +8,13 @@ Показывать текст при броске Zobrazí text při hodu granátem Wyświetl tekst przy rzucie granatem - Afficher texte lors d'un lancé de grenade + Afficher du texte lors d'un lancé de grenade Szöveg mutatása gránát eldobásakor Mostra indicazioni nel lancio granate - Mostrat texto ao lançar granada - 手榴弾を投げるときに通知 - 수류탄 투척시 화면에 문자 표시 - 投掷手榴弹时显示提示讯息 + Mostrar texto ao lançar granada + 手榴弾投擲時に通知 + 수류탄 투척 시 화면에 문자 표시 + 投掷手榴弹时显示提示信息 投擲手榴彈時顯示提示訊息 @@ -24,13 +24,13 @@ Показывать текст или подсказку при броске гранаты. Zobrazí upozornění nebo text při hodu granátem. Wyświetla powiadomienie lub tekst przy rzucie granatem. - Afficher texte/info au lancé de grenade + Affiche un texte ou une notification lors d'un lancé de grenade. Jelez egy súgót vagy szöveget a gránát eldobásakor. Mostra una notifica quando si lanciano granate - Mostra um hint ou texto ao lançar uma granada + Mostra uma notificação ou texto ao lançar uma granada 手榴弾を投げるときに、ヒントか文で通知します。 - 수류탄 투척시 화면에 문자나 힌트를 표시합니다. - 投掷手榴弹时显示提示讯息。 + 수류탄 투척 시 화면에 문자나 힌트를 표시합니다. + 投掷手榴弹时显示提示信息。 投擲手榴彈時顯示提示訊息 @@ -40,7 +40,7 @@ Wybierz pistolet Zvolit Pistoly Выбрать пистолет - Sélectionner Pistolet + Sélectionner le pistolet Pisztoly Kiválasztása Selecionar Pistola Seleziona la Pistola @@ -48,6 +48,7 @@ 권총 선택 选择手枪 選擇手槍 + Tabancayı Seç Select Rifle @@ -56,7 +57,7 @@ Wybierz karabin Zvolit Pušku Выбрать винтовку - Sélectionner Fusil + Sélectionner le fusil Puska Kiválasztása Selecionar Rifle Seleziona il fucile @@ -64,6 +65,7 @@ 소총 선택 选择步枪 選擇步槍 + Tüfeği Seç Select Launcher @@ -72,7 +74,7 @@ Wybierz wyrzutnię Zvolit Raketomet Выбрать гранатомёт - Sélectionner Lanceur + Sélectionner le lanceur Rakétavető Kiválasztása Selecionar Lançador Seleziona il lanciamissili @@ -80,6 +82,7 @@ 발사기 선택 选择发射器 選擇發射器 + Fırlatılabiliri Seç Select Grenade Launcher @@ -88,7 +91,7 @@ Wybierz granatnik Zvolit Granátomet Выбрать подствольный гранатомёт - Sélectionner Lance-grenades + Sélectionner le lance-grenades Gránátvető Kiválasztása Selecionar Lança-Granadas Seleziona il lanciagranate @@ -96,6 +99,7 @@ 유탄발사기 선택 选择榴弹发射器 選擇榴彈發射器 + Bombaatarı Seç Select Binoculars @@ -104,7 +108,7 @@ Wybierz lornetkę Zvolit Dalekohled Выбрать бинокль - Sélectionner Jumelles + Sélectionner les jumelles Távcső Kiválasztása Selecionar Binóculos Seleziona il Binocolo @@ -112,6 +116,7 @@ 망원경 선택 选择望远镜 選擇望遠鏡 + Dürbünü Seç Holster Weapon @@ -128,13 +133,14 @@ 무기 집어넣기 武器套 武器套 + Silahını Kılıfına Koy Engine on Motor an Encender motor Włącz silnik - Moteur allumé + Démarrer le moteur Motor indítása Zapnout motor Ligar Motor @@ -144,13 +150,14 @@ 엔진 켜기 引擎发动 引擎發動 + Motor Açık Engine off Motor aus Apagar motor Wyłącz silnik - Moteur éteint + Couper le moteur Motor leállítása Vypnout motor Desligar Motor @@ -160,45 +167,48 @@ 엔진 끄기 引擎熄火 引擎熄火 + Motor Kapalı Select Main Gun Hauptgeschütz auswählen Seleccionar arma principal Wybierz główną broń - Sélectionner l'Arme Principale + Sélectionner l'arme principale Elsődleges Fegyver Kiválasztása Zvolit Hlavní Zbraň Selecionar Arma Principal - Seleziona Arma Primaria + Seleziona Cannone Primario Выбрать основное оружие 主砲を選択 주포 선택 选择主武器 選擇主武器 + Ana Silahı Seç Select Machine Gun Maschinengewehr auswählen Seleccionar ametralladora Wybierz karabin maszynowy - Sélectionner Mitrailleuse + Sélectionner la mitrailleuse Géppuska Kiválasztása Zvolit Kulomet Selecionar Metralhadora Seleziona Mitragliatrice Выбрать пулемёт - 機関砲を選択 + 機銃を選択 기관총 선택 选择机枪 選擇機槍 + Makineli Silahı Seç Select Missiles Raketen auswählen Seleccionar misiles Wybierz rakiety - Sélectionner Missiles + Sélectionner les missiles Rakéták Kiválasztása Zvolit Rakety Selecionar Mísseis @@ -208,6 +218,7 @@ 미사일 선택 选择导弹 選擇導彈 + Füzeleri Seç Grenade %1 @@ -224,6 +235,7 @@ %1 수류탄 手榴弹 %1 手榴彈 %1 + El Bombası %1 Ready Grenade @@ -234,19 +246,20 @@ Gránát előkészítése Подготовить гранату Grenade prête - Granata pronta + Prepara Granata Granada pronta - 投てきよし + 手榴弾を準備 투척물 준비 准备手榴弹 準備手榴彈 + El Bombası Hazır Select Frag Grenade Explosive Granate auswählen Seleccionar granada de fragmenación Wybierz granat odłamkowy - Sélectionner grenade à fragmentation + Sélectionner les grenades à fragmentation Repeszgránát Kiválasztása Zvolit výbušný granát Selecionar Granada de Fragmentação @@ -256,13 +269,14 @@ 살상 투척물 선택 选择破片手榴弹 選擇破片手榴彈 + El Bombasını Seç Select Non-Frag Grenade Nichtexplosive Granate auswählen Seleccionar granada de no fragmentación Wybierz granat nieodłamkowy - Sélectionner grenade non-léthale + Sélectionner les grenades non létales Nem-robbanó Gránát Kiválasztása Zvolit ne-výbušný granát Selecionar Granada @@ -272,6 +286,7 @@ 비살상 투척물 선택 选择非破片手榴弹 選擇非破片手榴彈 + El Bombası Dışındakileri Seç Throw Selected Grenade @@ -284,39 +299,41 @@ Lançar Granada Selecionada Lancia la Granata Selezionata Бросить выбранную гранату - 選択された手榴弾を投げる + 選択された手榴弾を投擲 선택된 투척물 투척 投掷选择的手榴弹 投擲選擇的手榴彈 + Seçilen Bombayı Fırlat No grenades left Keine Granaten übrig No quedan granadas - Plus de grenades + Il n'y a plus de grenades. Brak granatów Žádné granáty Nincs több gránát Гранат не осталось Granate esaurite Sem mais granadas - もう手榴弾は無い + 手榴弾は残っていない 투척물 없음 已无手榴弹 已無手榴彈 + El Bombası Kalmadı No frags left Keine explosiven Granaten übrig No quedan granadas de fragmentación Brak granatów odłamkowych - Plus de grenades à fragmentation + Il n'y a plus de grenades à fragmentation. Nincs több repeszgránát Žádné výbušné granáty Não há granadas de fragmentação restantes Nessuna granata a frammentazione rimanente Осколочных гранат нет - もう破片手榴弾は無い + 破片手榴弾は残っていない 세열 수류탄 없음 已无破片手榴弹 已無破片手榴彈 @@ -326,13 +343,13 @@ Keine nichtexplosiven Granaten übrig Sin granadas misc. Brak granatów nieodłamkowych - Plus de grenades non-léthales + Il n'y a plus de grenades non létales. Nincs több egyéb gránát Už nejsou žádné ostatní granáty Não há outras granadas restantes Nessun'altra granata rimanente. Нелетальные гранаты закончились - もうその他の手榴弾は無い + その他の手榴弾は残っていない 기타 투척물 없음 已无其他手榴弹 已無其他手榴彈 @@ -342,32 +359,34 @@ Keine Granate ausgewählt Granada no seleccionada Nie wybrano żadnego granatu - Aucune grenade sélectionnée + Aucune grenade sélectionnée. Nincs semmilyen gránát kiválasztva Není zvolen žádný granát Nenhuma granada selecionada Nessuna granata selezionata Нет выбранной гранаты - 手榴弾は選択されていない + 手榴弾は未選択 선택된 수류탄 없음 未选择手榴弹 未選擇手榴彈 + Bomba Seçilmedi Fire Smoke Launcher Rauchwand abfeuern Disparar lanzador de humo Kouřový odpalovač - Tirer le lance-pots fumigènes + Lancer les pots fumigènes Wystrzel granat dymny Füstvető eltüzelése Пустить дымовую завесу - Lancia fumogeno + Lancia Cortina Fumogena Lançador de fumaça - 発煙弾発射機を発射 + 発煙弾を発射 연막발사기 박사 发射烟雾发射器 發射煙霧發射器 + Ateşli Sis Fırlatıcısı Toggle Collision Lights @@ -378,7 +397,12 @@ 切换碰撞灯 衝突防止灯を切り替え Przełącz światła kolizyjne - Вкл/Выкл Бортовые огни + Переключить бортовые огни + Alternar Luzes de Colisão + Alternar luces de colisión + Přepnout kolizní světla + Allumer les feux anti-collision + Çarpışma Işıklarını Aç/Kapat diff --git a/addons/weather/ACE_Settings.hpp b/addons/weather/ACE_Settings.hpp index e2eb4590b7..2028beac3e 100644 --- a/addons/weather/ACE_Settings.hpp +++ b/addons/weather/ACE_Settings.hpp @@ -1,24 +1,11 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(enabled_DisplayName); - description = CSTRING(enabled_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(updateInterval) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(updateInterval_DisplayName); - description = CSTRING(updateInterval_Description); - typeName = "SCALAR"; - value = 60; - sliderSettings[] = {0, 300, 0, 0}; + movedToSQF = 1; }; class GVAR(windSimulation) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(windSimulation_DisplayName); - description = CSTRING(windSimulation_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; }; diff --git a/addons/weather/CfgEventhandlers.hpp b/addons/weather/CfgEventhandlers.hpp index f913c4c22b..f180d1c700 100644 --- a/addons/weather/CfgEventhandlers.hpp +++ b/addons/weather/CfgEventhandlers.hpp @@ -1,25 +1,25 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - serverInit = QUOTE(call COMPILE_FILE(XEH_PostServerInit)); - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + serverInit = QUOTE(call COMPILE_SCRIPT(XEH_PostServerInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; class Extended_DisplayLoad_EventHandlers { class Display3DEN { - ADDON = QUOTE(call COMPILE_FILE(init3DEN)); + ADDON = QUOTE(call COMPILE_SCRIPT(init3DEN)); }; }; diff --git a/addons/weather/CfgVehicles.hpp b/addons/weather/CfgVehicles.hpp index cab16183a8..151b756c49 100644 --- a/addons/weather/CfgVehicles.hpp +++ b/addons/weather/CfgVehicles.hpp @@ -1,4 +1,17 @@ class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ACE_CheckAirTemperature { + displayName = CSTRING(CheckAirTemperature); + condition = QUOTE(GVAR(enabled) && GVAR(showCheckAirTemperature)); + exceptions[] = {"isNotInside", "isNotSitting"}; + statement = QUOTE([ACE_player] call FUNC(getApproximateAirTemp)); + icon = QPATHTOF(UI\temp_ca.paa); + }; + }; + }; + class ACE_Module; class GVAR(ModuleSettings): ACE_Module { scope = 1; diff --git a/addons/weather/README.md b/addons/weather/README.md index da83f62fd2..62572a878d 100644 --- a/addons/weather/README.md +++ b/addons/weather/README.md @@ -3,12 +3,3 @@ ace_weather This module simulates realistic weather effects, according to the geographical location of the map, the date and time. It also ensures that all players experience the same weather effects. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [commy2](https://github.com/commy2) -- [esteldunedain](https://github.com/esteldunedain) -- [walterpearce](https://github.com/walterpearce) diff --git a/addons/weather/RscTitles.hpp b/addons/weather/RscTitles.hpp index d89c8d0671..4b338f87cc 100644 --- a/addons/weather/RscTitles.hpp +++ b/addons/weather/RscTitles.hpp @@ -17,7 +17,7 @@ class RscTitles { x="SafeZoneX + 0.001"; y="SafeZoneY + 0.001"; w=0.2; - h=0.2*4/3; + h="0.2*4/3"; size=0.034; sizeEx=0.027; text=""; diff --git a/addons/weather/UI/temp_ca.paa b/addons/weather/UI/temp_ca.paa new file mode 100644 index 0000000000..3bbc441e26 Binary files /dev/null and b/addons/weather/UI/temp_ca.paa differ diff --git a/addons/weather/XEH_PREP.hpp b/addons/weather/XEH_PREP.hpp index 48788c0546..220a18ef3c 100644 --- a/addons/weather/XEH_PREP.hpp +++ b/addons/weather/XEH_PREP.hpp @@ -1,16 +1,18 @@ - PREP(calculateAirDensity); PREP(calculateBarometricPressure); PREP(calculateDensityAltitude); PREP(calculateDewPoint); PREP(calculateHeatIndex); +PREP(calculateOxygenDensity); PREP(calculateRoughnessLength); PREP(calculateSpeedOfSound); PREP(calculateTemperatureAtHeight); PREP(calculateWetBulb); PREP(calculateWindChill); PREP(calculateWindSpeed); +PREP(displayAirTemp); PREP(displayWindInfo); +PREP(getApproximateAirTemp); PREP(getMapData); PREP(initModuleSettings); PREP(initWind); diff --git a/addons/weather/XEH_postInit.sqf b/addons/weather/XEH_postInit.sqf index 51350226e1..98909dc2d4 100644 --- a/addons/weather/XEH_postInit.sqf +++ b/addons/weather/XEH_postInit.sqf @@ -1,10 +1,12 @@ #include "script_component.hpp" GVAR(WindInfo) = false; + ["ACE3 Common", QGVAR(WindInfoKey), localize LSTRING(WindInfoKeyToggle), { // Conditions: canInteract - if !([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, ACE_player, ["isNotDragging", "isNotCarrying", "isNotSitting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !(isNull objectParent ACE_player || {objectParent ACE_player isKindOf "StaticWeapon"}) exitWith {false}; // Statement [] call FUNC(displayWindInfo); @@ -15,7 +17,8 @@ GVAR(WindInfo) = false; ["ACE3 Common", QGVAR(WindInfoKey_hold), localize LSTRING(WindInfoKeyHold), { // Conditions: canInteract - if !([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, ACE_player, ["isNotDragging", "isNotCarrying", "isNotSitting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !(isNull objectParent ACE_player || {objectParent ACE_player isKindOf "StaticWeapon"}) exitWith {false}; // Statement [] call FUNC(displayWindInfo); diff --git a/addons/weather/XEH_postServerInit.sqf b/addons/weather/XEH_postServerInit.sqf index 433c161979..2c20f672fe 100644 --- a/addons/weather/XEH_postServerInit.sqf +++ b/addons/weather/XEH_postServerInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -["ace_settingsInitialized", { +["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; GVAR(temperatureShift) = random [-SD_TO_MIN_MAX(4), 0, SD_TO_MIN_MAX(4)]; // Gauss(0, 4) @@ -9,8 +9,8 @@ if (GVAR(windSimulation)) then { call FUNC(initWind); - [FUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; }; - [FUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/weather/XEH_preInit.sqf b/addons/weather/XEH_preInit.sqf index 1b551f133e..bae7c82516 100644 --- a/addons/weather/XEH_preInit.sqf +++ b/addons/weather/XEH_preInit.sqf @@ -7,6 +7,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + // Make sure this data is read before client/server postInit call FUNC(getMapData); diff --git a/addons/weather/functions/fnc_calculateAirDensity.sqf b/addons/weather/functions/fnc_calculateAirDensity.sqf index 43da78eab9..6bab73618f 100644 --- a/addons/weather/functions/fnc_calculateAirDensity.sqf +++ b/addons/weather/functions/fnc_calculateAirDensity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the air density diff --git a/addons/weather/functions/fnc_calculateBarometricPressure.sqf b/addons/weather/functions/fnc_calculateBarometricPressure.sqf index 70cdf370bf..abd9cc00bd 100644 --- a/addons/weather/functions/fnc_calculateBarometricPressure.sqf +++ b/addons/weather/functions/fnc_calculateBarometricPressure.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the barometric pressure based on altitude and weather diff --git a/addons/weather/functions/fnc_calculateDensityAltitude.sqf b/addons/weather/functions/fnc_calculateDensityAltitude.sqf index fdfe57877d..3a3d0dad10 100644 --- a/addons/weather/functions/fnc_calculateDensityAltitude.sqf +++ b/addons/weather/functions/fnc_calculateDensityAltitude.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates density altitude for a given air density diff --git a/addons/weather/functions/fnc_calculateDewPoint.sqf b/addons/weather/functions/fnc_calculateDewPoint.sqf index 5f020f47d1..441be06d32 100644 --- a/addons/weather/functions/fnc_calculateDewPoint.sqf +++ b/addons/weather/functions/fnc_calculateDewPoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates dew point based on temperature and relative humidity diff --git a/addons/weather/functions/fnc_calculateHeatIndex.sqf b/addons/weather/functions/fnc_calculateHeatIndex.sqf index de333d801f..3548326917 100644 --- a/addons/weather/functions/fnc_calculateHeatIndex.sqf +++ b/addons/weather/functions/fnc_calculateHeatIndex.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates heat index based on temperature and relative humidity diff --git a/addons/weather/functions/fnc_calculateOxygenDensity.sqf b/addons/weather/functions/fnc_calculateOxygenDensity.sqf new file mode 100644 index 0000000000..542b4b2f10 --- /dev/null +++ b/addons/weather/functions/fnc_calculateOxygenDensity.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Calculates the oxygen density + * + * Arguments: + * 0: Temperature - °C + * 1: Pressure - hPa + * 2: Relative humidity - value between 0.0 and 1.0 + * + * Return Value: + * Density of oxygen - kg * m^(-3) + * + * Example: + * [0, 1020] call ace_weather_fnc_calculateOxygenDensity + * + * Public: No + */ + +(_this call FUNC(calculateAirDensity)) * 0.21 diff --git a/addons/weather/functions/fnc_calculateRoughnessLength.sqf b/addons/weather/functions/fnc_calculateRoughnessLength.sqf index 57723355e8..252ed8a957 100644 --- a/addons/weather/functions/fnc_calculateRoughnessLength.sqf +++ b/addons/weather/functions/fnc_calculateRoughnessLength.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the terrain roughness length at a given world position @@ -19,18 +19,18 @@ #define ROUGHNESS_LENGTHS [0.0002, 0.0005, 0.0024, 0.03, 0.055, 0.1, 0.2, 0.4, 0.8, 1.6] private _windSource = _this vectorDiff ((vectorNormalized wind) vectorMultiply 25); -private _nearBuildings = { +private _nearBuildingCount = { // Filter lights - fixes high roughness on airports (#6602) str _x find "light" == -1 -} count (_windSource nearObjects ["Building", 50]); +} count (ASLToAGL _windSource nearObjects ["Building", 50]); private _isWater = surfaceIsWater _windSource; -if (_nearBuildings == 0 && _isWater) exitWith { +if (_nearBuildingCount == 0 && _isWater) exitWith { 0.0005 }; -if (_nearBuildings >= 10) exitWith { +if (_nearBuildingCount >= 10) exitWith { 1.6 }; -ROUGHNESS_LENGTHS select (2 + (_nearBuildings min 6)) +ROUGHNESS_LENGTHS select (2 + (_nearBuildingCount min 6)) diff --git a/addons/weather/functions/fnc_calculateSpeedOfSound.sqf b/addons/weather/functions/fnc_calculateSpeedOfSound.sqf index 90d524e560..755769d39a 100644 --- a/addons/weather/functions/fnc_calculateSpeedOfSound.sqf +++ b/addons/weather/functions/fnc_calculateSpeedOfSound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the speed of sound for a given temperature diff --git a/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf b/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf index c392b15900..8e3b9b624e 100644 --- a/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf +++ b/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the temperature based on altitude and weather diff --git a/addons/weather/functions/fnc_calculateWetBulb.sqf b/addons/weather/functions/fnc_calculateWetBulb.sqf index 5ebb497a16..16527771f6 100644 --- a/addons/weather/functions/fnc_calculateWetBulb.sqf +++ b/addons/weather/functions/fnc_calculateWetBulb.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates wet bulb based on temperature and relative humidity diff --git a/addons/weather/functions/fnc_calculateWindChill.sqf b/addons/weather/functions/fnc_calculateWindChill.sqf index f657cba638..3145839c00 100644 --- a/addons/weather/functions/fnc_calculateWindChill.sqf +++ b/addons/weather/functions/fnc_calculateWindChill.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates wind chill based on temperature and wind speed @@ -23,5 +23,5 @@ params ["_t", "_v"]; if (_t > 10) exitWith { _t }; if (_v < 1.39) exitWith { _t }; -_v = _v * 3,6; // wind speed in km/h +_v = _v * 3.6; // wind speed in km/h (13.12 + 0.6215 * _t - 11.37 * _v ^ 0.16 + 0.3965 * _t * _v ^ 0.16) diff --git a/addons/weather/functions/fnc_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index f14d6dfbfc..d24322bef0 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Calculates the true wind speed at a given world position @@ -47,19 +47,18 @@ if (_terrainEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; - nil - } count [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + } forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; _windSpeed = _newWindSpeed; }; }; @@ -70,19 +69,18 @@ if (_obstacleEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; - nil - } count [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; + } forEach [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; _windSpeed = _newWindSpeed; }; }; diff --git a/addons/weather/functions/fnc_displayAirTemp.sqf b/addons/weather/functions/fnc_displayAirTemp.sqf new file mode 100644 index 0000000000..08b325dcac --- /dev/null +++ b/addons/weather/functions/fnc_displayAirTemp.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Displays an abstracted depiction of air temperature to a unit. + * + * Arguments: + * 0: Temperature + * 1: Unit Bias range + * + * Return Value: + * None + * + * Example: + * [15.8] call ace_weather_fnc_displayAirTemp + * + * Public: No + */ + +params ["_apparent_temperature", "_bias"]; +TRACE_2("displayAirTemp",_apparent_temperature,_bias); + +private _temperature1 = floor(_apparent_temperature + (_bias select 0) - (random 2)); +private _temperature2 = floor(_apparent_temperature + (_bias select 1) + (random 2)); + +private _color1 = [ +// Colors obtained by quartic regression formula of RGB values at corresponding temperatures as marked on advanced_ballistics rangecard + ( (((-0.000238348 * (_temperature1 ^ 4)) - (0.00865642 * (_temperature1 ^ 3)) + (0.794548 * (_temperature1 ^2)) - (0.323314 * _temperature1) +6.78445) min 255) /255) max 0, + ( (((-0.000308515 * (_temperature1 ^ 4)) + (0.000245732 * (_temperature1 ^ 3)) + (0.308531 * (_temperature1 ^2)) - (02.78916 * _temperature1) +164.326) min 255) /255) max 0, + ( (((-0.000107648 * (_temperature1 ^ 4)) + (0.00106365 * (_temperature1 ^ 3)) - (0.0989707 * (_temperature1 ^2)) - (9.66256 * _temperature1) +171.402) min 255) /255) max 0 +]; + +private _text = composeText ["", [format ["%1C", _temperature1],_color1] call EFUNC(common,stringToColoredText)]; +_text = composeText [_text, [" --- ", [1,1,1]] call EFUNC(common,stringToColoredText)]; + +private _color2 = [ +// Colors obtained by quartic regression formula of RGB values at corresponding temperatures as marked on advanced_ballistics rangecard + ( (((-0.000238348 * (_temperature2 ^ 4)) - (0.00865642 * (_temperature2 ^ 3)) + (0.794548 * (_temperature2 ^2)) - (0.323314 * _temperature2) +6.78445) min 255) /255) max 0, + ( (((-0.000308515 * (_temperature2 ^ 4)) + (0.000245732 * (_temperature2 ^ 3)) + (0.308531 * (_temperature2 ^2)) - (02.78916 * _temperature2) +164.326) min 255) /255) max 0, + ( (((-0.000107648 * (_temperature2 ^ 4)) + (0.00106365 * (_temperature2 ^ 3)) - (0.0989707 * (_temperature2 ^2)) - (9.66256 * _temperature2) +171.402) min 255) /255) max 0 +]; + + _text = composeText [_text, [format ["%1C", _temperature2], _color2] call EFUNC(common,stringToColoredText)]; + +/* +for "_i" from -40 to 40 step 4 do { + _temp_color = _color; + + if (_i == 0) then { + _text = composeText [_text, ["[", _temp_color] call EFUNC(common,stringToColoredText)]; + _text = composeText [_text, ["0", [0.6, 1, 0.6]] call EFUNC(common,stringToColoredText)]; + _text = composeText [_text, ["]", _temp_color] call EFUNC(common,stringToColoredText)]; + } else { + _string = "I"; + }; + + if (abs( _i - _apparent_temperature) < 8.5) then { + _temp_color = [ + // Colors obtained by quartic regression formula of RGB values at corresponding temperatures as marked on advanced_ballistics rangecard + ( (((-0.000238348 * (_i ^ 4)) - (0.00865642 * (_i ^ 3)) + (0.794548 * (_i ^2)) - (0.323314 * _i) +6.78445) min 255) /255) max 0, + ( (((-0.000308515 * (_i ^ 4)) + (0.000245732 * (_i ^ 3)) + (0.308531 * (_i ^2)) - (02.78916 * _i) +164.326) min 255) /255) max 0, + ( (((-0.000107648 * (_i ^ 4)) + (0.00106365 * (_i ^ 3)) - (0.0989707 * (_i ^2)) - (9.66256 * _i) +171.402) min 255) /255) max 0 + ]; + }; + + _text = composeText [_text, [_string, [_temp_color select 0, _temp_color select 1, _temp_color select 2]] call EFUNC(common,stringToColoredText)]; +}; + +_text = composeText [_text, [" +40C", [1,0,0]] call EFUNC(common,stringToColoredText)]; +*/ +[_text, QPATHTOF(UI\temp_ca.paa),[1,1,1], ACE_player, 2] call EFUNC(common,displayTextPicture); diff --git a/addons/weather/functions/fnc_displayWindInfo.sqf b/addons/weather/functions/fnc_displayWindInfo.sqf index 35c840bf85..aeb7d580ae 100644 --- a/addons/weather/functions/fnc_displayWindInfo.sqf +++ b/addons/weather/functions/fnc_displayWindInfo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Displays a wind info (colored arrow) in the top left corner of the screen @@ -29,14 +29,20 @@ EGVAR(advanced_ballistics,Protractor) = false; GVAR(WindInfo) = true; -TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo)); +TRACE_1("Starting Wind Info PFEH",GVAR(WindInfo)); [{ disableSerialization; params ["", "_pfID"]; - if ((!GVAR(WindInfo)) || {!([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith { - TRACE_1("Ending Wind Info PFEH", GVAR(WindInfo)); + // Allow wind indicator inside static weapons + private _playerInStaticWeapon = objectParent ACE_Player isKindOf "StaticWeapon"; + + if ( + (!GVAR(WindInfo)) || + {!([ACE_player, ACE_player, ["notOnMap", "isNotDragging", "isNotCarrying", "isNotSitting"]] call EFUNC(common,canInteractWith)) && !(_playerInStaticWeapon)} + ) exitWith { + TRACE_1("Ending Wind Info PFEH",GVAR(WindInfo)); GVAR(WindInfo) = false; (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; [_pfID] call CBA_fnc_removePerFrameHandler; @@ -45,12 +51,18 @@ TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo)); //Keeps the display open: (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutRsc ["RscWindIntuitive", "PLAIN", 1, false]; + private _playerEyePos = eyePos ACE_Player; + if (_playerInStaticWeapon) then { + // Raise eyePos by 1 meter if player is in a static weapon, to prevent wind from being blocked by the open vehicle + _playerEyePos = _playerEyePos vectorAdd [0, 0, 1]; + }; + private _windSpeed = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { // With wind gradient - [eyePos ACE_player, true, true, true] call FUNC(calculateWindSpeed); + [_playerEyePos, true, true, true] call FUNC(calculateWindSpeed); } else { // Without wind gradient - [eyePos ACE_player, false, true, true] call FUNC(calculateWindSpeed); + [_playerEyePos, false, true, true] call FUNC(calculateWindSpeed); }; diff --git a/addons/weather/functions/fnc_getApproximateAirTemp.sqf b/addons/weather/functions/fnc_getApproximateAirTemp.sqf new file mode 100644 index 0000000000..91b8af3fcc --- /dev/null +++ b/addons/weather/functions/fnc_getApproximateAirTemp.sqf @@ -0,0 +1,70 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Returns an approximate representation of temperature at a unit's location. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [ACE_player] call ace_weather_fnc_getApproximateAirTemp + * + * Public: No + */ + +params ["_unit"]; +TRACE_1("params",_unit); + +if (isNil {_unit getVariable "ACE_airTemperatureBias"}) then { + _unit setVariable ["ACE_airTemperatureBias", [-(random(3) + 1), random(3) + 1]]; +}; + +private _temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight); +private _humidity = EGVAR(weather,currentHumidity); +private _heatIndex = [_temperature, _humidity] call EFUNC(weather,calculateHeatIndex); +private _chill = [_temperature, _humidity] call EFUNC(weather,calculateWindChill); + +private _e = 2^(1/(ln 2)); + +/* +// Windchill calc with wind vars; https://en.wikipedia.org/wiki/Wind_chill#Australian_Apparent_Temperature +private _windspeed = [getPosASL _unit, true, true, true] call EFUNC(weather,calculateWindSpeed); +private _water_vapor_pressure = _humidity * 6.105 *(_e ^ ((17.27 * _temperature)/(237.7 + _temperature))) / 100; +private _chill = _temperature + (0.33 * _water_vapor_pressure) - (0.70 * _windspeed) - 400; +*/ + +// sigmoid = f(x) = L / (1 + e^(-k * (x - x_0))); +// L max value, e = euler, k = steepness, + +// L = max value +private _sigmoid_L = 1; + +// x_0 = sigmoid midpoint, aka 50% proportion; 18.5C, ~65F +private _sigmoid_midpoint = 18.5; + +// place +- midpoint with desired proportion +private _sigmoid_valuation = 8.5; + +// desired upper and proportion on sigmoid +private _sigmoid_proportion_at_valuation = 0.95; +private _sigmoid_proportion_at_lower_valuation = 1 - _sigmoid_proportion_at_valuation; + +// k = steepness +private _sigmoid_k = (ln ((_sigmoid_proportion_at_lower_valuation^-1) - 1) ) / _sigmoid_valuation; + +// 5$/95% @ 10C/27C; [5% and 95% values at 50F and ~80F]; +// 5% = 0.05 = 1/20 = f(_midpoint - _valuation) = L / (1 + e^(-k * ((_midpoint - _valuation) - _midpoint) +// (0.05)^-1 = 20 = (L / (1 + e^(-k * (-_valuation))) )^-1 = (1 + e^(-k * -_valuation))/L; +// L = 1;> 20 = (1 + e^(k * valuation)); 20 - 1 = e^(k * valuation); +// 19 = e^(k * 8.5); (log_e 19) = (k * 8.5); (log_e 19)/8.5 = k; + +// retrieve sigmoid proportion at _temperature +private _temperature_sigmoid = _sigmoid_L / (1 + _e^(-_sigmoid_k * (_temperature - _sigmoid_midpoint))); + +// Weighted average between windchill and heat index based on sigmoid levels, plus +- 4deg randomisation +private _apparent_temperature = ((_temperature_sigmoid * _heatIndex) + ((1 - _temperature_sigmoid) * _chill) + random(8) - 4); + +[_apparent_temperature, (_unit getVariable "ACE_airTemperatureBias")] call FUNC(displayAirTemp); diff --git a/addons/weather/functions/fnc_getMapData.sqf b/addons/weather/functions/fnc_getMapData.sqf index 20a8f1df70..555704fc87 100644 --- a/addons/weather/functions/fnc_getMapData.sqf +++ b/addons/weather/functions/fnc_getMapData.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg, esteldunedain * Get the weather data for the current map @@ -15,7 +15,7 @@ * Public: No */ -private _worldName = toLower worldName; +private _worldName = toLowerANSI worldName; TRACE_1("getting map data",_worldName); // Set default values @@ -48,34 +48,35 @@ GVAR(currentHumidity) = 0; GVAR(currentOvercast) = 0; // Get all non inherited arrays to filter maps that inherit from Stratis/Altis/Tanoa -private _nonInheritedArrays = configProperties [configFile >> "CfgWorlds" >> _worldName, "isArray _x", false]; +private _cfgPath = configFile >> "CfgWorlds" >> _worldName; +private _nonInheritedArrays = configProperties [_cfgPath, "isArray _x", false]; // And check if any custom non-inherited weather is defined through config and use that if so -if ((configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay") in _nonInheritedArrays) exitWith { - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay")) then { - GVAR(TempDay) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay"); +if ((_cfgPath >> "ACE_TempDay") in _nonInheritedArrays) exitWith { + if (isArray (_cfgPath >> "ACE_TempDay")) then { + GVAR(TempDay) = getArray (_cfgPath >> "ACE_TempDay"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight")) then { - GVAR(TempNight) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight"); + if (isArray (_cfgPath >> "ACE_TempNight")) then { + GVAR(TempNight) = getArray (_cfgPath >> "ACE_TempNight"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity")) then { - GVAR(Humidity) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity"); + if (isArray (_cfgPath >> "ACE_Humidity")) then { + GVAR(Humidity) = getArray (_cfgPath >> "ACE_Humidity"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin")) then { - GVAR(WindSpeedMin) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin"); + if (isArray (_cfgPath >> "ACE_WindSpeedMin")) then { + GVAR(WindSpeedMin) = getArray (_cfgPath >> "ACE_WindSpeedMin"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean")) then { - GVAR(WindSpeedMean) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean"); + if (isArray (_cfgPath >> "ACE_WindSpeedMean")) then { + GVAR(WindSpeedMean) = getArray (_cfgPath >> "ACE_WindSpeedMean"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax")) then { - GVAR(WindSpeedMax) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax"); + if (isArray (_cfgPath >> "ACE_WindSpeedMax")) then { + GVAR(WindSpeedMax) = getArray (_cfgPath >> "ACE_WindSpeedMax"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities")) then { - GVAR(WindDirectionProbabilities) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities"); + if (isArray (_cfgPath >> "ACE_WindDirectionProbabilities")) then { + GVAR(WindDirectionProbabilities) = getArray (_cfgPath >> "ACE_WindDirectionProbabilities"); }; }; // Check if the map is among the most popular -if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) then { +if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) exitWith { // Source: http://www.iten-online.ch/klima/europa/tschechien/prag.htm GVAR(TempDay) = [1, 3, 9, 14, 19, 23, 25, 24, 21, 13, 7, 2]; GVAR(TempNight) = [-4, -3, 0, 4, 9, 12, 14, 14, 10, 6, 2, -2]; @@ -239,3 +240,17 @@ if (_worldName in ["kunduz"]) exitWith { [0.04, 0.02, 0.05, 0.14, 0.19, 0.07, 0.10, 0.07] // December ]; }; + + +// Catches any "Winter" Map that hasnt been defined otherwise - this should stay at the end of the file +// Values are not based on any RL reference since the snow terrain textures persists regardless the date +_cfgPath = _cfgPath >> "RainParticles"; +if ( + "winter" in _worldName || + {"snow" in getText (_cfgPath >> "rainDropTexture")} || + {getNumber (_cfgPath >> "snow") != 0} +) exitWith { + GVAR(TempDay) = [-10,-9,-8,-7,-6,-5,-6,-7,-8,-9,-10,-11]; + GVAR(TempNight) = [-15,-14,-13,-12,-11,-10,-9,-10,-11,-12,-13,-17]; + GVAR(Humidity) = [82, 80, 81, 82, 83, 82, 81, 82, 83, 82, 83, 82]; +}; diff --git a/addons/weather/functions/fnc_initModuleSettings.sqf b/addons/weather/functions/fnc_initModuleSettings.sqf index 3b306398f9..cd00bd0e95 100644 --- a/addons/weather/functions/fnc_initModuleSettings.sqf +++ b/addons/weather/functions/fnc_initModuleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the wind deflection settings diff --git a/addons/weather/functions/fnc_initWind.sqf b/addons/weather/functions/fnc_initWind.sqf index 29e4e7dbe8..45d444912d 100644 --- a/addons/weather/functions/fnc_initWind.sqf +++ b/addons/weather/functions/fnc_initWind.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Inits the wind variables on the server (on mission start) diff --git a/addons/weather/functions/fnc_updateHumidity.sqf b/addons/weather/functions/fnc_updateHumidity.sqf index 2660076f9f..afbdb61d0c 100644 --- a/addons/weather/functions/fnc_updateHumidity.sqf +++ b/addons/weather/functions/fnc_updateHumidity.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE2 Team * Smoothly updates GVAR(currentHumidity) on the server (based on time of day and map data) diff --git a/addons/weather/functions/fnc_updateTemperature.sqf b/addons/weather/functions/fnc_updateTemperature.sqf index ea7a84a269..3036171145 100644 --- a/addons/weather/functions/fnc_updateTemperature.sqf +++ b/addons/weather/functions/fnc_updateTemperature.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE2 Team * Smoothly updates GVAR(currentTemperature) on the server (based on time of day and map data) diff --git a/addons/weather/functions/fnc_updateWeather.sqf b/addons/weather/functions/fnc_updateWeather.sqf index c573d190ce..d7f629147d 100644 --- a/addons/weather/functions/fnc_updateWeather.sqf +++ b/addons/weather/functions/fnc_updateWeather.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE2 Team, esteldunedain, Ruthberg * Updates the weather evolution on the server. Broadcasts relevant weather information to the clients. @@ -20,8 +20,8 @@ missionNamespace setVariable [QGVAR(currentOvercast), overcast, true]; [] call FUNC(updateTemperature); [] call FUNC(updateHumidity); -// Wind simulation -if (GVAR(windSimulation) && CBA_missionTime > GVAR(next_wind_udpate)) then { +// Wind simulation, take API for temporarily disabling into account along with setting +if (GVAR(windSimulation) && {!(missionNamespace getVariable [QGVAR(disableWindSimulation), false])} && {CBA_missionTime > GVAR(next_wind_udpate)}) then { GVAR(current_wind_direction) = GVAR(next_wind_direction); GVAR(current_wind_speed) = GVAR(next_wind_speed); diff --git a/addons/weather/functions/fnc_updateWind.sqf b/addons/weather/functions/fnc_updateWind.sqf index 569179dce8..af3d414a18 100644 --- a/addons/weather/functions/fnc_updateWind.sqf +++ b/addons/weather/functions/fnc_updateWind.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE2 Team, Ruthberg * Smoothly updates wind on the server (based on time of year and map data) @@ -15,6 +15,9 @@ * Public: No */ +// Public API to temporarily disable wind simulation +if (missionNamespace getVariable [QGVAR(disableWindSimulation), false]) exitWith {}; + private _speed = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_speed), GVAR(next_wind_speed), true]; private _direction = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_direction), GVAR(next_wind_direction), true]; diff --git a/addons/weather/functions/script_component.hpp b/addons/weather/functions/script_component.hpp deleted file mode 100644 index e1916225e8..0000000000 --- a/addons/weather/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\weather\script_component.hpp" \ No newline at end of file diff --git a/addons/weather/init3DEN.sqf b/addons/weather/init3DEN.sqf index 34b7dc2d5b..74af5fbaf1 100644 --- a/addons/weather/init3DEN.sqf +++ b/addons/weather/init3DEN.sqf @@ -5,7 +5,7 @@ // cannot create checkboxes which have the default value "true" // 3den uses inverted checkboxes instead, but those only change in appearence // we have to auto set these settings manually - on mission creation -add3DENEventHandler ["onMissionNew", { +add3DENEventHandler ["OnMissionNew", { set3DENMissionAttributes [ ["Intel", "IntelWavesIsForced", true], ["Intel", "IntelWindIsForced", true] diff --git a/addons/weather/initSettings.inc.sqf b/addons/weather/initSettings.inc.sqf new file mode 100644 index 0000000000..26f4442084 --- /dev/null +++ b/addons/weather/initSettings.inc.sqf @@ -0,0 +1,38 @@ +private _category = [format ["ACE %1", LLSTRING(Module_DisplayName)]]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(enabled_DisplayName), LSTRING(enabled_Description)], + _category, + true, // default value + true, // isGlobal + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(updateInterval), "SLIDER", + [LSTRING(updateInterval_DisplayName), LSTRING(updateInterval_Description)], + _category, + [0,300,60,0], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(updateInterval), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(windSimulation), "CHECKBOX", + [LSTRING(windSimulation_DisplayName), LSTRING(windSimulation_Description)], + _category, + true, // default value + true, // isGlobal + {[QGVAR(windSimulation), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(showCheckAirTemperature), "CHECKBOX", + [LSTRING(showCheckAirTemperature_DisplayName), LELSTRING(common,showActionInSelfInteraction)], + _category, + true // default value +] call CBA_fnc_addSetting; diff --git a/addons/weather/stringtable.xml b/addons/weather/stringtable.xml index 2c0859ef50..bb815b8d06 100644 --- a/addons/weather/stringtable.xml +++ b/addons/weather/stringtable.xml @@ -5,7 +5,7 @@ Show Wind Info Pokaż inf. o wietrze Показать информацию о ветре - Afficher information sur le vent + Afficher les informations sur le vent Mostrar información del viento Mostra informazioni sul vento Zeige Windinformationen @@ -14,14 +14,15 @@ Mostrar informação do vento 風速を表示 바람 정보 표시 - 显示风力资讯 + 显示风力信息 顯示風力資訊 + Rüzgar Bilgilerini Göster Show Wind Info (Toggle) Pokaż inf. o wietrze (przełącz) Показать информацию о ветре (перекл.) - Afficher information sur le vent (bascule) + Afficher les informations sur le vent (bascule) Mostrar información del viento (cambiar) Mostra informazioni sul vento (camb.) Zeige Windinformationen (umsch.) @@ -30,8 +31,9 @@ Mostrar informação do vento (alternar) 風速を表示 (切り替え) 바람 정보 표시 (토글) - 显示风力资讯(切换) + 显示风力信息(切换) 顯示風力資訊(切換) + Rüzgar Bilgilerini Göster (Değiştir) Weather @@ -45,9 +47,10 @@ Погода Meteo 天候 - 기후 + 날씨 天气 天氣 + Hava Durumu Multiplayer synchronized ACE weather module @@ -56,14 +59,15 @@ ACE-Wettermodul (synchron im Multiplayer) Synchronizovat ACE počasí v multiplayeru Módulo climático ACE para sincronismo multiplayer - Module ACE de synchronisation de la météo en multi. + Module météo ACE synchronisé en multijoueur. Többjátékos szinkronizált ACE időjárás modul ACE Модуль для синхронизации погоды в мультиплеере - Modulo Sincronizzazione Meteo ACE Multiplayer + Modulo Sincronizzazione Meteo ACE Multigiocatore ACE 天候モジュールではマルチプレイで同期します。 ACE 기후 모듈과 멀티플레이가 동기화됩니다. - 使用ACE天气模块来同步所有客户端的天气状态(多人游戏) + 使用 ACE 天气模块来同步所有客户端的天气状态(多人游戏) 使用ACE天氣模塊來同步所有客戶端的天氣狀態(多人遊戲) + Çok oyunculu ACE ACE Weather @@ -77,20 +81,26 @@ Погода ACE Meteo ACE ACE 天候 - ACE 기후 + ACE 날씨 ACE 天气 ACE 天氣 + ACE Hava Durumu Expands the existing weather by temperature, humidity and air pressure. Erweitert das vorhandene Wetter um Temperatur, Luftfeuchtigkeit und Luftdruck. - Espande il tempo esistente per temperatura, umidità e pressione dell'aria. + Espande il tempo esistente con temperatura, umidità e pressione dell'aria. 透過增加濕度、溫度與氣壓來增強天氣模擬的表現。 透过增加湿度、温度与气压来增强天气模拟的表现。 気温や湿度、大気圧によって既存の天候を拡張します。 온도, 습도 및 기압에 따라 기존 날씨를 확장합니다. Poszerza istniejącą pogodę o temperaturę, wilgotność i ciśnienie powietrza. Расширяет текущие возможности погоды с учетом температуры, влажности и давления + Expande o clima existente com temperatura, umidade e pressão do ar. + Rozšiřuje stávající počasí o teplotu, vlhkost a tlak vzduchu. + Améliore le module météo existant en y ajoutant la température, l'humidité et la pression atmosphérique. + Mevcut havayı sıcaklık, nem ve hava basıncı ile genişletir. + Expande el clima actual en cuanto a temperatura, humedad y presión atmosférica. Update Interval @@ -99,14 +109,15 @@ Aktualisierungsintervall Interval aktualizace Intervalo de atualização - Intervalle de synchronisation + Intervalle de mises à jour Frissítési intervallum Интервал обновления - Intervallo Aggiornamento + Intervallo Aggiornamenti 更新間隔 갱신 간격 更新间隔 更新間隔 + Güncelleştirme Aralığı Defines the interval (seconds) between weather updates @@ -115,36 +126,79 @@ Definiert das Intervall (in Sekunden) zwischen Wetteraktualisierungen Určit interval (v sekundách) mezi aktualizacemi počasí Defina o intervalo (em segundos) entre as atualizações de clima - Défini un intervalle (secondes) entre deux synchronisations + Définit l'intervalle (en secondes) entre les mises à jour des conditions météo. Megadja az intervallumot (másodpercben) az időjárás-frissítések között Определяет интервал (в секундах) между обновлениями погоды - Definisce l'intervallo(in secondi) tra aggiornamenti del meteo - 天候を更新する間隔を定義します。(秒) - 기후를 갱신 하는 간격을 초 단위로 정합니다. - 设定天气更新的时间间隔(秒) + Definisce l'intervallo (in secondi) tra aggiornamenti del meteo + 天候を更新する間隔 (秒) を定義します + 기후를 갱신하는 간격을 초 단위로 정합니다. + 设定天气更新的时间间隔(秒) 設定天氣更新的時間間隔(秒) + Hava durumu güncellemeleri arasındaki aralığı (saniye) tanımlar Wind Simulation (map based) Wind Simulation (kartenbasiert) Simulazione del Vento (basato sulla mappa) 風力模擬(基於地圖) - 风力模拟(基于地图) + 风力模拟(基于地图) 風シミュレーション (マップを基に) 바람 시뮬레이션 (지도 기반) Symulacja Wiatru (bazowana na mapie) Симуляция ветра (на основе местности) + Simulação de Vento (baseado no mapa) + Simulace větru (podle mapy) + Simulation du vent (basée sur la carte) + Rüzgar Simülasyonu (harita tabanlı) + Simulación de viento (según mapa) Enables the map based wind simulation (overwrites vanilla wind) Aktiviert die kartenbasierte Windsimulation (überschreibt Vanilla Wind) Abilita la simulazione del vento basato sulla mappa (sovrascrive il vento vanilla) 啟用後將遵照地圖特色進行風力模擬(覆蓋掉官方原版的風力模擬) - 启用后将遵照地图特色进行风力模拟(覆盖掉官方原版的风力模拟) - マップを基にした風シミュレーションを有効化 (標準の風を上書き) - 지도 기반의 바람 시뮬레이션을 활성화합니다 (바닐라 바람을 덮음) + 启用后将遵照地图特色进行风力模拟(覆盖掉官方原版的风力模拟) + マップを基にした風シミュレーションを有効化 (ゲーム標準の風を上書き) + 지도 기반의 바람 시뮬레이션을 활성화합니다. (바닐라 바람을 덮어 씀) Aktywuje symulację wiatru bazującą na mapie (nadpisuje wind z domyślnej wersji gry) Включает симуляцию ветра на основе текущей местности (переписывает ванильный ветер) + Ativar a simulação de vento dos mapas. (sobrepõe vento vanilla) + Povoluje simulaci větru založenou na mapě (přepíše původní vítr) + Active la simulation du vent basée sur la carte (écrase le vent vanilla). + Harita tabanlı rüzgar simülasyonunu etkinleştirir (Normal rüzgarının üzerine yazar) + Activa la simulación de viento según mapa (sobreescribe el clima vanilla) + + + Check Air Temperature + Überprüfe Lufttemperatur + 檢查氣溫 + 检查气温 + Controlla temperatura dell'aria + Zkontrolovat teplotu vzduchu + 気温を確認 + Sprawdź temperaturę powietrza + Vérifier la température + Checar a temperatura do ar + Hava Sıcaklığını Kontrol Et + Проверить температуру воздуха + Comprobar temperatura de aire + 기온 측정하기 + + + Show Check Air Temperature Action + Zeige "Überprüfe Lufttemperatur" im Selbstinteraktionsmenü + 顯示檢查氣溫動作 + 显示检查气温选项 + Mostra l'azione di controllo della temperatura dell'aria + Ukázat akci kontroly teploty vzduchu + 気温を確認のアクションを表示 + Pokaż akcje sprawdzającą temperaturę powietrza + Afficher l'interaction "Vérifier la température" + Mostrar a ação "Checar a temperatura do ar" + Hava Sıcaklığını Kontrol Etme Eylemini Göster + Показывать действие проверки температуры + Mostrar acción de comprobar temperatura de aire + 상호작용에서 기온 측정하기 표시 diff --git a/addons/winddeflection/ACE_Settings.hpp b/addons/winddeflection/ACE_Settings.hpp index 73c333479f..84ded86810 100644 --- a/addons/winddeflection/ACE_Settings.hpp +++ b/addons/winddeflection/ACE_Settings.hpp @@ -1,24 +1,11 @@ class ACE_Settings { class GVAR(enabled) { - category = CSTRING(windDeflection_DisplayName); - displayName = CSTRING(deflectionModule_DisplayName); - description = CSTRING(deflectionModule_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(vehicleEnabled) { - category = CSTRING(windDeflection_DisplayName); - displayName = CSTRING(vehicleEnabled_DisplayName); - description = CSTRING(vehicleEnabled_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(simulationInterval) { - category = CSTRING(windDeflection_DisplayName); - displayName = CSTRING(simulationInterval_DisplayName); - description = CSTRING(simulationInterval_Description); - typeName = "SCALAR"; - value = 0.05; - sliderSettings[] = {0, 0.2, 0.05, 2}; + movedToSQF = 1; }; }; diff --git a/addons/winddeflection/CfgEventHandlers.hpp b/addons/winddeflection/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/winddeflection/CfgEventHandlers.hpp +++ b/addons/winddeflection/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/winddeflection/README.md b/addons/winddeflection/README.md index 926b957715..bfa86b83f1 100644 --- a/addons/winddeflection/README.md +++ b/addons/winddeflection/README.md @@ -2,11 +2,3 @@ ace_winddeflection =============== Wind deflection for projectiles/bullets. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Glowbal](https://github.com/Glowbal) -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/winddeflection/XEH_postInit.sqf b/addons/winddeflection/XEH_postInit.sqf index fe454cb00d..a414058349 100644 --- a/addons/winddeflection/XEH_postInit.sqf +++ b/addons/winddeflection/XEH_postInit.sqf @@ -4,17 +4,17 @@ if (!hasInterface) exitWith {}; GVAR(trackedBullets) = []; -["ace_settingsInitialized", { +["CBA_settingsInitialized", { //If not enabled, dont't add PFEH if (!GVAR(enabled)) exitWith {}; // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; if (GVAR(vehicleEnabled)) then { - ["ace_firedPlayerVehicle", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicleNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; }; [] call FUNC(updateTrajectoryPFH); diff --git a/addons/winddeflection/XEH_preInit.sqf b/addons/winddeflection/XEH_preInit.sqf index b47cf6628d..894773534a 100644 --- a/addons/winddeflection/XEH_preInit.sqf +++ b/addons/winddeflection/XEH_preInit.sqf @@ -6,4 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + ADDON = true; diff --git a/addons/winddeflection/functions/fnc_handleFired.sqf b/addons/winddeflection/functions/fnc_handleFired.sqf index f43b40f455..c1b93818f0 100644 --- a/addons/winddeflection/functions/fnc_handleFired.sqf +++ b/addons/winddeflection/functions/fnc_handleFired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * Handles wind deflection for projectiles. Called from the unified fired EH only for players on foot and their vehicles if required by settings. @@ -10,13 +10,13 @@ * None * * Example: - * [clientFiredBIS-XEH] call ace_advanced_ballistics_fnc_handleFired + * [clientFiredBIS-XEH] call ace_winddeflection_fnc_handleFired * * Public: No */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && {_projectile isKindOf "BulletBase" && {_unit isKindOf "Man"}}) exitWith {false}; diff --git a/addons/winddeflection/functions/fnc_initModuleSettings.sqf b/addons/winddeflection/functions/fnc_initModuleSettings.sqf index 39e7fc6f31..58fc1b2f17 100644 --- a/addons/winddeflection/functions/fnc_initModuleSettings.sqf +++ b/addons/winddeflection/functions/fnc_initModuleSettings.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the wind deflection settings @@ -12,7 +12,7 @@ * None * * Example: - * [LOGIC, [bob, kevin], true] call ace_winddeflection_fnc_initModuelSettings + * [LOGIC, [bob, kevin], true] call ace_winddeflection_fnc_initModuleSettings * * Public: No */ diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index e0a6b5da54..4ebea1f507 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg * Handles wind deflection for projectiles. @@ -25,6 +25,7 @@ _args set [0, CBA_missionTime]; private _isWind = (vectorMagnitude wind > 0); + private _deleted = false; { _x params ["_bullet", "_airFriction"]; @@ -32,7 +33,8 @@ private _bulletSpeedSqr = vectorMagnitudeSqr _bulletVelocity; if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeedSqr < 10000}}) then { - GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); + GVAR(trackedBullets) set [_forEachIndex, objNull]; + _deleted = true; } else { if (_isWind) then { private _trueVelocity = _bulletVelocity vectorDiff wind; @@ -48,7 +50,11 @@ }; _bullet setVelocity _bulletVelocity; }; - nil - } count +GVAR(trackedBullets); + } forEach GVAR(trackedBullets); + + if (_deleted) then { + GVAR(trackedBullets) = GVAR(trackedBullets) - [objNull]; + }; + // END_COUNTER(pfeh); }, GVAR(simulationInterval), [CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/winddeflection/functions/script_component.hpp b/addons/winddeflection/functions/script_component.hpp deleted file mode 100644 index ea22ecb35c..0000000000 --- a/addons/winddeflection/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\winddeflection\script_component.hpp" diff --git a/addons/winddeflection/initSettings.inc.sqf b/addons/winddeflection/initSettings.inc.sqf new file mode 100644 index 0000000000..172a1fed2b --- /dev/null +++ b/addons/winddeflection/initSettings.inc.sqf @@ -0,0 +1,25 @@ +private _category = format ["ACE %1", localize LSTRING(windDeflection_DisplayName)]; + +[ + QGVAR(enabled), "CHECKBOX", + [LSTRING(deflectionModule_DisplayName), LSTRING(deflectionModule_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(vehicleEnabled), "CHECKBOX", + [LSTRING(vehicleEnabled_DisplayName), LSTRING(vehicleEnabled_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(simulationInterval), "SLIDER", + [LSTRING(simulationInterval_DisplayName), LSTRING(simulationInterval_Description)], + _category, + [0, 0.2, 0.05, 2], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/winddeflection/stringtable.xml b/addons/winddeflection/stringtable.xml index 53648b2e37..d0c0863a6e 100644 --- a/addons/winddeflection/stringtable.xml +++ b/addons/winddeflection/stringtable.xml @@ -14,8 +14,9 @@ Informação do vento 風の情報 바람 정보 - 风力资讯 + 风力信息 風力資訊 + Rüzgar Bilgisi Direction: %1 @@ -23,15 +24,16 @@ Dirección: %1 Направление: %1° Směr: %1 - Direction %1 + Direction : %1 Windrichtung: %1 Irány: %1 Direzione: %1° Direção: %1 風向: %1 - 방향: %1 - 风向: %1 + 풍향: %1 + 风向:%1 風向: %1 + Yön: %1 Speed: %1 m/s @@ -39,15 +41,16 @@ Velocidad: %1 m/s Скорость: %1 м/с Rychlost: %1 m/s - Vitesse %1 m/s + Vitesse : %1 m/s Geschwindigkeit: %1 m/s Sebesség: %1 m/s Velocità: %1 m/s Velocidade: %1 m/s 風速: %1 m/s 풍속: %1 m/s - 风速: %1 m/s + 风速:%1 m/s 風速: %1 m/s + Hız: %1 m/s Weather Information @@ -58,12 +61,13 @@ Météo Wetterinformationen Időjárás-Információ - Meteo + Informazioni Meteo Informação Meteorológica 天候の情報 기상 정보 - 天气资讯 + 天气信息 天氣資訊 + Hava Durumu Bilgisi Humidity: %1% @@ -71,15 +75,16 @@ Humedad: %1% Влажность: %1% Vlhkost: %1% - Humidité: %1% + Humidité : %1% Luftfeuchtigkeit: %1 Páratartalom: %1% Umidità: %1% - Humidade: %1% + Umidade: %1% 湿度: %1% 습도: %1% - 湿度: %1% + 湿度:%1% 濕度: %1% + Nem Oranı: %1% Wind Deflection @@ -88,14 +93,15 @@ Účinky větru Windablenkung Desvio de vento - Déflexion du vent + Déflexion due au vent Szél-hárítás Отклонение ветром Deviazione del Vento 風向の変化 풍향 변화 - 风偏 + 弹道风偏 風偏 + Rüzgar Sapması Wind Deflection @@ -104,14 +110,15 @@ Windablenkung Účinky větru Desvio de vento - Déflexion du vent + Déflexion due au vent Szél-hárítás Отклонение ветром Deviazione del Vento 風向の変化 풍향 변화 - 风偏 + 弹道风偏 風偏 + Rüzgar Sapması Enables wind deflection @@ -120,14 +127,15 @@ Aktiviert Windablenkung Umožňit vliv větru Ativa o desvio de vento - Active la déflexion dûe au vent + Active la déflexion due au vent. Engedélyezi a szél-hárítást Включает отклонение ветром Abilita deviazione del vento 風向の変化を有効化 풍향 변화를 적용합니다 - 开启风偏效果 + 开启弹道风偏效果 開啟風偏效果 + Rüzgar sapmasını aktif et Vehicle Enabled @@ -136,14 +144,15 @@ Fahrzeuge aktiviert Vozidla povolena Ativado em veículos - Activer les véhicules + Activer pour les véhicules Jármű engedélyezve Для техники Abilita per Veicoli 車両へ有効化 차량 적용 - 启用风偏给载具 + 给载具启用弹道风偏 啟用風偏給載具 + Araçlar da etkin Enables wind deflection for static/vehicle gunners @@ -152,14 +161,15 @@ Aktiviere Windablenkung für statische oder Fahrzeugschützen Umožnit vliv větru pro střelce z vozidla/statiky Ativa o desvio de vento para atiradores de estáticas e veículos - Activer la déflection dûe au vent pour les armes statique et les véhicules + Active la déflexion due au vent pour les armes statiques et les mitrailleuses des véhicules. Engedélyezi a szél-hárítást a statikus/jármű-lövészeknél Включает отклонение ветром для стрелков стационарных орудий и техники Abilita deviazione del vento per artiglieri di statiche/veicoli 重火器や車両へ、風向の変化を有効化 차량이나 거치식 무기 사수에게 풍향 변화를 적용합니다 - 使风偏作用在固定式武器与载具炮手身上 + 使弹道风偏作用在固定式武器与载具炮手身上 使風偏作用在固定式武器與載具砲手身上 + Araç nişancıları için rüzgar sapmasını etkinleştirir. Simulation Interval @@ -184,7 +194,7 @@ Definiert das Intervall zwischen jedem Berechnungsschritt Určuje interval mezi každým výpočtem Define o intervalo entre cada cálculo - Défini l'intervalle entre deux points de calcul + Définit l'intervalle entre chacune des étapes de calcul. Megszabja a számítási lépések közötti intervallumot Определяет временной интервал между расчетами Definisce l'intervallo tra ogni passaggio di calcolo @@ -200,7 +210,7 @@ Windeinfluss auf die Geschossbahnen Vítr ovlivňuje trajektorii projektilu Influência do vento na trajetória dos projéteis - Le vent influe sur la trajectoire des projectiles + Le vent influe sur la trajectoire des projectiles. Szél hatása a lövedékek röppályájára Влияние втера на траекторию снарядов Influenza del vento sulla traiettoria dei proiettili diff --git a/addons/xm157/$PBOPREFIX$ b/addons/xm157/$PBOPREFIX$ new file mode 100644 index 0000000000..2bddd0ac4e --- /dev/null +++ b/addons/xm157/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\xm157 \ No newline at end of file diff --git a/addons/xm157/CfgEventHandlers.hpp b/addons/xm157/CfgEventHandlers.hpp new file mode 100644 index 0000000000..2a3f71f852 --- /dev/null +++ b/addons/xm157/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/xm157/CfgSounds.hpp b/addons/xm157/CfgSounds.hpp new file mode 100644 index 0000000000..6b9b81496b --- /dev/null +++ b/addons/xm157/CfgSounds.hpp @@ -0,0 +1,6 @@ +class CfgSounds { + class GVAR(click) { + sound[] = {QPATHTOF(sounds\click.wav), "db-30", 3}; + titles[] = {}; + }; +}; diff --git a/addons/xm157/CfgWeapons.hpp b/addons/xm157/CfgWeapons.hpp new file mode 100644 index 0000000000..cfa8197f48 --- /dev/null +++ b/addons/xm157/CfgWeapons.hpp @@ -0,0 +1,49 @@ +class CfgWeapons { + class ItemCore; + class InventoryOpticsItem_Base_F; + + class ace_xm157_prototype: ItemCore { + author = ECSTRING(common,ACETeam); + scope = 1; // hidden + displayName = "XM157 Prototype"; + descriptionShort = ""; + picture = "\a3\Weapons_F\acc\Data\UI\icon_optic_tws_ca.paa"; + model = "\A3\weapons_f\acc\acco_tws_F"; + inertia = 0.3; + ACE_ScopeHeightAboveRail = 5.52874; + + class CBA_ScriptedOptic { + bodyTexture = QPATHTOF(data\ace_vector_body_co.paa); + // bodyTextureNight = ".paa"; // optional + bodyTextureSize = 1; + hideMagnification = 1; // no point, and it flickers at 1x + disableTilt = 0; + }; + + weaponInfoType = QGVAR(info); + class ItemInfo: InventoryOpticsItem_Base_F { + mass = 14; + optics = 1; + modelOptics = "\x\cba\addons\optics\cba_optic_big_100.p3d"; + class OpticsModes { + class lpvo { + opticsID = 1; + useModelOptics = 1; + opticsPPEffects[] = { "OpticsCHAbera1", "OpticsBlur1" }; + opticsZoomMin = "8 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + opticsZoomMax = "1 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + opticsZoomInit = "1 call (uiNamespace getVariable 'cba_optics_fnc_setOpticMagnificationHelper')"; + discreteDistance[] = {100}; + discreteDistanceInitIndex = 0; + distanceZoomMin = 100; + distanceZoomMax = 100; + memoryPointCamera = "opticView"; + visionMode[] = {"Normal"}; + opticsFlare = 1; + opticsDisablePeripherialVision = 1; + cameraDir = ""; + }; + }; + }; + }; +}; diff --git a/addons/xm157/README.md b/addons/xm157/README.md new file mode 100644 index 0000000000..55a0696216 --- /dev/null +++ b/addons/xm157/README.md @@ -0,0 +1,2 @@ +ace_xm157 +========== diff --git a/addons/xm157/RscInGameUI.hpp b/addons/xm157/RscInGameUI.hpp new file mode 100644 index 0000000000..f08e79d451 --- /dev/null +++ b/addons/xm157/RscInGameUI.hpp @@ -0,0 +1,79 @@ +class RscObject; +class RscControlsGroupNoScrollbars; + +class RscText; +class GVAR(text): RscText { + font = "EtelkaMonospacePro"; + SizeEx = 0.04; + colorText[]={1,0.1,0.05,0.95}; + shadow = 0; +}; +class GVAR(textMenu): GVAR(text) { + SizeEx = 0.09; + style = "2+16"; +}; + +class RscInGameUI { + class CBA_ScriptedOptic_zooming; + class GVAR(info): CBA_ScriptedOptic_zooming { + onLoad = QUOTE(call FUNC(weaponInfo_onLoad)); + class objects { + class Optic: RscObject { // first focal plane + idc = IDC_SCOPE_OBJECT; + type = 82; + model = "\A3\Misc_F\Helpers\UserTexture1m.p3d"; + x = 0; + y = 0; + z = 0; + xBack = 0.9; + yBack = 0.9; + zBack = 0.3; + inBack = 0; + enableZoom = 1; + zoomDuration = 0.001; + class Areas { + class usertexture { + selection = "usertexture"; + class controls { + class test: RscControlsGroupNoScrollbars { + idc = IDC_SCOPE_GROUP; + x = 0; + y = 0; + w = 1; + h = "4/3"; + }; + }; + }; + }; + }; + class Screen: RscObject { + idc = IDC_SCREEN_OBJECT; + type = 82; + model = "\A3\Misc_F\Helpers\UserTexture1m.p3d"; + x = 0; + y = 0; + z = 0; + xBack = 0.9; + yBack = 0.9; + zBack = 0.3; + inBack = 1; + enableZoom = 1; + zoomDuration = 0.001; + class Areas { + class usertexture { + selection = "usertexture"; + class controls { + class test: RscControlsGroupNoScrollbars { + idc = IDC_SCREEN_GROUP; + x = 0; + y = 0; + w = 1; + h = "4/3"; + }; + }; + }; + }; + }; + }; + }; +}; diff --git a/addons/xm157/XEH_PREP.hpp b/addons/xm157/XEH_PREP.hpp new file mode 100644 index 0000000000..56613ffe34 --- /dev/null +++ b/addons/xm157/XEH_PREP.hpp @@ -0,0 +1,8 @@ +LOG("prep"); + +PREP(ballistics_calculator); +PREP(ballistics_getData); +PREP(keyPress); +PREP(weaponInfo_draw); +PREP(weaponInfo_drawMenu); +PREP(weaponInfo_onLoad); diff --git a/addons/xm157/XEH_postInit.sqf b/addons/xm157/XEH_postInit.sqf new file mode 100644 index 0000000000..8b77f466c8 --- /dev/null +++ b/addons/xm157/XEH_postInit.sqf @@ -0,0 +1,65 @@ +#include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +GVAR(shown) = false; +GVAR(data) = createHashMap; +GVAR(data) set ["latitude", EGVAR(common,mapLatitude)]; + + +// Add Keybinds +["ACE3 Equipment", QGVAR(range), [format ["XM157 - %1", localize "str_a3_rscdisplayarsenal_stat_range"]], { + ["range", true] call FUNC(keyPress); +}, { + ["range", false] call FUNC(keyPress); +}, [DIK_TAB, [false, false, false]], false, 0] call CBA_fnc_addKeybind; + +["ACE3 Equipment", QGVAR(left), [format ["XM157 - %1", localize "str_a3_left"]], { + ["right", true] call FUNC(keyPress); +}, { + ["right", false] call FUNC(keyPress); +}, [DIK_END, [false, false, false]], false, 0] call CBA_fnc_addKeybind; + +["ACE3 Equipment", QGVAR(right), [format ["XM157 - %1", localize "str_a3_right"]], { + ["left", true] call FUNC(keyPress); +}, { + ["left", false] call FUNC(keyPress); +}, [DIK_DELETE, [false, false, false]], false, 0] call CBA_fnc_addKeybind; + +["ACE3 Equipment", QGVAR(up), [format ["XM157 - %1", localize "str_a3_rscattributetargetstate_up"]], { + ["up", true] call FUNC(keyPress); +}, { + ["up", false] call FUNC(keyPress); +}, [DIK_PGUP, [false, false, false]], false, 0] call CBA_fnc_addKeybind; + +["ACE3 Equipment", QGVAR(down), [format ["XM157 - %1", localize "str_a3_rscattributetargetstate_down"]], { + ["down", true] call FUNC(keyPress); +}, { + ["down", false] call FUNC(keyPress); +}, [DIK_PGDN, [false, false, false]], false, 0] call CBA_fnc_addKeybind; + + + +#ifdef ENABLE_QUICK_TESTING +player addPrimaryWeaponItem "ace_xm157_prototype"; +[player] call CBA_fnc_addUnitTrackProjectiles; +player addItem "ACE_ATragMX"; +player addItem "ace_rangecard"; + +["recompile", "recompile", "recompile", { + private _start = diag_tickTime; + [] call ACE_PREP_RECOMPILE; + [] call ace_common_fnc_dumpPerformanceCounters; + private _end = diag_tickTime; + systemChat format ["recompile took [%1 ms]", (1000 * (_end - _start)) toFixed 1]; + + if (productVersion #4 == "Diag") then { + call compile "diag_mergeConfigFile ['P:\z\ace\addons\xm157\config.cpp']"; + }; + + private _windSpd = vectorMagnitude wind; + private _windDir = (wind select 0) atan2 (wind select 1); + systemChat format ["Wind %1 @ %2", _windSpd, _windDir + 180]; + + false +}, {false}, [0x21, [false, false, false]], false] call CBA_fnc_addKeybind; // F Key +#endif diff --git a/addons/xm157/XEH_preInit.sqf b/addons/xm157/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/xm157/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/xm157/XEH_preStart.sqf b/addons/xm157/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/xm157/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/xm157/config.cpp b/addons/xm157/config.cpp new file mode 100644 index 0000000000..2689764b19 --- /dev/null +++ b/addons/xm157/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {"ace_xm157_prototype"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_advanced_ballistics", "ace_scopes"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgSounds.hpp" +#include "CfgWeapons.hpp" +#include "RscInGameUI.hpp" + +class asdg_OpticRail; +class asdg_OpticRail1913: asdg_OpticRail { + class compatibleItems { + ace_xm157_prototype = 1; + }; +}; diff --git a/addons/xm157/data/ace_vector_body_co.paa b/addons/xm157/data/ace_vector_body_co.paa new file mode 100644 index 0000000000..71e1984c6e Binary files /dev/null and b/addons/xm157/data/ace_vector_body_co.paa differ diff --git a/addons/xm157/data/mrad_10_ca.paa b/addons/xm157/data/mrad_10_ca.paa new file mode 100644 index 0000000000..293a29debe Binary files /dev/null and b/addons/xm157/data/mrad_10_ca.paa differ diff --git a/addons/xm157/data/mrad_20_ca.paa b/addons/xm157/data/mrad_20_ca.paa new file mode 100644 index 0000000000..99b724a861 Binary files /dev/null and b/addons/xm157/data/mrad_20_ca.paa differ diff --git a/addons/xm157/data/mrad_40_ca.paa b/addons/xm157/data/mrad_40_ca.paa new file mode 100644 index 0000000000..9e097adff1 Binary files /dev/null and b/addons/xm157/data/mrad_40_ca.paa differ diff --git a/addons/xm157/dev/generate_reticle.py b/addons/xm157/dev/generate_reticle.py new file mode 100644 index 0000000000..119b547ab4 --- /dev/null +++ b/addons/xm157/dev/generate_reticle.py @@ -0,0 +1,178 @@ +from PIL import Image, ImageDraw, ImageFont, ImageFilter +import math + +# based on vortex razor hd + +final_scale = 10 + +supersample = 4 +# supersampling helps make rounded circles, does slighly blur text and straight lines +pixels_per_mrad = supersample * final_scale +image_size = supersample * 4096 +image_center = image_size / 2 + +# create an image +out = Image.new("RGBA", (image_size, image_size), (255, 255, 255, 0)) +# get a drawing context +d = ImageDraw.Draw(out) + +line_thin = math.floor(0.07 * pixels_per_mrad) +line_thick = math.floor(0.15 * pixels_per_mrad) +font_size = math.floor(0.55 * pixels_per_mrad) +# source https://fonts.google.com/specimen/Electrolize (Open Font License) +fnt = ImageFont.truetype("Electrolize-Regular.ttf", font_size) + +# draw center dot +d.ellipse([ + (image_center - 0.1 * pixels_per_mrad, image_center - 0.1 * pixels_per_mrad), + (image_center + 0.1 * pixels_per_mrad, image_center + 0.1 * pixels_per_mrad) +], fill=(0, 0, 0)) + +# draw 3 main axis lines +d.line([ + (image_center - 8 * pixels_per_mrad, image_center), + (image_center - 0.5 * pixels_per_mrad, image_center) +], fill=(0, 0, 0), width=line_thin) +d.line([ + (0, image_center), + (image_center - 8.5 * pixels_per_mrad, image_center) +], fill=(0, 0, 0), width=line_thick) +d.line([ + (image_center + 0.5 * pixels_per_mrad, image_center), + (image_center + 8 * pixels_per_mrad, image_center) +], fill=(0, 0, 0), width=line_thin) +d.line([ + (image_center + 8.5 * pixels_per_mrad, image_center), + (image_size, image_center) +], fill=(0, 0, 0), width=line_thick) +d.line([ + (image_center, image_center + 0.5 * pixels_per_mrad), + (image_center, image_center + 11 * pixels_per_mrad) +], fill=(0, 0, 0), width=line_thin) +d.line([ + (image_center, image_center + 11.5 * pixels_per_mrad), + (image_center, image_size) +], fill=(0, 0, 0), width=line_thick) + +# draw big triangle bar things +if (image_center - 15 * pixels_per_mrad > 0): + d.polygon([ + (0, image_center + 2 * pixels_per_mrad), + (image_center - 20 * pixels_per_mrad, image_center + 2 * pixels_per_mrad), + (image_center - 15 * pixels_per_mrad, image_center), + (image_center - 20 * pixels_per_mrad, image_center - 2 * pixels_per_mrad), + (0, image_center - 2 * pixels_per_mrad), + ], fill=(0, 0, 0)) + d.polygon([ + (image_size, image_center + 2 * pixels_per_mrad), + (image_center + 20 * pixels_per_mrad, image_center + 2 * pixels_per_mrad), + (image_center + 15 * pixels_per_mrad, image_center), + (image_center + 20 * pixels_per_mrad, image_center - 2 * pixels_per_mrad), + (image_size, image_center - 2 * pixels_per_mrad), + ], fill=(0, 0, 0)) + d.polygon([ + (image_center - 2 * pixels_per_mrad, image_size), + (image_center - 2 * pixels_per_mrad, image_center + 20 * pixels_per_mrad), + (image_center, image_center + 15 * pixels_per_mrad), + (image_center + 2 * pixels_per_mrad, image_center + 20 * pixels_per_mrad), + (image_center + 2 * pixels_per_mrad, image_size), + ], fill=(0, 0, 0)) + + +# draw windage hash marks and text +for x in range(1, 9): + if (x % 2 == 0): + text = f"{abs(x)}" + # windage odd numbers + d.text((image_center + (x - 0.15) * pixels_per_mrad, image_center - 1.2 * pixels_per_mrad), text, font=fnt, fill=(0, 0, 0)) + d.text((image_center - (x + 0.15) * pixels_per_mrad, image_center - 1.2 * pixels_per_mrad), text, font=fnt, fill=(0, 0, 0)) + # windage mrad hashs + d.line([ + (image_center + x * pixels_per_mrad, image_center + line_thin / 2), + (image_center + x * pixels_per_mrad, image_center - 0.5 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thin) + d.line([ + (image_center - x * pixels_per_mrad, image_center + line_thin / 2), + (image_center - x * pixels_per_mrad, image_center - 0.5 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thin) + if (x % 2 == 0): + d.line([ + (image_center - x * pixels_per_mrad, image_center + 0.2 * pixels_per_mrad), + (image_center - x * pixels_per_mrad, image_center + 0.7 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thick) + d.line([ + (image_center + x * pixels_per_mrad, image_center + 0.2 * pixels_per_mrad), + (image_center + x * pixels_per_mrad, image_center + 0.7 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thick) + else: + d.line([ + (image_center - x * pixels_per_mrad, image_center + 0.2 * pixels_per_mrad), + (image_center - x * pixels_per_mrad, image_center + 0.55 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thick) + d.line([ + (image_center + x * pixels_per_mrad, image_center + 0.2 * pixels_per_mrad), + (image_center + x * pixels_per_mrad, image_center + 0.55 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thick) + + if (x < 8): + # windage half mrad marks + d.line([ + (image_center + (x + .5) * pixels_per_mrad, image_center), + (image_center + (x + .5) * pixels_per_mrad, image_center - 0.25 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thin) + d.line([ + (image_center - (x + .5) * pixels_per_mrad, image_center), + (image_center - (x + .5) * pixels_per_mrad, image_center - 0.25 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thin) + +# handle 10 mrad thick line +d.multiline_text((image_center + (10 - 0.4) * pixels_per_mrad, image_center - 1.2 * pixels_per_mrad), "10", font=fnt, fill=(0, 0, 0)) +d.line([ + (image_center + 10 * pixels_per_mrad, image_center - 0.5 * pixels_per_mrad), + (image_center + 10 * pixels_per_mrad, image_center + 0.5 * pixels_per_mrad) +], fill=(0, 0, 0), width=line_thick) +d.multiline_text((image_center + (-10 - 0.4) * pixels_per_mrad, image_center - 1.2 * pixels_per_mrad), "10", font=fnt, fill=(0, 0, 0)) +d.line([ + (image_center - 10 * pixels_per_mrad, image_center - 0.5 * pixels_per_mrad), + (image_center - 10 * pixels_per_mrad, image_center + 0.5 * pixels_per_mrad) +], fill=(0, 0, 0), width=line_thick) + +for y in range(1, 12): + line_y = image_center + y * pixels_per_mrad + # elev hash marks + d.line([ + (image_center - 0.5 * pixels_per_mrad, line_y), + (image_center + 0.5 * pixels_per_mrad, line_y) + ], fill=(0, 0, 0), width=line_thin) + if (y < 11): # half marks + d.line([ + (image_center - 0.1 * pixels_per_mrad, line_y + 0.5 * pixels_per_mrad), + (image_center + 0.1 * pixels_per_mrad, line_y + 0.5 * pixels_per_mrad) + ], fill=(0, 0, 0), width=line_thin) + + dot_count = 2 + if (y > 2): dot_count = 3 + if (y > 4): dot_count = 4 + if (y > 6): dot_count = 5 + for dot in range(1, dot_count + 1): + d.ellipse([ + (image_center + (dot - 0.1) * pixels_per_mrad, line_y - 0.1 * pixels_per_mrad), + (image_center + (dot + 0.1) * pixels_per_mrad, line_y + 0.1 * pixels_per_mrad) + ], fill=(0, 0, 0)) + d.ellipse([ + (image_center + (-dot - 0.1) * pixels_per_mrad, line_y - 0.1 * pixels_per_mrad), + (image_center + (-dot + 0.1) * pixels_per_mrad, line_y + 0.1 * pixels_per_mrad) + ], fill=(0, 0, 0)) + if (y % 2 == 0): + d.text((image_center + (dot_count + 0.85) * pixels_per_mrad, line_y - 0.3 * pixels_per_mrad), f"{y}", font=fnt, fill=(0, 0, 0)) + if (y >= 10): dot_count += 0.2 + d.text((image_center - (dot_count + 1.15) * pixels_per_mrad, line_y - 0.3 * pixels_per_mrad), f"{y}", font=fnt, fill=(0, 0, 0)) + +if (supersample > 1): + out = out.resize((4096, 4096)) + + +output_filename = f"mrad_{final_scale}_ca.png" +out.show() +out.save(output_filename) +print(f"written to {output_filename}") diff --git a/addons/xm157/functions/fnc_ballistics_calculator.sqf b/addons/xm157/functions/fnc_ballistics_calculator.sqf new file mode 100644 index 0000000000..a39b09a705 --- /dev/null +++ b/addons/xm157/functions/fnc_ballistics_calculator.sqf @@ -0,0 +1,101 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, Ruthberg (Based on ace_atragmx_fnc_calculate_solution) + * Calculates elevation and windage + * + * Arguments: + * 0: Range + * 1: Direction of Fire (deg) - Yaw + * 2: Inlination (deg) - Pitch + * 3: Bank (deg) - Roll + * + * Return Value: + * Elevation and Windage in MRAD + * + * Example: + * [500, 90, 0, 0] call ace_xm157_fnc_ballistics_calculator + * + * Public: No + */ + +params ["_targetRange", "_directionOfFire", "_inclinationAngle", "_bank"]; + +private _weaponInfo = [] call FUNC(ballistics_getData); +if (_weaponInfo isEqualTo []) exitWith { [0,0] }; +_weaponInfo params ["_scopeBaseAngle","_boreHeight","_airFriction","_muzzleVelocity","_bc", + "_dragModel","_atmosphereModel","_barrelTwist","_twistDirection","_caliber","_bulletLength","_bulletMass"]; + +private _latitude = GVAR(data) getOrDefault ["latitude", 0]; + +// Get Wind +private _windSpeed = GVAR(data) getOrDefault ["wind_speed", 0]; +private _windDirection = 22.5 * (GVAR(data) getOrDefault ["wind_dir", 0]); +private _wind = [sin (_directionOfFire-_windDirection) * _windSpeed, -cos (_directionOfFire-_windDirection) * _windSpeed, 0]; + +// Get atmosphere +private _altitude = (getPosASL ace_player) select 2; +private _relativeHumidity = EGVAR(weather,currentHumidity); +private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); +private _barometricPressure = _altitude call EFUNC(weather,calculateBarometricPressure); + + +private _bulletPos = [0,0,-(_boreHeight / 100)]; +private _lastBulletPos = +_bulletPos; +private _bulletVelocity = [0,Cos(_scopeBaseAngle) * _muzzleVelocity,Sin(_scopeBaseAngle) * _muzzleVelocity]; +private _gravity = [-sin (_bank) * cos(_scopeBaseAngle + _inclinationAngle) * -GRAVITY, + sin(_scopeBaseAngle + _inclinationAngle) * -GRAVITY, + cos (_bank) * cos(_scopeBaseAngle + _inclinationAngle) * -GRAVITY]; + +private _useAB = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; +if (_useAB) then { + _bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel])); +}; + +private _deltaT = 1 / 60; +private _TOF = 0; // Limit TOF to 5 seconds! +while {(_TOF < 5) && {(_bulletPos # 1) < _targetRange}} do { + private _trueVelocity = _bulletVelocity vectorDiff _wind; + private _trueSpeed = vectorMagnitude _trueVelocity; + + private _bulletAccel = if (_useAB) then { + private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _trueSpeed, _temperature])); + (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); + } else { + _trueVelocity vectorMultiply (_trueSpeed * _airFriction); + }; + _bulletAccel = _bulletAccel vectorAdd _gravity; + _lastBulletPos = _bulletPos; + _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply (_deltaT * 0.5)); + _bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT); + _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply (_deltaT * 0.5)); + + _TOF = _TOF + _deltaT; +}; + +private _tx = (_lastBulletPos select 0) + (_targetRange - (_lastBulletPos select 1)) * ((_bulletPos select 0) - (_lastBulletPos select 0)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); +private _tz = (_lastBulletPos select 2) + (_targetRange - (_lastBulletPos select 1)) * ((_bulletPos select 2) - (_lastBulletPos select 2)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); +private _elevation = - atan(_tz / _targetRange); +private _windage = - atan(_tx / _targetRange); + + +if (_useAB && {(_bulletPos select 1) > 0}) then { + // Coriolis + private _horizontalDeflection = 0.0000729 * (_bulletPos select 1) * _TOF * sin(_latitude); + private _horizontalCoriolis = - atan(_horizontalDeflection / (_bulletPos select 1)); + _windage = _windage + _horizontalCoriolis; + // Eoetvoes + private _eoetvoesMultiplier = 2 * (0.0000729 * _muzzleVelocity / -GRAVITY) * cos(_latitude) * sin(_directionOfFire); + private _verticalDeflection = (_bulletPos select 2) * _eoetvoesMultiplier; + private _verticalCoriolis = - atan(_verticalDeflection / (_bulletPos select 1)); + _elevation = _elevation + _verticalCoriolis; + // Spin drift + private _stabilityFactor = 1.5; + if (_caliber * _bulletLength * _bulletMass * _barrelTwist > 0) then { + _stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call EFUNC(advanced_ballistics,calculateStabilityFactor); + }; + private _spinDeflection = _twistDirection * 0.0254 * 1.25 * (_stabilityFactor + 1.2) * _TOF ^ 1.83; + private _spinDrift = - atan(_spinDeflection / (_bulletPos select 1)); + _windage = _windage + _spinDrift; +}; + +[17.453*_elevation, 17.453*_windage] // Convert to MRAD and return diff --git a/addons/xm157/functions/fnc_ballistics_getData.sqf b/addons/xm157/functions/fnc_ballistics_getData.sqf new file mode 100644 index 0000000000..828db8e4ae --- /dev/null +++ b/addons/xm157/functions/fnc_ballistics_getData.sqf @@ -0,0 +1,67 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, Ruthberg (Based on ace_atragmx) + * Gets ballistic info for a weapon, mag and ammo + * + * Arguments: + * None + * + * Return Value: + * Weapon Info + * + * Example: + * [] call ace_xm157_fnc_ballistics_getData + * + * Public: No + */ + +private _unit = ace_player; +private _weaponClass = primaryWeapon _unit; +private _magazineClass = (primaryWeaponMagazine _unit) param [0, ""]; +private _ammoClass = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); + +private _key = format ["weaponInfoCache-%1-%2-%3",_weaponClass,_magazineClass,_ammoClass]; +private _weaponInfo = GVAR(data) getOrDefault [_key, []]; +if ((_weaponInfo isEqualTo []) && {_magazineClass != ""}) then { + TRACE_3("new weapon/mag",_weaponClass,_magazineClass,_ammoClass); + + private _zeroRange = 100; + private _boreHeight = [_unit, 0] call EFUNC(scopes,getBoreHeight); + + private _ammoConfig = _ammoClass call EFUNC(advanced_ballistics,readAmmoDataFromConfig); + _ammoConfig params ["_airFriction","_caliber","_bulletLength","_bulletMass","","_dragModel","_ballisticCoefficients","","_atmosphereModel","","_muzzleVelocityTable","_barrelLengthTable"]; + private _weaponConfig = _weaponClass call EFUNC(advanced_ballistics,readWeaponDataFromConfig); + _weaponConfig params ["_barrelTwist", "_twistDirection", "_barrelLength"]; + private _bc = if (_ballisticCoefficients isEqualTo []) then { 0 } else { _ballisticCoefficients # 0 }; + + private _useAB = ( + missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} && + {_bc != 0} + ); + + // Get Muzzle Velocity + private _muzzleVelocity = if (_barrelLength > 0 && _useAB) then { + [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift) + } else { + private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed"); + private _initSpeedCoef = getNumber (configFile >> "CfgWeapons" >> _weaponClass >> "initSpeed"); + if (_initSpeedCoef < 0) then { + _initSpeed = _initSpeed * -_initSpeedCoef; + }; + if (_initSpeedCoef > 0) then { + _initSpeed = _initSpeedCoef; + }; + _initSpeed + }; + + // Scope Base Angle + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; + private _scopeBaseAngle = parseNumber _zeroAngle; + + _weaponInfo = [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,_bc,_dragModel,_atmosphereModel,_barrelTwist,_twistDirection,_caliber,_bulletLength,_bulletMass]; + GVAR(data) set [_key, _weaponInfo]; + TRACE_1("setting cache",_weaponInfo); +}; + +_weaponInfo diff --git a/addons/xm157/functions/fnc_keyPress.sqf b/addons/xm157/functions/fnc_keyPress.sqf new file mode 100644 index 0000000000..3a9dd53a26 --- /dev/null +++ b/addons/xm157/functions/fnc_keyPress.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Handles key presses + * + * Arguments: + * 0: Type + * 1: IsKeyDown + * + * Return Value: + * Handled + * + * Example: + * ["range", true] call ace_xm157_fnc_keyPress + * + * Public: No + */ + +params ["_func", "_keyDown"]; + +if (!GVAR(shown)) exitWith { false }; // fast exit if not shown +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith { false }; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith { false }; + +if (currentMuzzle ACE_player != currentWeapon ACE_player) exitWith { false }; +private _display = uinamespace getVariable [QGVAR(display), displayNull]; +if (isNull _display) exitWith { ERROR("keyPress-no display"); false }; + +if (_keyDown) then { playSound QGVAR(click); }; +GVAR(data) set ["lastInputTime", CBA_missionTime]; + +call { + if (_func == "range") exitWith { + if (_keyDown) then { + GVAR(data) set ["range_keyDownStart", CBA_missionTime]; + } else { + private _holdTime = CBA_missionTime - (GVAR(data) getOrDefault ["range_keyDownStart", 0]); + private _range = 0; + if (_holdTime < 0.5) then { + private _distance = round parseNumber ctrlText (_display displayCtrl 151); + if (_distance > 10 && {_distance < RANGEFINDER_MAX}) then { + _range = _distance; + } else { + _range = -1; // bad return + }; + }; + TRACE_1("Updating range",_range); + GVAR(data) set ["range", _range]; + }; + }; + if (!_keyDown) exitWith {}; + + GVAR(data) set ["menu_updated", true]; + private _index = GVAR(data) getOrDefault ["menu_index", 0]; + if (_func in ["left", "right"]) exitWith { + _index = (_index + ([-1, 1] select (_func == "right")) + count GVAR(menu)) % count GVAR(menu); + GVAR(data) set ["menu_index", _index]; + }; + (GVAR(menu) # _index) params ["", "_var", "_thing", ["_upAction", {}], ["_downAction", {}]]; + if (_func == "up") exitWith { + [_index, _var, _thing] call _upAction; + }; + if (_func == "down") exitWith { + [_index, _var, _thing] call _downAction; + }; +}; + +true diff --git a/addons/xm157/functions/fnc_weaponInfo_draw.sqf b/addons/xm157/functions/fnc_weaponInfo_draw.sqf new file mode 100644 index 0000000000..c03b575f4e --- /dev/null +++ b/addons/xm157/functions/fnc_weaponInfo_draw.sqf @@ -0,0 +1,144 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Draw3D event handler when scope is active + * + * Arguments: + * None (implicit vars from missionEventHandler) + * + * Return Value: + * None + * + * Example: + * [] call ace_xm157_fnc_weaponInfo_draw + * + * Public: No + */ + +//IGNORE_PRIVATE_WARNING ["_thisArgs", "_thisEventHandler"]; // from missionEventHandler +_thisArgs params ["_display"]; +if (isNull _display) exitWith { + TRACE_1("cleaning up display",_thisEventHandler); + GVAR(shown) = false; + removeMissionEventHandler ["Draw3D", _thisEventHandler]; +}; +private _ctrlScopeObject = _display displayCtrl IDC_SCOPE_OBJECT; +private _ctrlScreenObject = _display displayCtrl IDC_SCREEN_OBJECT; + + +// Hide everything when not in scope +private _isUsingOptic = ctrlShown (_display displayCtrl 154); +if (!_isUsingOptic) exitWith { + _ctrlScopeObject ctrlShow false; + _ctrlScreenObject ctrlShow false; +}; +_ctrlScopeObject ctrlShow true; +_ctrlScreenObject ctrlShow true; +BEGIN_COUNTER(draw); + +// Get common info +private _weaponVec = ace_player weaponDirection currentWeapon ace_player; +(_weaponVec call CBA_fnc_vect2Polar) params ["", "_weaponDir", "_weaponPitch"]; +private _weaponBank = call cba_optics_fnc_gunBank; +private _viewBank = _weaponBank; +if (isWeaponDeployed [player, true]) then { // prone deploy tilting is special (screen doesn't tilt, but player does) + _weaponBank = (((vectorUp ace_player) vectorCrossProduct _weaponVec) call CBA_fnc_vect2Polar) # 2; // I think this is right? +}; + +(0.25 call CBA_fnc_getFov) params ["_fov", "_zoom"]; +private _fovMRAD = 1000 * _fov; // Real MRAD (not mils) +private _nonMagnified = _zoom < 1.1; +private _range = GVAR(data) getOrDefault ["range", 0]; +private _needsUpdate = GVAR(data) getOrDefault ["menu_updated", true]; // Updated when a menu item changed +private _timeSinceLastInput = CBA_missionTime - (GVAR(data) getOrDefault ["lastInputTime", 0]); + + +// Bank-tilt display objects +_ctrlScopeObject ctrlSetModelDirAndUp [[0,1,0],[sin _viewBank,0,cos _viewBank]]; +_ctrlScreenObject ctrlSetModelDirAndUp [[0,1,0],[sin _viewBank,0,cos _viewBank]]; + + +// Scope - Handle etched reticle +private _retTex = QPATHTOF(data\mrad_10_ca.paa); +private _retScale = 4096/10; // texureResolution / (px/MRAD) +switch (true) do { + case (_fovMRAD < 4096/40): { + _retTex = QPATHTOF(data\mrad_40_ca.paa); + _retScale = 4096/40; + }; + case (_fovMRAD < 4096/20): { + _retTex = QPATHTOF(data\mrad_20_ca.paa); + _retScale = 4096/20; + }; +}; +private _scale = 1 / (getResolution # 5); +_scale = 2 * _scale * _retScale / _fovMRAD; +_ctrlScopeObject ctrlSetModelScale _scale; +private _ctrlScopeReticle = _display displayCtrl IDC_SCOPE_RETICLE; +if (_retTex != ctrlText _ctrlScopeReticle) then { _ctrlScopeReticle ctrlSetText _retTex; }; + + +// Screen - Draw menu +[_display, _needsUpdate] call FUNC(weaponInfo_drawMenu); + + +// Screen - Show range info +private _rangeInfo = _range call { + if (_range == 0) exitWith { "" }; + if (_range < 0) exitWith { // range error - blink if recent + ["", "----"] select ((_timeSinceLastInput < 3) && {(floor (4*_timeSinceLastInput)) % 2 == 1}); + }; + format ["%1 m", _range toFixed 0] +}; +private _ctrl = _display displayCtrl IDC_SCREEN_TEXT_UPPER_RIGHT; +_ctrl ctrlSetText _rangeInfo; + + +// Screen - Show bearing info +private _bearingInfo = call { + private _bearingSetting = GVAR(data) getOrDefault ["bearing_show", 0]; + if ((_bearingSetting == 2) && {_timeSinceLastInput > 2}) exitWith { "" }; + if ((_bearingSetting == 1)) exitWith { str floor (17.777777 * _weaponDir); }; // (6400 Mils, not MRAD) + format ["%1°", floor _weaponDir]; +}; +private _ctrl = _display displayCtrl IDC_SCREEN_TEXT_UPPER_LEFT; +_ctrl ctrlSetText _bearingInfo; + + +// Screen - update reticle type based on settings and zoom level +private _ctrl = _display displayCtrl IDC_SCREEN_RETICLE; +private _lastMagnified = GVAR(data) getOrDefault ["reticle_cache_lastMag", true]; +private _size = GVAR(data) getOrDefault ["reticle_cache_size", 1]; +if (_needsUpdate || {_nonMagnified isNotEqualTo _lastMagnified}) then { + private _tex = ""; + if (_nonMagnified) then { + switch (GVAR(data) getOrDefault ["reticle_cqb", 0]) do { + case (0): { _tex = "\a3\weapons_f\acc\data\collimdot_dot_red_ca.paa"; _size = 1; }; + case (1): { _tex = "\a3\weapons_f\acc\data\collimdot_dot_red_ca.paa"; _size = 2; }; + case (2): { _tex = "\a3\weapons_f\acc\data\collimdot_circle_red_ca.paa"; _size = 1; }; + case (3): { _tex = "\a3\weapons_f\acc\data\collimdot_dot_green_ca.paa"; _size = 1; }; + case (4): { _size = 0; }; + }; + } else { + _tex = "\a3\weapons_f\acc\data\collimdot_dot_red_ca.paa"; _size = 1; + }; + _ctrl ctrlSetText _tex; + GVAR(data) set ["reticle_cache_lastMag", _nonMagnified]; + GVAR(data) set ["reticle_cache_size", _size]; +}; + + +// Screen - update reticle position based on ballistics computer +if (_range > 0 && {_size > 0}) then { + BEGIN_COUNTER(ballistics_calculator); + ([_range, _weaponDir, _weaponPitch, _weaponBank] call FUNC(ballistics_calculator)) params ["_elevMRAD", "_windMRAD"]; + END_COUNTER(ballistics_calculator); + _ctrl ctrlSetPosition [-_windMRAD / _fovMRAD + 0.5 - _size / 2, + 4/3 * (_elevMRAD / _fovMRAD + 0.5 - _size/2), _size, _size*4/3]; + _ctrl ctrlCommit 0; +} else { + _ctrl ctrlSetPosition [0.5 - _size / 2, + 4/3 * (0.5 - _size/2), _size, _size*4/3]; + _ctrl ctrlCommit 0; +}; + + +END_COUNTER(draw); diff --git a/addons/xm157/functions/fnc_weaponInfo_drawMenu.sqf b/addons/xm157/functions/fnc_weaponInfo_drawMenu.sqf new file mode 100644 index 0000000000..ca72adf807 --- /dev/null +++ b/addons/xm157/functions/fnc_weaponInfo_drawMenu.sqf @@ -0,0 +1,81 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Updates the menu display + * + * Arguments: + * 0: Display + * 1: Menu Item Needs Updating + * + * Return Value: + * None + * + * Example: + * [display, true] call ace_xm157_fnc_weaponInfo_drawMenu + * + * Public: No + */ + +params ["_display", "_needsUpdate"]; + +if (isNil QGVAR(menu)) then { + private _arrayUp = { + params ["", "_var", "_thing"]; + private _value = GVAR(data) getOrDefault [_var, 0]; + _value = (_value + 1 + count _thing) % count _thing; + GVAR(data) set [_var, _value]; + }; + private _arrayDown = { + params ["", "_var", "_thing"]; + private _value = GVAR(data) getOrDefault [_var, 0]; + _value = (_value - 1 + count _thing) % count _thing; + GVAR(data) set [_var, _value]; + }; + private _rangeUp = { + private _range = GVAR(data) getOrDefault ["range", -1]; + if (_range < 0) then { _range = 0; }; + _range = RANGEFINDER_MAX min (100 + 100 * floor (_range/100)); + GVAR(data) set ["range", _range]; + }; + private _rangeDown = { + private _range = GVAR(data) getOrDefault ["range", -1]; + if (_range < 0) then { _range = 0; }; + _range = 0 max (-100 + 100 * ceil (_range/100)); + GVAR(data) set ["range", _range]; + }; + private _atmosphereInfo = { + private _altitude = (getPosASL ace_player) select 2; + private _relativeHumidity = EGVAR(weather,currentHumidity); + private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); + private _barometricPressure = _altitude call EFUNC(weather,calculateBarometricPressure); // hPA + format ["%1%2 %3%4 %5hPA", _temperature toFixed 1, "°C", _relativeHumidity toFixed 1, "%", _barometricPressure toFixed 0] + }; + GVAR(menu) = [ + ["", "", [""], _rangeUp, _rangeDown], + ["Wind Speed (m/s)", "wind_speed", ["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"], _arrayUp, _arrayDown], + ["Wind Direction", "wind_dir", ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"], _arrayUp, _arrayDown], + // ["CQB Reticle", "reticle_cqb", ["2 MOA Red Dot", "4 MOA Red Dot", "Off"], _arrayUp, _arrayDown], + ["Bearing Display", "bearing_show", ["Degrees", "Mils", "Off"], _arrayUp, _arrayDown], + ["Atmosphere", "", _atmosphereInfo, {}, {}] + ]; +}; + + +private _index = GVAR(data) getOrDefault ["menu_index", 0]; +(GVAR(menu) # _index) params ["_title", "_var", "_thing"]; +if ((!_needsUpdate) && {_thing isEqualType []}) exitWith {}; + +private _ctrlMenuText = _display displayCtrl IDC_SCREEN_MENU_TEXT; +private _text = ""; +if (_index != 0) then { + if (_thing isEqualType []) then { + GVAR(data) set ["menu_updated", false]; + private _value = GVAR(data) getOrDefault [_var, 0]; + _text = _title + "\n" + "<" + (_thing param [_value, "#BadIndex"]) + ">"; + } else { + _text = _title + "\n" + ([_var] call _thing); + }; +}; +_ctrlMenuText ctrlSetText _text; + +GVAR(data) set ["menu_updated", false]; diff --git a/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf b/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf new file mode 100644 index 0000000000..dfefca30d4 --- /dev/null +++ b/addons/xm157/functions/fnc_weaponInfo_onLoad.sqf @@ -0,0 +1,83 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Creates UI + * + * Arguments: + * 0: Display + * + * Return Value: + * None + * + * Example: + * [display] call ace_xm157_fnc_weaponInfo_onLoad + * + * Public: No + */ + +params ["_display"]; +TRACE_1("weaponInfo_onLoad",_display); + +uinamespace setVariable [QGVAR(display), _display]; +[_display, true] call cba_optics_fnc_loadScriptedOptic; // pass thru to cba + + +// Setup the scope object +private _ctrlScopeObject = _display displayCtrl IDC_SCOPE_OBJECT; +private _scale = 1 / (getResolution # 5); // keep object the same size for any interface size +private _distance = 2.0 * 4/3; +if ((getResolution # 4) < (4/3)) then { _distance = _distance * (getResolution # 7); }; // eg 5x4 +private _base = ["3d", [0,0,_distance], _scale] call EFUNC(common,rscObjectHelper); +_ctrlScopeObject ctrlSetPosition _base; +_ctrlScopeObject ctrlSetModelScale _scale; +_ctrlScopeObject ctrlSetModelDirAndUp [[0,1,0],[0,0,1]]; +_ctrlScopeObject ctrlShow true; + +private _ctrlScopeGroup = _display displayCtrl IDC_SCOPE_GROUP; +// Add reticle +private _ctrlScopeReticle = _display ctrlCreate ["RscPicture", IDC_SCOPE_RETICLE, _ctrlScopeGroup]; +_ctrlScopeReticle ctrlSetPosition [0, 0, 1, 4/3]; +_ctrlScopeReticle ctrlCommit 0; + + +// Setup the screen object +private _ctrlScreenObject = _display displayCtrl IDC_SCREEN_OBJECT; +private _scale = 1 / (getResolution # 5); // keep object the same size for any interface size +private _distance = 4/3; +if ((getResolution # 4) < (4/3)) then { _distance = _distance * (getResolution # 7); }; // eg 5x4 +private _base = ["3d", [0,0,_distance], _scale] call EFUNC(common,rscObjectHelper); +_ctrlScreenObject ctrlSetPosition _base; +_ctrlScreenObject ctrlSetModelScale _scale; +_ctrlScreenObject ctrlSetModelDirAndUp [[0,1,0],[0,0,1]]; +_ctrlScreenObject ctrlShow true; + +private _ctrlScreenGroup = _display displayCtrl IDC_SCREEN_GROUP; +// Info display +private _ctrl = _display ctrlCreate [QGVAR(text), IDC_SCREEN_TEXT_UPPER_LEFT, _ctrlScreenGroup]; +_ctrl ctrlSetPosition [0.3, 0.2, 0.25, 0.25]; +_ctrl ctrlCommit 0; +private _ctrl = _display ctrlCreate [QGVAR(text), IDC_SCREEN_TEXT_UPPER_RIGHT, _ctrlScreenGroup]; +_ctrl ctrlSetPosition [0.7, 0.2, 0.25, 0.25]; +_ctrl ctrlCommit 0; +// Menu +private _ctrlMenuText = _display ctrlCreate [QGVAR(textMenu), IDC_SCREEN_MENU_TEXT, _ctrlScreenGroup]; +_ctrlMenuText ctrlSetPosition [0.1, 0.45, 0.8, 0.7]; +_ctrlMenuText ctrlCommit 0; + + +// Add screen reticle +private _ctrl = _display ctrlCreate ["RscPicture", IDC_SCREEN_RETICLE, _ctrlScreenGroup]; + + +// Add dummy idcs for dist/angle from engine +// 151=Dist, 156=Heading, 182=Pitch, +private _ctrl = _display ctrlCreate ["RscText", 151]; // IDC_IGUI_WEAPON_DISTANCE +_ctrl ctrlSetPosition [-1, -1, 0, 0]; +_ctrl ctrlCommit 0; +private _ctrl = _display displayCtrl 168; // hide ca_zeroing (from cba) +_ctrl ctrlShow false; + + +GVAR(shown) = true; +GVAR(data) set ["menu_updated", true]; +addMissionEventHandler ["Draw3D", LINKFUNC(weaponInfo_draw), [_display]]; diff --git a/addons/xm157/script_component.hpp b/addons/xm157/script_component.hpp new file mode 100644 index 0000000000..432fb05830 --- /dev/null +++ b/addons/xm157/script_component.hpp @@ -0,0 +1,24 @@ +#define COMPONENT xm157 +#define COMPONENT_BEAUTIFIED XM157 Fire Control Scope +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS +// #define ENABLE_QUICK_TESTING + +#include "\z\ace\addons\main\script_macros.hpp" + +#define RANGEFINDER_MAX 5000 + +#define IDC_SCOPE_OBJECT 7000 +#define IDC_SCOPE_GROUP 7001 +#define IDC_SCOPE_RETICLE 7201 + +#define IDC_SCREEN_OBJECT 8000 +#define IDC_SCREEN_GROUP 8001 +#define IDC_SCREEN_MENU_TEXT 8201 +#define IDC_SCREEN_TEXT_UPPER_LEFT 8202 +#define IDC_SCREEN_TEXT_UPPER_RIGHT 8203 +#define IDC_SCREEN_RETICLE 8204 + diff --git a/addons/xm157/sounds/click.wav b/addons/xm157/sounds/click.wav new file mode 100644 index 0000000000..efc08e62d1 Binary files /dev/null and b/addons/xm157/sounds/click.wav differ diff --git a/addons/xm157/stringtable.xml b/addons/xm157/stringtable.xml new file mode 100644 index 0000000000..761d11def9 --- /dev/null +++ b/addons/xm157/stringtable.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/addons/yardage450/CfgEventHandlers.hpp b/addons/yardage450/CfgEventHandlers.hpp index 2bed8a2eef..851e58197c 100644 --- a/addons/yardage450/CfgEventHandlers.hpp +++ b/addons/yardage450/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/yardage450/CfgWeapons.hpp b/addons/yardage450/CfgWeapons.hpp index 382a6d09fc..9d9bcb4ecf 100644 --- a/addons/yardage450/CfgWeapons.hpp +++ b/addons/yardage450/CfgWeapons.hpp @@ -8,12 +8,12 @@ class CfgWeapons { model = QPATHTOF(data\ace_yardage_pro_450.p3d); modelOptics = QPATHTOF(data\bushnell_optic.p3d); picture = QPATHTOF(UI\w_bushnell_ca.paa); - opticsZoomMin = 0.33333/4; - opticsZoomMax = 0.33333/4; - opticsZoomInit = 0.33333/4; + opticsZoomMin = "0.33333/4"; + opticsZoomMax = "0.33333/4"; + opticsZoomInit = "0.33333/4"; distanceZoomMin = 400; distanceZoomMax = 400; - discretefov[] = {0.33333/4}; + discretefov[] = {"0.33333/4"}; discreteInitIndex = 0; visionMode[] = {"Normal"}; class WeaponSlotsInfo { diff --git a/addons/yardage450/README.md b/addons/yardage450/README.md index 991c4f8a22..cce219eb33 100644 --- a/addons/yardage450/README.md +++ b/addons/yardage450/README.md @@ -2,10 +2,3 @@ ace_yardage450 ========== Adds the Bushnell Yardage Pro Sport 450 Laser Rangefinder. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Ruthberg](http://github.com/Ulteq) diff --git a/addons/yardage450/RscTitles.hpp b/addons/yardage450/RscTitles.hpp index 28fd7735e9..75ca73d5f3 100644 --- a/addons/yardage450/RscTitles.hpp +++ b/addons/yardage450/RscTitles.hpp @@ -24,7 +24,7 @@ class RscTitles { onUnload = "with uiNameSpace do { ACE_RscYardage450 = displayNull; };"; class Controls { - class ACE_Yardage450_RscTarget : ACE_Yardage450_RscText { + class ACE_Yardage450_RscTarget: ACE_Yardage450_RscText { idc = 720041; style = ST_CENTER; x = "0.5 - (0.18 * SafeZoneH)"; @@ -34,7 +34,7 @@ class RscTitles { sizeEx = "0.05 * SafeZoneH"; text = "TARGET ACQUIRED"; }; - class ACE_Yardage450_RscLaser : ACE_Yardage450_RscTarget { + class ACE_Yardage450_RscLaser: ACE_Yardage450_RscTarget { idc = 720042; x = "0.5 - (0.14 * SafeZoneH)"; y = "0.5 - (0.18 * SafeZoneH)"; @@ -45,7 +45,7 @@ class RscTitles { colorBackground[] = {0, 0, 0, 1}; text = "LASER"; }; - class ACE_Yardage450_RscRange : ACE_Yardage450_RscTarget { + class ACE_Yardage450_RscRange: ACE_Yardage450_RscTarget { idc = 720043; style = ST_RIGHT; x = "0.5 - (0.02 * SafeZoneH)"; @@ -55,7 +55,7 @@ class RscTitles { sizeEx = "0.06 * SafeZoneH"; text = "---"; }; - class ACE_Yardage450_RscMeters : ACE_Yardage450_RscLaser { + class ACE_Yardage450_RscMeters: ACE_Yardage450_RscLaser { idc = 720044; x = "0.5 + (0.06 * SafeZoneH)"; y = "0.5 + (0.19 * SafeZoneH)"; @@ -64,7 +64,7 @@ class RscTitles { sizeEx = "0.018 * SafeZoneH"; text = "METERS"; }; - class ACE_Yardage450_RscYards : ACE_Yardage450_RscMeters { + class ACE_Yardage450_RscYards: ACE_Yardage450_RscMeters { idc = 720045; y = "0.5 + (0.21 * SafeZoneH)"; w = "0.0417 * SafeZoneH"; diff --git a/addons/yardage450/XEH_postInit.sqf b/addons/yardage450/XEH_postInit.sqf index 2d4ef89968..1f3cb1a1cf 100644 --- a/addons/yardage450/XEH_postInit.sqf +++ b/addons/yardage450/XEH_postInit.sqf @@ -1,6 +1,8 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" GVAR(active) = false; diff --git a/addons/yardage450/functions/fnc_acquireTarget.sqf b/addons/yardage450/functions/fnc_acquireTarget.sqf index a6fb23f3f7..d5aea3a800 100644 --- a/addons/yardage450/functions/fnc_acquireTarget.sqf +++ b/addons/yardage450/functions/fnc_acquireTarget.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Fires the laser to acquire the target diff --git a/addons/yardage450/functions/fnc_turnOn.sqf b/addons/yardage450/functions/fnc_turnOn.sqf index 05ae3db398..62bb135a2c 100644 --- a/addons/yardage450/functions/fnc_turnOn.sqf +++ b/addons/yardage450/functions/fnc_turnOn.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Ruthberg * Shows the Yardage 450 screen elements @@ -15,12 +15,12 @@ * Public: No */ -#define __dsp (uiNamespace getVariable "ACE_RscYardage450") -#define __ctrlTarget (__dsp displayCtrl 720041) -#define __ctrlLaser (__dsp displayCtrl 720042) -#define __ctrlRange (__dsp displayCtrl 720043) -#define __ctrlMeters (__dsp displayCtrl 720044) -#define __ctrlYards (__dsp displayCtrl 720045) +#define DISPLAY_YARDAGE (uiNamespace getVariable "ACE_RscYardage450") +#define CTRL_TARGET (DISPLAY_YARDAGE displayCtrl 720041) +#define CTRL_LASER (DISPLAY_YARDAGE displayCtrl 720042) +#define CTRL_RANGE (DISPLAY_YARDAGE displayCtrl 720043) +#define CTRL_METERS (DISPLAY_YARDAGE displayCtrl 720044) +#define CTRL_YARDS (DISPLAY_YARDAGE displayCtrl 720045) if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {}; @@ -33,25 +33,28 @@ GVAR(active) = true; [{ if (CBA_missionTime - GVAR(powerOnTime) > 30) exitWith { GVAR(active) = false; - 74210 cutText ["", "PLAIN"]; + QUOTE(ADDON) cutText ["", "PLAIN"]; [_this select 1] call CBA_fnc_removePerFrameHandler; }; if (currentWeapon ACE_player == "ACE_Yardage450" && cameraView == "GUNNER") then { - 74210 cutRsc ["ACE_RscYardage450", "PLAIN", 1, false]; - - __ctrlLaser ctrlShow GVAR(lasing); - if (GVAR(targetAcquired)) then { - __ctrlTarget ctrlSetText "Target Acquired"; - __ctrlRange ctrlSetText GVAR(targetRangeText); - } else { - __ctrlTarget ctrlSetText ""; - __ctrlRange ctrlSetText "---"; + if (isNil {DISPLAY_YARDAGE} || {isNull DISPLAY_YARDAGE} || {ctrlIDD DISPLAY_YARDAGE != -1}) then { + TRACE_1("making display",DISPLAY_YARDAGE); + QUOTE(ADDON) cutRsc ["ACE_RscYardage450", "PLAIN", 1, false]; }; - __ctrlMeters ctrlShow !GVAR(useYards); - __ctrlYards ctrlShow GVAR(useYards); + + CTRL_LASER ctrlShow GVAR(lasing); + if (GVAR(targetAcquired)) then { + CTRL_TARGET ctrlSetText "Target Acquired"; + CTRL_RANGE ctrlSetText GVAR(targetRangeText); + } else { + CTRL_TARGET ctrlSetText ""; + CTRL_RANGE ctrlSetText "---"; + }; + CTRL_METERS ctrlShow !GVAR(useYards); + CTRL_YARDS ctrlShow GVAR(useYards); } else { - 74210 cutText ["", "PLAIN"]; + QUOTE(ADDON) cutText ["", "PLAIN"]; }; }, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/yardage450/functions/script_component.hpp b/addons/yardage450/functions/script_component.hpp deleted file mode 100644 index ed5cf1b7c7..0000000000 --- a/addons/yardage450/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\yardage450\script_component.hpp" \ No newline at end of file diff --git a/addons/yardage450/initKeybinds.inc.sqf b/addons/yardage450/initKeybinds.inc.sqf new file mode 100644 index 0000000000..210141a681 --- /dev/null +++ b/addons/yardage450/initKeybinds.inc.sqf @@ -0,0 +1,27 @@ +["ACE3 Equipment", QGVAR(DistanceKey), LLSTRING(PowerButtonKey), +{ + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !(GVAR(active)) exitWith {false}; + if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {false}; + + // Statement + if !(GVAR(powerButtonPressed)) then { + GVAR(powerButtonPressed) = true; + call FUNC(acquireTarget); + }; + true +}, +{ + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {false}; + + // Statement + GVAR(powerButtonPressed) = false; + call FUNC(turnOn); + true +}, +[19, [false, false, false]], false] call CBA_fnc_addKeybind; //R Key diff --git a/addons/yardage450/initKeybinds.sqf b/addons/yardage450/initKeybinds.sqf deleted file mode 100644 index 9ad3005d28..0000000000 --- a/addons/yardage450/initKeybinds.sqf +++ /dev/null @@ -1,28 +0,0 @@ - -["ACE3 Equipment", QGVAR(DistanceKey), localize "STR_ACE_Yardage450_PowerButtonKey", -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if !(GVAR(active)) exitWith {false}; - if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {false}; - - // Statement - if !(GVAR(powerButtonPressed)) then { - GVAR(powerButtonPressed) = true; - call FUNC(acquireTarget); - }; - true -}, -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {false}; - - // Statement - GVAR(powerButtonPressed) = false; - call FUNC(turnOn); - true -}, -[19, [false, false, false]], false] call CBA_fnc_addKeybind; //R Key diff --git a/addons/yardage450/stringtable.xml b/addons/yardage450/stringtable.xml index 6ab95aff7f..4e94b4a5d8 100644 --- a/addons/yardage450/stringtable.xml +++ b/addons/yardage450/stringtable.xml @@ -1,6 +1,6 @@ - + Yardage 450 Yardage 450 @@ -13,9 +13,10 @@ Yardage 450 Yardage 450 ヤードエイジ 450 - Yardage 450 + 야드에이지 450 Yardage 450 Yardage 450 + Yardage 450 Laser Rangefinder @@ -26,12 +27,13 @@ Medidor de Distância a laser Lézeres távolságmérő Лазерный дальномер - Distanziometro Laser + Telemetro Laser Télémètre laser レーザー測距機 레이저 거리측정기 - 雷射测距仪 + 激光测距仪 雷射測距儀 + Lazer Menzil Bulucu Yardage 450 - Power Button @@ -43,11 +45,12 @@ Yardage 450 - Főkapcsoló gomb Yardage 450 - Кнопка питания Yardage 450 - Bottone Accensione - Yardage 450 - bouton d'alimentation + Yardage 450 - Bouton d'alimentation ヤードエイジ 450 - 起動ボタン - Yardage 450 - 전원 버튼 - Yardage 450 - 电源按钮 + 야드에이지 450 - 전원 버튼 + Yardage 450—电源按钮 Yardage 450 - 電源按鈕 + Yardage 450 - Güç Tuşu diff --git a/addons/zeus/ACE_Settings.hpp b/addons/zeus/ACE_Settings.hpp index 0955fb135a..4b027d20a8 100644 --- a/addons/zeus/ACE_Settings.hpp +++ b/addons/zeus/ACE_Settings.hpp @@ -1,45 +1,20 @@ class ACE_Settings { class GVAR(zeusAscension) { - category = CSTRING(DisplayName); - displayName = CSTRING(ascension_DisplayName); - description = CSTRING(ascension_Description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(zeusBird) { - category = CSTRING(DisplayName); - displayName = CSTRING(bird_DisplayName); - description = CSTRING(bird_Description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(remoteWind) { - category = CSTRING(DisplayName); - displayName = CSTRING(remoteWind_DisplayName); - description = CSTRING(remoteWind_Description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(radioOrdnance) { - category = CSTRING(DisplayName); - displayName = CSTRING(radioOrdnance_DisplayName); - description = CSTRING(radioOrdnance_Description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(revealMines) { - category = CSTRING(DisplayName); - displayName = CSTRING(revealMines_DisplayName); - description = CSTRING(revealMines_Description); - typeName = "SCALAR"; - value = 0; - values[] = {"$STR_A3_OPTIONS_DISABLED", CSTRING(revealMines_partial), CSTRING(revealMines_full)}; + movedToSQF = 1; }; class GVAR(autoAddObjects) { - category = CSTRING(DisplayName); - typeName = "BOOL"; - value = 0; - displayName = CSTRING(AddObjectsToCurator); - description = CSTRING(AddObjectsToCurator_desc); + movedToSQF = 1; }; }; diff --git a/addons/zeus/CfgEventHandlers.hpp b/addons/zeus/CfgEventHandlers.hpp index becf395052..6c29240403 100644 --- a/addons/zeus/CfgEventHandlers.hpp +++ b/addons/zeus/CfgEventHandlers.hpp @@ -1,18 +1,18 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 1d86d5fee3..5fb4a4f61a 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -179,6 +179,11 @@ class CfgVehicles { function = QFUNC(moduleHeal); icon = QPATHTOF(ui\Icon_Module_Zeus_Heal_ca.paa); }; + class GVAR(moduleLayTrench): GVAR(moduleBase) { + category = QGVAR(Utility); + displayName = CSTRING(ModuleLayTrenchline_DisplayName); + function = QFUNC(moduleLayTrench); + }; class GVAR(moduleLoadIntoCargo): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(Utility); @@ -186,6 +191,13 @@ class CfgVehicles { function = QFUNC(moduleLoadIntoCargo); icon = "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa"; }; + class GVAR(moduleUnloadFromCargo): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleUnloadFromCargo_DisplayName); + function = QFUNC(moduleUnloadFromCargo); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa"; + }; class GVAR(moduleCargoParadrop): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); @@ -244,6 +256,12 @@ class CfgVehicles { displayName = CSTRING(ModuleSimulation_DisplayName); function = QFUNC(moduleSimulation); }; + class GVAR(moduleSpectator): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = ECSTRING(spectator,Module_DisplayName); + curatorInfoType = QGVAR(RscSpectator); + }; class GVAR(moduleSuicideBomber): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); @@ -324,6 +342,20 @@ class CfgVehicles { class ModuleArsenal_F: Module_F { function=QFUNC(bi_moduleArsenal); }; + class GVAR(moduleBurn): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Medical); + displayName = CSTRING(ModuleBurn_DisplayName); + function = QFUNC(moduleBurn); + icon = QPATHTOF(ui\Icon_Module_Zeus_Burn_ca.paa); + }; + class GVAR(moduleMedicalMenu): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Medical); + displayName = CSTRING(ModuleMedicalMenu_DisplayName); + function = QFUNC(moduleMedicalMenu); + icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa); + }; class Man; class CAManBase: Man { @@ -333,7 +365,7 @@ class CfgVehicles { condition = QUOTE(call FUNC(canCreateModule)); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; //Set GVAR(zeus) to null first to disable the action through the isNil check - statement = QUOTE(GVAR(zeus) = objNull; [ARR_2(QQGVAR(createZeus), ACE_player)] call CBA_fnc_serverEvent); + statement = QUOTE(GVAR(zeus) = objNull; [ARR_2(QQGVAR(createZeus),ACE_player)] call CBA_fnc_serverEvent); showDisabled = 1; icon = "\A3\Ui_F_Curator\Data\Logos\arma3_curator_eye_32_ca.paa"; }; diff --git a/addons/zeus/README.md b/addons/zeus/README.md index 35e7da1cdd..4846a82f80 100644 --- a/addons/zeus/README.md +++ b/addons/zeus/README.md @@ -7,10 +7,3 @@ Provides control over various aspects of Zeus: - Wind sounds - Ordnance radio messages - Mine markers - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [SilentSpike](http://github.com/SilentSpike) diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index 2d218ddb8f..69dd7b18a6 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -8,11 +8,12 @@ PREP(bi_moduleRemoteControl); PREP(canCreateModule); PREP(getModuleDestination); PREP(handleZeusUnitAssigned); -PREP(moduleAddArsenal); PREP(moduleAddAceArsenal); +PREP(moduleAddArsenal); +PREP(moduleAddOrRemoveFRIES); PREP(moduleAddSpareTrack); PREP(moduleAddSpareWheel); -PREP(moduleAddOrRemoveFRIES); +PREP(moduleBurn); PREP(moduleCaptive); PREP(moduleCargoParadrop); PREP(moduleConfigurePylons); @@ -20,17 +21,20 @@ PREP(moduleGarrison); PREP(moduleGlobalSetSkill); PREP(moduleGroupSide); PREP(moduleHeal); +PREP(moduleLayTrench); PREP(moduleLoadIntoCargo); -PREP(moduleRemoveArsenal); +PREP(moduleMedicalMenu); PREP(moduleRemoveAceArsenal); +PREP(moduleRemoveArsenal); PREP(moduleSearchNearby); PREP(moduleSetEngineer); PREP(moduleSetMedic); -PREP(moduleSetMedicalVehicle); PREP(moduleSetMedicalFacility); +PREP(moduleSetMedicalVehicle); PREP(moduleSetRepairFacility); PREP(moduleSetRepairVehicle); PREP(moduleSimulation); +PREP(moduleSpectator); PREP(moduleSuicideBomber); PREP(moduleSuppressiveFire); PREP(moduleSuppressiveFireLocal); @@ -40,6 +44,7 @@ PREP(moduleToggleFlashlight); PREP(moduleToggleNvg); PREP(moduleUnconscious); PREP(moduleUnGarrison); +PREP(moduleUnloadFromCargo); PREP(moduleZeusSettings); PREP(showMessage); PREP(ui_attributeCargo); @@ -52,6 +57,7 @@ PREP(ui_groupSide); PREP(ui_patrolArea); PREP(ui_searchArea); PREP(ui_setEngineer); +PREP(ui_spectator); PREP(ui_suicideBomber); PREP(ui_teleportPlayers); PREP(ui_toggleFlashlight); diff --git a/addons/zeus/XEH_postInit.sqf b/addons/zeus/XEH_postInit.sqf index 6de64b6d99..15b4c15f76 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -2,13 +2,6 @@ #define IDD_DISPLAY3DEN 313 -["ace_settingsInitialized",{ - // Only add an InitPost EH if setting is enabled (and apply retroactively) - if (isServer && {GVAR(autoAddObjects)}) then { - ["AllVehicles", "InitPost", FUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; - }; -}] call CBA_fnc_addEventHandler; - // Global skill module PVs values for persistence, just listen for the PV QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); @@ -18,6 +11,7 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); [QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler; [QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler; [QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(moduleSpectator), LINKFUNC(moduleSpectator)] call CBA_fnc_addEventHandler; // Editable object commands must be ran on server, this events are used in the respective module if (isServer) then { @@ -26,20 +20,32 @@ if (isServer) then { [QGVAR(addObjects), { params ["_objects", ["_curator", objNull]]; - if (!isNull _curator) exitWith {_curator addCuratorEditableObjects [_objects, true]}; + // If valid object + if (_curator isEqualType objNull && {!isNull _curator}) exitWith {_curator addCuratorEditableObjects [_objects, true]}; + + // If invalid object (= objNull) or other + if !(_curator isEqualType []) then { + _curator = allCurators; + }; { _x addCuratorEditableObjects [_objects, true]; - } forEach allCurators; + } forEach _curator; }] call CBA_fnc_addEventHandler; [QGVAR(removeObjects), { params ["_objects", ["_curator", objNull]]; - if (!isNull _curator) exitWith {_curator removeCuratorEditableObjects [_objects, true]}; + // If valid object + if (_curator isEqualType objNull && {!isNull _curator}) exitWith {_curator removeCuratorEditableObjects [_objects, true]}; + + // If invalid object (= objNull) or other + if !(_curator isEqualType []) then { + _curator = allCurators; + }; { _x removeCuratorEditableObjects [_objects, true]; - } forEach allCurators; + } forEach _curator; }] call CBA_fnc_addEventHandler; [QGVAR(createZeus), { diff --git a/addons/zeus/XEH_preInit.sqf b/addons/zeus/XEH_preInit.sqf index 909005e73e..46e95431a1 100644 --- a/addons/zeus/XEH_preInit.sqf +++ b/addons/zeus/XEH_preInit.sqf @@ -7,11 +7,18 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; if (isServer) then { - [QGVAR(zeusUnitAssigned), FUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; + [QGVAR(zeusUnitAssigned), LINKFUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; + + // Only add an InitPost EH if setting is enabled (and apply retroactively) + ["CBA_settingsInitialized", { + if (GVAR(autoAddObjects)) then { + ["AllVehicles", "InitPost", LINKFUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; + }; + }] call CBA_fnc_addEventHandler; }; GVAR(GlobalSkillAI) = [0.5,0.5,0.5,0.5,true,true]; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index 932d5e09c8..d90c906294 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -32,7 +32,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common", "ace_ai"}; author = ECSTRING(common,ACETeam); - authors[] = {"SilentSpike", "mharis001"}; + authors[] = {"kymckay", "mharis001"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; @@ -49,12 +49,14 @@ class CfgPatches { QGVAR(moduleUnconscious), QGVAR(moduleSetMedic), QGVAR(moduleSetMedicalVehicle), - QGVAR(moduleSetMedicalFacility) + QGVAR(moduleSetMedicalFacility), + QGVAR(moduleMedicalMenu) }; }; class GVAR(cargo): ADDON { units[] = { QGVAR(moduleLoadIntoCargo), + QGVAR(moduleUnloadFromCargo), QGVAR(moduleCargoParadrop) }; }; @@ -87,6 +89,21 @@ class CfgPatches { QGVAR(RemoveFullAceArsenal) }; }; + class GVAR(fire): ADDON { + units[] = { + QGVAR(moduleBurn) + }; + }; + class GVAR(trenches): ADDON { + units[] = { + QGVAR(moduleLayTrench) + }; + }; + class GVAR(spectator): ADDON { + units[] = { + QGVAR(moduleSpectator) + }; + }; }; class ACE_Curator { @@ -98,6 +115,9 @@ class ACE_Curator { GVAR(fastroping) = "ace_fastroping"; GVAR(pylons) = "ace_pylons"; GVAR(arsenal) = "ace_arsenal"; + GVAR(fire) = "ace_fire"; + GVAR(trenches) = "ace_trenches"; + GVAR(spectator) = "ace_spectator"; }; #include "CfgFactionClasses.hpp" diff --git a/addons/zeus/functions/fnc_addObjectToCurator.sqf b/addons/zeus/functions/fnc_addObjectToCurator.sqf index 975da83f93..4b87904d0f 100644 --- a/addons/zeus/functions/fnc_addObjectToCurator.sqf +++ b/addons/zeus/functions/fnc_addObjectToCurator.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Glowbal * Adds an object to curator upon spawn @@ -17,7 +17,7 @@ params ["_object"]; -if (!(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)])) exitWith {}; +if !(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)]) exitWith {}; [{ TRACE_1("Delayed addCuratorEditableObjects",_this); diff --git a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf index 65c394a67e..8dd5f26929 100644 --- a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf +++ b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Bohemia Interactive * Module function to open a full arsenal on a unit @@ -29,11 +29,11 @@ if (_activated && local _logic) then { case (isnull _unit): {_error = localize "str_a3_BIS_fnc_showCuratorFeedbackMessage_506";}; case !(alive _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorDead";}; case (isnull group _unit || !(side group _unit in [east,west,resistance,civilian])): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorBrain";}; - case (vehicle _unit != _unit || effectivecommander _unit != _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorVehicle";}; + case (!isNull objectParent _unit || effectivecommander _unit != _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorVehicle";}; }; if (_error == "") then { - if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { if (!isPlayer _unit || {player == _unit}) then { [{ diff --git a/addons/zeus/functions/fnc_bi_moduleCurator.sqf b/addons/zeus/functions/fnc_bi_moduleCurator.sqf index b74cc28781..cdc4d35b64 100644 --- a/addons/zeus/functions/fnc_bi_moduleCurator.sqf +++ b/addons/zeus/functions/fnc_bi_moduleCurator.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Bohemia Interactive * Module function for initalizing zeus @@ -23,13 +23,13 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - //--- Terminate when not created on the server - if (!isserver && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { + // Terminate when not created on the server + if (!isServer && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { [format ["%1 is trying to create curator logic ModuleCurator_F",profilename],"bis_fnc_error",false] call bis_fnc_mp; deletevehicle _logic; }; - //--- Get curator owner + // Get curator owner _ownerVar = _logic getvariable ["owner",""]; _ownerUID = parsenumber _ownerVar; if (cheatsenabled) then { @@ -46,13 +46,13 @@ if (_activated) then { }; _isAdmin = _ownerVar == "#adminLogged" || _ownerVar == "#adminVoted"; - //--- Wipe out the variable so clients can't access it + // Wipe out the variable so clients can't access it _logic setvariable ["owner",nil]; - //--- Server + // Server if (isserver) then { - //--- Prepare admin variable + // Prepare admin variable _adminVar = ""; if (_isAdmin) then { _letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]; @@ -61,27 +61,28 @@ if (_activated) then { _logic setvariable ["adminVar",_adminVar,true]; }; - //--- Get allowed addons + // Get allowed addons _addonsType = _logic getvariable ["Addons",2]; _addons = []; switch _addonsType do { - //--- All (including unofficial ones) + // All (including unofficial ones) case 3: { _cfgPatches = configfile >> "cfgpatches"; for "_i" from 0 to (count _cfgPatches - 1) do { _class = _cfgPatches select _i; if (isclass _class) then {_addons set [count _addons,configname _class];}; }; - _addons call bis_fnc_activateaddons; + // Modified by ace_zeus - bis_fnc_activateaddons will error if time > 0 so only call if at start + if (time <= 0) then { _addons call bis_fnc_activateaddons; }; removeallcuratoraddons _logic; _logic addcuratoraddons _addons; }; - //--- All active + // All active case 2: {}; - //--- All mission + // All mission case 1: { _addonsList = []; { @@ -91,13 +92,13 @@ if (_activated) then { _logic addcuratoraddons _addonsList; }; - //--- None + // None case 0: { removeallcuratoraddons _logic; }; }; - //--- Handle ownership + // Handle ownership [_logic,_ownerVar,_ownerUID,_adminVar] spawn { scriptname "BIS_fnc_moduleCurator: Owner"; @@ -109,16 +110,16 @@ if (_activated) then { _name = _logic getvariable ["name",""]; if (_name == "") then {_name = localize "STR_A3_curator";}; - //--- Wait until mission starts + // Wait until mission starts waitUntil {time > 0}; // NOTE: DO NOT CHANGE TO CBA_missionTime, IT BREAKS THE MODULE - //--- Refresh addon list, so it's broadcasted to clients + // Refresh addon list, so it's broadcasted to clients _addons = curatoraddons _logic; removeAllCuratorAddons _logic; _logic addcuratoraddons _addons; while {true} do { - //--- Wait for player to become Zeus + // Wait for player to become Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -132,7 +133,7 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Assign + // Assign _player = objnull; switch true do { case (_ownerUID > 0): { @@ -149,7 +150,7 @@ if (_activated) then { waituntil {_player assignCurator _logic; getassignedcuratorunit _logic == _player || isnull _logic}; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochanneladd [_player]; } foreach (_logic getvariable ["channels",[]]); @@ -158,7 +159,7 @@ if (_activated) then { private _msgCode = { params ["_logic","_player"]; - //--- Sent notification to all assigned players + // Sent notification to all assigned players if ((_logic getVariable ["showNotification",true]) && GVAR(zeusAscension)) then { { if (isplayer _x) then { @@ -180,7 +181,7 @@ if (_activated) then { // Added by ace_zeus [QGVAR(zeusUnitAssigned), [_logic,_player]] call CBA_fnc_globalEvent; - //--- Wait for player to stop being Zeus + // Wait for player to stop being Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -194,12 +195,12 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochannelremove [_player]; } foreach (_logic getvariable ["channels",[]]); - //--- Unassign + // Unassign waituntil {unassigncurator _logic; isnull (getassignedcuratorunit _logic) || isnull _logic}; if (isnull _logic) exitwith {}; }; @@ -210,14 +211,14 @@ if (_activated) then { params ["_logic"]; if (GVAR(zeusBird)) then { - //--- Create bird + // Create bird _birdType = _logic getVariable ["birdType","eagle_f"]; if (_birdType != "") then { _bird = createvehicle [_birdType,[100,100,100],[],0,"none"]; _logic setVariable ["bird",_bird,true]; }; - //--- Locality changed + // Locality changed _logic addeventhandler [ "local", { @@ -236,7 +237,7 @@ if (_activated) then { [_logic] call _birdCode; }; - //--- Activated all future addons + // Activated all future addons _addons = []; { if (typeof _x == "ModuleCuratorAddAddons_F") then { @@ -249,15 +250,16 @@ if (_activated) then { } foreach _paramAddons; }; } foreach (synchronizedobjects _logic); - _addons call bis_fnc_activateaddons; + // Modified by ace_zeus - bis_fnc_activateaddons will error if time > 0 so only call if at start + if (time <= 0) then { _addons call bis_fnc_activateaddons; }; }; - //--- Player + // Player if (hasinterface) then { waituntil {local player}; - _serverCommand = if (_ownerVar == "#adminLogged") then {"#shutdown"} else {"#kick"}; + _serverCommand = ["#kick", "#shutdown"] select (_ownerVar == "#adminLogged"); - //--- Black effect until the interface is open + // Black effect until the interface is open _forced = _logic getvariable ["forced",0] > 0; if (_forced) then { _isCurator = switch true do { @@ -277,15 +279,15 @@ if (_activated) then { }; }; - //--- Check if player is server admin + // Check if player is server admin if (_isAdmin) then { _adminVar = _logic getvariable ["adminVar",""]; _logic setvariable ["adminVar",nil]; if (isserver) then { - //--- Host + // Host missionnamespace setvariable [_adminVar,player]; } else { - //--- Client + // Client [_logic,_adminVar,_serverCommand] spawn { scriptname "BIS_fnc_moduleCurator: Admin check"; @@ -312,7 +314,7 @@ if (_activated) then { sleep 1; waituntil {alive player}; - //--- Show warning when Zeus key is not assigned + // Show warning when Zeus key is not assigned if (count (actionkeys "curatorInterface") == 0) then { [ format [ @@ -322,7 +324,7 @@ if (_activated) then { ] call bis_fnc_guiMessage; }; - //--- Show hint about pinging for players + // Show hint about pinging for players if ( isnil {profilenamespace getvariable "bis_fnc_curatorPinged_done"} && @@ -337,7 +339,7 @@ if (_activated) then { }; }; - //--- Add local event handlers + // Add local event handlers _logic addeventhandler ["curatorFeedbackMessage",{_this call bis_fnc_showCuratorFeedbackMessage;}]; _logic addeventhandler ["curatorPinged",{_this call bis_fnc_curatorPinged;}]; _logic addeventhandler ["curatorObjectPlaced",{_this call bis_fnc_curatorObjectPlaced;}]; diff --git a/addons/zeus/functions/fnc_bi_moduleMine.sqf b/addons/zeus/functions/fnc_bi_moduleMine.sqf index 6b8866aaa4..0bd8ba574f 100644 --- a/addons/zeus/functions/fnc_bi_moduleMine.sqf +++ b/addons/zeus/functions/fnc_bi_moduleMine.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Bohemia Interactive * Module function for spawning mines @@ -21,20 +21,20 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - _explosive = gettext (configfile >> "cfgvehicles" >> typeof _logic >> "explosive"); + _explosive = gettext (configOf _logic >> "explosive"); if (_explosive != "") then { _explosive = createvehicle [_explosive,position _logic,[],0,"none"]; _explosive attachto [_logic]; // Added by ace_zeus to control if mines are revealed - if (GVAR(revealMines) > 0) then { + if (GVAR(revealMines) > MINE_REVEAL_NONE) then { //--- Reveal the mine to curator's side { _side = (getassignedcuratorunit _x) call bis_fnc_objectSide; _side revealmine _explosive; } forEach (objectcurators _logic); - if (GVAR(revealMines) > 1) then { + if (GVAR(revealMines) == MINE_REVEAL_FULL) then { //--- Mark minefields in the map [] spawn bis_fnc_drawMinefields; }; diff --git a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf index 4439ad3517..ba30a2eaf4 100644 --- a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf +++ b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Bohemia Interactive * Module function for spawning projectiles @@ -31,7 +31,7 @@ if ({local _x} count (objectcurators _logic) > 0) then { if !(isserver) exitwith {}; if (_activated) then { - _ammo = _logic getvariable ["type",gettext (configfile >> "cfgvehicles" >> typeof _logic >> "ammo")]; + _ammo = _logic getvariable ["type",gettext (configOf _logic >> "ammo")]; if (_ammo != "") then { _cfgAmmo = configfile >> "cfgammo" >> _ammo; //if !(isclass _cfgAmmo) exitwith {["CfgAmmo class '%1' not found.",_ammo] call bis_fnc_error;}; @@ -42,7 +42,7 @@ if (_activated) then { _posAmmo = +_pos; _posAmmo set [2,0]; _dir = direction _logic; - _simulation = tolower gettext (configfile >> "cfgammo" >> _ammo >> "simulation"); + _simulation = toLowerANSI gettext (configfile >> "cfgammo" >> _ammo >> "simulation"); _altitude = 0; _velocity = []; _attach = false; @@ -90,10 +90,9 @@ if (_activated) then { }; _fnc_playRadio = { if (_radio != "") then { - _entities = (getposatl _logic) nearentities ["All",100]; _sides = []; { - if (isplayer _x) then { + if (_x distance2D _logic < 100) then { _side = side group _x; if (_side in [east,west,resistance,civilian]) then { //--- Play radio (only if it wasn't played recently) @@ -103,14 +102,14 @@ if (_activated) then { }; }; }; - } foreach _entities; + } foreach allPlayers; }; }; if (count _hint > 0 && {count objectcurators _logic > 0}) then { [[_hint,nil,nil,nil,nil,nil,nil,true],"bis_fnc_advHint",objectcurators _logic] call bis_fnc_mp; }; if (count _velocity == 3) then { - _altitude = (_logic getvariable ["altitude",_altitude]) call bis_fnc_parsenumber; + _altitude = (_logic getvariable ["altitude",_altitude]) call BIS_fnc_parseNumberSafe; _radio = _logic getvariable ["radio",_radio]; //--- Create projectile diff --git a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf index b35c8a508c..2aa438be53 100644 --- a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf +++ b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Bohemia Interactive * Module function for remote controlling units as zeus @@ -30,7 +30,7 @@ if (_activated && local _logic && !isnull curatorcamera) then { //--- Get unit under cursor _unit = objnull; _mouseOver = missionnamespace getvariable ["bis_fnc_curatorObjectPlaced_mouseOver",[""]]; - if ((_mouseOver select 0) == typename objnull) then {_unit = _mouseOver select 1;}; + if ((_mouseOver select 0) == "OBJECT") then {_unit = _mouseOver select 1;}; _unit = effectivecommander _unit; //--- Temp owner diff --git a/addons/zeus/functions/fnc_canCreateModule.sqf b/addons/zeus/functions/fnc_canCreateModule.sqf index df6cb99400..b70e8afa50 100644 --- a/addons/zeus/functions/fnc_canCreateModule.sqf +++ b/addons/zeus/functions/fnc_canCreateModule.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Dystopian * Check whether local player is currently allowed to create a Zeus Module @@ -15,6 +15,9 @@ * Public: No */ +// Don't allow if we already are a zeus, intentionally using player instead of ace_player + if (!isNull getAssignedCuratorLogic player) exitWith { false }; + (isNil QGVAR(zeus)) && { switch (GVAR(canCreateZeus)) do { case CAN_CREATE_ADMIN: {isServer || {IS_ADMIN_LOGGED}}; diff --git a/addons/zeus/functions/fnc_getModuleDestination.sqf b/addons/zeus/functions/fnc_getModuleDestination.sqf index 2066d5887e..10d7acae9e 100644 --- a/addons/zeus/functions/fnc_getModuleDestination.sqf +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -1,22 +1,24 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Allows zeus to click to indicate a 3d position. * * Arguments: * 0: The souce object - * 1: Code to run when position is ready - * - Code is passed - * 0: Successful - * 1: Object - * 2: Position ASL - * 3: State of Shift - * 4: State of Ctrl - * 5: State of Alt + * 1: Code to run when position is ready (will be passed the following array) + * - 0: Successful + * - 1: Object + * - 2: Mouse Pos ASL + * - 3: State of Shift + * - 4: State of Ctrl + * - 5: State of Alt * 2: Text (default: "") * 3: Icon image file (default: "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa") * 4: Icon color (default: [1,0,0,1]) * 5: Icon Angle (default: 0) + * 6: Draw Code (default: {}) + * - 0: Object + * - 1: Mouse Pos ASL * * Return Value: * None @@ -27,7 +29,7 @@ * Public: No */ -params ["_object", "_code", ["_text", ""], ["_icon", "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa"], ["_color", [1,0,0,1]], ["_angle", 0]]; +params ["_object", "_code", ["_text", ""], ["_icon", "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa"], ["_color", [1,0,0,1]], ["_angle", 0], ["_drawCode", {}]]; if (missionNamespace getVariable [QGVAR(moduleDestination_running), false]) exitWith { [false, _object, [0,0,0], false, false, false] call _code; @@ -96,7 +98,7 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", // Add draw EH for 3D camera view - draws the 3D icon and line [{ - (_this select 0) params ["_object", "_code", "_text", "_icon", "_color", "_angle"]; + (_this select 0) params ["_object", "_code", "_text", "_icon", "_color", "_angle", "_drawCode"]; if ((isNull _object) || {isNull findDisplay 312} || {!isNull findDisplay 49}) then { TRACE_3("null-exit",isNull _object,isNull findDisplay 312,isNull findDisplay 49); GVAR(moduleDestination_running) = false; @@ -105,16 +107,17 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", if (GVAR(moduleDestination_running)) then { // Draw the 3d icon and line private _mousePosAGL = screenToWorld getMousePosition; + [_object, AGLToASL _mousePosAGL] call _drawCode; drawIcon3D [_icon, _color, _mousePosAGL, 1.5, 1.5, _angle, _text]; drawLine3D [_mousePosAGL, ASLtoAGL (getPosASL _object), _color];; } else { TRACE_4("cleaning up",_this select 1,GVAR(moduleDestination_displayEHMouse),GVAR(moduleDestination_displayEHKeyboard),GVAR(moduleDestination_mapDrawEH)); (_this select 1) call CBA_fnc_removePerFrameHandler; - (findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; + (findDisplay 312) displayRemoveEventHandler ["MouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; (findDisplay 312) displayRemoveEventHandler ["KeyDown", GVAR(moduleDestination_displayEHKeyboard)]; - ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)]; + ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["Draw", GVAR(moduleDestination_mapDrawEH)]; GVAR(moduleDestination_displayEHMouse) = nil; GVAR(moduleDestination_displayEHKeyboard) = nil; GVAR(moduleDestination_mapDrawEH) = nil; }; -}, 0, [_object, _code, _text, _icon, _color, _angle]] call CBA_fnc_addPerFrameHandler; +}, 0, [_object, _code, _text, _icon, _color, _angle, _drawCode]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf b/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf index 05bf5fdfb3..935ce1e2e0 100644 --- a/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf +++ b/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Contextually removes addons (given in ACE_Curator) from zeus based on their required addon(s) * * ACE_Curator format: @@ -30,14 +30,14 @@ private _removeAddons = []; private _addon = _x; if (isArray _addon) then { { - if !(isClass (configFile >> "CfgPatches" >> _x)) exitWith { + if !([_x] call EFUNC(common,isModLoaded)) exitWith { _removeAddons pushBack (configName _addon); }; } forEach (getArray _addon); }; if (isText _addon) then { - if !(isClass (configFile >> "CfgPatches" >> getText _addon)) then { + if !([getText _addon] call EFUNC(common,isModLoaded)) then { _removeAddons pushBack (configName _addon); }; }; diff --git a/addons/zeus/functions/fnc_moduleAddAceArsenal.sqf b/addons/zeus/functions/fnc_moduleAddAceArsenal.sqf index 5bdb2803f9..8158e9090f 100644 --- a/addons/zeus/functions/fnc_moduleAddAceArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleAddAceArsenal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Add a full ACE Arsenal to an object diff --git a/addons/zeus/functions/fnc_moduleAddArsenal.sqf b/addons/zeus/functions/fnc_moduleAddArsenal.sqf index d284b9bb08..6a3d811e66 100644 --- a/addons/zeus/functions/fnc_moduleAddArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleAddArsenal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Add a full arsenal to an object diff --git a/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf b/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf index 967edc9396..d3534cff25 100644 --- a/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf +++ b/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Add/Removes FRIES from a helicopter. @@ -32,7 +32,7 @@ if !(["ace_fastroping"] call EFUNC(common,isModLoaded)) then { if !(alive _mouseOverUnit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - private _config = configFile >> "CfgVehicles" >> typeOf _mouseOverUnit; + private _config = configOf _mouseOverUnit; private _displayName = getText (_config >> "displayName"); if !(isNumber (_config >> QEGVAR(fastroping,enabled))) then { [LSTRING(NotFastRopeCompatible), _displayName] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf index 580d691996..2e4efca6e0 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Adds a Spare Track to the vehicle. @@ -32,10 +32,10 @@ if !(["ace_cargo"] call EFUNC(common,isModLoaded) && ["ace_repair"] call EFUNC(c if !(alive _mouseOverUnit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - if (getNumber (configFile >> "CfgVehicles" >> "ACE_Track" >> QEGVAR(cargo,size)) > [_mouseOverUnit] call EFUNC(cargo,getCargoSpaceLeft)) then { + if ("ACE_Track" call EFUNC(cargo,getSizeItem) > _mouseOverUnit call EFUNC(cargo,getCargoSpaceLeft)) then { [LSTRING(OnlyEnoughCargoSpace)] call FUNC(showMessage); } else { - ["ace_addCargo", ["ACE_Track", _mouseOverUnit, 1, true]] call CBA_fnc_localEvent; + ["ace_addCargo", ["ACE_Track", _mouseOverUnit, 1]] call CBA_fnc_localEvent; }; }; }; diff --git a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf index b08af3ed9d..d913300709 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jonpas * Adds a Spare Wheel to the vehicle. @@ -32,10 +32,10 @@ if !(["ace_cargo"] call EFUNC(common,isModLoaded) && ["ace_repair"] call EFUNC(c if !(alive _mouseOverUnit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - if (getNumber (configFile >> "CfgVehicles" >> "ACE_Wheel" >> QEGVAR(cargo,size)) > [_mouseOverUnit] call EFUNC(cargo,getCargoSpaceLeft)) then { + if ("ACE_Wheel" call EFUNC(cargo,getSizeItem) > _mouseOverUnit call EFUNC(cargo,getCargoSpaceLeft)) then { [LSTRING(OnlyEnoughCargoSpace)] call FUNC(showMessage); } else { - ["ace_addCargo", ["ACE_Wheel", _mouseOverUnit, 1, true]] call CBA_fnc_localEvent; + ["ace_addCargo", ["ACE_Wheel", _mouseOverUnit, 1]] call CBA_fnc_localEvent; }; }; }; diff --git a/addons/zeus/functions/fnc_moduleBurn.sqf b/addons/zeus/functions/fnc_moduleBurn.sqf new file mode 100644 index 0000000000..9fb3b085af --- /dev/null +++ b/addons/zeus/functions/fnc_moduleBurn.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: BaerMitUmlaut + * Inflames a unit. + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleBurn + * + * Public: No + */ + +params ["_logic"]; + +if (!local _logic) exitWith {}; + +private _unit = attachedTo _logic; +deleteVehicle _logic; + +switch (false) do { + case (!isNull _unit): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (_unit isKindOf "CAManBase" && {getNumber (configOf _unit >> "isPlayableLogic") == 0}): { + [LSTRING(OnlyInfantry)] call FUNC(showMessage); + }; + case (["ace_fire"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call FUNC(showMessage); + }; + default { + [QEGVAR(fire,burn), [_unit, 5], _unit] call CBA_fnc_targetEvent; + }; +}; diff --git a/addons/zeus/functions/fnc_moduleCaptive.sqf b/addons/zeus/functions/fnc_moduleCaptive.sqf index 6420559a3f..ad359575e9 100644 --- a/addons/zeus/functions/fnc_moduleCaptive.sqf +++ b/addons/zeus/functions/fnc_moduleCaptive.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Flips the capture state of the unit the module is placed on. * * Arguments: diff --git a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf index 948a54a7a9..2aaffb3796 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Commands the selected vehicle to paradrop all cargo at the specified location @@ -30,13 +30,13 @@ TRACE_4("moduleCargoParadrop placed",_logic,typeOf _vehicle,_pilot,typeOf _pilot deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached vehicle -if (!(missionNamespace getVariable [QEGVAR(cargo,enable), false])) exitWith { +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; if (isNull _vehicle) exitWith { [LSTRING(NothingSelected)] call FUNC(showMessage); }; -if (!(_vehicle isKindOf "Air")) exitWith { +if !(_vehicle isKindOf "Air") exitWith { [format ["%1 %2", localize "str_dn_aircraft", localize "str_msg_no_veh_select"]] call FUNC(showMessage); }; if ((!alive _vehicle) || {!alive _pilot}) exitWith { diff --git a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf index 1b4e00960c..6570648499 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Handles the paradrop cargo scripted waypoint (Scheduled Environment) @@ -22,7 +22,7 @@ TRACE_2("moduleCargoParadropWaypoint",_vehicleGroup,_wpPos); private _vehicle = vehicle leader _vehicleGroup; private _commander = driver _vehicle; private _cargo = _vehicle getVariable [QEGVAR(cargo,loaded), []]; -if (!(_vehicle isKindOf "Air")) exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; +if !(_vehicle isKindOf "Air") exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; if (_cargo isEqualTo []) exitWith {WARNING_1("no cargo",_cargo); true}; private _previousSpeedMode = speedMode _vehicleGroup; @@ -48,7 +48,7 @@ waitUntil { }; TRACE_2("Finished primary movement",_vehicle distance2D _wpPos,_closeEnoughTicks); -if ((!alive _vehicle) || {!alive _commander}) exitWith {TRACE_2("died",alive _vehicle, alive _commander); true}; +if ((!alive _vehicle) || {!alive _commander}) exitWith {TRACE_2("died",alive _vehicle,alive _commander); true}; if (((getPos _vehicle) select 2) < 25) exitWith {TRACE_1("too low",getPos _vehicle); true}; // Fly level and straight diff --git a/addons/zeus/functions/fnc_moduleConfigurePylons.sqf b/addons/zeus/functions/fnc_moduleConfigurePylons.sqf index 6371183192..05cfcd0521 100644 --- a/addons/zeus/functions/fnc_moduleConfigurePylons.sqf +++ b/addons/zeus/functions/fnc_moduleConfigurePylons.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Opens the pylon configuration menu for the aircraft module is placed on. diff --git a/addons/zeus/functions/fnc_moduleGarrison.sqf b/addons/zeus/functions/fnc_moduleGarrison.sqf index ae0dd4292e..dcebd5f1fb 100644 --- a/addons/zeus/functions/fnc_moduleGarrison.sqf +++ b/addons/zeus/functions/fnc_moduleGarrison.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Module calling the garrison function. @@ -51,7 +51,7 @@ switch (false) do { private _units = units _unit; // Make sure all units are disembarked { - if (vehicle _x != _x) then { + if (vehicle _x != _x && {!isPlayer _x}) then { moveOut _x; }; } forEach _units; diff --git a/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf b/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf index 4659fba2d5..3e359c6c69 100644 --- a/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf +++ b/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * PV event handler to update the AI skill on all machines when set by zeus module * * Arguments: diff --git a/addons/zeus/functions/fnc_moduleGroupSide.sqf b/addons/zeus/functions/fnc_moduleGroupSide.sqf index 087838ed30..16f64aa665 100644 --- a/addons/zeus/functions/fnc_moduleGroupSide.sqf +++ b/addons/zeus/functions/fnc_moduleGroupSide.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike, Brett + * Author: kymckay, Brett * Zeus module function to change side of a group on dialog confirmation * * Arguments: @@ -44,11 +44,19 @@ if (GETVAR(_unit,ACE_isUnconscious,false) && {GETMVAR(EGVAR(medical,moveUnitsFro _unit setVariable [QEGVAR(common,previousGroupSwitchTo), _previousGroupsList, true]; } else { + private _units = units _unit; + // Preserve assignedTeam for each unit - { + // Teams need to be gotten before removing units from group + private _teams = _units apply { private _team = assignedTeam _x; + [_team, "MAIN"] select (_team == "") + }; + + { [_x] joinSilent _newGroup; - _x assignTeam _team; - } forEach units _unit; + _x assignTeam (_teams select _forEachIndex); + } forEach _units; + deleteGroup _oldGroup; }; diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 627c48ef36..4bf0525ea7 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Full heal unit. @@ -43,7 +43,7 @@ switch (false) do { }; // Heal validated target -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +if (GETEGVAR(medical,enabled,false)) then { TRACE_1("healing with ace_medical",_unit); [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { diff --git a/addons/zeus/functions/fnc_moduleLayTrench.sqf b/addons/zeus/functions/fnc_moduleLayTrench.sqf new file mode 100644 index 0000000000..fe4e29b62c --- /dev/null +++ b/addons/zeus/functions/fnc_moduleLayTrench.sqf @@ -0,0 +1,60 @@ +#include "..\script_component.hpp" +/* + * PabstMirror + * Dig trenchline + * + * Arguments: + * 0: Module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [], true] call ace_zeus_fnc_moduleLayTrench + * + * Public: No + */ +if (canSuspend) exitWith {[FUNC(moduleLayTrench), _this] call CBA_fnc_directCall;}; + +params ["_logic", "_units", "_activated"]; +if !(_activated && {local _logic}) exitWith {}; +TRACE_1("",_logic); + +if !(["ace_trenches"] call EFUNC(common,isModLoaded)) exitWith { + deleteVehicle _logic; + [LSTRING(RequiresAddon)] call FUNC(showMessage); +}; + +if (_logic getVariable [QGVAR(ran), false]) exitWith {}; +_logic setVariable [QGVAR(ran), true]; + +private _drawCode = { + params ["_object", "_mousePos"]; + private _startPos = getPos _object; + ([_startPos, _mousePos, false, false, true] call EFUNC(trenches,blockTrench_place)) params ["_valid", "_reason", "_extra"]; + if (_valid) then { + { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [0,0,1,1], (_x select [0,2]) + [0], 1.5, 1.5, 0, ""]; + } forEach _extra; + } else { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,1,1], (_startPos select [0,2]) + [0], 1.5, 1.5, 0, ""]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,1,1], (_mousePos select [0,2]) + [0], 1.5, 1.5, 0, ""]; + }; +}; + +private _text = format ["%1 %2", LELSTRING(trenches,ConfirmDig), LLSTRING(ModuleLayTrenchline_Tooltip)]; +[_logic, { + params ["_successful", "_logic", "_mousePosASL", "_shift"]; + TRACE_4("getModuleDestination",_successful,_logic,_mousePosASL,_shift); + + if (isNull _logic) exitWith { WARNING("logic missing"); }; + private _startPosASL = getPosASL _logic; + deleteVehicle _logic; + if (!_successful) exitWith { TRACE_1("exit",_successful); }; + + private _args = [_startPosASL, _mousePosASL, _shift]; + TRACE_1("sending event",_args); + [QEGVAR(trenches,layTrenchline), [ace_player, _args]] call CBA_fnc_serverEvent; +}, _text, "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [0, 1, 0, 1], 45, _drawCode] call FUNC(getModuleDestination); diff --git a/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf b/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf index 7411c8ee9f..6ab7473f91 100644 --- a/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf +++ b/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Loads the object module is placed on into selected vehicle. @@ -56,6 +56,7 @@ if (!alive _cargo) exitWith { private _loadedItem = [localize ELSTRING(cargo,LoadedItem), "
", " "] call CBA_fnc_replace; private _holderDisplayName = [_holder] call EFUNC(common,getName); [_loadedItem, _displayName, _holderDisplayName] call FUNC(showMessage); + ["ace_cargoLoaded", [_cargo, _holder]] call CBA_fnc_globalEvent; } else { private _loadingFailed = [localize ELSTRING(cargo,LoadingFailed), "
", " "] call CBA_fnc_replace; [_loadingFailed, _displayName] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleMedicalMenu.sqf b/addons/zeus/functions/fnc_moduleMedicalMenu.sqf new file mode 100644 index 0000000000..a69a65fb74 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleMedicalMenu.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Opens the medical menu for the unit + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleMedicalMenu + * + * Public: No + */ + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _unit = attachedTo _logic; +deleteVehicle _logic; + +switch (false) do { + case !(isNull _unit): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call FUNC(showMessage); + }; + case (["ace_medical_gui"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call FUNC(showMessage); + }; + case ([objNull, _unit] call EFUNC(medical_gui,canOpenMenu)): { + [LSTRING(MedicalMenuDisabled)] call FUNC(showMessage); + }; + default { + [_unit] call EFUNC(medical_gui,openMenu); + }; +}; diff --git a/addons/zeus/functions/fnc_moduleRemoveAceArsenal.sqf b/addons/zeus/functions/fnc_moduleRemoveAceArsenal.sqf index bc6ba69d87..d34e974868 100644 --- a/addons/zeus/functions/fnc_moduleRemoveAceArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleRemoveAceArsenal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Remove ACE Arsenal from an object diff --git a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf index ec203572e4..6d2a94139b 100644 --- a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Remove arsenal from an object @@ -30,7 +30,7 @@ switch (true) do { }; default { - TRACE_1("Calling removeVirtualXXXCargo functions", _object); + TRACE_1("Calling removeVirtualXXXCargo functions",_object); [_object, (_object call BIS_fnc_getVirtualItemCargo), true] call BIS_fnc_removeVirtualItemCargo; [_object, (_object call BIS_fnc_getVirtualWeaponCargo), true] call BIS_fnc_removeVirtualWeaponCargo; [_object, (_object call BIS_fnc_getVirtualMagazineCargo), true] call BIS_fnc_removeVirtualMagazineCargo; diff --git a/addons/zeus/functions/fnc_moduleSearchNearby.sqf b/addons/zeus/functions/fnc_moduleSearchNearby.sqf index 9515ab3fdc..46338b5e90 100644 --- a/addons/zeus/functions/fnc_moduleSearchNearby.sqf +++ b/addons/zeus/functions/fnc_moduleSearchNearby.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Commands the group the module is placed on to search the nearest building * * Arguments: diff --git a/addons/zeus/functions/fnc_moduleSetEngineer.sqf b/addons/zeus/functions/fnc_moduleSetEngineer.sqf index 8280d75e65..372c56974b 100644 --- a/addons/zeus/functions/fnc_moduleSetEngineer.sqf +++ b/addons/zeus/functions/fnc_moduleSetEngineer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Zeus module function to set unit engineer skill. diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index 63b962d429..d44dd56e59 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike, Glowbal + * Author: kymckay, Glowbal * Assigns a medic role from the medical module to a unit * * Arguments: @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf index ec8106d9ff..b6742a25a4 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike, Glowbal + * Author: kymckay, Glowbal * Assigns a medic role from the medical module to a unit * * Arguments: @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); @@ -40,7 +40,7 @@ if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - if (!(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false))) then { + if !(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false)) then { _unit setVariable [QEGVAR(medical,isMedicalFacility), true, true]; }; }; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index fa3ced078c..26bb3fcfe9 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike, Glowbal + * Author: kymckay, Glowbal * Assigns a medic role from the medical module to a unit * * Arguments: @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSetRepairFacility.sqf b/addons/zeus/functions/fnc_moduleSetRepairFacility.sqf index e8d5fa84a3..42c91acc5b 100644 --- a/addons/zeus/functions/fnc_moduleSetRepairFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetRepairFacility.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Assigns object as repair facility. diff --git a/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf b/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf index 79c89dfa88..b1b3427f33 100644 --- a/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Assigns object as repair vehicle. diff --git a/addons/zeus/functions/fnc_moduleSimulation.sqf b/addons/zeus/functions/fnc_moduleSimulation.sqf index 69d7abe36c..055088b6dd 100644 --- a/addons/zeus/functions/fnc_moduleSimulation.sqf +++ b/addons/zeus/functions/fnc_moduleSimulation.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Fisher, SilentSpike + * Author: Fisher, kymckay * Toggle Simulation on object. * * Arguments: diff --git a/addons/zeus/functions/fnc_moduleSpectator.sqf b/addons/zeus/functions/fnc_moduleSpectator.sqf new file mode 100644 index 0000000000..fb9ca2a63b --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSpectator.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Zeus module function to make the local player an ACE Spectator. + * + * Arguments: + * 0: Force interface + * 1: Hide player + * 2: Sides available to spectate + * 3: Camera modes available + * 4: Vision modes available + * + * Return Value: + * None + * + * Example: + * [true, true, [west], [0, 1, 2], [-2, -1, 0, 1]] call ace_zeus_fnc_moduleSpectator + * + * Public: No + */ + +params ["_force", "_hide", "_sides", "_modes", "_visions"]; +TRACE_1("params",_this); + +// Update sides available to spectate +[_sides, [west, east, independent, civilian] - _sides] call EFUNC(spectator,updateSides); + +// Update available camera modes +[_modes, [0, 1, 2] - _modes] call EFUNC(spectator,updateCameraModes); + +// Update available vision modes +[_visions, [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] - _visions] call EFUNC(spectator,updateVisionModes); + +// Make unit spectator (close Zeus camera if open) +if (!isNull curatorCamera) then { + (findDisplay 312) closeDisplay 2; +}; + +[true, _force, _hide] call EFUNC(spectator,setSpectator); diff --git a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf index c659ca7a9a..8425ff1548 100644 --- a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf +++ b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Zeus module function to make unit a suicide bomber. @@ -57,11 +57,11 @@ if (_autoSeek) then { LOG("Unit deleted or killed, PFH removed"); }; - if (!([_unit] call EFUNC(common,isAwake))) exitWith {}; + if !([_unit] call EFUNC(common,isAwake)) exitWith {}; // Detonation private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}}; - if !(_nearObjects isEqualTo []) then { + if (_nearObjects isNotEqualTo []) then { createVehicle [EXPLOSIVES select _explosionSize, _unit, [], 0, "CAN_COLLIDE"]; [_pfhID] call CBA_fnc_removePerFrameHandler; LOG("Explosion created, PFH removed"); @@ -77,7 +77,7 @@ if (_autoSeek) then { private _nearestObjects = nearestObjects [_unit, [], _range] select {side _x == _activationSide && {_x != _unit} && {alive _x}}; #ifdef DEBUG_MODE_FULL - if !(isNil "_lastMove") then { + if (!isNil "_lastMove") then { drawLine3D [_unit modelToWorldVisual [0, 0, 1], _lastMove, [1, 0, 0, 1]]; }; for "_i" from 0 to 35 do { diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf index 1900e5a7a3..a624b7dded 100644 --- a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf +++ b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux, PabstMirror * Commands the selected unit or group to start suppressive fire on the unit, group or location the module is placed on @@ -49,7 +49,7 @@ if ([_unit] call EFUNC(common,isPlayer)) exitWith { private _targetASL = _mousePosASL vectorAdd [0,0,0.6]; // mouse pos is at ground level zero, raise up a bit; private _artilleryMag = ""; - if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "artilleryScanner")) == 1) then { + if ((getNumber (configOf _vehicle >> "artilleryScanner")) == 1) then { // Artillery - Get mortar ammo type and verify in range if (isNull gunner _vehicle) exitWith {_targetASL = [];}; { @@ -69,7 +69,7 @@ if ([_unit] call EFUNC(common,isPlayer)) exitWith { } else { // Direct fire - Get a target position that will work private _lis = lineIntersectsSurfaces [eyePos _unit, _targetASL, _unit, _vehicle]; - if ((count _lis) > 0) then { // If point is hidden, unit won't fire, do a ray cast to find where they should shoot at + if (_lis isNotEqualTo []) then { // If point is hidden, unit won't fire, do a ray cast to find where they should shoot at _targetASL = ((_lis select 0) select 0); TRACE_1("using ray cast pos",_mousePosASL distance _targetASL); }; diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf index 2512269865..f09211b034 100644 --- a/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf +++ b/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: bux, PabstMirror * Commands the selected unit or group to start suppressive fire on the unit, group or location the module is placed on diff --git a/addons/zeus/functions/fnc_moduleSurrender.sqf b/addons/zeus/functions/fnc_moduleSurrender.sqf index 5fc0ae9e0c..07517d7e71 100644 --- a/addons/zeus/functions/fnc_moduleSurrender.sqf +++ b/addons/zeus/functions/fnc_moduleSurrender.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Flips the surrender state of the unit the module is placed on. * * Arguments: diff --git a/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf b/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf index c120ee14f9..84df0d013a 100644 --- a/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf +++ b/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Zeus module function to teleport players on dialog confirmation * * Arguments: diff --git a/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf b/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf index 3f169028a5..429f825abf 100644 --- a/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf +++ b/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe, mharis001 * Zeus module function to toggle flashlights. @@ -25,10 +25,10 @@ TRACE_1("params",_this); private _units = []; if (_target == -1) then { - _units = (units attachedTo _logic) select {alive _x && {!([_x] call EFUNC(common,isPlayer))} && {!(currentWeapon _x isEqualTo "")}}; + _units = (units attachedTo _logic) select {alive _x && {!([_x] call EFUNC(common,isPlayer))} && {currentWeapon _x isNotEqualTo ""}}; } else { private _side = [west, east, independent, civilian] select _target; - _units = allUnits select {alive _x && {side _x == _side} && {!([_x] call EFUNC(common,isPlayer))} && {!(currentWeapon _x isEqualTo "")}}; + _units = allUnits select {alive _x && {side _x == _side} && {!([_x] call EFUNC(common,isPlayer))} && {currentWeapon _x isNotEqualTo ""}}; }; // Toggle flashlights for units @@ -38,7 +38,7 @@ if (_toggle) then { private _weapon = currentWeapon _x; private _pointer = (_x weaponAccessories _weapon) select 1; - if (!(_pointer isEqualTo "") && {getNumber (_cfgWeapons >> _pointer >> "ItemInfo" >> "FlashLight" >> "size") > 0}) then { + if ((_pointer isNotEqualTo "") && {getNumber (_cfgWeapons >> _pointer >> "ItemInfo" >> "FlashLight" >> "size") > 0}) then { [QEGVAR(ai,enableGunLights), [_x, "forceOn"], _x] call CBA_fnc_targetEvent; } else { if (_addGear) then { diff --git a/addons/zeus/functions/fnc_moduleToggleNvg.sqf b/addons/zeus/functions/fnc_moduleToggleNvg.sqf index f8627acfe6..ca2b270a3d 100644 --- a/addons/zeus/functions/fnc_moduleToggleNvg.sqf +++ b/addons/zeus/functions/fnc_moduleToggleNvg.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe, mharis001 * Zeus module function to toggle NVGs. @@ -31,24 +31,23 @@ if (_target == -1) then { }; // Add or remove NVGs from units -private _cfgVehicles = configFile >> "CfgVehicles"; private _cfgWeapons = configFile >> "CfgWeapons"; if (_toggle) then { { if (hmd _x isEqualTo "") then { // Get NVG item and helmet from unit config - private _linkedItems = getArray (_cfgVehicles >> typeOf _x >> "linkedItems"); + private _linkedItems = getArray (configOf _x >> "linkedItems"); private _nvgItem = _linkedItems select {_x isKindOf ["NVGoggles", _cfgWeapons]}; - private _nvgHelmet = _linkedItems select {!(getArray (_cfgWeapons >> _x >> "subItems") isEqualTo [])}; + private _nvgHelmet = _linkedItems select {getArray (_cfgWeapons >> _x >> "subItems") isNotEqualTo []}; // Add NVG helmet if defined - if !(_nvgHelmet isEqualTo []) exitWith { + if (_nvgHelmet isNotEqualTo []) exitWith { _x addHeadgear (_nvgHelmet select 0); }; // Add NVGs if defined - if !(_nvgItem isEqualTo []) exitWith { + if (_nvgItem isNotEqualTo []) exitWith { _x linkItem (_nvgItem select 0); }; @@ -67,7 +66,7 @@ if (_toggle) then { removeHeadgear _x; }; - if !(_nvgItem isEqualTo "") then { + if (_nvgItem isNotEqualTo "") then { _x unlinkItem _nvgItem; }; } forEach _units; diff --git a/addons/zeus/functions/fnc_moduleUnGarrison.sqf b/addons/zeus/functions/fnc_moduleUnGarrison.sqf index 5ac9ea5dcf..8f69afdbbc 100644 --- a/addons/zeus/functions/fnc_moduleUnGarrison.sqf +++ b/addons/zeus/functions/fnc_moduleUnGarrison.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe * Un-garrison a garrisoned group. @@ -10,7 +10,7 @@ * None * * Example: - * [LOGIC] call ace_zeus_fnc_moduleUngarrison + * [LOGIC] call ace_zeus_fnc_moduleUnGarrison * * Public: No */ diff --git a/addons/zeus/functions/fnc_moduleUnconscious.sqf b/addons/zeus/functions/fnc_moduleUnconscious.sqf index 9bcec2cdcb..7eede3cdec 100644 --- a/addons/zeus/functions/fnc_moduleUnconscious.sqf +++ b/addons/zeus/functions/fnc_moduleUnconscious.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Flips the unconscious state of the unit the module is placed on. * * Arguments: @@ -38,6 +38,11 @@ if (isNil QEFUNC(medical,setUnconscious)) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { private _unconscious = GETVAR(_unit,ACE_isUnconscious,false); + if (_unconscious) then { + _unit setVariable [QEGVAR(medical_statemachine,AIUnconsciousness), nil, true]; + } else { + _unit setVariable [QEGVAR(medical_statemachine,AIUnconsciousness), true, true]; + }; // Function handles locality for me [_unit, !_unconscious, 10e10] call EFUNC(medical,setUnconscious); }; diff --git a/addons/zeus/functions/fnc_moduleUnloadFromCargo.sqf b/addons/zeus/functions/fnc_moduleUnloadFromCargo.sqf new file mode 100644 index 0000000000..dc4b1dea9a --- /dev/null +++ b/addons/zeus/functions/fnc_moduleUnloadFromCargo.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Loads the object module is placed on into selected vehicle. + * + * Arguments: + * 0: Module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleUnloadFromCargo + * + * Public: No + */ + +if (canSuspend) exitWith { + [FUNC(moduleUnloadFromCargo), _this] call CBA_fnc_directCall; +}; + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _vehicle = attachedTo _logic; + +deleteVehicle _logic; + +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { + [LSTRING(RequiresAddon)] call FUNC(showMessage); +}; +if (isNull _vehicle) exitWith { + [LSTRING(NothingSelected)] call FUNC(showMessage); +}; +if (!alive _vehicle) exitWith { + [LSTRING(OnlyAlive)] call FUNC(showMessage); +}; +if ((_vehicle getVariable [QEGVAR(cargo,loaded), []]) isEqualTo []) exitWith { + [LSTRING(paradrop_noCargoLoaded)] call FUNC(showMessage); +}; + +EGVAR(cargo,interactionVehicle) = _vehicle; +EGVAR(cargo,interactionParadrop) = false; +createDialog QEGVAR(cargo,menu); diff --git a/addons/zeus/functions/fnc_moduleZeusSettings.sqf b/addons/zeus/functions/fnc_moduleZeusSettings.sqf index 6024126952..c1d3e4610e 100644 --- a/addons/zeus/functions/fnc_moduleZeusSettings.sqf +++ b/addons/zeus/functions/fnc_moduleZeusSettings.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Module for adjusting various aspects of zeus * * Arguments: diff --git a/addons/zeus/functions/fnc_showMessage.sqf b/addons/zeus/functions/fnc_showMessage.sqf index b38652eeba..53094dbfb3 100644 --- a/addons/zeus/functions/fnc_showMessage.sqf +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: 654wak654 * Shows a Zeus message through the BIS function, handles localization. @@ -18,7 +18,7 @@ * Public: Yes */ -if (!(_this isEqualTypeParams [""])) exitWith {ERROR_1("First arg must be string [%1]",_this);}; +if !(_this isEqualTypeParams [""]) exitWith {ERROR_1("First arg must be string [%1]",_this);}; private _message = _this apply {if ((_x isEqualType "") && {isLocalized _x}) then {localize _x} else {_x}}; [objNull, format _message] call BIS_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_ui_attributeCargo.sqf b/addons/zeus/functions/fnc_ui_attributeCargo.sqf index b4fc156127..1b3626d5d9 100644 --- a/addons/zeus/functions/fnc_ui_attributeCargo.sqf +++ b/addons/zeus/functions/fnc_ui_attributeCargo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror, mharis001 * Initializes the ace_cargo attribute of the zeus vehicle attributes display. @@ -60,7 +60,7 @@ private _fnc_onButtonUnload = { private _class = if (_item isEqualType "") then {_item} else {typeOf _item}; private _itemName = getText (configFile >> "CfgVehicles" >> _class >> "displayName"); if ([_item, _vehicle] call EFUNC(cargo,unloadItem)) then { - private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + private _vehicleName = getText (configOf _vehicle >> "displayName"); private _message = [localize ELSTRING(cargo,UnloadedItem), "
", " "] call CBA_fnc_replace; [_message, _itemName, _vehicleName] call FUNC(showMessage); } else { diff --git a/addons/zeus/functions/fnc_ui_attributeRadius.sqf b/addons/zeus/functions/fnc_ui_attributeRadius.sqf index d8a0c46305..86f13eb71b 100644 --- a/addons/zeus/functions/fnc_ui_attributeRadius.sqf +++ b/addons/zeus/functions/fnc_ui_attributeRadius.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Initializes the "Radius" Zeus module attribute. * * Arguments: diff --git a/addons/zeus/functions/fnc_ui_defendArea.sqf b/addons/zeus/functions/fnc_ui_defendArea.sqf index aaa05adbbf..b8051ac1c1 100644 --- a/addons/zeus/functions/fnc_ui_defendArea.sqf +++ b/addons/zeus/functions/fnc_ui_defendArea.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Initializes the "Defend Area" Zeus module display. * * Arguments: diff --git a/addons/zeus/functions/fnc_ui_editableObjects.sqf b/addons/zeus/functions/fnc_ui_editableObjects.sqf index b21b50ea26..8ecb86c2b4 100644 --- a/addons/zeus/functions/fnc_ui_editableObjects.sqf +++ b/addons/zeus/functions/fnc_ui_editableObjects.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: Fisher, SilentSpike, mharis001 + * Author: Fisher, kymckay, mharis001 * Initializes the "Editable Objects" Zeus module display. * * Arguments: diff --git a/addons/zeus/functions/fnc_ui_garrison.sqf b/addons/zeus/functions/fnc_ui_garrison.sqf index a0843b5866..95e2948e5c 100644 --- a/addons/zeus/functions/fnc_ui_garrison.sqf +++ b/addons/zeus/functions/fnc_ui_garrison.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe, mharis001 * Initializes the "Garrison" Zeus module display. diff --git a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf index 79e7ea077d..5a7c5fc5e0 100644 --- a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf +++ b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Initalises the `global skill` zeus module display @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _fnc_sliderMove = { @@ -74,5 +74,5 @@ private _fnc_onConfirm = { [QGVAR(GlobalSkillAI),GVAR(GlobalSkillAI)] call FUNC(moduleGlobalSetSkill); }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_groupSide.sqf b/addons/zeus/functions/fnc_ui_groupSide.sqf index e74ab97c9e..110e2e302d 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Initalises the `group side` zeus module display * * Arguments: @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); @@ -101,7 +101,7 @@ private _fnc_onSelection = { _ctrl ctrlSetTextColor _color; - _ctrl ctrlAddEventHandler ["buttonclick", _fnc_onSelection]; + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSelection]; } forEach IDCs; private _fnc_onUnload = { @@ -129,5 +129,5 @@ private _fnc_onConfirm = { deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_patrolArea.sqf b/addons/zeus/functions/fnc_ui_patrolArea.sqf index 93cae24aa5..03991ee5c7 100644 --- a/addons/zeus/functions/fnc_ui_patrolArea.sqf +++ b/addons/zeus/functions/fnc_ui_patrolArea.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Initializes the "Patrol Area" Zeus module display. * * Arguments: diff --git a/addons/zeus/functions/fnc_ui_searchArea.sqf b/addons/zeus/functions/fnc_ui_searchArea.sqf index db2748e629..6268cd7d22 100644 --- a/addons/zeus/functions/fnc_ui_searchArea.sqf +++ b/addons/zeus/functions/fnc_ui_searchArea.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike + * Author: kymckay * Initializes the "Search Area" Zeus module display. * * Arguments: diff --git a/addons/zeus/functions/fnc_ui_setEngineer.sqf b/addons/zeus/functions/fnc_ui_setEngineer.sqf index 20e8113c7a..3f008403cc 100644 --- a/addons/zeus/functions/fnc_ui_setEngineer.sqf +++ b/addons/zeus/functions/fnc_ui_setEngineer.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Initalizes the "Set Engineer" Zeus module display. @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; // Validate module target private _unit = attachedTo _logic; diff --git a/addons/zeus/functions/fnc_ui_spectator.sqf b/addons/zeus/functions/fnc_ui_spectator.sqf new file mode 100644 index 0000000000..fe9b4a3668 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_spectator.sqf @@ -0,0 +1,265 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Initializes the "Spectator" Zeus module display. + * + * Arguments: + * 0: spectator controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_spectator + * + * Public: No + */ + +#define SIDE_IDCs [92540, 92541, 92542, 92543] +#define CAMERA_IDCs [92550, 92551, 92552] +#define VISION_IDCs [92558, 92559, 92560, 92561] + +params ["_control"]; + +private _display = ctrlParent _control; +private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK +private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; +TRACE_1("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = attachedTo _logic; +TRACE_1("Unit",_unit); + +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +switch (false) do { + case (["ace_spectator"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call _fnc_errorAndClose; + }; + case (!isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case ([_unit, true] call EFUNC(common,isPlayer)): { + [LSTRING(OnlyPlayers)] call _fnc_errorAndClose; + }; +}; + +// Specific onLoad stuff +private _side = side _unit; + +// Spectate sides +private _fnc_onSideSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = _ctrl getVariable "color"; + private _scale = 1; + + private _sides = _display getVariable [QGVAR(spectateSides), []]; + private _selectedSide = (ctrlIDC _ctrl) - 92540; + + // Add or remove from spectatable sides and update color and scale + if (_selectedSide in _sides) then { + _display setVariable [QGVAR(spectateSides), _sides - [_selectedSide]]; + _color set [3, 0.5]; + } else { + _display setVariable [QGVAR(spectateSides), _sides + [_selectedSide]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use the unit's side as default +private _activeSide = [east, west, independent, civilian] find _side; + +// Handle sides other than default four (sideEnemy) +if (_activeSide != -1) then { + _display setVariable [QGVAR(spectateSides), [_activeSide]]; +}; + +{ + private _ctrl = _display displayCtrl _x; + private _side = _x - 92540; + private _color = [_side] call BIS_fnc_sideColor; + _ctrl setVariable ["color", _color]; + _ctrl ctrlSetActiveColor _color; + _color set [3, 0.5]; + + if (_side == _activeSide) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSideSelection]; +} forEach SIDE_IDCs; + +// Camera modes +private _fnc_onModesSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = [1, 1, 1, 0.5]; + private _scale = 1; + + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _selectedMode = (ctrlIDC _ctrl) - 92550; + + // Add or remove from camera modes and update color and scale + if (_selectedMode in _modes) then { + _display setVariable [QGVAR(cameraModes), _modes - [_selectedMode]]; + } else { + _display setVariable [QGVAR(cameraModes), _modes + [_selectedMode]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use setting as default since global variable will change +private _availableModes = [[0, 1, 2], [1, 2], [0], [1], [2]] select EGVAR(spectator,restrictModes); +_display setVariable [QGVAR(cameraModes), _availableModes]; + +{ + private _ctrl = _display displayCtrl _x; + private _color = [1, 1, 1, 0.5]; + + if ((_x - 92550) in _availableModes) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onModesSelection]; +} forEach CAMERA_IDCs; + +// Vision Modes +private _fnc_onVisionSelection = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitwith {}; + + // Convert to boolean since EH returns state as 0 or 1 + private _state = [false, true] select _state; + + private _visions = _display getVariable [QGVAR(visionModes), []]; + private _selectedVision = (ctrlIDC _ctrl) - 92560; + + // Add or remove from vision modes + if (_state) then { + _display setVariable [QGVAR(visionModes), _visions + [_selectedVision]]; + } else { + _display setVariable [QGVAR(visionModes), _visions - [_selectedVision]]; + }; + + // Handle all checked/unchecked + private _allCheckboxes = VISION_IDCs apply {cbChecked (_display displayCtrl _x)}; + + if (_allCheckboxes isEqualTo [_state, _state, _state, _state]) then { + (_display displayCtrl 92557) cbSetChecked _state; + }; +}; + +// Use setting as default since global variable will change +private _availableVisions = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select EGVAR(spectator,restrictVisions); +_display setVariable [QGVAR(visionModes), _availableVisions]; + +{ + private _ctrl = _display displayCtrl _x; + + if ((_x - 92560) in _availableVisions) then { + _ctrl cbSetChecked true; + }; + + _ctrl ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionSelection]; +} forEach VISION_IDCs; + +// Init all visions checkbox +private _fnc_onVisionsAll = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + // Convert to boolean since EH returns state as 0 or 1 + _state = _state == 1; + + // Set state of all checkboxes + { + (_display displayCtrl _x) cbSetChecked _state; + } forEach VISION_IDCs; + + // Store new visions mode setting + private _setting = [[], [-2, -1, 0, 1]] select _state; + _display setVariable [QGVAR(visionModes), _setting]; +}; + +private _allCheckbox = _display displayCtrl 92557; + +// Set to checked by default if setting is all vision modes +if (_availableVisions isEqualTo [-2, -1, 0, 1]) then { + _allCheckbox cbSetChecked true; +}; + +_allCheckbox ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionsAll]; + +// Confirm and Cancel +private _fnc_onUnload = { + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlParent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + private _unit = attachedTo _logic; + if (isNull _unit) exitWith {}; + + private _force = lbCurSel (_display displayCtrl 92531) > 0; + private _hide = lbCurSel (_display displayCtrl 92532) > 0; + private _sides = (_display getVariable [QGVAR(spectateSides), []]) apply {_x call BIS_fnc_sideType}; + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _visions = _display getVariable [QGVAR(visionModes), []]; + + [QGVAR(moduleSpectator), [_force, _hide, _sides, _modes, _visions], _unit] call CBA_fnc_targetEvent; + + deleteVehicle _logic; +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_suicideBomber.sqf b/addons/zeus/functions/fnc_ui_suicideBomber.sqf index 060618e536..2618451871 100644 --- a/addons/zeus/functions/fnc_ui_suicideBomber.sqf +++ b/addons/zeus/functions/fnc_ui_suicideBomber.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: mharis001 * Initializes the "Suicide Bomber" Zeus module display. diff --git a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf index 0594554dc5..b7aab41126 100644 --- a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf +++ b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf @@ -1,6 +1,6 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* - * Author: SilentSpike, mharis001 + * Author: kymckay, mharis001 * Initalizes the "Teleport Players" Zeus module display. * * Arguments: @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _listbox = _display displayCtrl 16189; @@ -91,5 +91,5 @@ private _fnc_onConfirm = { }; _display displayAddEventHandler ["KeyUp", _fnc_onKeyUp]; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf index 333da80ac3..5c9a220615 100644 --- a/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf +++ b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe, mharis001 * Initializes the "Toggle Flashlights" Zeus module display. @@ -53,7 +53,7 @@ if !(isNull _unit) then { if (isNull _unit) then { (_display displayCtrl 56220) lbDelete 0; } else { - (_display displayCtrl 56218) lbSetCurSel ([0, 1] select (_unit isFlashlightOn currentWeapon _unit)); + (_display displayCtrl 56218) lbSetCurSel (parseNumber (_unit isFlashlightOn currentWeapon _unit)); }; private _fnc_onUnload = { diff --git a/addons/zeus/functions/fnc_ui_toggleNvg.sqf b/addons/zeus/functions/fnc_ui_toggleNvg.sqf index 037c216205..5d5747c7ca 100644 --- a/addons/zeus/functions/fnc_ui_toggleNvg.sqf +++ b/addons/zeus/functions/fnc_ui_toggleNvg.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: alganthe, mharis001 * Initializes the "Toggle NVGs" Zeus module display. @@ -53,7 +53,7 @@ if !(isNull _unit) then { if (isNull _unit) then { (_display displayCtrl 92856) lbDelete 0; } else { - (_display displayCtrl 92855) lbSetCurSel ([0, 1] select !(hmd _unit isEqualTo "")); + (_display displayCtrl 92855) lbSetCurSel (parseNumber (hmd _unit isNotEqualTo "")); }; private _fnc_onUnload = { diff --git a/addons/zeus/functions/fnc_zeusAttributes.sqf b/addons/zeus/functions/fnc_zeusAttributes.sqf index 4e2b3eb897..5c3fa8d08c 100644 --- a/addons/zeus/functions/fnc_zeusAttributes.sqf +++ b/addons/zeus/functions/fnc_zeusAttributes.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Dummy function to include BIS script file. @@ -20,4 +20,4 @@ TRACE_1("params",_this); -#include "\a3\ui_f_curator\UI\Displays\RscDisplayAttributes.sqf" +#include "\a3\ui_f_curator\ui\displays\RscDisplayAttributes.sqf" diff --git a/addons/zeus/functions/script_component.hpp b/addons/zeus/functions/script_component.hpp deleted file mode 100644 index 35453cc4e8..0000000000 --- a/addons/zeus/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\zeus\script_component.hpp" \ No newline at end of file diff --git a/addons/zeus/initSettings.inc.sqf b/addons/zeus/initSettings.inc.sqf new file mode 100644 index 0000000000..cf4722c5c3 --- /dev/null +++ b/addons/zeus/initSettings.inc.sqf @@ -0,0 +1,90 @@ +[ + QGVAR(zeusAscension), + "CHECKBOX", + [LLSTRING(ascension_DisplayName), LLSTRING(ascension_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(zeusBird), + "CHECKBOX", + [LLSTRING(bird_DisplayName), LLSTRING(bird_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(remoteWind), + "CHECKBOX", + [LLSTRING(remoteWind_DisplayName), LLSTRING(remoteWind_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(radioOrdnance), + "CHECKBOX", + [LLSTRING(radioOrdnance_DisplayName), LLSTRING(radioOrdnance_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(revealMines), + "LIST", + [LLSTRING(revealMines_DisplayName), LLSTRING(revealMines_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + [ + [ + MINE_REVEAL_NONE, + MINE_REVEAL_TO_SIDE, + MINE_REVEAL_FULL + ], + [ + localize "STR_A3_OPTIONS_DISABLED", + LLSTRING(revealMines_partial), + LLSTRING(revealMines_full) + ], + 0 + ], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(autoAddObjects), + "CHECKBOX", + [LLSTRING(AddObjectsToCurator), LLSTRING(AddObjectsToCurator_desc)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true, + {}, + true // XEH class EH cannot be removed, requires mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(canCreateZeus), + "LIST", + format [LLSTRING(MenuSetting), LLSTRING(CreateZeus)], + format ["ACE %1", LLSTRING(DisplayName)], + [ + [ + CAN_CREATE_NONE, + CAN_CREATE_ADMIN, + CAN_CREATE_CONSOLE, + CAN_CREATE_ALL + ], + [ + localize "STR_A3_None", + localize "str_3den_attributes_enabledebugconsole_host_text", + localize "str_ui_debug_title", + localize "str_3den_attributes_enabledebugconsole_all_text" + ], + 0 + ], + true +] call CBA_fnc_addSetting; diff --git a/addons/zeus/initSettings.sqf b/addons/zeus/initSettings.sqf deleted file mode 100644 index 1db3fe5205..0000000000 --- a/addons/zeus/initSettings.sqf +++ /dev/null @@ -1,22 +0,0 @@ -[ - QGVAR(canCreateZeus), - "LIST", - format [LLSTRING(MenuSetting), LLSTRING(CreateZeus)], - format ["ACE %1", LLSTRING(DisplayName)], - [ - [ - CAN_CREATE_NONE, - CAN_CREATE_ADMIN, - CAN_CREATE_CONSOLE, - CAN_CREATE_ALL - ], - [ - localize "STR_A3_None", - localize "str_3den_attributes_enabledebugconsole_host_text", - localize "str_ui_debug_title", - localize "str_3den_attributes_enabledebugconsole_all_text" - ], - 0 - ], - true -] call CBA_settings_fnc_init; diff --git a/addons/zeus/script_component.hpp b/addons/zeus/script_component.hpp index 957c7699d3..8b59ac1032 100644 --- a/addons/zeus/script_component.hpp +++ b/addons/zeus/script_component.hpp @@ -28,3 +28,7 @@ #define CAN_CREATE_ADMIN 0 #define CAN_CREATE_CONSOLE 1 #define CAN_CREATE_ALL 2 + +#define MINE_REVEAL_NONE 0 +#define MINE_REVEAL_TO_SIDE 1 +#define MINE_REVEAL_FULL 2 diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 9ec53fe265..28a73213ca 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -11,6 +11,11 @@ 제우스 Zeus Зевс + Zeus + Zeus + Zeus + Zeus + Zeus Zeus Settings @@ -24,9 +29,10 @@ Настройки Зевса Impostazioni Zeus Zeus 設定 - Zeus 설정 + 제우스 설정 宙斯设定 宙斯設定 + Zeus Ayarları Provides control over various aspects of Zeus. @@ -35,12 +41,12 @@ Poskytuje kontrolu na různými aspekty Zeuse. Bietet die Steuerung verschiedener Zeus-Optionen an. Proporciona controle sobre diversos aspectos do Zeus. - Fourni le contrôle des différents aspects de Zeus. + Fournit un contrôle sur divers aspects de Zeus. Különböző beállítási lehetőségeket biztosít a Zeus részeihez. Позволяет контролировать различные аспекты Зевса. Fornisce controllo su vari aspetti di Zeus. - Zeus の操作性を様々な側面から強化します。 - Zeus에게 다양한 방면의 조작을 제공해줍니다 + Zeusの操作性を様々な側面から強化します。 + 제우스에게 다양한 방면의 조작을 제공해줍니다 提供宙斯各个方面的控制权 提供宙斯各個方面的控制權 @@ -51,13 +57,13 @@ Zpráva o novém Zeusovi Aufstiegsnachrichten Mensagens de ascensão - Message d'ascension + Message d'Ascension Felemelkedési üzenetek Сообщения о вознесении Messaggi di Ascesa - 転生表示 + 転生の布告 재림 메세지 - 宙斯上任讯息 + 宙斯上任信息 宙斯上任訊息 @@ -66,14 +72,14 @@ Mostrar mensajes emergentes globales cuando a un jugador se le asigna como Zeus. Zobrazit globální zprávu když je hráč přiřazen jako Zeus. Zeige globale Popup-Nachrichten wenn ein Spieler zu Zeus wird. - Mostra uma mensagem popup quando um jogador é atribuido ao Zeus. - Affiche un message global quand un joueur est assigné en tant que Zeus. + Mostra uma mensagem popup quando um jogador é atribuído ao Zeus. + Affiche des messages popup globaux lorsqu'un joueur est élevé au rang de Zeus. Globális üzeneteket jelez ki, ha egy játékos Zeus-nak lesz beosztva. Отображает глобальное всплывающее сообщение, когда один из игроков становится Зевсом. Mostra messaggi popup globali quando un giocatore viene assegnato come Zeus. - プレイヤーが Zeus になる際、全体へポップアップ表示を行います。 - 플레이어가 Zeus 될 시 서버에 이를 알리는 팝업이 등장합니다. - 当一位玩家被指定为宙斯时显示全域讯息 + プレイヤーがZeusになる際、全体へポップアップ表示を行います。 + 플레이어가 제우스가 되면 서버에 알림 팝업이 등장합니다. + 当一位玩家被指定为宙斯时显示全局信息 當一位玩家被指定為宙斯時顯示全域訊息 @@ -88,9 +94,10 @@ Орел Зевса Aquila Zeus Zeus イーグル - Zeus 독수리 + 제우스 독수리 宙斯鹰眼模式 宙斯鷹眼模式 + Zeus Kartalı Spawn an eagle that follows the Zeus camera. @@ -99,12 +106,12 @@ Vytvoří orla, který následuje kameru Zeuse. Erstelle einen Adler, der der Zeus-Kamera folgt. Cria uma águia que segue a câmera do Zeus - Faire apparaitre un aigle qui suit la caméra Zeus + Crée un aigle qui suit la caméra Zeus. Lerak egy sast, ami követi a Zeus kamerát. Спавнит орла, который следует за камерой Зевса. - Crea un'aquila che segue la camera Zeus. - Zeus カメラを追うイーグルを出現します。 - Zeus의 카메라를 따라다니는 독수리를 생성합니다. + Crea un'aquila che segue la videocamera Zeus. + Zeusカメラを追いかける鷲を出現させます。 + 제우스의 카메라를 따라다니는 독수리를 생성합니다. 生成一个老鹰跟着宙斯的摄影机 生成一個老鷹跟著宙斯的攝影機 @@ -115,7 +122,7 @@ Zvuky větru Windgeräusche Sons de vento - Bruit de vent + Bruits de vent Szélhangok Звук ветра Suoni del Vento @@ -123,6 +130,7 @@ 바람 소리 风声 風聲 + Rüzgar sesi Play wind sounds when Zeus remote controls a unit. @@ -131,12 +139,12 @@ Přehrát varování (vítr) když Zeus převezmě kontrolu nad jednotkou. Spiele Windgeräusche ab, wenn Zeus eine Einheit steuert. Reproduz sons de vento quando uma unidade é remotamente controlada pelo Zeus. - Joue des bruits de vent quand Zeus controle une unité. + Joue des bruits de vent lorsque Zeus contrôle une unité distante. Szélhangokat játszik le, ha a Zeus távvezérel egy egységet. Проигрывает звук ветра каждый раз, когда Зевс вселяется в юнита. - Esegui rumori di vento quando Zeus controlla un'unità in remoto. - ユニットが Zeus 遠隔操作になった際、風の音がします。 - Zeus가 유닛을 조작할 때 바람소리가 납니다. + Riproduci rumori di vento quando Zeus controlla un'unità in remoto. + Zeusがユニットを遠隔操作した際、風の音を再生します。 + 제우스가 유닛을 조작할 때 바람소리가 납니다. 当宙斯开始控制单位时利用风的声音提示 當宙斯開始控制單位時利用風的聲音提示 @@ -147,11 +155,11 @@ Varování před dělostřelectvem Artilleriewarnung Aviso de explosivos - Alerte d'équipement militaire + Alerte d'artillerie Tüzérségi figyelmeztetés Предупреждение об арте - Allarme Esplosivi - 砲撃警告 + Allerta Artiglieria + 砲撃の警告 폭격 경고 武装警告 武裝警告 @@ -163,12 +171,12 @@ Přehrát varování (rádio) když Zeus použije dělostřelectvo. Spiele eine Radiowarnung ab, wenn Zeus Artillerie verwendet. Reproduz uma aviso via rádio quando o Zeus usa um explosivo. - Joue un son radio quand le Zeus utilise du matériel militaire. + Diffuse un avertissement radio lorsque Zeus utilise de l'artillerie. Rádiós figyelmeztetés kiadása, ha a Zeus tüzérséget használ. Проигрывает звук радио каждый раз, когда Зевс использует артиллерию. - Riproduci un messaggio radio quando Zeus usa esplosivi. - Zeus が砲撃を使う際に、無線で警告を流します。 - Zeus가 폭격시 경고 무전을 재생합니다. + Riproduci un messaggio radio quando Zeus usa artiglieria. + Zeusが砲撃を使う際に、無線で警告を流します。 + 제우스가 폭격 시 경고 무전을 재생합니다. 当宙斯开始攻击时使用无线电警告 當宙斯開始攻擊時使用無線電警告 @@ -195,11 +203,11 @@ Odhalí miny pro spojence a umístnit jejich značku na mapu. Melde Minen gegenüber Verbündeten und platziere entsprechende Kartenmarkierungen. Revelar minas para aliados e colocar marcadores no mapa. - Révéler les mines et placer un marqueur sur la carte. + Révèle les mines aux alliés et place des marqueurs sur la carte. Feltárja az aknákat a szövetségeseknek, és jelölőket helyez el a térképen. Показывает мины союзникам и отмечает их маркерами на карте. Rivela mine ad alleati e piazza marcatori in mappa. - 友軍に地雷と地図へ設置マーカーを表示します。 + 地雷の位置を味方に公開し、マップマーカーを配置します。 아군에게 지도 상의 모든 지뢰를 표시합니다. 地图将标记队友放置的地雷 地圖將標記隊友放置的地雷 @@ -217,7 +225,7 @@ Rivela ad Alleati 友軍へ表示 모든 아군에게 표시 - 透露给盟军 + 透露给友军 透露給盟軍 @@ -233,7 +241,7 @@ Alleati + Marcatori Mappa 友軍と地図マーカー 아군 + 지도 마커 - 显示盟军+地图标记 + 显示友军+地图标记 顯示盟軍+地圖標記 @@ -243,27 +251,31 @@ Přepnout - Vězeň Gefangennahme umschalten Alternar prisioneiro - Basculer en captif + Commuter captivité Elfogott állapot váltása Пленный (вкл./выкл.) - Attivatore Prigioniero - 捕虜に切り替え + Imposta Prigioniero + 捕虜状態を切り替え 포로 토글 切换俘虏 切換俘虜 + Tutuklamayı Aç/Kapat Defend Area Défendre la zone Защитить зону Bránit oblast - 防衛範囲 + エリアの防衛 Broń obszaru Verteidige Gebiet 지역 방어 Difendi Area 防御区域 防禦區域 + Defender Área + Bölgeyi Koru + Defender área Update Editable Objects @@ -271,37 +283,60 @@ 編集可能オブジェクトを更新 Aktualizuj edytowalne obiekty 수정 가능한 물체 갱신 - Màj les objets éditables + Màj les objets modifiables Aggiorna Oggetti Modificabili - 更新可编辑的物件 + 更新可编辑的物体 更新可編輯的物件 Обновить редактируемые объекты + Atualizar objetos editáveis + Aktualizujte upravitelné objekty + Actualizar objetos editables Editing Mode 編輯模式 + 编辑模式 Modalità per editare Bearbeitungsmodus 編集モード Tryb Edytowania Режим редактирования + Modo de edição + Režim úprav + Mode d'édition + Modo de edición + 편집 모드 Add or remove editable objects from Zeus 新增或移除可編輯物件給宙斯 + 添加或删除宙斯的可编辑物体 Aktiviere oder deaktiviere zu bearbeitende Objekte von Zeus Agguingi o rimuovi oggetti che Zeus può modificare - Zeus から編集可能オブジェクトの追加と削除をする + Zeusから編集可能オブジェクトの追加と削除をする Dodaj lub usuń edytowalne obiekty z Zeus'a Добавить или удалить редактируемые объекты от Зевса + Adiciona ou remove objetos editáveis do Zeus + Přidej nebo odeber upravitelné objekty ze Zeusu + Ajoute ou supprime les objets modifiables depuis Zeus. + Añadir o eliminar objetos editables desde Zeus + 제우스가 편집 가능한 물체를 추가하거나 제거합니다 Add Objects + Füge Objekte hinzu 新增物件 + 新增物体 Aggiungi Oggetti オブジェクト追加 Dodaj obiekty Добавить объекты + Adicionar Objetos + Přidat objekty + Ajouter des objets + Obje Ekle + Añadir objetos + 물체 추가 Remove Objects @@ -309,64 +344,91 @@ オブジェクト削除 물체 삭제 Usuń obiekty - Enlève les objets + Enlever des objets Rimuovi Oggetti - 移除物件 + 移除物体 移除物件 Удалить объекты + Remover Objetos + Odebrat objekty + Objeyi Kaldır + Eliminar objetos All Curators - Alle Zeus' + Alle Kuratoren 全キュレーター 모든 큐레이터 Wszyscy kuratorzy - Tous curateurs - Tutti i Moderatori - 所有编辑者 + Tous les curateurs + Tutti gli Zeus + 所有宙斯 所有編輯者 Все кураторы + Todos os Curadores + Všichni kurátoři + Todos los curadores Apply changes to all curators - Änderungen bei allen Zeus' aktualisieren - 全キュレーターへ変更を適用します。 + Änderungen bei allen Kuratoren aktualisieren + 全キュレーターへ変更を適用します 모든 큐레이터에 변화를 적용합니다 Zatwierdź zmiany dla wszystkich kuratorów - Applique les changements à tous les curateurs - Applica i cambiamenti a tutti i moderatori - 确认变更给所有编辑者 + Applique les changements à tous les curateurs. + Applica i cambiamenti a tutti gli Zeus + 确认变更给所有宙斯 確認變更給所有編輯者 Применить изменения ко всем кураторам + Aplicar mudanças à todos os Curadores + Použít změny na všechny kurátory + Aplicar cambios a todos los curadores Additional Objects Zusätzliche Objekte Oggetti aggiuntivi - オブジェクト増加 + 追加のオブジェクト Dodatkowe obiekty Доп. объекты + Objetos adicionais + Další objekty + 額外物件 + 额外物体 + Objets supplémentaires + Objetos adicionales + 추가 목표 Additional objects to include in the action regardless of Task Radius Zusätzliche Objekte unabhängig vom Aufgabenradius einbeziehen - Oggetti aggiuntivi da includere nell'azione indipendentemente dal Raggio di Attività - タスク範囲に関係無くオブジェクトを更に増加させます + Oggetti aggiuntivi da includere nell'azione indipendentemente dal Raggio dell'Incarico + タスク半径に関係なく次のオブジェクトを編集可能に追加します Dodatkowe obiekty do uwzględnienia w akcji niezależnie od zasięgu zadania Дополнительные объекты для включения в действие, независимо от радиуса выполнения задачи + Objetos adicionais para incluir na ação, ignorando a distância da tarefa + Další objekty, které mají být zahrnuty do akce, bez ohledu na poloměr úlohy + 無論任務範圍何處,都在行動中包含著額外的物件 + 确认变更给所有宙斯 + Objets supplémentaires à intégrer dans l'action, quel que soit le rayon de la tâche. + Objetos adicionales para incluir en la acción al margen del Radio de Tarea + 목표 반경 상관없이 추가 목표를 추가합니다. Global AI Skill - Compétence global de l'IA + Compétence globale de l'IA Мастерство ботов Globální zkušenosti AI - 総合的 AI スキル + 全体のAIスキル Globalne umiejętności AI Globale KI-Fähigkeit 서버 인공지능 실력 - Abilità AI Globale - AI技巧设定 + Abilità IA Globale + AI 技巧设定 AI技巧設定 + Habilidade Global da IA + Genel AI Yetenekleri + Habilidad de IA Global General Skill @@ -380,10 +442,13 @@ Abilità Generale 总体技巧 總體技巧 + Habilidade Geral + Genel Yetenekler + Habilidad general Changes: general, commanding, courage - Change: general, commanding, courage + Changements : `general`, `commanding`, `courage`. Изменяет: general, commanding, courage Upravuje: general, commanding, courage 変更: general, commanding, courage @@ -391,8 +456,10 @@ Ändert: general, commanding, courage 변화: 전반적, 지휘, 사기 Cambia: generale, comando, - 改变: 战斗技巧,指挥技巧,勇气大小 + 改变:战斗技巧,指挥技巧,勇气大小 改變: 戰鬥技巧,指揮技巧,勇氣大小 + Muda: general, commanding, courage + Cambios: general, commanding, courage Accuracy @@ -406,10 +473,12 @@ Precisione 精确度 精確度 + Precisão + Precisión Changes: aimingAccuracy - Change : aimingAccuracy + Changements : `aimingAccuracy`. Изменяет: aimingAccuracy Upravuje: aimingAccuracy 変更: aimingAccuracy @@ -417,12 +486,14 @@ Ändert: aimingAccuracy 변화: 조준 명중률 Cambia: aimingAccuracy - 改变: 瞄准精确度 + 改变:瞄准精确度 改變: 瞄準精確度 + Muda: aimingAccuracy + Cambios: aimingAccuracy Weapon Handling - Maniement d'armes + Manipulation des armes Владение оружием Zacházení se zbraní 武器の扱い @@ -432,10 +503,12 @@ Uso dell'Arma 武器掌握 武器掌握 + Uso de Arma + Manejo de arma Changes: aimingShake, aimingSpeed, reloadSpeed - Change : aimingShake, aimingSpeed, reloadSpeed + Changements : `aimingShake`, `aimingSpeed`, `reloadSpeed`. Изменяет: aimingShake, aimingSpeed, reloadSpeed Upravuje: aimingShake, aimingSpeed, reloadSpeed 変更: aimingShake, aimingSpeed, reloadSpeed @@ -443,8 +516,10 @@ Ändert: aimingShake, aimingSpeed, reloadSpeed 변화: 조준시 흔들림, 조준 속도, 재장전 속도 Cambia: aimingShake, aimingSpeed, reloadSpeed - 改变: 手晃幅度,瞄准速度, 重新装填速度 + 改变:手晃幅度,瞄准速度, 重新装填速度 改變: 手晃幅度,瞄準速度, 重新裝填速度 + Muda: aimingShake, aimingSpeed, reloadSpeed + Cambios: aimingShake, aimingSpeed, reloadSpeed Spotting @@ -455,13 +530,15 @@ Rozpoznanie Aufklärung 탐지 - Ricognizione + Individuazione 索敌能力 索敵能力 + Detecção + Detección Changes: spotDistance, spotTime - Change : spotDistance, spotTime + Changements : `spotDistance`, `spotTime`. Изменяет: spotDistance, spotTime Upravuje: spotDistance, spotTime 変更: spotDistance, spotTime @@ -469,12 +546,14 @@ Ändert: spotDistance, spotTime 변화: 탐지 거리, 탐지까지의 시간 Cambia: spotDistance, spotTime - 改变: 搜索距离, 发现时间 + 改变:搜索距离,发现时间 改變: 搜索距離, 發現時間 + Muda: spotDistance, spotTime + Cambios: spotDistance, spotTime Seek Cover - Chercher des couvertures + Chercher des couverts Поиск укрытий Vyhledávat krytí 遮蔽 @@ -484,19 +563,23 @@ Cerca Copertura 寻找掩护 尋找掩護 + Procurar Cobertura + Buscar cobertura Should AI seek cover - L'IA devrait elle chercher des couvertures + L'IA se met à couvert. Должны ли боты искать укрытия AI se bude snažit vyhledávat krytí - AI は遮蔽を取るようになります + AIは遮蔽を取るようになります Czy AI powinno szukać osłon Soll KI nach Deckung suchen 인공지능이 엄폐물을 찾아갑니다 - Le AI dovrebbero cercare una copertura - 决定AI是否会寻找掩护 + Le IA dovrebbero cercare coperture + 决定 AI 是否会寻找掩护 決定AI是否會尋找掩護 + A IA dever buscar cobertura + La IA debe buscar cobertura Auto Combat @@ -510,45 +593,55 @@ Combattimento Automatico 自动交战 自動交戰 + Combate automático + Combate automático Should AI automatically switch to combat mode - L'IA devrait elle passer automatiquement en mode combat + L'IA passe automatiquement en mode combat. Должны ли боты автоматически переходить в режим боя AI se automaticky přepne do bojového režimu - AI は自動的に戦闘状態へ切り替えます + AIは自動的に戦闘状態へ切り替えます Czy AI powinno automatycznie przechodzić w tryb walki Soll KI automatisch in Kampfmodus umschalten 인공지능이 자동적으로 교전 상태에 돌입합니다 - Le AI dovrebbero passare in modalità di combattimento automaticamente - 决定AI是否会自动与敌人交战 + Le IA dovrebbero passare in modalità di combattimento automaticamente + 决定 AI 是否会自动与敌人交战 決定AI是否會自動與敵人交戰 + A IA deveria automaticamente mudar para modo de combate + La IA debe automáticamente cambiar a modo de combate Group Side - Côté du groupe + Camp du groupe Сторона группы Strana skupiny - グループ側 + グループの陣営 Strona grupy Gruppenseite 진영 측 Fazione del Gruppo 小队阵营 小隊陣營 + Lado do Grupo + Tarafı Değiştir + Bando de grupo Patrol Area Zone de patrouille Патрулировать зону Oblast hlídkování - 哨戒範囲 + エリアの哨戒 Patrol obszaru Patrouillengebiet 정찰 구역 Area di Pattugliamento 巡逻区域 巡邏區域 + Patrulhar Área + Devriye ayarla + Patrullar área Toggle Surrender @@ -557,14 +650,15 @@ Přepnout - Vzdávání Aufgabe umschalten Alternar rendição - Basculer en capitulation + Commuter capitulation Kapituláló állapot váltása Сдавшийся (вкл./выкл.) - Attivatore Resa - 投降として切り替え + Imposta Resa + 投降状態を切り替え 항복 토글 切换投降 切換投降 + Teslim olmayı Aç/Kapat Add/Remove FRIES @@ -572,11 +666,15 @@ FRIES の追加と削除 패스트로프 추가/제거 Dodaj/usuń FRIES - Aj./Enlève FRIES + Ajouter/Enlever le FRIES Aggiungi/Rimuovi FRIES 增加/移除快速垂降进场撤离系统 增加/移除快速垂降進場撤離系統 Добавить/Удалить FRIES + Adicionar/Remover FRIES + Přidat/Odebrat FRIES (slaňování) + Ekle/Kaldır FRIES + Añadir/Eliminar FRIES %1 is not fastrope compatible. @@ -584,11 +682,14 @@ %1 はファストロープに対応していません。 %1은 패스트로프하기에 적합하지 않습니다. %1 nie jest kompatybilny ze zjazdem linowym. - %1 n'est pas compatible. + Le %1 n'est pas compatible avec l'hélicordage. %1 non è compatibile con il fastrope. %1无法使用快速绳降系统 %1無法使用快速繩降系統 %1 несовместим с быстрым спуском + %1 não é compatível com sistema de corda. + %1 není kompatibilní se slaňováním. + %1 no es compatible con descenso por cuerda. Unable to remove FRIES, ropes are deployed. @@ -596,24 +697,30 @@ 既にロープが展開されているため、FRIES を削除できません。 패스트로프 제거 불가능, 줄이 이미 배치되었습니다. Nie można usunąć FRIES, liny są wypuszczone. - Pas en mesure d'enlever le FRIES, les cordes ne sont pas déployées. + Impossible d'enlever le FRIES, les cordes sont déployées. Impossibile rimuovere le FRIES, le corde sono ancora dispiegate 无法移除快速绳降系统,因为绳索已被释放出来 無法移除快速繩降系統,因為繩索已被釋放出來 Невозможно удалить FRIES, канаты развернуты. + Não foi possível remover o FRIES, as cordas estão soltas. + Nemohu odebrat FRIES, lana jsou vytažena. + No es posible eliminar FRIES, las cuerdas están desplegadas- Teleport Players Téléporter joueurs Телепортиваровать игроков Teleportovat hráče - プレイヤーを移動 + プレイヤーのテレポート Teleportuj graczy Spieler teleportieren 플레이어 순간이동 Teletrasporta Giocatori 传送玩家 傳送玩家 + Teleportar Jogadores + Teletransportadores + Oyuncuları Işınla Player @@ -627,45 +734,55 @@ Giocatore 玩家 玩家 + Jogador + Player + Oyuncu Teleport selected player to module position - Téléporter le joueur sélectionné à la position du module + Téléporte le joueur sélectionné à la position du module. Телепортирует выбранного игрока к местоположению модуля Teleportuje vybraného hráče na pozici modulu 選択したプレイヤーをモジュール位置へ移動します Teleportuje wybranego gracza na pozycję modułu Teleportiert ausgewählten Spieler zur Position des Moduls 모듈의 위치로 플레이어 순간이동 - Teletrasporta il giocatore selezionato nella posizione del modulo + Teletrasporta il giocatore selezionato sulla posizione del modulo 传送选定的玩家至模块位置 傳送選定的玩家至模塊位置 + Teleporta o jogador selecionado para a posição do módulo + Teleportar al jugador seleccionado a la posición del módulo Teleport Group Téléporter le groupe Телепортировать Группу Teleportovat skupinu - グループを移動 + グループで移動 Teleport grupy Gruppe teleportieren 그룹 순간이동 Teletrasporta Gruppo 传送小队 傳送小隊 + Teleportar Grupo + Grubu ışınla + Teleportar al grupo Teleports all units in group - Téléporte toutes les unités du groupe + Téléporte toutes les unités du groupe. Телепортирует всех юнитов в группе Teleportuje všechny jednotky ve skupině グループ内の全ユニットを移動させます Teleportuje wszystkie jednostki w grupie Teleportiert alle Einheiten der Gruppe - 그룹내에 모든 인원을 순간이동 시킵니다 + 그룹 내에 모든 인원을 순간이동 시킵니다 Teletrasporta tutte le unità del gruppo 传送全部小队成员 傳送全部小隊成員 + Teleporta todas as unidades do grupo + Teletransporta todas las unidades en el grupo Toggle Unconscious @@ -674,40 +791,46 @@ Přepnout - Bezvědomí Bewusstlosigkeit umschalten Alternar inconsciência - Basculer en inconscient + Commuter état de conscience Eszméletlen állapot váltása Без сознания (вкл./выкл.) - Attivatore Incoscienza - 気絶を切り替え + Imposta Incoscienza + 無意識状態を切り替え 기절 토글 切换昏迷 切換昏迷 + Bayıltmayı Aç/Kapat Search Area - Chercher la zone + Zone de recherche Обыскать зону Prohledat oblast - 捜索範囲 + エリアの捜索 Przeszukaj teren Durchsuche Gebiet 지역 수색 Area di Ricerca 搜索区域 搜索區域 + Procurar Área + Área de búsqueda + Bölgeyi Ara Search Nearby Building - Chercher le bâtiment proche + Chercher un bâtiment proche Обыскать ближайшие здания Prohledat nejbližší budovu - 近くの建物を捜索します + 至近の建物を捜索 Przeszukaj najbliższy budynek Durchsuche nahegelegenes Gebäude 근처 건물 수색 - Cerca Edifici nelle Vicinanze + Bonifica Edifici Vicini 搜索附近的建筑物 搜索附近的建築物 + Procurar construções próximas + Buscar edificios cercanos Assign Medic @@ -733,8 +856,8 @@ Určit zdravotnické vozidlo Asignar vehículo médico Assegna Veicolo Medico - Assigner véhicule médical - 医療車両として割り当て + Affecter véhicule sanitaire + 医療車両に割り当て 의무 차량 임명 指定医疗载具 指定醫療載具 @@ -748,8 +871,8 @@ Určit zdravotnické zařízení Asignar instalación médica Assegna Struttura Medica - Assigner installation médicale - 医療施設として割り当て + Affecter installation sanitaire + 医療施設に割り当て 의무 시설 임명 指定医疗设施 指定醫療設施 @@ -760,26 +883,31 @@ Przełącz symulację シミュレーションを切り替え 재현 토글 - Bascule Simulation - Attivatore Simulazione + Commuter Simulation + Imposta Simulazione 切换模拟 切換模擬 - Вкл/Выкл симуляцию + Переключить симуляцию + Alternar Simulação + Activar simulación + Přepnout simulaci objektu + Similasyonu Aç/Kapat Add Spare Wheel - Adicionar roda sobressalente + Adicionar roda sobressalente (estepe) Dodaj koło zapasowe Добавить запасное колесо Přidat rezervní kolo Aggiungi Ruota di Scorta Ersatzrad hinzufügen Agregar rueda de auxilio - Ajouter pièce de rechange + Ajouter une pièce de rechange 予備タイヤを追加 예비 바퀴 추가 增加备用轮胎 增加備用輪胎 + Tekerlek Ekle Add Spare Track @@ -790,31 +918,33 @@ Aggiungi Cingolo di Scorta Ersatzkette hinzufügen Agregar oruga de repuesto - Ajouter une chenille de secours - 車両へ予備タイヤを追加 + Ajouter une chenille de rechange + 予備履帯を追加 예비 궤도 추가 增加备用履带 增加備用履帶 + Yedek Parça Ekle Unit must be alive - Utiliser uniquement sur une unité vivante + L'unité doit être vivante. Einheit muss lebendig sein. Utilizar solo en unidades vivas Použitelné jen na živé jednotky Używaj tylko na żywych jednostkach Применимо только к живым юнитам Csak élő egységeken használni - Si può fare solo su persone vive - Usar somente em unidades vivas - ユニットを生存させます - 대상이 반드시 살아있어야 합니다 - 单位必须是活着 + Si può fare solo su unità vive + Unidade deve estar viva + ユニットは生きている必要があります + 대상이 반드시 살아 있어야 합니다 + 单位必须是活的 單位必須是活著 + Birliğin yaşaması gerekiyor Unit must be infantry - Utiliser uniquement sur du personnel à pied + L'unité doit être un fantassin. Nur bei abgesessener Infanterie verwendbar Utilizar solo en infanteria desmontada Použitelné jen na pěsích jednotkách @@ -822,8 +952,8 @@ Применимо только к пехоте вне техники 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 + ユニットは歩兵である必要があります 대상이 반드시 보병이어야 합니다 单位必须是步兵 單位必須是步兵 @@ -837,9 +967,9 @@ La unidad debe ser una estructura Jednotka musí být budova Si può usare solo su strutture - L'unité doit être une structure - ユニットを構造物とします - 대상이 반드시 건축물이어야만 합니다 + L'unité doit être une structure. + ユニットは構造物である必要があります + 대상이 반드시 건축물이어야 합니다 单位必须是建筑 單位必須是建築 @@ -852,9 +982,9 @@ La unidad debe ser un vehículo Jednotka musí být vozidlo Si può usare solo su veicoli - L'unité doit être un véhicule - ユニットを車両とします - 대상이 반드시 차량이어야만 합니다 + L'unité doit être un véhicule. + ユニットは車両である必要があります + 대상이 반드시 차량이어야 합니다 单位必须是载具 單位必須是載具 @@ -867,24 +997,24 @@ L'unità dev'essere un veicolo con spazio di carico Einheit muss ein Fahrzeug mit Ladekapazität sein La unidad debe ser un vehículo con espacio de carga - L'unité doit être un véhicule avec de l'espace de cargaison - ユニットをカーゴ スペースがある車両にします + L'unité doit être un véhicule muni d'un espace de stockage. + ユニットは貨物室のある車両である必要があります 대상이 반드시 화물을 실을 수 있는 차량이어야 합니다 单位必须是载具且有载货空间 單位必須是載具且有載貨空間 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 L'unità deve avere spazio di carico disponibile Einheit muss freie Ladekapazität haben La unidad debe tener espacio de carga disponible - L'unité doit avoir de l'espace libre en cargaison - ユニットへカーゴ スペースを与えます - 대상의 화물공간이 남아있어야합니다 + L'unité doit avoir de l'espace de chargement disponible. + ユニットの貨物室に空きが必要です + 대상의 화물공간이 남아 있어야 합니다 单位必须有剩余的载货空间 單位必須有剩餘的載貨空間 @@ -895,44 +1025,48 @@ Jednotka nemí být vězeň Einheit darf nicht gefangen sein Unidade não pode ser prisioneira - L'unité ne doit pas être captive + L'unité ne doit pas être en captivité. Csak elfogatlan egységeken használni Юнит не должен быть пленным L'unità non dev'essere un prigioniero - ユニットを捕虜にさせません + ユニットは捕虜ではない必要があります 대상이 포로면 안됩니다 单位不能被俘虏 單位不能被俘虜 Unit must belong to an appropriate side - L'unité doit appartenir à un côté approprié + L'unité doit appartenir à un camp approprié. Юнит должен принадлежать соответствующей стороне Jednotka musí patřit k příslušné straně - ユニットを適切な陣営にします + ユニットは適切な陣営である必要があります Jednostka musi należeć do odpowiedniej strony Einheit muss einer passenden Seite angehören - 대상이 적절한 진영에 속해야만합니다 + 대상이 적절한 진영에 속해야 합니다 L'unità deve appartenere ad una fazione coerente 单位必须属于一个合适的一边 單位必須屬於一個合適的一邊 + Unidade deve pertencer á um lado apropriado + La unidad debe pertenecer al bando apropiado Nearest building is too far away - Le bâtiment le plus proche est trop loin + Le bâtiment le plus proche est trop éloigné. Ближайшие здания слишком далеко Nejbližší budova je příliš daleko - 近くに建物がありません。 + 一番近い建物まで遠すぎます Najbliższy budynek jest zbyt daleko Nächstgelegenes Gebäude ist zu weit entfernt - 가장가까운 건물이 너무 멈 + 가장 가까운 건물이 너무 멉니다 L'edificio più vicino è troppo lontano 最近的房子离太远了 最近的房子離太遠了 + A construção mais próxima está longe demais + El edificio más cercano está muy lejos. Place on a unit - Placez sur une unité + Placer sur une unité. Es wurde nichts ausgewählt Nada bajo el ratón Coloque em uma unidade @@ -941,10 +1075,11 @@ Ничего не выделено Semmi sincs az egér alatt Piazza su una unità - ユニットの上に設置 + ユニットの上に配置する必要があります 대상에 배치하기 放置在一个单位上 放置在一個單位上 + Bir birim yerleştir Requires an addon that is not present @@ -953,22 +1088,46 @@ Vyžaduje addon, který není přítomen Benötigt ein Addon, das nicht vorhanden ist Requer um addon que não está presente - Requiert un addon qui n'est pas présent + Nécessite un addon qui n'est pas présent. Egy jelenleg hiányzó bővítményt igényel Требуется аддон, который отсутствует Richiede un addon che non è presente - 要求されたアドオンは存在していません + 要求されたアドオンがありません 需要一个不存在的插件 需要一個不存在的插件 현재 없는 애드온을 필요로 합니다 + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 仅玩家 + 只有玩家 + Только игроки + Apenas Jogadores + Pouze hráči + Solo jugadores + Sadece Oyuncular + None Keiner - Niente + Nessuno Żadne なし Нет + Nenhum + Ninguno + + + Nikdo + Aucun + Hiçbiri + 없음 Players @@ -977,14 +1136,30 @@ Gracze プレイヤー Игроки + Jogadores + Jugadores + 玩家 + 玩家 + Hráči + Joueurs + Oyuncular + 플레이어 Players and AI Spieler und KI's - Giocati e AI + Giocatori e IA Gracze i SI - プレイヤーと AI + プレイヤーとAI Игроки и ИИ + Jogadores e IA + Jugadores e IA + 玩家與AI + 玩家与 AI + Hráči a AI + Joueurs et IA + Oyuncular ve AI + 플레이어와 인공지능 Add Objects to Curator @@ -998,7 +1173,7 @@ Fügt Objekte zum Kurator hinzu キュレーターにオブジェクトを追加 큐레이터에 물체 추가 - 增加物件给任务策划人 + 增加物体给任务宙斯 增加物件給任務策劃人 @@ -1009,71 +1184,89 @@ Añadir cualquier objeto creado a todos los directores en la misión Přidá jakékoliv spawnuté objekty všem kurátorům v misi Aggiungi ogni oggetto creato a tutti i Curatori in missione - Ajoute n'importe quel objet spawné à tous les curateurs de la mission + Ajoute n'importe quel objet créé à tous les curateurs de la mission. Fügt jedes gespawnte Objekt allen Kuratoren der Mission hinzu ミッション内で作成されたオブジェクトに全キュレーターを追加 미션 내 큐레이터에 모든 생성 물체 추가 - 在任务中生成物件给所有的任务策划人 + 在任务中生成物体给所有的任务宙斯 在任務中生成物件給所有的任務策劃人 Cargo: - Cargo : + Cargaison : Груз: Náklad: - カーゴ: + 貨物: Ładunek: Ladung: 화물: Cargo: - 货物: + 货物: 貨物: + Carga: + Kargo: + Carga: Select cargo to unload Ladung zum ausladen auswählen 選擇要卸載的貨物 + 选择要卸载的货物 Scegli il carico da scaricare - 選択したカーゴを降ろす + 積み荷を選択すると降ろせます Wybierz ładunek do wyładowania Выберите груз для выгрузки + Selecione objeto para descarregar + Vyberte náklad na vyložení + Sélectionner une cargaison à décharger + Seçilen kargo boşaltıldı + Seleccionar carga para descargar: + 내릴 화물을 선택하세요 Task Radius Rayon de la tâche Радиус задания - タスク範囲 + タスク半径 Obszar zadania Radius der Aufgabe 작업 반경 Raggio Incarico 目标半径 目標半徑 + Área da tarefa + Radio de tarea + Okruh úkolu Radius to perform the task within - Rayon dans lequel la tâche prend place + Rayon dans lequel effectuer la tâche. Радиус выполнения задания - 次の範囲をタスクとして実行 + タスクを実行される半径 Obszar na którym zadanie powinno zostać wykonane Radius, in dem die Aufgabe ausgeführt werden soll 다음 반경 내에서 작업 Raggio per eseguire un incarico 设定目标范围半径 設定目標範圍半徑 + Raio para se executar uma tarefa + Okruh ve kterém bude úkol vykonán + Radio en dentro del cual realizar la tarea Invalid radius entered - Rayon invalide entré + Rayon entré invalide. Введен неправильный радиус Vložen neplatný parametr 無効な半径が入力されました Wpisano nieprawidłowy promień Ungültiger Radius eingegeben 알 수 없는 반경 입력됨 - Raggio Invalido Inserito + Inserito Raggio Invalido 错误的半径值 錯誤的半徑值 + Raio inválido inserido + Radio inválido introducido Suppressive Fire @@ -1086,97 +1279,143 @@ Ogień zaporowy 엄호사격 Огонь на подавление + Fogo de Supressão + Fuego supresivo + Krycí palba - Add Full Arsenal + Add Full BI Arsenal Füge ganzes Arsenal hinzu - Ajouter Arsenal Complet - Aggiungi Arsenale Completo - オブジェクトに完全なアーセナルを追加 - 增加完整的虚拟军火库到物件上 + Ajouter un arsenal complet + Aggiungi Arsenale BI Completo + BI 武器庫を追加 + 增加完整的虚拟军火库到物体上 增加完整的虛擬軍火庫到物件上 Dodaj Wirtualny Arsenał 아스날 놓기 Добавить весь Арсенал + Adicionar Arsenal Completo + Přidat plný arzenál + Arsenal Ekle + Añadir Arsenal completo - Remove Arsenal + Remove BI Arsenal Entferne Arsenal - Retirer Arsenal - Rimuovi Arsenale - オブジェクトからアーセナルを削除 - 移除物件上的虚拟军火库 + Retirer un arsenal + Rimuovi Arsenale BI + BI 武器庫を削除 + 移除物体上的虚拟军火库 移除物件上的虛擬軍火庫 Usuń Wirtualny Arsenał 아스날 제거 Убрать Арсенал + Remover Arsenal + Odebrat arzenál + Arsenali Kaldır + Eliminar Arsenal Load into Cargo In Frachtraum laden - Carica nel Cargo - カーゴに積み込み + Carica nel carico + 貨物室へ積載 裝載到貨物中 装载到货物中 화물 싣기 Załaduj do ładunku Загрузить в отсек + Carregar na carga + Naložit do nákladového prostoru + Charger dans le véhicule + Cargar en la carga + + + Unload from cargo + Aus Frachtraum ausladen + Scarica dal carico + 貨物室から降ろす + 화물 내리기 + Выгрузить из отсека + Décharger de la cargaison + Descargar de la carga Toggle NVGs Nachtsichtgeräte Hinzufügen/Entfernen - Basculer JVN - Attiva NVGs + Commuter JVN + Attiva NVG 暗視装置の切り替え 切換夜視鏡 - 切换夜视镜 + 切换夜视仪 야시경 토글 Przełącz NVG - Вкл/Выкл ПНВ + Переключить ПНВ + Alternar Visão Noturna + Přepnout noktovizory + Alternar visión nocturna NVG Equipment Nachtsichtgeräte - Equipment de vision nocturne + Équipement JVN Attrezzatura NVG 暗視装置 夜視鏡裝備 - 夜视镜装备 + 夜视仪装备 야시경 장비 Ekwipunek NVG Приборы ночного видения + Equipamento de Visão Noturna + Noktovizory - vybavení + Gece Görüşü Ekipmanı + Equipamiento de visión nocturna Add or remove NVGs from units Nachtsichtgeräte Hinzufügen/Entfernen - Ajouter ou retirer JVN des unités - Aggiunge o rimuove NVGs alle unità - ユニットから暗視装置の追加と削除 + Ajoute ou retire l'équipement de vision nocturne aux unités. + Aggiunge o rimuove NVG alle unità + ユニットの暗視装置を追加または削除します 增加或移除單位的夜視鏡 - 增加或移除单位的夜视镜 + 增加或移除单位的夜视仪 야시경 추가/제거 Dodaj lub usuń noktowizję z jednostek Добавить/Убрать ПНВ у юнитов + Adiciona ou remove visão noturna de unidades + Přidat nebo odebrat noktovizory jednotkám + Gece Görüşü ekle veya kaldır + Añadir o eliminar visión nocturna de las unidades Toggle Target Ziel umschalten - 目標を切り替え + 切り替えの対象 切换目标 切換目標 - Scambia obiettivo + Imposta Bersaglio Przełącz cel Кому переключить + Alternar alvo + Objetivo de palanca + Přepnout cíl + Unités cible + 타겟 토글 Units affected by the toggle Betroffene Spieler beim umschalten - ユニットは切り替えに影響を受けます - 被选单位受切换影响 + 切り替えの影響を受ける対象 + 被菜单位受切换影响 受切換所影響的單位 - Unità influenzate dallo scambio + Unità influenzate dall'impostazione Jednostki pod wpływem przełączenia Юниты, к которым применяется переключение + Unidades afetadas pela alteração + Jednotky ovlivněné přepnutím + Unités affectées par le changement. + Unidades afectadas por esta alternancia + 유닛은 토글에 영향받습니다 Selected Group @@ -1189,83 +1428,108 @@ 그룹 선택 Wybrana grupa Выбранная группа + Grupo Selecionado + Vybraná skupina + Seçilen Grup + Grupo seleccionado Toggle Flashlights Ändere Taschenlampen - Basculer lampes torches - Attiva torce + Commuter lampes torches + Attiva Torce フラッシュライトの切り替え 切換手電筒 切换手电筒 손전등 토글 Przełącz latarki - Вкл/Выкл Фонари + Переключить фонари + Alternar Lanternas + Alternar linternas + Přepnout svítilny + Feneriı Aç/Kapat Flashlights Taschenlampe - Lampe torche - Torcia + Lampes torches + Torce フラッシュライト 手電筒 手电筒 손전등 Latarki Фонари + Lanternas + Linternas + Svítilny + Fenerler Add Gear Ausrüstung hinzufügen - Ajouter équipement - Aggiungi equipaggiamento - 装備を追加 + Ajouter du matériel + Aggiungi Equipaggiamento + 装備の追加 增加裝備 增加装备 장비 추가 Dodaj wyposażenie Добавить снаряжение + Adicionar equipamento + Přidat vybavení + Tekerlek Ekle + Añadir equipamiento Garrison Group Gebäude besetzen Garnir zone - 歩哨グループ - Proteggi gruppo + グループの駐屯 + Barrica Gruppo 佈置駐軍 布置驻军 그룹 주둔 Rozmieść grupę w garnizonie Разместить группу в здании + Guarnecer grupo + Umístit posádku (jednotka) + Guarnicionar grupo Fill from top to bottom Von oben nach unten befüllen Remplir de haut en bas - 上から下まで占拠 + 上から下へと占拠 Riempi dall'alto al basso 由上而下進行填滿 由上而下进行填满 위에서부터 채우기 Wypełnij od góry do dołu Занять здание сверху до низу + Preencher de cima para baixo + Naplnit odshora dolů + Rellenar de arriba hacia abajo 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 + Les bâtiments se remplissent en commençant par le haut. 建物を最も高い位置から占拠していきます - Riempi gli edifici dalla posizione più alta prima + Riempi gli edifici prima dalla posizione più alta 從建築物的最高點開始布置衛哨 从建筑物的最高点开始布置卫哨 건물의 높은 위치부터 먼저 채움 Wypełnij budynki zaczynając od najwyższej pozycji Занять здание начиная с верхних позиций + Preencher construções do lugar mais alto primeiro + Naplní nejdříve nejvyšší pozice v budovách + Rellenar edificios comenzando por la posición más elevada Building filling mode Gebäude befüllen - Mode de remplissage de bâtiment + Mode de remplissage des bâtiments 建物占拠モード Modalità riempimento edifici 駐軍填充建築物模式 @@ -1273,35 +1537,44 @@ 건물 채우기 모드 Tryb wypełniania budynków Режим заполнения здания + Modo de preenchimento da construção + Režim plnění budov + Modo de rellenar edificios Even filling Gleichmäßig befüllen - Remplissage égal + Remplissage homogène 均一に占拠 - Riempimento uguale + Riempimento omogeno 平均分配 平均分配 평균 채우기 Równe wypełnienie Равномерно + Preenchimento equilibrado + Rovnoměrné plnění + Rellenado equilibrado Building by building Gebäude nach Gebäude Bâtiment par bâtiment - 建物から建物へ + 建物ごとに Edificio per edificio 一棟填滿後再換下一棟 一栋填满后再换下一栋 건물에서 건물로 Budynek za budynkiem Здание за зданием + Construção por construção + Budova za budovou + Edificio a edificio Random filling Zufällig füllen - Remplir au hasard + Remplissage aléatoire ランダムに占拠 Riempimento casuale 隨機分配 @@ -1309,46 +1582,57 @@ 무작위 채우기 Losowe wypełnienie Случайно + Preenchimento aleatório + Náhodné plnění + Rellenado aleatorio Teleport Teleportieren Téléporter テレポート - Teletrasporto + Teletrasporta 傳送 传送 순간이동 Teleport Телепорт + Teleportar + Teletransporte + Teleportovat + Işınla Un-garrison Group Garnisionsgruppe auflösen Dégarnir zone - 非歩哨グループ - Non proteggere gruppo + グループの駐屯解除 + Sbarrica Gruppo 解除駐軍駐守狀態 解除驻军驻守状态 주둔해제 Cofnij rozmieszczenie grupu w garnizonie Вывести группу из здания + Desguarnecer grupo + Zrušit posádku - uvolnit jednotku + Desaguarnicionar grupo No players found 沒有玩家找到 没有玩家找到 - Nije pronađen nijedan igrač - Aucun joueur trouvé + Nenalezen žádný hráč + Aucun joueur trouvé. Keine Spieler gefunden Nincsenek játékosok Nessun giocatore trovato - プレーヤーが見つかりません + プレーヤーが見つかりませんでした 플레이어가 없습니다. Nie znaleziono graczy Nenhum jogador encontrado Игроки не найдены No se encontraron jugadores + Kullanıcı bulunamadı Assign Repair Vehicle @@ -1359,60 +1643,64 @@ Fahrzeug reparieren zuweisen Hozzárendelés javítóműhöz Assegna veicolo di riparazione - 修理車両を割り当てる + 修理車両に割り当て 수리 차량 지정 Przydziel pojazd do naprawy - Atribuir veículo de reparação + Definir como veículo de reparo Назначить ремонтный автомобиль Asignar vehículo de reparación + Tamir Aracı Yap Assign Repair Facility 分配修理設施 分配修理设施 Přiřaďte opravu - Affecter une installation de réparation + Affecter un atelier de réparation Zuweisen von Reparatureinrichtung Hozzárendelés javításhoz Assegna struttura di riparazione - 修理施設を割り当てる + 修理施設に割り当て 수리 시설 지정 Przydziel naprawę - Atribuir facilidade de reparação + Definir como oficina de reparo Назначить ремонтный комплекс Asignar instalación de reparación + Tamir Tesisi Yap Assign Engineer 指派工程師 指派工程师 Přiřadit inženýra - Affecter ingénieur + Assigner ingénieur Engineer zuweisen Engedélyezze a mérnököt - Assign Engineer - 担当エンジニア + Assegna Geniere + 工兵に割り当て 엔지니어 지정 Przydziel inżyniera - Encarregar o engenheiro + Definir como engenheiro Назначить инженера Asignar Ingeniero + Mühendis yap Engineer Skill 工程師技能 工程师技能 Inženýrská dovednost - Compétence d'ingénieur + Qualification technique Ingenieur Fähigkeit Mérnöki készség - Abilità ingegnere - エンジニアのスキル + Abilità Geniere + 工兵のスキル 기술자의 기술 Umiejętność inżyniera Habilidade do engenheiro Инженерное мастерство Habilidad de Ingeniero + Mühendislik yeteneği Full Heal @@ -1423,104 +1711,110 @@ Vollständige Heilung Teljes gyógyítás Guarigione completa - 完全に回復 + 完全回復 완전 치유 Pełne uleczenie Cura completa Полное исцеление Totalmente curado + Full Can Suicide Bomber 自殺式炸彈襲擊者 - 自杀式炸弹袭击者 + 自杀炸弹手 Samovražedný bombardér Kamikaze Selbstmordattentäter Öngyilkos merénylő Kamikaze - 自爆テロ犯 + 自爆兵化 자살 폭탄 Samobójca Bombardeiro suicida Террорист-смертник Bombardeo suicida + Intihar Bombacısı Activation Side 激活方 激活方 Aktivační strana - Activation latérale + Camp cible Aktivierungsseite Aktiválási oldal - Lato di attivazione + Fazione Bersaglio 対象陣営 - 활성화면 + 활성화 진영 Strona aktywacji - Lado de ativação + Explodir em: Сторона активации Lado de activación + Aktivasyon tarafı Activation Radius 激活半徑 激活半径 Aktivační poloměr - Rayon d'activation + Rayon de déclenchement Aktivierungsradius Aktiválási sugár - Raggio di attivazione + Raggio di Attivazione 活性化半径 활성화 반경 Promień aktywacji - Rádio de ativação + Raio de ativação Радиус активации Radio de activación + Aktivasyon yarıçapı Explosion Size 爆炸尺寸 - 爆炸尺寸 + 爆炸大小 Velikost výbuchu - Taille d'explosion + Taille de l'explosion Explosionsgröße Robbanásméret - Dimensione di esplosione + Dimensione dell'Esplosione 爆発サイズ 폭발 크기 Rozmiar wybuchu Tamanho da Explosão Размер взрыва Tamaño de Explosión + Patlama boyutu Auto Seek 自動尋求 - 自动寻求 + 自动寻的 Auto Seek Recherche automatique Automatische Suche Automatikus keresés - Ricerca automatica + Ricerca Automatica 自動誘導 자동 탐색 Auto Seek - Busca automática + Buscar alvos automaticamente Автоматический поиск Búsqueda automática + Otomatik arama Unit will actively try to find and move towards nearby units of the activation side. The range of Auto Seek is based on the unit's spot distance skill with a minimum of 100 meters. 單位將主動嘗試尋找並移動到附近的激活方單位。自動搜索的範圍是基於單位的距離技能,最少100米 单位将主动尝试寻找并移动到附近的激活方单位。自动搜索的范围是基于单位的距离技能,最少100米。 Jednotka se bude aktivně snažit najít a přejít na blízké jednotky na straně aktivace. Rozsah Auto Seek je založen na dovednosti spotové vzdálenosti jednotky s minimem 100 metrů. - L'unité essayera activement de trouver et de se déplacer vers les unités à proximité du côté d'activation. La portée d'Auto Seek est basée sur la compétence de distance de l'unité avec un minimum de 100 mètres. + L'unité essaiera de trouver activement des unités proches appartenant à au camp cible, puis elle se déplacera dans leur direction.\nLa portée de la recherche automatique est basée sur l'aptitude en repérage de l'unité, avec une distance minimale de 100 mètres. Die Einheit versucht aktiv, in der Nähe befindliche Einheiten der Aktivierungsseite zu finden und sich dorthin zu bewegen. Der Bereich der automatischen Suche basiert auf der Fähigkeit der Zielentfernung der Einheit mit einer Mindestentfernung von 100 Metern. Az egység aktívan megpróbálja megtalálni és elmozdulni az aktivációs oldal közeli egységei felé.Az automatikus keresési tartomány az egység helyszíni szakértelmén alapul, legalább 100 méterrel. - L'unità cercherà attivamente di trovare e spostarsi verso le unità vicine del lato di attivazione. La gamma di Auto Seek si basa sull'abilità a distanza spot dell'unità con un minimo di 100 metri. - 対象陣営ユニットを見つけて移動しようと積極的に試みます。自動誘導の範囲は、ユニットの索敵能力に基づいており、最低100メートルです。 - 유닛은 액티브 측의 근접 유닛을 향해 적극적으로 찾아서 이동하려고 시도합니다. 자동 시크의 범위는 유닛의 스팟 거리 스킬을 기준으로 최소 100 미터입니다. + L'unità cercherà attivamente di trovare e spostarsi verso unità vicine della fazione bersaglio. La distanza di Ricerca Automatica si basa sull'abilità di identificazione dell'unità, con un minimo di 100 metri. + 対象陣営ユニットを見つけて移動しようと積極的に試みます。自動誘導の半径は、ユニットの索敵能力に基づいており、最低100メートルです。 + 유닛은 활성화 측의 근접 유닛을 향해 적극적으로 찾아서 이동하려고 시도합니다. 자동 탐색의 범위는 유닛의 색적 거리 스킬을 기준으로 최소 100미터입니다. Jednostka będzie aktywnie próbowała znaleźć i ruszyć w kierunku pobliskich jednostek strony aktywacji. Zasięg Auto Seek opiera się na umiejętności punktowej odległości jednostki z minimum 100 metrów. A unidade tentará ativamente encontrar e se mover para as unidades próximas do lado da ativação. O alcance da Auto Seek é baseado na habilidade de distância do ponto da unidade com um mínimo de 100 metros. Устройство будет активно пытаться найти и перейти к соседним единицам активации. Диапазон автоматического поиска основан на умении снимать расстояние на расстоянии не менее 100 метров. @@ -1531,52 +1825,81 @@ 這個單位已經是自殺炸彈手了 这个单位已经是自杀炸弹手了 Jednotka je již samovražedným bombardérem - L'unité est déjà un kamikaze + L'unité est déjà un kamikaze. Die Einheit ist bereits ein Selbstmordattentäter Az egység már öngyilkos bombázó L'unità è già un kamikaze - 既に自爆ユニットです - 유닛은 이미 자살 폭탄 테러범이다. + ユニットは既に自爆兵です + 유닛은 이미 자살 폭탄 테러범입니다. Jednostka jest już zamachowcem-samobójcą A unidade já é um suicida Единица уже является террористом-смертником La unidad ya es un terrorista suicida + Kişi zaten bir intihar bombacısı Add full ACE Arsenal Vollständiges ACE Arsenal hinzufügen ACE 武器庫を追加 - 添加ACE模式军火库 + 添加 ACE 军火库 增加完整的ACE軍火庫 - Aggiungi l'arsenale ACE completo + Aggiungi Arsenale ACE Completo Dodaj pełny arsenał ACE Добавить полный ACE Арсенал + Adicionar Arsenal ACE Completo + Añadir ACE Arsenal completo + Přidat plný ACE Arzenál + Ajouter arsenal ACE complet + ACE Arsenal ekle + 전체 ACE 아스널 추가 Remove ACE Arsenal ACE Arsenal entfernen ACE 武器庫を削除 - 删除ACE模式军火库 + 删除 ACE 军火库 移除ACE軍火庫 - Rimuovi l'arsenale ACE + Rimuovi Arsenale ACE Usuń arsenał ACE Убрать ACE Арсенал + Remover Arsenal ACE + Eliminar ACE Arsenal + Odebrat plný ACE Arzenál + Retirer un arsenal ACE + ACE Arsenali sil + 전체 ACE 아스널 제거 Create Zeus Zeus erstellen Создать Зевса - Zeus を作る + Zeus を作成 Stwórz Zeus'a Crea Zeus + Criar Zeus + Crear Zeus + 新增宙斯 + 创建宙斯 + Vytvořit Zeuse + Créer Zeus + Zeus oluştur + 제우스 생성 Delete Zeus Zeus löschen Удалить Зевса - Zeus を消す + Zeus を削除 Usuń Zeus'a Cancella Zeus + Apagar Zeus + Eliminar Zeus + 刪除宙斯 + 删除宙斯 + Smazat Zeuse + Supprimer Zeus + Zeus sil + 제우스 제거 "%1" menu @@ -1585,20 +1908,162 @@ "%1" メニュー "%1" menu menu "%1" + Menu "%1" + 選單 %1 + 菜单"%1" + "%1" menu + Menu "%1" + "%1" menü + "%1" menu + "%1" 메뉴 Paradrop Cargo - Paradrop Ladung - カーゴを空中投下 + Ladung abwerfen (Fallschirm) + 貨物を空中投下 Zrzut ładunku (cargo) Десантировать груз + Soltar carga de paraquedas + 空投貨物 + 空投货物 + Paracaduta Carico + Výsadek nákladu + Paralargage de cargaison + Paraşüt Kargosu + Carga mediante paracaidas + 화물 공수 No cargo loaded Keine Ladung geladen - カーゴは未積載 + 貨物は積載されていません Niczego nie załadowano do cargo Грузовой отсек пуст + Nenhuma carga carregada + No hay carga cargada + 沒有貨物裝載 + 没有装载货物 + Nessun carico caricato + Žádný náklad není naložen + Aucune cargaison chargée + Kargo yüklenmedi + 화물이 실려있지 않습니다 + + + Burn Unit + Einheit anzünden + 焚烧单位 + Incendia Unità + 유닛 불로 태우기 + Podpal Jednostkę + ユニットを燃やす + Поджечь юнита + Quemar a unidad + Brûler l'unité + + + Medical Menu + Sanitätsmenü + Menu medyczne + Menu Médico + Медицинское меню + Menú médico + Zdravotnická nabídka + Menù Medico + Menu médical + 医療メニュー + 의료 메뉴 + 医疗菜单 + 醫療選單 + Medikal Menü + + + The medical menu is disabled + Das Sanitätsmenü ist deaktiviert + Il Menù Medico è disabilitato + 医療メニューは無効になっています + 의료 메뉴가 비활성화되었습니다 + Медицинское меню отключено + Le Menu médical est désactivé + El menú médico está deshabilitado + + + Lay Trenchline + Wykop Okop + 참호라인 깔기 + Poser une tranchée + Grabenlinie legen + Piazza Trincea + 塹壕溝線を敷設 + Проложить траншею + Poner una Trinchera + + + +SHIFT to force (Can only lay N/S or E/W) + +SHIFT aby wymusić (Można wykopać tylko N/S lub E/W) + + Shift 키로 강제하기 (동서남북 방향으로만 깔 수 있음) + +MAJ pour forcer (Disponible uniquement sur les alignements N/S ou E/O) + +SHIFT zum Erzwingen (Kann nur nach N/S oder E/W legen) + +SHIFT per forzare (Può piazzare solo N/S o E/O) + +SHIFTキー で強制的に敷設 (北/南または東/西方向にのみ配置可能) + +SHIFT на принудительное (может укладываться только на Север/Юг или Восток/Запад) + +SHIFT para forzar (Puede solo colocar en N/S or E/O) + + + Forces the spectator interface preventing the player from closing it with the Escape key + 観戦インターフェイスを強制し、ユーザーがEscキーでも閉じられないようにします。 + Активирует интерфейс spectator, не позволяя игроку закрыть его с помощью клавиши Escape. + 플레이어가 Esc 키로 관전자 인터페이스를 닫지 못하도록 강제로 관전자 인터페이스를 설정합니다. + Erzwingt die Zuschauer-Ansicht und verhindert dass der Spieler sie mit der Esc-Taste schließen kann + Forza l'interfaccia di spettatore, impedendo al giocatore di chiuderla con il tasto Esc + + + Hide player + プレイヤーを隠す + Скрыть игрока + 플레이어 숨기기 + Spieler ausblenden + Nascondi giocatore + + + Hides the player by making them invisible, invulnerable, muted, and removing them from their group + 透明化、無敵化、ミュート、グループからの除外を行いプレーヤーを隠します + Скрывает игрока, делая его невидимым, неуязвимым, отключая звук и удаляя из группы. + 플레이어를 투명, 무적, 음소거화하고 그룹에서 제거하여 숨깁니다. + Blendet den Spieler aus, macht ihn unsichtbar, unverwundbar, stumm und entfernt ihn von seiner Gruppe + Nasconde il giocatore, rendendolo invisibile, invulnerabile, muto e lo rimuove dal proprio gruppo + + + Sets the sides that are available to spectate + 指定の陣営を観戦可能に設定します + Устанавливает стороны, доступные для режима spectator + 관전 가능한 진영을 설정합니다. + Bestimmt die Seiten denen man zuschauen kann + Imposta le fazioni che lo spettatore può osservare + + + White Hot + 白=熱源 + Белый + 백색 열원 + Weiß-Schwarz + Bianco-caldo + + + Black Hot + 黒=熱源 + Чёрный + 흑색 열원 + Schwarz-Weiß + Nero-caldo + + + Toggle All + 全てを切り替え + Выключить все + 전부 토글 + Alle wechseln + Cambia tutti diff --git a/addons/zeus/ui/Icon_Module_Zeus_Burn_ca.paa b/addons/zeus/ui/Icon_Module_Zeus_Burn_ca.paa new file mode 100644 index 0000000000..b76c33f1b5 Binary files /dev/null and b/addons/zeus/ui/Icon_Module_Zeus_Burn_ca.paa differ diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 1174267466..da3f53364f 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -1,7 +1,7 @@ class RscControlsGroup; class RscControlsGroupNoScrollbars; class RscText; -class RscListbox; +class RscListBox; class RscCombo; class RscEdit; class RscXSliderH; @@ -29,33 +29,33 @@ class GVAR(AttributeRadius): RscControlsGroupNoScrollbars { idc = 26466; x = 0; y = 0; - w = W_PART(26); - h = H_PART(1.1); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1.1)); class controls { class Label: RscText { idc = -1; text = CSTRING(AttributeRadius); tooltip = CSTRING(AttributeRadius_Tooltip); x = 0; - y = H_PART(0.1); - w = W_PART(10); - h = H_PART(1); + y = QUOTE(H_PART(0.1)); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class Radius: RscEdit { idc = 26467; - x = W_PART(10.1); - y = H_PART(0.1); - w = W_PART(15.9); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(0.1)); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); autocomplete = ""; }; }; }; class GVAR(RscDefendArea): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscDefendArea))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscDefendArea))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscDefendArea))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscDefendArea))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -72,8 +72,8 @@ class GVAR(RscDefendArea): RscDisplayAttributes { }; class GVAR(RscEditableObjects): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscEditableObjects))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscEditableObjects))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscEditableObjects))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscEditableObjects))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -85,8 +85,8 @@ class GVAR(RscEditableObjects): RscDisplayAttributes { idc = 19180; x = 0; y = 0; - w = W_PART(26); - h = H_PART(3.2); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.2)); class controls { class EditingModeLabel: RscText { idc = -1; @@ -94,16 +94,16 @@ class GVAR(RscEditableObjects): RscDisplayAttributes { tooltip = CSTRING(ModuleEditableObjects_EditingMode_Tooltip); x = 0; y = 0; - w = W_PART(10); - h = H_PART(1); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class EditingMode: ctrlToolbox { idc = 19181; - x = W_PART(10.1); + x = QUOTE(W_PART(10.1)); y = 0; - w = W_PART(15.9); - h = H_PART(1); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); rows = 1; columns = 2; strings[] = {CSTRING(ModuleEditableObjects_RemoveObjects), CSTRING(ModuleEditableObjects_AddObjects)}; @@ -111,21 +111,21 @@ class GVAR(RscEditableObjects): RscDisplayAttributes { class AllCuratorsLabel: EditingModeLabel { text = CSTRING(ModuleEditableObjects_AllCurators); tooltip = CSTRING(ModuleEditableObjects_AllCurators_Tooltip); - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class AllCurators: EditingMode { idc = 19182; - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; }; class AdditionalObjectsLabel: EditingModeLabel { text = CSTRING(ModuleEditableObjects_AdditionalObjects); tooltip = CSTRING(ModuleEditableObjects_AdditionalObjects_Tooltip); - y = H_PART(2.2); + y = QUOTE(H_PART(2.2)); }; class AdditionalObjects: EditingMode { idc = 19183; - y = H_PART(2.2); + y = QUOTE(H_PART(2.2)); columns = 3; strings[] = {CSTRING(None), CSTRING(Players), CSTRING(PlayersAndAI)}; }; @@ -139,8 +139,8 @@ class GVAR(RscEditableObjects): RscDisplayAttributes { }; class GVAR(RscGlobalSetSkill): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscGlobalSetSkill))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscGlobalSetSkill))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscGlobalSetSkill))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscGlobalSetSkill))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -151,8 +151,8 @@ class GVAR(RscGlobalSetSkill): RscDisplayAttributes { idc = 26422; x = 0; y = 0; - w = W_PART(26); - h = H_PART(6.5); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(6.5)); class controls { class Title1: RscText { idc = -1; @@ -160,69 +160,69 @@ class GVAR(RscGlobalSetSkill): RscDisplayAttributes { toolTip = CSTRING(ModuleGlobalSetSkill_general_desc); x = 0; y = 0; - w = W_PART(10); - h = H_PART(1); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0,0,0,0.5}; }; class General: RscXSliderH { idc = 16184; - x = W_PART(10.1); + x = QUOTE(W_PART(10.1)); y = 0; - w = W_PART(15.9); - h = H_PART(1); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); }; class Title2: Title1 { idc = -1; text = CSTRING(ModuleGlobalSetSkill_accuracy); toolTip = CSTRING(ModuleGlobalSetSkill_accuracy_desc); - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class Accuracy: General { idc = 16185; - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class Title3: Title1 { idc = -1; text = CSTRING(ModuleGlobalSetSkill_handling); toolTip = CSTRING(ModuleGlobalSetSkill_handling_desc); - y = H_PART(2.2); + y = QUOTE(H_PART(2.2)); }; class Handling: General { idc = 16186; - y = H_PART(2.2); + y = QUOTE(H_PART(2.2)); }; class Title4: Title1 { idc = -1; text = CSTRING(ModuleGlobalSetSkill_spotting); toolTip = CSTRING(ModuleGlobalSetSkill_spotting_desc); - y = H_PART(3.3); + y = QUOTE(H_PART(3.3)); }; class Spotting: General { idc = 16187; - y = H_PART(3.3); + y = QUOTE(H_PART(3.3)); }; class Title5: Title1 { idc = -1; text = CSTRING(ModuleGlobalSetSkill_cover); toolTip = CSTRING(ModuleGlobalSetSkill_cover_desc); - y = H_PART(4.4); + y = QUOTE(H_PART(4.4)); }; class Cover: RscCheckBox { idc = 16188; - x = W_PART(10.1); - y = H_PART(4.4); - w = W_PART(1); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(4.4)); + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); }; class Title6: Title5 { idc = -1; text = CSTRING(ModuleGlobalSetSkill_combat); toolTip = CSTRING(ModuleGlobalSetSkill_combat_desc); - y = H_PART(5.5); + y = QUOTE(H_PART(5.5)); }; class Combat: Cover { idc = 16189; - y = H_PART(5.5); + y = QUOTE(H_PART(5.5)); }; }; }; @@ -234,8 +234,8 @@ class GVAR(RscGlobalSetSkill): RscDisplayAttributes { }; class GVAR(RscGroupSide): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscGroupSide))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscGroupSide))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscGroupSide))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscGroupSide))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -246,60 +246,60 @@ class GVAR(RscGroupSide): RscDisplayAttributes { idc = 26422; x = 0; y = 0; - w = W_PART(26); - h = H_PART(2.5); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); class controls { class Title: RscText { idc = 31002; text = "$STR_disp_arcunit_side"; x = 0; y = 0; - w = W_PART(10); - h = H_PART(2.5); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); colorBackground[] = {0,0,0,0.5}; }; class Background: RscText { idc = 31000; - x = W_PART(10); + x = QUOTE(W_PART(10)); y = 0; - w = W_PART(16); - h = H_PART(2.5); + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); colorBackground[] = {1,1,1,0.1}; }; class BLUFOR: RscActivePicture { idc = 31200; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; - x = W_PART(12.5); - y = H_PART(0.25); - w = W_PART(2); - h = H_PART(2); + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); tooltip = "$STR_WEST"; }; class OPFOR: BLUFOR { idc = 31201; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; - x = W_PART(15.5); - y = H_PART(0.25); - w = W_PART(2); - h = H_PART(2); + x = QUOTE(W_PART(15.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); tooltip = "$STR_EAST"; }; class Independent: BLUFOR { idc = 31202; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; - x = W_PART(18.5); - y = H_PART(0.25); - w = W_PART(2); - h = H_PART(2); + x = QUOTE(W_PART(18.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); tooltip = "$STR_guerrila"; }; class Civilian: BLUFOR { idc = 31203; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; - x = W_PART(21.5); - y = H_PART(0.25); - w = W_PART(2); - h = H_PART(2); + x = QUOTE(W_PART(21.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); tooltip = "$STR_Civilian"; }; }; @@ -312,8 +312,8 @@ class GVAR(RscGroupSide): RscDisplayAttributes { }; class GVAR(RscPatrolArea): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscPatrolArea))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscPatrolArea))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscPatrolArea))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscPatrolArea))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -330,8 +330,8 @@ class GVAR(RscPatrolArea): RscDisplayAttributes { }; class GVAR(RscSearchArea): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscSearchArea))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscSearchArea))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSearchArea))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSearchArea))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -348,8 +348,8 @@ class GVAR(RscSearchArea): RscDisplayAttributes { }; class GVAR(RscTeleportPlayers): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscTeleportPlayers))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscTeleportPlayers))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscTeleportPlayers))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscTeleportPlayers))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -360,8 +360,8 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { idc = 26422; x = 0; y = 0; - w = W_PART(26); - h = H_PART(8.1); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(8.1)); class controls { class Title: RscText { idc = -1; @@ -369,55 +369,55 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { toolTip = CSTRING(ModuleTeleportPlayers_player_desc); x = 0; y = 0; - w = W_PART(26); - h = H_PART(1); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; - class Unit: RscListbox { + class Unit: RscListBox { idc = 16189; x = 0; - y = H_PART(1.1); - w = W_PART(26); - h = H_PART(5.9); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(5.9)); }; class SearchBackground: RscText { idc = -1; x = 0; - y = H_PART(7.1); - w = W_PART(1); - h = H_PART(1); + y = QUOTE(H_PART(7.1)); + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class SearchPicture: RscPicture { idc = -1; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; x = 0; - y = H_PART(7.1); - w = W_PART(1); - h = H_PART(1); + y = QUOTE(H_PART(7.1)); + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); }; class Search: RscEdit { idc = 16190; - x = W_PART(1.2); - y = H_PART(7.1); - w = W_PART(14.5); - h = H_PART(1); + x = QUOTE(W_PART(1.2)); + y = QUOTE(H_PART(7.1)); + w = QUOTE(W_PART(14.5)); + h = QUOTE(H_PART(1)); autocomplete = ""; }; class LabelGroup: Title { idc = -1; text = CSTRING(ModuleTeleportPlayers_group); toolTip = CSTRING(ModuleTeleportPlayers_group_desc); - x = W_PART(15.9); - y = H_PART(7.1); - w = W_PART(9); + x = QUOTE(W_PART(15.9)); + y = QUOTE(H_PART(7.1)); + w = QUOTE(W_PART(9)); }; class UseGroup: RscCheckBox { idc = 16188; - x = W_PART(25); - y = H_PART(7.1); - w = W_PART(1); - h = H_PART(1); + x = QUOTE(W_PART(25)); + y = QUOTE(H_PART(7.1)); + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); }; }; }; @@ -431,42 +431,42 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { class GVAR(AttributeCargo): RscControlsGroupNoScrollbars { onSetFocus = QUOTE(_this call FUNC(ui_attributeCargo)); idc = -1; - x = X_PART(7); - y = Y_PART(10); - w = W_PART(26); - h = H_PART(3); + x = QUOTE(X_PART(7)); + y = QUOTE(Y_PART(10)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3)); class controls { class Title: RscText { idc = -1; text = CSTRING(AttributeCargo); x = 0; y = 0; - w = W_PART(10); - h = H_PART(2); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2)); colorBackground[] = {0,0,0,0.5}; }; class Background: RscText { idc = -1; - x = W_PART(10); + x = QUOTE(W_PART(10)); y = 0; - w = W_PART(16); - h = H_PART(3); + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(3)); colorBackground[] = {1,1,1,0.1}; }; class Cargo: RscListBox { idc = 80086; - x = W_PART(10); + x = QUOTE(W_PART(10)); y = 0; - w = W_PART(16); - h = H_PART(3); + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(3)); }; class Unload: RscButton { idc = 80087; text = ECSTRING(cargo,unloadObject); x = 0; - y = H_PART(2); - w = W_PART(10); - h = H_PART(1); + y = QUOTE(H_PART(2)); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.7}; }; }; @@ -475,7 +475,7 @@ class GVAR(AttributeCargo): RscControlsGroupNoScrollbars { class RscDisplayAttributesVehicle: RscDisplayAttributes { class Controls: Controls { class Content: Content { - class Controls: controls { + class controls: controls { class ace_cargo: GVAR(AttributeCargo) { }; }; }; @@ -485,7 +485,7 @@ class RscDisplayAttributesVehicle: RscDisplayAttributes { class RscDisplayAttributesVehicleEmpty: RscDisplayAttributes { class Controls: Controls { class Content: Content { - class Controls: controls { + class controls: controls { class ace_cargo: GVAR(AttributeCargo) { }; }; }; @@ -493,8 +493,8 @@ class RscDisplayAttributesVehicleEmpty: RscDisplayAttributes { }; class GVAR(RscGarrison): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscGarrison))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscGarrison))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscGarrison))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscGarrison))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -506,24 +506,24 @@ class GVAR(RscGarrison): RscDisplayAttributes { idc = 73060; x = 0; y = 0; - w = W_PART(26); - h = H_PART(6.2); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(6.2)); class controls { class TeleportLabel: RscText { idc = -1; text = CSTRING(ModuleGarrison_TeleportText); x = 0; y = 0; - w = W_PART(10); - h = H_PART(1); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class Teleport: ctrlToolbox { idc = 73061; - x = W_PART(10.1); + x = QUOTE(W_PART(10.1)); y = 0; - w = W_PART(15.9); - h = H_PART(1); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); rows = 1; columns = 2; strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; @@ -531,23 +531,23 @@ class GVAR(RscGarrison): RscDisplayAttributes { class TopDownLabel: TeleportLabel { text = CSTRING(ModuleGarrison_TopDownFillingText); tooltip = CSTRING(ModuleGarrison_TopDownFillingTooltip); - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class TopDown: Teleport { idc = 73062; - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class FillingModeLabel: TeleportLabel { text = CSTRING(ModuleGarrison_FillingModeText); - y = H_PART(2.2); - w = W_PART(26); + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(26)); }; - class FillingMode: RscListbox { + class FillingMode: RscListBox { idc = 73063; x = 0; - y = H_PART(3.2); - w = W_PART(26); - h = H_PART(3); + y = QUOTE(H_PART(3.2)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3)); class Items { class Even { text = CSTRING(ModuleGarrison_FillingModeEven); @@ -571,8 +571,8 @@ class GVAR(RscGarrison): RscDisplayAttributes { }; class GVAR(RscToggleNvg): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscToggleNvg))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscToggleNvg))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscToggleNvg))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscToggleNvg))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -583,8 +583,8 @@ class GVAR(RscToggleNvg): RscDisplayAttributes { idc = 92854; x = 0; y = 0; - w = W_PART(26); - h = H_PART(2.1); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.1)); class controls { class ToggleLabel: RscText { idc = -1; @@ -592,16 +592,16 @@ class GVAR(RscToggleNvg): RscDisplayAttributes { tooltip = CSTRING(ModuleToggleNVG_NvgEquipment_tooltip); x = 0; y = 0; - w = W_PART(10); - h = H_PART(1); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class Toggle: ctrlToolbox { idc = 92855; - x = W_PART(10.1); + x = QUOTE(W_PART(10.1)); y = 0; - w = W_PART(15.9); - h = H_PART(1); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); rows = 1; columns = 2; strings[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled)}; @@ -609,14 +609,14 @@ class GVAR(RscToggleNvg): RscDisplayAttributes { class TargetLabel: ToggleLabel { text = CSTRING(ToggleTarget); tooltip = CSTRING(ToggleTarget_Tooltip); - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class Target: RscCombo { idc = 92856; - x = W_PART(10.1); - y = H_PART(1.1); - w = W_PART(15.9); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.7}; class Items { class Group { @@ -652,8 +652,8 @@ class GVAR(RscToggleNvg): RscDisplayAttributes { }; class GVAR(RscToggleFlashlight): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscToggleFlashlight))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscToggleFlashlight))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscToggleFlashlight))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscToggleFlashlight))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -664,48 +664,48 @@ class GVAR(RscToggleFlashlight): RscDisplayAttributes { idc = 56217; x = 0; y = 0; - w = W_PART(26); - h = H_PART(3.2); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.2)); class controls { class ToggleLabel: RscText { idc = -1; text = CSTRING(ModuleToggleFlashlight_Flashlights); x = 0; y = 0; - w = W_PART(10); - h = H_PART(1); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class Toggle: ctrlToolbox { idc = 56218; - x = W_PART(10.1); + x = QUOTE(W_PART(10.1)); y = 0; - w = W_PART(15.9); - h = H_PART(1); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); rows = 1; columns = 2; strings[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled)}; }; class AddGearLabel: ToggleLabel { text = CSTRING(ModuleToggleFlashlight_AddGear); - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); }; class AddGear: Toggle { idc = 56219; - y = H_PART(1.1); + y = QUOTE(H_PART(1.1)); strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; }; class TargetLabel: ToggleLabel { text = CSTRING(ToggleTarget); tooltip = CSTRING(ToggleTarget_Tooltip); - y = H_PART(2.2); + y = QUOTE(H_PART(2.2)); }; class Target: RscCombo { idc = 56220; - x = W_PART(10.1); - y = H_PART(2.2); - w = W_PART(15.9); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.7}; class Items { class Group { @@ -741,8 +741,8 @@ class GVAR(RscToggleFlashlight): RscDisplayAttributes { }; class GVAR(RscSetEngineer): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscSetEngineer))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscSetEngineer))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSetEngineer))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSetEngineer))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -753,25 +753,25 @@ class GVAR(RscSetEngineer): RscDisplayAttributes { idc = 86946; x = 0; y = 0; - w = W_PART(26); - h = H_PART(1.2); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1.2)); class controls { class Label: RscText { idc = -1; text = CSTRING(ModuleSetEngineer_skill); toolTip = ECSTRING(repair,AssignEngineerRole_role_Description); x = 0; - y = H_PART(0.1); - w = W_PART(10); - h = H_PART(1); + y = QUOTE(H_PART(0.1)); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class Roles: ctrlToolbox { idc = 86947; - x = W_PART(10.1); - y = H_PART(0.1); - w = W_PART(15.9); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(0.1)); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); rows = 1; columns = 2; strings[] = {ECSTRING(repair,AssignEngineerRole_role_engineer), ECSTRING(repair,AssignEngineerRole_role_advanced)}; @@ -786,8 +786,8 @@ class GVAR(RscSetEngineer): RscDisplayAttributes { }; class GVAR(RscSuicideBomber): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscSuicideBomber))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscSuicideBomber))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSuicideBomber))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSuicideBomber))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -798,58 +798,58 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { idc = 83470; x = 0; y = 0; - w = W_PART(26); - h = H_PART(5.8); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(5.8)); class controls { class ActivationSide: RscControlsGroupNoScrollbars { idc = 83571; x = 0; y = 0; - w = W_PART(26); - h = H_PART(2.5); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); class controls { class Label: RscText { idc = -1; text = CSTRING(ModuleSuicideBomber_ActivationSide); x = 0; y = 0; - w = W_PART(10); - h = H_PART(2.5); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); colorBackground[] = {0, 0, 0, 0.5}; }; class Background: RscText { idc = -1; - x = W_PART(10); + x = QUOTE(W_PART(10)); y = 0; - w = W_PART(16); - h = H_PART(2.5); + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); colorBackground[] = {1, 1, 1, 0.1}; }; class BLUFOR: RscActivePicture { idc = 83581; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; - x = W_PART(12.5); - y = H_PART(0.25); - w = W_PART(2); - h = H_PART(2); + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); tooltip = "$STR_WEST"; }; class OPFOR: BLUFOR { idc = 83580; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; - x = W_PART(15.5); + x = QUOTE(W_PART(15.5)); tooltip = "$STR_EAST"; }; class Independent: BLUFOR { idc = 83582; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; - x = W_PART(18.5); + x = QUOTE(W_PART(18.5)); tooltip = "$STR_guerrila"; }; class Civilian: BLUFOR { idc = 83583; text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; - x = W_PART(21.5); + x = QUOTE(W_PART(21.5)); tooltip = "$STR_Civilian"; }; }; @@ -858,24 +858,24 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { idc = -1; text = CSTRING(ModuleSuicideBomber_ActivationRadius); x = 0; - y = H_PART(2.6); - w = W_PART(10); - h = H_PART(1); + y = QUOTE(H_PART(2.6)); + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); colorBackground[] = {0, 0, 0, 0.5}; }; class DistanceSlider: RscXSliderH { idc = 83572; - x = W_PART(10.1); - y = H_PART(2.6); - w = W_PART(13.9); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(2.6)); + w = QUOTE(W_PART(13.9)); + h = QUOTE(H_PART(1)); }; class DistanceEdit: RscEdit { idc = 83573; - x = W_PART(24.1); - y = H_PART(2.6); - w = W_PART(1.9); - h = H_PART(1); + x = QUOTE(W_PART(24.1)); + y = QUOTE(H_PART(2.6)); + w = QUOTE(W_PART(1.9)); + h = QUOTE(H_PART(1)); autocomplete = ""; maxChars = 3; canModify = 0; @@ -883,14 +883,14 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class ExplosionLabel: DistanceLabel { idc = -1; text = CSTRING(ModuleSuicideBomber_ExplosionSize); - y = H_PART(3.7); + y = QUOTE(H_PART(3.7)); }; class Explosion: ctrlToolbox { idc = 83574; - x = W_PART(10.1); - y = H_PART(3.7); - w = W_PART(15.9); - h = H_PART(1); + x = QUOTE(W_PART(10.1)); + y = QUOTE(H_PART(3.7)); + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); rows = 1; columns = 3; strings[] = {"$STR_small", "$STR_medium", "$STR_large"}; @@ -898,12 +898,12 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class AutoSeekLabel: DistanceLabel { idc = -1; text = CSTRING(ModuleSuicideBomber_AutoSeek); - y = H_PART(4.8); + y = QUOTE(H_PART(4.8)); toolTip = CSTRING(ModuleSuicideBomber_AutoSeek_tooltip); }; class AutoSeek: Explosion { idc = 83575; - y = H_PART(4.8); + y = QUOTE(H_PART(4.8)); columns = 2; strings[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled)}; }; @@ -915,3 +915,231 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class ButtonCancel: ButtonCancel {}; }; }; + +class GVAR(RscSpectator): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class spectator: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_spectator)); + idc = 92530; + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(10.7)); + class controls { + class ForceInterfaceLabel: RscText { + idc = -1; + text = "$STR_a3_cfgvehicles_modulecurator_f_arguments_forced"; + tooltip = CSTRING(ModuleSpectator_ForceInterface_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class ForceInterface: ctrlToolbox { + idc = 92531; + x = QUOTE(W_PART(10.1)); + y = 0; + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class HidePlayerLabel: ForceInterfaceLabel { + text = CSTRING(ModuleSpectator_HidePlayer); + tooltip = CSTRING(ModuleSpectator_HidePlayer_Tooltip); + y = QUOTE(H_PART(1.1)); + }; + class HidePlayer: ForceInterface { + idc = 92532; + y = QUOTE(H_PART(1.1)); + }; + class SpectateSides: RscControlsGroupNoScrollbars { + idc = 92533; + x = 0; + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = "$STR_A3_Spectator_Eden_WhitelistedSides_Name"; + tooltip = CSTRING(ModuleSpectator_SpectableSides_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class BLUFOR: RscActivePicture { + idc = 92541; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); + tooltip = "$STR_WEST"; + }; + class OPFOR: BLUFOR { + idc = 92540; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; + x = QUOTE(W_PART(15.5)); + tooltip = "$STR_EAST"; + }; + class Independent: BLUFOR { + idc = 92542; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; + x = QUOTE(W_PART(18.5)); + tooltip = "$STR_guerrila"; + }; + class Civilian: BLUFOR { + idc = 92543; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; + x = QUOTE(W_PART(21.5)); + tooltip = "$STR_Civilian"; + }; + }; + }; + class CameraModes: RscControlsGroupNoScrollbars { + idc = 92534; + x = 0; + y = QUOTE(H_PART(4.8)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,modes_DisplayName); + tooltip = ECSTRING(spectator,modes_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x =QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class Free: RscActivePicture { + idc = 92550; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Free.paa"; + x = QUOTE(W_PART(13.375)); + y = QUOTE(H_PART(0.375)); + w = QUOTE(W_PART(1.75)); + h = QUOTE(H_PART(1.75)); + tooltip = "$STR_A3_Spectator_free_camera_tooltip"; + }; + class Follow: Free { + idc = 92552; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Follow.paa"; + x = QUOTE(W_PART(17.125)); + tooltip = "$STR_A3_Spectator_3pp_camera_tooltip"; + }; + class FirstPerson: Free { + idc = 92551; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Fps.paa"; + x = QUOTE(W_PART(20.875)); + tooltip = "$STR_A3_Spectator_1pp_camera_tooltip"; + }; + }; + }; + class VisionModes: RscControlsGroupNoScrollbars { + idc = 92535; + x = 0; + y = QUOTE(H_PART(7.4)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.3)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,visions_DisplayName); + tooltip = ECSTRING(spectator,visions_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = 0; + y = QUOTE(H_PART(1)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.3)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class AllCheckBox: RscCheckBox { + idc = 92557; + tooltip = CSTRING(ToggleAll); + x = QUOTE(W_PART(25)); + y = 0; + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); + }; + class NormalLabel: Label { + text = "$STR_speed_normal"; + tooltip = ""; + x = QUOTE(W_PART(1)); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(10.8)); + colorBackground[] = {0, 0, 0, 0.6}; + }; + class Normal: AllCheckBox { + idc = 92558; + x = QUOTE(W_PART(11.9)); + y = QUOTE(H_PART(1.1)); + }; + class NightVisionLabel: NormalLabel { + text = "$STR_usract_night_vision"; + y = QUOTE(H_PART(2.2)); + }; + class NightVision: Normal { + idc = 92559; + y = QUOTE(H_PART(2.2)); + }; + class WhiteHotLabel: NormalLabel { + text = CSTRING(ModuleSpectator_WhiteHot); + x = QUOTE(W_PART(13.1)); + }; + class WhiteHot: Normal { + idc = 92560; + x = QUOTE(W_PART(24)); + }; + class BlackHotLabel: WhiteHotLabel { + text = CSTRING(ModuleSpectator_BlackHot); + y = QUOTE(Y_PART(2.2)); + }; + class BlackHot: WhiteHot { + idc = 92561; + y = QUOTE(H_PART(2.2)); + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/build.bat b/build.bat new file mode 100644 index 0000000000..3392b5bf8d --- /dev/null +++ b/build.bat @@ -0,0 +1,3 @@ +@echo off +hemtt.exe build +pause diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 496de0f73f..0000000000 --- a/circle.yml +++ /dev/null @@ -1,62 +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 - 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/.gitattributes b/docs/.gitattributes index de2616570b..b6b22eb5f6 100644 --- a/docs/.gitattributes +++ b/docs/.gitattributes @@ -1,5 +1,6 @@ * text=auto *.png binary *.jpg binary +*.webp binary *.paa binary *.sh eol=lf diff --git a/docs/.gitignore b/docs/.gitignore index 7836aaf3f3..c2ef6dec77 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -20,3 +20,8 @@ CNAME tools/temp Gemfile.lock + +# Generated +_includes/dependencies_list.md +wiki/functions/*.md +!wiki/functions/index.md diff --git a/docs/404.html b/docs/404.md similarity index 100% rename from docs/404.html rename to docs/404.md diff --git a/docs/CNAME b/docs/CNAME index 21637da470..bb4ad3ca6d 100644 --- a/docs/CNAME +++ b/docs/CNAME @@ -1 +1 @@ -ace3mod.com \ No newline at end of file +ace3.acemod.org \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index ee47a3cdd9..599940594c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -# Source of https://ace3mod.com/ +# Source of https://ace3.acemod.org/ ## Updating compiled JavaScript and CSS files diff --git a/docs/README.zh-TW.md b/docs/README.zh-TW.md new file mode 100644 index 0000000000..da04d2b631 --- /dev/null +++ b/docs/README.zh-TW.md @@ -0,0 +1,125 @@ +

+ +

+ +

+ + ACE3 版本 + + + ACE3 問題 + + + ACE3 下載 + + + 波希米亞互動論壇上的文章 + + + ACE3 條款 + + + 加入ACE3 Discord + +

+ +

+ 需要最新版本之 CBA A3.
+ 在以下社群網站拜訪我們 推特 | 臉書 | YouTube | Reddit
+

+ +**進階戰鬥環境3(ACE3)** 是由 **進階戰鬥環境2(ACE2)**, **可靠性遊戲模改(AGM)** 以及 **戰鬥空間強化(CSE)**的幕後團隊人員精心打造,用於改善武裝行動三裡面的真實與可靠性。 + +這整個項目是 **開放原始碼**並且樂意接受任何的維護。若要歡迎你建立維護你自訂版本的ACE3,只要你所做的向公眾所做更改是有遵守著「GNU通用公眾授權條款」 ([GPLv2](https://github.com/acemod/ACE3/blob/master/LICENSE)). + +這個模組架構為 **模組化**設計,所以幾乎任何模組內包含的PBO元件可以輕鬆地從設置來移除。因此,一個團隊可以維護著藉由免除自己沒有打算加入的元件來量身訂製的ACE3版本,或者如果有與其他模組衝突。模塊本身,例如醫療系統,那就可以簡單的去除掉。而且,也包含許多可自訂義的設定,允許任務設計者來為整體的任務體驗從頭到尾的調教。 + +## 核心功能 + +- 全新的立體互動/動作系統 +- 可靠又高效的框架 +- 專注於可模組化與可自訂性 +- 客戶端及伺服端全新的靈活的設置及配置 +- 改進醫療系統並劃分為多層次(基礎/進階)以此專注於遊玩向或者真實向體驗 +- 透過網路同步的精確且一致的天氣 +- 以風和天氣為考量的彈道系統 +- 戰俘系統 +- 爆裂物系統,內含不同的觸發爆裂物的類型 +- 地圖畫面的改進 - 標記的擺放以及地圖工具 +- 後勤系統 +- 進階的飛彈引導以及雷射指示器 + +### 添加功能 + +- 揹起與拖動。 +- 還原真實世界的載具及武器名稱 +- 裝甲載具以及直升機有著火控系統(FCS) +- 以C/C++編寫的真實彈道及火控運算插件 +- 尾焰以及高壓範圍的模擬 +- 一次性使用發射器 +- 真實G力 +- 載具上鎖系統 +- 真實的熱傳導以及夜視模式 +- 彈匣重填功能 +- 真實的武器過熱機制 +- 戰鬥耳聾(暫時性失去聽覺)模擬 +- 改進行動後預覽以及火力掩護 +- 可調性狙擊槍瞄具 +- 當放下武器時沒有閒置動作 +- 去除說話中玩家的提示 +- 跳過障礙物,翻牆以及割開柵欄。 +- Vector望遠鏡, 微型軍用GPS接收器以及獵隼4500測風儀裝置
+***不只這些呢...*** + +## 新手起步 + +ACE3需要最新版本的武裝行動3以及最新版本的 CBA A3模組。以下的網頁可用於幫助以及提供安裝ACE3上的資訊。 +- [安裝指南-英文](https://ace3.acemod.org/wiki/user/installation-guide.html) +- [資訊中心-英文](https://ace3.acemod.org/wiki/user/information-center.html) + +## 維護 + +你透過幫忙找出我們原始碼的漏洞來幫助我們接下來的開發,或者維護著新功能。我們總是歡迎提交漏洞修補以及程式碼重構或者新功能。我們有列出我們遇到的問題或者目標在Github上如果有想要維護的話請在問題上留言避免多餘重複的付出。 + +### 維護指南 + +如果想要維護ACE3的某個部件的話, 簡單的分支該儲存庫並申請提交來讓合作者檢視。請記得如果你有修改PBO部件請將自己加入到作者們的文件 - [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt);包括可連絡的電子信箱。 + +### 提交問題或者申請功能 + +麻煩,請使用我們的 [問題追蹤](https://github.com/acemod/ACE3/issues)來回報漏洞,想要的功能,或者建議調整目前已有的功能,也請到以下參閱: +- [如何回報問題-英文](https://ace3.acemod.org/wiki/user/how-to-report-an-issue.html) +- [如何申請功能-英文](https://ace3.acemod.org/wiki/user/how-to-make-a-feature-request.html) + +### 測試與建構。 + +若要幫助我們測試最新的開發版所造成的更改,下載我們的主分支([直接下載](https://github.com/acemod/ACE3/archive/master.zip),或者 [git](https://help.github.com/articles/fetching-a-remote/)),然後用於編譯組建: + +- [設置開發環境-英文](https://ace3.acemod.org/wiki/development/setting-up-the-development-environment.html) –一步一步的引導如何為了測試目的來正確的建構ACE3 + +### 聯繫 + + + + + + + + + + + + + + + + + + + + +
Discord我們有著公共的Discord團隊供大家加入,而該模組所有開發者以及維護者也會在此出現並公告
推特你可以追隨我們的推特帳號來獲得更新消息以及一些指南聯結。
臉書你可以追隨我們的臉書帳號來獲得更新消息以及一些指南聯結。
波希米亞論壇我們在波希米亞互動論壇上也有專門的ACE3之文章
+ +## 條款 + +ACE3遵守在GNU通用公眾授權條款之下 ([GPLv2](https://github.com/acemod/ACE3/blob/master/LICENSE)). diff --git a/docs/README_DE.md b/docs/README_DE.md index 701939741a..160fb111b2 100644 --- a/docs/README_DE.md +++ b/docs/README_DE.md @@ -3,7 +3,7 @@

- + ACE3 Version @@ -15,11 +15,8 @@ ACE3 Lizenz - - ACE3 Slack - - - ACE3 Build Status + + ACE3 Discord

@@ -70,14 +67,14 @@ Die Mod ist **modular aufgebaut**. Beinahe jede PBO kann entfernt werden, sodass #### Anleitungen Du hast ACE3 installiert, hast aber keine Ahnung was und wie alles funktioniert und wo sich was befindet? -- [Erste Schritte](https://ace3mod.com/wiki/user/getting-started.html). +- [Erste Schritte](https://ace3.acemod.org/wiki/user/getting-started.html). #### Mitwirken Wenn du bei der Entwicklung von ACE3 mithelfen möchtest, kannst du dies tun, indem du nach Fehlern Ausschau hältst oder neue Funktionen vorschlägst. Um etwas beizutragen, "Forke" dieses Repository und erstelle deine "Pull-Requests", welche von anderen Entwicklern und Beiträgern überprüft werden. Bitte trage dich dabei in [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) mit deinem Nutzernamen und einer gültigen Email-Adresse ein. Um uns einen Fehler, Anregungen oder neue Funktionalitäten mitzuteilen: Nutze unseren [Issue Tracker](https://github.com/acemod/ACE3/issues). Besuche auch: -- [Wie kann ich ein Problem melden](https://ace3mod.com/wiki/user/how-to-report-an-issue.html) -- [Wie kann ich ein Wunsch zu einer neuen Funktion mitteilen?](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) +- [Wie kann ich ein Problem melden](https://ace3.acemod.org/wiki/user/how-to-report-an-issue.html) +- [Wie kann ich ein Wunsch zu einer neuen Funktion mitteilen?](https://ace3.acemod.org/wiki/user/how-to-make-a-feature-request.html) #### Testen & Mod erstellen Wenn du die neusten Entwicklungen erleben und uns dabei helfen möchtest bestehende Fehler zu entdecken, lade dir die "Master Branch" herunter. Entweder nutzt du [Git](https://help.github.com/articles/fetching-a-remote/) - wenn die Schritte bekannt sind - oder du lädst es dir direkt über [diesen Link](https://github.com/acemod/ACE3/archive/master.zip) herunter. diff --git a/docs/README_PL.md b/docs/README_PL.md index b99b96ca95..b1917f4080 100644 --- a/docs/README_PL.md +++ b/docs/README_PL.md @@ -2,7 +2,7 @@

- + ACE3 Wersja @@ -14,11 +14,8 @@ ACE3 Licencja - - ACE3 Slack - - - ACE3 Build Status + + ACE3 Discord

Wymaga najnowszej wersji CBA A3. Odwiedź nas na Facebook | YouTube | Twitter | Reddit

@@ -65,15 +62,15 @@ Modyfikacja ta jest **budowana modułowo**, dzięki temu prawie każdy dostarczo ### Poradniki i instrukcje Jeżeli zainstalowałeś ACE3 lecz masz problem ze zrozumieniem jak to wszystko działa, lub gdzie zacząć, zacznij od przeczytania tego: -- [Wprowadzenie](https://ace3mod.com/wiki/user/getting-started.html) +- [Wprowadzenie](https://ace3.acemod.org/wiki/user/getting-started.html) #### Współpraca Możesz pomóc w rozwoju addonu szukając potencjalnych bugów w naszym kodzie, lub zgłaszając nowe funkcje. Aby wnieść swój wkład do ACE3, po prostu zforkuj to repozytorium na swoje konto GitHub i zgłoś swoje pull requesty do przeglądu przez innych współpracowników. Pamiętaj, aby dodać siebie do listy autorów każdego PBO jakie edytujesz oraz do pliku ['AUTHORS.txt'](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) dodając także swój adres e-mail. Używaj naszego [Issue Tracker-a](https://github.com/acemod/ACE3/issues) aby zgłaszać bugi, proponować nowe funkcje lub sugerować zmiany do aktualnie istniejących. Zobacz także: -- [Jak zgłosić bug-a](https://ace3mod.com/wiki/user/how-to-report-an-issue.html) -- [Jak zgłosić feature request-a](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) +- [Jak zgłosić bug-a](https://ace3.acemod.org/wiki/user/how-to-report-an-issue.html) +- [Jak zgłosić feature request-a](https://ace3.acemod.org/wiki/user/how-to-make-a-feature-request.html) #### Testowanie i budowanie Aby pomóc nam w testowaniu najnowszych zmian rozwojowych, pobierz nasz master branch ([bezpośrednio](https://github.com/acemod/ACE3/archive/master.zip), lub [korzystając z git](https://help.github.com/articles/fetching-a-remote/)), a następnie złóż testowego build-a: -- [Konfiguracja środowiska do testów](https://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – intrukcja krok-po-kroku jak poprawnie ustawić i zbudować wersję ACE3 do celów testowych. +- [Konfiguracja środowiska do testów](https://ace3.acemod.org/wiki/development/setting-up-the-development-environment.html) – intrukcja krok-po-kroku jak poprawnie ustawić i zbudować wersję ACE3 do celów testowych. diff --git a/docs/_config.yml b/docs/_config.yml index 224559582d..ee7822969d 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,24 +1,16 @@ -name: ACE3 +title: ACE3 description: ACE3 is a joint effort by the teams behind ACE 2, AGM and CSE to improve the realism and authenticity of Arma 3. keywords: Advanced Combat Enhancement 3, ACE, ACE3, Arma, Arma 3, Mod, Modification, Realism, AGM, CSE, Bohemia, Interactive -productionUrl: https://ace3mod.com +productionUrl: https://ace3.acemod.org ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 12 - patch: 6 - build: 43 - -acex: - githubUrl: https://github.com/acemod/ACEX - version: - major: 3 - minor: 4 - patch: 2 - build: 13 + minor: 17 + patch: 1 + build: 86 markdown: kramdown @@ -34,7 +26,7 @@ highlighter: rouge safe: true lsi: false -exclude: [src, .editorconfig, .gitignore, CNAME, Gemfile, Gemfile.lock, README.md] +exclude: [src, .editorconfig, .gitignore, CNAME, Gemfile, Gemfile.lock, README*.md, Dockerfile, docker-compose.yml, entrypoint.sh, package-lock.json, acebot.json] plugins: - jekyll-redirect-from diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml index a1d68d7786..348e1aee44 100644 --- a/docs/_config_dev.yml +++ b/docs/_config_dev.yml @@ -1,4 +1,4 @@ -name: ACE3 +title: ACE3 description: ACE3 is a joint effort by the teams behind ACE 2, AGM and CSE to improve the realism and authenticity of Arma 3. keywords: Advanced Combat Enhancement 3, ACE, ACE3, Arma, Arma 3, Mod, Modification, Realism, AGM, CSE, Bohemia, Interactive @@ -8,17 +8,9 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 12 - patch: 6 - build: 43 - -acex: - githubUrl: https://github.com/acemod/ACEX - version: - major: 3 - minor: 4 - patch: 2 - build: 13 + minor: 17 + patch: 1 + build: 86 markdown: kramdown @@ -34,7 +26,7 @@ highlighter: rouge safe: true lsi: false -exclude: [src, .editorconfig, .gitignore, CNAME, Gemfile, Gemfile.lock, README.md] +exclude: [src, .editorconfig, .gitignore, CNAME, Gemfile, Gemfile.lock, README*.md, Dockerfile, docker-compose.yml, entrypoint.sh, package-lock.json, acebot.json] plugins: - jekyll-redirect-from diff --git a/docs/_includes/_footer.html b/docs/_includes/_footer.html index 8763b6c35a..b13d9d47b5 100644 --- a/docs/_includes/_footer.html +++ b/docs/_includes/_footer.html @@ -3,41 +3,49 @@

ACE3

ACE3 is a joint effort by the teams behind ACE2, AGM and CSE to improve the realism and authenticity of Arma 3.

-

If you want to contribute something to ACE3, simply fork the GitHub repository and submit your pull requests for review.

+

If you want to contribute something to ACE3, simply fork the GitHub repository and submit your pull requests for review.

Issues / Feedback

-

Issues, feature requests and feedback are welcome at the ACE3 GitHub issue tracker.

+

Issues, feature requests and feedback are welcome at the ACE3 GitHub issue tracker.

Before reporting an issue, please read the wiki entry "How to report an issue".

-

We have created a single issue for feature requests.

+

We have created a single issue for feature requests.

Social Media

-
- - - + diff --git a/docs/_includes/_header.html b/docs/_includes/_header.html index 84bcab8d2e..8c6cd8c39e 100644 --- a/docs/_includes/_header.html +++ b/docs/_includes/_header.html @@ -8,7 +8,6 @@ - @@ -17,16 +16,19 @@ - + - + - - + + + + +
diff --git a/docs/_includes/_navigation.html b/docs/_includes/_navigation.html index f0e2703ffd..e929b8d438 100644 --- a/docs/_includes/_navigation.html +++ b/docs/_includes/_navigation.html @@ -1,9 +1,17 @@